mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Fix many bugs in replies so they all appear, in the right order, and as soon as they are made.
This commit is contained in:
parent
4599f2c472
commit
01036172b3
11 changed files with 97 additions and 51 deletions
|
@ -133,15 +133,15 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/comment_replies_container"
|
||||
android:orientation="horizontal"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
<View
|
||||
android:id="@+id/comment_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
style="?storyCommentDivider" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -323,6 +323,7 @@ public class BlurDatabaseHelper {
|
|||
commentValues.add(comment.getValues());
|
||||
for (Reply reply : comment.replies) {
|
||||
reply.commentId = comment.id;
|
||||
reply.id = reply.constructId();
|
||||
replyValues.add(reply.getValues());
|
||||
}
|
||||
}
|
||||
|
@ -334,6 +335,7 @@ public class BlurDatabaseHelper {
|
|||
commentValues.add(comment.getValues());
|
||||
for (Reply reply : comment.replies) {
|
||||
reply.commentId = comment.id;
|
||||
reply.id = reply.constructId();
|
||||
replyValues.add(reply.getValues());
|
||||
}
|
||||
}
|
||||
|
@ -346,6 +348,7 @@ public class BlurDatabaseHelper {
|
|||
commentValues.add(comment.getValues());
|
||||
for (Reply reply : comment.replies) {
|
||||
reply.commentId = comment.id;
|
||||
reply.id = reply.constructId();
|
||||
replyValues.add(reply.getValues());
|
||||
}
|
||||
}
|
||||
|
@ -965,7 +968,7 @@ public class BlurDatabaseHelper {
|
|||
public List<Reply> getCommentReplies(String commentId) {
|
||||
String[] selArgs = new String[] {commentId};
|
||||
String selection = DatabaseConstants.REPLY_COMMENTID+ " = ?";
|
||||
Cursor c = dbRO.query(DatabaseConstants.REPLY_TABLE, DatabaseConstants.REPLY_COLUMNS, selection, selArgs, null, null, DatabaseConstants.REPLY_DATE + " DESC");
|
||||
Cursor c = dbRO.query(DatabaseConstants.REPLY_TABLE, null, selection, selArgs, null, null, DatabaseConstants.REPLY_DATE + " ASC");
|
||||
List<Reply> replies = new ArrayList<Reply>(c.getCount());
|
||||
while (c.moveToNext()) {
|
||||
replies.add(Reply.fromCursor(c));
|
||||
|
@ -974,6 +977,16 @@ public class BlurDatabaseHelper {
|
|||
return replies;
|
||||
}
|
||||
|
||||
public void replyToComment(String storyId, String feedId, String commentUserId, String replyText) {
|
||||
Reply reply = new Reply();
|
||||
reply.commentId = Comment.constructId(storyId, feedId, commentUserId);
|
||||
reply.text = replyText;
|
||||
reply.userId = PrefsUtils.getUserDetails(context).id;
|
||||
reply.date = new Date();
|
||||
reply.id = reply.constructId();
|
||||
synchronized (RW_MUTEX) {dbRW.insertWithOnConflict(DatabaseConstants.REPLY_TABLE, null, reply.getValues(), SQLiteDatabase.CONFLICT_REPLACE);}
|
||||
}
|
||||
|
||||
public static void closeQuietly(Cursor c) {
|
||||
if (c == null) return;
|
||||
try {c.close();} catch (Exception e) {;}
|
||||
|
|
|
@ -134,7 +134,8 @@ public class DatabaseConstants {
|
|||
public static final String ACTION_UNSHARE = "unshare";
|
||||
public static final String ACTION_LIKE_COMMENT = "like_comment";
|
||||
public static final String ACTION_UNLIKE_COMMENT = "unlike_comment";
|
||||
public static final String ACTION_COMMENT = "comment";
|
||||
public static final String ACTION_REPLY = "reply";
|
||||
public static final String ACTION_COMMENT_TEXT = "comment_text";
|
||||
public static final String ACTION_STORY_HASH = "story_hash";
|
||||
public static final String ACTION_FEED_ID = "feed_id";
|
||||
public static final String ACTION_INCLUDE_OLDER = "include_older";
|
||||
|
@ -275,7 +276,8 @@ public class DatabaseConstants {
|
|||
ACTION_UNSHARE + INTEGER + " DEFAULT 0, " +
|
||||
ACTION_LIKE_COMMENT + INTEGER + " DEFAULT 0, " +
|
||||
ACTION_UNLIKE_COMMENT + INTEGER + " DEFAULT 0, " +
|
||||
ACTION_COMMENT + TEXT + ", " +
|
||||
ACTION_REPLY + INTEGER + " DEFAULT 0, " +
|
||||
ACTION_COMMENT_TEXT + TEXT + ", " +
|
||||
ACTION_STORY_HASH + TEXT + ", " +
|
||||
ACTION_FEED_ID + TEXT + ", " +
|
||||
ACTION_INCLUDE_OLDER + INTEGER + ", " +
|
||||
|
@ -294,10 +296,6 @@ public class DatabaseConstants {
|
|||
SOCIAL_FEED_ID, SOCIAL_FEED_USERNAME, SOCIAL_FEED_TITLE, SOCIAL_FEED_ICON, SOCIAL_FEED_POSITIVE_COUNT, SOCIAL_FEED_NEUTRAL_COUNT, SOCIAL_FEED_NEGATIVE_COUNT
|
||||
};
|
||||
|
||||
public static final String[] REPLY_COLUMNS = {
|
||||
REPLY_COMMENTID, REPLY_DATE, REPLY_ID, REPLY_SHORTDATE, REPLY_TEXT, REPLY_USERID
|
||||
};
|
||||
|
||||
public static final String SUM_STORY_TOTAL = "storyTotal";
|
||||
private static String STORY_SUM_TOTAL = " CASE " +
|
||||
"WHEN MAX(" + STORY_INTELLIGENCE_AUTHORS + "," + STORY_INTELLIGENCE_TAGS + "," + STORY_INTELLIGENCE_TITLE + ") > 0 " +
|
||||
|
|
|
@ -76,7 +76,7 @@ public class Comment implements Serializable {
|
|||
}
|
||||
|
||||
public static String constructId(String storyId, String feedId, String userId) {
|
||||
return TextUtils.concat(storyId, feedId, userId).toString();
|
||||
return TextUtils.concat(feedId, storyId, userId).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Date;
|
|||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.newsblur.database.DatabaseConstants;
|
||||
|
@ -24,6 +25,7 @@ public class Reply {
|
|||
@SerializedName("date")
|
||||
public Date date;
|
||||
|
||||
// NB: this is the commentId that we generate, not the API one
|
||||
public String commentId;
|
||||
|
||||
public ContentValues getValues() {
|
||||
|
@ -47,4 +49,9 @@ public class Reply {
|
|||
reply.userId = cursor.getString(cursor.getColumnIndex(DatabaseConstants.REPLY_USERID));
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
|
||||
// construct a string we can internally use as a PK
|
||||
public String constructId() {
|
||||
return TextUtils.concat(commentId, "_", Long.toString(date.getTime())).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.widget.Toast;
|
|||
import com.newsblur.R;
|
||||
import com.newsblur.domain.Story;
|
||||
import com.newsblur.network.APIManager;
|
||||
import com.newsblur.util.FeedUtils;
|
||||
|
||||
public class ReplyDialogFragment extends DialogFragment {
|
||||
|
||||
|
@ -25,9 +26,6 @@ public class ReplyDialogFragment extends DialogFragment {
|
|||
private String commentUserId, commentUsername;
|
||||
private Story story;
|
||||
|
||||
private APIManager apiManager;
|
||||
|
||||
|
||||
public static ReplyDialogFragment newInstance(final Story story, final String commentUserId, final String commentUsername) {
|
||||
ReplyDialogFragment frag = new ReplyDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
@ -40,17 +38,14 @@ public class ReplyDialogFragment extends DialogFragment {
|
|||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
|
||||
story = (Story) getArguments().getSerializable(STORY);
|
||||
|
||||
commentUserId = getArguments().getString(COMMENT_USER_ID);
|
||||
commentUsername = getArguments().getString(COMMENT_USERNAME);
|
||||
|
||||
final Activity activity = getActivity();
|
||||
apiManager = new APIManager(activity);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
final String shareString = getResources().getString(R.string.reply_to);
|
||||
String shareString = getResources().getString(R.string.reply_to);
|
||||
builder.setTitle(String.format(shareString, getArguments().getString(COMMENT_USERNAME)));
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(activity);
|
||||
|
@ -61,23 +56,7 @@ public class ReplyDialogFragment extends DialogFragment {
|
|||
builder.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
|
||||
new AsyncTask<Void, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... arg) {
|
||||
return apiManager.replyToComment(story.id, story.feedId, commentUserId, reply.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (result) {
|
||||
Toast.makeText(activity, R.string.replied, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(activity, R.string.error_replying, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
ReplyDialogFragment.this.dismiss();
|
||||
};
|
||||
}.execute();
|
||||
FeedUtils.replyToComment(story.id, story.feedId, commentUserId, reply.getText().toString(), activity);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
|
||||
|
|
|
@ -177,8 +177,10 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
|
|||
replyUsername.setText(R.string.unknown_user);
|
||||
}
|
||||
|
||||
TextView replySharedDate = (TextView) replyView.findViewById(R.id.reply_shareddate);
|
||||
replySharedDate.setText(reply.shortDate + " ago");
|
||||
if (reply.shortDate != null) {
|
||||
TextView replySharedDate = (TextView) replyView.findViewById(R.id.reply_shareddate);
|
||||
replySharedDate.setText(reply.shortDate + " ago");
|
||||
}
|
||||
|
||||
((LinearLayout) commentView.findViewById(R.id.comment_replies_container)).addView(replyView);
|
||||
}
|
||||
|
|
|
@ -466,14 +466,14 @@ public class APIManager {
|
|||
return response.getResponse(gson, NewsBlurResponse.class);
|
||||
}
|
||||
|
||||
public boolean replyToComment(String storyId, String storyFeedId, String commentUserId, String reply) {
|
||||
public NewsBlurResponse replyToComment(String storyId, String storyFeedId, String commentUserId, String reply) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(APIConstants.PARAMETER_STORYID, storyId);
|
||||
values.put(APIConstants.PARAMETER_STORY_FEEDID, storyFeedId);
|
||||
values.put(APIConstants.PARAMETER_COMMENT_USERID, commentUserId);
|
||||
values.put(APIConstants.PARAMETER_REPLY_TEXT, reply);
|
||||
final APIResponse response = post(APIConstants.URL_REPLY_TO, values);
|
||||
return (!response.isError());
|
||||
APIResponse response = post(APIConstants.URL_REPLY_TO, values);
|
||||
return response.getResponse(gson, NewsBlurResponse.class);
|
||||
}
|
||||
|
||||
public boolean addFeed(String feedUrl, String folderName) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.text.DateFormat;
|
|||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
@ -15,8 +16,15 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class DateStringTypeAdapter implements JsonDeserializer<Date> {
|
||||
// 2012-07-23 02:43:02
|
||||
private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private final DateFormat df;
|
||||
|
||||
public DateStringTypeAdapter() {
|
||||
// API sends dates like 2012-07-23 02:43:02
|
||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
// API doesn't indicate TZ, but it is UTC
|
||||
df.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date deserialize(JsonElement element, Type type, JsonDeserializationContext arg2) throws JsonParseException {
|
||||
|
|
|
@ -227,6 +227,14 @@ public class FeedUtils {
|
|||
NbActivity.updateAllActivities(true);
|
||||
triggerSync(context);
|
||||
}
|
||||
|
||||
public static void replyToComment(String storyId, String feedId, String commentUserId, String replyText, Context context) {
|
||||
ReadingAction ra = ReadingAction.replyToComment(storyId, feedId, commentUserId, replyText);
|
||||
dbHelper.enqueueAction(ra);
|
||||
ra.doLocal(dbHelper);
|
||||
NbActivity.updateAllActivities(true);
|
||||
triggerSync(context);
|
||||
}
|
||||
|
||||
public static FeedSet feedSetFromFolderName(String folderName) {
|
||||
return FeedSet.folder(folderName, getFeedIdsRecursive(folderName));
|
||||
|
|
|
@ -33,7 +33,7 @@ public class ReadingAction {
|
|||
private String storyId;
|
||||
private String feedId;
|
||||
private String sourceUserId;
|
||||
private String commentText;
|
||||
private String commentReplyText; // used for both comments and replies
|
||||
private String commentUserId;
|
||||
|
||||
private ReadingAction() {
|
||||
|
@ -77,14 +77,14 @@ public class ReadingAction {
|
|||
return ra;
|
||||
}
|
||||
|
||||
public static ReadingAction shareStory(String hash, String storyId, String feedId, String sourceUserId, String commentText) {
|
||||
public static ReadingAction shareStory(String hash, String storyId, String feedId, String sourceUserId, String commentReplyText) {
|
||||
ReadingAction ra = new ReadingAction();
|
||||
ra.type = ActionType.SHARE;
|
||||
ra.storyHash = hash;
|
||||
ra.storyId = storyId;
|
||||
ra.feedId = feedId;
|
||||
ra.sourceUserId = sourceUserId;
|
||||
ra.commentText = commentText;
|
||||
ra.commentReplyText = commentReplyText;
|
||||
return ra;
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,16 @@ public class ReadingAction {
|
|||
return ra;
|
||||
}
|
||||
|
||||
public static ReadingAction replyToComment(String storyId, String feedId, String commentUserId, String commentReplyText) {
|
||||
ReadingAction ra = new ReadingAction();
|
||||
ra.type = ActionType.REPLY;
|
||||
ra.storyId = storyId;
|
||||
ra.commentUserId = commentUserId;
|
||||
ra.feedId = feedId;
|
||||
ra.commentReplyText = commentReplyText;
|
||||
return ra;
|
||||
}
|
||||
|
||||
public ContentValues toContentValues() {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(DatabaseConstants.ACTION_TIME, System.currentTimeMillis());
|
||||
|
@ -145,7 +155,7 @@ public class ReadingAction {
|
|||
values.put(DatabaseConstants.ACTION_STORY_ID, storyId);
|
||||
values.put(DatabaseConstants.ACTION_FEED_ID, feedId);
|
||||
values.put(DatabaseConstants.ACTION_SOURCE_USER_ID, sourceUserId);
|
||||
values.put(DatabaseConstants.ACTION_COMMENT, commentText);
|
||||
values.put(DatabaseConstants.ACTION_COMMENT_TEXT, commentReplyText);
|
||||
break;
|
||||
|
||||
case LIKE_COMMENT:
|
||||
|
@ -162,6 +172,14 @@ public class ReadingAction {
|
|||
values.put(DatabaseConstants.ACTION_COMMENT_ID, commentUserId);
|
||||
break;
|
||||
|
||||
case REPLY:
|
||||
values.put(DatabaseConstants.ACTION_REPLY, 1);
|
||||
values.put(DatabaseConstants.ACTION_STORY_ID, storyId);
|
||||
values.put(DatabaseConstants.ACTION_FEED_ID, feedId);
|
||||
values.put(DatabaseConstants.ACTION_COMMENT_ID, commentUserId);
|
||||
values.put(DatabaseConstants.ACTION_COMMENT_TEXT, commentReplyText);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("cannot serialise uknown type of action.");
|
||||
|
||||
|
@ -202,7 +220,7 @@ public class ReadingAction {
|
|||
ra.storyId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_STORY_ID));
|
||||
ra.feedId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_FEED_ID));
|
||||
ra.sourceUserId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_SOURCE_USER_ID));
|
||||
ra.commentText = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT));
|
||||
ra.commentReplyText = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_TEXT));
|
||||
} else if (c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_LIKE_COMMENT)) == 1) {
|
||||
ra.type = ActionType.LIKE_COMMENT;
|
||||
ra.storyId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_STORY_ID));
|
||||
|
@ -213,6 +231,12 @@ public class ReadingAction {
|
|||
ra.storyId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_STORY_ID));
|
||||
ra.feedId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_FEED_ID));
|
||||
ra.commentUserId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_ID));
|
||||
} else if (c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_REPLY)) == 1) {
|
||||
ra.type = ActionType.REPLY;
|
||||
ra.storyId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_STORY_ID));
|
||||
ra.feedId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_FEED_ID));
|
||||
ra.commentUserId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_ID));
|
||||
ra.commentReplyText = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_TEXT));
|
||||
} else {
|
||||
throw new IllegalStateException("cannot deserialise uknown type of action.");
|
||||
}
|
||||
|
@ -243,7 +267,7 @@ public class ReadingAction {
|
|||
return apiManager.markStoryAsUnstarred(storyHash);
|
||||
|
||||
case SHARE:
|
||||
return apiManager.shareStory(storyId, feedId, commentText, sourceUserId);
|
||||
return apiManager.shareStory(storyId, feedId, commentReplyText, sourceUserId);
|
||||
|
||||
case LIKE_COMMENT:
|
||||
return apiManager.favouriteComment(storyId, commentUserId, feedId);
|
||||
|
@ -251,6 +275,9 @@ public class ReadingAction {
|
|||
case UNLIKE_COMMENT:
|
||||
return apiManager.unFavouriteComment(storyId, commentUserId, feedId);
|
||||
|
||||
case REPLY:
|
||||
return apiManager.replyToComment(storyId, feedId, commentUserId, commentReplyText);
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
|
@ -286,8 +313,8 @@ public class ReadingAction {
|
|||
|
||||
case SHARE:
|
||||
dbHelper.setStoryShared(storyHash);
|
||||
if (!TextUtils.isEmpty(commentText)) {
|
||||
dbHelper.insertUpdateComment(storyId, feedId, commentText);
|
||||
if (!TextUtils.isEmpty(commentReplyText)) {
|
||||
dbHelper.insertUpdateComment(storyId, feedId, commentReplyText);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -299,6 +326,10 @@ public class ReadingAction {
|
|||
dbHelper.setCommentLiked(storyId, commentUserId, feedId, false);
|
||||
break;
|
||||
|
||||
case REPLY:
|
||||
dbHelper.replyToComment(storyId, feedId, commentUserId, commentReplyText);
|
||||
break;
|
||||
|
||||
default:
|
||||
// not all actions have these, which is fine
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue