Added Comments to search results

This commit adds the ability to search for comments. It adds a new tab to the SearchResultActivity with a CommentsListingFragment. #241

This commit also fixes an issue where you can't upvote comments on when in a listing (e.g. on a profile, or now search)
This commit is contained in:
Bazsalanszky 2024-07-12 08:22:29 +02:00
parent 0fb834fb38
commit 21861a5884
9 changed files with 141 additions and 27 deletions

View File

@ -67,6 +67,7 @@ import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.fragments.SubredditListingFragment;
import eu.toldi.infinityforlemmy.fragments.UserListingFragment;
@ -272,6 +273,9 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
case 2:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.users));
break;
case 3:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.comments));
break;
}
}).attach();
fixViewPager2Sensitivity(viewPager2);
@ -407,13 +411,14 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag());
} else {
if (fragment instanceof SubredditListingFragment) {
SearchUserAndSubredditSortTypeBottomSheetFragment searchUserAndSubredditSortTypeBottomSheetFragment
= SearchUserAndSubredditSortTypeBottomSheetFragment.getNewInstance(viewPager2.getCurrentItem(), ((SubredditListingFragment) fragment).getSortType());
searchUserAndSubredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchUserAndSubredditSortTypeBottomSheetFragment.getTag());
SortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment = SortTypeBottomSheetFragment.getNewInstance(SortTypeBottomSheetFragment.PAGE_TYPE_SEARCH,((SubredditListingFragment) fragment).getSortType());
searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag());
} else if (fragment instanceof UserListingFragment) {
SearchUserAndSubredditSortTypeBottomSheetFragment searchUserAndSubredditSortTypeBottomSheetFragment
= SearchUserAndSubredditSortTypeBottomSheetFragment.getNewInstance(viewPager2.getCurrentItem(), ((UserListingFragment) fragment).getSortType());
searchUserAndSubredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchUserAndSubredditSortTypeBottomSheetFragment.getTag());
SortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment = SortTypeBottomSheetFragment.getNewInstance(SortTypeBottomSheetFragment.PAGE_TYPE_SEARCH,((UserListingFragment) fragment).getSortType());
searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag());
} else if (fragment instanceof CommentsListingFragment) {
SortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment = SortTypeBottomSheetFragment.getNewInstance(SortTypeBottomSheetFragment.PAGE_TYPE_SEARCH,((CommentsListingFragment) fragment).getSortType());
searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag());
}
}
}
@ -473,7 +478,6 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.changeSortType(sortType);
}
}
@Override
@ -792,7 +796,7 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
mFragment.setArguments(bundle);
return mFragment;
}
default: {
case 2: {
UserListingFragment mFragment = new UserListingFragment();
Bundle bundle = new Bundle();
bundle.putString(UserListingFragment.EXTRA_QUERY, mQuery);
@ -802,6 +806,15 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
mFragment.setArguments(bundle);
return mFragment;
}
default: {
CommentsListingFragment mFragment = new CommentsListingFragment();
Bundle bundle = new Bundle();
bundle.putString(CommentsListingFragment.EXTRA_SEARCH_QUERY, mQuery);
bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
mFragment.setArguments(bundle);
return mFragment;
}
}
}
@ -826,9 +839,19 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
void changeSortType(SortType sortType) {
Fragment fragment = getCurrentFragment();
if (fragment instanceof PostFragment) {
((PostFragment) fragment).changeSortType(sortType);
displaySortTypeInToolbar();
} else if (fragment instanceof SubredditListingFragment) {
((SubredditListingFragment) fragment).changeSortType(sortType);
displaySortTypeInToolbar();
} else if (fragment instanceof UserListingFragment) {
((UserListingFragment) fragment).changeSortType(sortType);
displaySortTypeInToolbar();
} else if (fragment instanceof CommentsListingFragment) {
((CommentsListingFragment) fragment).changeSortType(sortType);
displaySortTypeInToolbar();
}
}
@ -871,6 +894,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
((SubredditListingFragment) fragment).goBackToTop();
} else if (fragment instanceof UserListingFragment) {
((UserListingFragment) fragment).goBackToTop();
} else if (fragment instanceof CommentsListingFragment) {
((CommentsListingFragment) fragment).goBackToTop();
}
}
@ -885,6 +910,9 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
} else if (fragment instanceof UserListingFragment) {
SortType sortType = ((UserListingFragment) fragment).getSortType();
Utils.displaySortTypeInToolbar(sortType, toolbar);
} else if (fragment instanceof CommentsListingFragment) {
SortType sortType = ((CommentsListingFragment) fragment).getSortType();
Utils.displaySortTypeInToolbar(sortType, toolbar);
}
}
@ -904,7 +932,7 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
@Override
public int getItemCount() {
return 3;
return 4;
}
}

View File

@ -558,7 +558,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
comment.getScore() + comment.getVoteType()));
VoteThing.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() {
VoteThing.voteComment(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position1) {
int currentPosition = getBindingAdapterPosition();
@ -637,7 +637,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
comment.getScore() + comment.getVoteType()));
VoteThing.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() {
VoteThing.voteComment(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position1) {
int currentPosition = getBindingAdapterPosition();

View File

@ -29,6 +29,7 @@ public class CommentDataSource extends PageKeyedDataSource<Integer, Comment> {
@Nullable
private String accessToken;
private String username;
private String query;
private SortType sortType;
private boolean areSavedComments;
@ -39,12 +40,13 @@ public class CommentDataSource extends PageKeyedDataSource<Integer, Comment> {
private LoadParams<Integer> params;
private LoadCallback<Integer, Comment> callback;
CommentDataSource(Retrofit retrofit, Locale locale, @Nullable String accessToken, String username, SortType sortType,
boolean areSavedComments) {
CommentDataSource(Retrofit retrofit, Locale locale, @Nullable String accessToken, String username,
String query,SortType sortType, boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.query = query;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
paginationNetworkStateLiveData = new MutableLiveData<>();
@ -69,6 +71,68 @@ public class CommentDataSource extends PageKeyedDataSource<Integer, Comment> {
}
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Comment> callback) {
updateNetworkState(initialLoadStateLiveData, NetworkState.LOADING);
LemmyAPI api = retrofit.create(LemmyAPI.class);
if (query != null && !query.isEmpty()) {
fetchComments(api.search(query, null, null, null,"Comments", sortType.getType().value,"All",1, 25, accessToken), callback, true);
} else {
fetchComments(api.getUserComments(username, sortType.getType().value, 1, 25, areSavedComments, accessToken), callback, true);
}
}
@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Comment> callback) {
this.params = params;
updateNetworkState(paginationNetworkStateLiveData, NetworkState.LOADING);
LemmyAPI api = retrofit.create(LemmyAPI.class);
if (query != null && !query.isEmpty()) {
fetchComments(api.search(query, null, null, null,"Comments", sortType.getType().value,"All",params.key, 25, accessToken), callback, false);
} else {
fetchComments(api.getUserComments(username, sortType.getType().value, params.key, 25, areSavedComments, accessToken), callback, false);
}
}
private void fetchComments(Call<String> call, Object callback, boolean isInitialLoad) {
call.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
new ParseCommentAsyncTask(response.body(), locale, new ParseCommentAsyncTask.ParseCommentAsyncTaskListener() {
@Override
public void parseSuccessful(ArrayList<Comment> comments, Integer page) {
if (isInitialLoad) {
((LoadInitialCallback<Integer, Comment>) callback).onResult(comments, null, comments.isEmpty() ? null : 2);
hasPostLiveData.postValue(!comments.isEmpty());
} else {
((LoadCallback<Integer, Comment>) callback).onResult(comments, page);
}
updateNetworkState(isInitialLoad ? initialLoadStateLiveData : paginationNetworkStateLiveData, NetworkState.LOADED);
}
@Override
public void parseFailed() {
updateNetworkState(isInitialLoad ? initialLoadStateLiveData : paginationNetworkStateLiveData, new NetworkState(NetworkState.Status.FAILED, "Error parsing data"));
}
}).execute();
} else {
updateNetworkState(isInitialLoad ? initialLoadStateLiveData : paginationNetworkStateLiveData, new NetworkState(NetworkState.Status.FAILED, "Error fetching data"));
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
updateNetworkState(isInitialLoad ? initialLoadStateLiveData : paginationNetworkStateLiveData, new NetworkState(NetworkState.Status.FAILED, "Error fetching data"));
}
});
}
private void updateNetworkState(MutableLiveData<NetworkState> liveData, NetworkState state) {
liveData.postValue(state);
}
/*
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Comment> callback) {
initialLoadStateLiveData.postValue(NetworkState.LOADING);
@ -109,12 +173,12 @@ public class CommentDataSource extends PageKeyedDataSource<Integer, Comment> {
}
});
}
*/
@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Comment> callback) {
}
/*
@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Comment> callback) {
this.params = params;
@ -154,7 +218,7 @@ public class CommentDataSource extends PageKeyedDataSource<Integer, Comment> {
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data"));
}
});
}
}*/
private static class ParseCommentAsyncTask extends AsyncTask<Void, ArrayList<Comment>, ArrayList<Comment>> {
private Integer after;

View File

@ -15,6 +15,7 @@ class CommentDataSourceFactory extends DataSource.Factory {
private Locale locale;
private String accessToken;
private String username;
private String query;
private SortType sortType;
private boolean areSavedComments;
@ -22,12 +23,13 @@ class CommentDataSourceFactory extends DataSource.Factory {
private MutableLiveData<CommentDataSource> commentDataSourceLiveData;
CommentDataSourceFactory(Retrofit retrofit, Locale locale, @Nullable String accessToken,
String username, SortType sortType,
String username,String query, SortType sortType,
boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.query = query;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
commentDataSourceLiveData = new MutableLiveData<>();
@ -36,8 +38,8 @@ class CommentDataSourceFactory extends DataSource.Factory {
@NonNull
@Override
public DataSource create() {
commentDataSource = new CommentDataSource(retrofit, locale, accessToken, username, sortType,
areSavedComments);
commentDataSource = new CommentDataSource(retrofit, locale, accessToken, username, query,
sortType, areSavedComments);
commentDataSourceLiveData.postValue(commentDataSource);
return commentDataSource;
}

View File

@ -23,9 +23,9 @@ public class CommentViewModel extends ViewModel {
private LiveData<PagedList<Comment>> comments;
private MutableLiveData<SortType> sortTypeLiveData;
public CommentViewModel(Retrofit retrofit, Locale locale, String accessToken, String username, SortType sortType,
public CommentViewModel(Retrofit retrofit, Locale locale, String accessToken, String username, String query, SortType sortType,
boolean areSavedComments) {
commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, accessToken, username, sortType,
commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, accessToken, username,query, sortType,
areSavedComments);
initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(),
@ -84,15 +84,17 @@ public class CommentViewModel extends ViewModel {
private Locale locale;
private String accessToken;
private String username;
private String query;
private SortType sortType;
private boolean areSavedComments;
public Factory(Retrofit retrofit, Locale locale, String accessToken, String username,
SortType sortType, boolean areSavedComments) {
String query, SortType sortType, boolean areSavedComments) {
this.retrofit = retrofit;
this.locale = locale;
this.accessToken = accessToken;
this.username = username;
this.query = query;
this.sortType = sortType;
this.areSavedComments = areSavedComments;
}
@ -100,7 +102,7 @@ public class CommentViewModel extends ViewModel {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new CommentViewModel(retrofit, locale, accessToken, username, sortType, areSavedComments);
return (T) new CommentViewModel(retrofit, locale, accessToken, username,query, sortType, areSavedComments);
}
}
}

View File

@ -60,6 +60,7 @@ import eu.toldi.infinityforlemmy.utils.Utils;
public class CommentsListingFragment extends Fragment implements FragmentCommunicator {
public static final String EXTRA_USERNAME = "EN";
public static final String EXTRA_SEARCH_QUERY = "ESQ";
public static final String EXTRA_ACCESS_TOKEN = "EAT";
public static final String EXTRA_ACCOUNT_NAME = "EAN";
public static final String EXTRA_ARE_SAVED_COMMENTS = "EISC";
@ -266,6 +267,8 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
() -> mCommentViewModel.retryLoadingMore());
String username = getArguments().getString(EXTRA_USERNAME);
String query = getArguments().getString(EXTRA_SEARCH_QUERY);
String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT, SortType.Type.NEW.name());
if (sort.equals(SortType.Type.TOP.name())) {
String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_USER_COMMENT, SortType.Time.ALL.name());
@ -293,7 +296,7 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni
factory = new CommentViewModel.Factory(mRetrofit.getRetrofit(),
resources.getConfiguration().locale, mAccessToken, username, sortType,
resources.getConfiguration().locale, mAccessToken, username, query,sortType,
getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS));

View File

@ -183,7 +183,14 @@ public class SubredditListingFragment extends Fragment implements FragmentCommun
SubredditListingViewModel.Factory factory = new SubredditListingViewModel.Factory(
mRetrofit.getRetrofit(), query, sortType, accessToken, nsfw);
mSubredditListingViewModel = new ViewModelProvider(this, factory).get(SubredditListingViewModel.class);
mSubredditListingViewModel.getSubreddits().observe(getViewLifecycleOwner(), subredditData -> mAdapter.submitList(subredditData));
mSubredditListingViewModel.getSubreddits().observe(getViewLifecycleOwner(), subredditData -> {
if (subredditData != null && !subredditData.isEmpty()) {
mAdapter.submitList(subredditData);
} else {
mAdapter.submitList(null);
}
});
mSubredditListingViewModel.hasSubredditLiveData().observe(getViewLifecycleOwner(), hasSubreddit -> {
mSwipeRefreshLayout.setRefreshing(false);

View File

@ -183,7 +183,15 @@ public class UserListingFragment extends Fragment implements FragmentCommunicato
UserListingViewModel.Factory factory = new UserListingViewModel.Factory(mRetrofit.getRetrofit(), mQuery,
sortType, nsfw);
mUserListingViewModel = new ViewModelProvider(this, factory).get(UserListingViewModel.class);
mUserListingViewModel.getUsers().observe(getViewLifecycleOwner(), UserData -> mAdapter.submitList(UserData));
mUserListingViewModel.getUsers().observe(getViewLifecycleOwner(), (UserData) -> {
if (UserData != null && !UserData.isEmpty()) {
mAdapter.submitList(UserData);
} else {
mAdapter.submitList(null);
}
});
mUserListingViewModel.hasUser().observe(getViewLifecycleOwner(), hasUser -> {
mSwipeRefreshLayout.setRefreshing(false);

View File

@ -54,7 +54,7 @@ public class UserListingDataSource extends PageKeyedDataSource<Integer, UserData
new FetchUserData.FetchUserListingDataListener() {
@Override
public void onFetchUserListingDataSuccess(ArrayList<UserData> UserData, String after) {
hasUserLiveData.postValue(UserData.size() != 0);
hasUserLiveData.postValue(!UserData.isEmpty());
callback.onResult(UserData, null, 2);
initialLoadStateLiveData.postValue(NetworkState.LOADED);