Prepare to support PM.

This commit is contained in:
Alex Ning 2020-06-23 16:32:40 +08:00
parent 421315f0c6
commit 5daa0de82d
5 changed files with 203 additions and 10 deletions

View File

@ -29,15 +29,19 @@ public class FetchMessages {
public static final String WHERE_UNREAD = "unread";
public static final String WHERE_SENT = "sent";
public static final String WHERE_COMMENTS = "comments";
public static final String WHERE_MESSAGES = "messages";
public static final int MESSAGE_TYPE_NOTIFICATION = 0;
public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1;
static void fetchMessagesAsync(Retrofit oauthRetrofit, Locale locale, String accessToken, String where,
String after, FetchMessagesListener fetchMessagesListener) {
static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where,
String after, int messageType, FetchMessagesListener fetchMessagesListener) {
oauthRetrofit.create(RedditAPI.class).getMessages(APIUtils.getOAuthHeader(accessToken), where, after)
.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
new ParseMessageAsnycTask(response.body(), locale, fetchMessagesListener::fetchSuccess).execute();
new ParseMessageAsnycTask(response.body(), locale, messageType,
fetchMessagesListener::fetchSuccess).execute();
} else {
fetchMessagesListener.fetchFailed();
}
@ -50,8 +54,7 @@ public class FetchMessages {
});
}
@Nullable
static ArrayList<Message> parseMessage(String response, Locale locale) {
static ArrayList<Message> parseMessage(String response, Locale locale, int messageType) {
JSONArray messageArray;
try {
messageArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
@ -65,6 +68,10 @@ public class FetchMessages {
try {
JSONObject messageJSON = messageArray.getJSONObject(i);
String kind = messageJSON.getString(JSONUtils.KIND_KEY);
if ((messageType == MESSAGE_TYPE_NOTIFICATION && kind.equals("t4")) ||
(messageType == MESSAGE_TYPE_PRIVATE_MESSAGE && !kind.equals("t4"))) {
continue;
}
JSONObject rawMessageJSON = messageJSON.getJSONObject(JSONUtils.DATA_KEY);
String subredditName = rawMessageJSON.getString(JSONUtils.SUBREDDIT_KEY);
@ -111,17 +118,20 @@ public class FetchMessages {
private Locale locale;
private ArrayList<Message> messages;
private String after;
private int messageType;
private ParseMessageAsyncTaskListener parseMessageAsyncTaskListener;
ParseMessageAsnycTask(String response, Locale locale, ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) {
ParseMessageAsnycTask(String response, Locale locale, int messageType,
ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) {
this.response = response;
this.locale = locale;
this.messageType = messageType;
messages = new ArrayList<>();
this.parseMessageAsyncTaskListener = parseMessageAsnycTaskListener;
}
@Override
protected Void doInBackground(Void... voids) {
messages = parseMessage(response, locale);
messages = parseMessage(response, locale, messageType);
try {
after = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY);
} catch (JSONException e) {

View File

@ -0,0 +1,128 @@
package ml.docilealligator.infinityforreddit.Fragment;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.bumptech.glide.RequestManager;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.BindView;
import ml.docilealligator.infinityforreddit.Adapter.MessageRecyclerViewAdapter;
import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.FetchMessages;
import ml.docilealligator.infinityforreddit.FragmentCommunicator;
import ml.docilealligator.infinityforreddit.MessageViewModel;
import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import retrofit2.Retrofit;
public class ViewMessagesFragment extends Fragment implements FragmentCommunicator {
@BindView(R.id.swipe_refresh_layout_view_messages_fragment)
SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recycler_view_view_messages_fragment)
RecyclerView mRecyclerView;
@BindView(R.id.fetch_messages_info_linear_layout_view_messages_fragment)
LinearLayout mFetchMessageInfoLinearLayout;
@BindView(R.id.fetch_messages_info_image_view_view_messages_fragment)
ImageView mFetchMessageInfoImageView;
@BindView(R.id.fetch_messages_info_text_view_view_messages_fragment)
TextView mFetchMessageInfoTextView;
MessageViewModel mMessageViewModel;
@Inject
@Named("oauth")
Retrofit mOauthRetrofit;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
private String mAccessToken;
private MessageRecyclerViewAdapter mAdapter;
private RequestManager mGlide;
private LinearLayoutManager mLinearLayoutManager;
public ViewMessagesFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_view_messages, container, false);
MessageViewModel.Factory factory = new MessageViewModel.Factory(mOauthRetrofit,
getResources().getConfiguration().locale, mAccessToken, FetchMessages.WHERE_INBOX);
mMessageViewModel = new ViewModelProvider(this, factory).get(MessageViewModel.class);
mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages));
mMessageViewModel.hasMessage().observe(getViewLifecycleOwner(), hasMessage -> {
mSwipeRefreshLayout.setRefreshing(false);
if (hasMessage) {
mFetchMessageInfoLinearLayout.setVisibility(View.GONE);
} else {
mFetchMessageInfoLinearLayout.setOnClickListener(view -> {
//Do nothing
});
showErrorView(R.string.no_messages);
}
});
mMessageViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> {
if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) {
mSwipeRefreshLayout.setRefreshing(false);
} else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) {
mSwipeRefreshLayout.setRefreshing(false);
mFetchMessageInfoLinearLayout.setOnClickListener(view -> {
mFetchMessageInfoLinearLayout.setVisibility(View.GONE);
mMessageViewModel.refresh();
mAdapter.setNetworkState(null);
});
showErrorView(R.string.load_messages_failed);
} else {
mSwipeRefreshLayout.setRefreshing(true);
}
});
mMessageViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> {
mAdapter.setNetworkState(networkState);
});
mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh);
return rootView;
}
private void showErrorView(int stringResId) {
mSwipeRefreshLayout.setRefreshing(false);
mFetchMessageInfoLinearLayout.setVisibility(View.VISIBLE);
mFetchMessageInfoTextView.setText(stringResId);
mGlide.load(R.drawable.error_image).into(mFetchMessageInfoImageView);
}
@Override
public void applyTheme() {
}
private void onRefresh() {
mMessageViewModel.refresh();
}
}

View File

@ -15,6 +15,7 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> {
private Locale locale;
private String accessToken;
private String where;
private int messageType;
private MutableLiveData<NetworkState> paginationNetworkStateLiveData;
private MutableLiveData<NetworkState> initialLoadStateLiveData;
@ -28,6 +29,11 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> {
this.locale = locale;
this.accessToken = accessToken;
this.where = where;
if (where.equals(FetchMessages.WHERE_MESSAGES)) {
messageType = FetchMessages.MESSAGE_TYPE_PRIVATE_MESSAGE;
} else {
messageType = FetchMessages.MESSAGE_TYPE_NOTIFICATION;
}
paginationNetworkStateLiveData = new MutableLiveData<>();
initialLoadStateLiveData = new MutableLiveData<>();
hasPostLiveData = new MutableLiveData<>();
@ -53,7 +59,8 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> {
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull LoadInitialCallback<String, Message> callback) {
initialLoadStateLiveData.postValue(NetworkState.LOADING);
FetchMessages.fetchMessagesAsync(oauthRetrofit, locale, accessToken, where, null, new FetchMessages.FetchMessagesListener() {
FetchMessages.fetchInbox(oauthRetrofit, locale, accessToken, where, null, messageType,
new FetchMessages.FetchMessagesListener() {
@Override
public void fetchSuccess(ArrayList<Message> messages, @Nullable String after) {
if (messages.size() == 0) {
@ -89,7 +96,8 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> {
paginationNetworkStateLiveData.postValue(NetworkState.LOADING);
FetchMessages.fetchMessagesAsync(oauthRetrofit, locale, accessToken, where, params.key, new FetchMessages.FetchMessagesListener() {
FetchMessages.fetchInbox(oauthRetrofit, locale, accessToken, where, params.key, messageType,
new FetchMessages.FetchMessagesListener() {
@Override
public void fetchSuccess(ArrayList<Message> messages, @Nullable String after) {
if (after == null || after.equals("") || after.equals("null")) {

View File

@ -74,7 +74,8 @@ public class PullNotificationWorker extends Worker {
if (response != null && response.isSuccessful()) {
String responseBody = response.body();
ArrayList<Message> messages = FetchMessages.parseMessage(responseBody, context.getResources().getConfiguration().locale);
ArrayList<Message> messages = FetchMessages.parseMessage(responseBody,
context.getResources().getConfiguration().locale, FetchMessages.MESSAGE_TYPE_NOTIFICATION);
if (messages != null && !messages.isEmpty()) {
NotificationManagerCompat notificationManager = NotificationUtils.getNotificationManager(context);

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.ViewMessagesFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout_view_messages_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_view_messages_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:id="@+id/fetch_messages_info_linear_layout_view_messages_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/fetch_messages_info_image_view_view_messages_fragment"
android:layout_width="150dp"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/fetch_messages_info_text_view_view_messages_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:fontFamily="?attr/font_family"
android:gravity="center"
android:textSize="?attr/font_default" />
</LinearLayout>
</RelativeLayout>