From a888ae84355fe7fe3a936ce8077b3ac0ba8bb970 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Mon, 29 Jun 2020 16:42:43 +0800 Subject: Show all the messages in ViewPrivateMessagesActivity. --- .../infinityforreddit/Activity/BaseActivity.java | 2 +- .../Activity/ViewPrivateMessagesActivity.java | 33 ++++- .../Adapter/MessageRecyclerViewAdapter.java | 15 +- .../PrivateMessagesDetailRecyclerViewAdapter.java | 164 +++++++++++++++++++++ .../infinityforreddit/FetchMessages.java | 2 + .../docilealligator/infinityforreddit/Message.java | 7 + .../res/layout/activity_view_private_messages.xml | 3 +- 7 files changed, 211 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java (limited to 'app/src/main') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java index 6f24bc3f..4212fd6e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java @@ -295,4 +295,4 @@ public abstract class BaseActivity extends AppCompatActivity { fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorPrimaryLightTheme())); fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor())); } -} +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java index 0d666658..1a98eec0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java @@ -4,9 +4,11 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; +import android.view.MenuItem; import android.view.Window; import android.view.WindowManager; +import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.recyclerview.widget.LinearLayoutManager; @@ -17,14 +19,13 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.r0adkll.slidr.Slidr; -import java.util.ArrayList; - import javax.inject.Inject; import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.Adapter.PrivateMessagesDetailRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.Infinity; @@ -36,8 +37,7 @@ import retrofit2.Retrofit; public class ViewPrivateMessagesActivity extends BaseActivity implements ActivityToolbarInterface { - public static final String EXTRA_PRIVATE_MESSAGES = "EPM"; - public static final String EXTRA_SENDER_USERNAME = "ESU"; + public static final String EXTRA_PRIVATE_MESSAGE = "EPM"; private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; private static final String ACCESS_TOKEN_STATE = "ATS"; @BindView(R.id.coordinator_layout_view_private_messages_activity) @@ -63,7 +63,8 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit @Inject CustomThemeWrapper mCustomThemeWrapper; private LinearLayoutManager mLinearLayoutManager; - private ArrayList privateMessages; + private PrivateMessagesDetailRecyclerViewAdapter mAdapter; + private Message privateMessage; private boolean mNullAccessToken = false; private String mAccessToken; @@ -96,6 +97,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit int navBarHeight = getNavBarHeight(); if (navBarHeight > 0) { + mRecyclerView.setPadding(0, 0, 0, navBarHeight); CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFab.getLayoutParams(); params.bottomMargin = navBarHeight; mFab.setLayoutParams(params); @@ -104,9 +106,11 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit } Intent intent = getIntent(); - privateMessages = intent.getParcelableArrayListExtra(EXTRA_PRIVATE_MESSAGES); + privateMessage = intent.getParcelableExtra(EXTRA_PRIVATE_MESSAGE); - mToolbar.setTitle(intent.getStringExtra(EXTRA_SENDER_USERNAME)); + if (privateMessage != null) { + mToolbar.setTitle(privateMessage.getTitle()); + } setSupportActionBar(mToolbar); setToolbarGoToTop(mToolbar); @@ -136,7 +140,22 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit } private void bindView() { + mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, privateMessage, mCustomThemeWrapper); + mLinearLayoutManager = new LinearLayoutManager(this); + mLinearLayoutManager.setReverseLayout(true); + mLinearLayoutManager.setStackFromEnd(true); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + mRecyclerView.setAdapter(mAdapter); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java index 4deefed2..d3f010da 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java @@ -102,8 +102,13 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter { - if (message.getContext() != null && !message.getContext().equals("")) { + if (mMessageType == FetchMessages.MESSAGE_TYPE_NOTIFICATION + && message.getContext() != null && !message.getContext().equals("")) { Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); Intent intent = new Intent(mContext, LinkResolverActivity.class); intent.setData(uri); mContext.startActivity(intent); } else if (mMessageType == FetchMessages.MESSAGE_TYPE_PRIVATE_MESSAGE) { Intent intent = new Intent(mContext, ViewPrivateMessagesActivity.class); - intent.putExtra(ViewPrivateMessagesActivity.EXTRA_SENDER_USERNAME, message.getAuthor()); - intent.putExtra(ViewPrivateMessagesActivity.EXTRA_PRIVATE_MESSAGES, message.getReplies()); + intent.putExtra(ViewPrivateMessagesActivity.EXTRA_PRIVATE_MESSAGE, message); mContext.startActivity(intent); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java new file mode 100644 index 00000000..821d0e08 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java @@ -0,0 +1,164 @@ +package ml.docilealligator.infinityforreddit.Adapter; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Message; +import ml.docilealligator.infinityforreddit.R; + +public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter { + private Message mMessage; + private Context mContext; + private Markwon mMarkwon; + private int mMessageBackgroundColor; + private int mUsernameColor; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + private int mUnreadMessageBackgroundColor; + + public PrivateMessagesDetailRecyclerViewAdapter(Context context, Message message, CustomThemeWrapper customThemeWrapper) { + mMessage = message; + mContext = context; + mMarkwon = Markwon.builder(mContext) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mMessageBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); + mUsernameColor = customThemeWrapper.getUsername(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mUnreadMessageBackgroundColor = customThemeWrapper.getUnreadMessageBackgroundColor(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new DataViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof DataViewHolder) { + Message message; + if (holder.getAdapterPosition() == 0) { + message = mMessage; + } else { + message = mMessage.getReplies().get(holder.getAdapterPosition() - 1); + } + + if (message != null) { + if (message.isNew()) { + ((DataViewHolder) holder).itemView.setBackgroundColor( + mUnreadMessageBackgroundColor); + } + + ((DataViewHolder) holder).authorTextView.setText(message.getAuthor()); + String subject = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); + ((DataViewHolder) holder).subjectTextView.setText(subject); + mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getBody()); + + ((DataViewHolder) holder).authorTextView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); + mContext.startActivity(intent); + }); + + ((DataViewHolder) holder).contentCustomMarkwonView.setOnClickListener(view -> ((DataViewHolder) holder).itemView.performClick()); + } + } + } + + @Override + public int getItemCount() { + if (mMessage == null) { + return 0; + } else if (mMessage.getReplies() == null) { + return 1; + } else { + return 1 + mMessage.getReplies().size(); + } + } + + public void setMessage(Message message) { + mMessage = message; + notifyDataSetChanged(); + } + + public void addReply(Message reply) { + int currentSize = getItemCount(); + + if (mMessage != null) { + mMessage.addReply(reply); + } else { + mMessage = reply; + } + + notifyItemInserted(currentSize); + } + + class DataViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.author_text_view_item_message) + TextView authorTextView; + @BindView(R.id.subject_text_view_item_message) + TextView subjectTextView; + @BindView(R.id.title_text_view_item_message) + TextView titleTextView; + @BindView(R.id.content_custom_markwon_view_item_message) + TextView contentCustomMarkwonView; + + DataViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + titleTextView.setVisibility(View.GONE); + + itemView.setBackgroundColor(mMessageBackgroundColor); + authorTextView.setTextColor(mUsernameColor); + subjectTextView.setTextColor(mPrimaryTextColor); + titleTextView.setTextColor(mPrimaryTextColor); + contentCustomMarkwonView.setTextColor(mSecondaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java index 17937af2..d93081de 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java @@ -30,8 +30,10 @@ public class FetchMessages { public static final String WHERE_SENT = "sent"; public static final String WHERE_COMMENTS = "comments"; public static final String WHERE_MESSAGES = "messages"; + public static final String WHERE_MESSAGES_DETAIL = "messages_detail"; public static final int MESSAGE_TYPE_NOTIFICATION = 0; public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1; + public static final int MESSAGE_TYPE_PRIVATE_MESSAGE_DETAIL = 2; static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where, String after, int messageType, FetchMessagesListener fetchMessagesListener) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message.java index 0aa2c439..9f3131e0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Message.java @@ -176,6 +176,13 @@ public class Message implements Parcelable { this.replies = replies; } + public void addReply(Message reply) { + if (replies == null) { + replies = new ArrayList<>(); + } + replies.add(reply); + } + @Override public int describeContents() { return 0; diff --git a/app/src/main/res/layout/activity_view_private_messages.xml b/app/src/main/res/layout/activity_view_private_messages.xml index bc663b3a..67c665a9 100644 --- a/app/src/main/res/layout/activity_view_private_messages.xml +++ b/app/src/main/res/layout/activity_view_private_messages.xml @@ -46,7 +46,6 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" - app:srcCompat="@drawable/ic_add_day_night_24dp" - app:tint="@android:color/white" /> + app:srcCompat="@drawable/ic_add_day_night_24dp" /> \ No newline at end of file -- cgit v1.2.3