From 28231affc8b4a31ebc9558dbe4aeb62dee6ec08c Mon Sep 17 00:00:00 2001 From: Natanel Shitrit <65548905+Natanel-Shitrit@users.noreply.github.com> Date: Tue, 26 Sep 2023 00:34:06 +0300 Subject: [PATCH] fix: show server select fragment when server has no current user (#235) (#439) * Organize code, fix "locking" problem Organize `MainActivity.kt`. Open `serverSelectFragment` instead of `loginFragment` which could've lead to app locking if no user has logged in after adding the server. * Fix linting * Optimize imports * fix: update jellyfinApi before navigating to login fragment Also move logic to viewmodel --------- Co-authored-by: Jarne Demeulemeester --- .../java/dev/jdtech/jellyfin/MainActivity.kt | 64 +++++++++++-------- .../fragments/ServerSelectFragment.kt | 10 ++- .../main/res/navigation/app_navigation.xml | 3 + .../viewmodels/ServerSelectViewModel.kt | 17 ++++- 4 files changed, 65 insertions(+), 29 deletions(-) diff --git a/app/phone/src/main/java/dev/jdtech/jellyfin/MainActivity.kt b/app/phone/src/main/java/dev/jdtech/jellyfin/MainActivity.kt index eb6a939e..6df373d6 100644 --- a/app/phone/src/main/java/dev/jdtech/jellyfin/MainActivity.kt +++ b/app/phone/src/main/java/dev/jdtech/jellyfin/MainActivity.kt @@ -43,34 +43,17 @@ class MainActivity : AppCompatActivity() { private lateinit var navController: NavController - @OptIn(NavigationUiSaveStateControl::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + scheduleUserDataSync() + cleanUpOldDownloads() + applyTheme() + setupActivity() + } - val syncWorkRequest = OneTimeWorkRequestBuilder() - .setConstraints( - Constraints.Builder() - .setRequiredNetworkType( - NetworkType.CONNECTED, - ) - .build(), - ) - .build() - - val workManager = WorkManager.getInstance(applicationContext) - - workManager.beginUniqueWork("syncUserData", ExistingWorkPolicy.KEEP, syncWorkRequest).enqueue() - - if (!appPreferences.downloadsMigrated) { - cleanUpOldDownloads() - } - - if (appPreferences.amoledTheme) { - setTheme(CoreR.style.Theme_FindroidAMOLED) - } - + @OptIn(NavigationUiSaveStateControl::class) + private fun setupActivity() { binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) val navHostFragment = @@ -129,8 +112,8 @@ class MainActivity : AppCompatActivity() { private fun checkServersEmpty(graph: NavGraph, onServersEmpty: () -> Unit = {}) { if (!viewModel.startDestinationChanged) { - val nServers = database.getServersCount() - if (nServers < 1) { + val numOfServers = database.getServersCount() + if (numOfServers < 1) { graph.setStartDestination(R.id.addServerFragment) viewModel.startDestinationChanged = true onServersEmpty() @@ -143,7 +126,7 @@ class MainActivity : AppCompatActivity() { appPreferences.currentServer?.let { val currentUser = database.getServerCurrentUser(it) if (currentUser == null) { - graph.setStartDestination(R.id.loginFragment) + graph.setStartDestination(R.id.serverSelectFragment) viewModel.startDestinationChanged = true onNoUser() } @@ -155,6 +138,10 @@ class MainActivity : AppCompatActivity() { * Temp to remove old downloads, will be removed in a future version */ private fun cleanUpOldDownloads() { + if (appPreferences.downloadsMigrated) { + return + } + lifecycleScope.launch { val oldDir = applicationContext.getExternalFilesDir(Environment.DIRECTORY_MOVIES) if (oldDir == null) { @@ -171,4 +158,27 @@ class MainActivity : AppCompatActivity() { appPreferences.downloadsMigrated = true } } + + private fun scheduleUserDataSync() { + val syncWorkRequest = OneTimeWorkRequestBuilder() + .setConstraints( + Constraints.Builder() + .setRequiredNetworkType( + NetworkType.CONNECTED, + ) + .build(), + ) + .build() + + val workManager = WorkManager.getInstance(applicationContext) + + workManager.beginUniqueWork("syncUserData", ExistingWorkPolicy.KEEP, syncWorkRequest) + .enqueue() + } + + private fun applyTheme() { + if (appPreferences.amoledTheme) { + setTheme(CoreR.style.Theme_FindroidAMOLED) + } + } } diff --git a/app/phone/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt b/app/phone/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt index a78311e6..eb212f14 100644 --- a/app/phone/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt +++ b/app/phone/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt @@ -20,7 +20,6 @@ import timber.log.Timber @AndroidEntryPoint class ServerSelectFragment : Fragment() { - private lateinit var binding: FragmentServerSelectBinding private val viewModel: ServerSelectViewModel by viewModels() @@ -66,6 +65,11 @@ class ServerSelectFragment : Fragment() { if (it) navigateToMainActivity() } } + launch { + viewModel.navigateToLogin.collect { + if (it) navigateToLoginFragment() + } + } } } @@ -87,4 +91,8 @@ class ServerSelectFragment : Fragment() { private fun navigateToMainActivity() { findNavController().navigate(ServerSelectFragmentDirections.actionServerSelectFragmentToHomeFragment()) } + + private fun navigateToLoginFragment() { + findNavController().navigate(ServerSelectFragmentDirections.actionServerSelectFragmentToLoginFragment()) + } } diff --git a/app/phone/src/main/res/navigation/app_navigation.xml b/app/phone/src/main/res/navigation/app_navigation.xml index 4b8b44e6..cf534870 100644 --- a/app/phone/src/main/res/navigation/app_navigation.xml +++ b/app/phone/src/main/res/navigation/app_navigation.xml @@ -299,6 +299,9 @@ app:destination="@id/homeFragment" app:popUpTo="@id/homeFragment" app:popUpToInclusive="true" /> + () val navigateToMain = _navigateToMain.asSharedFlow() + private val _navigateToLogin = MutableSharedFlow() + val navigateToLogin = _navigateToLogin.asSharedFlow() + sealed class UiState { data class Normal(val servers: List) : UiState() data object Loading : UiState() @@ -62,7 +65,19 @@ constructor( viewModelScope.launch { val serverWithAddressesAndUsers = database.getServerWithAddressesAndUsers(server.id) ?: return@launch val serverAddress = serverWithAddressesAndUsers.addresses.firstOrNull { it.id == server.currentServerAddressId } ?: return@launch - val user = serverWithAddressesAndUsers.users.firstOrNull { it.id == server.currentUserId } ?: return@launch + val user = serverWithAddressesAndUsers.users.firstOrNull { it.id == server.currentUserId } + + // If server has no selected user, navigate to login fragment + if (user == null) { + jellyfinApi.apply { + api.baseUrl = serverAddress.address + api.accessToken = null + userId = null + } + appPreferences.currentServer = server.id + _navigateToLogin.emit(true) + return@launch + } jellyfinApi.apply { api.baseUrl = serverAddress.address