From 05f8b1b8e3359f63f87fdc3a8e1e9fa4ff77eecb Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sat, 3 Jul 2021 21:36:34 +0900 Subject: [PATCH] Migrate Navigation to 2.4.0-alpha4 1. 2.4.0 introduces multistack navigation. Which removes the need for NavigationExtensions 2. Organised all nav graphs into a single graph to remove global action redundancy. --- app/build.gradle | 7 +- .../instagrabber/activities/MainActivity.kt | 374 +++----- .../NavHostFragmentWithDefaultAnimations.java | 120 +-- .../TabOrderPreferenceDialogFragment.java | 20 +- .../fragments/CollectionPostsFragment.java | 83 +- .../fragments/FavoritesFragment.kt | 47 +- .../fragments/FollowViewerFragment.java | 11 +- .../fragments/HashTagFragment.java | 137 ++- .../fragments/LikesViewerFragment.java | 20 +- .../fragments/LocationFragment.java | 112 ++- .../NotificationsViewerFragment.java | 34 +- .../fragments/PostViewV2Fragment.java | 103 +- .../fragments/SavedCollectionsFragment.java | 5 +- .../fragments/SavedViewerFragment.java | 74 +- .../fragments/StoryListViewerFragment.java | 28 +- .../fragments/StoryViewerFragment.java | 25 +- .../fragments/TopicPostsFragment.java | 60 +- .../fragments/UserSearchFragment.java | 16 - .../instagrabber/fragments/UserSearchMode.kt | 7 + .../comments/CommentsViewerFragment.java | 2 +- .../fragments/comments/Helper.java | 27 +- .../fragments/comments/RepliesFragment.java | 28 +- .../DirectMessageInboxFragment.kt | 10 +- .../DirectMessageSettingsFragment.kt | 57 +- .../DirectMessageThreadFragment.java | 161 ++-- .../DirectPendingInboxFragment.kt | 2 +- .../fragments/main/DiscoverFragment.java | 26 +- .../fragments/main/FeedFragment.java | 92 +- .../fragments/main/ProfileFragment.kt | 118 +-- .../fragments/search/SearchFragment.java | 23 +- .../settings/GeneralPreferencesFragment.java | 27 +- .../settings/MorePreferencesFragment.java | 136 ++- .../java/awais/instagrabber/models/Tab.kt | 12 - .../utils/NavigationExtensions.java | 494 +++++----- .../instagrabber/utils/NavigationHelper.kt | 162 ++++ .../java/awais/instagrabber/utils/Utils.java | 120 --- .../viewmodels/UserSearchViewModel.java | 8 +- app/src/main/res/layout/activity_main.xml | 2 + .../res/navigation/comments_nav_graph.xml | 78 -- .../navigation/direct_messages_nav_graph.xml | 216 ----- .../res/navigation/discover_nav_graph.xml | 155 --- .../res/navigation/favorites_nav_graph.xml | 70 -- .../main/res/navigation/feed_nav_graph.xml | 159 ---- .../main/res/navigation/hashtag_nav_graph.xml | 130 --- .../main/res/navigation/likes_nav_graph.xml | 48 - .../res/navigation/location_nav_graph.xml | 129 --- .../main/res/navigation/more_nav_graph.xml | 205 ---- app/src/main/res/navigation/nav_graph.xml | 894 ++++++++++++++++++ .../notification_viewer_nav_graph.xml | 126 --- .../main/res/navigation/profile_nav_graph.xml | 223 ----- .../main/res/navigation/saved_nav_graph.xml | 119 --- .../res/navigation/settings_nav_graph.xml | 188 ++++ .../res/navigation/story_list_nav_graph.xml | 49 - .../res/navigation/user_search_nav_graph.xml | 80 -- app/src/main/res/values/arrays.xml | 54 +- app/src/main/res/values/ids.xml | 11 + build.gradle | 6 +- 57 files changed, 2523 insertions(+), 3207 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/fragments/UserSearchMode.kt create mode 100644 app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt delete mode 100644 app/src/main/res/navigation/comments_nav_graph.xml delete mode 100644 app/src/main/res/navigation/direct_messages_nav_graph.xml delete mode 100644 app/src/main/res/navigation/discover_nav_graph.xml delete mode 100644 app/src/main/res/navigation/favorites_nav_graph.xml delete mode 100644 app/src/main/res/navigation/feed_nav_graph.xml delete mode 100644 app/src/main/res/navigation/hashtag_nav_graph.xml delete mode 100644 app/src/main/res/navigation/likes_nav_graph.xml delete mode 100644 app/src/main/res/navigation/location_nav_graph.xml delete mode 100644 app/src/main/res/navigation/more_nav_graph.xml create mode 100644 app/src/main/res/navigation/nav_graph.xml delete mode 100644 app/src/main/res/navigation/notification_viewer_nav_graph.xml delete mode 100644 app/src/main/res/navigation/profile_nav_graph.xml delete mode 100644 app/src/main/res/navigation/saved_nav_graph.xml create mode 100644 app/src/main/res/navigation/settings_nav_graph.xml delete mode 100644 app/src/main/res/navigation/story_list_nav_graph.xml delete mode 100644 app/src/main/res/navigation/user_search_nav_graph.xml diff --git a/app/build.gradle b/app/build.gradle index f184bcc6..fd8fd0f2 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -163,7 +163,6 @@ configurations.all { dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - def nav_version = '2.3.5' def exoplayer_version = '2.14.1' implementation 'com.google.android.material:material:1.4.0-rc01' @@ -175,8 +174,6 @@ dependencies { implementation "androidx.recyclerview:recyclerview:1.2.1" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation "androidx.viewpager2:viewpager2:1.0.0" - implementation "androidx.navigation:navigation-fragment:$nav_version" - implementation "androidx.navigation:navigation-ui:$nav_version" implementation "androidx.constraintlayout:constraintlayout:2.0.4" implementation "androidx.preference:preference:1.1.1" implementation 'androidx.palette:palette:1.0.0' @@ -195,6 +192,10 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1" + // Navigation + implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.nav_version" + implementation "androidx.navigation:navigation-ui-ktx:$rootProject.nav_version" + // Room def room_version = "2.3.0" implementation "androidx.room:room-runtime:$room_version" diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.kt b/app/src/main/java/awais/instagrabber/activities/MainActivity.kt index fc7b4a2c..dd0a7298 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.kt +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.kt @@ -1,7 +1,6 @@ package awais.instagrabber.activities import android.animation.LayoutTransition -import android.annotation.SuppressLint import android.app.NotificationChannel import android.app.NotificationManager import android.content.ComponentName @@ -16,7 +15,6 @@ import android.view.MenuItem import android.view.View import android.view.WindowManager import android.widget.Toast -import androidx.annotation.IdRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout @@ -29,22 +27,22 @@ import androidx.emoji.text.EmojiCompat import androidx.emoji.text.EmojiCompat.InitCallback import androidx.emoji.text.FontRequestEmojiCompatConfig import androidx.fragment.app.FragmentManager -import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController -import androidx.navigation.NavController.OnDestinationChangedListener import androidx.navigation.NavDestination -import androidx.navigation.ui.NavigationUI +import androidx.navigation.NavGraph +import androidx.navigation.NavGraphNavigator +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.* import awais.instagrabber.BuildConfig +import awais.instagrabber.NavGraphDirections import awais.instagrabber.R import awais.instagrabber.customviews.emoji.EmojiVariantManager import awais.instagrabber.customviews.helpers.RootViewDeferringInsetsCallback import awais.instagrabber.customviews.helpers.TextWatcherAdapter import awais.instagrabber.databinding.ActivityMainBinding -import awais.instagrabber.fragments.PostViewV2Fragment -import awais.instagrabber.fragments.directmessages.DirectMessageInboxFragmentDirections +import awais.instagrabber.fragments.main.FeedFragment import awais.instagrabber.fragments.settings.PreferenceKeys import awais.instagrabber.models.IntentModel import awais.instagrabber.models.Resource @@ -68,20 +66,22 @@ import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.textfield.TextInputLayout import com.google.common.collect.ImmutableList -import com.google.common.collect.Iterators import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.util.* -import java.util.stream.Collectors class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedListener { private lateinit var binding: ActivityMainBinding + private lateinit var navController: NavController + private lateinit var appBarConfiguration: AppBarConfiguration - private var currentNavControllerLiveData: LiveData? = null + // private var currentNavControllerLiveData: LiveData? = null private var searchMenuItem: MenuItem? = null - private var firstFragmentGraphIndex = 0 + private var startNavRootId: Int = 0 + + // private var firstFragmentGraphIndex = 0 private var lastSelectedNavMenuId = 0 private var isActivityCheckerServiceBound = false private var isBackStackEmpty = false @@ -141,8 +141,10 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL // } catch (e: Exception) { // Log.e(TAG, "onCreate: ", e) // } + val navHostFragment = supportFragmentManager.findFragmentById(R.id.main_nav_host) as NavHostFragment + navController = navHostFragment.navController if (savedInstanceState == null) { - setupBottomNavigationBar(true) + setupNavigation(true) } if (!BuildConfig.isPre) { val checkUpdates = Utils.settingsHelper.getBoolean(PreferenceKeys.CHECK_UPDATES) @@ -233,40 +235,18 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.main_menu, menu) searchMenuItem = menu.findItem(R.id.search) - val navController = currentNavControllerLiveData?.value - if (navController != null) { - val currentDestination = navController.currentDestination - if (currentDestination != null) { - @SuppressLint("RestrictedApi") val backStack = navController.backStack - setupMenu(backStack.size, currentDestination.id) - } + // val navController = currentNavControllerLiveData?.value + val currentDestination = navController.currentDestination + if (currentDestination != null) { + val backStack = navController.backQueue + setupMenu(backStack.size, currentDestination.id) } - // if (binding.searchInputLayout.getVisibility() == View.VISIBLE) { - // searchMenuItem.setVisible(false).setEnabled(false); - // return true; - // } - // searchMenuItem.setVisible(true).setEnabled(true); - // if (showSearch && currentNavControllerLiveData != null) { - // final NavController navController = currentNavControllerLiveData.getValue(); - // if (navController != null) { - // final NavDestination currentDestination = navController.getCurrentDestination(); - // if (currentDestination != null) { - // final int destinationId = currentDestination.getId(); - // showSearch = destinationId == R.id.profileFragment; - // } - // } - // } - // if (!showSearch) { - // searchMenuItem.setVisible(false); - // return true; - // } - // return setupSearchView(); return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.search) { - val navController = currentNavControllerLiveData?.value ?: return false + // val navController = currentNavControllerLiveData?.value ?: return false try { navController.navigate(R.id.action_global_search) return true @@ -279,20 +259,13 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL } override fun onSaveInstanceState(outState: Bundle) { - outState.putString(FIRST_FRAGMENT_GRAPH_INDEX_KEY, firstFragmentGraphIndex.toString()) + // outState.putString(FIRST_FRAGMENT_GRAPH_INDEX_KEY, firstFragmentGraphIndex.toString()) outState.putString(LAST_SELECT_NAV_MENU_ID, binding.bottomNavView.selectedItemId.toString()) super.onSaveInstanceState(outState) } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) - val key = savedInstanceState[FIRST_FRAGMENT_GRAPH_INDEX_KEY] as String? - if (key != null) { - try { - firstFragmentGraphIndex = key.toInt() - } catch (ignored: NumberFormatException) { - } - } val lastSelected = savedInstanceState[LAST_SELECT_NAV_MENU_ID] as String? if (lastSelected != null) { try { @@ -300,13 +273,11 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL } catch (ignored: NumberFormatException) { } } - setupBottomNavigationBar(false) + setupNavigation(false) } override fun onSupportNavigateUp(): Boolean { - if (currentNavControllerLiveData == null) return false - val navController = currentNavControllerLiveData?.value ?: return false - return navController.navigateUp() + return navController.navigateUp(appBarConfiguration) } override fun onNewIntent(intent: Intent) { @@ -331,14 +302,8 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL } override fun onBackPressed() { - var currentNavControllerBackStack = 2 - currentNavControllerLiveData?.let { - val navController = it.value - if (navController != null) { - @SuppressLint("RestrictedApi") val backStack = navController.backStack - currentNavControllerBackStack = backStack.size - } - } + val backStack = navController.backQueue + val currentNavControllerBackStack = backStack.size if (isTaskRoot && isBackStackEmpty && currentNavControllerBackStack == 2) { finishAfterTransition() return @@ -391,117 +356,40 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL notificationManager.createNotificationChannel(silentNotificationChannel) } - private fun setupBottomNavigationBar(setDefaultTabFromSettings: Boolean) { - currentTabs = if (!isLoggedIn) setupAnonBottomNav() else setupMainBottomNav() - val mainNavList = currentTabs.stream() - .map(Tab::navigationResId) - .collect(Collectors.toList()) + private fun setupNavigation(setDefaultTabFromSettings: Boolean) { + currentTabs = if (isLoggedIn) setupMainBottomNav() else setupAnonBottomNav() showBottomViewDestinations = currentTabs.asSequence().map { it.startDestinationFragmentId }.toMutableList().apply { add(R.id.postViewFragment) add(R.id.favoritesFragment) + add(R.id.profile_non_top) } if (setDefaultTabFromSettings) { setSelectedTab(currentTabs) } else { binding.bottomNavView.selectedItemId = lastSelectedNavMenuId } - val navControllerLiveData = NavigationExtensions.setupWithNavController( - binding.bottomNavView, - mainNavList, - supportFragmentManager, - R.id.main_nav_host, - intent, - firstFragmentGraphIndex - ) - navControllerLiveData.observe(this, { navController: NavController? -> setupNavigation(binding.toolbar, navController) }) - currentNavControllerLiveData = navControllerLiveData - } - - private fun setSelectedTab(tabs: List) { - val defaultTabResNameString = Utils.settingsHelper.getString(Constants.DEFAULT_TAB) - try { - var navId = 0 - if (!isEmpty(defaultTabResNameString)) { - navId = resources.getIdentifier(defaultTabResNameString, "navigation", packageName) - } - val navGraph = if (isLoggedIn) R.navigation.feed_nav_graph else R.navigation.profile_nav_graph - val defaultNavId = if (navId <= 0) navGraph else navId - var index = Iterators.indexOf(tabs.iterator()) { tab: Tab? -> - if (tab == null) return@indexOf false - tab.navigationResId == defaultNavId - } - if (index < 0 || index >= tabs.size) index = 0 - firstFragmentGraphIndex = index - setBottomNavSelectedTab(tabs[index]) - } catch (e: Exception) { - Log.e(TAG, "Error parsing id", e) + val navigatorProvider = navController.navigatorProvider + val navigator = navigatorProvider.getNavigator("navigation") + val rootNavGraph = NavGraph(navigator) + 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 } - } - - private fun setupAnonBottomNav(): List { - val selectedItemId = binding.bottomNavView.selectedItemId - val favoriteTab = Tab( - R.drawable.ic_star_24, - getString(R.string.title_favorites), - false, - "favorites_nav_graph", - R.navigation.favorites_nav_graph, - R.id.favorites_nav_graph, - R.id.favoritesFragment - ) - val profileTab = Tab( - R.drawable.ic_person_24, - getString(R.string.profile), - false, - "profile_nav_graph", - R.navigation.profile_nav_graph, - R.id.profile_nav_graph, - R.id.profileFragment - ) - val moreTab = Tab( - R.drawable.ic_more_horiz_24, - getString(R.string.more), - false, - "more_nav_graph", - R.navigation.more_nav_graph, - R.id.more_nav_graph, - R.id.morePreferencesFragment - ) - val menu = binding.bottomNavView.menu - menu.clear() - menu.add(0, favoriteTab.navigationRootId, 0, favoriteTab.title).setIcon(favoriteTab.iconResId) - menu.add(0, profileTab.navigationRootId, 0, profileTab.title).setIcon(profileTab.iconResId) - menu.add(0, moreTab.navigationRootId, 0, moreTab.title).setIcon(moreTab.iconResId) - if (selectedItemId != R.id.profile_nav_graph && selectedItemId != R.id.more_nav_graph && selectedItemId != R.id.favorites_nav_graph) { - setBottomNavSelectedTab(profileTab) - } - return ImmutableList.of(favoriteTab, profileTab, moreTab) - } - - private fun setupMainBottomNav(): List { - val menu = binding.bottomNavView.menu - menu.clear() - val navTabList = Utils.getNavTabList(this).first - for ((iconResId, title, _, _, _, navigationRootId) in navTabList) { - menu.add(0, navigationRootId, 0, title).setIcon(iconResId) - } - return navTabList - } - - private fun setBottomNavSelectedTab(tab: Tab) { - binding.bottomNavView.selectedItemId = tab.navigationRootId - } - - private fun setBottomNavSelectedTab(@IdRes navGraphRootId: Int) { - binding.bottomNavView.selectedItemId = navGraphRootId - } - - private fun setupNavigation(toolbar: Toolbar, navController: NavController?) { - if (navController == null) return - NavigationUI.setupWithNavController(toolbar, navController) - navController.addOnDestinationChangedListener(OnDestinationChangedListener { _: NavController?, destination: NavDestination, arguments: Bundle? -> + rootNavGraph.id = R.id.root_nav_graph + rootNavGraph.label = "root_nav_graph" + rootNavGraph.addDestinations(destinations) + rootNavGraph.setStartDestination(if (startNavRootId != 0) startNavRootId else R.id.profile_nav_graph) + navController.graph = rootNavGraph + binding.bottomNavView.setupWithNavController(navController) + appBarConfiguration = AppBarConfiguration(currentTabs.map { it.startDestinationFragmentId }.toSet()) + setupActionBarWithNavController(navController, appBarConfiguration) + navController.addOnDestinationChangedListener { _: NavController?, destination: NavDestination, arguments: Bundle? -> if (destination.id == R.id.directMessagesThreadFragment && arguments != null) { // Set the thread title earlier for better ux val title = arguments.getString("title") @@ -519,7 +407,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL // below is a hack to check if we are at the end of the current stack, to setup the search view binding.appBarLayout.setExpanded(true, true) val destinationId = destination.id - @SuppressLint("RestrictedApi") val backStack = navController.backStack + val backStack = navController.backQueue setupMenu(backStack.size, destinationId) val contains = showBottomViewDestinations.contains(destinationId) binding.root.post { @@ -531,7 +419,65 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL // explicitly hide keyboard when we navigate val view = currentFocus Utils.hideKeyboard(view) - }) + } + setupReselection() + } + + private fun setupReselection() { + binding.bottomNavView.setOnItemReselectedListener { + val navHostFragment = (supportFragmentManager.primaryNavigationFragment ?: return@setOnItemReselectedListener) as NavHostFragment + val currentFragment = navHostFragment.childFragmentManager.fragments.firstOrNull() ?: return@setOnItemReselectedListener + if (currentFragment is FeedFragment) { + currentFragment.scrollToTop() + return@setOnItemReselectedListener + } + val currentDestination = navController.currentDestination ?: return@setOnItemReselectedListener + val currentTabStartDestId = (navController.getBackStackEntry(it.itemId).destination as NavGraph).startDestinationId + if (currentDestination.id == currentTabStartDestId) return@setOnItemReselectedListener + navController.popBackStack(currentTabStartDestId, false) + } + } + + private fun setSelectedTab(tabs: List) { + val defaultTabResNameString = Utils.settingsHelper.getString(Constants.DEFAULT_TAB) + try { + var navId = 0 + if (defaultTabResNameString.isNotBlank()) { + navId = resources.getIdentifier(defaultTabResNameString, "id", packageName) + } + val startFragmentNavResId = if (navId <= 0) R.id.profile_nav_graph else navId + val tab = tabs.firstOrNull { it.navigationRootId == startFragmentNavResId } + // if (index < 0 || index >= tabs.size) index = 0 + val firstTab = tab ?: tabs[0] + startNavRootId = firstTab.navigationRootId + binding.bottomNavView.selectedItemId = firstTab.navigationRootId + } catch (e: Exception) { + Log.e(TAG, "Error parsing id", e) + } + } + + private fun setupAnonBottomNav(): List { + val selectedItemId = binding.bottomNavView.selectedItemId + val anonNavTabs = getAnonNavTabs(this) + val menu = binding.bottomNavView.menu + menu.clear() + for (tab in anonNavTabs) { + menu.add(0, tab.navigationRootId, 0, tab.title).setIcon(tab.iconResId) + } + if (selectedItemId != R.id.profile_nav_graph && selectedItemId != R.id.more_nav_graph && selectedItemId != R.id.favorites_nav_graph) { + binding.bottomNavView.selectedItemId = R.id.profile_nav_graph + } + return anonNavTabs + } + + private fun setupMainBottomNav(): List { + val menu = binding.bottomNavView.menu + menu.clear() + val navTabList = getLoggedInNavTabs(this).first + for (tab in navTabList) { + menu.add(0, tab.navigationRootId, 0, tab.title).setIcon(tab.iconResId) + } + return navTabList } private fun setupMenu(backStackSize: Int, destinationId: Int) { @@ -589,47 +535,11 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL fun navigateToThread(threadId: String?, threadTitle: String?) { if (threadId == null || threadTitle == null) return - currentNavControllerLiveData?.observe(this, object : Observer { - override fun onChanged(navController: NavController?) { - if (navController == null) return - if (navController.graph.id != R.id.direct_messages_nav_graph) return - try { - val currentDestination = navController.currentDestination - if (currentDestination != null && currentDestination.id == R.id.directMessagesInboxFragment) { - // if we are already on the inbox page, navigate to the thread - // need handler.post() to wait for the fragment manager to be ready to navigate - Handler(Looper.getMainLooper()).post { - val action = DirectMessageInboxFragmentDirections - .actionInboxToThread(threadId, threadTitle) - navController.navigate(action) - } - return - } - // add a destination change listener to navigate to thread once we are on the inbox page - navController.addOnDestinationChangedListener(object : OnDestinationChangedListener { - override fun onDestinationChanged( - controller: NavController, - destination: NavDestination, - arguments: Bundle?, - ) { - if (destination.id == R.id.directMessagesInboxFragment) { - val action = DirectMessageInboxFragmentDirections - .actionInboxToThread(threadId, threadTitle) - controller.navigate(action) - controller.removeOnDestinationChangedListener(this) - } - } - }) - // pop back stack until we reach the inbox page - navController.popBackStack(R.id.directMessagesInboxFragment, false) - } finally { - currentNavControllerLiveData?.removeObserver(this) - } - } - }) - val selectedItemId = binding.bottomNavView.selectedItemId - if (selectedItemId != R.navigation.direct_messages_nav_graph) { - setBottomNavSelectedTab(R.id.direct_messages_nav_graph) + try { + val action = NavGraphDirections.actionGlobalDirectThread(threadId, threadTitle) + navController.navigate(action) + } catch (e: Exception) { + Log.e(TAG, "navigateToThread: ", e) } } @@ -652,14 +562,10 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL } private fun showProfileView(intentModel: IntentModel) { - val username = intentModel.text - // Log.d(TAG, "username: " + username); - val currentNavControllerLiveData = currentNavControllerLiveData ?: return - val navController = currentNavControllerLiveData.value - val bundle = Bundle() - bundle.putString("username", "@$username") try { - navController?.navigate(R.id.action_global_profileFragment, bundle) + val username = intentModel.text + val action = NavGraphDirections.actionGlobalProfile().setUsername(username) + navController.navigate(action) } catch (e: Exception) { Log.e(TAG, "showProfileView: ", e) } @@ -681,12 +587,9 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL Toast.makeText(applicationContext, R.string.post_not_found, Toast.LENGTH_SHORT).show() return@withContext } - val currentNavControllerLiveData = currentNavControllerLiveData ?: return@withContext - val navController = currentNavControllerLiveData.value - val bundle = Bundle() - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media) try { - navController?.navigate(R.id.action_global_post_view, bundle) + val action = NavGraphDirections.actionGlobalPost(media, 0) + navController.navigate(action) } catch (e: Exception) { Log.e(TAG, "showPostView: ", e) } @@ -704,29 +607,32 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL private fun showLocationView(intentModel: IntentModel) { val locationId = intentModel.text // Log.d(TAG, "locationId: " + locationId); - val currentNavControllerLiveData = currentNavControllerLiveData ?: return - val navController = currentNavControllerLiveData.value - val bundle = Bundle() - bundle.putLong("locationId", locationId.toLong()) - navController?.navigate(R.id.action_global_locationFragment, bundle) + try { + val action = NavGraphDirections.actionGlobalLocation(locationId.toLong()) + navController.navigate(action) + } catch (e: Exception) { + Log.e(TAG, "showLocationView: ", e) + } } private fun showHashtagView(intentModel: IntentModel) { val hashtag = intentModel.text // Log.d(TAG, "hashtag: " + hashtag); - val currentNavControllerLiveData = currentNavControllerLiveData ?: return - val navController = currentNavControllerLiveData.value - val bundle = Bundle() - bundle.putString("hashtag", hashtag) - navController?.navigate(R.id.action_global_hashTagFragment, bundle) + try { + val action = NavGraphDirections.actionGlobalHashTag(hashtag) + navController.navigate(action) + } catch (e: Exception) { + Log.e(TAG, "showHashtagView: ", e) + } } private fun showActivityView() { - val currentNavControllerLiveData = currentNavControllerLiveData ?: return - val navController = currentNavControllerLiveData.value - val bundle = Bundle() - bundle.putString("type", "notif") - navController?.navigate(R.id.action_global_notificationsViewerFragment, bundle) + try { + val action = NavGraphDirections.actionGlobalNotifications().apply { type = "notif" } + navController.navigate(action) + } catch (e: Exception) { + Log.e(TAG, "showActivityView: ", e) + } } private fun bindActivityCheckerService() { @@ -763,8 +669,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL binding.appBarLayout.visibility = View.VISIBLE setScrollingBehaviour() setSupportActionBar(binding.toolbar) - val currentNavControllerLiveData = currentNavControllerLiveData ?: return - setupNavigation(binding.toolbar, currentNavControllerLiveData.value) + setupActionBarWithNavController(navController, appBarConfiguration) } val collapsingToolbarView: CollapsingToolbarLayout @@ -808,8 +713,7 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL binding.appBarLayout.visibility = View.GONE removeScrollingBehaviour() setSupportActionBar(toolbar) - if (currentNavControllerLiveData == null) return - setupNavigation(toolbar, currentNavControllerLiveData?.value) + NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration) } val rootView: View get() = binding.root @@ -839,8 +743,8 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL companion object { private const val TAG = "MainActivity" - private const val FIRST_FRAGMENT_GRAPH_INDEX_KEY = "firstFragmentGraphIndex" private const val LAST_SELECT_NAV_MENU_ID = "lastSelectedNavMenuId" + private val SEARCH_VISIBLE_DESTINATIONS: List = ImmutableList.of( R.id.feedFragment, R.id.profileFragment, diff --git a/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java b/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java index 11621a6c..a67166cf 100644 --- a/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java +++ b/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java @@ -1,60 +1,60 @@ -package awais.instagrabber.customviews; - -import android.os.Bundle; - -import androidx.annotation.NavigationRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.navigation.NavController; -import androidx.navigation.Navigator; -import androidx.navigation.fragment.FragmentNavigator; -import androidx.navigation.fragment.NavHostFragment; - -public class NavHostFragmentWithDefaultAnimations extends NavHostFragment { - private static final String KEY_GRAPH_ID = "android-support-nav:fragment:graphId"; - private static final String KEY_START_DESTINATION_ARGS = - "android-support-nav:fragment:startDestinationArgs"; - private static final String KEY_NAV_CONTROLLER_STATE = - "android-support-nav:fragment:navControllerState"; - private static final String KEY_DEFAULT_NAV_HOST = "android-support-nav:fragment:defaultHost"; - - @NonNull - public static NavHostFragment create(@NavigationRes int graphResId) { - return create(graphResId, null); - } - - @NonNull - public static NavHostFragment create(@NavigationRes int graphResId, - @Nullable Bundle startDestinationArgs) { - Bundle b = null; - if (graphResId != 0) { - b = new Bundle(); - b.putInt(KEY_GRAPH_ID, graphResId); - } - if (startDestinationArgs != null) { - if (b == null) { - b = new Bundle(); - } - b.putBundle(KEY_START_DESTINATION_ARGS, startDestinationArgs); - } - - final NavHostFragmentWithDefaultAnimations result = new NavHostFragmentWithDefaultAnimations(); - if (b != null) { - result.setArguments(b); - } - return result; - } - - @NonNull - @Override - protected Navigator createFragmentNavigator() { - return new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId()); - } - - @Override - protected void onCreateNavController(@NonNull final NavController navController) { - super.onCreateNavController(navController); - navController.getNavigatorProvider() - .addNavigator(new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId())); - } -} +// package awais.instagrabber.customviews; +// +// import android.os.Bundle; +// +// import androidx.annotation.NavigationRes; +// import androidx.annotation.NonNull; +// import androidx.annotation.Nullable; +// import androidx.navigation.NavController; +// import androidx.navigation.Navigator; +// import androidx.navigation.fragment.FragmentNavigator; +// import androidx.navigation.fragment.NavHostFragment; +// +// public class NavHostFragmentWithDefaultAnimations extends NavHostFragment { +// private static final String KEY_GRAPH_ID = "android-support-nav:fragment:graphId"; +// private static final String KEY_START_DESTINATION_ARGS = +// "android-support-nav:fragment:startDestinationArgs"; +// private static final String KEY_NAV_CONTROLLER_STATE = +// "android-support-nav:fragment:navControllerState"; +// private static final String KEY_DEFAULT_NAV_HOST = "android-support-nav:fragment:defaultHost"; +// +// @NonNull +// public static NavHostFragment create(@NavigationRes int graphResId) { +// return create(graphResId, null); +// } +// +// @NonNull +// public static NavHostFragment create(@NavigationRes int graphResId, +// @Nullable Bundle startDestinationArgs) { +// Bundle b = null; +// if (graphResId != 0) { +// b = new Bundle(); +// b.putInt(KEY_GRAPH_ID, graphResId); +// } +// if (startDestinationArgs != null) { +// if (b == null) { +// b = new Bundle(); +// } +// b.putBundle(KEY_START_DESTINATION_ARGS, startDestinationArgs); +// } +// +// final NavHostFragmentWithDefaultAnimations result = new NavHostFragmentWithDefaultAnimations(); +// if (b != null) { +// result.setArguments(b); +// } +// return result; +// } +// +// @NonNull +// @Override +// protected Navigator createFragmentNavigator() { +// return new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId()); +// } +// +// @Override +// protected void onCreateNavController(@NonNull final NavController navController) { +// super.onCreateNavController(navController); +// navController.getNavigatorProvider() +// .addNavigator(new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId())); +// } +// } diff --git a/app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java index 0ac2dd23..4ed6e8c5 100644 --- a/app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java +++ b/app/src/main/java/awais/instagrabber/dialogs/TabOrderPreferenceDialogFragment.java @@ -4,7 +4,6 @@ import android.app.Dialog; import android.content.Context; import android.graphics.Canvas; import android.os.Bundle; -import android.util.Pair; import android.view.View; import androidx.annotation.NonNull; @@ -28,7 +27,9 @@ import awais.instagrabber.adapters.TabsAdapter; import awais.instagrabber.adapters.viewholder.TabViewHolder; import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.Tab; +import awais.instagrabber.utils.NavigationHelperKt; import awais.instagrabber.utils.Utils; +import kotlin.Pair; import static androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_DRAG; import static androidx.recyclerview.widget.ItemTouchHelper.DOWN; @@ -235,9 +236,10 @@ public class TabOrderPreferenceDialogFragment extends DialogFragment { } private void saveNewOrder() { - final String newOrderString = newOrderTabs.stream() - .map(Tab::getGraphName) - .collect(Collectors.joining(",")); + final String newOrderString = newOrderTabs + .stream() + .map(tab -> NavigationHelperKt.geNavGraphNameForNavRootId(tab.getNavigationRootId())) + .collect(Collectors.joining(",")); Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString); } @@ -258,12 +260,12 @@ public class TabOrderPreferenceDialogFragment extends DialogFragment { itemTouchHelper.attachToRecyclerView(list); adapter = new TabsAdapter(tabAdapterCallback); list.setAdapter(adapter); - final Pair, List> navTabListPair = Utils.getNavTabList(context); - tabsInPref = navTabListPair.first; + final Pair, List> navTabListPair = NavigationHelperKt.getLoggedInNavTabs(context); + tabsInPref = navTabListPair.getFirst(); // initially set newOrderTabs and newOtherTabs same as current tabs - newOrderTabs = navTabListPair.first; - newOtherTabs = navTabListPair.second; - adapter.submitList(navTabListPair.first, navTabListPair.second); + newOrderTabs = navTabListPair.getFirst(); + newOtherTabs = navTabListPair.getSecond(); + adapter.submitList(navTabListPair.getFirst(), navTabListPair.getSecond()); return list; } diff --git a/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java b/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java index f69ebcc9..5b59ae65 100644 --- a/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java @@ -2,7 +2,6 @@ package awais.instagrabber.fragments; import android.animation.ArgbEvaluator; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Animatable; @@ -29,7 +28,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.graphics.ColorUtils; import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -54,7 +52,9 @@ import awais.instagrabber.databinding.FragmentCollectionPostsBinding; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.PostItemType; +import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; +import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.saved.SavedCollection; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; @@ -76,7 +76,6 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay private Set selectedFeedModels; private CollectionService collectionService; private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_SAVED_POSTS_LAYOUT); - private MenuItem deleteMenu, editMenu; private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) { @Override @@ -107,22 +106,28 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final Media feedModel, final View profilePicView, final View mainPostImage) { - openPostDialog(feedModel, profilePicView, mainPostImage, -1); + openPostDialog(feedModel, -1); } @Override public void onSliderClick(final Media feedModel, final int position) { - openPostDialog(feedModel, null, null, position); + openPostDialog(feedModel, position); } @Override public void onCommentsClick(final Media feedModel) { - final NavDirections commentsAction = CollectionPostsFragmentDirections.actionGlobalCommentsViewerFragment( - feedModel.getCode(), - feedModel.getPk(), - feedModel.getUser().getPk() - ); - NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(commentsAction); + final User user = feedModel.getUser(); + if (user == null) return; + try { + final NavDirections commentsAction = CollectionPostsFragmentDirections.actionToComments( + feedModel.getCode(), + feedModel.getPk(), + user.getPk() + ); + NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(commentsAction); + } catch (Exception e) { + Log.e(TAG, "onCommentsClick: ", e); + } } @Override @@ -134,14 +139,24 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = CollectionPostsFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(action); + try { + final NavDirections action = CollectionPostsFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override public void onLocationClick(final Media feedModel) { - final NavDirections action = CollectionPostsFragmentDirections.actionGlobalLocationFragment(feedModel.getLocation().getPk()); - NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(action); + final Location location = feedModel.getLocation(); + if (location == null) return; + try { + final NavDirections action = CollectionPostsFragmentDirections.actionToLocation(location.getPk()); + NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onLocationClick: ", e); + } } @Override @@ -151,12 +166,16 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay @Override public void onNameClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override public void onProfilePicClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override @@ -169,16 +188,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay Utils.openEmailAddress(getContext(), emailId); } - private void openPostDialog(final Media feedModel, - final View profilePicView, - final View mainPostImage, - final int position) { - final NavController navController = NavHostFragment.findNavController(CollectionPostsFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); + private void openPostDialog(final Media feedModel, final int position) { try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = CollectionPostsFragmentDirections.actionToPost(feedModel, position); + NavHostFragment.findNavController(CollectionPostsFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -265,10 +278,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay @Override public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) { inflater.inflate(R.menu.collection_posts_menu, menu); - deleteMenu = menu.findItem(R.id.delete); + final MenuItem deleteMenu = menu.findItem(R.id.delete); if (deleteMenu != null) deleteMenu.setVisible(savedCollection.getCollectionType().equals("MEDIA")); - editMenu = menu.findItem(R.id.edit); + final MenuItem editMenu = menu.findItem(R.id.edit); if (editMenu != null) editMenu.setVisible(savedCollection.getCollectionType().equals("MEDIA")); } @@ -411,9 +424,7 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay } private void setupCover() { - final String coverUrl = ResponseBodyUtils.getImageUrl(savedCollection.getCoverMediaList() == null - ? savedCollection.getCoverMedia() - : savedCollection.getCoverMediaList().get(0)); + final String coverUrl = ResponseBodyUtils.getImageUrl(savedCollection.getCoverMediaList().get(0)); final DraweeController controller = Fresco .newDraweeControllerBuilder() .setOldController(binding.cover.getController()) @@ -454,10 +465,12 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay } private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = CollectionPostsFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } private void showPostsLayoutPreferences() { diff --git a/app/src/main/java/awais/instagrabber/fragments/FavoritesFragment.kt b/app/src/main/java/awais/instagrabber/fragments/FavoritesFragment.kt index cbd587a2..6bb75bdb 100644 --- a/app/src/main/java/awais/instagrabber/fragments/FavoritesFragment.kt +++ b/app/src/main/java/awais/instagrabber/fragments/FavoritesFragment.kt @@ -8,7 +8,7 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import awais.instagrabber.R @@ -48,17 +48,17 @@ class FavoritesFragment : Fragment() { override fun onPause() { super.onPause() - adapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT) + adapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT } override fun onResume() { super.onResume() if (!this::adapter.isInitialized) return // refresh list every time in onViewStateRestored since it is cheaper than implementing pull down to refresh - favoritesViewModel.list.observe(viewLifecycleOwner, { - list: List? -> adapter.submitList(list, Runnable { - adapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.ALLOW) - }) + favoritesViewModel.list.observe(viewLifecycleOwner, { list: List? -> + adapter.submitList(list) { + adapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.ALLOW + } }) } @@ -66,32 +66,31 @@ class FavoritesFragment : Fragment() { adapter = FavoritesAdapter({ model: Favorite -> when (model.type) { FavoriteType.USER -> { - val username = model.query - // Log.d(TAG, "username: " + username); - val navController = NavHostFragment.findNavController(this) - val bundle = Bundle() - bundle.putString("username", "@$username") - navController.navigate(R.id.action_global_profileFragment, bundle) + try { + val username = model.query ?: return@FavoritesAdapter + val actionToProfile = FavoritesFragmentDirections.actionToProfile().apply { this.username = username } + findNavController().navigate(actionToProfile) + } catch (e: Exception) { + Log.e(TAG, "init: ", e) + } } FavoriteType.LOCATION -> { - val locationId = model.query ?: return@FavoritesAdapter - // Log.d(TAG, "locationId: " + locationId); - val navController = NavHostFragment.findNavController(this) - val bundle = Bundle() try { - bundle.putLong("locationId", locationId.toLong()) - navController.navigate(R.id.action_global_locationFragment, bundle) + val locationId = model.query ?: return@FavoritesAdapter + val actionToLocation = FavoritesFragmentDirections.actionToLocation(locationId.toLong()) + findNavController().navigate(actionToLocation) } catch (e: Exception) { Log.e(TAG, "init: ", e) } } FavoriteType.HASHTAG -> { - val hashtag = model.query - // Log.d(TAG, "hashtag: " + hashtag); - val navController = NavHostFragment.findNavController(this) - val bundle = Bundle() - bundle.putString("hashtag", "#$hashtag") - navController.navigate(R.id.action_global_hashTagFragment, bundle) + try { + val hashtag = model.query ?: return@FavoritesAdapter + val actionToHashtag = FavoritesFragmentDirections.actionToHashtag(hashtag) + findNavController().navigate(actionToHashtag) + } catch (e: Exception) { + Log.e(TAG, "init: ", e) + } } else -> { } diff --git a/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java index 26a1381b..c8aa2056 100644 --- a/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java @@ -18,6 +18,7 @@ import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.fragment.app.Fragment; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -209,10 +210,12 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh final Object tag = v.getTag(); if (tag instanceof FollowModel) { model = (FollowModel) tag; - final FollowViewerFragmentDirections.ActionFollowViewerFragmentToProfileFragment action = FollowViewerFragmentDirections - .actionFollowViewerFragmentToProfileFragment(); - action.setUsername("@" + model.getUsername()); - NavHostFragment.findNavController(this).navigate(action); + try { + final NavDirections action = FollowViewerFragmentDirections.actionToProfile().setUsername(model.getUsername()); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "init: ", e); + } } }; binding.swipeRefreshLayout.setOnRefreshListener(this); diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java index 189820f6..e1f1d5a0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java @@ -2,7 +2,6 @@ package awais.instagrabber.fragments; import android.annotation.SuppressLint; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; @@ -27,7 +26,6 @@ import androidx.appcompat.app.ActionBar; import androidx.constraintlayout.motion.widget.MotionLayout; import androidx.constraintlayout.motion.widget.MotionScene; import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.RecyclerView; @@ -53,7 +51,6 @@ import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.models.enums.FollowingType; -import awais.instagrabber.repositories.requests.StoryViewerOptions; import awais.instagrabber.repositories.responses.Hashtag; import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; @@ -67,7 +64,6 @@ import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.webservices.GraphQLRepository; import awais.instagrabber.webservices.ServiceCallback; -import awais.instagrabber.webservices.StoriesRepository; import awais.instagrabber.webservices.TagsService; import kotlinx.coroutines.Dispatchers; @@ -76,22 +72,17 @@ import static awais.instagrabber.utils.Utils.settingsHelper; public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { private static final String TAG = "HashTagFragment"; - public static final String ARG_HASHTAG = "hashtag"; - private MainActivity fragmentActivity; private FragmentHashtagBinding binding; private MotionLayout root; private boolean shouldRefresh = true; -// private boolean hasStories = false; private boolean opening = false; private String hashtag; private Hashtag hashtagModel = null; private ActionMode actionMode; - private StoriesRepository storiesRepository; private boolean isLoggedIn; private TagsService tagsService; private GraphQLRepository graphQLRepository; - private boolean storiesFetching; private Set selectedFeedModels; private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_HASHTAG_POSTS_LAYOUT); private LayoutHashtagDetailsBinding hashtagDetailsBinding; @@ -126,22 +117,28 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final Media feedModel, final View profilePicView, final View mainPostImage) { - openPostDialog(feedModel, profilePicView, mainPostImage, -1); + openPostDialog(feedModel, -1); } @Override public void onSliderClick(final Media feedModel, final int position) { - openPostDialog(feedModel, null, null, position); + openPostDialog(feedModel, position); } @Override public void onCommentsClick(final Media feedModel) { - final NavDirections commentsAction = HashTagFragmentDirections.actionGlobalCommentsViewerFragment( - feedModel.getCode(), - feedModel.getCode(), - feedModel.getUser().getPk() - ); - NavHostFragment.findNavController(HashTagFragment.this).navigate(commentsAction); + final User user = feedModel.getUser(); + if (user == null) return; + try { + final NavDirections commentsAction = HashTagFragmentDirections.actionToComments( + feedModel.getCode(), + feedModel.getCode(), + user.getPk() + ); + NavHostFragment.findNavController(HashTagFragment.this).navigate(commentsAction); + } catch (Exception e) { + Log.e(TAG, "onCommentsClick: ", e); + } } @Override @@ -153,16 +150,24 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = HashTagFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(HashTagFragment.this).navigate(action); + try { + final NavDirections action = HashTagFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(HashTagFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override public void onLocationClick(final Media media) { final Location location = media.getLocation(); if (location == null) return; - final NavDirections action = HashTagFragmentDirections.actionGlobalLocationFragment(location.getPk()); - NavHostFragment.findNavController(HashTagFragment.this).navigate(action); + try { + final NavDirections action = HashTagFragmentDirections.actionToLocation(location.getPk()); + NavHostFragment.findNavController(HashTagFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onLocationClick: ", e); + } } @Override @@ -172,12 +177,16 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe @Override public void onNameClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override public void onProfilePicClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override @@ -191,8 +200,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe } private void openPostDialog(@NonNull final Media feedModel, - final View profilePicView, - final View mainPostImage, final int position) { if (opening) return; final User user = feedModel.getUser(); @@ -200,24 +207,23 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe if (TextUtils.isEmpty(user.getUsername())) { // this only happens for anons opening = true; - graphQLRepository.fetchPost(feedModel.getCode(), CoroutineUtilsKt.getContinuation((media, throwable) -> { + final String code = feedModel.getCode(); + if (code == null) return; + graphQLRepository.fetchPost(code, CoroutineUtilsKt.getContinuation((media, throwable) -> { opening = false; if (throwable != null) { Log.e(TAG, "Error", throwable); return; } if (media == null) return; - AppExecutors.INSTANCE.getMainThread().execute(() -> openPostDialog(media, profilePicView, mainPostImage, position)); + AppExecutors.INSTANCE.getMainThread().execute(() -> openPostDialog(media, position)); }, Dispatchers.getIO())); return; } opening = true; - final NavController navController = NavHostFragment.findNavController(HashTagFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = HashTagFragmentDirections.actionToPost(feedModel, position); + NavHostFragment.findNavController(HashTagFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -280,7 +286,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe final String cookie = settingsHelper.getString(Constants.COOKIE); isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0; tagsService = isLoggedIn ? TagsService.getInstance() : null; - storiesRepository = isLoggedIn ? StoriesRepository.Companion.getInstance() : null; graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance(); setHasOptionsMenu(true); } @@ -309,7 +314,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe @Override public void onRefresh() { binding.posts.refresh(); -// fetchStories(); + // fetchStories(); } @Override @@ -385,7 +390,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe } setTitle(); setupPosts(); -// fetchStories(); + // fetchStories(); if (isLoggedIn) { hashtagDetailsBinding.btnFollowTag.setVisibility(View.VISIBLE); hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollowing() == FollowingType.FOLLOWING @@ -519,22 +524,23 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe ); hashtagDetailsBinding.mainHashtagImage.setImageURI("res:/" + R.drawable.ic_hashtag); final String postCount = String.valueOf(hashtagModel.getMediaCount()); - final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline, - hashtagModel.getMediaCount() > 2000000000L - ? 2000000000 - : Long.valueOf(hashtagModel.getMediaCount()).intValue(), - postCount)); + final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString( + R.plurals.main_posts_count_inline, + hashtagModel.getMediaCount() > 2000000000L ? 2000000000 + : Long.valueOf(hashtagModel.getMediaCount()).intValue(), + postCount) + ); span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0); hashtagDetailsBinding.mainTagPostCount.setText(span); hashtagDetailsBinding.mainTagPostCount.setVisibility(View.VISIBLE); -// hashtagDetailsBinding.mainHashtagImage.setOnClickListener(v -> { -// if (!hasStories) return; -// // show stories -// final NavDirections action = HashTagFragmentDirections -// .actionHashtagFragmentToStoryViewerFragment(StoryViewerOptions.forHashtag(hashtagModel.getName())); -// NavHostFragment.findNavController(this).navigate(action); -// }); + // hashtagDetailsBinding.mainHashtagImage.setOnClickListener(v -> { + // if (!hasStories) return; + // // show stories + // final NavDirections action = HashTagFragmentDirections + // .actionHashtagFragmentToStoryViewerFragment(StoryViewerOptions.forHashtag(hashtagModel.getName())); + // NavHostFragment.findNavController(this).navigate(action); + // }); } private void showSnackbar(final String message) { @@ -545,47 +551,24 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe .show(); } -// private void fetchStories() { -// if (!isLoggedIn) return; -// storiesFetching = true; -// storiesRepository.getStories( -// StoryViewerOptions.forHashtag(hashtagModel.getName()), -// CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { -// if (throwable != null) { -// Log.e(TAG, "Error", throwable); -// storiesFetching = false; -// return; -// } -// if (storyModels != null && !storyModels.isEmpty()) { -// hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(1); -// hasStories = true; -// } else { -// hasStories = false; -// } -// storiesFetching = false; -// }), Dispatchers.getIO()) -// ); -// } - private void setTitle() { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); if (actionBar != null) { - // Log.d(TAG, "setting title: " + hashtag); actionBar.setTitle('#' + hashtag); - // final Handler handler = new Handler(); - // handler.postDelayed(() -> , 1000); } } private void updateSwipeRefreshState() { - binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching() || storiesFetching); + binding.swipeRefreshLayout.setRefreshing(binding.posts.isFetching()); } private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = HashTagFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } private void showPostsLayoutPreferences() { diff --git a/app/src/main/java/awais/instagrabber/fragments/LikesViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/LikesViewerFragment.java index 5b3ca53d..bbf97bd6 100644 --- a/app/src/main/java/awais/instagrabber/fragments/LikesViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/LikesViewerFragment.java @@ -10,6 +10,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -19,7 +20,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import java.util.List; -import awais.instagrabber.R; import awais.instagrabber.adapters.LikesAdapter; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.databinding.FragmentLikesBinding; @@ -55,9 +55,12 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme final Object tag = v.getTag(); if (tag instanceof User) { User model = (User) tag; - final Bundle bundle = new Bundle(); - bundle.putString("username", "@" + model.getUsername()); - NavHostFragment.findNavController(LikesViewerFragment.this).navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = LikesViewerFragmentDirections.actionToProfile().setUsername(model.getUsername()); + NavHostFragment.findNavController(LikesViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onSuccess: ", e); + } } }); binding.rvLikes.setAdapter(likesAdapter); @@ -84,9 +87,12 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme final Object tag = v.getTag(); if (tag instanceof User) { User model = (User) tag; - final Bundle bundle = new Bundle(); - bundle.putString("username", "@" + model.getUsername()); - NavHostFragment.findNavController(LikesViewerFragment.this).navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = LikesViewerFragmentDirections.actionToProfile().setUsername(model.getUsername()); + NavHostFragment.findNavController(LikesViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onSuccess: ", e); + } } }); binding.rvLikes.setAdapter(likesAdapter); diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java index 17f1f1b9..6344eb8f 100644 --- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java @@ -3,7 +3,6 @@ package awais.instagrabber.fragments; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -25,7 +24,6 @@ import androidx.appcompat.app.ActionBar; import androidx.constraintlayout.motion.widget.MotionLayout; import androidx.constraintlayout.motion.widget.MotionScene; import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.RecyclerView; @@ -50,7 +48,6 @@ import awais.instagrabber.db.repositories.FavoriteRepository; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.FavoriteType; -import awais.instagrabber.repositories.requests.StoryViewerOptions; import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.User; @@ -76,7 +73,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR private FragmentLocationBinding binding; private MotionLayout root; private boolean shouldRefresh = true; -// private boolean hasStories = false; + // private boolean hasStories = false; private boolean opening = false; private long locationId; private Location locationModel; @@ -130,12 +127,18 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR @Override public void onCommentsClick(final Media feedModel) { - final NavDirections commentsAction = LocationFragmentDirections.actionGlobalCommentsViewerFragment( - feedModel.getCode(), - feedModel.getPk(), - feedModel.getUser().getPk() - ); - NavHostFragment.findNavController(LocationFragment.this).navigate(commentsAction); + final User user = feedModel.getUser(); + if (user == null) return; + try { + final NavDirections commentsAction = LocationFragmentDirections.actionToComments( + feedModel.getCode(), + feedModel.getPk(), + user.getPk() + ); + NavHostFragment.findNavController(LocationFragment.this).navigate(commentsAction); + } catch (Exception e) { + Log.e(TAG, "onCommentsClick: ", e); + } } @Override @@ -147,13 +150,19 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = LocationFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(LocationFragment.this).navigate(action); + try { + final NavDirections action = LocationFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(LocationFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override public void onLocationClick(final Media feedModel) { - final NavDirections action = LocationFragmentDirections.actionGlobalLocationFragment(feedModel.getLocation().getPk()); + final Location location = feedModel.getLocation(); + if (location == null) return; + final NavDirections action = LocationFragmentDirections.actionToLocation(location.getPk()); NavHostFragment.findNavController(LocationFragment.this).navigate(action); } @@ -206,12 +215,9 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR return; } opening = true; - final NavController navController = NavHostFragment.findNavController(LocationFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = LocationFragmentDirections.actionToPost(feedModel, position); + NavHostFragment.findNavController(LocationFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -305,7 +311,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR @Override public void onRefresh() { binding.posts.refresh(); -// fetchStories(); + // fetchStories(); } @Override @@ -386,7 +392,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR } setTitle(); setupPosts(); -// fetchStories(); + // fetchStories(); final long locationId = locationModel.getPk(); // binding.swipeRefreshLayout.setRefreshing(true); locationDetailsBinding.mainLocationImage.setImageURI("res:/" + R.drawable.ic_location); @@ -531,14 +537,14 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR ); }), Dispatchers.getIO()) )); -// locationDetailsBinding.mainLocationImage.setOnClickListener(v -> { -// if (hasStories) { -// // show stories -// final NavDirections action = LocationFragmentDirections -// .actionLocationFragmentToStoryViewerFragment(StoryViewerOptions.forLocation(locationId, locationModel.getName())); -// NavHostFragment.findNavController(this).navigate(action); -// } -// }); + // locationDetailsBinding.mainLocationImage.setOnClickListener(v -> { + // if (hasStories) { + // // show stories + // final NavDirections action = LocationFragmentDirections + // .actionLocationFragmentToStoryViewerFragment(StoryViewerOptions.forLocation(locationId, locationModel.getName())); + // NavHostFragment.findNavController(this).navigate(action); + // } + // }); } private void showSnackbar(final String message) { @@ -549,26 +555,26 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR .show(); } -// private void fetchStories() { -// if (isLoggedIn) { -// storiesFetching = true; -// storiesRepository.getStories( -// StoryViewerOptions.forLocation(locationId, locationModel.getName()), -// CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { -// if (throwable != null) { -// Log.e(TAG, "Error", throwable); -// storiesFetching = false; -// return; -// } -// if (storyModels != null && !storyModels.isEmpty()) { -// locationDetailsBinding.mainLocationImage.setStoriesBorder(1); -// hasStories = true; -// } -// storiesFetching = false; -// }), Dispatchers.getIO()) -// ); -// } -// } + // private void fetchStories() { + // if (isLoggedIn) { + // storiesFetching = true; + // storiesRepository.getStories( + // StoryViewerOptions.forLocation(locationId, locationModel.getName()), + // CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + // if (throwable != null) { + // Log.e(TAG, "Error", throwable); + // storiesFetching = false; + // return; + // } + // if (storyModels != null && !storyModels.isEmpty()) { + // locationDetailsBinding.mainLocationImage.setStoriesBorder(1); + // hasStories = true; + // } + // storiesFetching = false; + // }), Dispatchers.getIO()) + // ); + // } + // } private void setTitle() { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); @@ -582,10 +588,12 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR } private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = LocationFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } private void showPostsLayoutPreferences() { diff --git a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java index 4ce968b7..a997bc65 100644 --- a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java @@ -20,7 +20,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NotificationManagerCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.LinearLayoutManager; @@ -50,8 +49,6 @@ import awais.instagrabber.webservices.NewsService; import awais.instagrabber.webservices.ServiceCallback; import kotlinx.coroutines.Dispatchers; -import static awais.instagrabber.utils.Utils.settingsHelper; - public final class NotificationsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { private static final String TAG = "NotificationsViewer"; @@ -98,10 +95,14 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe if (model.getType() == NotificationType.RESPONDED_STORY) { final StoryViewerOptions options = StoryViewerOptions.forStory( mediaId, - model.getArgs().getUsername()); - final Bundle bundle = new Bundle(); - bundle.putSerializable("options", options); - NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(R.id.action_notifications_to_story, bundle); + model.getArgs().getUsername() + ); + try { + final NavDirections action = NotificationsViewerFragmentDirections.actionToStory(options); + NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onPreviewClick: ", e); + } } else { final AlertDialog alertDialog = new AlertDialog.Builder(context) .setCancelable(false) @@ -116,14 +117,13 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); return; } - final NavController navController = NavHostFragment.findNavController(NotificationsViewerFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media); try { - navController.navigate(R.id.action_global_post_view, bundle); - alertDialog.dismiss(); + final NavDirections action = NotificationsViewerFragmentDirections.actionToPost(media, 0); + NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "onSuccess: ", e); + } finally { + alertDialog.dismiss(); } }), Dispatchers.getIO()) ); @@ -257,7 +257,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe type = fragmentArgs.getType(); targetId = fragmentArgs.getTargetId(); final Context context = getContext(); - CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE)); + CookieUtils.setupCookies(Utils.settingsHelper.getString(Constants.COOKIE)); binding.swipeRefreshLayout.setOnRefreshListener(this); notificationViewModel = new ViewModelProvider(this).get(NotificationViewModel.class); final NotificationsAdapter adapter = new NotificationsAdapter(clickListener); @@ -288,7 +288,11 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe } private void openProfile(final String username) { - final NavDirections action = NotificationsViewerFragmentDirections.actionGlobalProfileFragment("@" + username); - NavHostFragment.findNavController(this).navigate(action); + try { + final NavDirections action = NotificationsViewerFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "openProfile: ", e); + } } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java index 9a987981..5a7c99f8 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java @@ -40,6 +40,7 @@ import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavBackStackEntry; import androidx.navigation.NavController; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.RecyclerView; import androidx.transition.TransitionManager; @@ -70,7 +71,6 @@ import java.util.List; import java.util.Set; import awais.instagrabber.R; -import awais.instagrabber.UserSearchNavGraphDirections; import awais.instagrabber.activities.MainActivity; import awais.instagrabber.adapters.SliderCallbackAdapter; import awais.instagrabber.adapters.SliderItemsAdapter; @@ -103,9 +103,7 @@ import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.PostViewV2ViewModel; -import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG; import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_SHOWN_COUNT_TOOLTIP; -import static awais.instagrabber.utils.Utils.settingsHelper; public class PostViewV2Fragment extends Fragment implements EditTextDialogFragment.EditTextDialogFragmentCallback { private static final String TAG = "PostViewV2Fragment"; @@ -217,7 +215,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme public void onPause() { super.onPause(); // wasPaused = true; - if (settingsHelper.getBoolean(PreferenceKeys.PLAY_IN_BACKGROUND)) return; + if (Utils.settingsHelper.getBoolean(PreferenceKeys.PLAY_IN_BACKGROUND)) return; final Media media = viewModel.getMedia(); if (media.getType() == null) return; switch (media.getType()) { @@ -333,7 +331,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme viewModel.getLikeCount().observe(getViewLifecycleOwner(), count -> { bottom.likesCount.setNumber(getSafeCount(count)); binding.getRoot().postDelayed(() -> bottom.likesCount.setAnimateChanges(true), 1000); - if (count > 1000 && !settingsHelper.getBoolean(PREF_SHOWN_COUNT_TOOLTIP)) { + if (count > 1000 && !Utils.settingsHelper.getBoolean(PREF_SHOWN_COUNT_TOOLTIP)) { binding.getRoot().postDelayed(this::showCountTooltip, 1000); } }); @@ -392,7 +390,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme .setDismissWhenOverlayClicked(false) .build(); balloon.showAlignBottom(bottom.likesCount); - settingsHelper.putBoolean(PREF_SHOWN_COUNT_TOOLTIP, true); + Utils.settingsHelper.putBoolean(PREF_SHOWN_COUNT_TOOLTIP, true); balloon.setOnBalloonOutsideTouchListener((view, motionEvent) -> { if (rect.contains((int) motionEvent.getRawX(), (int) motionEvent.getRawY())) { bottom.likesCount.setShowAbbreviation(false); @@ -431,12 +429,9 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme if (user == null) return; final NavController navController = getNavController(); if (navController == null) return; - final Bundle bundle = new Bundle(); - bundle.putString("shortCode", media.getCode()); - bundle.putString("postId", media.getPk()); - bundle.putLong("postUserId", user.getPk()); try { - navController.navigate(R.id.action_global_commentsViewerFragment, bundle); + final NavDirections action = PostViewV2FragmentDirections.actionToComments(media.getCode(), media.getPk(), user.getPk()); + navController.navigate(action); } catch (Exception e) { Log.e(TAG, "setupComment: ", e); } @@ -445,9 +440,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme } private void setupDownload() { - bottom.download.setOnClickListener(v -> { - DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition, bottom.download); - }); + bottom.download.setOnClickListener(v -> DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition, bottom.download)); TooltipCompat.setTooltipText(bottom.download, getString(R.string.action_download)); } @@ -470,10 +463,12 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme bottom.like.setOnLongClickListener(v -> { final NavController navController = getNavController(); if (navController != null && viewModel.isLoggedIn()) { - final Bundle bundle = new Bundle(); - bundle.putString("postId", viewModel.getMedia().getPk()); - bundle.putBoolean("isComment", false); - navController.navigate(R.id.action_global_likesViewerFragment, bundle); + try { + final NavDirections action = PostViewV2FragmentDirections.actionToLikes(viewModel.getMedia().getPk(), false); + navController.navigate(action); + } catch (Exception e) { + Log.e(TAG, "setupLike: ", e); + } return true; } return true; @@ -543,11 +538,14 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme handleSaveUnsaveResourceLiveData(viewModel.toggleSave()); }); bottom.save.setOnLongClickListener(v -> { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putBoolean("isSaving", true); - navController.navigate(R.id.action_global_savedCollectionsFragment, bundle); - return true; + try { + final NavDirections action = PostViewV2FragmentDirections.actionToSavedCollections().setIsSaving(true); + NavHostFragment.findNavController(this).navigate(action); + return true; + } catch (Exception e) { + Log.e(TAG, "setupSave: ", e); + } + return false; }); } @@ -668,11 +666,13 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme } final String postCaption = caption.getText(); bottom.caption.addOnHashtagListener(autoLinkItem -> { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - final String originalText = autoLinkItem.getOriginalText().trim(); - bundle.putString(ARG_HASHTAG, originalText); - navController.navigate(R.id.action_global_hashTagFragment, bundle); + try { + final String originalText = autoLinkItem.getOriginalText().trim(); + final NavDirections action = PostViewV2FragmentDirections.actionToHashtag(originalText); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "setupCaption: ", e); + } }); bottom.caption.addOnMentionClickListener(autoLinkItem -> { final String originalText = autoLinkItem.getOriginalText().trim(); @@ -701,7 +701,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme case ERROR: bottom.translate.setEnabled(true); String message = resource.message; - if (TextUtils.isEmpty(resource.message)) { + if (TextUtils.isEmpty(message)) { message = getString(R.string.downloader_unknown_error); } final Snackbar snackbar = Snackbar.make(binding.getRoot(), message, Snackbar.LENGTH_INDEFINITE); @@ -725,11 +725,14 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme binding.location.setText(locationName); binding.location.setVisibility(View.VISIBLE); binding.location.setOnClickListener(v -> { - final NavController navController = getNavController(); - if (navController == null) return; - final Bundle bundle = new Bundle(); - bundle.putLong("locationId", location.getPk()); - navController.navigate(R.id.action_global_locationFragment, bundle); + try { + final NavController navController = getNavController(); + if (navController == null) return; + final NavDirections action = PostViewV2FragmentDirections.actionToLocation(location.getPk()); + navController.navigate(action); + } catch (Exception e) { + Log.e(TAG, "setupLocation: ", e); + } }); } @@ -755,16 +758,15 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme popupMenu.setOnMenuItemClickListener(item -> { final int itemId = item.getItemId(); if (itemId == R.id.share_dm) { - final UserSearchNavGraphDirections.ActionGlobalUserSearch actionGlobalUserSearch = UserSearchFragmentDirections - .actionGlobalUserSearch() - .setTitle(getString(R.string.share)) - .setActionLabel(getString(R.string.send)) - .setShowGroups(true) - .setMultiple(true) - .setSearchMode(UserSearchFragment.SearchMode.RAVEN); - final NavController navController = NavHostFragment.findNavController(PostViewV2Fragment.this); try { - navController.navigate(actionGlobalUserSearch); + final NavDirections actionGlobalUserSearch = PostViewV2FragmentDirections + .actionToUserSearch() + .setTitle(getString(R.string.share)) + .setActionLabel(getString(R.string.send)) + .setShowGroups(true) + .setMultiple(true) + .setSearchMode(UserSearchMode.RAVEN); + NavHostFragment.findNavController(this).navigate(actionGlobalUserSearch); } catch (Exception e) { Log.e(TAG, "setupShare: ", e); } @@ -1087,7 +1089,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme // gestureDetector.onTouchEvent(event); // return true; // }); - final float vol = settingsHelper.getBoolean(PreferenceKeys.MUTED_VIDEOS) ? 0f : 1f; + final float vol = Utils.settingsHelper.getBoolean(PreferenceKeys.MUTED_VIDEOS) ? 0f : 1f; final VideoPlayerViewHelper.VideoPlayerCallback videoPlayerCallback = new VideoPlayerCallbackAdapter() { @Override public void onThumbnailLoaded() { @@ -1423,9 +1425,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme final CollapsingToolbarLayout appbarLayout = activity.getCollapsingToolbarView(); appbarLayout.setVisibility(View.GONE); final Toolbar toolbar = activity.getToolbar(); - if (toolbar != null) { - toolbar.setVisibility(View.GONE); - } + toolbar.setVisibility(View.GONE); binding.getRoot().setPadding(binding.getRoot().getPaddingLeft(), binding.getRoot().getPaddingTop(), binding.getRoot().getPaddingRight(), @@ -1448,9 +1448,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme final CollapsingToolbarLayout appbarLayout = activity.getCollapsingToolbarView(); appbarLayout.setVisibility(View.VISIBLE); final Toolbar toolbar = activity.getToolbar(); - if (toolbar != null) { - toolbar.setVisibility(View.VISIBLE); - } + toolbar.setVisibility(View.VISIBLE); final Context context = getContext(); if (context == null) return; binding.getRoot().setPadding(binding.getRoot().getPaddingLeft(), @@ -1465,9 +1463,8 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme private void navigateToProfile(final String username) { final NavController navController = getNavController(); if (navController == null) return; - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + final NavDirections actionToProfile = PostViewV2FragmentDirections.actionToProfile().setUsername(username); + navController.navigate(actionToProfile); } @Nullable diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java index 35382476..57127d8e 100644 --- a/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java @@ -21,6 +21,7 @@ import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavBackStackEntry; import androidx.navigation.NavController; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.FragmentNavigator; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -151,8 +152,8 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa try { final FragmentNavigator.Extras.Builder builder = new FragmentNavigator.Extras.Builder() .addSharedElement(cover, "collection-" + topicCluster.getCollectionId()); - final SavedCollectionsFragmentDirections.ActionSavedCollectionsFragmentToCollectionPostsFragment action = SavedCollectionsFragmentDirections - .actionSavedCollectionsFragmentToCollectionPostsFragment(topicCluster, titleColor, backgroundColor); + final NavDirections action = SavedCollectionsFragmentDirections + .actionToCollectionPosts(topicCluster, titleColor, backgroundColor); navController.navigate(action, builder.build()); } catch (Exception e) { Log.e(TAG, "setupTopics: ", e); diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java index 57c40b85..e1559e82 100644 --- a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java @@ -1,7 +1,6 @@ package awais.instagrabber.fragments; import android.content.Context; -import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.util.Log; @@ -20,7 +19,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -38,7 +36,9 @@ import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.fragments.main.ProfileFragmentDirections; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.PostItemType; +import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; +import awais.instagrabber.repositories.responses.User; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DownloadUtils; @@ -90,22 +90,28 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final Media feedModel, final View profilePicView, final View mainPostImage) { - openPostDialog(feedModel, profilePicView, mainPostImage, -1); + openPostDialog(feedModel, -1); } @Override public void onSliderClick(final Media feedModel, final int position) { - openPostDialog(feedModel, null, null, position); + openPostDialog(feedModel, position); } @Override public void onCommentsClick(final Media feedModel) { - final NavDirections commentsAction = ProfileFragmentDirections.actionGlobalCommentsViewerFragment( - feedModel.getCode(), - feedModel.getPk(), - feedModel.getUser().getPk() - ); - NavHostFragment.findNavController(SavedViewerFragment.this).navigate(commentsAction); + final User user = feedModel.getUser(); + if (user == null) return; + try { + final NavDirections commentsAction = ProfileFragmentDirections.actionToComments( + feedModel.getCode(), + feedModel.getPk(), + user.getPk() + ); + NavHostFragment.findNavController(SavedViewerFragment.this).navigate(commentsAction); + } catch (Exception e) { + Log.e(TAG, "onCommentsClick: ", e); + } } @Override @@ -117,14 +123,24 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = ProfileFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(SavedViewerFragment.this).navigate(action); + try { + final NavDirections action = ProfileFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(SavedViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override public void onLocationClick(final Media feedModel) { - final NavDirections action = ProfileFragmentDirections.actionGlobalLocationFragment(feedModel.getLocation().getPk()); - NavHostFragment.findNavController(SavedViewerFragment.this).navigate(action); + final Location location = feedModel.getLocation(); + if (location == null) return; + try { + final NavDirections action = ProfileFragmentDirections.actionToLocation(location.getPk()); + NavHostFragment.findNavController(SavedViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onLocationClick: ", e); + } } @Override @@ -134,12 +150,16 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL @Override public void onNameClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override public void onProfilePicClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override @@ -152,16 +172,10 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL Utils.openEmailAddress(getContext(), emailId); } - private void openPostDialog(final Media feedModel, - final View profilePicView, - final View mainPostImage, - final int position) { - final NavController navController = NavHostFragment.findNavController(SavedViewerFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); + private void openPostDialog(final Media feedModel, final int position) { try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = SavedViewerFragmentDirections.actionToPost(feedModel, position); + NavHostFragment.findNavController(SavedViewerFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -317,10 +331,12 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL } private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = SavedViewerFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } private void showPostsLayoutPreferences() { diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java index 6f0516a2..92dd23e4 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java @@ -37,7 +37,6 @@ import awais.instagrabber.adapters.HighlightStoriesListAdapter; import awais.instagrabber.adapters.HighlightStoriesListAdapter.OnHighlightStoryClickListener; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.databinding.FragmentStoryListViewerBinding; -import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections; import awais.instagrabber.repositories.requests.StoryViewerOptions; import awais.instagrabber.repositories.responses.stories.ArchiveResponse; import awais.instagrabber.repositories.responses.stories.Story; @@ -74,9 +73,12 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr if (feedStoryModels == null) return; final int position = Iterables.indexOf(feedStoryModels, feedStoryModel -> feedStoryModel != null && Objects.equals(feedStoryModel.getId(), model.getId())); - final NavDirections action = StoryListViewerFragmentDirections - .actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forFeedStoryPosition(position)); - NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action); + try { + final NavDirections action = StoryListViewerFragmentDirections.actionToStory(StoryViewerOptions.forFeedStoryPosition(position)); + NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onFeedStoryClick: ", e); + } } @Override @@ -89,9 +91,12 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr @Override public void onHighlightClick(final Story model, final int position) { if (model == null) return; - final NavDirections action = StoryListViewerFragmentDirections - .actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forStoryArchive(position)); - NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action); + try { + final NavDirections action = StoryListViewerFragmentDirections.actionToStory(StoryViewerOptions.forStoryArchive(position)); + NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHighlightClick: ", e); + } } @Override @@ -271,8 +276,11 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr } private void openProfile(final String username) { - final NavDirections action = MorePreferencesFragmentDirections - .actionGlobalProfileFragment("@" + username); - NavHostFragment.findNavController(this).navigate(action); + try { + final NavDirections action = StoryListViewerFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "openProfile: ", e); + } } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index d6400c7e..2a046d66 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -58,13 +58,13 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import java.io.IOException; import java.text.NumberFormat; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; -import java.util.stream.Collectors; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import awais.instagrabber.BuildConfig; import awais.instagrabber.R; @@ -78,7 +78,16 @@ import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.requests.StoryViewerOptions; import awais.instagrabber.repositories.requests.StoryViewerOptions.Type; import awais.instagrabber.repositories.requests.directmessages.ThreadIdsOrUserIds; -import awais.instagrabber.repositories.responses.stories.*; +import awais.instagrabber.repositories.responses.stories.Broadcast; +import awais.instagrabber.repositories.responses.stories.PollSticker; +import awais.instagrabber.repositories.responses.stories.QuestionSticker; +import awais.instagrabber.repositories.responses.stories.QuizSticker; +import awais.instagrabber.repositories.responses.stories.SliderSticker; +import awais.instagrabber.repositories.responses.stories.Story; +import awais.instagrabber.repositories.responses.stories.StoryAppAttribution; +import awais.instagrabber.repositories.responses.stories.StoryCta; +import awais.instagrabber.repositories.responses.stories.StoryMedia; +import awais.instagrabber.repositories.responses.stories.Tally; import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; @@ -459,7 +468,8 @@ public class StoryViewerFragment extends Fragment { final Bundle bundle = new Bundle(); bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media); try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = StoryViewerFragmentDirections.actionToPost(media, 0); + navController.navigate(action); alertDialog.dismiss(); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); @@ -1243,14 +1253,13 @@ public class StoryViewerFragment extends Fragment { } final char t = username.charAt(0); if (t == '@') { - final NavDirections action = HashTagFragmentDirections.actionGlobalProfileFragment(username); + final NavDirections action = HashTagFragmentDirections.actionToProfile().setUsername(username); NavHostFragment.findNavController(this).navigate(action); } else if (t == '#') { - final NavDirections action = HashTagFragmentDirections.actionGlobalHashTagFragment(username.substring(1)); + final NavDirections action = HashTagFragmentDirections.actionToHashtag(username.substring(1)); NavHostFragment.findNavController(this).navigate(action); } else { - final NavDirections action = ProfileFragmentDirections - .actionGlobalLocationFragment(Long.parseLong(username.split(" \\(")[1].replace(")", ""))); + final NavDirections action = ProfileFragmentDirections.actionToLocation(Long.parseLong(username.split(" \\(")[1].replace(")", ""))); NavHostFragment.findNavController(this).navigate(action); } } diff --git a/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java b/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java index acbc2eef..bcc8a1e2 100644 --- a/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java @@ -2,7 +2,6 @@ package awais.instagrabber.fragments; import android.animation.ArgbEvaluator; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Animatable; @@ -26,7 +25,6 @@ import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.graphics.ColorUtils; import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -49,9 +47,10 @@ import awais.instagrabber.asyncs.DiscoverPostFetchService; import awais.instagrabber.customviews.PrimaryActionModeCallback; import awais.instagrabber.databinding.FragmentTopicPostsBinding; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; -import awais.instagrabber.fragments.main.DiscoverFragmentDirections; import awais.instagrabber.models.PostsLayoutPreferences; +import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; +import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.discover.TopicCluster; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.DownloadUtils; @@ -101,20 +100,22 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final Media feedModel, final View profilePicView, final View mainPostImage) { - openPostDialog(feedModel, profilePicView, mainPostImage, -1); + openPostDialog(feedModel, -1); } @Override public void onSliderClick(final Media feedModel, final int position) { - openPostDialog(feedModel, null, null, position); + openPostDialog(feedModel, position); } @Override public void onCommentsClick(final Media feedModel) { - final NavDirections commentsAction = DiscoverFragmentDirections.actionGlobalCommentsViewerFragment( + final User user = feedModel.getUser(); + if (user == null) return; + final NavDirections commentsAction = TopicPostsFragmentDirections.actionToComments( feedModel.getCode(), feedModel.getPk(), - feedModel.getUser().getPk() + user.getPk() ); NavHostFragment.findNavController(TopicPostsFragment.this).navigate(commentsAction); } @@ -128,13 +129,15 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = DiscoverFragmentDirections.actionGlobalHashTagFragment(hashtag); + final NavDirections action = TopicPostsFragmentDirections.actionToHashtag(hashtag); NavHostFragment.findNavController(TopicPostsFragment.this).navigate(action); } @Override public void onLocationClick(final Media feedModel) { - final NavDirections action = DiscoverFragmentDirections.actionGlobalLocationFragment(feedModel.getLocation().getPk()); + final Location location = feedModel.getLocation(); + if (location == null) return; + final NavDirections action = TopicPostsFragmentDirections.actionToLocation(location.getPk()); NavHostFragment.findNavController(TopicPostsFragment.this).navigate(action); } @@ -150,7 +153,9 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O @Override public void onProfilePicClick(final Media feedModel, final View profilePicView) { - navigateToProfile("@" + feedModel.getUser().getUsername()); + final User user = feedModel.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } @Override @@ -163,16 +168,10 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O Utils.openEmailAddress(getContext(), emailId); } - private void openPostDialog(final Media feedModel, - final View profilePicView, - final View mainPostImage, - final int position) { - final NavController navController = NavHostFragment.findNavController(TopicPostsFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); + private void openPostDialog(final Media feedModel, final int position) { try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = TopicPostsFragmentDirections.actionGlobalPost(feedModel, position); + NavHostFragment.findNavController(TopicPostsFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -218,11 +217,14 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); fragmentActivity = (MainActivity) requireActivity(); - final TransitionSet transitionSet = new TransitionSet(); - transitionSet.addTransition(new ChangeBounds()) - .addTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move)) - .setDuration(200); - setSharedElementEnterTransition(transitionSet); + final Context context = getContext(); + if (context != null) { + final TransitionSet transitionSet = new TransitionSet(); + transitionSet.addTransition(new ChangeBounds()) + .addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.move)) + .setDuration(200); + setSharedElementEnterTransition(transitionSet); + } postponeEnterTransition(); setHasOptionsMenu(true); } @@ -379,10 +381,12 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O } private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = TopicPostsFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } private void showPostsLayoutPreferences() { diff --git a/app/src/main/java/awais/instagrabber/fragments/UserSearchFragment.java b/app/src/main/java/awais/instagrabber/fragments/UserSearchFragment.java index 4fa33649..417b7237 100644 --- a/app/src/main/java/awais/instagrabber/fragments/UserSearchFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/UserSearchFragment.java @@ -309,20 +309,4 @@ public class UserSearchFragment extends Fragment { } return null; } - - public enum SearchMode { - USER_SEARCH("user_name"), - RAVEN("raven"), - RESHARE("reshare"); - - private final String name; - - SearchMode(final String name) { - this.name = name; - } - - public String getName() { - return name; - } - } } diff --git a/app/src/main/java/awais/instagrabber/fragments/UserSearchMode.kt b/app/src/main/java/awais/instagrabber/fragments/UserSearchMode.kt new file mode 100644 index 00000000..8d0da314 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/fragments/UserSearchMode.kt @@ -0,0 +1,7 @@ +package awais.instagrabber.fragments + +enum class UserSearchMode(name: String) { + USER_SEARCH("user_name"), + RAVEN("raven"), + RESHARE("reshare"); +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/comments/CommentsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/comments/CommentsViewerFragment.java index 6e3ba016..0b5dbc82 100644 --- a/app/src/main/java/awais/instagrabber/fragments/comments/CommentsViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/comments/CommentsViewerFragment.java @@ -205,7 +205,7 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment { viewModel, (comment, focusInput) -> { if (comment == null) return null; - final RepliesFragment repliesFragment = RepliesFragment.newInstance(comment, focusInput == null ? false : focusInput); + final RepliesFragment repliesFragment = RepliesFragment.newInstance(comment, focusInput != null && focusInput); getChildFragmentManager().beginTransaction() .setCustomAnimations(R.anim.slide_left, R.anim.slide_right, 0, R.anim.slide_right) .add(R.id.replies_container_view, repliesFragment) diff --git a/app/src/main/java/awais/instagrabber/fragments/comments/Helper.java b/app/src/main/java/awais/instagrabber/fragments/comments/Helper.java index c3fc3f32..f3aabf54 100644 --- a/app/src/main/java/awais/instagrabber/fragments/comments/Helper.java +++ b/app/src/main/java/awais/instagrabber/fragments/comments/Helper.java @@ -1,7 +1,7 @@ package awais.instagrabber.fragments.comments; import android.content.Context; -import android.os.Bundle; +import android.graphics.drawable.Drawable; import android.text.Editable; import android.util.Log; import android.view.View; @@ -45,7 +45,10 @@ public final class Helper { @NonNull final RecyclerView.OnScrollListener lazyLoader) { list.setLayoutManager(layoutManager); final DividerItemDecoration itemDecoration = new DividerItemDecoration(context, LinearLayoutManager.VERTICAL); - itemDecoration.setDrawable(ContextCompat.getDrawable(context, R.drawable.pref_list_divider_material)); + final Drawable drawable = ContextCompat.getDrawable(context, R.drawable.pref_list_divider_material); + if (drawable != null) { + itemDecoration.setDrawable(drawable); + } list.addItemDecoration(itemDecoration); list.addOnScrollListener(lazyLoader); } @@ -68,8 +71,7 @@ public final class Helper { public void onHashtagClick(final String hashtag) { try { if (navController == null) return; - final NavDirections action = CommentsViewerFragmentDirections.actionGlobalHashTagFragment(hashtag); - navController.navigate(action); + navController.navigate(CommentsViewerFragmentDirections.actionToHashtag(hashtag)); } catch (Exception e) { Log.e(TAG, "onHashtagClick: ", e); } @@ -123,12 +125,10 @@ public final class Helper { @Override public void onViewLikes(final Comment comment) { - if (navController == null) return; try { - final Bundle bundle = new Bundle(); - bundle.putString("postId", comment.getPk()); - bundle.putBoolean("isComment", true); - navController.navigate(R.id.action_global_likesViewerFragment, bundle); + if (navController == null) return; + final NavDirections actionToLikes = CommentsViewerFragmentDirections.actionToLikes(comment.getPk(), true); + navController.navigate(actionToLikes); } catch (Exception e) { Log.e(TAG, "onViewLikes: ", e); } @@ -144,10 +144,7 @@ public final class Helper { Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); return; } - String username = ""; - if (comment.getUser() != null) { - username = comment.getUser().getUsername(); - } + final String username = comment.getUser().getUsername(); new MaterialAlertDialogBuilder(context) .setTitle(username) .setMessage(result) @@ -192,9 +189,9 @@ public final class Helper { private static void openProfile(final NavController navController, @NonNull final String username) { - if (navController == null) return; try { - final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment(username); + if (navController == null) return; + final NavDirections action = CommentsViewerFragmentDirections.actionToProfile().setUsername(username); navController.navigate(action); } catch (Exception e) { Log.e(TAG, "openProfile: ", e); diff --git a/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java b/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java index e799e673..ebeb89fa 100644 --- a/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java @@ -185,18 +185,22 @@ public class RepliesFragment extends Fragment { private void setupAdapter(final long currentUserId) { final Context context = getContext(); if (context == null) return; - commentsAdapter = new CommentsAdapter(currentUserId, - true, - Helper.getCommentCallback(context, - getViewLifecycleOwner(), - getNavController(), - viewModel, - (comment, focusInput) -> { - viewModel.setReplyTo(comment); - binding.commentText.setText(String.format("@%s ", comment.getUser().getUsername())); - if (focusInput) Utils.showKeyboard(binding.commentText); - return null; - })); + commentsAdapter = new CommentsAdapter( + currentUserId, + true, + Helper.getCommentCallback( + context, + getViewLifecycleOwner(), + getNavController(), + viewModel, + (comment, focusInput) -> { + viewModel.setReplyTo(comment); + binding.commentText.setText(String.format("@%s ", comment.getUser().getUsername())); + if (focusInput) Utils.showKeyboard(binding.commentText); + return null; + } + ) + ); binding.comments.setAdapter(commentsAdapter); final Resource> listResource = viewModel.getReplyList().getValue(); commentsAdapter.submitList(listResource != null ? listResource.data : Collections.emptyList()); diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt index 3138f0e7..f55e07d7 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.kt @@ -11,7 +11,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer -import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import awais.instagrabber.R @@ -103,9 +103,9 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.pending_requests) { - val directions = DirectMessageInboxFragmentDirections.actionInboxToPendingInbox() try { - NavHostFragment.findNavController(this).navigate(directions) + val directions = DirectMessageInboxFragmentDirections.actionToPendingInbox() + findNavController().navigate(directions) } catch (e: Exception) { Log.e(TAG, "onOptionsItemSelected: ", e) } @@ -210,9 +210,9 @@ class DirectMessageInboxFragment : Fragment(), OnRefreshListener { if (navigating || threadId.isNullOrBlank() || threadTitle.isNullOrBlank()) return@DirectMessageInboxAdapter navigating = true if (isAdded) { - val directions = DirectMessageInboxFragmentDirections.actionInboxToThread(threadId, threadTitle) try { - NavHostFragment.findNavController(this).navigate(directions) + val directions = DirectMessageInboxFragmentDirections.actionToThread(threadId, threadTitle) + findNavController().navigate(directions) } catch (e: Exception) { Log.e(TAG, "init: ", e) } diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.kt b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.kt index ee39b885..83fe3274 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.kt +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.kt @@ -11,8 +11,8 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import awais.instagrabber.ProfileNavGraphDirections import awais.instagrabber.R import awais.instagrabber.activities.MainActivity import awais.instagrabber.adapters.DirectPendingUsersAdapter @@ -25,13 +25,11 @@ import awais.instagrabber.dialogs.ConfirmDialogFragment import awais.instagrabber.dialogs.ConfirmDialogFragment.ConfirmDialogFragmentCallback import awais.instagrabber.dialogs.MultiOptionDialogFragment import awais.instagrabber.dialogs.MultiOptionDialogFragment.MultiOptionDialogSingleCallback -import awais.instagrabber.fragments.UserSearchFragment -import awais.instagrabber.fragments.UserSearchFragmentDirections +import awais.instagrabber.fragments.UserSearchMode import awais.instagrabber.models.Resource import awais.instagrabber.repositories.responses.User import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse import awais.instagrabber.repositories.responses.directmessages.RankedRecipient -import awais.instagrabber.utils.TextUtils.isEmpty import awais.instagrabber.utils.Utils import awais.instagrabber.utils.extensions.TAG import awais.instagrabber.viewmodels.AppStateViewModel @@ -203,19 +201,22 @@ class DirectMessageSettingsFragment : Fragment(), ConfirmDialogFragmentCallback } binding.addMembers.setOnClickListener { if (!isAdded) return@setOnClickListener - val navController = NavHostFragment.findNavController(this) - val currentDestination = navController.currentDestination ?: return@setOnClickListener - if (currentDestination.id != R.id.directMessagesSettingsFragment) return@setOnClickListener - val users = viewModel.getUsers().value - val currentUserIds: LongArray = users?.asSequence()?.map { obj: User -> obj.pk }?.sorted()?.toList()?.toLongArray() ?: LongArray(0) - val actionGlobalUserSearch = UserSearchFragmentDirections - .actionGlobalUserSearch() - .setTitle(getString(R.string.add_members)) - .setActionLabel(getString(R.string.add)) - .setHideUserIds(currentUserIds) - .setSearchMode(UserSearchFragment.SearchMode.RAVEN) - .setMultiple(true) - navController.navigate(actionGlobalUserSearch) + try { + val navController = findNavController() + if (navController.currentDestination?.id != R.id.directMessagesSettingsFragment) return@setOnClickListener + val users = viewModel.getUsers().value ?: return@setOnClickListener + val currentUserIds = users.asSequence().map(User::pk).sorted().toList().toLongArray() + val actionGlobalUserSearch = DirectMessageSettingsFragmentDirections.actionToUserSearch().apply { + title = getString(R.string.add_members) + actionLabel = getString(R.string.add) + hideUserIds = currentUserIds + searchMode = UserSearchMode.RAVEN + multiple = true + } + navController.navigate(actionGlobalUserSearch) + } catch (e: Exception) { + Log.e(TAG, "setupSettings: ", e) + } } binding.muteMentionsLabel.setOnClickListener { binding.muteMentions.toggle() } binding.muteMentions.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean -> @@ -300,10 +301,13 @@ class DirectMessageSettingsFragment : Fragment(), ConfirmDialogFragmentCallback Utils.openURL(context, "https://facebook.com/" + user.interopMessagingUserFbid) return@DirectUsersAdapter } - if (isEmpty(user.username)) return@DirectUsersAdapter - val directions = ProfileNavGraphDirections - .actionGlobalProfileFragment("@" + user.username) - NavHostFragment.findNavController(this).navigate(directions) + if (user.username.isBlank()) return@DirectUsersAdapter + try { + val directions = DirectMessageSettingsFragmentDirections.actionToProfile().apply { this.username = user.username } + findNavController().navigate(directions) + } catch (e: Exception) { + Log.e(TAG, "setupMembers: ", e) + } }, { _: Int, user: User? -> val options = viewModel.createUserOptions(user) @@ -339,9 +343,12 @@ class DirectMessageSettingsFragment : Fragment(), ConfirmDialogFragmentCallback binding.pendingMembers.layoutManager = LinearLayoutManager(context) pendingUsersAdapter = DirectPendingUsersAdapter(object : PendingUserCallback { override fun onClick(position: Int, pendingUser: PendingUser) { - val directions = ProfileNavGraphDirections - .actionGlobalProfileFragment("@" + pendingUser.user.username) - NavHostFragment.findNavController(this@DirectMessageSettingsFragment).navigate(directions) + try { + val directions = DirectMessageSettingsFragmentDirections.actionToProfile().apply { this.username = pendingUser.user.username } + findNavController().navigate(directions) + } catch (e: Exception) { + Log.e(TAG, "onClick: ", e) + } } override fun onApprove(position: Int, pendingUser: PendingUser) { @@ -420,7 +427,7 @@ class DirectMessageSettingsFragment : Fragment(), ConfirmDialogFragmentCallback if (resource == null) return@observe when (resource.status) { Resource.Status.SUCCESS -> { - val directions = DirectMessageSettingsFragmentDirections.actionSettingsToInbox() + val directions = DirectMessageSettingsFragmentDirections.actionToInbox() NavHostFragment.findNavController(this).navigate(directions) } Resource.Status.ERROR -> { diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 1169a989..520dfae8 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -65,9 +65,7 @@ import java.util.List; import java.util.Set; import java.util.function.Function; -import awais.instagrabber.ProfileNavGraphDirections; import awais.instagrabber.R; -import awais.instagrabber.UserSearchNavGraphDirections; import awais.instagrabber.activities.CameraActivity; import awais.instagrabber.activities.MainActivity; import awais.instagrabber.adapters.DirectItemsAdapter; @@ -95,9 +93,7 @@ import awais.instagrabber.customviews.helpers.TranslateDeferringInsetsAnimationC import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding; import awais.instagrabber.dialogs.DirectItemReactionDialogFragment; import awais.instagrabber.dialogs.GifPickerBottomDialogFragment; -import awais.instagrabber.fragments.PostViewV2Fragment; -import awais.instagrabber.fragments.UserSearchFragment; -import awais.instagrabber.fragments.UserSearchFragmentDirections; +import awais.instagrabber.fragments.UserSearchMode; import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.Resource; import awais.instagrabber.models.enums.DirectItemType; @@ -107,6 +103,9 @@ import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectItemEmojiReaction; +import awais.instagrabber.repositories.responses.directmessages.DirectItemLink; +import awais.instagrabber.repositories.responses.directmessages.DirectItemReactions; +import awais.instagrabber.repositories.responses.directmessages.DirectItemReelShare; import awais.instagrabber.repositories.responses.directmessages.DirectItemStoryShare; import awais.instagrabber.repositories.responses.directmessages.DirectItemVisualMedia; import awais.instagrabber.repositories.responses.directmessages.DirectThread; @@ -136,7 +135,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact private InsetsAnimationLinearLayout root; private boolean shouldRefresh = true; private List itemOrHeaders; - private List users; private FragmentDirectMessagesThreadBinding binding; private Tooltip tooltip; private float initialSendX; @@ -163,7 +161,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact private LiveData> usersLiveData; private boolean autoMarkAsSeen = false; private MenuItem markAsSeenMenuItem; - private Media tempMedia; private DirectItem addReactionItem; private TranslateDeferringInsetsAnimationCallback inputHolderAnimationCallback; private TranslateDeferringInsetsAnimationCallback chatsAnimationCallback; @@ -189,8 +186,12 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact private final DirectItemCallback directItemCallback = new DirectItemCallback() { @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = DirectMessageThreadFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + try { + final NavDirections action = DirectMessageThreadFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override @@ -200,8 +201,12 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact @Override public void onLocationClick(final long locationId) { - final NavDirections action = DirectMessageThreadFragmentDirections.actionGlobalLocationFragment(locationId); - NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + try { + final NavDirections action = DirectMessageThreadFragmentDirections.actionToLocation(locationId); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onLocationClick: ", e); + } } @Override @@ -221,26 +226,23 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact @Override public void onMediaClick(final Media media, final int index) { if (media.isReelMedia()) { - final String pk = media.getPk(); try { + final String pk = media.getPk(); + if (pk == null) return; final long mediaId = Long.parseLong(pk); final User user = media.getUser(); if (user == null) return; final String username = user.getUsername(); - final NavDirections action = DirectMessageThreadFragmentDirections - .actionThreadToStory(StoryViewerOptions.forStory(mediaId, username)); + final NavDirections action = DirectMessageThreadFragmentDirections.actionToStory(StoryViewerOptions.forStory(mediaId, username)); NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); - } catch (NumberFormatException e) { + } catch (Exception e) { Log.e(TAG, "onMediaClick (story): ", e); } return; } - final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, index); try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections actionToPost = DirectMessageThreadFragmentDirections.actionToPost(media, index); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(actionToPost); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -248,16 +250,18 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact @Override public void onStoryClick(final DirectItemStoryShare storyShare) { - final String pk = storyShare.getReelId(); try { + final String pk = storyShare.getReelId(); + if (pk == null) return; final long mediaId = Long.parseLong(pk); - final User user = storyShare.getMedia().getUser(); + final Media media = storyShare.getMedia(); + if (media == null) return; + final User user = media.getUser(); if (user == null) return; final String username = user.getUsername(); - final NavDirections action = DirectMessageThreadFragmentDirections - .actionThreadToStory(StoryViewerOptions.forUser(mediaId, username)); + final NavDirections action = DirectMessageThreadFragmentDirections.actionToStory(StoryViewerOptions.forUser(mediaId, username)); NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); - } catch (NumberFormatException e) { + } catch (Exception e) { Log.e(TAG, "onStoryClick: ", e); } } @@ -266,9 +270,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact public void onReaction(final DirectItem item, final Emoji emoji) { if (item == null || emoji == null) return; final LiveData> resourceLiveData = viewModel.sendReaction(item, emoji); - if (resourceLiveData != null) { - resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); - } + resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); } @Override @@ -284,15 +286,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } if (itemId == R.id.forward) { itemToForward = item; - final UserSearchNavGraphDirections.ActionGlobalUserSearch actionGlobalUserSearch = UserSearchFragmentDirections - .actionGlobalUserSearch() + final NavDirections actionGlobalUserSearch = DirectMessageThreadFragmentDirections + .actionToUserSearch() .setTitle(getString(R.string.forward)) .setActionLabel(getString(R.string.send)) .setShowGroups(true) .setMultiple(true) - .setSearchMode(UserSearchFragment.SearchMode.RAVEN); - final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this); - navController.navigate(actionGlobalUserSearch); + .setSearchMode(UserSearchMode.RAVEN); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(actionGlobalUserSearch); } if (itemId == R.id.download) { downloadItem(item); @@ -418,10 +419,10 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact public boolean onOptionsItemSelected(@NonNull final MenuItem item) { final int itemId = item.getItemId(); if (itemId == R.id.info) { - final DirectMessageThreadFragmentDirections.ActionThreadToSettings directions = DirectMessageThreadFragmentDirections - .actionThreadToSettings(viewModel.getThreadId(), null); final Boolean pending = viewModel.isPending().getValue(); - directions.setPending(pending != null && pending); + final NavDirections directions = DirectMessageThreadFragmentDirections + .actionToSettings(viewModel.getThreadId(), null) + .setPending(pending != null && pending); NavHostFragment.findNavController(this).navigate(directions); return true; } @@ -485,7 +486,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } final Uri uri = data.getData(); final String mimeType = Utils.getMimeType(uri, context.getContentResolver()); - if (mimeType.startsWith("image")) { + if (mimeType != null && mimeType.startsWith("image")) { navigateToImageEditFragment(uri); return; } @@ -894,19 +895,26 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact binding.gallery.setVisibility(View.GONE); } - private String getDirectItemPreviewText(final DirectItem item) { - switch (item.getItemType()) { + private String getDirectItemPreviewText(@NonNull final DirectItem item) { + final DirectItemType itemType = item.getItemType(); + if (itemType == null) return ""; + switch (itemType) { case TEXT: return item.getText(); case LINK: - return item.getLink().getText(); + final DirectItemLink link = item.getLink(); + if (link == null) return ""; + return link.getText(); case MEDIA: { final Media media = item.getMedia(); + if (media == null) return ""; return getMediaPreviewTextString(media); } case RAVEN_MEDIA: { final DirectItemVisualMedia visualMedia = item.getVisualMedia(); + if (visualMedia == null) return ""; final Media media = visualMedia.getMedia(); + if (media == null) return ""; return getMediaPreviewTextString(media); } case VOICE_MEDIA: @@ -914,14 +922,17 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact case MEDIA_SHARE: return getString(R.string.post); case REEL_SHARE: - return item.getReelShare().getText(); + final DirectItemReelShare reelShare = item.getReelShare(); + if (reelShare == null) return ""; + return reelShare.getText(); } return ""; } @NonNull - private String getMediaPreviewTextString(final Media media) { + private String getMediaPreviewTextString(@NonNull final Media media) { final MediaItemType mediaType = media.getType(); + if (mediaType == null) return ""; switch (mediaType) { case MEDIA_TYPE_IMAGE: return getString(R.string.photo); @@ -932,8 +943,11 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } } - private String getDirectItemPreviewImageUrl(final DirectItem item) { - switch (item.getItemType()) { + @Nullable + private String getDirectItemPreviewImageUrl(@NonNull final DirectItem item) { + final DirectItemType itemType = item.getItemType(); + if (itemType == null) return null; + switch (itemType) { case TEXT: case LINK: case VOICE_MEDIA: @@ -945,6 +959,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } case RAVEN_MEDIA: { final DirectItemVisualMedia visualMedia = item.getVisualMedia(); + if (visualMedia == null) return null; final Media media = visualMedia.getMedia(); return ResponseBodyUtils.getThumbUrl(media); } @@ -1009,7 +1024,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact itemsAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); binding.chats.setAdapter(itemsAdapter); registerDataObserver(); - users = thread.getUsers(); final List items = viewModel.getItems().getValue(); if (items != null && itemsAdapter.getItems() != items) { submitItemsToAdapter(items); @@ -1234,9 +1248,12 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } private void navigateToImageEditFragment(final Uri uri) { - final NavDirections navDirections = DirectMessageThreadFragmentDirections.actionThreadToImageEdit(uri); - final NavController navController = NavHostFragment.findNavController(this); - navController.navigate(navDirections); + try { + final NavDirections navDirections = DirectMessageThreadFragmentDirections.actionToImageEdit(uri); + NavHostFragment.findNavController(this).navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "navigateToImageEditFragment: ", e); + } } private void handleSentMessage(final LiveData> resourceLiveData) { @@ -1403,11 +1420,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact final Context context = getContext(); if (context == null) return; final DirectItemType itemType = item.getItemType(); + if (itemType == null) return; //noinspection SwitchStatementWithTooFewBranches switch (itemType) { case VOICE_MEDIA: downloadItem(context, item.getVoiceMedia() == null ? null : item.getVoiceMedia().getMedia()); break; + default: + break; } } @@ -1421,15 +1441,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show(); } - @Nullable - private User getUser(final long userId) { - for (final User user : users) { - if (userId != user.getPk()) continue; - return user; - } - return null; - } - // Sets the translationY of views to height with animation private void animatePan(final int height, @Nullable final Function onAnimationStart, @@ -1476,17 +1487,22 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact final LiveData> leftUsers = viewModel.getLeftUsers(); final ArrayList allUsers = new ArrayList<>(); allUsers.add(viewModel.getCurrentUser()); - if (users != null && users.getValue() != null) { + if (users.getValue() != null) { allUsers.addAll(users.getValue()); } - if (leftUsers != null && leftUsers.getValue() != null) { + if (leftUsers.getValue() != null) { allUsers.addAll(leftUsers.getValue()); } - reactionDialogFragment = DirectItemReactionDialogFragment - .newInstance(viewModel.getViewerId(), - allUsers, - item.getItemId(), - item.getReactions()); + final String itemId = item.getItemId(); + if (itemId == null) return; + final DirectItemReactions reactions = item.getReactions(); + if (reactions == null) return; + reactionDialogFragment = DirectItemReactionDialogFragment.newInstance( + viewModel.getViewerId(), + allUsers, + itemId, + reactions + ); reactionDialogFragment.show(getChildFragmentManager(), "reactions_dialog"); } @@ -1498,9 +1514,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact if (itemId == null || reaction == null) return; if (reaction.getSenderId() == viewModel.getViewerId()) { final LiveData> resourceLiveData = viewModel.sendDeleteReaction(itemId); - if (resourceLiveData != null) { - resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); - } + resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); return; } // navigate to user @@ -1510,17 +1524,18 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } private void navigateToUser(@NonNull final String username) { - final ProfileNavGraphDirections.ActionGlobalProfileFragment direction = ProfileNavGraphDirections - .actionGlobalProfileFragment("@" + username); - NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(direction); + try { + final NavDirections direction = DirectMessageThreadFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(direction); + } catch (Exception e) { + Log.e(TAG, "navigateToUser: ", e); + } } @Override public void onClick(final View view, final Emoji emoji) { if (addReactionItem == null || emoji == null) return; final LiveData> resourceLiveData = viewModel.sendReaction(addReactionItem, emoji); - if (resourceLiveData != null) { - resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); - } + resourceLiveData.observe(getViewLifecycleOwner(), directItemResource -> handleSentMessage(resourceLiveData)); } } diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectPendingInboxFragment.kt b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectPendingInboxFragment.kt index efb4d73f..f321a556 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectPendingInboxFragment.kt +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectPendingInboxFragment.kt @@ -134,7 +134,7 @@ class DirectPendingInboxFragment : Fragment(), OnRefreshListener { val threadTitle = thread.threadTitle ?: return@DirectMessageInboxAdapter navigating = true if (isAdded) { - val directions = DirectPendingInboxFragmentDirections.actionPendingInboxToThread(threadId, threadTitle) + val directions = DirectPendingInboxFragmentDirections.actionToThread(threadId, threadTitle) directions.pending = true NavHostFragment.findNavController(this).navigate(directions) } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java index 80120a44..1f832c6b 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java @@ -13,7 +13,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavController; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.FragmentNavigator; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -26,7 +26,6 @@ import awais.instagrabber.activities.MainActivity; import awais.instagrabber.adapters.DiscoverTopicsAdapter; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.databinding.FragmentDiscoverBinding; -import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.discover.TopicCluster; import awais.instagrabber.repositories.responses.discover.TopicalExploreFeedResponse; @@ -98,11 +97,14 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR binding.topicsRecyclerView.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(2))); final DiscoverTopicsAdapter.OnTopicClickListener otcl = new DiscoverTopicsAdapter.OnTopicClickListener() { public void onTopicClick(final TopicCluster topicCluster, final View cover, final int titleColor, final int backgroundColor) { - final FragmentNavigator.Extras.Builder builder = new FragmentNavigator.Extras.Builder() - .addSharedElement(cover, "cover-" + topicCluster.getId()); - final DiscoverFragmentDirections.ActionDiscoverFragmentToTopicPostsFragment action = DiscoverFragmentDirections - .actionDiscoverFragmentToTopicPostsFragment(topicCluster, titleColor, backgroundColor); - NavHostFragment.findNavController(DiscoverFragment.this).navigate(action, builder.build()); + try { + final FragmentNavigator.Extras.Builder builder = new FragmentNavigator.Extras.Builder() + .addSharedElement(cover, "cover-" + topicCluster.getId()); + final NavDirections action = DiscoverFragmentDirections.actionToTopicPosts(topicCluster, titleColor, backgroundColor); + NavHostFragment.findNavController(DiscoverFragment.this).navigate(action, builder.build()); + } catch (Exception e) { + Log.e(TAG, "onTopicClick: ", e); + } } public void onTopicLongClick(final Media coverMedia) { @@ -123,11 +125,9 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR } catch (Throwable ignored) {} return; } - final NavController navController = NavHostFragment.findNavController(DiscoverFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media); try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = DiscoverFragmentDirections.actionToPost(media, 0); + NavHostFragment.findNavController(DiscoverFragment.this).navigate(action); alertDialog.dismiss(); } catch (Exception e) { Log.e(TAG, "onTopicLongClick: ", e); @@ -148,11 +148,13 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR public void onSuccess(final TopicalExploreFeedResponse result) { if (result == null) return; final List clusters = result.getClusters(); + if (clusters == null || result.getItems() == null) return; binding.swipeRefreshLayout.setRefreshing(false); if (clusters.size() == 1 && result.getItems().size() > 0) { final TopicCluster cluster = clusters.get(0); - if (cluster.getCoverMedia() == null) + if (cluster.getCoverMedia() == null) { cluster.setCoverMedia(result.getItems().get(0).getMedia()); + } topicClusterViewModel.getList().postValue(Collections.singletonList(cluster)); return; } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index 593ea96f..c2d3dfc9 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -40,10 +40,11 @@ import awais.instagrabber.asyncs.FeedPostFetchService; import awais.instagrabber.customviews.PrimaryActionModeCallback; import awais.instagrabber.databinding.FragmentFeedBinding; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; -import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.repositories.requests.StoryViewerOptions; +import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; +import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.stories.Story; import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.Constants; @@ -62,7 +63,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre private FragmentFeedBinding binding; private StoriesRepository storiesRepository; private boolean shouldRefresh = true; - private final boolean isRotate = false; private FeedStoriesViewModel feedStoriesViewModel; private boolean storiesFetching; private ActionMode actionMode; @@ -77,15 +77,20 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre public void onFeedStoryClick(Story model, int position) { final NavController navController = NavHostFragment.findNavController(FeedFragment.this); if (isSafeToNavigate(navController)) { - final NavDirections action = FeedFragmentDirections - .actionFeedFragmentToStoryViewerFragment(StoryViewerOptions.forFeedStoryPosition(position)); - navController.navigate(action); + try { + final NavDirections action = FeedFragmentDirections.actionToStory(StoryViewerOptions.forFeedStoryPosition(position)); + navController.navigate(action); + } catch (Exception e) { + Log.e(TAG, "onFeedStoryClick: ", e); + } } } @Override public void onFeedStoryLongClick(Story model, int position) { - navigateToProfile("@" + model.getUser().getUsername()); + final User user = model.getUser(); + if (user == null) return; + navigateToProfile("@" + user.getUsername()); } } ); @@ -93,21 +98,23 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final Media feedModel, final View profilePicView, final View mainPostImage) { - openPostDialog(feedModel, profilePicView, mainPostImage, -1); + openPostDialog(feedModel, -1); } @Override public void onSliderClick(final Media feedModel, final int position) { - openPostDialog(feedModel, null, null, position); + openPostDialog(feedModel, position); } @Override public void onCommentsClick(final Media feedModel) { try { - final NavDirections commentsAction = FeedFragmentDirections.actionGlobalCommentsViewerFragment( + final User user = feedModel.getUser(); + if (user == null) return; + final NavDirections commentsAction = FeedFragmentDirections.actionToComments( feedModel.getCode(), feedModel.getPk(), - feedModel.getUser().getPk() + user.getPk() ); NavHostFragment.findNavController(FeedFragment.this).navigate(commentsAction); } catch (Exception e) { @@ -124,14 +131,24 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre @Override public void onHashtagClick(final String hashtag) { - final NavDirections action = FeedFragmentDirections.actionGlobalHashTagFragment(hashtag); - NavHostFragment.findNavController(FeedFragment.this).navigate(action); + try { + final NavDirections action = FeedFragmentDirections.actionToHashtag(hashtag); + NavHostFragment.findNavController(FeedFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onHashtagClick: ", e); + } } @Override public void onLocationClick(final Media feedModel) { - final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(feedModel.getLocation().getPk()); - NavHostFragment.findNavController(FeedFragment.this).navigate(action); + final Location location = feedModel.getLocation(); + if (location == null) return; + try { + final NavDirections action = FeedFragmentDirections.actionToLocation(location.getPk()); + NavHostFragment.findNavController(FeedFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onLocationClick: ", e); + } } @Override @@ -161,22 +178,10 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre Utils.openEmailAddress(getContext(), emailId); } - private void openPostDialog(final Media feedModel, - final View profilePicView, - final View mainPostImage, - final int position) { - // ViewCompat.setTransitionName(profilePicView, "profile_pic"); - // ViewCompat.setTransitionName(mainPostImage, "post_image"); - // final FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder() - // .addSharedElement(profilePicView, "profile_pic") - // .addSharedElement(mainPostImage, "post_image") - // .build(); - final NavController navController = NavHostFragment.findNavController(FeedFragment.this); - final Bundle bundle = new Bundle(); - bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); - bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position); + private void openPostDialog(final Media feedModel, final int position) { try { - navController.navigate(R.id.action_global_post_view, bundle); + final NavDirections action = FeedFragmentDirections.actionToPost(feedModel, position); + NavHostFragment.findNavController(FeedFragment.this).navigate(action); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -246,10 +251,12 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre }; private void navigateToProfile(final String username) { - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); - bundle.putString("username", username); - navController.navigate(R.id.action_global_profileFragment, bundle); + try { + final NavDirections action = FeedFragmentDirections.actionToProfile().setUsername(username); + NavHostFragment.findNavController(this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "navigateToProfile: ", e); + } } @Override @@ -310,8 +317,12 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre @Override public boolean onOptionsItemSelected(@NonNull final MenuItem item) { if (item.getItemId() == R.id.storyList) { - final NavDirections action = FeedFragmentDirections.actionGlobalStoryListViewerFragment("feed"); - NavHostFragment.findNavController(FeedFragment.this).navigate(action); + try { + final NavDirections action = FeedFragmentDirections.actionToStoryList("feed"); + NavHostFragment.findNavController(FeedFragment.this).navigate(action); + } catch (Exception e) { + Log.e(TAG, "onOptionsItemSelected: ", e); + } } else if (item.getItemId() == R.id.layout) { showPostsLayoutPreferences(); return true; @@ -331,14 +342,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre fetchStories(); } - @Override - public void onDestroyView() { - super.onDestroyView(); - if (storiesRecyclerView != null) { - fragmentActivity.removeCollapsingView(storiesRecyclerView); - } - } - private void setupFeed() { binding.feedRecyclerView.setViewModelStoreOwner(this) .setLifeCycleOwner(this) @@ -412,7 +415,8 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre preferences -> { layoutPreferences = preferences; new Handler().postDelayed(() -> binding.feedRecyclerView.setLayoutPreferences(preferences), 200); - }); + } + ); fragment.show(getChildFragmentManager(), "posts_layout_preferences"); } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt index 9c2ef9ae..d5708533 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt +++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt @@ -20,6 +20,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener @@ -40,10 +41,7 @@ import awais.instagrabber.dialogs.MultiOptionDialogFragment.MultiOptionDialogSin import awais.instagrabber.dialogs.MultiOptionDialogFragment.Option import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment import awais.instagrabber.dialogs.ProfilePicDialogFragment -import awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG -import awais.instagrabber.fragments.PostViewV2Fragment -import awais.instagrabber.fragments.UserSearchFragment -import awais.instagrabber.fragments.UserSearchFragmentDirections +import awais.instagrabber.fragments.UserSearchMode import awais.instagrabber.managers.DirectMessagesManager import awais.instagrabber.models.Resource import awais.instagrabber.models.enums.PostItemType @@ -105,8 +103,12 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } override fun onLocationClick(media: Media?) { - val action = FeedFragmentDirections.actionGlobalLocationFragment(media?.location?.pk ?: return) - NavHostFragment.findNavController(this@ProfileFragment).navigate(action) + try { + val action = ProfileFragmentDirections.actionToLocation(media?.location?.pk ?: return) + findNavController().navigate(action) + } catch (e: Exception) { + Log.e(TAG, "onLocationClick: ", e) + } } override fun onMentionClick(mention: String?) { @@ -114,17 +116,25 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } override fun onHashtagClick(hashtag: String?) { - val action = FeedFragmentDirections.actionGlobalHashTagFragment(hashtag ?: return) - NavHostFragment.findNavController(this@ProfileFragment).navigate(action) + try { + val action = ProfileFragmentDirections.actionToHashtag(hashtag ?: return) + findNavController().navigate(action) + } catch (e: Exception) { + Log.e(TAG, "onHashtagClick: ", e) + } } override fun onCommentsClick(media: Media?) { - val commentsAction = ProfileFragmentDirections.actionGlobalCommentsViewerFragment( - media?.code ?: return, - media.pk ?: return, - media.user?.pk ?: return - ) - NavHostFragment.findNavController(this@ProfileFragment).navigate(commentsAction) + try { + val commentsAction = ProfileFragmentDirections.actionToComments( + media?.code ?: return, + media.pk ?: return, + media.user?.pk ?: return + ) + findNavController().navigate(commentsAction) + } catch (e: Exception) { + Log.e(TAG, "onCommentsClick: ", e) + } } override fun onDownloadClick(media: Media?, childPosition: Int, popupLocation: View) { @@ -216,24 +226,24 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } private val onFollowersClickListener = View.OnClickListener { try { - val action = ProfileFragmentDirections.actionProfileFragmentToFollowViewerFragment( + val action = ProfileFragmentDirections.actionToFollowViewer( viewModel.profile.value?.data?.pk ?: return@OnClickListener, true, viewModel.profile.value?.data?.username ?: return@OnClickListener ) - NavHostFragment.findNavController(this).navigate(action) + findNavController().navigate(action) } catch (e: Exception) { Log.e(TAG, "onFollowersClickListener: ", e) } } private val onFollowingClickListener = View.OnClickListener { try { - val action = ProfileFragmentDirections.actionProfileFragmentToFollowViewerFragment( + val action = ProfileFragmentDirections.actionToFollowViewer( viewModel.profile.value?.data?.pk ?: return@OnClickListener, false, viewModel.profile.value?.data?.username ?: return@OnClickListener ) - NavHostFragment.findNavController(this).navigate(action) + findNavController().navigate(action) } catch (e: Exception) { Log.e(TAG, "onFollowersClickListener: ", e) } @@ -243,9 +253,8 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } private val onHashtagClickListener = OnHashtagClickListener { try { - val bundle = Bundle() - bundle.putString(ARG_HASHTAG, it.originalText.trimAll()) - NavHostFragment.findNavController(this).navigate(R.id.action_global_hashTagFragment, bundle) + val actionToHashtag = ProfileFragmentDirections.actionToHashtag(it.originalText.trimAll()) + findNavController().navigate(actionToHashtag) } catch (e: Exception) { Log.e(TAG, "onHashtagClickListener: ", e) } @@ -280,13 +289,9 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } private fun openPostDialog(media: Media, position: Int) { - val bundle = Bundle().apply { - putSerializable(PostViewV2Fragment.ARG_MEDIA, media) - putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position) - } try { - val navController = NavHostFragment.findNavController(this) - navController.navigate(R.id.action_global_post_view, bundle) + val actionToPost = ProfileFragmentDirections.actionToPost(media, position) + findNavController().navigate(actionToPost) } catch (e: Exception) { Log.e(TAG, "openPostDialog: ", e) } @@ -387,16 +392,15 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } private fun shareProfileViaDm() { - val actionGlobalUserSearch = UserSearchFragmentDirections.actionGlobalUserSearch().apply { - setTitle(getString(R.string.share)) - setActionLabel(getString(R.string.send)) - showGroups = true - multiple = true - setSearchMode(UserSearchFragment.SearchMode.RAVEN) - } try { - val navController = NavHostFragment.findNavController(this@ProfileFragment) - navController.navigate(actionGlobalUserSearch) + val actionToUserSearch = ProfileFragmentDirections.actionToUserSearch().apply { + title = getString(R.string.share) + actionLabel = getString(R.string.send) + showGroups = true + multiple = true + searchMode = UserSearchMode.RAVEN + } + findNavController().navigate(actionToUserSearch) } catch (e: Exception) { Log.e(TAG, "shareProfileViaDm: ", e) } @@ -413,12 +417,12 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall private fun navigateToChaining() { viewModel.currentUser.value?.data ?: return val profile = viewModel.profile.value?.data ?: return - val bundle = Bundle().apply { - putString("type", "chaining") - putLong("targetId", profile.pk) - } try { - NavHostFragment.findNavController(this).navigate(R.id.action_global_notificationsViewerFragment, bundle) + val actionToNotifications = ProfileFragmentDirections.actionToNotifications().apply { + type = "chaining" + targetId = profile.pk + } + findNavController().navigate(actionToNotifications) } catch (e: Exception) { Log.e(TAG, "navigateToChaining: ", e) } @@ -426,7 +430,7 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall private fun init() { binding.swipeRefreshLayout.setOnRefreshListener(this) - disableDm = !Utils.isNavRootInCurrentTabs("direct_messages_nav_graph") + disableDm = !isNavRootInCurrentTabs("direct_messages_nav_graph") setupHighlights() setupObservers() } @@ -717,14 +721,14 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } binding.header.btnLiked.setOnClickListener { try { - val action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment( + val action = ProfileFragmentDirections.actionToSaved( viewModel.profile.value?.data?.username ?: return@setOnClickListener, viewModel.profile.value?.data?.pk ?: return@setOnClickListener, PostItemType.LIKED ) - NavHostFragment.findNavController(this).navigate(action) + findNavController().navigate(action) } catch (e: Exception) { - Log.e(TAG, "setupTaggedButton: ", e) + Log.e(TAG, "setupLikedButton: ", e) } } } @@ -738,12 +742,12 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } binding.header.btnTagged.setOnClickListener { try { - val action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment( + val action = ProfileFragmentDirections.actionToSaved( viewModel.profile.value?.data?.username ?: return@setOnClickListener, viewModel.profile.value?.data?.pk ?: return@setOnClickListener, PostItemType.TAGGED ) - NavHostFragment.findNavController(this).navigate(action) + findNavController().navigate(action) } catch (e: Exception) { Log.e(TAG, "setupTaggedButton: ", e) } @@ -759,8 +763,8 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall } binding.header.btnSaved.setOnClickListener { try { - val action = ProfileFragmentDirections.actionGlobalSavedCollectionsFragment(false) - NavHostFragment.findNavController(this).navigate(action) + val action = ProfileFragmentDirections.actionToSavedCollections().apply { isSaving = false } + findNavController().navigate(action) } catch (e: Exception) { Log.e(TAG, "setupSavedButton: ", e) } @@ -851,9 +855,8 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall private fun setupHighlights() { val context = context ?: return highlightsAdapter = HighlightsAdapter { model, position -> - val options = StoryViewerOptions.forHighlight(model.title) - options.currentFeedStoryIndex = position - val action = ProfileFragmentDirections.actionProfileFragmentToStoryViewerFragment(options) + val options = StoryViewerOptions.forHighlight(model.title).apply { currentFeedStoryIndex = position } + val action = ProfileFragmentDirections.actionToStory(options) NavHostFragment.findNavController(this).navigate(action) } binding.header.highlightsList.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) @@ -881,10 +884,9 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall private fun navigateToProfile(username: String?) { try { - val bundle = Bundle() - bundle.putString("username", username ?: return) - val navController = NavHostFragment.findNavController(this) - navController.navigate(R.id.action_global_profileFragment, bundle) + val username1 = username ?: return + val actionToProfile = ProfileFragmentDirections.actionToProfile().apply { this.username = username1 } + findNavController().navigate(actionToProfile) } catch (e: Exception) { Log.e(TAG, "navigateToProfile: ", e) } @@ -937,13 +939,13 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall "profile_pic" -> showProfilePicDialog() "show_stories" -> { try { - val action = ProfileFragmentDirections.actionProfileFragmentToStoryViewerFragment( + val action = ProfileFragmentDirections.actionToStory( StoryViewerOptions.forUser( viewModel.profile.value?.data?.pk ?: return, viewModel.profile.value?.data?.fullName ?: return, ) ) - NavHostFragment.findNavController(this).navigate(action) + findNavController().navigate(action) } catch (e: Exception) { Log.e(TAG, "omPpOptionSelect: ", e) } diff --git a/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java b/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java index 371793cc..40ad363d 100644 --- a/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java @@ -19,7 +19,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavController; +import androidx.navigation.NavDirections; import androidx.navigation.fragment.NavHostFragment; import com.google.android.material.snackbar.Snackbar; @@ -125,7 +125,9 @@ public class SearchFragment extends Fragment implements SearchCategoryFragment.O mainActivity.showSearchView(); } if (settingsHelper.getBoolean(PREF_SEARCH_FOCUS_KEYBOARD)) { - searchInput.requestFocus(); + if (searchInput != null) { + searchInput.requestFocus(); + } final InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) imm.showSoftInput(searchInput, InputMethodManager.SHOW_IMPLICIT); } @@ -205,24 +207,23 @@ public class SearchFragment extends Fragment implements SearchCategoryFragment.O if (!searchItem.isFavorite()) { viewModel.saveToRecentSearches(searchItem); // insert or update recent } - final NavController navController = NavHostFragment.findNavController(this); - final Bundle bundle = new Bundle(); + final NavDirections action; switch (type) { case USER: - bundle.putString("username", searchItem.getUser().getUsername()); - navController.navigate(R.id.action_global_profileFragment, bundle); + action = SearchFragmentDirections.actionToProfile().setUsername(searchItem.getUser().getUsername()); + NavHostFragment.findNavController(this).navigate(action); break; case HASHTAG: - bundle.putString("hashtag", searchItem.getHashtag().getName()); - navController.navigate(R.id.action_global_hashTagFragment, bundle); + action = SearchFragmentDirections.actionToHashtag(searchItem.getHashtag().getName()); + NavHostFragment.findNavController(this).navigate(action); break; case LOCATION: - bundle.putLong("locationId", searchItem.getPlace().getLocation().getPk()); - navController.navigate(R.id.action_global_locationFragment, bundle); + action = SearchFragmentDirections.actionToLocation(searchItem.getPlace().getLocation().getPk()); break; default: - break; + return; } + NavHostFragment.findNavController(this).navigate(action); } catch (Exception e) { Log.e(TAG, "onSearchItemClick: ", e); } diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java index e8403162..c8552bd1 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java @@ -1,7 +1,6 @@ package awais.instagrabber.fragments.settings; import android.content.Context; -import android.util.Pair; import androidx.annotation.NonNull; import androidx.preference.ListPreference; @@ -17,8 +16,9 @@ import awais.instagrabber.dialogs.TabOrderPreferenceDialogFragment; import awais.instagrabber.models.Tab; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.NavigationHelperKt; import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.utils.Utils; +import kotlin.Pair; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -37,27 +37,28 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen screen.addPreference(getUpdateCheckPreference(context)); screen.addPreference(getFlagSecurePreference(context)); screen.addPreference(getSearchFocusPreference(context)); - final List preferences = FlavorSettings.getInstance() - .getPreferences(context, - getChildFragmentManager(), - SettingCategory.GENERAL); - if (preferences != null) { - for (final Preference preference : preferences) { - screen.addPreference(preference); - } + final List preferences = FlavorSettings + .getInstance() + .getPreferences( + context, + getChildFragmentManager(), + SettingCategory.GENERAL + ); + for (final Preference preference : preferences) { + screen.addPreference(preference); } } private Preference getDefaultTabPreference(@NonNull final Context context) { final ListPreference preference = new ListPreference(context); preference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance()); - final Pair, List> listPair = Utils.getNavTabList(context); - final List tabs = listPair.first; + final Pair, List> listPair = NavigationHelperKt.getLoggedInNavTabs(context); + final List tabs = listPair.getFirst(); final String[] titles = tabs.stream() .map(Tab::getTitle) .toArray(String[]::new); final String[] navGraphFileNames = tabs.stream() - .map(Tab::getGraphName) + .map(tab -> NavigationHelperKt.geNavGraphNameForNavRootId(tab.getNavigationRootId())) .toArray(String[]::new); preference.setKey(Constants.DEFAULT_TAB); preference.setTitle(R.string.pref_start_screen); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java index 64546efc..51186d50 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java @@ -35,6 +35,7 @@ import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.utils.FlavorTown; +import awais.instagrabber.utils.NavigationHelperKt; import awais.instagrabber.utils.ProcessPhoenix; import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; @@ -174,14 +175,18 @@ public class MorePreferencesFragment extends BasePreferencesFragment { boolean showActivity = true; boolean showExplore = false; if (activity != null) { - showActivity = !Utils.isNavRootInCurrentTabs("notification_viewer_nav_graph"); - showExplore = !Utils.isNavRootInCurrentTabs("discover_nav_graph"); + showActivity = !NavigationHelperKt.isNavRootInCurrentTabs("notification_viewer_nav_graph"); + showExplore = !NavigationHelperKt.isNavRootInCurrentTabs("discover_nav_graph"); } if (showActivity) { screen.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("notif"); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToNotifications().setType("notif"); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); @@ -197,15 +202,23 @@ public class MorePreferencesFragment extends BasePreferencesFragment { screen.addPreference(getPreference(R.string.action_ayml, R.drawable.ic_suggested_users, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("ayml"); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToNotifications().setType("ayml"); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); screen.addPreference(getPreference(R.string.action_archive, R.drawable.ic_archive, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalStoryListViewerFragment("archive"); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToStoryList("archive"); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); @@ -214,13 +227,17 @@ public class MorePreferencesFragment extends BasePreferencesFragment { // Check if favorites has been added as a tab. And if so, do not add in this list boolean showFavorites = true; if (activity != null) { - showFavorites = !Utils.isNavRootInCurrentTabs("favorites_nav_graph"); + showFavorites = !NavigationHelperKt.isNavRootInCurrentTabs("favorites_nav_graph"); } if (showFavorites) { screen.addPreference(getPreference(R.string.title_favorites, R.drawable.ic_star_24, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToFavoritesFragment(); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToFavorites(); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); @@ -229,36 +246,50 @@ public class MorePreferencesFragment extends BasePreferencesFragment { screen.addPreference(getDivider(context)); screen.addPreference(getPreference(R.string.action_settings, R.drawable.ic_outline_settings_24, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToSettingsPreferencesFragment(); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToSettings(); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); screen.addPreference(getPreference(R.string.backup_and_restore, R.drawable.ic_settings_backup_restore_24, preference -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToBackupPreferencesFragment(); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToBackup(); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); screen.addPreference(getPreference(R.string.action_about, R.drawable.ic_outline_info_24, preference1 -> { if (isSafeToNavigate(navController)) { - final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToAboutFragment(); - navController.navigate(navDirections); + try { + final NavDirections navDirections = MorePreferencesFragmentDirections.actionToAbout(); + navController.navigate(navDirections); + } catch (Exception e) { + Log.e(TAG, "setupPreferenceScreen: ", e); + } } return true; })); screen.addPreference(getDivider(context)); - screen.addPreference(getPreference(R.string.version, - BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")", - -1, - preference -> { - if (BuildConfig.isPre) return true; - if (activity == null) return false; - FlavorTown.updateCheck(activity, true); - return true; - })); + screen.addPreference(getPreference( + R.string.version, + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")", + -1, + preference -> { + if (BuildConfig.isPre) return true; + if (activity == null) return false; + FlavorTown.updateCheck(activity, true); + return true; + }) + ); screen.addPreference(getDivider(context)); final Preference reminderPreference = getPreference(R.string.reminder, R.string.reminder_summary, R.drawable.ic_warning, null); @@ -285,32 +316,33 @@ public class MorePreferencesFragment extends BasePreferencesFragment { // adds cookies to database for quick access final long uid = CookieUtils.getUserIdFromCookie(cookie); final UserRepository userRepository = UserRepository.Companion.getInstance(); - userRepository.getUserInfo(uid, CoroutineUtilsKt.getContinuation((user, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { - if (throwable != null) { - Log.e(TAG, "Error fetching user info", throwable); - return; - } - if (user != null) { - accountRepository.insertOrUpdateAccount( - uid, - user.getUsername(), - cookie, - user.getFullName(), - user.getProfilePicUrl(), - CoroutineUtilsKt.getContinuation((account, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { - if (throwable1 != null) { - Log.e(TAG, "onActivityResult: ", throwable1); - return; - } - AppExecutors.INSTANCE.getMainThread().execute(() -> { - final Context context = getContext(); - if (context == null) return; - ProcessPhoenix.triggerRebirth(context); - }, 200); - }), Dispatchers.getIO()) - ); - } - }), Dispatchers.getIO())); + userRepository + .getUserInfo(uid, CoroutineUtilsKt.getContinuation((user, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "Error fetching user info", throwable); + return; + } + if (user != null) { + accountRepository.insertOrUpdateAccount( + uid, + user.getUsername(), + cookie, + user.getFullName(), + user.getProfilePicUrl(), + CoroutineUtilsKt.getContinuation((account, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onActivityResult: ", throwable1); + return; + } + AppExecutors.INSTANCE.getMainThread().execute(() -> { + final Context context = getContext(); + if (context == null) return; + ProcessPhoenix.triggerRebirth(context); + }, 200); + }), Dispatchers.getIO()) + ); + } + }), Dispatchers.getIO())); } } diff --git a/app/src/main/java/awais/instagrabber/models/Tab.kt b/app/src/main/java/awais/instagrabber/models/Tab.kt index 5a730d1e..4edfee0d 100644 --- a/app/src/main/java/awais/instagrabber/models/Tab.kt +++ b/app/src/main/java/awais/instagrabber/models/Tab.kt @@ -2,24 +2,12 @@ package awais.instagrabber.models import androidx.annotation.DrawableRes import androidx.annotation.IdRes -import androidx.annotation.NavigationRes data class Tab( @param:DrawableRes val iconResId: Int, val title: String, val isRemovable: Boolean, - /** - * This is name part of the navigation resource - * eg: @navigation/ **graphName** - */ - val graphName: String, - - /** - * 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. * diff --git a/app/src/main/java/awais/instagrabber/utils/NavigationExtensions.java b/app/src/main/java/awais/instagrabber/utils/NavigationExtensions.java index bc0f3cb4..02c8b0a7 100644 --- a/app/src/main/java/awais/instagrabber/utils/NavigationExtensions.java +++ b/app/src/main/java/awais/instagrabber/utils/NavigationExtensions.java @@ -1,247 +1,247 @@ -package awais.instagrabber.utils; - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.util.Log; -import android.util.SparseArray; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.navigation.NavController; -import androidx.navigation.NavDestination; -import androidx.navigation.NavGraph; -import androidx.navigation.fragment.NavHostFragment; - -import com.google.android.material.bottomnavigation.BottomNavigationView; - -import java.util.List; - -import awais.instagrabber.R; -import awais.instagrabber.customviews.NavHostFragmentWithDefaultAnimations; -import awais.instagrabber.fragments.main.FeedFragment; - -/** - * This is a Java rewrite of NavigationExtensions - * from architecture-components-samples. Some modifications have been done, check git history. - */ -public class NavigationExtensions { - private static final String TAG = NavigationExtensions.class.getSimpleName(); - private static String selectedItemTag; - private static boolean isOnFirstFragment; - - @NonNull - public static LiveData setupWithNavController(@NonNull final BottomNavigationView bottomNavigationView, - @NonNull List navGraphIds, - @NonNull final FragmentManager fragmentManager, - final int containerId, - @NonNull Intent intent, - final int firstFragmentGraphIndex) { - final SparseArray graphIdToTagMap = new SparseArray<>(); - final MutableLiveData selectedNavController = new MutableLiveData<>(); - int firstFragmentGraphId = 0; - for (int i = 0; i < navGraphIds.size(); i++) { - final int navGraphId = navGraphIds.get(i); - final String fragmentTag = getFragmentTag(navGraphId); - final NavHostFragment navHostFragment = obtainNavHostFragment(fragmentManager, fragmentTag, navGraphId, containerId); - final NavController navController = navHostFragment.getNavController(); - final int graphId = navController.getGraph().getId(); - if (i == firstFragmentGraphIndex) { - firstFragmentGraphId = graphId; - } - graphIdToTagMap.put(graphId, fragmentTag); - if (bottomNavigationView.getSelectedItemId() == graphId) { - selectedNavController.setValue(navHostFragment.getNavController()); - attachNavHostFragment(fragmentManager, navHostFragment, i == firstFragmentGraphIndex); - } else { - detachNavHostFragment(fragmentManager, navHostFragment); - } - } - selectedItemTag = graphIdToTagMap.get(bottomNavigationView.getSelectedItemId()); - final String firstFragmentTag = graphIdToTagMap.get(firstFragmentGraphId); - isOnFirstFragment = selectedItemTag != null && selectedItemTag.equals(firstFragmentTag); - bottomNavigationView.setOnItemSelectedListener(item -> { - if (fragmentManager.isStateSaved()) { - return false; - } - String newlySelectedItemTag = graphIdToTagMap.get(item.getItemId()); - String tag = selectedItemTag; - if (tag != null && !tag.equals(newlySelectedItemTag)) { - fragmentManager.popBackStack(firstFragmentTag, FragmentManager.POP_BACK_STACK_INCLUSIVE); - Fragment fragment = fragmentManager.findFragmentByTag(newlySelectedItemTag); - if (fragment == null) { - return false; - // throw new RuntimeException("null cannot be cast to non-null NavHostFragment"); - } - final NavHostFragment selectedFragment = (NavHostFragment) fragment; - if (firstFragmentTag != null && !firstFragmentTag.equals(newlySelectedItemTag)) { - FragmentTransaction fragmentTransaction = fragmentManager - .beginTransaction() - .setCustomAnimations( - R.anim.nav_default_enter_anim, - R.anim.nav_default_exit_anim, - R.anim.nav_default_pop_enter_anim, - R.anim.nav_default_pop_exit_anim - ) - .attach(selectedFragment) - .setPrimaryNavigationFragment(selectedFragment); - for (int i = 0; i < graphIdToTagMap.size(); i++) { - final int key = graphIdToTagMap.keyAt(i); - final String fragmentTagForId = graphIdToTagMap.get(key); - if (!fragmentTagForId.equals(newlySelectedItemTag)) { - final Fragment fragmentByTag = fragmentManager.findFragmentByTag(firstFragmentTag); - if (fragmentByTag == null) { - continue; - } - fragmentTransaction.detach(fragmentByTag); - } - } - fragmentTransaction.addToBackStack(firstFragmentTag) - .setReorderingAllowed(true) - .commit(); - } - selectedItemTag = newlySelectedItemTag; - isOnFirstFragment = selectedItemTag.equals(firstFragmentTag); - selectedNavController.setValue(selectedFragment.getNavController()); - return true; - } - return false; - }); - setupItemReselected(bottomNavigationView, graphIdToTagMap, fragmentManager); - setupDeepLinks(bottomNavigationView, navGraphIds, fragmentManager, containerId, intent); - final int finalFirstFragmentGraphId = firstFragmentGraphId; - fragmentManager.addOnBackStackChangedListener(() -> { - if (!isOnFirstFragment) { - if (firstFragmentTag == null) { - return; - } - if (!isOnBackStack(fragmentManager, firstFragmentTag)) { - bottomNavigationView.setSelectedItemId(finalFirstFragmentGraphId); - } - } - - final NavController navController = selectedNavController.getValue(); - if (navController != null && navController.getCurrentDestination() == null) { - final NavGraph navControllerGraph = navController.getGraph(); - navController.navigate(navControllerGraph.getId()); - } - }); - return selectedNavController; - } - - private static NavHostFragment obtainNavHostFragment(final FragmentManager fragmentManager, - final String fragmentTag, - final int navGraphId, - final int containerId) { - final NavHostFragment existingFragment = (NavHostFragment) fragmentManager.findFragmentByTag(fragmentTag); - if (existingFragment != null) { - return existingFragment; - } - final NavHostFragment navHostFragment = NavHostFragmentWithDefaultAnimations.create(navGraphId); - fragmentManager.beginTransaction() - .setReorderingAllowed(true) - .add(containerId, navHostFragment, fragmentTag) - .commitNow(); - return navHostFragment; - } - - private static void attachNavHostFragment(final FragmentManager fragmentManager, - final NavHostFragment navHostFragment, - final boolean isPrimaryNavFragment) { - final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction() - .attach(navHostFragment); - if (isPrimaryNavFragment) { - fragmentTransaction.setPrimaryNavigationFragment(navHostFragment); - } - fragmentTransaction.commitNow(); - } - - private static void detachNavHostFragment(final FragmentManager fragmentManager, final NavHostFragment navHostFragment) { - fragmentManager.beginTransaction() - .detach(navHostFragment) - .commitNow(); - } - - @SuppressLint("RestrictedApi") - private static void setupItemReselected(final BottomNavigationView bottomNavigationView, - final SparseArray graphIdToTagMap, - final FragmentManager fragmentManager) { - bottomNavigationView.setOnItemReselectedListener(item -> { - final String newlySelectedItemTag = graphIdToTagMap.get(item.getItemId()); - final Fragment fragmentByTag = fragmentManager.findFragmentByTag(newlySelectedItemTag); - if (fragmentByTag == null) { - return; - } - final NavHostFragment selectedFragment = (NavHostFragment) fragmentByTag; - final NavController navController = selectedFragment.getNavController(); - final NavGraph navControllerGraph = navController.getGraph(); - final NavDestination currentDestination = navController.getCurrentDestination(); - final int startDestination = navControllerGraph.getStartDestination(); - int backStackSize = navController.getBackStack().size(); - if (currentDestination != null && backStackSize == 2 && currentDestination.getId() == startDestination) { - // scroll to top - final List fragments = selectedFragment.getChildFragmentManager().getFragments(); - if (fragments.isEmpty()) return; - final Fragment fragment = fragments.get(0); - if (fragment instanceof FeedFragment) { - ((FeedFragment) fragment).scrollToTop(); - } - return; - } - final boolean popped = navController.popBackStack(startDestination, false); - backStackSize = navController.getBackStack().size(); - if (!popped || backStackSize > 2) { - try { - // try loop pop - do { - navController.popBackStack(); - backStackSize = navController.getBackStack().size(); - } while (backStackSize > 2); - } catch (Exception e) { - Log.e(TAG, "setupItemReselected: ", e); - } - } - }); - } - - private static void setupDeepLinks(final BottomNavigationView bottomNavigationView, - final List navGraphIds, - final FragmentManager fragmentManager, - final int containerId, - final Intent intent) { - for (int i = 0; i < navGraphIds.size(); i++) { - final int navGraphId = navGraphIds.get(i); - final String fragmentTag = getFragmentTag(navGraphId); - final NavHostFragment navHostFragment = obtainNavHostFragment(fragmentManager, fragmentTag, navGraphId, containerId); - if (navHostFragment.getNavController().handleDeepLink(intent)) { - final int selectedItemId = bottomNavigationView.getSelectedItemId(); - NavController navController = navHostFragment.getNavController(); - NavGraph graph = navController.getGraph(); - if (selectedItemId != graph.getId()) { - navController = navHostFragment.getNavController(); - graph = navController.getGraph(); - bottomNavigationView.setSelectedItemId(graph.getId()); - } - } - } - } - - private static boolean isOnBackStack(final FragmentManager fragmentManager, final String backStackName) { - int backStackCount = fragmentManager.getBackStackEntryCount(); - for (int i = 0; i < backStackCount; i++) { - final FragmentManager.BackStackEntry backStackEntry = fragmentManager.getBackStackEntryAt(i); - final String name = backStackEntry.getName(); - if (name != null && name.equals(backStackName)) { - return true; - } - } - return false; - } - - private static String getFragmentTag(final int index) { - return "bottomNavigation#" + index; - } -} +// package awais.instagrabber.utils; +// +// import android.annotation.SuppressLint; +// import android.content.Intent; +// import android.util.Log; +// import android.util.SparseArray; +// +// import androidx.annotation.NonNull; +// import androidx.fragment.app.Fragment; +// import androidx.fragment.app.FragmentManager; +// import androidx.fragment.app.FragmentTransaction; +// import androidx.lifecycle.LiveData; +// import androidx.lifecycle.MutableLiveData; +// import androidx.navigation.NavController; +// import androidx.navigation.NavDestination; +// import androidx.navigation.NavGraph; +// import androidx.navigation.fragment.NavHostFragment; +// +// import com.google.android.material.bottomnavigation.BottomNavigationView; +// +// import java.util.List; +// +// import awais.instagrabber.R; +// import awais.instagrabber.customviews.NavHostFragmentWithDefaultAnimations; +// import awais.instagrabber.fragments.main.FeedFragment; +// +// /** +// * This is a Java rewrite of NavigationExtensions +// * from architecture-components-samples. Some modifications have been done, check git history. +// */ +// public class NavigationExtensions { +// private static final String TAG = NavigationExtensions.class.getSimpleName(); +// private static String selectedItemTag; +// private static boolean isOnFirstFragment; +// +// @NonNull +// public static LiveData setupWithNavController(@NonNull final BottomNavigationView bottomNavigationView, +// @NonNull List navGraphIds, +// @NonNull final FragmentManager fragmentManager, +// final int containerId, +// @NonNull Intent intent, +// final int firstFragmentGraphIndex) { +// final SparseArray graphIdToTagMap = new SparseArray<>(); +// final MutableLiveData selectedNavController = new MutableLiveData<>(); +// int firstFragmentGraphId = 0; +// for (int i = 0; i < navGraphIds.size(); i++) { +// final int navGraphId = navGraphIds.get(i); +// final String fragmentTag = getFragmentTag(navGraphId); +// final NavHostFragment navHostFragment = obtainNavHostFragment(fragmentManager, fragmentTag, navGraphId, containerId); +// final NavController navController = navHostFragment.getNavController(); +// final int graphId = navController.getGraph().getId(); +// if (i == firstFragmentGraphIndex) { +// firstFragmentGraphId = graphId; +// } +// graphIdToTagMap.put(graphId, fragmentTag); +// if (bottomNavigationView.getSelectedItemId() == graphId) { +// selectedNavController.setValue(navHostFragment.getNavController()); +// attachNavHostFragment(fragmentManager, navHostFragment, i == firstFragmentGraphIndex); +// } else { +// detachNavHostFragment(fragmentManager, navHostFragment); +// } +// } +// selectedItemTag = graphIdToTagMap.get(bottomNavigationView.getSelectedItemId()); +// final String firstFragmentTag = graphIdToTagMap.get(firstFragmentGraphId); +// isOnFirstFragment = selectedItemTag != null && selectedItemTag.equals(firstFragmentTag); +// bottomNavigationView.setOnItemSelectedListener(item -> { +// if (fragmentManager.isStateSaved()) { +// return false; +// } +// String newlySelectedItemTag = graphIdToTagMap.get(item.getItemId()); +// String tag = selectedItemTag; +// if (tag != null && !tag.equals(newlySelectedItemTag)) { +// fragmentManager.popBackStack(firstFragmentTag, FragmentManager.POP_BACK_STACK_INCLUSIVE); +// Fragment fragment = fragmentManager.findFragmentByTag(newlySelectedItemTag); +// if (fragment == null) { +// return false; +// // throw new RuntimeException("null cannot be cast to non-null NavHostFragment"); +// } +// final NavHostFragment selectedFragment = (NavHostFragment) fragment; +// if (firstFragmentTag != null && !firstFragmentTag.equals(newlySelectedItemTag)) { +// FragmentTransaction fragmentTransaction = fragmentManager +// .beginTransaction() +// .setCustomAnimations( +// R.anim.nav_default_enter_anim, +// R.anim.nav_default_exit_anim, +// R.anim.nav_default_pop_enter_anim, +// R.anim.nav_default_pop_exit_anim +// ) +// .attach(selectedFragment) +// .setPrimaryNavigationFragment(selectedFragment); +// for (int i = 0; i < graphIdToTagMap.size(); i++) { +// final int key = graphIdToTagMap.keyAt(i); +// final String fragmentTagForId = graphIdToTagMap.get(key); +// if (!fragmentTagForId.equals(newlySelectedItemTag)) { +// final Fragment fragmentByTag = fragmentManager.findFragmentByTag(firstFragmentTag); +// if (fragmentByTag == null) { +// continue; +// } +// fragmentTransaction.detach(fragmentByTag); +// } +// } +// fragmentTransaction.addToBackStack(firstFragmentTag) +// .setReorderingAllowed(true) +// .commit(); +// } +// selectedItemTag = newlySelectedItemTag; +// isOnFirstFragment = selectedItemTag.equals(firstFragmentTag); +// selectedNavController.setValue(selectedFragment.getNavController()); +// return true; +// } +// return false; +// }); +// setupItemReselected(bottomNavigationView, graphIdToTagMap, fragmentManager); +// setupDeepLinks(bottomNavigationView, navGraphIds, fragmentManager, containerId, intent); +// final int finalFirstFragmentGraphId = firstFragmentGraphId; +// fragmentManager.addOnBackStackChangedListener(() -> { +// if (!isOnFirstFragment) { +// if (firstFragmentTag == null) { +// return; +// } +// if (!isOnBackStack(fragmentManager, firstFragmentTag)) { +// bottomNavigationView.setSelectedItemId(finalFirstFragmentGraphId); +// } +// } +// +// final NavController navController = selectedNavController.getValue(); +// if (navController != null && navController.getCurrentDestination() == null) { +// final NavGraph navControllerGraph = navController.getGraph(); +// navController.navigate(navControllerGraph.getId()); +// } +// }); +// return selectedNavController; +// } +// +// private static NavHostFragment obtainNavHostFragment(final FragmentManager fragmentManager, +// final String fragmentTag, +// final int navGraphId, +// final int containerId) { +// final NavHostFragment existingFragment = (NavHostFragment) fragmentManager.findFragmentByTag(fragmentTag); +// if (existingFragment != null) { +// return existingFragment; +// } +// final NavHostFragment navHostFragment = NavHostFragmentWithDefaultAnimations.create(navGraphId); +// fragmentManager.beginTransaction() +// .setReorderingAllowed(true) +// .add(containerId, navHostFragment, fragmentTag) +// .commitNow(); +// return navHostFragment; +// } +// +// private static void attachNavHostFragment(final FragmentManager fragmentManager, +// final NavHostFragment navHostFragment, +// final boolean isPrimaryNavFragment) { +// final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction() +// .attach(navHostFragment); +// if (isPrimaryNavFragment) { +// fragmentTransaction.setPrimaryNavigationFragment(navHostFragment); +// } +// fragmentTransaction.commitNow(); +// } +// +// private static void detachNavHostFragment(final FragmentManager fragmentManager, final NavHostFragment navHostFragment) { +// fragmentManager.beginTransaction() +// .detach(navHostFragment) +// .commitNow(); +// } +// +// @SuppressLint("RestrictedApi") +// private static void setupItemReselected(final BottomNavigationView bottomNavigationView, +// final SparseArray graphIdToTagMap, +// final FragmentManager fragmentManager) { +// bottomNavigationView.setOnItemReselectedListener(item -> { +// final String newlySelectedItemTag = graphIdToTagMap.get(item.getItemId()); +// final Fragment fragmentByTag = fragmentManager.findFragmentByTag(newlySelectedItemTag); +// if (fragmentByTag == null) { +// return; +// } +// final NavHostFragment selectedFragment = (NavHostFragment) fragmentByTag; +// final NavController navController = selectedFragment.getNavController(); +// final NavGraph navControllerGraph = navController.getGraph(); +// final NavDestination currentDestination = navController.getCurrentDestination(); +// final int startDestination = navControllerGraph.getStartDestination(); +// int backStackSize = navController.getBackStack().size(); +// if (currentDestination != null && backStackSize == 2 && currentDestination.getId() == startDestination) { +// // scroll to top +// final List fragments = selectedFragment.getChildFragmentManager().getFragments(); +// if (fragments.isEmpty()) return; +// final Fragment fragment = fragments.get(0); +// if (fragment instanceof FeedFragment) { +// ((FeedFragment) fragment).scrollToTop(); +// } +// return; +// } +// final boolean popped = navController.popBackStack(startDestination, false); +// backStackSize = navController.getBackStack().size(); +// if (!popped || backStackSize > 2) { +// try { +// // try loop pop +// do { +// navController.popBackStack(); +// backStackSize = navController.getBackStack().size(); +// } while (backStackSize > 2); +// } catch (Exception e) { +// Log.e(TAG, "setupItemReselected: ", e); +// } +// } +// }); +// } +// +// private static void setupDeepLinks(final BottomNavigationView bottomNavigationView, +// final List navGraphIds, +// final FragmentManager fragmentManager, +// final int containerId, +// final Intent intent) { +// for (int i = 0; i < navGraphIds.size(); i++) { +// final int navGraphId = navGraphIds.get(i); +// final String fragmentTag = getFragmentTag(navGraphId); +// final NavHostFragment navHostFragment = obtainNavHostFragment(fragmentManager, fragmentTag, navGraphId, containerId); +// if (navHostFragment.getNavController().handleDeepLink(intent)) { +// final int selectedItemId = bottomNavigationView.getSelectedItemId(); +// NavController navController = navHostFragment.getNavController(); +// NavGraph graph = navController.getGraph(); +// if (selectedItemId != graph.getId()) { +// navController = navHostFragment.getNavController(); +// graph = navController.getGraph(); +// bottomNavigationView.setSelectedItemId(graph.getId()); +// } +// } +// } +// } +// +// private static boolean isOnBackStack(final FragmentManager fragmentManager, final String backStackName) { +// int backStackCount = fragmentManager.getBackStackEntryCount(); +// for (int i = 0; i < backStackCount; i++) { +// final FragmentManager.BackStackEntry backStackEntry = fragmentManager.getBackStackEntryAt(i); +// final String name = backStackEntry.getName(); +// if (name != null && name.equals(backStackName)) { +// return true; +// } +// } +// return false; +// } +// +// private static String getFragmentTag(final int index) { +// return "bottomNavigation#" + index; +// } +// } diff --git a/app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt b/app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt new file mode 100644 index 00000000..8c2097a8 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/NavigationHelper.kt @@ -0,0 +1,162 @@ +package awais.instagrabber.utils + +import android.content.Context +import android.content.res.Resources +import androidx.annotation.ArrayRes +import awais.instagrabber.R +import awais.instagrabber.fragments.settings.PreferenceKeys +import awais.instagrabber.models.Tab + +var tabOrderString: String? = null + +private val NON_REMOVABLE_NAV_ROOT_IDS: List = listOf(R.id.profile_nav_graph, R.id.more_nav_graph) + + +fun getLoggedInNavTabs(context: Context): Pair, List> { + val navRootIds = getArrayResIds(context.resources, R.array.logged_in_nav_root_ids) + return getTabs(context, navRootIds) +} + +fun getAnonNavTabs(context: Context): List { + val navRootIds = getArrayResIds(context.resources, R.array.anon_nav_root_ids) + val (tabs, _) = getTabs(context, navRootIds) + return tabs +} + +private fun getTabs( + context: Context, + navRootIds: IntArray, + isAnon: Boolean = false, +): Pair, MutableList> { + val navGraphNames = getResIdsForNavRootIds(navRootIds, ::geNavGraphNameForNavRootId) + val titleArray = getResIdsForNavRootIds(navRootIds, ::getTitleResIdForNavRootId) + val iconIds = getResIdsForNavRootIds(navRootIds, ::getIconResIdForNavRootId) + val startDestFragIds = getResIdsForNavRootIds(navRootIds, ::getStartDestFragIdForNavRootId) + val (orderedGraphNames, orderedNavRootIds) = if (isAnon) navGraphNames to navRootIds.toList() else getOrderedNavRootIdsFromPref(navGraphNames) + val tabs = mutableListOf() + val otherTabs = mutableListOf() // Will contain tabs not in current list + for (i in navRootIds.indices) { + val navRootId = navRootIds[i] + val navGraphName = navGraphNames[i] + val tab = Tab( + iconIds[i], + context.getString(titleArray[i]), + if(isAnon) false else !NON_REMOVABLE_NAV_ROOT_IDS.contains(navRootId), + navRootId, + startDestFragIds[i] + ) + if (!isAnon && !orderedGraphNames.contains(navGraphName)) { + otherTabs.add(tab) + continue + } + tabs.add(tab) + } + val associateBy = tabs.associateBy { it.navigationRootId } + val orderedTabs = orderedNavRootIds.mapNotNull { associateBy[it] } + return orderedTabs to otherTabs +} + +private fun getArrayResIds(resources: Resources, @ArrayRes arrayRes: Int): IntArray { + val typedArray = resources.obtainTypedArray(arrayRes) + val length = typedArray.length() + val navRootIds = IntArray(length) + for (i in 0 until length) { + val resourceId = typedArray.getResourceId(i, 0) + if (resourceId == 0) continue + navRootIds[i] = resourceId + } + typedArray.recycle() + return navRootIds +} + +private fun getResIdsForNavRootIds(navRootIds: IntArray, resMapper: Function1): List = navRootIds + .asSequence() + .filterNot { it == 0 } + .map(resMapper) + .filterNot { it == 0 } + .toList() + +private fun getTitleResIdForNavRootId(id: Int): Int = when (id) { + R.id.direct_messages_nav_graph -> R.string.title_dm + R.id.feed_nav_graph -> R.string.feed + R.id.profile_nav_graph -> R.string.profile + R.id.discover_nav_graph -> R.string.title_discover + R.id.more_nav_graph -> R.string.more + R.id.favorites_nav_graph -> R.string.title_favorites + R.id.notification_viewer_nav_graph -> R.string.title_notifications + else -> 0 +} + +private fun getIconResIdForNavRootId(id: Int): Int = when (id) { + R.id.direct_messages_nav_graph -> R.drawable.ic_message_24 + R.id.feed_nav_graph -> R.drawable.ic_home_24 + R.id.profile_nav_graph -> R.drawable.ic_person_24 + R.id.discover_nav_graph -> R.drawable.ic_explore_24 + R.id.more_nav_graph -> R.drawable.ic_more_horiz_24 + R.id.favorites_nav_graph -> R.drawable.ic_star_24 + R.id.notification_viewer_nav_graph -> R.drawable.ic_not_liked + else -> 0 +} + +private fun getStartDestFragIdForNavRootId(id: Int): Int = when (id) { + R.id.direct_messages_nav_graph -> R.id.directMessagesInboxFragment + R.id.feed_nav_graph -> R.id.feedFragment + R.id.profile_nav_graph -> R.id.profileFragment + R.id.discover_nav_graph -> R.id.discoverFragment + R.id.more_nav_graph -> R.id.morePreferencesFragment + R.id.favorites_nav_graph -> R.id.favoritesFragment + R.id.notification_viewer_nav_graph -> R.id.notificationsViewer + else -> 0 +} + +fun geNavGraphNameForNavRootId(id: Int): String = when (id) { + R.id.direct_messages_nav_graph -> "direct_messages_nav_graph" + R.id.feed_nav_graph -> "feed_nav_graph" + R.id.profile_nav_graph -> "profile_nav_graph" + R.id.discover_nav_graph -> "discover_nav_graph" + R.id.more_nav_graph -> "more_nav_graph" + R.id.favorites_nav_graph -> "favorites_nav_graph" + R.id.notification_viewer_nav_graph -> "notification_viewer_nav_graph" + else -> "" +} + +private fun geNavGraphNameForNavRootId(navGraphName: String): Int = when (navGraphName) { + "direct_messages_nav_graph" -> R.id.direct_messages_nav_graph + "feed_nav_graph" -> R.id.feed_nav_graph + "profile_nav_graph" -> R.id.profile_nav_graph + "discover_nav_graph" -> R.id.discover_nav_graph + "more_nav_graph" -> R.id.more_nav_graph + "favorites_nav_graph" -> R.id.favorites_nav_graph + "notification_viewer_nav_graph" -> R.id.notification_viewer_nav_graph + else -> 0 +} + +private fun getOrderedNavRootIdsFromPref(navGraphNames: List): Pair, List> { + tabOrderString = Utils.settingsHelper.getString(PreferenceKeys.PREF_TAB_ORDER) + if (tabOrderString.isNullOrBlank()) { + // Use top 5 entries for default list + val top5navGraphNames: List = navGraphNames.subList(0, 5) + val newOrderString = top5navGraphNames.joinToString(",") + Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString) + tabOrderString = newOrderString + return top5navGraphNames to top5navGraphNames.map(::geNavGraphNameForNavRootId) + } + val orderString = tabOrderString ?: return navGraphNames to navGraphNames.subList(0, 5).map(::geNavGraphNameForNavRootId) + // Make sure that the list from preference does not contain any invalid values + val orderGraphNames = orderString + .split(",") + .asSequence() + .filter(String::isNotBlank) + .filter(navGraphNames::contains) + .toList() + val graphNames = if (orderGraphNames.isEmpty()) { + // Use top 5 entries for default list + navGraphNames.subList(0, 5) + } else orderGraphNames + return graphNames to graphNames.map(::geNavGraphNameForNavRootId) +} + +fun isNavRootInCurrentTabs(navRootString: String?): Boolean { + val navRoot = navRootString ?: return false + return tabOrderString?.contains(navRoot) ?: false +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java index 499f8c1e..0d5cda1d 100644 --- a/app/src/main/java/awais/instagrabber/utils/Utils.java +++ b/app/src/main/java/awais/instagrabber/utils/Utils.java @@ -8,7 +8,6 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.res.Resources; -import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; @@ -46,8 +45,6 @@ import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat; import com.google.android.exoplayer2.database.ExoDatabaseProvider; import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Ordering; import org.json.JSONObject; @@ -55,22 +52,15 @@ import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import awais.instagrabber.R; -import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.PostsLayoutPreferences; -import awais.instagrabber.models.Tab; import awais.instagrabber.models.enums.FavoriteType; -import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_BARINSTA_DIR_URI; - public final class Utils { private static final String TAG = "Utils"; private static final int VIDEO_CACHE_MAX_BYTES = 10 * 1024 * 1024; @@ -85,7 +75,6 @@ public final class Utils { private static int statusBarHeight; private static int actionBarHeight; public static String cacheDir; - public static String tabOrderString; private static int defaultStatusBarColor; private static Object[] volumes; @@ -421,115 +410,6 @@ public final class Utils { } } - private static final List NON_REMOVABLE_NAV_ROOT_IDS = ImmutableList.of(R.id.profile_nav_graph, R.id.more_nav_graph); - - @NonNull - public static Pair, List> getNavTabList(@NonNull final Context context) { - final Resources resources = context.getResources(); - final String[] titleArray = resources.getStringArray(R.array.main_nav_titles); - - TypedArray typedArray = resources.obtainTypedArray(R.array.main_nav_graphs); - int length = typedArray.length(); - final String[] navGraphNames = new String[length]; - final int[] navigationResIds = new int[length]; - for (int i = 0; i < length; i++) { - final int resourceId = typedArray.getResourceId(i, 0); - if (resourceId == 0) continue; - navigationResIds[i] = resourceId; - navGraphNames[i] = resources.getResourceEntryName(resourceId); - } - typedArray.recycle(); - - typedArray = resources.obtainTypedArray(R.array.main_nav_graph_root_ids); - length = typedArray.length(); - final int[] navRootIds = new int[length]; - for (int i = 0; i < length; i++) { - final int resourceId = typedArray.getResourceId(i, 0); - if (resourceId == 0) continue; - navRootIds[i] = resourceId; - } - typedArray.recycle(); - - typedArray = resources.obtainTypedArray(R.array.main_nav_drawables); - length = typedArray.length(); - final int[] iconIds = new int[length]; - for (int i = 0; i < length; i++) { - final int resourceId = typedArray.getResourceId(i, 0); - if (resourceId == 0) continue; - iconIds[i] = resourceId; - } - typedArray.recycle(); - - typedArray = resources.obtainTypedArray(R.array.main_nav_start_dest_frag_ids); - length = typedArray.length(); - final int[] startDestFragIds = new int[length]; - for (int i = 0; i < length; i++) { - final int resourceId = typedArray.getResourceId(i, 0); - if (resourceId == 0) continue; - startDestFragIds[i] = resourceId; - } - typedArray.recycle(); - - final List currentOrderGraphNames = getCurrentOrderOfGraphNamesFromPref(navGraphNames); - - if (titleArray.length != iconIds.length || titleArray.length != navGraphNames.length) { - throw new RuntimeException(String.format("Array lengths don't match!: titleArray%s, navGraphNames: %s, iconIds: %s", - Arrays.toString(titleArray), Arrays.toString(navGraphNames), Arrays.toString(iconIds))); - } - final List tabs = new ArrayList<>(); - final List otherTabs = new ArrayList<>(); // Will contain tabs not in current list - for (int i = 0; i < length; i++) { - final String navGraphName = navGraphNames[i]; - final int navRootId = navRootIds[i]; - final Tab tab = new Tab(iconIds[i], - titleArray[i], - !NON_REMOVABLE_NAV_ROOT_IDS.contains(navRootId), - navGraphName, - navigationResIds[i], - navRootId, - startDestFragIds[i]); - if (!currentOrderGraphNames.contains(navGraphName)) { - otherTabs.add(tab); - continue; - } - tabs.add(tab); - } - Collections.sort(tabs, Ordering.explicit(currentOrderGraphNames).onResultOf(tab -> { - if (tab == null) return null; - return tab.getGraphName(); - })); - return new Pair<>(tabs, otherTabs); - } - - @NonNull - private static List getCurrentOrderOfGraphNamesFromPref(@NonNull final String[] navGraphNames) { - tabOrderString = settingsHelper.getString(PreferenceKeys.PREF_TAB_ORDER); - final List navGraphNameList = Arrays.asList(navGraphNames); - if (TextUtils.isEmpty(tabOrderString)) { - // Use top 5 entries for default list - final List top5navGraphNames = navGraphNameList.subList(0, 5); - final String newOrderString = android.text.TextUtils.join(",", top5navGraphNames); - Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString); - tabOrderString = newOrderString; - return top5navGraphNames; - } - // Make sure that the list from preference does not contain any invalid values - final List orderGraphNames = Arrays.stream(tabOrderString.split(",")) - .filter(s -> !TextUtils.isEmpty(s)) - .filter(navGraphNameList::contains) - .collect(Collectors.toList()); - if (orderGraphNames.isEmpty()) { - // Use top 5 entries for default list - return navGraphNameList.subList(0, 5); - } - return orderGraphNames; - } - - public static boolean isNavRootInCurrentTabs(final String navRootString) { - if (navRootString == null || tabOrderString == null) return false; - return tabOrderString.contains(navRootString); - } - // public static void scanDocumentFile(@NonNull final Context context, // @NonNull final DocumentFile documentFile, // @NonNull final OnScanCompletedListener callback) { diff --git a/app/src/main/java/awais/instagrabber/viewmodels/UserSearchViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/UserSearchViewModel.java index c0ecd0b8..63161b94 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/UserSearchViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/UserSearchViewModel.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.stream.Collectors; import awais.instagrabber.R; -import awais.instagrabber.fragments.UserSearchFragment; +import awais.instagrabber.fragments.UserSearchMode; import awais.instagrabber.models.Resource; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; @@ -49,7 +49,7 @@ public class UserSearchViewModel extends ViewModel { private Call searchRequest; private long[] hideUserIds; private String[] hideThreadIds; - private UserSearchFragment.SearchMode searchMode; + private UserSearchMode searchMode; private boolean showGroups; private boolean waitingForCache; private boolean showCachedResults; @@ -192,7 +192,7 @@ public class UserSearchViewModel extends ViewModel { private void rankedRecipientSearch() { directMessagesRepository.rankedRecipients( - searchMode.getName(), + searchMode.name(), showGroups, currentQuery, CoroutineUtilsKt.getContinuation((response, throwable) -> { @@ -290,7 +290,7 @@ public class UserSearchViewModel extends ViewModel { return showAction; } - public void setSearchMode(final UserSearchFragment.SearchMode searchMode) { + public void setSearchMode(final UserSearchMode searchMode) { this.searchMode = searchMode; } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9d1e880a..5a714857 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -60,9 +60,11 @@ diff --git a/app/src/main/res/navigation/comments_nav_graph.xml b/app/src/main/res/navigation/comments_nav_graph.xml deleted file mode 100644 index 0cec9091..00000000 --- a/app/src/main/res/navigation/comments_nav_graph.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/direct_messages_nav_graph.xml b/app/src/main/res/navigation/direct_messages_nav_graph.xml deleted file mode 100644 index dce30b6a..00000000 --- a/app/src/main/res/navigation/direct_messages_nav_graph.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/discover_nav_graph.xml b/app/src/main/res/navigation/discover_nav_graph.xml deleted file mode 100644 index d63d7a7c..00000000 --- a/app/src/main/res/navigation/discover_nav_graph.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/favorites_nav_graph.xml b/app/src/main/res/navigation/favorites_nav_graph.xml deleted file mode 100644 index 63ae746e..00000000 --- a/app/src/main/res/navigation/favorites_nav_graph.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/feed_nav_graph.xml b/app/src/main/res/navigation/feed_nav_graph.xml deleted file mode 100644 index f770216f..00000000 --- a/app/src/main/res/navigation/feed_nav_graph.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/hashtag_nav_graph.xml b/app/src/main/res/navigation/hashtag_nav_graph.xml deleted file mode 100644 index 55937cbd..00000000 --- a/app/src/main/res/navigation/hashtag_nav_graph.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/likes_nav_graph.xml b/app/src/main/res/navigation/likes_nav_graph.xml deleted file mode 100644 index 0157f71a..00000000 --- a/app/src/main/res/navigation/likes_nav_graph.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/location_nav_graph.xml b/app/src/main/res/navigation/location_nav_graph.xml deleted file mode 100644 index 3828e5c4..00000000 --- a/app/src/main/res/navigation/location_nav_graph.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/more_nav_graph.xml b/app/src/main/res/navigation/more_nav_graph.xml deleted file mode 100644 index f4e99e1e..00000000 --- a/app/src/main/res/navigation/more_nav_graph.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 00000000..a14a2d24 --- /dev/null +++ b/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/notification_viewer_nav_graph.xml b/app/src/main/res/navigation/notification_viewer_nav_graph.xml deleted file mode 100644 index 83833a83..00000000 --- a/app/src/main/res/navigation/notification_viewer_nav_graph.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/profile_nav_graph.xml b/app/src/main/res/navigation/profile_nav_graph.xml deleted file mode 100644 index e5a8e87e..00000000 --- a/app/src/main/res/navigation/profile_nav_graph.xml +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/saved_nav_graph.xml b/app/src/main/res/navigation/saved_nav_graph.xml deleted file mode 100644 index dba1cb54..00000000 --- a/app/src/main/res/navigation/saved_nav_graph.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/settings_nav_graph.xml b/app/src/main/res/navigation/settings_nav_graph.xml new file mode 100644 index 00000000..d8ecbccf --- /dev/null +++ b/app/src/main/res/navigation/settings_nav_graph.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/story_list_nav_graph.xml b/app/src/main/res/navigation/story_list_nav_graph.xml deleted file mode 100644 index 0820b7d0..00000000 --- a/app/src/main/res/navigation/story_list_nav_graph.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/user_search_nav_graph.xml b/app/src/main/res/navigation/user_search_nav_graph.xml deleted file mode 100644 index e8667732..00000000 --- a/app/src/main/res/navigation/user_search_nav_graph.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 7b1723ae..d70b4757 100755 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -91,61 +91,23 @@ HH:mm:ss H:mm:ss - + + @id/direct_messages_nav_graph @id/feed_nav_graph @id/profile_nav_graph @id/discover_nav_graph @id/more_nav_graph - @id/favorites_nav_graph @id/notification_viewer_nav_graph - - - @navigation/direct_messages_nav_graph - @navigation/feed_nav_graph - @navigation/profile_nav_graph - @navigation/discover_nav_graph - @navigation/more_nav_graph - @navigation/favorites_nav_graph - @navigation/notification_viewer_nav_graph + + + @id/favorites_nav_graph + @id/profile_nav_graph + @id/more_nav_graph - - - @string/title_dm - @string/feed - @string/profile - @string/title_discover - @string/more - @string/title_favorites - @string/title_notifications - - - - @drawable/ic_message_24 - @drawable/ic_home_24 - @drawable/ic_person_24 - @drawable/ic_explore_24 - @drawable/ic_more_horiz_24 - @drawable/ic_star_24 - @drawable/ic_not_liked - - - - - @id/directMessagesInboxFragment - @id/feedFragment - @id/profileFragment - @id/discoverFragment - @id/morePreferencesFragment - @id/favoritesFragment - @id/notificationsViewer - - - - - + @string/light_white_theme @string/light_barinsta_theme diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 29c6fecc..c017d9bd 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -8,4 +8,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index e1d7b4a7..187a5d8c 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,8 @@ buildscript { - ext.kotlin_version = '1.5.20' + ext{ + kotlin_version = '1.5.20' + nav_version = "2.4.0-alpha04" + } repositories { google() @@ -9,7 +12,6 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - def nav_version = "2.3.5" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } }