Viewing saved comments in Saved is available.

This commit is contained in:
Alex Ning 2019-09-18 11:10:16 +08:00
parent 5172ae96a7
commit c1adf51537
19 changed files with 658 additions and 92 deletions

Binary file not shown.

View File

@ -11,20 +11,31 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".AccountSavedThingActivity"
android:label="@string/account_saved_thing_activity"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".ShareDataResolverActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
@ -54,12 +65,10 @@
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".FilteredThingActivity"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".SearchSubredditsResultActivity"
android:label="@string/search_subreddits_activity_label"
@ -102,7 +111,6 @@
<data
android:host="s.reddit.com"
android:scheme="https" />
<data
android:host="www.reddit.com"
android:scheme="http" />
@ -225,6 +233,7 @@
android:name=".ViewUserDetailActivity"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBarWithTranslucentWindow" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
@ -240,14 +249,13 @@
android:enabled="true"
android:exported="false" />
</application>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

View File

@ -58,8 +58,6 @@ public class AccountPostsActivity extends AppCompatActivity implements UserThing
private Menu mMenu;
private AppBarLayout.LayoutParams params;
private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@ -146,9 +144,6 @@ public class AccountPostsActivity extends AppCompatActivity implements UserThing
} else if(mUserWhere.equals(PostDataSource.USER_WHERE_HIDDEN)) {
toolbar.setTitle(R.string.hidden);
} else if(mUserWhere.equals(PostDataSource.USER_WHERE_GILDED)){
if(mMenu != null) {
mMenu.findItem(R.id.action_sort_account_posts_activity).setVisible(true);
}
toolbar.setTitle(R.string.gilded);
}
@ -171,8 +166,6 @@ public class AccountPostsActivity extends AppCompatActivity implements UserThing
} else {
getCurrentAccountAndInitializeFragment();
}
userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment();
}
private void getCurrentAccountAndInitializeFragment() {
@ -204,9 +197,6 @@ public class AccountPostsActivity extends AppCompatActivity implements UserThing
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.account_posts_activity, menu);
mMenu = menu;
if(mUserWhere != null && mUserWhere.equals(PostDataSource.USER_WHERE_GILDED)) {
menu.findItem(R.id.action_sort_account_posts_activity).setVisible(true);
}
MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_posts_activity);
if(isInLazyMode) {
lazyModeItem.setTitle(R.string.action_stop_lazy_mode);
@ -223,9 +213,6 @@ public class AccountPostsActivity extends AppCompatActivity implements UserThing
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_sort_account_posts_activity:
userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag());
return true;
case R.id.action_refresh_account_posts_activity:
if(mMenu != null) {
mMenu.findItem(R.id.action_lazy_mode_account_posts_activity).setTitle(R.string.action_start_lazy_mode);

View File

@ -0,0 +1,394 @@
package ml.docilealligator.infinityforreddit;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.tabs.TabLayout;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import retrofit2.Retrofit;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES;
public class AccountSavedThingActivity extends AppCompatActivity {
private static final String NULL_ACCESS_TOKEN_STATE = "NATS";
private static final String ACCESS_TOKEN_STATE = "ATS";
private static final String ACCOUNT_NAME_STATE = "ANS";
private static final String IS_IN_LAZY_MODE_STATE = "IILMS";
@BindView(R.id.collapsing_toolbar_layout_account_saved_thing_activity) CollapsingToolbarLayout collapsingToolbarLayout;
@BindView(R.id.appbar_layout_account_saved_thing_activity) AppBarLayout appBarLayout;
@BindView(R.id.toolbar_account_saved_thing_activity) Toolbar toolbar;
@BindView(R.id.tab_layout_tab_layout_account_saved_thing_activity_activity) TabLayout tabLayout;
@BindView(R.id.view_pager_account_saved_thing_activity) ViewPager viewPager;
private SectionsPagerAdapter sectionsPagerAdapter;
private Menu mMenu;
private AppBarLayout.LayoutParams params;
private boolean mNullAccessToken = false;
private String mAccessToken;
private String mAccountName;
private boolean isInLazyMode = false;
@Inject
@Named("oauth")
Retrofit mOauthRetrofit;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject
SharedPreferences mSharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account_saved_thing);
ButterKnife.bind(this);
((Infinity) getApplication()).getAppComponent().inject(this);
EventBus.getDefault().register(this);
Resources resources = getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
&& (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT
|| resources.getBoolean(R.bool.isTablet))) {
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
boolean lightNavBar = false;
if((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) {
lightNavBar = true;
}
boolean finalLightNavBar = lightNavBar;
View decorView = window.getDecorView();
if(finalLightNavBar) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
@Override
void onStateChanged(AppBarLayout appBarLayout, State state) {
if (state == State.COLLAPSED) {
if(finalLightNavBar) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
} else if (state == State.EXPANDED) {
if(finalLightNavBar) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
}
}
});
int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (statusBarResourceId > 0) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
params.topMargin = getResources().getDimensionPixelSize(statusBarResourceId);
toolbar.setLayoutParams(params);
}
}
boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
int themeType = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.THEME_KEY, "2"));
switch (themeType) {
case 0:
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO);
break;
case 1:
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES);
break;
case 2:
if(systemDefault) {
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM);
} else {
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY);
}
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
if(savedInstanceState != null) {
mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE);
mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE);
mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE);
isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE);
if(!mNullAccessToken && mAccessToken == null) {
getCurrentAccountAndInitializeViewPager();
} else {
initializeViewPager();
}
} else {
getCurrentAccountAndInitializeViewPager();
}
}
private void getCurrentAccountAndInitializeViewPager() {
new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> {
if(account == null) {
mNullAccessToken = true;
} else {
mAccessToken = account.getAccessToken();
mAccountName = account.getUsername();
}
initializeViewPager();
}).execute();
}
private void initializeViewPager() {
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOffscreenPageLimit(2);
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(isInLazyMode) {
if(viewPager.getCurrentItem() == 0) {
sectionsPagerAdapter.resumeLazyMode();
} else {
sectionsPagerAdapter.pauseLazyMode();
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.account_saved_thing_activity, menu);
mMenu = menu;
MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity);
if (isInLazyMode) {
lazyModeItem.setTitle(R.string.action_stop_lazy_mode);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
collapsingToolbarLayout.setLayoutParams(params);
} else {
lazyModeItem.setTitle(R.string.action_start_lazy_mode);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS |
AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED);
collapsingToolbarLayout.setLayoutParams(params);
}
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_refresh_account_saved_thing_activity:
if(mMenu != null) {
mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity).setTitle(R.string.action_start_lazy_mode);
}
sectionsPagerAdapter.refresh();
return true;
case R.id.action_lazy_mode_account_saved_thing_activity:
MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity);
if(isInLazyMode) {
isInLazyMode = false;
sectionsPagerAdapter.stopLazyMode();
lazyModeItem.setTitle(R.string.action_start_lazy_mode);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS |
AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED);
collapsingToolbarLayout.setLayoutParams(params);
} else {
isInLazyMode = true;
if(sectionsPagerAdapter.startLazyMode()) {
lazyModeItem.setTitle(R.string.action_stop_lazy_mode);
appBarLayout.setExpanded(false);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
collapsingToolbarLayout.setLayoutParams(params);
} else {
isInLazyMode = false;
}
}
return true;
}
return false;
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode);
outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken);
outState.putString(ACCESS_TOKEN_STATE, mAccessToken);
outState.putString(ACCOUNT_NAME_STATE, mAccountName);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe
public void onAccountSwitchEvent(SwitchAccountEvent event) {
finish();
}
@Subscribe
public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) {
sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw);
}
private class SectionsPagerAdapter extends FragmentPagerAdapter {
private PostFragment postFragment;
private CommentsListingFragment commentsListingFragment;
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
if (position == 0) {
PostFragment fragment = new PostFragment();
Bundle bundle = new Bundle();
bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER);
bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName);
bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SAVED);
bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_NEW);
bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER);
bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
fragment.setArguments(bundle);
return fragment;
}
CommentsListingFragment fragment = new CommentsListingFragment();
Bundle bundle = new Bundle();
bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountName);
bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, true);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Posts";
case 1:
return "Comments";
}
return null;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
switch (position) {
case 0:
postFragment = (PostFragment) fragment;
break;
case 1:
commentsListingFragment = (CommentsListingFragment) fragment;
}
return fragment;
}
public void refresh() {
if (viewPager.getCurrentItem() == 0) {
if(postFragment != null) {
postFragment.refresh();
}
} else {
if(commentsListingFragment != null) {
commentsListingFragment.refresh();
}
}
}
boolean startLazyMode() {
if(postFragment != null) {
return ((FragmentCommunicator) postFragment).startLazyMode();
}
return false;
}
void stopLazyMode() {
if(postFragment != null) {
((FragmentCommunicator) postFragment).stopLazyMode();
}
}
void resumeLazyMode() {
if(postFragment != null) {
((FragmentCommunicator) postFragment).resumeLazyMode(false);
}
}
void pauseLazyMode() {
if(postFragment != null) {
((FragmentCommunicator) postFragment).pauseLazyMode(false);
}
}
public void changeNSFW(boolean nsfw) {
if(postFragment != null) {
postFragment.changeNSFW(nsfw);
}
}
}
}

View File

@ -43,4 +43,5 @@ public interface AppComponent {
void inject(SearchActivity searchActivity);
void inject(SettingsActivity settingsActivity);
void inject(MainPreferenceFragment mainPreferenceFragment);
void inject(AccountSavedThingActivity accountSavedThingActivity);
}

View File

@ -1,9 +1,9 @@
package ml.docilealligator.infinityforreddit;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;
import androidx.paging.PageKeyedDataSource;
@ -23,8 +23,11 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
private Retrofit retrofit;
private Locale locale;
@Nullable
private String accessToken;
private String username;
private String sortType;
private boolean areSavedComments;
private MutableLiveData<NetworkState> paginationNetworkStateLiveData;
private MutableLiveData<NetworkState> initialLoadStateLiveData;
@ -33,11 +36,14 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
private LoadParams<String> params;
private LoadCallback<String, CommentData> callback;
CommentDataSource(Retrofit retrofit, Locale locale, String username, String sortType) {
CommentDataSource(Retrofit retrofit, Locale locale, @Nullable String accessToken, String username, String sortType,
boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
paginationNetworkStateLiveData = new MutableLiveData<>();
initialLoadStateLiveData = new MutableLiveData<>();
hasPostLiveData = new MutableLiveData<>();
@ -64,7 +70,18 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
initialLoadStateLiveData.postValue(NetworkState.LOADING);
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> commentsCall = api.getUserComments(username, null, sortType);
Call<String> commentsCall;
if(areSavedComments) {
commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED,
null, sortType, RedditUtils.getOAuthHeader(accessToken));
} else {
if(accessToken == null) {
commentsCall = api.getUserComments(username, null, sortType);
} else {
commentsCall = api.getUserCommentsOauth(RedditUtils.getOAuthHeader(accessToken), username,
null, sortType);
}
}
commentsCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
@ -116,8 +133,19 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
paginationNetworkStateLiveData.postValue(NetworkState.LOADING);
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> bestPost = api.getUserComments(username, params.key, sortType);
bestPost.enqueue(new Callback<String>() {
Call<String> commentsCall;
if(areSavedComments) {
commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, params.key,
sortType, RedditUtils.getOAuthHeader(accessToken));
} else {
if(accessToken == null) {
commentsCall = api.getUserComments(username, params.key, sortType);
} else {
commentsCall = api.getUserCommentsOauth(RedditUtils.getOAuthHeader(accessToken),
username, params.key, sortType);
}
}
commentsCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if(response.isSuccessful()) {
@ -150,9 +178,10 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
}
private static class ParseCommentAsyncTask extends AsyncTask<Void, ArrayList<CommentData>, ArrayList<CommentData>> {
private String response;
private String after;
private Locale locale;
private JSONArray commentsJSONArray;
private boolean parseFailed;
private ParseCommentAsyncTaskListener parseCommentAsyncTaskListener;
interface ParseCommentAsyncTaskListener {
@ -161,27 +190,33 @@ public class CommentDataSource extends PageKeyedDataSource<String, CommentData>
}
ParseCommentAsyncTask(String response, Locale locale, ParseCommentAsyncTaskListener parseCommentAsyncTaskListener) {
this.response = response;
this.locale = locale;
this.parseCommentAsyncTaskListener = parseCommentAsyncTaskListener;
try {
JSONObject data = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY);
commentsJSONArray = data.getJSONArray(JSONUtils.CHILDREN_KEY);
after = data.getString(JSONUtils.AFTER_KEY);
parseFailed = false;
} catch (JSONException e) {
parseFailed = true;
e.printStackTrace();
}
}
@Override
protected ArrayList<CommentData> doInBackground(Void... voids) {
try {
JSONObject data = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY);
JSONArray commentsJSONArray = data.getJSONArray(JSONUtils.CHILDREN_KEY);
ArrayList<CommentData> comments = new ArrayList<>();
for(int i = 0; i < commentsJSONArray.length(); i++) {
if(parseFailed) {
return null;
}
ArrayList<CommentData> comments = new ArrayList<>();
for(int i = 0; i < commentsJSONArray.length(); i++) {
try {
JSONObject commentJSON = commentsJSONArray.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
comments.add(ParseComment.parseSingleComment(commentJSON, 0, locale));
}
after = data.getString(JSONUtils.AFTER_KEY);
return comments;
} catch (JSONException e) {
e.printStackTrace();
} catch (JSONException ignored) {}
}
return null;
return comments;
}
@Override

View File

@ -1,6 +1,7 @@
package ml.docilealligator.infinityforreddit;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;
import androidx.paging.DataSource;
@ -11,24 +12,31 @@ import retrofit2.Retrofit;
class CommentDataSourceFactory extends DataSource.Factory {
private Retrofit retrofit;
private Locale locale;
private String accessToken;
private String username;
private String sortType;
private boolean areSavedComments;
private CommentDataSource commentDataSource;
private MutableLiveData<CommentDataSource> commentDataSourceLiveData;
CommentDataSourceFactory(Retrofit retrofit, Locale locale, String username, String sortType) {
CommentDataSourceFactory(Retrofit retrofit, Locale locale, @Nullable String accessToken,
String username, String sortType,
boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
commentDataSourceLiveData = new MutableLiveData<>();
}
@NonNull
@Override
public DataSource create() {
commentDataSource = new CommentDataSource(retrofit, locale, username, sortType);
commentDataSource = new CommentDataSource(retrofit, locale, accessToken, username, sortType,
areSavedComments);
commentDataSourceLiveData.postValue(commentDataSource);
return commentDataSource;
}

View File

@ -21,8 +21,10 @@ public class CommentViewModel extends ViewModel {
private LiveData<PagedList<CommentData>> comments;
private MutableLiveData<String> sortTypeLiveData;
public CommentViewModel(Retrofit retrofit, Locale locale, String username, String sortType) {
commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, username, sortType);
public CommentViewModel(Retrofit retrofit, Locale locale, String accessToken, String username, String sortType,
boolean areSavedComments) {
commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, accessToken, username, sortType,
areSavedComments);
initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(),
CommentDataSource::getInitialLoadStateLiveData);
@ -77,20 +79,25 @@ public class CommentViewModel extends ViewModel {
public static class Factory extends ViewModelProvider.NewInstanceFactory {
private Retrofit retrofit;
private Locale locale;
private String accessToken;
private String username;
private String sortType;
private boolean areSavedComments;
public Factory(Retrofit retrofit, Locale locale, String username, String sortType) {
public Factory(Retrofit retrofit, Locale locale, String accessToken, String username,
String sortType, boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new CommentViewModel(retrofit, locale, username, sortType);
return (T) new CommentViewModel(retrofit, locale, accessToken, username, sortType, areSavedComments);
}
}
}

View File

@ -38,9 +38,13 @@ import retrofit2.Retrofit;
*/
public class CommentsListingFragment extends Fragment implements FragmentCommunicator {
static final String EXTRA_USERNAME_KEY = "ENK";
static final String EXTRA_USERNAME = "EN";
static final String EXTRA_ACCESS_TOKEN = "EAT";
static final String EXTRA_ACCOUNT_NAME = "EAN";
static final String EXTRA_ARE_SAVED_COMMENTS = "EISC";
private static final String NULL_ACCESS_TOKEN_STATE = "NATS";
private static final String ACCESS_TOKEN_STATE = "ATS";
@BindView(R.id.coordinator_layout_comments_listing_fragment) CoordinatorLayout mCoordinatorLayout;
@BindView(R.id.recycler_view_comments_listing_fragment) RecyclerView mCommentRecyclerView;
@ -49,6 +53,9 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
@BindView(R.id.fetch_comments_info_image_view_comments_listing_fragment) ImageView mFetchCommentInfoImageView;
@BindView(R.id.fetch_comments_info_text_view_comments_listing_fragment) TextView mFetchCommentInfoTextView;
private boolean mNullAccessToken = false;
private String mAccessToken;
private RequestManager mGlide;
private Activity activity;
@ -64,6 +71,9 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
@Inject @Named("oauth")
Retrofit mOauthRetrofit;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
public CommentsListingFragment() {
// Required empty public constructor
}
@ -91,18 +101,56 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
}
}
if (savedInstanceState == null) {
getCurrentAccountAndBindView(resources);
} else {
mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE);
mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE);
if (!mNullAccessToken && mAccessToken == null) {
getCurrentAccountAndBindView(resources);
} else {
bindView(resources);
}
}
return rootView;
}
private void getCurrentAccountAndBindView(Resources resources) {
new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> {
if(account == null) {
mNullAccessToken = true;
} else {
mAccessToken = account.getAccessToken();
}
bindView(resources);
}).execute();
}
private void bindView(Resources resources) {
mCommentRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mAdapter = new CommentsListingRecyclerViewAdapter(activity, mOauthRetrofit,
getArguments().getString(EXTRA_ACCESS_TOKEN), getArguments().getString(EXTRA_ACCOUNT_NAME),
() -> mCommentViewModel.retryLoadingMore());
String username = getArguments().getString(EXTRA_USERNAME_KEY);
String username = getArguments().getString(EXTRA_USERNAME);
mCommentRecyclerView.setAdapter(mAdapter);
CommentViewModel.Factory factory = new CommentViewModel.Factory(mRetrofit,
resources.getConfiguration().locale, username, PostDataSource.SORT_TYPE_NEW);
CommentViewModel.Factory factory;
if(mAccessToken == null) {
factory = new CommentViewModel.Factory(mRetrofit,
resources.getConfiguration().locale, mAccessToken, username, PostDataSource.SORT_TYPE_NEW,
getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS));
} else {
factory = new CommentViewModel.Factory(mOauthRetrofit,
resources.getConfiguration().locale, mAccessToken, username, PostDataSource.SORT_TYPE_NEW,
getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS));
}
mCommentViewModel = new ViewModelProvider(this, factory).get(CommentViewModel.class);
mCommentViewModel.getComments().observe(this, comments -> mAdapter.submitList(comments));
@ -130,11 +178,7 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
}
});
mCommentViewModel.getPaginationNetworkState().observe(this, networkState -> {
mAdapter.setNetworkState(networkState);
});
return rootView;
mCommentViewModel.getPaginationNetworkState().observe(this, networkState -> mAdapter.setNetworkState(networkState));
}
void changeSortType(String sortType) {
@ -147,6 +191,13 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
this.activity = (Activity) context;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ACCESS_TOKEN_STATE, mAccessToken);
outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken);
}
@Override
public void refresh() {
mFetchCommentInfoLinearLayout.setVisibility(View.GONE);

View File

@ -625,8 +625,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe
});
savedLinearLayout.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, AccountPostsActivity.class);
intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SAVED);
Intent intent = new Intent(MainActivity.this, AccountSavedThingActivity.class);
startActivity(intent);
drawer.closeDrawers();
});

View File

@ -113,17 +113,19 @@ class ParsePost {
for (int i = 0; i < size; i++) {
try {
JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
Post post = parseBasicData(data, locale);
if(!(!nsfw && post.isNSFW())) {
if (filter == PostFragment.EXTRA_NO_FILTER) {
newPosts.add(post);
} else if (filter == post.getPostType()) {
newPosts.add(post);
} else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
newPosts.add(post);
} else if(filter == Post.NSFW_TYPE && post.isNSFW()) {
newPosts.add(post);
if(allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) {
JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
Post post = parseBasicData(data, locale);
if(post != null && !(!nsfw && post.isNSFW())) {
if (filter == PostFragment.EXTRA_NO_FILTER) {
newPosts.add(post);
} else if (filter == post.getPostType()) {
newPosts.add(post);
} else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
newPosts.add(post);
} else if(filter == Post.NSFW_TYPE && post.isNSFW()) {
newPosts.add(post);
}
}
}
} catch (JSONException e) {

View File

@ -1,7 +1,5 @@
package ml.docilealligator.infinityforreddit;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import androidx.paging.PageKeyedDataSource;
@ -412,9 +410,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
Call<String> getPost;
if(accessToken == null) {
getPost = api.getUserBestPosts(subredditOrUserName, lastItem, sortType);
getPost = api.getUserPosts(subredditOrUserName, lastItem, sortType);
} else {
getPost = api.getUserBestPostsOauth(subredditOrUserName, userWhere, lastItem, sortType,
getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, lastItem, sortType,
RedditUtils.getOAuthHeader(accessToken));
}
getPost.enqueue(new Callback<String>() {
@ -470,9 +468,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
Call<String> getPost;
if(accessToken == null) {
getPost = api.getUserBestPosts(subredditOrUserName, after, sortType);
getPost = api.getUserPosts(subredditOrUserName, after, sortType);
} else {
getPost = api.getUserBestPostsOauth(subredditOrUserName, userWhere, after, sortType,
getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, after, sortType,
RedditUtils.getOAuthHeader(accessToken));
}
getPost.enqueue(new Callback<String>() {

View File

@ -51,13 +51,13 @@ public interface RedditAPI {
Call<String> getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType,
@Query("after") String lastItem);
@GET("user/{username}/{where}.json?&raw_json=1&limit=25")
Call<String> getUserBestPostsOauth(@Path("username") String username, @Path("where") String where,
@Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map<String, String> headers);
@GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25")
Call<String> getUserPostsOauth(@Path("username") String username, @Path("where") String where,
@Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map<String, String> headers);
@GET("user/{username}/submitted.json?raw_json=1&limit=25")
Call<String> getUserBestPosts(@Path("username") String username, @Query("after") String lastItem,
@Query("sort") String sortType);
Call<String> getUserPosts(@Path("username") String username, @Query("after") String lastItem,
@Query("sort") String sortType);
@GET("user/{username}/about.json?raw_json=1")
Call<String> getUserData(@Path("username") String username);
@ -66,6 +66,14 @@ public interface RedditAPI {
Call<String> getUserComments(@Path("username") String username, @Query("after") String after,
@Query("sort") String sortType);
@GET("user/{username}/comments.json?raw_json=1")
Call<String> getUserCommentsOauth(@HeaderMap Map<String, String> headers, @Path("username") String username,
@Query("after") String after, @Query("sort") String sortType);
@GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25")
Call<String> getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where,
@Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map<String, String> headers);
@FormUrlEncoded
@POST("api/subscribe")
Call<String> subredditSubscription(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
@ -76,29 +84,29 @@ public interface RedditAPI {
@GET("/api/info.json?raw_json=1")
Call<String> getInfoOauth(@Query("id") String id, @HeaderMap Map<String, String> headers);
@GET("subreddits/search.json?raw_json=1")
@GET("subreddits/search.json?include_over_18=1&raw_json=1")
Call<String> searchSubreddits(@Query("q") String subredditName, @Query("after") String after,
@Query("sort") String sort);
@GET("search.json?raw_json=1&type=user")
@GET("search.json?include_over_18=1&raw_json=1&type=user")
Call<String> searchUsers(@Query("q") String profileName, @Query("after") String after,
@Query("sort") String sort);
@GET("search.json?raw_json=1&type=link")
@GET("search.json?include_over_18=1&raw_json=1&type=link")
Call<String> searchPostsOauth(@Query("q") String query, @Query("after") String after,
@Query("sort") String sort,
@HeaderMap Map<String, String> headers);
@GET("search.json?raw_json=1&type=link")
@GET("search.json?include_over_18=1&raw_json=1&type=link")
Call<String> searchPosts(@Query("q") String query, @Query("after") String after,
@Query("sort") String sort);
@GET("r/{subredditName}/search.json?raw_json=1&type=link&restrict_sr=true")
@GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true")
Call<String> searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName,
@Query("q") String query, @Query("after") String after,
@HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/search.json?raw_json=1&type=link&restrict_sr=true")
@GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true")
Call<String> searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName,
@Query("q") String query, @Query("after") String after);

View File

@ -667,9 +667,10 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi
}
CommentsListingFragment fragment = new CommentsListingFragment();
Bundle bundle = new Bundle();
bundle.putString(CommentsListingFragment.EXTRA_USERNAME_KEY, username);
bundle.putString(CommentsListingFragment.EXTRA_USERNAME, username);
bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, false);
fragment.setArguments(bundle);
return fragment;
}

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AccountPostsActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager_account_saved_thing_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_layout_account_saved_thing_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout_account_saved_thing_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|enterAlways"
app:titleEnabled="false"
app:toolbarId="@+id/toolbar_account_saved_thing_activity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_account_saved_thing_activity"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:navigationIcon="?attr/homeAsUpIndicator" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout_tab_layout_account_saved_thing_activity_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:tabGravity="fill"
app:tabIndicatorColor="@android:color/white"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed"
app:tabRippleColor="?attr/colorControlHighlight"
app:tabSelectedTextColor="@android:color/white"
app:tabTextColor="@android:color/white"
app:tabUnboundedRipple="false" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,23 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_sort_account_posts_activity"
android:orderInCategory="1"
android:title="@string/action_search"
android:icon="@drawable/ic_outline_sort_24px"
android:visible="false"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_refresh_account_posts_activity"
android:orderInCategory="2"
android:orderInCategory="1"
android:title="@string/action_refresh"
android:icon="@drawable/ic_refresh_white_24dp"
app:showAsAction="never" />
<item
android:id="@+id/action_lazy_mode_account_posts_activity"
android:orderInCategory="3"
android:orderInCategory="2"
android:title="@string/action_start_lazy_mode"
app:showAsAction="never" />
</menu>

View File

@ -0,0 +1,17 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:application="ml.docilealligator.infinityforreddit.AccountSavedThingActivity">
<item
android:id="@+id/action_refresh_account_saved_thing_activity"
android:orderInCategory="1"
android:title="@string/action_refresh"
android:icon="@drawable/ic_refresh_white_24dp"
app:showAsAction="never" />
<item
android:id="@+id/action_lazy_mode_account_saved_thing_activity"
android:orderInCategory="2"
android:title="@string/action_start_lazy_mode"
app:showAsAction="never" />
</menu>

View File

@ -15,6 +15,7 @@
<string name="edit_comment_activity_label">Edit Comment</string>
<string name="view_message_activity_label">Inbox</string>
<string name="settings_activity_label">Settings</string>
<string name="account_saved_thing_activity">Saved</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>