Migrate more social actions to service-moderated API use, fix local display of actions before network round-trip. Implement network half of new commenting-on-raw-shares feature. (#643)

This commit is contained in:
dosiecki 2015-06-03 00:43:58 -07:00
parent e075eb5433
commit ea70671644
11 changed files with 234 additions and 251 deletions

View file

@ -138,9 +138,13 @@ public class BlurDatabaseHelper {
}
public void cleanupFeedsFolders() {
synchronized (RW_MUTEX) {dbRW.delete(DatabaseConstants.FEED_TABLE, null, null);}
synchronized (RW_MUTEX) {dbRW.delete(DatabaseConstants.FOLDER_TABLE, null, null);}
synchronized (RW_MUTEX) {dbRW.delete(DatabaseConstants.SOCIALFEED_TABLE, null, null);}
synchronized (RW_MUTEX) {
dbRW.delete(DatabaseConstants.FEED_TABLE, null, null);
dbRW.delete(DatabaseConstants.FOLDER_TABLE, null, null);
dbRW.delete(DatabaseConstants.SOCIALFEED_TABLE, null, null);
dbRW.delete(DatabaseConstants.COMMENT_TABLE, null, null);
dbRW.delete(DatabaseConstants.REPLY_TABLE, null, null);
}
}
public void vacuum() {
@ -314,6 +318,7 @@ public class BlurDatabaseHelper {
for (Story story : apiResponse.stories) {
for (Comment comment : story.publicComments) {
comment.storyId = story.id;
// we need a primary key for comments, so construct one
comment.id = TextUtils.concat(story.id, story.feedId, comment.userId).toString();
commentValues.add(comment.getValues());
for (Reply reply : comment.replies) {
@ -323,6 +328,19 @@ public class BlurDatabaseHelper {
}
for (Comment comment : story.friendsComments) {
comment.storyId = story.id;
// we need a primary key for comments, so construct one
comment.id = TextUtils.concat(story.id, story.feedId, comment.userId).toString();
comment.byFriend = true;
commentValues.add(comment.getValues());
for (Reply reply : comment.replies) {
reply.commentId = comment.id;
replyValues.add(reply.getValues());
}
}
for (Comment comment : story.friendsShares) {
comment.isPseudo = true;
comment.storyId = story.id;
// we need a primary key for comments, so construct one
comment.id = TextUtils.concat(story.id, story.feedId, comment.userId).toString();
comment.byFriend = true;
commentValues.add(comment.getValues());
@ -890,6 +908,19 @@ public class BlurDatabaseHelper {
return comment;
}
public void insertUpdateComment(String storyId, String feedId, String commentText) {
// we can only insert comments as the currently logged-in user
String userId = PrefsUtils.getUserDetails(context).id;
Comment comment = new Comment();
comment.id = TextUtils.concat(storyId, feedId, userId).toString();
comment.storyId = storyId;
comment.userId = userId;
comment.commentText = commentText;
comment.byFriend = true;
synchronized (RW_MUTEX) {dbRW.insertWithOnConflict(DatabaseConstants.COMMENT_TABLE, null, comment.getValues(), SQLiteDatabase.CONFLICT_REPLACE);}
}
public UserProfile getUserProfile(String userId) {
String[] selArgs = new String[] {userId};
String selection = DatabaseConstants.USER_USERID + " = ?";

View file

@ -131,6 +131,8 @@ public class DatabaseConstants {
public static final String ACTION_UNSAVE = "unsave";
public static final String ACTION_SHARE = "share";
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_STORY_HASH = "story_hash";
public static final String ACTION_FEED_ID = "feed_id";
@ -138,6 +140,7 @@ public class DatabaseConstants {
public static final String ACTION_INCLUDE_NEWER = "include_newer";
public static final String ACTION_STORY_ID = "story_id";
public static final String ACTION_SOURCE_USER_ID = "source_user_id";
public static final String ACTION_COMMENT_ID = "comment_id";
static final String FOLDER_SQL = "CREATE TABLE " + FOLDER_TABLE + " (" +
FOLDER_NAME + TEXT + " PRIMARY KEY, " +
@ -268,13 +271,16 @@ public class DatabaseConstants {
ACTION_UNSAVE + INTEGER + " DEFAULT 0, " +
ACTION_SHARE + INTEGER + " DEFAULT 0, " +
ACTION_UNSHARE + INTEGER + " DEFAULT 0, " +
ACTION_LIKE_COMMENT + INTEGER + " DEFAULT 0, " +
ACTION_UNLIKE_COMMENT + INTEGER + " DEFAULT 0, " +
ACTION_COMMENT + TEXT + ", " +
ACTION_STORY_HASH + TEXT + ", " +
ACTION_FEED_ID + TEXT + ", " +
ACTION_INCLUDE_OLDER + INTEGER + ", " +
ACTION_INCLUDE_NEWER + INTEGER + ", " +
ACTION_STORY_ID + TEXT + ", " +
ACTION_SOURCE_USER_ID + TEXT +
ACTION_SOURCE_USER_ID + TEXT + ", " +
ACTION_COMMENT_ID + TEXT +
")";
public static final String[] FEED_COLUMNS = {

View file

@ -12,6 +12,7 @@ import com.newsblur.database.DatabaseConstants;
public class Comment implements Serializable {
private static final long serialVersionUID = -2018705258520565390L;
// we almost always override API version with sensible PK constructed by concating story, feed, and user IDs
public String id;
@SerializedName("comments")
@ -36,8 +37,12 @@ public class Comment implements Serializable {
public String storyId;
// not vended by API, but we set it depending on which comment block of the response in which it appeared
public boolean byFriend = false;
// means this "comment" is actually a text-less share, which looks a little bit different
public boolean isPseudo = false;
public ContentValues getValues() {
ContentValues values = new ContentValues();
values.put(DatabaseConstants.COMMENT_DATE, date);
@ -69,4 +74,4 @@ public class Comment implements Serializable {
return comment;
}
}
}

View file

@ -79,6 +79,10 @@ public class Story implements Serializable {
@SerializedName("friend_comments")
public Comment[] friendsComments;
// these are pseudo-comments that allow replying to empty shares
@SerializedName("friend_shares")
public Comment[] friendsShares;
@SerializedName("intelligence")
public Intelligence intelligence = new Intelligence();

View file

@ -41,8 +41,6 @@ import com.newsblur.activity.Reading;
import com.newsblur.domain.Classifier;
import com.newsblur.domain.Story;
import com.newsblur.domain.UserDetails;
import com.newsblur.network.APIManager;
import com.newsblur.network.SetupCommentSectionTask;
import com.newsblur.service.NBSyncService;
import com.newsblur.util.DefaultFeedView;
import com.newsblur.util.FeedUtils;
@ -69,7 +67,6 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
public static final String TEXT_SIZE_VALUE = "textSizeChangeValue";
public Story story;
private LayoutInflater inflater;
private APIManager apiManager;
private ImageLoader imageLoader;
private String feedColor, feedTitle, feedFade, feedBorder, feedIconUrl, faviconText;
private Classifier classifier;
@ -131,7 +128,6 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageLoader = ((NewsBlurApplication) getActivity().getApplicationContext()).getImageLoader();
apiManager = new APIManager(getActivity());
story = getArguments() != null ? (Story) getArguments().getSerializable("story") : null;
inflater = getActivity().getLayoutInflater();
@ -197,11 +193,7 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
updateShareButton();
updateSaveButton();
if (story.sharedUserIds.length > 0 || story.commentCount > 0 ) {
view.findViewById(R.id.reading_share_bar).setVisibility(View.VISIBLE);
view.findViewById(R.id.share_bar_underline).setVisibility(View.VISIBLE);
setupItemCommentsAndShares(view);
}
setupItemCommentsAndShares();
NonfocusScrollview scrollView = (NonfocusScrollview) view.findViewById(R.id.reading_scrollview);
scrollView.registerScrollChangeListener(this.activity);
@ -296,8 +288,8 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
shareButton.setText(R.string.share_this);
}
private void setupItemCommentsAndShares(final View view) {
new SetupCommentSectionTask(getActivity(), view, getFragmentManager(), inflater, apiManager, story, imageLoader).execute();
private void setupItemCommentsAndShares() {
new SetupCommentSectionTask(getActivity(), view, getFragmentManager(), inflater, story, imageLoader).execute();
}
private void setupItemMetadata() {
@ -452,6 +444,7 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
updateSaveButton();
updateShareButton();
reloadStoryContent();
setupItemCommentsAndShares();
}
private void loadOriginalText() {

View file

@ -1,4 +1,4 @@
package com.newsblur.network;
package com.newsblur.fragment;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@ -43,7 +43,6 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
private ArrayList<View> publicCommentViews;
private ArrayList<View> friendCommentViews;
private final APIManager apiManager;
private final Story story;
private final LayoutInflater inflater;
@ -54,11 +53,10 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
private final FragmentManager manager;
private List<Comment> comments;
public SetupCommentSectionTask(final Context context, final View view, final FragmentManager manager, LayoutInflater inflater, final APIManager apiManager, final Story story, final ImageLoader imageLoader) {
public SetupCommentSectionTask(Context context, View view, FragmentManager manager, LayoutInflater inflater, Story story, ImageLoader imageLoader) {
this.context = context;
this.manager = manager;
this.inflater = inflater;
this.apiManager = apiManager;
this.story = story;
this.imageLoader = imageLoader;
viewHolder = new WeakReference<View>(view);
@ -96,7 +94,10 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
ImageView commentImage = (ImageView) commentView.findViewById(R.id.comment_user_image);
TextView commentSharedDate = (TextView) commentView.findViewById(R.id.comment_shareddate);
commentSharedDate.setText(comment.sharedDate + " ago");
// TODO: this uses hard-coded "ago" values, which will be wrong when reading prefetched stories
if (comment.sharedDate != null) {
commentSharedDate.setText(comment.sharedDate + " ago");
}
commentSharedDate.setTag(COMMENT_DATE_BY + comment.userId);
final FlowLayout favouriteContainer = (FlowLayout) commentView.findViewById(R.id.comment_favourite_avatars);
@ -123,9 +124,9 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
@Override
public void onClick(View v) {
if (!Arrays.asList(comment.likingUsers).contains(user.id)) {
new LikeCommentTask(context, apiManager, favouriteIcon, favouriteContainer, story.id, comment, story.feedId, user.id).execute();
FeedUtils.likeComment(story, comment.userId, context);
} else {
new UnLikeCommentTask(context, apiManager, favouriteIcon, favouriteContainer, story.id, comment, story.feedId, user.id).execute();
FeedUtils.unlikeComment(story, comment.userId, context);
}
}
});
@ -204,12 +205,6 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
imageLoader.displayImage(userPhoto, commentImage, 10f);
}
if (comment.byFriend) {
friendCommentViews.add(commentView);
} else {
publicCommentViews.add(commentView);
}
commentImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@ -218,76 +213,100 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
context.startActivity(i);
}
});
if (comment.byFriend) {
friendCommentViews.add(commentView);
} else {
publicCommentViews.add(commentView);
}
}
return null;
}
protected void onPostExecute(Void result) {
if (viewHolder.get() != null) {
FlowLayout sharedGrid = (FlowLayout) viewHolder.get().findViewById(R.id.reading_social_shareimages);
FlowLayout commentGrid = (FlowLayout) viewHolder.get().findViewById(R.id.reading_social_commentimages);
View view = viewHolder.get();
if (view == null) return; // fragment was dismissed before we rendered
TextView friendCommentTotal = ((TextView) viewHolder.get().findViewById(R.id.reading_friend_comment_total));
TextView publicCommentTotal = ((TextView) viewHolder.get().findViewById(R.id.reading_public_comment_total));
ViewUtils.setupCommentCount(context, viewHolder.get(), comments.size());
ViewUtils.setupShareCount(context, viewHolder.get(), story.sharedUserIds.length);
if (story.sharedUserIds.length > 0 || publicCommentViews.size() > 0 || friendCommentViews.size() > 0) {
view.findViewById(R.id.reading_share_bar).setVisibility(View.VISIBLE);
view.findViewById(R.id.share_bar_underline).setVisibility(View.VISIBLE);
} else {
view.findViewById(R.id.reading_share_bar).setVisibility(View.GONE);
view.findViewById(R.id.share_bar_underline).setVisibility(View.GONE);
}
Set<String> commentIds = new HashSet<String>();
for (Comment comment : comments) {
commentIds.add(comment.userId);
}
FlowLayout sharedGrid = (FlowLayout) view.findViewById(R.id.reading_social_shareimages);
FlowLayout commentGrid = (FlowLayout) view.findViewById(R.id.reading_social_commentimages);
for (String userId : story.sharedUserIds) {
if (!commentIds.contains(userId)) {
UserProfile user = FeedUtils.dbHelper.getUserProfile(userId);
if (user != null) {
ImageView image = ViewUtils.createSharebarImage(context, imageLoader, user.photoUrl, user.userId);
sharedGrid.addView(image);
}
TextView friendCommentTotal = ((TextView) view.findViewById(R.id.reading_friend_comment_total));
TextView publicCommentTotal = ((TextView) view.findViewById(R.id.reading_public_comment_total));
ViewUtils.setupCommentCount(context, view, comments.size());
ViewUtils.setupShareCount(context, view, story.sharedUserIds.length);
Set<String> commentIds = new HashSet<String>();
for (Comment comment : comments) {
commentIds.add(comment.userId);
}
sharedGrid.removeAllViews();
for (String userId : story.sharedUserIds) {
if (!commentIds.contains(userId)) {
UserProfile user = FeedUtils.dbHelper.getUserProfile(userId);
if (user != null) {
ImageView image = ViewUtils.createSharebarImage(context, imageLoader, user.photoUrl, user.userId);
sharedGrid.addView(image);
}
}
}
for (Comment comment : comments) {
UserProfile user = FeedUtils.dbHelper.getUserProfile(comment.userId);
ImageView image = ViewUtils.createSharebarImage(context, imageLoader, user.photoUrl, user.userId);
commentGrid.addView(image);
}
if (publicCommentViews.size() > 0) {
String commentCount = context.getString(R.string.public_comment_count);
if (publicCommentViews.size() == 1) {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
publicCommentTotal.setText(String.format(commentCount, publicCommentViews.size()));
viewHolder.get().findViewById(R.id.reading_public_comment_header).setVisibility(View.VISIBLE);
commentGrid.removeAllViews();
for (Comment comment : comments) {
UserProfile user = FeedUtils.dbHelper.getUserProfile(comment.userId);
ImageView image = ViewUtils.createSharebarImage(context, imageLoader, user.photoUrl, user.userId);
commentGrid.addView(image);
}
if (publicCommentViews.size() > 0) {
String commentCount = context.getString(R.string.public_comment_count);
if (publicCommentViews.size() == 1) {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
if (friendCommentViews.size() > 0) {
String commentCount = context.getString(R.string.friends_comments_count);
if (friendCommentViews.size() == 1) {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
friendCommentTotal.setText(String.format(commentCount, friendCommentViews.size()));
viewHolder.get().findViewById(R.id.reading_friend_comment_header).setVisibility(View.VISIBLE);
publicCommentTotal.setText(String.format(commentCount, publicCommentViews.size()));
view.findViewById(R.id.reading_public_comment_header).setVisibility(View.VISIBLE);
} else {
view.findViewById(R.id.reading_public_comment_header).setVisibility(View.GONE);
}
if (friendCommentViews.size() > 0) {
String commentCount = context.getString(R.string.friends_comments_count);
if (friendCommentViews.size() == 1) {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
friendCommentTotal.setText(String.format(commentCount, friendCommentViews.size()));
view.findViewById(R.id.reading_friend_comment_header).setVisibility(View.VISIBLE);
} else {
view.findViewById(R.id.reading_friend_comment_header).setVisibility(View.GONE);
}
for (int i = 0; i < publicCommentViews.size(); i++) {
if (i == publicCommentViews.size() - 1) {
publicCommentViews.get(i).findViewById(R.id.comment_divider).setVisibility(View.GONE);
}
((LinearLayout) viewHolder.get().findViewById(R.id.reading_public_comment_container)).addView(publicCommentViews.get(i));
}
for (int i = 0; i < friendCommentViews.size(); i++) {
if (i == friendCommentViews.size() - 1) {
friendCommentViews.get(i).findViewById(R.id.comment_divider).setVisibility(View.GONE);
}
((LinearLayout) viewHolder.get().findViewById(R.id.reading_friend_comment_container)).addView(friendCommentViews.get(i));
}
}
LinearLayout publicCommentListContainer = (LinearLayout) view.findViewById(R.id.reading_public_comment_container);
publicCommentListContainer.removeAllViews();
for (int i = 0; i < publicCommentViews.size(); i++) {
if (i == publicCommentViews.size() - 1) {
publicCommentViews.get(i).findViewById(R.id.comment_divider).setVisibility(View.GONE);
}
publicCommentListContainer.addView(publicCommentViews.get(i));
}
LinearLayout friendCommentListContainer = (LinearLayout) view.findViewById(R.id.reading_friend_comment_container);
friendCommentListContainer.removeAllViews();
for (int i = 0; i < friendCommentViews.size(); i++) {
if (i == friendCommentViews.size() - 1) {
friendCommentViews.get(i).findViewById(R.id.comment_divider).setVisibility(View.GONE);
}
friendCommentListContainer.addView(friendCommentViews.get(i));
}
}
}

View file

@ -448,22 +448,22 @@ public class APIManager {
}
}
public boolean favouriteComment(String storyId, String commentId, String feedId) {
public NewsBlurResponse favouriteComment(String storyId, String commentId, String feedId) {
ContentValues values = new ContentValues();
values.put(APIConstants.PARAMETER_STORYID, storyId);
values.put(APIConstants.PARAMETER_STORY_FEEDID, feedId);
values.put(APIConstants.PARAMETER_COMMENT_USERID, commentId);
final APIResponse response = post(APIConstants.URL_LIKE_COMMENT, values);
return (!response.isError());
APIResponse response = post(APIConstants.URL_LIKE_COMMENT, values);
return response.getResponse(gson, NewsBlurResponse.class);
}
public Boolean unFavouriteComment(String storyId, String commentId, String feedId) {
public NewsBlurResponse unFavouriteComment(String storyId, String commentId, String feedId) {
ContentValues values = new ContentValues();
values.put(APIConstants.PARAMETER_STORYID, storyId);
values.put(APIConstants.PARAMETER_STORY_FEEDID, feedId);
values.put(APIConstants.PARAMETER_COMMENT_USERID, commentId);
final APIResponse response = post(APIConstants.URL_UNLIKE_COMMENT, values);
return (!response.isError());
APIResponse response = post(APIConstants.URL_UNLIKE_COMMENT, values);
return response.getResponse(gson, NewsBlurResponse.class);
}
public boolean replyToComment(String storyId, String storyFeedId, String commentUserId, String reply) {

View file

@ -1,77 +0,0 @@
package com.newsblur.network;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.Toast;
import com.newsblur.R;
import com.newsblur.domain.Comment;
import com.newsblur.domain.UserDetails;
import com.newsblur.util.PrefsUtils;
import com.newsblur.util.UIUtils;
import com.newsblur.view.FlowLayout;
public class LikeCommentTask extends AsyncTask<Void, Void, Boolean>{
final WeakReference<ImageView> favouriteIconViewHolder;
private final APIManager apiManager;
private final String storyId;
private final Comment comment;
private final String feedId;
private final Context context;
private final String userId;
private Bitmap userImage;
private WeakReference<FlowLayout> favouriteAvatarHolder;
private UserDetails user;
public LikeCommentTask(final Context context, final APIManager apiManager, final ImageView favouriteIcon, final FlowLayout favouriteAvatarLayout, final String storyId, final Comment comment, final String feedId, final String userId) {
this.apiManager = apiManager;
this.storyId = storyId;
this.comment = comment;
this.feedId = feedId;
this.context = context;
this.userId = userId;
favouriteAvatarHolder = new WeakReference<FlowLayout>(favouriteAvatarLayout);
favouriteIconViewHolder = new WeakReference<ImageView>(favouriteIcon);
userImage = PrefsUtils.getUserImage(context);
user = PrefsUtils.getUserDetails(context);
}
@Override
protected Boolean doInBackground(Void... params) {
return apiManager.favouriteComment(storyId, comment.userId, feedId);
}
@Override
protected void onPostExecute(Boolean result) {
if (favouriteIconViewHolder.get() != null) {
if (result.booleanValue()) {
favouriteIconViewHolder.get().setImageResource(R.drawable.have_favourite);
if (userImage != null) {
ImageView favouriteImage = new ImageView(context);
favouriteImage.setTag(user.id);
userImage = UIUtils.roundCorners(userImage, 10f);
favouriteImage.setImageBitmap(userImage);
favouriteAvatarHolder.get().addView(favouriteImage);
}
String[] newArray = new String[comment.likingUsers.length + 1];
System.arraycopy(comment.likingUsers, 0, newArray, 0, comment.likingUsers.length);
newArray[newArray.length - 1] = userId;
comment.likingUsers = newArray;
Toast.makeText(context, R.string.comment_favourited, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, R.string.error_liking_comment, Toast.LENGTH_SHORT).show();
}
}
}
}

View file

@ -1,77 +0,0 @@
package com.newsblur.network;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.newsblur.R;
import com.newsblur.domain.Comment;
import com.newsblur.domain.UserDetails;
import com.newsblur.util.PrefsUtils;
import com.newsblur.view.FlowLayout;
public class UnLikeCommentTask extends AsyncTask<Void, Void, Boolean>{
private static final String TAG = "LikeCommentTask";
final WeakReference<ImageView> favouriteIconViewHolder;
private final APIManager apiManager;
private final String storyId;
private final Comment comment;
private final String feedId;
private final Context context;
private final String userId;
private WeakReference<FlowLayout> favouriteAvatarHolder;
private UserDetails user;
public UnLikeCommentTask(final Context context, final APIManager apiManager, final ImageView favouriteIcon, final FlowLayout favouriteAvatarContainer, final String storyId, final Comment comment, final String feedId, final String userId) {
this.apiManager = apiManager;
this.storyId = storyId;
this.comment = comment;
this.feedId = feedId;
this.context = context;
this.userId = userId;
favouriteIconViewHolder = new WeakReference<ImageView>(favouriteIcon);
favouriteAvatarHolder = new WeakReference<FlowLayout>(favouriteAvatarContainer);
user = PrefsUtils.getUserDetails(context);
}
@Override
protected Boolean doInBackground(Void... params) {
return apiManager.unFavouriteComment(storyId, comment.userId, feedId);
}
@Override
protected void onPostExecute(Boolean result) {
if (favouriteIconViewHolder.get() != null) {
if (result.booleanValue()) {
favouriteIconViewHolder.get().setImageResource(R.drawable.favourite);
View v = favouriteAvatarHolder.get().findViewWithTag(user.id);
favouriteAvatarHolder.get().removeView(v);
ArrayList<String> likingUsers = new ArrayList<String>();
for (String user : comment.likingUsers) {
if (!TextUtils.equals(user, userId) && TextUtils.isEmpty(user)) {
likingUsers.add(user);
}
}
String[] newArray = new String[likingUsers.size()];
likingUsers.toArray(newArray);
comment.likingUsers = newArray;
Toast.makeText(context, "Removed favourite", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Error removing favorite from comment", Toast.LENGTH_SHORT).show();
}
}
}
}

View file

@ -212,6 +212,22 @@ public class FeedUtils {
triggerSync(context);
}
public static void likeComment(Story story, String commentId, Context context) {
ReadingAction ra = ReadingAction.likeComment(story.id, commentId, story.feedId);
dbHelper.enqueueAction(ra);
ra.doLocal(dbHelper);
NbActivity.updateAllActivities(true);
triggerSync(context);
}
public static void unlikeComment(Story story, String commentId, Context context) {
ReadingAction ra = ReadingAction.unlikeComment(story.id, commentId, story.feedId);
dbHelper.enqueueAction(ra);
ra.doLocal(dbHelper);
NbActivity.updateAllActivities(true);
triggerSync(context);
}
public static FeedSet feedSetFromFolderName(String folderName) {
return FeedSet.folder(folderName, getFeedIdsRecursive(folderName));
}

View file

@ -19,7 +19,10 @@ public class ReadingAction {
MARK_UNREAD,
SAVE,
UNSAVE,
SHARE
SHARE,
REPLY,
LIKE_COMMENT,
UNLIKE_COMMENT
};
private ActionType type;
@ -30,7 +33,8 @@ public class ReadingAction {
private String storyId;
private String feedId;
private String sourceUserId;
private String comment;
private String commentText;
private String commentId;
private ReadingAction() {
; // must use helpers
@ -73,14 +77,32 @@ public class ReadingAction {
return ra;
}
public static ReadingAction shareStory(String hash, String storyId, String feedId, String sourceUserId, String comment) {
public static ReadingAction shareStory(String hash, String storyId, String feedId, String sourceUserId, String commentText) {
ReadingAction ra = new ReadingAction();
ra.type = ActionType.SHARE;
ra.storyHash = hash;
ra.storyId = storyId;
ra.feedId = feedId;
ra.sourceUserId = sourceUserId;
ra.comment = comment;
ra.commentText = commentText;
return ra;
}
public static ReadingAction likeComment(String storyId, String commentId, String feedId) {
ReadingAction ra = new ReadingAction();
ra.type = ActionType.LIKE_COMMENT;
ra.storyId = storyId;
ra.commentId = commentId;
ra.feedId = feedId;
return ra;
}
public static ReadingAction unlikeComment(String storyId, String commentId, String feedId) {
ReadingAction ra = new ReadingAction();
ra.type = ActionType.UNLIKE_COMMENT;
ra.storyId = storyId;
ra.commentId = commentId;
ra.feedId = feedId;
return ra;
}
@ -123,7 +145,21 @@ 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, comment);
values.put(DatabaseConstants.ACTION_COMMENT, commentText);
break;
case LIKE_COMMENT:
values.put(DatabaseConstants.ACTION_LIKE_COMMENT, 1);
values.put(DatabaseConstants.ACTION_STORY_ID, storyId);
values.put(DatabaseConstants.ACTION_FEED_ID, feedId);
values.put(DatabaseConstants.ACTION_COMMENT_ID, commentId);
break;
case UNLIKE_COMMENT:
values.put(DatabaseConstants.ACTION_UNLIKE_COMMENT, 1);
values.put(DatabaseConstants.ACTION_STORY_ID, storyId);
values.put(DatabaseConstants.ACTION_FEED_ID, feedId);
values.put(DatabaseConstants.ACTION_COMMENT_ID, commentId);
break;
default:
@ -166,7 +202,17 @@ 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.comment = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT));
ra.commentText = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT));
} 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));
ra.feedId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_FEED_ID));
ra.commentId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_ID));
} else if (c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_UNLIKE_COMMENT)) == 1) {
ra.type = ActionType.UNLIKE_COMMENT;
ra.storyId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_STORY_ID));
ra.feedId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_FEED_ID));
ra.commentId = c.getString(c.getColumnIndexOrThrow(DatabaseConstants.ACTION_COMMENT_ID));
} else {
throw new IllegalStateException("cannot deserialise uknown type of action.");
}
@ -197,7 +243,13 @@ public class ReadingAction {
return apiManager.markStoryAsUnstarred(storyHash);
case SHARE:
return apiManager.shareStory(storyId, feedId, comment, sourceUserId);
return apiManager.shareStory(storyId, feedId, commentText, sourceUserId);
case LIKE_COMMENT:
return apiManager.favouriteComment(storyId, commentId, feedId);
case UNLIKE_COMMENT:
return apiManager.unFavouriteComment(storyId, commentId, feedId);
default:
@ -234,6 +286,17 @@ public class ReadingAction {
case SHARE:
dbHelper.setStoryShared(storyHash);
if (!TextUtils.isEmpty(commentText)) {
dbHelper.insertUpdateComment(storyId, feedId, commentText);
}
break;
case LIKE_COMMENT:
// TODO
break;
case UNLIKE_COMMENT:
// TODO
break;
default: