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.
main
Vavassor 8 years ago
parent c18186f135
commit 9e49da64bf
  1. 9
      app/src/main/java/com/keylesspalace/tusky/AccountActivity.java
  2. 10
      app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java
  3. 11
      app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java
  4. 7
      app/src/main/java/com/keylesspalace/tusky/SFragment.java
  5. 3
      app/src/main/java/com/keylesspalace/tusky/StatusActionListener.java
  6. 20
      app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java
  7. 21
      app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java
  8. 24
      app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java

@ -18,6 +18,7 @@ package com.keylesspalace.tusky;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; 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.app.ActionBar;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -105,10 +105,11 @@ public class AccountActivity extends BaseActivity {
}; };
adapter.setPageTitles(pageTitles); adapter.setPageTitles(pageTitles);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager); ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, int pageMargin = getResources().getDimensionPixelSize(R.dimen.tab_page_margin);
getResources().getDisplayMetrics());
viewPager.setPageMargin(pageMargin); 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); viewPager.setAdapter(adapter);
tabLayout = (TabLayout) findViewById(R.id.tab_layout); tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);

@ -103,8 +103,7 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
FollowViewHolder holder = (FollowViewHolder) viewHolder; FollowViewHolder holder = (FollowViewHolder) viewHolder;
holder.setMessage(notification.getDisplayName(), notification.getUsername(), holder.setMessage(notification.getDisplayName(), notification.getUsername(),
notification.getAvatar()); notification.getAvatar());
holder.setupButtons(followListener, notification.getAccountId(), holder.setupButtons(followListener, notification.getAccountId());
notification.getUsername());
break; break;
} }
} }
@ -186,7 +185,7 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
} }
interface FollowListener { interface FollowListener {
void onViewAccount(String id, String username); void onViewAccount(String id);
void onFollow(String id); void onFollow(String id);
} }
@ -224,12 +223,11 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
avatar.setImageUrl(avatarUrl, VolleySingleton.getInstance(context).getImageLoader()); avatar.setImageUrl(avatarUrl, VolleySingleton.getInstance(context).getImageLoader());
} }
void setupButtons(final FollowListener listener, final String accountId, void setupButtons(final FollowListener listener, final String accountId) {
final String username) {
avatar.setOnClickListener(new View.OnClickListener() { avatar.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onViewAccount(accountId, username); listener.onViewAccount(accountId);
} }
}); });
follow.setOnClickListener(new View.OnClickListener() { follow.setOnClickListener(new View.OnClickListener() {

@ -257,15 +257,8 @@ public class NotificationsFragment extends SFragment implements
super.viewTag(tag); super.viewTag(tag);
} }
public void onViewAccount(String id, String username) { public void onViewAccount(String id) {
super.viewAccount(id, username); super.viewAccount(id);
}
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 onFollow(String id) { public void onFollow(String id) {

@ -267,18 +267,17 @@ public class SFragment extends Fragment {
startActivity(intent); startActivity(intent);
} }
protected void viewAccount(String id, String username) { protected void viewAccount(String id) {
Intent intent = new Intent(getContext(), AccountActivity.class); Intent intent = new Intent(getContext(), AccountActivity.class);
intent.putExtra("id", id); intent.putExtra("id", id);
intent.putExtra("username", username);
startActivity(intent); startActivity(intent);
} }
protected void openReportPage(String accountId, String accoundUsername, String statusId, protected void openReportPage(String accountId, String accountUsername, String statusId,
Spanned statusContent) { Spanned statusContent) {
Intent intent = new Intent(getContext(), ReportActivity.class); Intent intent = new Intent(getContext(), ReportActivity.class);
intent.putExtra("account_id", accountId); intent.putExtra("account_id", accountId);
intent.putExtra("account_username", accoundUsername); intent.putExtra("account_username", accountUsername);
intent.putExtra("status_id", statusId); intent.putExtra("status_id", statusId);
intent.putExtra("status_content", HtmlUtils.toHtml(statusContent)); intent.putExtra("status_content", HtmlUtils.toHtml(statusContent));
startActivity(intent); startActivity(intent);

@ -25,6 +25,5 @@ interface StatusActionListener {
void onViewMedia(String url, Status.MediaAttachment.Type type); void onViewMedia(String url, Status.MediaAttachment.Type type);
void onViewThread(int position); void onViewThread(int position);
void onViewTag(String tag); void onViewTag(String tag);
void onViewAccount(String id, String username); void onViewAccount(String id);
void onViewAccount(int position);
} }

@ -98,7 +98,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder {
displayName.setText(name); displayName.setText(name);
} }
void setUsername(String name) { private void setUsername(String name) {
Context context = username.getContext(); Context context = username.getContext();
String format = context.getString(R.string.status_username_format); String format = context.getString(R.string.status_username_format);
String usernameText = String.format(format, name); String usernameText = String.format(format, name);
@ -139,7 +139,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder {
ClickableSpan newSpan = new ClickableSpan() { ClickableSpan newSpan = new ClickableSpan() {
@Override @Override
public void onClick(View widget) { public void onClick(View widget) {
listener.onViewAccount(accountId, accountUsername); listener.onViewAccount(accountId);
} }
}; };
builder.removeSpan(span); builder.removeSpan(span);
@ -294,35 +294,35 @@ class StatusViewHolder extends RecyclerView.ViewHolder {
content.setVisibility(View.VISIBLE); 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() { avatar.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onViewAccount(position); listener.onViewAccount(accountId);
} }
}); });
replyButton.setOnClickListener(new View.OnClickListener() { replyButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onReply(position); listener.onReply(getAdapterPosition());
} }
}); });
reblogButton.setOnClickListener(new View.OnClickListener() { reblogButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onReblog(!reblogged, position); listener.onReblog(!reblogged, getAdapterPosition());
} }
}); });
favouriteButton.setOnClickListener(new View.OnClickListener() { favouriteButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onFavourite(!favourited, position); listener.onFavourite(!favourited, getAdapterPosition());
} }
}); });
moreButton.setOnClickListener(new View.OnClickListener() { moreButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { 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 /* 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() { View.OnClickListener viewThreadListener = new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onViewThread(position); listener.onViewThread(getAdapterPosition());
} }
}; };
content.setOnClickListener(viewThreadListener); content.setOnClickListener(viewThreadListener);
@ -361,7 +361,7 @@ class StatusViewHolder extends RecyclerView.ViewHolder {
if (!sensitive || attachments.length == 0) { if (!sensitive || attachments.length == 0) {
hideSensitiveMediaWarning(); hideSensitiveMediaWarning();
} }
setupButtons(listener, position); setupButtons(listener, status.getAccountId());
setRebloggingEnabled(status.getVisibility() != Status.Visibility.PRIVATE); setRebloggingEnabled(status.getVisibility() != Status.Visibility.PRIVATE);
if (status.getSpoilerText().isEmpty()) { if (status.getSpoilerText().isEmpty()) {
hideSpoilerText(); hideSpoilerText();

@ -312,20 +312,19 @@ public class TimelineFragment extends SFragment implements
} }
public void onViewTag(String tag) { public void onViewTag(String tag) {
super.viewTag(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) { public void onViewAccount(String id) {
Status status = adapter.getItem(position); if (kind == Kind.USER && hashtagOrId.equals(id)) {
Assert.expect(status != null); /* If already viewing an account page, then any requests to view that account page
if (status != null) { * should be ignored. */
String id = status.getAccountId(); return;
String username = status.getUsername();
super.viewAccount(id, username);
} }
super.viewAccount(id);
} }
} }

@ -20,7 +20,6 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -40,6 +39,7 @@ import java.util.List;
public class ViewThreadFragment extends SFragment implements StatusActionListener { public class ViewThreadFragment extends SFragment implements StatusActionListener {
private RecyclerView recyclerView; private RecyclerView recyclerView;
private ThreadAdapter adapter; private ThreadAdapter adapter;
private String thisThreadsStatusId;
public static ViewThreadFragment newInstance(String id) { public static ViewThreadFragment newInstance(String id) {
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
@ -62,7 +62,8 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
recyclerView.setLayoutManager(layoutManager); recyclerView.setLayoutManager(layoutManager);
DividerItemDecoration divider = new DividerItemDecoration( DividerItemDecoration divider = new DividerItemDecoration(
context, layoutManager.getOrientation()); 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); divider.setDrawable(drawable);
recyclerView.addItemDecoration(divider); recyclerView.addItemDecoration(divider);
adapter = new ThreadAdapter(this); adapter = new ThreadAdapter(this);
@ -71,6 +72,7 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
String id = getArguments().getString("id"); String id = getArguments().getString("id");
sendStatusRequest(id); sendStatusRequest(id);
sendThreadRequest(id); sendThreadRequest(id);
thisThreadsStatusId = id;
return rootView; return rootView;
} }
@ -159,21 +161,19 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
} }
public void onViewThread(int position) { 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) { public void onViewTag(String tag) {
super.viewTag(tag); super.viewTag(tag);
} }
public void onViewAccount(String id, String username) { public void onViewAccount(String id) {
super.viewAccount(id, username); super.viewAccount(id);
}
public void onViewAccount(int position) {
Status status = adapter.getItem(position);
String id = status.getAccountId();
String username = status.getUsername();
super.viewAccount(id, username);
} }
} }

Loading…
Cancel
Save