Browse Source

Add HashTag fragment

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
5c273d18a4
  1. 3
      app/src/main/java/awais/instagrabber/activities/MainActivity.java
  2. 18
      app/src/main/java/awais/instagrabber/activities/SavedViewer.java
  3. 310
      app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
  4. 3
      app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
  5. 57
      app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java
  6. 17
      app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
  7. 2
      app/src/main/java/awais/instagrabber/fragments/main/viewmodels/PostsViewModel.java
  8. 77
      app/src/main/res/layout/fragment_hashtag.xml
  9. 13
      app/src/main/res/navigation/feed_nav_graph.xml

3
app/src/main/java/awais/instagrabber/activities/MainActivity.java

@ -43,7 +43,8 @@ public class MainActivity extends BaseLanguageActivity {
R.id.profileFragment, R.id.profileFragment,
R.id.discoverFragment, R.id.discoverFragment,
R.id.morePreferencesFragment, R.id.morePreferencesFragment,
R.id.settingsPreferencesFragment);
R.id.settingsPreferencesFragment,
R.id.hashTagFragment);
private ActivityMainBinding binding; private ActivityMainBinding binding;
private LiveData<NavController> currentNavControllerLiveData; private LiveData<NavController> currentNavControllerLiveData;

18
app/src/main/java/awais/instagrabber/activities/SavedViewer.java

@ -33,7 +33,7 @@ import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.ActivitySavedBinding; import awais.instagrabber.databinding.ActivitySavedBinding;
import awais.instagrabber.fragments.main.viewmodels.ProfilePostsViewModel;
import awais.instagrabber.fragments.main.viewmodels.PostsViewModel;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.ItemGetter; import awais.instagrabber.interfaces.ItemGetter;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
@ -58,7 +58,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
private Resources resources; private Resources resources;
private ArrayList<PostModel> selectedItems = new ArrayList<>(); private ArrayList<PostModel> selectedItems = new ArrayList<>();
private ActionMode actionMode; private ActionMode actionMode;
private ProfilePostsViewModel profilePostsViewModel;
private PostsViewModel postsViewModel;
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
@ -100,14 +100,14 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
@Override @Override
public void onResult(final PostModel[] result) { public void onResult(final PostModel[] result) {
if (result != null) { if (result != null) {
final List<PostModel> current = profilePostsViewModel.getList().getValue();
final List<PostModel> current = postsViewModel.getList().getValue();
final List<PostModel> resultList = Arrays.asList(result); final List<PostModel> resultList = Arrays.asList(result);
if (current == null) { if (current == null) {
profilePostsViewModel.getList().postValue(resultList);
postsViewModel.getList().postValue(resultList);
} else { } else {
final List<PostModel> currentCopy = new ArrayList<>(current); final List<PostModel> currentCopy = new ArrayList<>(current);
currentCopy.addAll(resultList); currentCopy.addAll(resultList);
profilePostsViewModel.getList().postValue(currentCopy);
postsViewModel.getList().postValue(currentCopy);
} }
savedBinding.mainPosts.post(() -> { savedBinding.mainPosts.post(() -> {
savedBinding.mainPosts.setNestedScrollingEnabled(true); savedBinding.mainPosts.setNestedScrollingEnabled(true);
@ -160,7 +160,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
return; return;
} }
profilePostsViewModel = new ViewModelProvider(this).get(ProfilePostsViewModel.class);
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
postsAdapter = new PostsAdapter((postModel, position) -> { postsAdapter = new PostsAdapter((postModel, position) -> {
if (postsAdapter.isSelecting()) { if (postsAdapter.isSelecting()) {
if (actionMode == null) return; if (actionMode == null) return;
@ -189,7 +189,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
return true; return true;
}); });
savedBinding.mainPosts.setAdapter(postsAdapter); savedBinding.mainPosts.setAdapter(postsAdapter);
profilePostsViewModel.getList().observe(this, postsAdapter::submitList);
postsViewModel.getList().observe(this, postsAdapter::submitList);
savedBinding.swipeRefreshLayout.setRefreshing(true); savedBinding.swipeRefreshLayout.setRefreshing(true);
setSupportActionBar(savedBinding.toolbar.toolbar); setSupportActionBar(savedBinding.toolbar.toolbar);
savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved : savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved :
@ -211,7 +211,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
itemGetter = itemGetType -> { itemGetter = itemGetType -> {
if (itemGetType == ItemGetType.SAVED_ITEMS) if (itemGetType == ItemGetType.SAVED_ITEMS)
return profilePostsViewModel.getList().getValue();
return postsViewModel.getList().getValue();
return null; return null;
}; };
@ -243,7 +243,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
public void onRefresh() { public void onRefresh() {
if (lazyLoader != null) lazyLoader.resetState(); if (lazyLoader != null) lazyLoader.resetState();
stopCurrentExecutor(); stopCurrentExecutor();
profilePostsViewModel.getList().postValue(Collections.emptyList());
postsViewModel.getList().postValue(Collections.emptyList());
selectedItems.clear(); selectedItems.clear();
if (postsAdapter != null) { if (postsAdapter != null) {
// postsAdapter.isSelecting = false; // postsAdapter.isSelecting = false;

310
app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java

@ -0,0 +1,310 @@
package awais.instagrabber.fragments;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HashtagFetcher;
import awais.instagrabber.asyncs.PostsFetcher;
import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
import awais.instagrabber.customviews.PrimaryActionModeCallback;
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.NestedCoordinatorLayout;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.FragmentHashtagBinding;
import awais.instagrabber.fragments.main.viewmodels.PostsViewModel;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class HashTagFragment extends Fragment {
private static final String TAG = "HashTagFragment";
private MainActivity fragmentActivity;
private FragmentHashtagBinding binding;
private NestedCoordinatorLayout root;
private boolean shouldRefresh = true;
private String hashtag;
private HashtagModel hashtagModel;
private PostsViewModel postsViewModel;
private PostsAdapter postsAdapter;
private ActionMode actionMode;
private boolean hasNextPage;
private String endCursor;
private AsyncTask<?, ?, ?> currentlyExecuting;
private boolean isLoggedIn;
private StoryModel[] storyModels;
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override
public void handleOnBackPressed() {
if (postsAdapter == null) {
setEnabled(false);
remove();
return;
}
postsAdapter.clearSelection();
setEnabled(false);
remove();
}
};
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
R.menu.multi_select_download_menu,
new PrimaryActionModeCallback.CallbacksHelper() {
@Override
public void onDestroy(final ActionMode mode) {
onBackPressedCallback.handleOnBackPressed();
}
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
if (item.getItemId() == R.id.action_download) {
if (postsAdapter == null || hashtag == null) {
return false;
}
Utils.batchDownload(requireContext(),
hashtag,
DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels());
checkAndResetAction();
return true;
}
return false;
}
});
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override
public void onResult(final PostModel[] result) {
binding.swipeRefreshLayout.setRefreshing(false);
if (result == null) return;
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
final List<PostModel> postModels = postsViewModel.getList().getValue();
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
finalList.addAll(Arrays.asList(result));
postsViewModel.getList().postValue(finalList);
PostModel model = null;
if (result.length != 0) {
model = result[result.length - 1];
}
if (model == null) return;
endCursor = model.getEndCursor();
hasNextPage = model.hasNextPage();
model.setPageCursor(false, null);
}
};
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity();
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
return root;
}
binding = FragmentHashtagBinding.inflate(inflater, container, false);
root = binding.getRoot();
return root;
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init();
shouldRefresh = false;
}
@Override
public void onDestroy() {
super.onDestroy();
if (postsViewModel != null) {
postsViewModel.getList().postValue(Collections.emptyList());
}
}
private void init() {
if (getArguments() == null) return;
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
hashtag = fragmentArgs.getHashtag();
setTitle();
setupPosts();
fetchHashtagModel();
}
private void setupPosts() {
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
binding.mainPosts.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
postsAdapter = new PostsAdapter((postModel, position) -> {
if (postsAdapter.isSelecting()) {
if (actionMode == null) return;
final String title = getString(R.string.number_selected, postsAdapter.getSelectedModels().size());
actionMode.setTitle(title);
return;
}
if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, hashtag)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
}, (model, position) -> {
if (!postsAdapter.isSelecting()) {
checkAndResetAction();
return true;
}
if (onBackPressedCallback.isEnabled()) {
return true;
}
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
onBackPressedCallback.setEnabled(true);
actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1);
actionMode.setTitle(title);
onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
return true;
});
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (!hasNextPage) return;
binding.swipeRefreshLayout.setRefreshing(true);
fetchPosts();
endCursor = null;
});
binding.mainPosts.addOnScrollListener(lazyLoader);
}
private void fetchHashtagModel() {
stopCurrentExecutor();
binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new HashtagFetcher(hashtag.substring(1), result -> {
hashtagModel = result;
binding.swipeRefreshLayout.setRefreshing(false);
if (hashtagModel == null) {
Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
return;
}
fetchPosts();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void fetchPosts() {
stopCurrentExecutor();
binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new PostsFetcher(hashtag, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (isLoggedIn) {
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
storyModels = stories;
if (stories != null && stories.length > 0) {
binding.mainHashtagImage.setStoriesBorder();
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
binding.btnFollowTag.setText(hashtagModel.getFollowing() ? R.string.unfollow : R.string.follow);
ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf(
ContextCompat.getColor(requireContext(), hashtagModel.getFollowing()
? R.color.btn_purple_background
: R.color.btn_pink_background)));
} else {
binding.btnFollowTag.setText(Utils.dataBox.getFavorite(hashtag) != null
? R.string.unfavorite_short
: R.string.favorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf(
ContextCompat.getColor(requireContext(), Utils.dataBox.getFavorite(hashtag) != null
? R.color.btn_purple_background
: R.color.btn_pink_background)));
}
binding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic());
final String postCount = String.valueOf(hashtagModel.getPostCount());
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count, postCount));
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
binding.mainTagPostCount.setText(span);
binding.mainTagPostCount.setVisibility(View.VISIBLE);
}
public void stopCurrentExecutor() {
if (currentlyExecuting != null) {
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e);
}
}
}
private void setTitle() {
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(hashtag.substring(1));
}
}
private boolean checkAndResetAction() {
if (!onBackPressedCallback.isEnabled() && actionMode == null) {
return false;
}
if (onBackPressedCallback.isEnabled()) {
onBackPressedCallback.setEnabled(false);
onBackPressedCallback.remove();
}
if (actionMode != null) {
actionMode.finish();
actionMode = null;
}
return true;
}
}

3
app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java

@ -211,7 +211,8 @@ public class FeedFragment extends Fragment {
// }); // });
// builder.show(); // builder.show();
if (isHashtag) { if (isHashtag) {
// hashtag...
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToHashTagFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return; return;
} }
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToProfileFragment("@" + text); final NavDirections action = FeedFragmentDirections.actionFeedFragmentToProfileFragment("@" + text);

57
app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java

@ -1,57 +0,0 @@
package awais.instagrabber.fragments.main;
import android.content.Intent;
import android.view.View;
import awais.instagrabber.MainHelper;
import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.databinding.FragmentProfileBinding;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox;
import awais.instagrabber.utils.Utils;
public class ProfileActionListener implements View.OnClickListener {
private String cookie;
private boolean isLoggedIn;
private ProfileModel profileModel;
private String userQuery;
private FragmentProfileBinding binding;
private LocationModel locationModel;
public ProfileActionListener(final String cookie, final boolean isLoggedIn, final ProfileModel profileModel, final String userQuery, final FragmentProfileBinding binding, final LocationModel locationModel) {
this.cookie = cookie;
this.isLoggedIn = isLoggedIn;
this.profileModel = profileModel;
this.userQuery = userQuery;
this.binding = binding;
this.locationModel = locationModel;
}
@Override
public void onClick(final View v) {
// else if (v == binding.btnFollow) {
//
// } else if (v == mainActivity.mainBinding.profileView.btnRestrict && isLoggedIn) {
// new ProfileAction().execute("restrict");
// } else if (v == mainActivity.mainBinding.profileView.btnSaved && !isSelf) {
// new ProfileAction().execute("block");
// } else if (v == mainActivity.mainBinding.profileView.btnFollowTag) {
// new ProfileAction().execute("followtag");
// } else if (v == mainActivity.mainBinding.profileView.btnTagged || (v == mainActivity.mainBinding.profileView.btnRestrict && !isLoggedIn)) {
// mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId())
// .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
// );
// } else if (v == mainActivity.mainBinding.profileView.btnSaved) {
//
// } else if (v == mainActivity.mainBinding.profileView.btnLiked) {
//
// }
}
}

17
app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java

@ -52,7 +52,7 @@ import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.FragmentProfileBinding; import awais.instagrabber.databinding.FragmentProfileBinding;
import awais.instagrabber.fragments.main.viewmodels.ProfilePostsViewModel;
import awais.instagrabber.fragments.main.viewmodels.PostsViewModel;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
@ -81,7 +81,7 @@ public class ProfileFragment extends Fragment {
private String cookie; private String cookie;
private String username; private String username;
private ProfileModel profileModel; private ProfileModel profileModel;
private ProfilePostsViewModel profilePostsViewModel;
private PostsViewModel postsViewModel;
private PostsAdapter postsAdapter; private PostsAdapter postsAdapter;
private ActionMode actionMode; private ActionMode actionMode;
private Handler usernameSettingHandler; private Handler usernameSettingHandler;
@ -133,7 +133,6 @@ public class ProfileFragment extends Fragment {
return false; return false;
} }
}); });
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() { private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override @Override
public void onResult(final PostModel[] result) { public void onResult(final PostModel[] result) {
@ -141,10 +140,10 @@ public class ProfileFragment extends Fragment {
if (result != null) { if (result != null) {
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
// final int oldSize = mainActivity.allItems.size(); // final int oldSize = mainActivity.allItems.size();
final List<PostModel> postModels = profilePostsViewModel.getList().getValue();
final List<PostModel> postModels = postsViewModel.getList().getValue();
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels); final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
finalList.addAll(Arrays.asList(result)); finalList.addAll(Arrays.asList(result));
profilePostsViewModel.getList().postValue(finalList);
postsViewModel.getList().postValue(finalList);
PostModel model = null; PostModel model = null;
if (result.length != 0) { if (result.length != 0) {
model = result[result.length - 1]; model = result[result.length - 1];
@ -202,8 +201,8 @@ public class ProfileFragment extends Fragment {
if (usernameSettingHandler != null) { if (usernameSettingHandler != null) {
usernameSettingHandler.removeCallbacks(usernameSettingRunnable); usernameSettingHandler.removeCallbacks(usernameSettingRunnable);
} }
if (profilePostsViewModel != null) {
profilePostsViewModel.getList().postValue(Collections.emptyList());
if (postsViewModel != null) {
postsViewModel.getList().postValue(Collections.emptyList());
} }
} }
@ -608,7 +607,7 @@ public class ProfileFragment extends Fragment {
} }
private void setupPosts() { private void setupPosts() {
profilePostsViewModel = new ViewModelProvider(this).get(ProfilePostsViewModel.class);
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110)); final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
binding.mainPosts.setLayoutManager(layoutManager); binding.mainPosts.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
@ -641,7 +640,7 @@ public class ProfileFragment extends Fragment {
onBackPressedDispatcher.addCallback(onBackPressedCallback); onBackPressedDispatcher.addCallback(onBackPressedCallback);
return true; return true;
}); });
profilePostsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter); binding.mainPosts.setAdapter(postsAdapter);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (!hasNextPage) return; if (!hasNextPage) return;

2
app/src/main/java/awais/instagrabber/fragments/main/viewmodels/ProfilePostsViewModel.java → app/src/main/java/awais/instagrabber/fragments/main/viewmodels/PostsViewModel.java

@ -7,7 +7,7 @@ import java.util.List;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
public class ProfilePostsViewModel extends ViewModel {
public class PostsViewModel extends ViewModel {
private MutableLiveData<List<PostModel>> list; private MutableLiveData<List<PostModel>> list;
public MutableLiveData<List<PostModel>> getList() { public MutableLiveData<List<PostModel>> getList() {

77
app/src/main/res/layout/fragment_hashtag.xml

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<awais.instagrabber.customviews.helpers.NestedCoordinatorLayout 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"
android:background="?attr/colorOnPrimarySurface">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorOnPrimarySurface">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll">
<LinearLayout
android:id="@+id/tagInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/profile_info_container_bottom_space"
android:visibility="visible">
<awais.instagrabber.customviews.CircularImageView
android:id="@+id/mainHashtagImage"
android:layout_width="@dimen/profile_picture_size"
android:layout_height="@dimen/profile_picture_size"
android:adjustViewBounds="true"
android:background="?selectableItemBackgroundBorderless" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mainTagPostCount"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:layout_weight="1"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="15sp"
tools:text="35\nPosts" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnFollowTag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/follow"
android:textColor="@color/btn_pink_text_color"
android:textSize="20sp"
android:visibility="gone"
app:backgroundTint="@color/btn_pink_background" />
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mainPosts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:listitem="@layout/item_post" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</awais.instagrabber.customviews.helpers.NestedCoordinatorLayout>

13
app/src/main/res/navigation/feed_nav_graph.xml

@ -16,6 +16,9 @@
<action <action
android:id="@+id/action_feedFragment_to_profileFragment" android:id="@+id/action_feedFragment_to_profileFragment"
app:destination="@id/profileFragment" /> app:destination="@id/profileFragment" />
<action
android:id="@+id/action_feedFragment_to_hashTagFragment"
app:destination="@id/hashTagFragment" />
</fragment> </fragment>
<fragment <fragment
android:id="@+id/storyViewerFragment" android:id="@+id/storyViewerFragment"
@ -44,4 +47,14 @@
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
</fragment> </fragment>
<fragment
android:id="@+id/hashTagFragment"
android:name="awais.instagrabber.fragments.HashTagFragment"
android:label=""
tools:layout="@layout/fragment_hashtag">
<argument
android:name="hashtag"
app:argType="string"
app:nullable="false" />
</fragment>
</navigation> </navigation>
Loading…
Cancel
Save