From 9e49da64bfceb9aeaa1ea05180590b18256a0bae Mon Sep 17 00:00:00 2001 From: Vavassor Date: Thu, 2 Mar 2017 19:25:35 -0500 Subject: [PATCH] Fixes two bugs: -One where deletion causes statuses to lose track of where they are in timelines, so subsequent deletion and other actions are performed on the wrong status. -It's was possible to infinitely open copies of the same thread, account page, and tag page by just continuously clicking on the status, avatar, or hash tag respectively. --- .../keylesspalace/tusky/AccountActivity.java | 9 +++---- .../com/keylesspalace/tusky/MainActivity.java | 2 +- .../tusky/NotificationsAdapter.java | 10 ++++---- .../tusky/NotificationsFragment.java | 11 ++------- .../com/keylesspalace/tusky/SFragment.java | 7 +++--- .../tusky/StatusActionListener.java | 3 +-- .../keylesspalace/tusky/StatusViewHolder.java | 20 ++++++++-------- .../keylesspalace/tusky/TimelineFragment.java | 21 ++++++++-------- .../tusky/ViewThreadFragment.java | 24 +++++++++---------- 9 files changed, 48 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java index a5faefe9a..dcb1f81a5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java @@ -18,6 +18,7 @@ package com.keylesspalace.tusky; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; @@ -27,7 +28,6 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import android.text.method.LinkMovementMethod; -import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -105,10 +105,11 @@ public class AccountActivity extends BaseActivity { }; adapter.setPageTitles(pageTitles); ViewPager viewPager = (ViewPager) findViewById(R.id.pager); - int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, - getResources().getDisplayMetrics()); + int pageMargin = getResources().getDimensionPixelSize(R.dimen.tab_page_margin); viewPager.setPageMargin(pageMargin); - viewPager.setPageMarginDrawable(R.drawable.tab_page_margin_dark); + Drawable pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable, + R.drawable.tab_page_margin_dark); + viewPager.setPageMarginDrawable(pageMarginDrawable); viewPager.setAdapter(adapter); tabLayout = (TabLayout) findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java index 38f90c93b..50c0463a1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java @@ -75,7 +75,7 @@ public class MainActivity extends BaseActivity { viewPager.setPageMargin(pageMargin); Drawable pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable, R.drawable.tab_page_margin_dark); - viewPager.setPageMarginDrawable(pageMarginDrawable); + viewPager.setPageMarginDrawable(pageMarginDrawable); viewPager.setAdapter(adapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java index 180c64b77..eecb1e33e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java @@ -103,8 +103,7 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe FollowViewHolder holder = (FollowViewHolder) viewHolder; holder.setMessage(notification.getDisplayName(), notification.getUsername(), notification.getAvatar()); - holder.setupButtons(followListener, notification.getAccountId(), - notification.getUsername()); + holder.setupButtons(followListener, notification.getAccountId()); break; } } @@ -186,7 +185,7 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe } interface FollowListener { - void onViewAccount(String id, String username); + void onViewAccount(String id); void onFollow(String id); } @@ -224,12 +223,11 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe avatar.setImageUrl(avatarUrl, VolleySingleton.getInstance(context).getImageLoader()); } - void setupButtons(final FollowListener listener, final String accountId, - final String username) { + void setupButtons(final FollowListener listener, final String accountId) { avatar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onViewAccount(accountId, username); + listener.onViewAccount(accountId); } }); follow.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java index 871754ce4..0aeded4df 100644 --- a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java @@ -257,15 +257,8 @@ public class NotificationsFragment extends SFragment implements super.viewTag(tag); } - public void onViewAccount(String id, String username) { - super.viewAccount(id, username); - } - - public void onViewAccount(int position) { - Status status = adapter.getItem(position).getStatus(); - String id = status.getAccountId(); - String username = status.getUsername(); - super.viewAccount(id, username); + public void onViewAccount(String id) { + super.viewAccount(id); } public void onFollow(String id) { diff --git a/app/src/main/java/com/keylesspalace/tusky/SFragment.java b/app/src/main/java/com/keylesspalace/tusky/SFragment.java index 73bafe8b3..549356acc 100644 --- a/app/src/main/java/com/keylesspalace/tusky/SFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/SFragment.java @@ -267,18 +267,17 @@ public class SFragment extends Fragment { startActivity(intent); } - protected void viewAccount(String id, String username) { + protected void viewAccount(String id) { Intent intent = new Intent(getContext(), AccountActivity.class); intent.putExtra("id", id); - intent.putExtra("username", username); startActivity(intent); } - protected void openReportPage(String accountId, String accoundUsername, String statusId, + protected void openReportPage(String accountId, String accountUsername, String statusId, Spanned statusContent) { Intent intent = new Intent(getContext(), ReportActivity.class); intent.putExtra("account_id", accountId); - intent.putExtra("account_username", accoundUsername); + intent.putExtra("account_username", accountUsername); intent.putExtra("status_id", statusId); intent.putExtra("status_content", HtmlUtils.toHtml(statusContent)); startActivity(intent); diff --git a/app/src/main/java/com/keylesspalace/tusky/StatusActionListener.java b/app/src/main/java/com/keylesspalace/tusky/StatusActionListener.java index b8baf0d39..abf0a5b6d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/StatusActionListener.java +++ b/app/src/main/java/com/keylesspalace/tusky/StatusActionListener.java @@ -25,6 +25,5 @@ interface StatusActionListener { void onViewMedia(String url, Status.MediaAttachment.Type type); void onViewThread(int position); void onViewTag(String tag); - void onViewAccount(String id, String username); - void onViewAccount(int position); + void onViewAccount(String id); } diff --git a/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java index 2c0a6ace1..dd72a5998 100644 --- a/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java @@ -98,7 +98,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder { displayName.setText(name); } - void setUsername(String name) { + private void setUsername(String name) { Context context = username.getContext(); String format = context.getString(R.string.status_username_format); String usernameText = String.format(format, name); @@ -139,7 +139,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder { ClickableSpan newSpan = new ClickableSpan() { @Override public void onClick(View widget) { - listener.onViewAccount(accountId, accountUsername); + listener.onViewAccount(accountId); } }; builder.removeSpan(span); @@ -294,35 +294,35 @@ class StatusViewHolder extends RecyclerView.ViewHolder { content.setVisibility(View.VISIBLE); } - private void setupButtons(final StatusActionListener listener, final int position) { + private void setupButtons(final StatusActionListener listener, final String accountId) { avatar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onViewAccount(position); + listener.onViewAccount(accountId); } }); replyButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onReply(position); + listener.onReply(getAdapterPosition()); } }); reblogButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onReblog(!reblogged, position); + listener.onReblog(!reblogged, getAdapterPosition()); } }); favouriteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onFavourite(!favourited, position); + listener.onFavourite(!favourited, getAdapterPosition()); } }); moreButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - listener.onMore(v, position); + listener.onMore(v, getAdapterPosition()); } }); /* Even though the content TextView is a child of the container, it won't respond to clicks @@ -332,7 +332,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder { View.OnClickListener viewThreadListener = new View.OnClickListener() { @Override public void onClick(View v) { - listener.onViewThread(position); + listener.onViewThread(getAdapterPosition()); } }; content.setOnClickListener(viewThreadListener); @@ -361,7 +361,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder { if (!sensitive || attachments.length == 0) { hideSensitiveMediaWarning(); } - setupButtons(listener, position); + setupButtons(listener, status.getAccountId()); setRebloggingEnabled(status.getVisibility() != Status.Visibility.PRIVATE); if (status.getSpoilerText().isEmpty()) { hideSpoilerText(); diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java index 142bd254e..0f41e534e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java @@ -312,20 +312,19 @@ public class TimelineFragment extends SFragment implements } public void onViewTag(String tag) { + if (kind == Kind.TAG && hashtagOrId.equals(tag)) { + // If already viewing a tag page, then ignore any request to view that tag again. + return; + } super.viewTag(tag); } - public void onViewAccount(String id, String username) { - super.viewAccount(id, username); - } - - public void onViewAccount(int position) { - Status status = adapter.getItem(position); - Assert.expect(status != null); - if (status != null) { - String id = status.getAccountId(); - String username = status.getUsername(); - super.viewAccount(id, username); + public void onViewAccount(String id) { + if (kind == Kind.USER && hashtagOrId.equals(id)) { + /* If already viewing an account page, then any requests to view that account page + * should be ignored. */ + return; } + super.viewAccount(id); } } diff --git a/app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java b/app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java index 546ab74d6..9389c0bfd 100644 --- a/app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java @@ -20,7 +20,6 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; -import android.support.v4.content.ContextCompat; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -40,6 +39,7 @@ import java.util.List; public class ViewThreadFragment extends SFragment implements StatusActionListener { private RecyclerView recyclerView; private ThreadAdapter adapter; + private String thisThreadsStatusId; public static ViewThreadFragment newInstance(String id) { Bundle arguments = new Bundle(); @@ -62,7 +62,8 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene recyclerView.setLayoutManager(layoutManager); DividerItemDecoration divider = new DividerItemDecoration( context, layoutManager.getOrientation()); - Drawable drawable = ContextCompat.getDrawable(context, R.drawable.status_divider_dark); + Drawable drawable = ThemeUtils.getDrawable(context, R.attr.status_divider_drawable, + R.drawable.status_divider_dark); divider.setDrawable(drawable); recyclerView.addItemDecoration(divider); adapter = new ThreadAdapter(this); @@ -71,6 +72,7 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene String id = getArguments().getString("id"); sendStatusRequest(id); sendThreadRequest(id); + thisThreadsStatusId = id; return rootView; } @@ -159,21 +161,19 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene } public void onViewThread(int position) { - super.viewThread(adapter.getItem(position)); + Status status = adapter.getItem(position); + if (thisThreadsStatusId.equals(status.getId())) { + // If already viewing this thread, don't reopen it. + return; + } + super.viewThread(status); } public void onViewTag(String tag) { super.viewTag(tag); } - public void onViewAccount(String id, String username) { - super.viewAccount(id, username); - } - - public void onViewAccount(int position) { - Status status = adapter.getItem(position); - String id = status.getAccountId(); - String username = status.getUsername(); - super.viewAccount(id, username); + public void onViewAccount(String id) { + super.viewAccount(id); } }