Browse Source

Fix re-init of fragments on tab change

renovate/androidx.fragment-fragment-ktx-1.x
Ammar Githam 3 years ago
parent
commit
74434aa3b3
  1. 148
      app/src/main/java/awais/instagrabber/activities/MainActivity.kt
  2. 77
      app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java
  3. 29
      app/src/main/java/awais/instagrabber/customviews/helpers/PostFetcher.java
  4. 78
      app/src/main/java/awais/instagrabber/dialogs/PostLoadingDialogFragment.kt
  5. 2
      app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java
  6. 2
      app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java
  7. 49
      app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt
  8. 39
      app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt
  9. 2
      app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java
  10. 6
      app/src/main/java/awais/instagrabber/models/Tab.kt
  11. 23
      app/src/main/java/awais/instagrabber/utils/BarinstaDeepLinkHelper.kt
  12. 33
      app/src/main/java/awais/instagrabber/utils/KeywordsFilterUtils.kt
  13. 30
      app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt
  14. 97
      app/src/main/java/awais/instagrabber/viewmodels/MediaViewModel.java
  15. 2
      app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt
  16. 3
      app/src/main/res/layout/activity_main.xml
  17. 28
      app/src/main/res/menu/bottom_nav_menu.xml
  18. 333
      app/src/main/res/navigation/direct_messages_nav_graph.xml
  19. 518
      app/src/main/res/navigation/discover_nav_graph.xml
  20. 484
      app/src/main/res/navigation/favorites_nav_graph.xml
  21. 520
      app/src/main/res/navigation/feed_nav_graph.xml
  22. 539
      app/src/main/res/navigation/more_nav_graph.xml
  23. 495
      app/src/main/res/navigation/notification_viewer_nav_graph.xml
  24. 567
      app/src/main/res/navigation/profile_nav_graph.xml
  25. 12
      app/src/main/res/navigation/root_nav_graph.xml
  26. 108
      app/src/main/res/navigation/settings_nav_graph.xml
  27. 9
      app/src/main/res/values/ids.xml

148
app/src/main/java/awais/instagrabber/activities/MainActivity.kt

@ -14,8 +14,6 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@ -26,9 +24,7 @@ import androidx.core.view.WindowInsetsCompat
import androidx.emoji.text.EmojiCompat import androidx.emoji.text.EmojiCompat
import androidx.emoji.text.EmojiCompat.InitCallback import androidx.emoji.text.EmojiCompat.InitCallback
import androidx.emoji.text.FontRequestEmojiCompatConfig import androidx.emoji.text.FontRequestEmojiCompatConfig
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.NavGraph import androidx.navigation.NavGraph
@ -36,7 +32,6 @@ import androidx.navigation.NavGraphNavigator
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.* import androidx.navigation.ui.*
import awais.instagrabber.BuildConfig import awais.instagrabber.BuildConfig
import awais.instagrabber.NavGraphDirections
import awais.instagrabber.R import awais.instagrabber.R
import awais.instagrabber.customviews.emoji.EmojiVariantManager import awais.instagrabber.customviews.emoji.EmojiVariantManager
import awais.instagrabber.customviews.helpers.RootViewDeferringInsetsCallback import awais.instagrabber.customviews.helpers.RootViewDeferringInsetsCallback
@ -54,37 +49,28 @@ import awais.instagrabber.utils.*
import awais.instagrabber.utils.AppExecutors.tasksThread import awais.instagrabber.utils.AppExecutors.tasksThread
import awais.instagrabber.utils.DownloadUtils.ReselectDocumentTreeException import awais.instagrabber.utils.DownloadUtils.ReselectDocumentTreeException
import awais.instagrabber.utils.TextUtils.isEmpty import awais.instagrabber.utils.TextUtils.isEmpty
import awais.instagrabber.utils.TextUtils.shortcodeToId
import awais.instagrabber.utils.emoji.EmojiParser import awais.instagrabber.utils.emoji.EmojiParser
import awais.instagrabber.viewmodels.AppStateViewModel import awais.instagrabber.viewmodels.AppStateViewModel
import awais.instagrabber.viewmodels.DirectInboxViewModel import awais.instagrabber.viewmodels.DirectInboxViewModel
import awais.instagrabber.webservices.GraphQLRepository
import awais.instagrabber.webservices.MediaRepository
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.* import java.util.*
class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedListener {
class MainActivity : BaseLanguageActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
// private var currentNavControllerLiveData: LiveData<NavController>? = null
private var searchMenuItem: MenuItem? = null private var searchMenuItem: MenuItem? = null
private var startNavRootId: Int = 0 private var startNavRootId: Int = 0
// private var firstFragmentGraphIndex = 0
private var lastSelectedNavMenuId = 0 private var lastSelectedNavMenuId = 0
private var isActivityCheckerServiceBound = false private var isActivityCheckerServiceBound = false
private var isBackStackEmpty = false
private var isLoggedIn = false private var isLoggedIn = false
private var deviceUuid: String? = null private var deviceUuid: String? = null
private var csrfToken: String? = null private var csrfToken: String? = null
@ -106,8 +92,6 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
isActivityCheckerServiceBound = false isActivityCheckerServiceBound = false
} }
} }
private val mediaRepository: MediaRepository by lazy { MediaRepository.getInstance() }
private val graphQLRepository: GraphQLRepository by lazy { GraphQLRepository.getInstance() }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
try { try {
@ -156,7 +140,6 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
if (isLoggedIn && Utils.settingsHelper.getBoolean(PreferenceKeys.CHECK_ACTIVITY)) { if (isLoggedIn && Utils.settingsHelper.getBoolean(PreferenceKeys.CHECK_ACTIVITY)) {
bindActivityCheckerService() bindActivityCheckerService()
} }
supportFragmentManager.addOnBackStackChangedListener(this)
// Initialise the internal map // Initialise the internal map
tasksThread.execute { tasksThread.execute {
EmojiParser.getInstance(this) EmojiParser.getInstance(this)
@ -235,7 +218,6 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu) menuInflater.inflate(R.menu.main_menu, menu)
searchMenuItem = menu.findItem(R.id.search) searchMenuItem = menu.findItem(R.id.search)
// val navController = currentNavControllerLiveData?.value
val currentDestination = navController.currentDestination val currentDestination = navController.currentDestination
if (currentDestination != null) { if (currentDestination != null) {
val backStack = navController.backQueue val backStack = navController.backQueue
@ -246,9 +228,8 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.search) { if (item.itemId == R.id.search) {
// val navController = currentNavControllerLiveData?.value ?: return false
try { try {
navController.navigate(R.id.action_global_search)
navController.navigate(getSearchDeepLink())
return true return true
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "onOptionsItemSelected: ", e) Log.e(TAG, "onOptionsItemSelected: ", e)
@ -301,27 +282,24 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
instance = null instance = null
} }
override fun onBackPressed() {
val backStack = navController.backQueue
val currentNavControllerBackStack = backStack.size
if (isTaskRoot && isBackStackEmpty && currentNavControllerBackStack == 2) {
finishAfterTransition()
return
}
if (!isFinishing) {
try {
super.onBackPressed()
} catch (e: Exception) {
Log.e(TAG, "onBackPressed: ", e)
finish()
}
}
}
override fun onBackStackChanged() {
val backStackEntryCount = supportFragmentManager.backStackEntryCount
isBackStackEmpty = backStackEntryCount == 0
}
// override fun onBackPressed() {
// Log.d(TAG, "onBackPressed: ")
// navController.navigateUp()
// val backStack = navController.backQueue
// val currentNavControllerBackStack = backStack.size
// if (isTaskRoot && isBackStackEmpty && currentNavControllerBackStack == 2) {
// finishAfterTransition()
// return
// }
// if (!isFinishing) {
// try {
// super.onBackPressed()
// } catch (e: Exception) {
// Log.e(TAG, "onBackPressed: ", e)
// finish()
// }
// }
// }
private fun createNotificationChannels() { private fun createNotificationChannels() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
@ -374,16 +352,10 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
val navigator = navigatorProvider.getNavigator<NavGraphNavigator>("navigation") val navigator = navigatorProvider.getNavigator<NavGraphNavigator>("navigation")
val rootNavGraph = NavGraph(navigator) val rootNavGraph = NavGraph(navigator)
val navInflater = navController.navInflater val navInflater = navController.navInflater
val destinations = currentTabs.map {
val navGraph = navInflater.inflate(R.navigation.nav_graph)
navGraph.id = it.navigationRootId
navGraph.label = "${it.title}_nav_graph".lowercase(Locale.getDefault())
navGraph.setStartDestination(it.startDestinationFragmentId)
return@map navGraph
}
val topLevelDestinations = currentTabs.map { navInflater.inflate(it.navigationResId) }
rootNavGraph.id = R.id.root_nav_graph rootNavGraph.id = R.id.root_nav_graph
rootNavGraph.label = "root_nav_graph" rootNavGraph.label = "root_nav_graph"
rootNavGraph.addDestinations(destinations)
rootNavGraph.addDestinations(topLevelDestinations)
rootNavGraph.setStartDestination(if (startNavRootId != 0) startNavRootId else R.id.profile_nav_graph) rootNavGraph.setStartDestination(if (startNavRootId != 0) startNavRootId else R.id.profile_nav_graph)
navController.graph = rootNavGraph navController.graph = rootNavGraph
binding.bottomNavView.setupWithNavController(navController) binding.bottomNavView.setupWithNavController(navController)
@ -536,8 +508,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
fun navigateToThread(threadId: String?, threadTitle: String?) { fun navigateToThread(threadId: String?, threadTitle: String?) {
if (threadId == null || threadTitle == null) return if (threadId == null || threadTitle == null) return
try { try {
val action = NavGraphDirections.actionGlobalDirectThread(threadId, threadTitle)
navController.navigate(action)
navController.navigate(getDirectThreadDeepLink(threadId, threadTitle))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "navigateToThread: ", e) Log.e(TAG, "navigateToThread: ", e)
} }
@ -564,8 +535,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
private fun showProfileView(intentModel: IntentModel) { private fun showProfileView(intentModel: IntentModel) {
try { try {
val username = intentModel.text val username = intentModel.text
val action = NavGraphDirections.actionGlobalProfile().setUsername(username)
navController.navigate(action)
navController.navigate(getProfileDeepLink(username))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "showProfileView: ", e) Log.e(TAG, "showProfileView: ", e)
} }
@ -574,33 +544,10 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
private fun showPostView(intentModel: IntentModel) { private fun showPostView(intentModel: IntentModel) {
val shortCode = intentModel.text val shortCode = intentModel.text
// Log.d(TAG, "shortCode: " + shortCode); // Log.d(TAG, "shortCode: " + shortCode);
val alertDialog = AlertDialog.Builder(this)
.setCancelable(false)
.setView(R.layout.dialog_opening_post)
.create()
alertDialog.show()
lifecycleScope.launch(Dispatchers.IO) {
try {
val media = if (isLoggedIn) mediaRepository.fetch(shortcodeToId(shortCode)) else graphQLRepository.fetchPost(shortCode)
withContext(Dispatchers.Main) {
if (media == null) {
Toast.makeText(applicationContext, R.string.post_not_found, Toast.LENGTH_SHORT).show()
return@withContext
}
try {
val action = NavGraphDirections.actionGlobalPost(media, 0)
navController.navigate(action)
} catch (e: Exception) {
Log.e(TAG, "showPostView: ", e)
}
}
} catch (e: Exception) {
Log.e(TAG, "showPostView: ", e)
} finally {
withContext(Dispatchers.Main) {
alertDialog.dismiss()
}
}
try {
navController.navigate(getPostDeepLink(shortCode))
} catch (e: Exception) {
Log.e(TAG, "showPostView: ", e)
} }
} }
@ -608,8 +555,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
val locationId = intentModel.text val locationId = intentModel.text
// Log.d(TAG, "locationId: " + locationId); // Log.d(TAG, "locationId: " + locationId);
try { try {
val action = NavGraphDirections.actionGlobalLocation(locationId.toLong())
navController.navigate(action)
navController.navigate(getLocationDeepLink(locationId))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "showLocationView: ", e) Log.e(TAG, "showLocationView: ", e)
} }
@ -619,8 +565,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
val hashtag = intentModel.text val hashtag = intentModel.text
// Log.d(TAG, "hashtag: " + hashtag); // Log.d(TAG, "hashtag: " + hashtag);
try { try {
val action = NavGraphDirections.actionGlobalHashTag(hashtag)
navController.navigate(action)
navController.navigate(getHashtagDeepLink(hashtag))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "showHashtagView: ", e) Log.e(TAG, "showHashtagView: ", e)
} }
@ -628,8 +573,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
private fun showActivityView() { private fun showActivityView() {
try { try {
val action = NavGraphDirections.actionGlobalNotifications().apply { type = "notif" }
navController.navigate(action)
navController.navigate(getNotificationsDeepLink("notif"))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "showActivityView: ", e) Log.e(TAG, "showActivityView: ", e)
} }
@ -649,21 +593,21 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
val bottomNavView: BottomNavigationView val bottomNavView: BottomNavigationView
get() = binding.bottomNavView get() = binding.bottomNavView
fun setCollapsingView(view: View) {
try {
binding.collapsingToolbarLayout.addView(view, 0)
} catch (e: Exception) {
Log.e(TAG, "setCollapsingView: ", e)
}
}
fun removeCollapsingView(view: View) {
try {
binding.collapsingToolbarLayout.removeView(view)
} catch (e: Exception) {
Log.e(TAG, "removeCollapsingView: ", e)
}
}
// fun setCollapsingView(view: View) {
// try {
// binding.collapsingToolbarLayout.addView(view, 0)
// } catch (e: Exception) {
// Log.e(TAG, "setCollapsingView: ", e)
// }
// }
//
// fun removeCollapsingView(view: View) {
// try {
// binding.collapsingToolbarLayout.removeView(view)
// } catch (e: Exception) {
// Log.e(TAG, "removeCollapsingView: ", e)
// }
// }
fun resetToolbar() { fun resetToolbar() {
binding.appBarLayout.visibility = View.VISIBLE binding.appBarLayout.visibility = View.VISIBLE

77
app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java

@ -3,12 +3,11 @@ package awais.instagrabber.customviews;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner; import androidx.lifecycle.ViewModelStoreOwner;
import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.LinearSmoothScroller;
@ -27,24 +26,18 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Function;
import awais.instagrabber.adapters.FeedAdapterV2; import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.PostFetcher; import awais.instagrabber.customviews.helpers.PostFetcher;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge; import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge;
import awais.instagrabber.fragments.settings.PreferenceKeys;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.utils.KeywordsFilterUtils;
import awais.instagrabber.utils.ResponseBodyUtils; import awais.instagrabber.utils.ResponseBodyUtils;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awais.instagrabber.viewmodels.MediaViewModel; import awais.instagrabber.viewmodels.MediaViewModel;
import awais.instagrabber.workers.DownloadWorker; import awais.instagrabber.workers.DownloadWorker;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class PostsRecyclerView extends RecyclerView { public class PostsRecyclerView extends RecyclerView {
private static final String TAG = "PostsRecyclerView"; private static final String TAG = "PostsRecyclerView";
@ -52,7 +45,6 @@ public class PostsRecyclerView extends RecyclerView {
private PostsLayoutPreferences layoutPreferences; private PostsLayoutPreferences layoutPreferences;
private PostFetcher.PostFetchService postFetchService; private PostFetcher.PostFetchService postFetchService;
private Transition transition; private Transition transition;
private PostFetcher postFetcher;
private ViewModelStoreOwner viewModelStoreOwner; private ViewModelStoreOwner viewModelStoreOwner;
private FeedAdapterV2 feedAdapter; private FeedAdapterV2 feedAdapter;
private LifecycleOwner lifeCycleOwner; private LifecycleOwner lifeCycleOwner;
@ -63,40 +55,9 @@ public class PostsRecyclerView extends RecyclerView {
private FeedAdapterV2.FeedItemCallback feedItemCallback; private FeedAdapterV2.FeedItemCallback feedItemCallback;
private boolean shouldScrollToTop; private boolean shouldScrollToTop;
private FeedAdapterV2.SelectionModeCallback selectionModeCallback; private FeedAdapterV2.SelectionModeCallback selectionModeCallback;
private Function<ViewGroup, View> headerViewCreator;
private Function<View, Void> headerBinder;
private boolean refresh = true;
private final List<FetchStatusChangeListener> fetchStatusChangeListeners = new ArrayList<>(); private final List<FetchStatusChangeListener> fetchStatusChangeListeners = new ArrayList<>();
private final FetchListener<List<Media>> fetchListener = new FetchListener<List<Media>>() {
@Override
public void onResult(final List<Media> result) {
if (refresh) {
refresh = false;
mediaViewModel.getList().postValue(result);
shouldScrollToTop = true;
dispatchFetchStatus();
return;
}
final List<Media> models = mediaViewModel.getList().getValue();
final List<Media> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
if (settingsHelper.getBoolean(PreferenceKeys.TOGGLE_KEYWORD_FILTER)) {
final ArrayList<String> items = new ArrayList<>(settingsHelper.getStringSet(PreferenceKeys.KEYWORD_FILTERS));
modelsCopy.addAll(new KeywordsFilterUtils(items).filter(result));
} else {
modelsCopy.addAll(result);
}
mediaViewModel.getList().postValue(modelsCopy);
dispatchFetchStatus();
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
};
private final RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) { private final RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) {
@Override @Override
protected int getVerticalSnapPreference() { protected int getVerticalSnapPreference() {
@ -199,18 +160,22 @@ public class PostsRecyclerView extends RecyclerView {
private void initSelf() { private void initSelf() {
try { try {
mediaViewModel = new ViewModelProvider(viewModelStoreOwner).get(MediaViewModel.class);
mediaViewModel = new ViewModelProvider(
viewModelStoreOwner,
new MediaViewModel.ViewModelFactory(postFetchService)
).get(MediaViewModel.class);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "initSelf: ", e); Log.e(TAG, "initSelf: ", e);
} }
if (mediaViewModel == null) return; if (mediaViewModel == null) return;
mediaViewModel.getList().observe(lifeCycleOwner, list -> feedAdapter.submitList(list, () -> {
final LiveData<List<Media>> mediaListLiveData = mediaViewModel.getList();
mediaListLiveData.observe(lifeCycleOwner, list -> feedAdapter.submitList(list, () -> {
dispatchFetchStatus();
// postDelayed(this::fetchMoreIfPossible, 1000); // postDelayed(this::fetchMoreIfPossible, 1000);
if (!shouldScrollToTop) return; if (!shouldScrollToTop) return;
shouldScrollToTop = false; shouldScrollToTop = false;
post(() -> smoothScrollToPosition(0)); post(() -> smoothScrollToPosition(0));
})); }));
postFetcher = new PostFetcher(postFetchService, fetchListener);
if (layoutPreferences.getHasGap()) { if (layoutPreferences.getHasGap()) {
addItemDecoration(gridSpacingItemDecoration); addItemDecoration(gridSpacingItemDecoration);
} }
@ -218,18 +183,20 @@ public class PostsRecyclerView extends RecyclerView {
setNestedScrollingEnabled(true); setNestedScrollingEnabled(true);
setItemAnimator(null); setItemAnimator(null);
lazyLoader = new RecyclerLazyLoaderAtEdge(layoutManager, (page) -> { lazyLoader = new RecyclerLazyLoaderAtEdge(layoutManager, (page) -> {
if (postFetcher.hasMore()) {
postFetcher.fetch();
if (mediaViewModel.hasMore()) {
mediaViewModel.fetch();
dispatchFetchStatus(); dispatchFetchStatus();
} }
}); });
addOnScrollListener(lazyLoader); addOnScrollListener(lazyLoader);
postFetcher.fetch();
dispatchFetchStatus();
if (mediaListLiveData.getValue() == null || mediaListLiveData.getValue().isEmpty()) {
mediaViewModel.fetch();
dispatchFetchStatus();
}
} }
private void fetchMoreIfPossible() { private void fetchMoreIfPossible() {
if (!postFetcher.hasMore()) return;
if (!mediaViewModel.hasMore()) return;
if (feedAdapter.getItemCount() == 0) return; if (feedAdapter.getItemCount() == 0) return;
final LayoutManager layoutManager = getLayoutManager(); final LayoutManager layoutManager = getLayoutManager();
if (!(layoutManager instanceof StaggeredGridLayoutManager)) return; if (!(layoutManager instanceof StaggeredGridLayoutManager)) return;
@ -238,7 +205,7 @@ public class PostsRecyclerView extends RecyclerView {
if (allNoPosition) return; if (allNoPosition) return;
final boolean match = Arrays.stream(itemPositions).anyMatch(position -> position == feedAdapter.getItemCount() - 1); final boolean match = Arrays.stream(itemPositions).anyMatch(position -> position == feedAdapter.getItemCount() - 1);
if (!match) return; if (!match) return;
postFetcher.fetch();
mediaViewModel.fetch();
dispatchFetchStatus(); dispatchFetchStatus();
} }
@ -268,6 +235,7 @@ public class PostsRecyclerView extends RecyclerView {
private List<String> getDisplayUrl(final Media feedModel) { private List<String> getDisplayUrl(final Media feedModel) {
List<String> urls = Collections.emptyList(); List<String> urls = Collections.emptyList();
if (feedModel == null || feedModel.getType() == null) return urls;
switch (feedModel.getType()) { switch (feedModel.getType()) {
case MEDIA_TYPE_IMAGE: case MEDIA_TYPE_IMAGE:
case MEDIA_TYPE_VIDEO: case MEDIA_TYPE_VIDEO:
@ -320,20 +288,18 @@ public class PostsRecyclerView extends RecyclerView {
} }
public void refresh() { public void refresh() {
refresh = true;
shouldScrollToTop = true;
if (lazyLoader != null) { if (lazyLoader != null) {
lazyLoader.resetState(); lazyLoader.resetState();
} }
if (postFetcher != null) {
// mediaViewModel.getList().postValue(Collections.emptyList());
postFetcher.reset();
postFetcher.fetch();
if (mediaViewModel != null) {
mediaViewModel.refresh();
} }
dispatchFetchStatus(); dispatchFetchStatus();
} }
public boolean isFetching() { public boolean isFetching() {
return postFetcher != null && postFetcher.isFetching();
return mediaViewModel != null && mediaViewModel.isFetching();
} }
public PostsRecyclerView addFetchStatusChangeListener(final FetchStatusChangeListener fetchStatusChangeListener) { public PostsRecyclerView addFetchStatusChangeListener(final FetchStatusChangeListener fetchStatusChangeListener) {
@ -369,6 +335,7 @@ public class PostsRecyclerView extends RecyclerView {
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
lifeCycleOwner = null; lifeCycleOwner = null;
initCalled = false;
} }
@Override @Override

29
app/src/main/java/awais/instagrabber/customviews/helpers/PostFetcher.java

@ -21,21 +21,20 @@ public class PostFetcher {
} }
public void fetch() { public void fetch() {
if (!fetching) {
fetching = true;
postFetchService.fetch(new FetchListener<List<Media>>() {
@Override
public void onResult(final List<Media> result) {
fetching = false;
fetchListener.onResult(result);
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
});
}
if (fetching) return;
fetching = true;
postFetchService.fetch(new FetchListener<List<Media>>() {
@Override
public void onResult(final List<Media> result) {
fetching = false;
fetchListener.onResult(result);
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
});
} }
public void reset() { public void reset() {

78
app/src/main/java/awais/instagrabber/dialogs/PostLoadingDialogFragment.kt

@ -0,0 +1,78 @@
package awais.instagrabber.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import awais.instagrabber.R
import awais.instagrabber.utils.*
import awais.instagrabber.utils.extensions.TAG
import awais.instagrabber.webservices.GraphQLRepository
import awais.instagrabber.webservices.MediaRepository
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
class PostLoadingDialogFragment : DialogFragment() {
private var isLoggedIn: Boolean = false
private val mediaRepository: MediaRepository by lazy { MediaRepository.getInstance() }
private val graphQLRepository: GraphQLRepository by lazy { GraphQLRepository.getInstance() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val cookie = Utils.settingsHelper.getString(Constants.COOKIE)
var userId: Long = 0
var csrfToken: String? = null
if (cookie.isNotBlank()) {
userId = getUserIdFromCookie(cookie)
csrfToken = getCsrfTokenFromCookie(cookie)
}
if (cookie.isBlank() || userId == 0L || csrfToken.isNullOrBlank()) {
isLoggedIn = false
return
}
isLoggedIn = true
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext())
.setCancelable(false)
.setView(R.layout.dialog_opening_post)
.create()
}
override fun onAttach(context: Context) {
super.onAttach(context)
val arguments = PostLoadingDialogFragmentArgs.fromBundle(arguments ?: return)
val shortCode = arguments.shortCode
lifecycleScope.launch(Dispatchers.IO) {
try {
val media = if (isLoggedIn) mediaRepository.fetch(TextUtils.shortcodeToId(shortCode)) else graphQLRepository.fetchPost(shortCode)
withContext(Dispatchers.Main) {
if (media == null) {
Toast.makeText(context, R.string.post_not_found, Toast.LENGTH_SHORT).show()
return@withContext
}
try {
findNavController().navigate(PostLoadingDialogFragmentDirections.actionToPost(media, 0))
} catch (e: Exception) {
Log.e(TAG, "showPostView: ", e)
}
}
} catch (e: Exception) {
Log.e(TAG, "showPostView: ", e)
} finally {
withContext(Dispatchers.Main) {
dismiss()
}
}
}
}
}

2
app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java

@ -238,7 +238,7 @@ public class TabOrderPreferenceDialogFragment extends DialogFragment {
private void saveNewOrder() { private void saveNewOrder() {
final String newOrderString = newOrderTabs final String newOrderString = newOrderTabs
.stream() .stream()
.map(tab -> NavigationHelperKt.geNavGraphNameForNavRootId(tab.getNavigationRootId()))
.map(tab -> NavigationHelperKt.getNavGraphNameForNavRootId(tab.getNavigationRootId()))
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString); Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString);
} }

2
app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java

@ -170,7 +170,7 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
private void openPostDialog(final Media feedModel, final int position) { private void openPostDialog(final Media feedModel, final int position) {
try { try {
final NavDirections action = TopicPostsFragmentDirections.actionGlobalPost(feedModel, position);
final NavDirections action = TopicPostsFragmentDirections.actionToPost(feedModel, position);
NavHostFragment.findNavController(TopicPostsFragment.this).navigate(action); NavHostFragment.findNavController(TopicPostsFragment.this).navigate(action);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e); Log.e(TAG, "openPostDialog: ", e);

49
app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt

@ -7,10 +7,8 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import android.view.* import android.view.*
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
@ -33,18 +31,16 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
private val viewModel: DirectInboxViewModel by activityViewModels() private val viewModel: DirectInboxViewModel by activityViewModels()
private lateinit var fragmentActivity: MainActivity private lateinit var fragmentActivity: MainActivity
private lateinit var root: CoordinatorLayout
private lateinit var binding: FragmentDirectMessagesInboxBinding private lateinit var binding: FragmentDirectMessagesInboxBinding
private lateinit var inboxAdapter: DirectMessageInboxAdapter
private lateinit var lazyLoader: RecyclerLazyLoaderAtEdge private lateinit var lazyLoader: RecyclerLazyLoaderAtEdge
private var shouldRefresh = true
private var scrollToTop = false private var scrollToTop = false
private var navigating = false private var navigating = false
private var threadsObserver: Observer<List<DirectThread?>>? = null
private var pendingRequestsMenuItem: MenuItem? = null private var pendingRequestsMenuItem: MenuItem? = null
private var pendingRequestTotalBadgeDrawable: BadgeDrawable? = null private var pendingRequestTotalBadgeDrawable: BadgeDrawable? = null
private var isPendingRequestTotalBadgeAttached = false private var isPendingRequestTotalBadgeAttached = false
private var inboxAdapter: DirectMessageInboxAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -57,17 +53,11 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle?, savedInstanceState: Bundle?,
): View { ): View {
if (this::root.isInitialized) {
shouldRefresh = false
return root
}
binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false) binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false)
root = binding.root
return root
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (!shouldRefresh) return
init() init()
} }
@ -90,11 +80,6 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
} }
} }
override fun onResume() {
super.onResume()
setupObservers()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.dm_inbox_menu, menu) inflater.inflate(R.menu.dm_inbox_menu, menu)
pendingRequestsMenuItem = menu.findItem(R.id.pending_requests) pendingRequestsMenuItem = menu.findItem(R.id.pending_requests)
@ -119,23 +104,14 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
init() init()
} }
override fun onDestroy() {
super.onDestroy()
removeViewModelObservers()
viewModel.onDestroy()
}
private fun setupObservers() { private fun setupObservers() {
removeViewModelObservers()
threadsObserver = Observer { list: List<DirectThread?> ->
if (!this::inboxAdapter.isInitialized) return@Observer
inboxAdapter.submitList(list) {
viewModel.threads.observe(viewLifecycleOwner, { list: List<DirectThread?> ->
inboxAdapter?.submitList(list) {
if (!scrollToTop) return@submitList if (!scrollToTop) return@submitList
binding.inboxList.post { binding.inboxList.smoothScrollToPosition(0) } binding.inboxList.post { binding.inboxList.smoothScrollToPosition(0) }
scrollToTop = false scrollToTop = false
} }
}
threadsObserver?.let { viewModel.threads.observe(fragmentActivity, it) }
})
viewModel.inbox.observe(viewLifecycleOwner, { inboxResource: Resource<DirectInbox?>? -> viewModel.inbox.observe(viewLifecycleOwner, { inboxResource: Resource<DirectInbox?>? ->
if (inboxResource == null) return@observe if (inboxResource == null) return@observe
when (inboxResource.status) { when (inboxResource.status) {
@ -191,11 +167,6 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
} }
} }
private fun removeViewModelObservers() {
threadsObserver?.let { viewModel.threads.removeObserver(it) }
// no need to explicitly remove observers whose lifecycle owner is getViewLifecycleOwner
}
private fun init() { private fun init() {
val context = context ?: return val context = context ?: return
setupObservers() setupObservers()
@ -218,10 +189,12 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener {
} }
} }
navigating = false navigating = false
}.also {
it.setHasStableIds(true)
} }
inboxAdapter.setHasStableIds(true)
binding.inboxList.adapter = inboxAdapter binding.inboxList.adapter = inboxAdapter
lazyLoader = RecyclerLazyLoaderAtEdge(layoutManager) { viewModel.fetchInbox() }
lazyLoader.let { binding.inboxList.addOnScrollListener(it) }
lazyLoader = RecyclerLazyLoaderAtEdge(layoutManager) { viewModel.fetchInbox() }.also {
binding.inboxList.addOnScrollListener(it)
}
} }
} }

39
app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt

@ -13,7 +13,6 @@ import android.view.*
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
@ -75,12 +74,14 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
private var selectedMedia: List<Media>? = null private var selectedMedia: List<Media>? = null
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private var disableDm: Boolean = false private var disableDm: Boolean = false
private var shouldRefresh: Boolean = true
// private var shouldRefresh: Boolean = true
private var highlightsAdapter: HighlightsAdapter? = null private var highlightsAdapter: HighlightsAdapter? = null
private var layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_PROFILE_POSTS_LAYOUT) private var layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_PROFILE_POSTS_LAYOUT)
private lateinit var mainActivity: MainActivity private lateinit var mainActivity: MainActivity
private lateinit var root: MotionLayout
// private lateinit var root: MotionLayout
private lateinit var binding: FragmentProfileBinding private lateinit var binding: FragmentProfileBinding
private lateinit var appStateViewModel: AppStateViewModel private lateinit var appStateViewModel: AppStateViewModel
private lateinit var viewModel: ProfileFragmentViewModel private lateinit var viewModel: ProfileFragmentViewModel
@ -335,23 +336,12 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
if (this::root.isInitialized) {
shouldRefresh = false
return root
}
appStateViewModel.currentUserLiveData.observe(viewLifecycleOwner, viewModel::setCurrentUser)
binding = FragmentProfileBinding.inflate(inflater, container, false) binding = FragmentProfileBinding.inflate(inflater, container, false)
root = binding.root
return root
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (!shouldRefresh) {
setupObservers()
return
}
init() init()
shouldRefresh = false
} }
override fun onRefresh() { override fun onRefresh() {
@ -399,6 +389,11 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
} }
} }
override fun onDestroyView() {
super.onDestroyView()
setupPostsDone = false
}
private fun shareProfileViaDm() { private fun shareProfileViaDm() {
try { try {
val actionToUserSearch = ProfileFragmentDirections.actionToUserSearch().apply { val actionToUserSearch = ProfileFragmentDirections.actionToUserSearch().apply {
@ -444,7 +439,11 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
} }
private fun setupObservers() { private fun setupObservers() {
viewModel.isLoggedIn.observe(viewLifecycleOwner) {} // observe so that `isLoggedIn.value` is correct
appStateViewModel.currentUserLiveData.observe(viewLifecycleOwner, viewModel::setCurrentUser)
viewModel.isLoggedIn.observe(viewLifecycleOwner) {
// observe so that `isLoggedIn.value` is correct
Log.d(TAG, "setupObservers: $it")
}
viewModel.currentUserProfileActionLiveData.observe(viewLifecycleOwner) { viewModel.currentUserProfileActionLiveData.observe(viewLifecycleOwner) {
val (currentUserResource, profileResource) = it val (currentUserResource, profileResource) = it
if (currentUserResource.status == Resource.Status.ERROR || profileResource.status == Resource.Status.ERROR) { if (currentUserResource.status == Resource.Status.ERROR || profileResource.status == Resource.Status.ERROR) {
@ -469,7 +468,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
context?.let { ctx -> Toast.makeText(ctx, R.string.error_loading_profile, Toast.LENGTH_LONG).show() } context?.let { ctx -> Toast.makeText(ctx, R.string.error_loading_profile, Toast.LENGTH_LONG).show() }
return@observe return@observe
} }
root.loadLayoutDescription(R.xml.header_list_scene)
binding.root.loadLayoutDescription(R.xml.header_list_scene)
setupFavChip(profile, currentUser) setupFavChip(profile, currentUser)
setupFavButton(currentUser, profile) setupFavButton(currentUser, profile)
setupSavedButton(currentUser, profile) setupSavedButton(currentUser, profile)
@ -549,7 +548,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
binding.privatePage2.visibility = VISIBLE binding.privatePage2.visibility = VISIBLE
binding.postsRecyclerView.visibility = GONE binding.postsRecyclerView.visibility = GONE
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
root.getTransition(R.id.transition)?.setEnable(false)
binding.root.getTransition(R.id.transition)?.setEnable(false)
} }
private fun setupProfileContext(contextPair: Pair<String?, List<UserProfileContextLink>?>) { private fun setupProfileContext(contextPair: Pair<String?, List<UserProfileContextLink>?>) {
@ -853,7 +852,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
} }
private fun showDefaultMessage() { private fun showDefaultMessage() {
root.loadLayoutDescription(R.xml.profile_fragment_no_acc_layout)
binding.root.loadLayoutDescription(R.xml.profile_fragment_no_acc_layout)
binding.privatePage1.visibility = View.VISIBLE binding.privatePage1.visibility = View.VISIBLE
binding.privatePage2.visibility = View.VISIBLE binding.privatePage2.visibility = View.VISIBLE
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24) binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24)
@ -884,7 +883,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
val canScrollVertically = recyclerView.canScrollVertically(-1) val canScrollVertically = recyclerView.canScrollVertically(-1)
root.getTransition(R.id.transition)?.setEnable(!canScrollVertically)
binding.root.getTransition(R.id.transition)?.setEnable(!canScrollVertically)
} }
}) })
setupPostsDone = true setupPostsDone = true

2
app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java

@ -59,7 +59,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen
.map(Tab::getTitle) .map(Tab::getTitle)
.toArray(String[]::new); .toArray(String[]::new);
final String[] navGraphFileNames = tabs.stream() final String[] navGraphFileNames = tabs.stream()
.map(tab -> NavigationHelperKt.geNavGraphNameForNavRootId(tab.getNavigationRootId()))
.map(tab -> NavigationHelperKt.getNavGraphNameForNavRootId(tab.getNavigationRootId()))
.toArray(String[]::new); .toArray(String[]::new);
preference.setKey(Constants.DEFAULT_TAB); preference.setKey(Constants.DEFAULT_TAB);
preference.setTitle(R.string.pref_start_screen); preference.setTitle(R.string.pref_start_screen);

6
app/src/main/java/awais/instagrabber/models/Tab.kt

@ -2,12 +2,18 @@ package awais.instagrabber.models
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.annotation.NavigationRes
data class Tab( data class Tab(
@param:DrawableRes val iconResId: Int, @param:DrawableRes val iconResId: Int,
val title: String, val title: String,
val isRemovable: Boolean, val isRemovable: Boolean,
/**
* This is the actual resource id of the navigation resource (R.navigation.graphName = navigationResId)
*/
@param:NavigationRes val navigationResId: Int,
/** /**
* This is the resource id of the root navigation tag of the navigation resource. * This is the resource id of the root navigation tag of the navigation resource.
* *

23
app/src/main/java/awais/instagrabber/utils/BarinstaDeepLinkHelper.kt

@ -0,0 +1,23 @@
package awais.instagrabber.utils
import android.net.Uri
import androidx.core.net.toUri
private const val domain = "barinsta"
fun getDirectThreadDeepLink(threadId: String, threadTitle: String, isPending: Boolean = false): Uri =
"$domain://dm_thread/$threadId/$threadTitle?pending=${isPending}".toUri()
fun getProfileDeepLink(username: String): Uri = "$domain://profile/$username".toUri()
fun getPostDeepLink(shortCode: String): Uri = "$domain://post/$shortCode".toUri()
fun getLocationDeepLink(locationId: Long): Uri = "$domain://location/$locationId".toUri()
fun getLocationDeepLink(locationId: String): Uri = "$domain://location/$locationId".toUri()
fun getHashtagDeepLink(hashtag: String): Uri = "$domain://hashtag/$hashtag".toUri()
fun getNotificationsDeepLink(type: String, targetId: Long = 0): Uri = "$domain://notifications/$type?targetId=$targetId".toUri()
fun getSearchDeepLink(): Uri = "$domain://search".toUri()

33
app/src/main/java/awais/instagrabber/utils/KeywordsFilterUtils.kt

@ -2,8 +2,8 @@ package awais.instagrabber.utils
import awais.instagrabber.repositories.responses.Media import awais.instagrabber.repositories.responses.Media
import java.util.* import java.util.*
import kotlin.collections.ArrayList
class KeywordsFilterUtils(private val keywords: ArrayList<String>) {
// fun filter(caption: String?): Boolean { // fun filter(caption: String?): Boolean {
// if (caption == null) return false // if (caption == null) return false
// if (keywords.isEmpty()) return false // if (keywords.isEmpty()) return false
@ -14,24 +14,17 @@ class KeywordsFilterUtils(private val keywords: ArrayList<String>) {
// return false // return false
// } // }
fun filter(media: Media?): Boolean {
if (media == null) return false
val (_, text) = media.caption ?: return false
if (keywords.isEmpty()) return false
val temp = text!!.lowercase(Locale.getDefault())
for (s in keywords) {
if (temp.contains(s)) return true
}
return false
}
private fun containsAnyKeyword(keywords: List<String>, media: Media?): Boolean {
if (media == null || keywords.isEmpty()) return false
val (_, text) = media.caption ?: return false
val temp = text!!.lowercase(Locale.getDefault())
return keywords.any { temp.contains(it) }
}
fun filter(media: List<Media>?): List<Media>? {
if (keywords.isEmpty()) return media
if (media == null) return ArrayList()
val result: MutableList<Media> = ArrayList()
for (m in media) {
if (!filter(m)) result.add(m)
}
return result
}
fun filter(keywords: List<String>, media: List<Media>?): List<Media>? {
if (keywords.isEmpty()) return media
if (media == null) return ArrayList()
val result: MutableList<Media> = ArrayList()
media.filterNotTo(result) { containsAnyKeyword(keywords, it) }
return result
} }

30
app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt

@ -28,7 +28,8 @@ private fun getTabs(
navRootIds: IntArray, navRootIds: IntArray,
isAnon: Boolean = false, isAnon: Boolean = false,
): Pair<List<Tab>, MutableList<Tab>> { ): Pair<List<Tab>, MutableList<Tab>> {
val navGraphNames = getResIdsForNavRootIds(navRootIds, ::geNavGraphNameForNavRootId)
val navGraphNames = getResIdsForNavRootIds(navRootIds, ::getNavGraphNameForNavRootId)
val navGraphResIds = getResIdsForNavRootIds(navRootIds, ::getNavGraphResIdForNavRootId)
val titleArray = getResIdsForNavRootIds(navRootIds, ::getTitleResIdForNavRootId) val titleArray = getResIdsForNavRootIds(navRootIds, ::getTitleResIdForNavRootId)
val iconIds = getResIdsForNavRootIds(navRootIds, ::getIconResIdForNavRootId) val iconIds = getResIdsForNavRootIds(navRootIds, ::getIconResIdForNavRootId)
val startDestFragIds = getResIdsForNavRootIds(navRootIds, ::getStartDestFragIdForNavRootId) val startDestFragIds = getResIdsForNavRootIds(navRootIds, ::getStartDestFragIdForNavRootId)
@ -37,15 +38,15 @@ private fun getTabs(
val otherTabs = mutableListOf<Tab>() // Will contain tabs not in current list val otherTabs = mutableListOf<Tab>() // Will contain tabs not in current list
for (i in navRootIds.indices) { for (i in navRootIds.indices) {
val navRootId = navRootIds[i] val navRootId = navRootIds[i]
val navGraphName = navGraphNames[i]
val tab = Tab( val tab = Tab(
iconIds[i], iconIds[i],
context.getString(titleArray[i]), context.getString(titleArray[i]),
if(isAnon) false else !NON_REMOVABLE_NAV_ROOT_IDS.contains(navRootId),
if (isAnon) false else !NON_REMOVABLE_NAV_ROOT_IDS.contains(navRootId),
navGraphResIds[i],
navRootId, navRootId,
startDestFragIds[i] startDestFragIds[i]
) )
if (!isAnon && !orderedGraphNames.contains(navGraphName)) {
if (!isAnon && !orderedGraphNames.contains(navGraphNames[i])) {
otherTabs.add(tab) otherTabs.add(tab)
continue continue
} }
@ -109,7 +110,7 @@ private fun getStartDestFragIdForNavRootId(id: Int): Int = when (id) {
else -> 0 else -> 0
} }
fun geNavGraphNameForNavRootId(id: Int): String = when (id) {
fun getNavGraphNameForNavRootId(id: Int): String = when (id) {
R.id.direct_messages_nav_graph -> "direct_messages_nav_graph" R.id.direct_messages_nav_graph -> "direct_messages_nav_graph"
R.id.feed_nav_graph -> "feed_nav_graph" R.id.feed_nav_graph -> "feed_nav_graph"
R.id.profile_nav_graph -> "profile_nav_graph" R.id.profile_nav_graph -> "profile_nav_graph"
@ -120,7 +121,18 @@ fun geNavGraphNameForNavRootId(id: Int): String = when (id) {
else -> "" else -> ""
} }
private fun geNavGraphNameForNavRootId(navGraphName: String): Int = when (navGraphName) {
fun getNavGraphResIdForNavRootId(id: Int): Int = when (id) {
R.id.direct_messages_nav_graph -> R.navigation.direct_messages_nav_graph
R.id.feed_nav_graph -> R.navigation.feed_nav_graph
R.id.profile_nav_graph -> R.navigation.profile_nav_graph
R.id.discover_nav_graph -> R.navigation.discover_nav_graph
R.id.more_nav_graph -> R.navigation.more_nav_graph
R.id.favorites_nav_graph -> R.navigation.favorites_nav_graph
R.id.notification_viewer_nav_graph -> R.navigation.notification_viewer_nav_graph
else -> 0
}
private fun getNavRootIdForGraphName(navGraphName: String): Int = when (navGraphName) {
"direct_messages_nav_graph" -> R.id.direct_messages_nav_graph "direct_messages_nav_graph" -> R.id.direct_messages_nav_graph
"feed_nav_graph" -> R.id.feed_nav_graph "feed_nav_graph" -> R.id.feed_nav_graph
"profile_nav_graph" -> R.id.profile_nav_graph "profile_nav_graph" -> R.id.profile_nav_graph
@ -139,9 +151,9 @@ private fun getOrderedNavRootIdsFromPref(navGraphNames: List<String>): Pair<List
val newOrderString = top5navGraphNames.joinToString(",") val newOrderString = top5navGraphNames.joinToString(",")
Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString) Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString)
tabOrderString = newOrderString tabOrderString = newOrderString
return top5navGraphNames to top5navGraphNames.map(::geNavGraphNameForNavRootId)
return top5navGraphNames to top5navGraphNames.map(::getNavRootIdForGraphName)
} }
val orderString = tabOrderString ?: return navGraphNames to navGraphNames.subList(0, 5).map(::geNavGraphNameForNavRootId)
val orderString = tabOrderString ?: return navGraphNames to navGraphNames.subList(0, 5).map(::getNavRootIdForGraphName)
// Make sure that the list from preference does not contain any invalid values // Make sure that the list from preference does not contain any invalid values
val orderGraphNames = orderString val orderGraphNames = orderString
.split(",") .split(",")
@ -153,7 +165,7 @@ private fun getOrderedNavRootIdsFromPref(navGraphNames: List<String>): Pair<List
// Use top 5 entries for default list // Use top 5 entries for default list
navGraphNames.subList(0, 5) navGraphNames.subList(0, 5)
} else orderGraphNames } else orderGraphNames
return graphNames to graphNames.map(::geNavGraphNameForNavRootId)
return graphNames to graphNames.map(::getNavRootIdForGraphName)
} }
fun isNavRootInCurrentTabs(navRootString: String?): Boolean { fun isNavRootInCurrentTabs(navRootString: String?): Boolean {

97
app/src/main/java/awais/instagrabber/viewmodels/MediaViewModel.java

@ -1,19 +1,108 @@
package awais.instagrabber.viewmodels; package awais.instagrabber.viewmodels;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import awais.instagrabber.customviews.helpers.PostFetcher;
import awais.instagrabber.fragments.settings.PreferenceKeys;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.utils.KeywordsFilterUtilsKt;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class MediaViewModel extends ViewModel { public class MediaViewModel extends ViewModel {
private MutableLiveData<List<Media>> list;
private static final String TAG = MediaViewModel.class.getSimpleName();
private boolean refresh = true;
private final PostFetcher postFetcher;
private final MutableLiveData<List<Media>> list = new MutableLiveData<>();
public MediaViewModel(@NonNull final PostFetcher.PostFetchService postFetchService) {
final FetchListener<List<Media>> fetchListener = new FetchListener<List<Media>>() {
@Override
public void onResult(final List<Media> result) {
if (refresh) {
list.postValue(filterResult(result, true));
refresh = false;
return;
}
list.postValue(filterResult(result, false));
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
};
postFetcher = new PostFetcher(postFetchService, fetchListener);
}
public MutableLiveData<List<Media>> getList() {
if (list == null) {
list = new MutableLiveData<>();
@NonNull
private List<Media> filterResult(final List<Media> result, final boolean isRefresh) {
final List<Media> models = list.getValue();
final List<Media> modelsCopy = models == null || isRefresh ? new ArrayList<>() : new ArrayList<>(models);
if (settingsHelper.getBoolean(PreferenceKeys.TOGGLE_KEYWORD_FILTER)) {
final List<String> keywords = new ArrayList<>(settingsHelper.getStringSet(PreferenceKeys.KEYWORD_FILTERS));
final List<Media> filter = KeywordsFilterUtilsKt.filter(keywords, result);
if (filter != null) {
modelsCopy.addAll(filter);
}
return modelsCopy;
} }
modelsCopy.addAll(result);
return modelsCopy;
}
public LiveData<List<Media>> getList() {
return list; return list;
} }
public boolean hasMore() {
return postFetcher.hasMore();
}
public void fetch() {
postFetcher.fetch();
}
public void reset() {
postFetcher.reset();
}
public boolean isFetching() {
return postFetcher.isFetching();
}
public void refresh() {
refresh = true;
reset();
fetch();
}
public static class ViewModelFactory implements ViewModelProvider.Factory {
@NonNull
private final PostFetcher.PostFetchService postFetchService;
public ViewModelFactory(@NonNull final PostFetcher.PostFetchService postFetchService) {
this.postFetchService = postFetchService;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) {
//noinspection unchecked
return (T) new MediaViewModel(postFetchService);
}
}
} }

2
app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt

@ -26,6 +26,7 @@ import awais.instagrabber.viewmodels.ProfileFragmentViewModel.ProfileEvent.*
import awais.instagrabber.webservices.* import awais.instagrabber.webservices.*
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.time.LocalDateTime import java.time.LocalDateTime
@ -380,6 +381,7 @@ class ProfileFragmentViewModel(
} }
val threadId = thread.threadId ?: return@afterPrevious val threadId = thread.threadId ?: return@afterPrevious
_eventLiveData.postValue(Event(NavigateToThread(threadId, username))) _eventLiveData.postValue(Event(NavigateToThread(threadId, username)))
delay(200) // Add delay so that the postValue in finally does not overwrite the NavigateToThread event
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "sendDm: ", e) Log.e(TAG, "sendDm: ", e)
} finally { } finally {

3
app/src/main/res/layout/activity_main.xml

@ -73,5 +73,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
app:labelVisibilityMode="auto" />
app:labelVisibilityMode="auto"
tools:menu="@menu/bottom_nav_menu" />
</awais.instagrabber.customviews.InsetsNotifyingCoordinatorLayout> </awais.instagrabber.customviews.InsetsNotifyingCoordinatorLayout>

28
app/src/main/res/menu/bottom_nav_menu.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/direct_messages_nav_graph"
android:icon="@drawable/ic_message_24"
android:contentDescription="@string/title_dm"
android:title="@string/title_dm" />
<item
android:id="@id/feed_nav_graph"
android:icon="@drawable/ic_home_24"
android:contentDescription="@string/feed"
android:title="@string/feed" />
<item
android:id="@id/profile_nav_graph"
android:icon="@drawable/ic_person_24"
android:contentDescription="@string/profile"
android:title="@string/profile" />
<item
android:id="@id/discover_nav_graph"
android:icon="@drawable/ic_explore_24"
android:contentDescription="@string/title_discover"
android:title="@string/title_discover" />
<item
android:id="@id/more_nav_graph"
android:icon="@drawable/ic_more_horiz_24"
android:contentDescription="@string/more"
android:title="@string/more" />
</menu>

333
app/src/main/res/navigation/nav_graph.xml → app/src/main/res/navigation/direct_messages_nav_graph.xml

@ -2,70 +2,22 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android" <navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/feedFragment">
<action
android:id="@+id/action_global_hashTag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_global_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_global_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_global_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_global_direct_thread"
app:destination="@id/directMessagesThreadFragment" />
android:id="@+id/direct_messages_nav_graph"
app:startDestination="@id/directMessagesInboxFragment">
<fragment <fragment
android:id="@+id/feedFragment"
android:name="awais.instagrabber.fragments.main.FeedFragment"
android:label="@string/feed"
tools:layout="@layout/fragment_feed">
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
android:id="@+id/directMessagesInboxFragment"
android:name="awais.instagrabber.fragments.directmessages.DirectMessageInboxFragment"
android:label="@string/action_dms"
tools:layout="@layout/fragment_direct_messages_inbox">
<action <action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
android:id="@+id/action_to_thread"
app:destination="@id/directMessagesThreadFragment" />
<action <action
android:id="@+id/action_to_story_list"
app:destination="@id/storyListViewerFragment" />
android:id="@+id/action_to_pending_inbox"
app:destination="@id/directPendingInboxFragment" />
</fragment> </fragment>
<fragment <fragment
@ -99,25 +51,6 @@
app:destination="@id/user_search" /> app:destination="@id/user_search" />
</fragment> </fragment>
<fragment
android:id="@+id/searchFragment"
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search">
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
</fragment>
<fragment <fragment
android:id="@+id/postViewFragment" android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment" android:name="awais.instagrabber.fragments.PostViewV2Fragment"
@ -266,63 +199,6 @@
app:destination="@id/profile_non_top" /> app:destination="@id/profile_non_top" />
</dialog> </dialog>
<fragment
android:id="@+id/profileFragment"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<!-- Copy of profile fragment tag --> <!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar --> <!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 --> <!-- See https://issuetracker.google.com/issues/192395936 -->
@ -470,126 +346,6 @@
app:destination="@id/profile_non_top" /> app:destination="@id/profile_non_top" />
</dialog> </dialog>
<fragment
android:id="@+id/discoverFragment"
android:name="awais.instagrabber.fragments.main.DiscoverFragment"
android:label="@string/title_discover"
tools:layout="@layout/fragment_discover">
<action
android:id="@+id/action_to_topic_posts"
app:destination="@id/topicPostsFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/topicPostsFragment"
android:name="awais.instagrabber.fragments.TopicPostsFragment"
tools:layout="@layout/fragment_topic_posts">
<argument
android:name="topicCluster"
app:argType="awais.instagrabber.repositories.responses.discover.TopicCluster" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/favoritesFragment"
android:name="awais.instagrabber.fragments.FavoritesFragment"
android:label="@string/title_favorites"
tools:layout="@layout/fragment_favorites">
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
</fragment>
<!-- Copy of favorites fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/favorites_non_top"
android:name="awais.instagrabber.fragments.FavoritesFragment"
android:label="@string/title_favorites"
tools:layout="@layout/fragment_favorites">
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
</fragment>
<fragment
android:id="@+id/notificationsViewer"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<!-- Copy of notification viewer fragment tag --> <!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar --> <!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 --> <!-- See https://issuetracker.google.com/issues/192395936 -->
@ -677,41 +433,6 @@
app:destination="@id/profile_non_top" /> app:destination="@id/profile_non_top" />
</fragment> </fragment>
<fragment
android:id="@+id/storyListViewerFragment"
android:name="awais.instagrabber.fragments.StoryListViewerFragment"
android:label="Stories"
tools:layout="@layout/fragment_story_list_viewer">
<argument
android:name="type"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/directMessagesInboxFragment"
android:name="awais.instagrabber.fragments.directmessages.DirectMessageInboxFragment"
android:label="@string/action_dms"
tools:layout="@layout/fragment_direct_messages_inbox">
<action
android:id="@+id/action_to_thread"
app:destination="@id/directMessagesThreadFragment" />
<action
android:id="@+id/action_to_pending_inbox"
app:destination="@id/directPendingInboxFragment" />
</fragment>
<fragment <fragment
android:id="@+id/directMessagesThreadFragment" android:id="@+id/directMessagesThreadFragment"
android:name="awais.instagrabber.fragments.directmessages.DirectMessageThreadFragment" android:name="awais.instagrabber.fragments.directmessages.DirectMessageThreadFragment"
@ -730,6 +451,8 @@
android:defaultValue="false" android:defaultValue="false"
app:argType="boolean" /> app:argType="boolean" />
<deepLink app:uri="barinsta://dm_thread/{threadId}/{title}?pending={pending}" />
<action <action
android:id="@+id/action_to_settings" android:id="@+id/action_to_settings"
app:destination="@id/directMessagesSettingsFragment" /> app:destination="@id/directMessagesSettingsFragment" />
@ -863,36 +586,4 @@
app:argType="string[]" app:argType="string[]"
app:nullable="true" /> app:nullable="true" />
</fragment> </fragment>
<include app:graph="@navigation/settings_nav_graph" />
<fragment
android:id="@+id/morePreferencesFragment"
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
android:label="@string/more">
<action
android:id="@+id/action_to_settings"
app:destination="@id/settings_nav_graph" />
<action
android:id="@+id/action_to_about"
app:destination="@id/aboutFragment" />
<action
android:id="@+id/action_to_favorites"
app:destination="@id/favorites_non_top" />
<action
android:id="@+id/action_to_backup"
app:destination="@id/backupPreferencesFragment" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_story_list"
app:destination="@id/storyListViewerFragment" />
</fragment>
</navigation> </navigation>

518
app/src/main/res/navigation/discover_nav_graph.xml

@ -0,0 +1,518 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/discover_nav_graph"
app:startDestination="@id/discoverFragment">
<fragment
android:id="@+id/discoverFragment"
android:name="awais.instagrabber.fragments.main.DiscoverFragment"
android:label="@string/title_discover"
tools:layout="@layout/fragment_discover">
<action
android:id="@+id/action_to_topic_posts"
app:destination="@id/topicPostsFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<fragment
android:id="@+id/topicPostsFragment"
android:name="awais.instagrabber.fragments.TopicPostsFragment"
tools:layout="@layout/fragment_topic_posts">
<argument
android:name="topicCluster"
app:argType="awais.instagrabber.repositories.responses.discover.TopicCluster" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
</navigation>

484
app/src/main/res/navigation/favorites_nav_graph.xml

@ -0,0 +1,484 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/favorites_nav_graph"
app:startDestination="@id/favoritesFragment">
<fragment
android:id="@+id/favoritesFragment"
android:name="awais.instagrabber.fragments.FavoritesFragment"
android:label="@string/title_favorites"
tools:layout="@layout/fragment_favorites">
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
</navigation>

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

@ -0,0 +1,520 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/feed_nav_graph"
app:startDestination="@id/feedFragment">
<fragment
android:id="@+id/feedFragment"
android:name="awais.instagrabber.fragments.main.FeedFragment"
android:label="@string/feed"
tools:layout="@layout/fragment_feed">
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_story_list"
app:destination="@id/storyListViewerFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/storyListViewerFragment"
android:name="awais.instagrabber.fragments.StoryListViewerFragment"
android:label="Stories"
tools:layout="@layout/fragment_story_list_viewer">
<argument
android:name="type"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
</navigation>

539
app/src/main/res/navigation/more_nav_graph.xml

@ -0,0 +1,539 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/more_nav_graph"
app:startDestination="@id/morePreferencesFragment">
<fragment
android:id="@+id/morePreferencesFragment"
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
android:label="@string/more">
<action
android:id="@+id/action_to_settings"
app:destination="@id/settings_nav_graph" />
<action
android:id="@+id/action_to_about"
app:destination="@id/aboutFragment" />
<action
android:id="@+id/action_to_favorites"
app:destination="@id/favorites_non_top" />
<action
android:id="@+id/action_to_backup"
app:destination="@id/backupPreferencesFragment" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_story_list"
app:destination="@id/storyListViewerFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of favorites fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/favorites_non_top"
android:name="awais.instagrabber.fragments.FavoritesFragment"
android:label="@string/title_favorites"
tools:layout="@layout/fragment_favorites">
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
</fragment>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
<include app:graph="@navigation/settings_nav_graph" />
<fragment
android:id="@+id/storyListViewerFragment"
android:name="awais.instagrabber.fragments.StoryListViewerFragment"
android:label="Stories"
tools:layout="@layout/fragment_story_list_viewer">
<argument
android:name="type"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
</navigation>

495
app/src/main/res/navigation/notification_viewer_nav_graph.xml

@ -0,0 +1,495 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/notification_viewer_nav_graph"
app:startDestination="@id/notificationsViewer">
<fragment
android:id="@+id/notificationsViewer"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
</navigation>

567
app/src/main/res/navigation/profile_nav_graph.xml

@ -0,0 +1,567 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/profile_nav_graph"
app:startDestination="@id/profileFragment">
<fragment
android:id="@+id/profileFragment"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/post_loading_dialog"
android:name="awais.instagrabber.dialogs.PostLoadingDialogFragment"
android:label="@string/direct_download_loading">
<argument
android:name="shortCode"
app:argType="string" />
<deepLink app:uri="barinsta://post/{shortCode}" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</dialog>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
android:label="StoryViewerFragment"
tools:layout="@layout/fragment_story_viewer">
<argument
android:name="options"
app:argType="awais.instagrabber.repositories.requests.StoryViewerOptions" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search">
<deepLink app:uri="barinsta://search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="@string/post"
tools:layout="@layout/dialog_post_view">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="long" />
<deepLink app:uri="barinsta://location/{locationId}" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</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" />
<deepLink app:uri="barinsta://hashtag/{hashtag}" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/commentsViewerFragment"
android:name="awais.instagrabber.fragments.comments.CommentsViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_comments">
<argument
android:name="shortCode"
app:argType="string"
app:nullable="false" />
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="postUserId"
app:argType="long" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_likes"
app:destination="@id/likesViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of profile fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/profile_non_top"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="true" />
<deepLink app:uri="barinsta://profile/{username}" />
<action
android:id="@+id/action_to_saved"
app:destination="@id/savedViewerFragment" />
<action
android:id="@+id/action_to_saved_collections"
app:destination="@id/savedCollectionsFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_follow_viewer"
app:destination="@id/followViewerFragment" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_user_search"
app:destination="@id/user_search" />
<action
android:id="@+id/action_to_notifications"
app:destination="@id/notifications_viewer_non_top" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/followViewerFragment"
android:name="awais.instagrabber.fragments.FollowViewerFragment"
android:label=""
tools:layout="@layout/fragment_followers_viewer">
<argument
android:name="profileId"
app:argType="long" />
<argument
android:name="isFollowersList"
app:argType="boolean"
app:nullable="false" />
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<dialog
android:id="@+id/likesViewerFragment"
android:name="awais.instagrabber.fragments.LikesViewerFragment"
android:label="Comments"
tools:layout="@layout/fragment_likes">
<argument
android:name="postId"
app:argType="string"
app:nullable="false" />
<argument
android:name="isComment"
app:argType="boolean"
app:nullable="false" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</dialog>
<!-- Copy of notification viewer fragment tag -->
<!-- Required to get back arrow in action bar -->
<!-- See https://issuetracker.google.com/issues/192395936 -->
<fragment
android:id="@+id/notifications_viewer_non_top"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
app:argType="long" />
<deepLink app:uri="barinsta://notifications/{type}?targetId={targetId}" />
<action
android:id="@+id/action_to_story"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
</fragment>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_to_collection_posts"
app:destination="@id/collectionPostsFragment" />
</fragment>
<fragment
android:id="@+id/collectionPostsFragment"
android:name="awais.instagrabber.fragments.CollectionPostsFragment"
tools:layout="@layout/fragment_collection_posts">
<argument
android:name="savedCollection"
app:argType="awais.instagrabber.repositories.responses.saved.SavedCollection" />
<argument
android:name="titleColor"
app:argType="integer" />
<argument
android:name="backgroundColor"
app:argType="integer" />
<action
android:id="@+id/action_to_comments"
app:destination="@id/commentsViewerFragment" />
<action
android:id="@+id/action_to_hashtag"
app:destination="@id/hashTagFragment" />
<action
android:id="@+id/action_to_location"
app:destination="@id/locationFragment" />
<action
android:id="@+id/action_to_post"
app:destination="@id/postViewFragment" />
<action
android:id="@+id/action_to_profile"
app:destination="@id/profile_non_top" />
</fragment>
<fragment
android:id="@+id/user_search"
android:name="awais.instagrabber.fragments.UserSearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_user_search">
<argument
android:name="multiple"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="title"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="action_label"
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
<argument
android:name="show_groups"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="search_mode"
android:defaultValue="USER_SEARCH"
app:argType="awais.instagrabber.fragments.UserSearchMode" />
<argument
android:name="hideUserIds"
android:defaultValue="@null"
app:argType="long[]"
app:nullable="true" />
<argument
android:name="hideThreadIds"
android:defaultValue="@null"
app:argType="string[]"
app:nullable="true" />
</fragment>
</navigation>

12
app/src/main/res/navigation/root_nav_graph.xml

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation>
<!--android:id="@+id/root"-->
<!--app:startDestination="@id/profile_nav_graph"-->
<!--<include app:graph="@navigation/dm_nav_graph" />-->
<!--<include app:graph="@navigation/feed_nav_graph" />-->
<!--<include app:graph="@navigation/profile_nav_graph" />-->
<!--<include app:graph="@navigation/discover_nav_graph" />-->
<!--<include app:graph="@navigation/more_nav_graph" />-->
</navigation>

108
app/src/main/res/navigation/settings_nav_graph.xml

@ -4,110 +4,6 @@
android:id="@+id/settings_nav_graph" android:id="@+id/settings_nav_graph"
app:startDestination="@id/settingsPreferencesFragment"> app:startDestination="@id/settingsPreferencesFragment">
<!--<include app:graph="@navigation/profile_nav_graph" />-->
<!--<include app:graph="@navigation/hashtag_nav_graph" />-->
<!--<include app:graph="@navigation/location_nav_graph" />-->
<!--<include app:graph="@navigation/comments_nav_graph" />-->
<!--<include app:graph="@navigation/likes_nav_graph" />-->
<!--<include app:graph="@navigation/notification_viewer_nav_graph" />-->
<!--<include app:graph="@navigation/story_list_nav_graph" />-->
<!--<include app:graph="@navigation/discover_nav_graph" />-->
<!--<action-->
<!-- android:id="@+id/action_global_commentsViewerFragment"-->
<!-- app:destination="@id/comments_nav_graph">-->
<!-- <argument-->
<!-- android:name="shortCode"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!-- <argument-->
<!-- android:name="postId"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!-- <argument-->
<!-- android:name="postUserId"-->
<!-- app:argType="long" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_likesViewerFragment"-->
<!-- app:destination="@id/likes_nav_graph">-->
<!-- <argument-->
<!-- android:name="postId"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!-- <argument-->
<!-- android:name="isComment"-->
<!-- app:argType="boolean"-->
<!-- app:nullable="false" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_profileFragment"-->
<!-- app:destination="@id/profile_nav_graph">-->
<!-- <argument-->
<!-- android:name="username"-->
<!-- app:argType="string"-->
<!-- app:nullable="true" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_hashTagFragment"-->
<!-- app:destination="@id/hashtag_nav_graph">-->
<!-- <argument-->
<!-- android:name="hashtag"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_locationFragment"-->
<!-- app:destination="@id/location_nav_graph">-->
<!-- <argument-->
<!-- android:name="locationId"-->
<!-- app:argType="long" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_storyListViewerFragment"-->
<!-- app:destination="@id/story_list_nav_graph">-->
<!-- <argument-->
<!-- android:name="type"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_notificationsViewerFragment"-->
<!-- app:destination="@id/notification_viewer_nav_graph">-->
<!-- <argument-->
<!-- android:name="type"-->
<!-- app:argType="string"-->
<!-- app:nullable="false" />-->
<!-- <argument-->
<!-- android:name="targetId"-->
<!-- android:defaultValue="0L"-->
<!-- app:argType="long" />-->
<!--</action>-->
<!--<action-->
<!-- android:id="@+id/action_global_post_view"-->
<!-- app:destination="@id/postViewFragment">-->
<!-- <argument-->
<!-- android:name="media"-->
<!-- app:argType="awais.instagrabber.repositories.responses.Media"-->
<!-- app:nullable="false" />-->
<!-- <argument-->
<!-- android:name="position"-->
<!-- app:argType="integer" />-->
<!--</action>-->
<!--<include app:graph="@navigation/user_search_nav_graph" />-->
<!--<action-->
<!-- android:id="@+id/action_global_user_search"-->
<!-- app:destination="@id/user_search_nav_graph" />-->
<fragment <fragment
android:id="@+id/settingsPreferencesFragment" android:id="@+id/settingsPreferencesFragment"
android:name="awais.instagrabber.fragments.settings.SettingsPreferencesFragment" android:name="awais.instagrabber.fragments.settings.SettingsPreferencesFragment"
@ -181,8 +77,4 @@
android:id="@+id/postPreferencesFragment" android:id="@+id/postPreferencesFragment"
android:name="awais.instagrabber.fragments.settings.PostPreferencesFragment" android:name="awais.instagrabber.fragments.settings.PostPreferencesFragment"
android:label="@string/pref_category_post" /> android:label="@string/pref_category_post" />
<!--<fragment-->
<!-- android:id="@+id/postViewFragment"-->
<!-- android:name="awais.instagrabber.fragments.PostViewV2Fragment"-->
<!-- android:label="@string/post" />-->
</navigation> </navigation>

9
app/src/main/res/values/ids.xml

@ -11,15 +11,6 @@
<item name="root_nav_graph" type="id" /> <item name="root_nav_graph" type="id" />
<!-- Navigation top level root ids -->
<item name="feed_nav_graph" type="id" />
<item name="profile_nav_graph" type="id" />
<item name="direct_messages_nav_graph" type="id" />
<item name="notification_viewer_nav_graph" type="id" />
<item name="discover_nav_graph" type="id" />
<item name="favorites_nav_graph" type="id" />
<item name="more_nav_graph" type="id" />
<!-- story stickers --> <!-- story stickers -->
<item name="mentions" type="id" /> <item name="mentions" type="id" />
<item name="spotify" type="id" /> <item name="spotify" type="id" />

Loading…
Cancel
Save