| package org.wordpress.android.ui.reader.services; |
| |
| import android.app.Service; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.os.IBinder; |
| |
| import com.android.volley.VolleyError; |
| import com.wordpress.rest.RestRequest; |
| |
| import org.json.JSONArray; |
| import org.json.JSONObject; |
| import org.wordpress.android.WordPress; |
| import org.wordpress.android.datasets.ReaderCommentTable; |
| import org.wordpress.android.datasets.ReaderDatabase; |
| import org.wordpress.android.datasets.ReaderLikeTable; |
| import org.wordpress.android.datasets.ReaderUserTable; |
| import org.wordpress.android.models.ReaderComment; |
| import org.wordpress.android.models.ReaderCommentList; |
| import org.wordpress.android.models.ReaderUserList; |
| import org.wordpress.android.ui.reader.ReaderConstants; |
| import org.wordpress.android.ui.reader.ReaderEvents; |
| import org.wordpress.android.ui.reader.actions.ReaderActions; |
| import org.wordpress.android.ui.reader.actions.ReaderActions.UpdateResult; |
| import org.wordpress.android.ui.reader.actions.ReaderActions.UpdateResultListener; |
| import org.wordpress.android.util.AppLog; |
| import org.wordpress.android.util.JSONUtils; |
| |
| import de.greenrobot.event.EventBus; |
| |
| public class ReaderCommentService extends Service { |
| |
| private static final String ARG_POST_ID = "post_id"; |
| private static final String ARG_BLOG_ID = "blog_id"; |
| private static final String ARG_COMMENT_ID = "comment_id"; |
| private static final String ARG_NEXT_PAGE = "next_page"; |
| |
| private static int mCurrentPage; |
| |
| public static void startService(Context context, long blogId, long postId, boolean requestNextPage) { |
| if (context == null) return; |
| |
| Intent intent = new Intent(context, ReaderCommentService.class); |
| intent.putExtra(ARG_BLOG_ID, blogId); |
| intent.putExtra(ARG_POST_ID, postId); |
| intent.putExtra(ARG_NEXT_PAGE, requestNextPage); |
| context.startService(intent); |
| } |
| |
| // Requests comments until the passed commentId is found |
| public static void startServiceForComment(Context context, long blogId, long postId, long commentId) { |
| if (context == null) return; |
| |
| Intent intent = new Intent(context, ReaderCommentService.class); |
| intent.putExtra(ARG_BLOG_ID, blogId); |
| intent.putExtra(ARG_POST_ID, postId); |
| intent.putExtra(ARG_COMMENT_ID, commentId); |
| context.startService(intent); |
| } |
| |
| public static void stopService(Context context) { |
| if (context == null) return; |
| |
| Intent intent = new Intent(context, ReaderCommentService.class); |
| context.stopService(intent); |
| } |
| |
| @Override |
| public IBinder onBind(Intent intent) { |
| return null; |
| } |
| |
| @Override |
| public void onCreate() { |
| super.onCreate(); |
| AppLog.i(AppLog.T.READER, "reader comment service > created"); |
| } |
| |
| @Override |
| public void onDestroy() { |
| AppLog.i(AppLog.T.READER, "reader comment service > destroyed"); |
| super.onDestroy(); |
| } |
| |
| @Override |
| public int onStartCommand(Intent intent, int flags, int startId) { |
| if (intent == null) { |
| return START_NOT_STICKY; |
| } |
| |
| EventBus.getDefault().post(new ReaderEvents.UpdateCommentsStarted()); |
| |
| final long blogId = intent.getLongExtra(ARG_BLOG_ID, 0); |
| final long postId = intent.getLongExtra(ARG_POST_ID, 0); |
| final long commentId = intent.getLongExtra(ARG_COMMENT_ID, 0); |
| boolean requestNextPage = intent.getBooleanExtra(ARG_NEXT_PAGE, false); |
| |
| if (requestNextPage) { |
| int prevPage = ReaderCommentTable.getLastPageNumberForPost(blogId, postId); |
| mCurrentPage = prevPage + 1; |
| } else { |
| mCurrentPage = 1; |
| } |
| |
| updateCommentsForPost(blogId, postId, mCurrentPage, new UpdateResultListener() { |
| @Override |
| public void onUpdateResult(UpdateResult result) { |
| if (commentId > 0) { |
| if (ReaderCommentTable.commentExists(blogId, postId, commentId) || !result.isNewOrChanged()) { |
| EventBus.getDefault().post(new ReaderEvents.UpdateCommentsEnded(result)); |
| stopSelf(); |
| } else { |
| // Comment not found yet, request the next page |
| mCurrentPage++; |
| updateCommentsForPost(blogId, postId, mCurrentPage, this); |
| } |
| } else { |
| EventBus.getDefault().post(new ReaderEvents.UpdateCommentsEnded(result)); |
| stopSelf(); |
| } |
| } |
| }); |
| |
| return START_NOT_STICKY; |
| } |
| |
| private static void updateCommentsForPost(final long blogId, |
| final long postId, |
| final int pageNumber, |
| final ReaderActions.UpdateResultListener resultListener) { |
| String path = "sites/" + blogId + "/posts/" + postId + "/replies/" |
| + "?number=" + Integer.toString(ReaderConstants.READER_MAX_COMMENTS_TO_REQUEST) |
| + "&meta=likes" |
| + "&hierarchical=true" |
| + "&order=ASC" |
| + "&page=" + pageNumber; |
| |
| RestRequest.Listener listener = new RestRequest.Listener() { |
| @Override |
| public void onResponse(JSONObject jsonObject) { |
| handleUpdateCommentsResponse(jsonObject, blogId, pageNumber, resultListener); |
| } |
| }; |
| RestRequest.ErrorListener errorListener = new RestRequest.ErrorListener() { |
| @Override |
| public void onErrorResponse(VolleyError volleyError) { |
| AppLog.e(AppLog.T.READER, volleyError); |
| resultListener.onUpdateResult(ReaderActions.UpdateResult.FAILED); |
| } |
| }; |
| AppLog.d(AppLog.T.READER, "updating comments"); |
| WordPress.getRestClientUtilsV1_1().get(path, null, null, listener, errorListener); |
| } |
| private static void handleUpdateCommentsResponse(final JSONObject jsonObject, |
| final long blogId, |
| final int pageNumber, |
| final ReaderActions.UpdateResultListener resultListener) { |
| if (jsonObject == null) { |
| resultListener.onUpdateResult(ReaderActions.UpdateResult.FAILED); |
| return; |
| } |
| |
| new Thread() { |
| @Override |
| public void run() { |
| final boolean hasNewComments; |
| |
| ReaderDatabase.getWritableDb().beginTransaction(); |
| try { |
| ReaderCommentList serverComments = new ReaderCommentList(); |
| JSONArray jsonCommentList = jsonObject.optJSONArray("comments"); |
| if (jsonCommentList != null) { |
| for (int i = 0; i < jsonCommentList.length(); i++) { |
| JSONObject jsonComment = jsonCommentList.optJSONObject(i); |
| |
| // extract this comment and add it to the list |
| ReaderComment comment = ReaderComment.fromJson(jsonComment, blogId); |
| comment.pageNumber = pageNumber; |
| serverComments.add(comment); |
| |
| // extract and save likes for this comment |
| JSONObject jsonLikes = JSONUtils.getJSONChild(jsonComment, "meta/data/likes"); |
| if (jsonLikes != null) { |
| ReaderUserList likingUsers = ReaderUserList.fromJsonLikes(jsonLikes); |
| ReaderUserTable.addOrUpdateUsers(likingUsers); |
| ReaderLikeTable.setLikesForComment(comment, likingUsers.getUserIds()); |
| } |
| } |
| } |
| |
| hasNewComments = (serverComments.size() > 0); |
| |
| // save to db regardless of whether any are new so changes to likes are stored |
| ReaderCommentTable.addOrUpdateComments(serverComments); |
| ReaderDatabase.getWritableDb().setTransactionSuccessful(); |
| } finally { |
| ReaderDatabase.getWritableDb().endTransaction(); |
| } |
| |
| ReaderActions.UpdateResult result = |
| (hasNewComments ? ReaderActions.UpdateResult.HAS_NEW : ReaderActions.UpdateResult.UNCHANGED); |
| resultListener.onUpdateResult(result); |
| } |
| }.start(); |
| } |
| } |