Skip to content

Commit

Permalink
Merge pull request #6424 from wordpress-mobile/feature/async-error-sc…
Browse files Browse the repository at this point in the history
…roll-to-post

Async media: Scroll to failed post from error notifications
  • Loading branch information
mzorz authored Jul 31, 2017
2 parents 2483fef + fece2bf commit b0ddcf3
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.wordpress.android.ui.posts;

import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;

import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.fluxc.model.PostModel;
import org.wordpress.android.fluxc.model.SiteModel;
import org.wordpress.android.fluxc.store.PostStore;
import org.wordpress.android.fluxc.store.SiteStore;
import org.wordpress.android.ui.ActivityId;
import org.wordpress.android.ui.RequestCodes;
Expand All @@ -21,13 +21,14 @@

public class PostsListActivity extends AppCompatActivity {
public static final String EXTRA_VIEW_PAGES = "viewPages";
public static final String EXTRA_ERROR_MSG = "errorMessage";
public static final String EXTRA_TARGET_POST_LOCAL_ID = "targetPostLocalId";

private boolean mIsPage = false;
private PostsListFragment mPostList;
private SiteModel mSite;

@Inject SiteStore mSiteStore;
@Inject PostStore mPostStore;

@Override
public void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -89,10 +90,19 @@ private void handleIntent(Intent intent) {
actionBar.setDisplayHomeAsUpEnabled(true);
}

PostModel targetPost = null;
int targetPostId = intent.getIntExtra(EXTRA_TARGET_POST_LOCAL_ID, 0);
if (targetPostId > 0) {
targetPost = mPostStore.getPostByLocalPostId(intent.getIntExtra(EXTRA_TARGET_POST_LOCAL_ID, 0));
if (targetPost == null) {
ToastUtils.showToast(this, R.string.error_post_does_not_exist);
}
}

mPostList = (PostsListFragment) getFragmentManager().findFragmentByTag(PostsListFragment.TAG);
if (mPostList == null || siteHasChanged || pageHasChanged) {
if (mPostList == null || siteHasChanged || pageHasChanged || targetPost != null) {
PostsListFragment oldFragment = mPostList;
mPostList = PostsListFragment.newInstance(mSite, mIsPage);
mPostList = PostsListFragment.newInstance(mSite, mIsPage, targetPost);
if (oldFragment == null) {
getFragmentManager().beginTransaction()
.add(R.id.post_list_container, mPostList, PostsListFragment.TAG)
Expand All @@ -103,8 +113,6 @@ private void handleIntent(Intent intent) {
.commit();
}
}

showErrorDialogIfNeeded(intent.getExtras());
}

@Override
Expand All @@ -122,30 +130,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}

/**
* intent extras will contain error info if this activity was started from an
* upload error notification
*/
private void showErrorDialogIfNeeded(Bundle extras) {
if (extras == null || !extras.containsKey(EXTRA_ERROR_MSG) || isFinishing()) {
return;
}

final String errorMessage = extras.getString(EXTRA_ERROR_MSG);

if (TextUtils.isEmpty(errorMessage)) {
return;
}

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getResources().getText(R.string.error))
.setMessage(errorMessage)
.setPositiveButton(android.R.string.ok, null)
.setCancelable(true);

builder.create().show();
}

public boolean isRefreshing() {
return mPostList.isRefreshing();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -84,6 +86,7 @@ public class PostsListFragment extends Fragment

private boolean mCanLoadMorePosts = true;
private boolean mIsPage;
private PostModel mTargetPost;
private boolean mIsFetchingPosts;
private boolean mShouldCancelPendingDraftNotification = false;
private int mPostIdForPostToBeDeleted = 0;
Expand All @@ -96,11 +99,14 @@ public class PostsListFragment extends Fragment
@Inject PostStore mPostStore;
@Inject Dispatcher mDispatcher;

public static PostsListFragment newInstance(SiteModel site, boolean isPage) {
public static PostsListFragment newInstance(SiteModel site, boolean isPage, @Nullable PostModel targetPost) {
PostsListFragment fragment = new PostsListFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(WordPress.SITE, site);
bundle.putBoolean(PostsListActivity.EXTRA_VIEW_PAGES, isPage);
if (targetPost != null) {
bundle.putInt(PostsListActivity.EXTRA_TARGET_POST_LOCAL_ID, targetPost.getId());
}
fragment.setArguments(bundle);
return fragment;
}
Expand Down Expand Up @@ -129,18 +135,23 @@ private void updateSiteOrFinishActivity(Bundle savedInstanceState) {
if (getArguments() != null) {
mSite = (SiteModel) getArguments().getSerializable(WordPress.SITE);
mIsPage = getArguments().getBoolean(PostsListActivity.EXTRA_VIEW_PAGES);
mTargetPost = mPostStore.getPostByLocalPostId(
getArguments().getInt(PostsListActivity.EXTRA_TARGET_POST_LOCAL_ID));
} else {
mSite = (SiteModel) getActivity().getIntent().getSerializableExtra(WordPress.SITE);
mIsPage = getActivity().getIntent().getBooleanExtra(PostsListActivity.EXTRA_VIEW_PAGES, false);
mTargetPost = mPostStore.getPostByLocalPostId(
getActivity().getIntent().getIntExtra(PostsListActivity.EXTRA_TARGET_POST_LOCAL_ID, 0));
}
} else {
mSite = (SiteModel) savedInstanceState.getSerializable(WordPress.SITE);
mIsPage = savedInstanceState.getBoolean(PostsListActivity.EXTRA_VIEW_PAGES);
mTargetPost = mPostStore.getPostByLocalPostId(
savedInstanceState.getInt(PostsListActivity.EXTRA_TARGET_POST_LOCAL_ID));
}

if (mSite == null) {
ToastUtils.showToast(getActivity(), R.string.blog_not_found,
ToastUtils.Duration.SHORT);
ToastUtils.showToast(getActivity(), R.string.blog_not_found, ToastUtils.Duration.SHORT);
getActivity().finish();
}
}
Expand Down Expand Up @@ -409,6 +420,36 @@ public void onPostsLoaded(int postCount) {
} else if (postCount > 0) {
hideEmptyView();
}

// If the activity was given a target post, and this is the first time posts are loaded, scroll to that post
if (mTargetPost != null) {
if (mPostsListAdapter != null) {
final int position = mPostsListAdapter.getPositionForPost(mTargetPost);
if (position > -1) {
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getActivity()) {
private static final int SCROLL_OFFSET_DP = 23;

@Override
protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}

@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd,
int snapPreference) {
// Assume SNAP_TO_START, and offset the scroll, so the bottom of the above post shows
int offsetPx = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, SCROLL_OFFSET_DP, getResources().getDisplayMetrics());
return boxStart - viewStart + offsetPx;
}
};

smoothScroller.setTargetPosition(position);
mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
}
}
mTargetPost = null;
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,10 @@ public void onAnimationEnd(Animator animation) {
animOut.start();
}

public int getPositionForPost(PostModel post) {
return PostUtils.indexOfPostInList(post, mPosts);
}

public void loadPosts(LoadMode mode) {
if (mIsLoadingPosts) {
AppLog.d(AppLog.T.POSTS, "post adapter > already loading posts");
Expand All @@ -642,7 +646,7 @@ public void loadPosts(LoadMode mode) {

public void updateProgressForPost(@NonNull PostModel post) {
if (mRecyclerView != null) {
int position = PostUtils.indexOfPostInList(post, mPosts);
int position = getPositionForPost(post);
if (position > -1) {
RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(position);
if (viewHolder instanceof PostViewHolder) {
Expand All @@ -661,7 +665,7 @@ public void updateProgressForPost(@NonNull PostModel post) {
public void hidePost(PostModel post) {
mHiddenPosts.add(post);

int position = PostUtils.indexOfPostInList(post, mPosts);
int position = getPositionForPost(post);
if (position > -1) {
mPosts.remove(position);
if (mPosts.size() > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void updateNotificationError(PostModel post, SiteModel site, String errorMessage
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.putExtra(WordPress.SITE, site);
notificationIntent.putExtra(PostsListActivity.EXTRA_VIEW_PAGES, post.isPage());
notificationIntent.putExtra(PostsListActivity.EXTRA_ERROR_MSG, errorMessage);
notificationIntent.putExtra(PostsListActivity.EXTRA_TARGET_POST_LOCAL_ID, post.getId());
notificationIntent.setAction(String.valueOf(notificationId));

PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
Expand Down
1 change: 1 addition & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@
<string name="error_media_save">Unable to save media</string>
<string name="error_media_canceled">Uploading media were canceled</string>
<string name="error_media_recover">We were unable to upload this post\'s media. Please edit the post to try again.</string>
<string name="error_post_does_not_exist">This post no longer exists</string>
<string name="error_blog_hidden">This blog is hidden and couldn\'t be loaded. Enable it again in settings and try again.</string>
<string name="fatal_db_error">An error occurred while creating the app database. Try reinstalling the app.</string>
<string name="error_copy_to_clipboard">An error occurred while copying text to clipboard</string>
Expand Down

0 comments on commit b0ddcf3

Please sign in to comment.