From 0a32c588018e7e10ec0d13edfa46d9a37557b420 Mon Sep 17 00:00:00 2001 From: Vavassor Date: Sun, 26 Feb 2017 20:14:13 -0500 Subject: [PATCH] Follow notifications now allow you to view the account that followed and follow back from the notification timeline. --- .../com/keylesspalace/tusky/Notification.java | 27 ++++- .../tusky/NotificationsAdapter.java | 54 ++++++++- .../tusky/NotificationsFragment.java | 9 +- .../com/keylesspalace/tusky/SFragment.java | 2 +- app/src/main/res/layout/item_follow.xml | 107 ++++++++++++++---- 5 files changed, 172 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/Notification.java b/app/src/main/java/com/keylesspalace/tusky/Notification.java index 83aee6c4..f7691172 100644 --- a/app/src/main/java/com/keylesspalace/tusky/Notification.java +++ b/app/src/main/java/com/keylesspalace/tusky/Notification.java @@ -34,13 +34,20 @@ class Notification { private Type type; private String id; private String displayName; + private String username; + private String avatar; + private String accountId; /** Which of the user's statuses has been mentioned, reblogged, or favourited. */ private Status status; - private Notification(Type type, String id, String displayName) { + private Notification(Type type, String id, String displayName, String username, String avatar, + String accountId) { this.type = type; this.id = id; this.displayName = displayName; + this.username = username; + this.avatar = avatar; + this.accountId = accountId; } Type getType() { @@ -55,6 +62,18 @@ class Notification { return displayName; } + String getUsername() { + return username; + } + + String getAvatar() { + return avatar; + } + + String getAccountId() { + return accountId; + } + @Nullable Status getStatus() { return status; } @@ -81,7 +100,11 @@ class Notification { if (displayName.isEmpty()) { displayName = account.getString("username"); } - Notification notification = new Notification(type, id, displayName); + String username = account.getString("acct"); + String avatar = account.getString("avatar"); + String accountId = account.getString("id"); + Notification notification = new Notification(type, id, displayName, username, avatar, + accountId); if (notification.hasStatusType()) { JSONObject statusObject = object.getJSONObject("status"); Status status = Status.parse(statusObject, false); diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java index 9e1e1390..180c64b7 100644 --- a/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsAdapter.java @@ -21,9 +21,12 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import com.android.volley.toolbox.NetworkImageView; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -36,14 +39,16 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe private List notifications; private StatusActionListener statusListener; + private FollowListener followListener; private FooterActionListener footerListener; private FooterViewHolder.State footerState; - NotificationsAdapter(StatusActionListener statusListener, + NotificationsAdapter(StatusActionListener statusListener, FollowListener followListener, FooterActionListener footerListener) { super(); notifications = new ArrayList<>(); this.statusListener = statusListener; + this.followListener = followListener; this.footerListener = footerListener; footerState = FooterViewHolder.State.LOADING; } @@ -96,7 +101,10 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe } case FOLLOW: { FollowViewHolder holder = (FollowViewHolder) viewHolder; - holder.setMessage(notification.getDisplayName()); + holder.setMessage(notification.getDisplayName(), notification.getUsername(), + notification.getAvatar()); + holder.setupButtons(followListener, notification.getAccountId(), + notification.getUsername()); break; } } @@ -177,19 +185,59 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe footerState = state; } + interface FollowListener { + void onViewAccount(String id, String username); + void onFollow(String id); + } + private static class FollowViewHolder extends RecyclerView.ViewHolder { private TextView message; + private TextView usernameView; + private TextView displayNameView; + private NetworkImageView avatar; + private Button follow; FollowViewHolder(View itemView) { super(itemView); message = (TextView) itemView.findViewById(R.id.notification_text); + usernameView = (TextView) itemView.findViewById(R.id.notification_username); + displayNameView = (TextView) itemView.findViewById(R.id.notification_display_name); + avatar = (NetworkImageView) itemView.findViewById(R.id.notification_avatar); + avatar.setDefaultImageResId(R.drawable.avatar_default); + avatar.setErrorImageResId(R.drawable.avatar_error); + follow = (Button) itemView.findViewById(R.id.notification_follow_button); } - void setMessage(String displayName) { + void setMessage(String displayName, String username, String avatarUrl) { Context context = message.getContext(); + String format = context.getString(R.string.notification_follow_format); String wholeMessage = String.format(format, displayName); message.setText(wholeMessage); + + format = context.getString(R.string.status_username_format); + String wholeUsername = String.format(format, username); + usernameView.setText(wholeUsername); + + displayNameView.setText(displayName); + + avatar.setImageUrl(avatarUrl, VolleySingleton.getInstance(context).getImageLoader()); + } + + void setupButtons(final FollowListener listener, final String accountId, + final String username) { + avatar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onViewAccount(accountId, username); + } + }); + follow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onFollow(accountId); + } + }); } } diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java index e18894ff..871754ce 100644 --- a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java @@ -41,7 +41,8 @@ import java.util.List; import java.util.Map; public class NotificationsFragment extends SFragment implements - SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener { + SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener, + NotificationsAdapter.FollowListener { private static final String TAG = "Notifications"; // logging tag and Volley request tag private SwipeRefreshLayout swipeRefreshLayout; @@ -98,7 +99,7 @@ public class NotificationsFragment extends SFragment implements } }; recyclerView.addOnScrollListener(scrollListener); - adapter = new NotificationsAdapter(this, this); + adapter = new NotificationsAdapter(this, this, this); recyclerView.setAdapter(adapter); TabLayout layout = (TabLayout) getActivity().findViewById(R.id.tab_layout); @@ -266,4 +267,8 @@ public class NotificationsFragment extends SFragment implements String username = status.getUsername(); super.viewAccount(id, username); } + + public void onFollow(String id) { + super.follow(id); + } } diff --git a/app/src/main/java/com/keylesspalace/tusky/SFragment.java b/app/src/main/java/com/keylesspalace/tusky/SFragment.java index ede25fbe..e3f4cb40 100644 --- a/app/src/main/java/com/keylesspalace/tusky/SFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/SFragment.java @@ -161,7 +161,7 @@ public class SFragment extends Fragment { }, null); } - private void follow(String id) { + protected void follow(String id) { String endpoint = String.format(getString(R.string.endpoint_follow), id); postRequest(endpoint); } diff --git a/app/src/main/res/layout/item_follow.xml b/app/src/main/res/layout/item_follow.xml index 30a8730d..ddc9a0ca 100644 --- a/app/src/main/res/layout/item_follow.xml +++ b/app/src/main/res/layout/item_follow.xml @@ -1,25 +1,94 @@ - + + android:layout_height="wrap_content" + android:orientation="vertical"> - - - + android:layout_height="wrap_content"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + +