From 5c273d18a42a8615d63c268966304c8f616dc3c5 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sun, 30 Aug 2020 20:45:37 +0900 Subject: [PATCH] Add HashTag fragment --- .../instagrabber/activities/MainActivity.java | 3 +- .../instagrabber/activities/SavedViewer.java | 18 +- .../fragments/HashTagFragment.java | 310 ++++++++++++++++++ .../fragments/main/FeedFragment.java | 3 +- .../fragments/main/ProfileActionListener.java | 57 ---- .../fragments/main/ProfileFragment.java | 17 +- ...ostsViewModel.java => PostsViewModel.java} | 2 +- app/src/main/res/layout/fragment_hashtag.xml | 77 +++++ .../main/res/navigation/feed_nav_graph.xml | 13 + 9 files changed, 422 insertions(+), 78 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java delete mode 100644 app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java rename app/src/main/java/awais/instagrabber/fragments/main/viewmodels/{ProfilePostsViewModel.java => PostsViewModel.java} (88%) create mode 100644 app/src/main/res/layout/fragment_hashtag.xml diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java index 36043e98..863cfacc 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java @@ -43,7 +43,8 @@ public class MainActivity extends BaseLanguageActivity { R.id.profileFragment, R.id.discoverFragment, R.id.morePreferencesFragment, - R.id.settingsPreferencesFragment); + R.id.settingsPreferencesFragment, + R.id.hashTagFragment); private ActivityMainBinding binding; private LiveData currentNavControllerLiveData; diff --git a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java b/app/src/main/java/awais/instagrabber/activities/SavedViewer.java index a650a8d9..16178f27 100755 --- a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java +++ b/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.RecyclerLazyLoader; 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.ItemGetter; import awais.instagrabber.models.PostModel; @@ -58,7 +58,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr private Resources resources; private ArrayList selectedItems = new ArrayList<>(); private ActionMode actionMode; - private ProfilePostsViewModel profilePostsViewModel; + private PostsViewModel postsViewModel; private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { @@ -100,14 +100,14 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr @Override public void onResult(final PostModel[] result) { if (result != null) { - final List current = profilePostsViewModel.getList().getValue(); + final List current = postsViewModel.getList().getValue(); final List resultList = Arrays.asList(result); if (current == null) { - profilePostsViewModel.getList().postValue(resultList); + postsViewModel.getList().postValue(resultList); } else { final List currentCopy = new ArrayList<>(current); currentCopy.addAll(resultList); - profilePostsViewModel.getList().postValue(currentCopy); + postsViewModel.getList().postValue(currentCopy); } savedBinding.mainPosts.post(() -> { savedBinding.mainPosts.setNestedScrollingEnabled(true); @@ -160,7 +160,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr return; } - profilePostsViewModel = new ViewModelProvider(this).get(ProfilePostsViewModel.class); + postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class); postsAdapter = new PostsAdapter((postModel, position) -> { if (postsAdapter.isSelecting()) { if (actionMode == null) return; @@ -189,7 +189,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr return true; }); savedBinding.mainPosts.setAdapter(postsAdapter); - profilePostsViewModel.getList().observe(this, postsAdapter::submitList); + postsViewModel.getList().observe(this, postsAdapter::submitList); savedBinding.swipeRefreshLayout.setRefreshing(true); setSupportActionBar(savedBinding.toolbar.toolbar); savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved : @@ -211,7 +211,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr itemGetter = itemGetType -> { if (itemGetType == ItemGetType.SAVED_ITEMS) - return profilePostsViewModel.getList().getValue(); + return postsViewModel.getList().getValue(); return null; }; @@ -243,7 +243,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr public void onRefresh() { if (lazyLoader != null) lazyLoader.resetState(); stopCurrentExecutor(); - profilePostsViewModel.getList().postValue(Collections.emptyList()); + postsViewModel.getList().postValue(Collections.emptyList()); selectedItems.clear(); if (postsAdapter != null) { // postsAdapter.isSelecting = false; diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java new file mode 100644 index 00000000..689c7769 --- /dev/null +++ b/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 postsFetchListener = new FetchListener() { + @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 postModels = postsViewModel.getList().getValue(); + final List 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; + } +} diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index 4d7f6e4f..f33f7a06 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -211,7 +211,8 @@ public class FeedFragment extends Fragment { // }); // builder.show(); if (isHashtag) { - // hashtag... + final NavDirections action = FeedFragmentDirections.actionFeedFragmentToHashTagFragment(text); + NavHostFragment.findNavController(this).navigate(action); return; } final NavDirections action = FeedFragmentDirections.actionFeedFragmentToProfileFragment("@" + text); diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java deleted file mode 100644 index 3c4a4721..00000000 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileActionListener.java +++ /dev/null @@ -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) { - // - // } - } -} diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java index cc075b85..9d6f0b80 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java +++ b/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.RecyclerLazyLoader; 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.models.PostModel; import awais.instagrabber.models.ProfileModel; @@ -81,7 +81,7 @@ public class ProfileFragment extends Fragment { private String cookie; private String username; private ProfileModel profileModel; - private ProfilePostsViewModel profilePostsViewModel; + private PostsViewModel postsViewModel; private PostsAdapter postsAdapter; private ActionMode actionMode; private Handler usernameSettingHandler; @@ -133,7 +133,6 @@ public class ProfileFragment extends Fragment { return false; } }); - private final FetchListener postsFetchListener = new FetchListener() { @Override public void onResult(final PostModel[] result) { @@ -141,10 +140,10 @@ public class ProfileFragment extends Fragment { if (result != null) { binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); // final int oldSize = mainActivity.allItems.size(); - final List postModels = profilePostsViewModel.getList().getValue(); + final List postModels = postsViewModel.getList().getValue(); final List finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels); finalList.addAll(Arrays.asList(result)); - profilePostsViewModel.getList().postValue(finalList); + postsViewModel.getList().postValue(finalList); PostModel model = null; if (result.length != 0) { model = result[result.length - 1]; @@ -202,8 +201,8 @@ public class ProfileFragment extends Fragment { if (usernameSettingHandler != null) { 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() { - profilePostsViewModel = new ViewModelProvider(this).get(ProfilePostsViewModel.class); + 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))); @@ -641,7 +640,7 @@ public class ProfileFragment extends Fragment { onBackPressedDispatcher.addCallback(onBackPressedCallback); return true; }); - profilePostsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); + postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); binding.mainPosts.setAdapter(postsAdapter); final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { if (!hasNextPage) return; diff --git a/app/src/main/java/awais/instagrabber/fragments/main/viewmodels/ProfilePostsViewModel.java b/app/src/main/java/awais/instagrabber/fragments/main/viewmodels/PostsViewModel.java similarity index 88% rename from app/src/main/java/awais/instagrabber/fragments/main/viewmodels/ProfilePostsViewModel.java rename to app/src/main/java/awais/instagrabber/fragments/main/viewmodels/PostsViewModel.java index 5c4c645c..d19d0140 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/viewmodels/ProfilePostsViewModel.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/viewmodels/PostsViewModel.java @@ -7,7 +7,7 @@ import java.util.List; import awais.instagrabber.models.PostModel; -public class ProfilePostsViewModel extends ViewModel { +public class PostsViewModel extends ViewModel { private MutableLiveData> list; public MutableLiveData> getList() { diff --git a/app/src/main/res/layout/fragment_hashtag.xml b/app/src/main/res/layout/fragment_hashtag.xml new file mode 100644 index 00000000..3f7c355e --- /dev/null +++ b/app/src/main/res/layout/fragment_hashtag.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/feed_nav_graph.xml b/app/src/main/res/navigation/feed_nav_graph.xml index 0dc1f3f6..89fc12f7 100644 --- a/app/src/main/res/navigation/feed_nav_graph.xml +++ b/app/src/main/res/navigation/feed_nav_graph.xml @@ -16,6 +16,9 @@ + + + + \ No newline at end of file