diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f15f38d3..71b3b2f6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,13 +16,9 @@ - + android:windowSoftInputMode="adjustPan" + android:exported="true"> diff --git a/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt index fe8eb76b..78ce1139 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt @@ -1,24 +1,33 @@ package dev.jdtech.jellyfin import android.os.Bundle +import android.view.View +import androidx.activity.viewModels import com.google.android.material.bottomnavigation.BottomNavigationView import androidx.appcompat.app.AppCompatActivity +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.databinding.ActivityMainBinding +import dev.jdtech.jellyfin.fragments.InitializingFragmentDirections +import dev.jdtech.jellyfin.viewmodels.MainViewModel @AndroidEntryPoint class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding + private val viewModel: MainViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + installSplashScreen() + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) val navView: BottomNavigationView = binding.navView @@ -34,11 +43,32 @@ class MainActivity : AppCompatActivity() { // menu should be considered as top level destinations. val appBarConfiguration = AppBarConfiguration( setOf( - R.id.navigation_home, R.id.navigation_media, R.id.favoriteFragment + R.id.homeFragment, R.id.mediaFragment, R.id.favoriteFragment ) ) + setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) + + navController.addOnDestinationChangedListener { _, destination, _ -> + binding.navView.visibility = when (destination.id) { + R.id.settingsFragment, R.id.serverSelectFragment, R.id.addServerFragment, R.id.loginFragment -> View.GONE + else -> View.VISIBLE + } + } + + viewModel.navigateToAddServer.observe(this, { + if (it) { + navController.navigate(InitializingFragmentDirections.actionInitializingFragmentToAddServerFragment3()) + viewModel.doneNavigateToAddServer() + } + }) + + viewModel.doneLoading.observe(this, { + if (it) { + navController.navigate(InitializingFragmentDirections.actionInitializingFragmentToNavigationHome()) + } + }) } override fun onSupportNavigateUp(): Boolean { diff --git a/app/src/main/java/dev/jdtech/jellyfin/SetupActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/SetupActivity.kt deleted file mode 100644 index 8e03525a..00000000 --- a/app/src/main/java/dev/jdtech/jellyfin/SetupActivity.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.jdtech.jellyfin - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class SetupActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - installSplashScreen() - setContentView(R.layout.activity_setup) - } -} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt new file mode 100644 index 00000000..d3f6de19 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt @@ -0,0 +1,22 @@ +package dev.jdtech.jellyfin.di + +import android.content.Context +import android.content.SharedPreferences +import androidx.preference.PreferenceManager +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + + +@Module +@InstallIn(SingletonComponent::class) +object SharedPreferencesModule { + @Singleton + @Provides + fun provideSharedPreferences(@ApplicationContext application: Context): SharedPreferences { + return PreferenceManager.getDefaultSharedPreferences(application) + } +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt index 8560e48d..10fbcddc 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt @@ -51,7 +51,7 @@ class AddServerFragment : Fragment() { } private fun navigateToLoginFragment() { - findNavController().navigate(AddServerFragmentDirections.actionAddServerFragmentToLoginFragment()) + findNavController().navigate(AddServerFragmentDirections.actionAddServerFragment3ToLoginFragment2()) viewModel.onNavigateToLoginDone() } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/InitializingFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/InitializingFragment.kt new file mode 100644 index 00000000..e30ba480 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/InitializingFragment.kt @@ -0,0 +1,24 @@ +package dev.jdtech.jellyfin.fragments + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import dev.jdtech.jellyfin.R + + +class InitializingFragment : Fragment() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_initializing, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt index 596fbb32..61d9e6aa 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt @@ -47,7 +47,7 @@ class LoginFragment : Fragment() { } private fun navigateToMainActivity() { - findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToMainActivity()) + findNavController().navigate(LoginFragmentDirections.actionLoginFragment2ToNavigationHome()) viewModel.doneNavigatingToMain() } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt index 2154a624..d082b145 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt @@ -55,11 +55,13 @@ class ServerSelectFragment : Fragment() { } private fun navigateToAddServerFragment() { - findNavController().navigate(R.id.action_serverSelectFragment_to_addServerFragment) + findNavController().navigate( + ServerSelectFragmentDirections.actionServerSelectFragment2ToAddServerFragment3() + ) } private fun navigateToMainActivity() { - findNavController().navigate(R.id.action_serverSelectFragment_to_mainActivity) + findNavController().navigate(ServerSelectFragmentDirections.actionServerSelectFragmentToHomeFragment()) viewModel.doneNavigatingToMain() } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt index dc9d0ae0..7cfd58d7 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt @@ -1,11 +1,18 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import dev.jdtech.jellyfin.R class SettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.fragment_settings, rootKey) + + findPreference("switchServer")?.setOnPreferenceClickListener { + findNavController().navigate(SettingsFragmentDirections.actionNavigationSettingsToServerSelectFragment2()) + true + } } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt index 47fcf7a1..7722a3e7 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt @@ -1,5 +1,6 @@ package dev.jdtech.jellyfin.viewmodels +import android.content.SharedPreferences import androidx.lifecycle.* import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.api.JellyfinApi @@ -17,6 +18,7 @@ import javax.inject.Inject class LoginViewModel @Inject constructor( + private val sharedPreferences: SharedPreferences, private val jellyfinApi: JellyfinApi, private val database: ServerDatabaseDao ) : ViewModel() { @@ -54,6 +56,9 @@ constructor( authenticationResult.accessToken!! ) insert(server) + val spEdit = sharedPreferences.edit() + spEdit.putString("selectedServer", server.id) + spEdit.apply() jellyfinApi.apply { api.accessToken = authenticationResult.accessToken userId = authenticationResult.user?.id diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt new file mode 100644 index 00000000..92cab80b --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt @@ -0,0 +1,65 @@ +package dev.jdtech.jellyfin.viewmodels + +import android.app.Application +import android.content.SharedPreferences +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.preference.PreferenceManager +import dagger.hilt.android.lifecycle.HiltViewModel +import dev.jdtech.jellyfin.api.JellyfinApi +import dev.jdtech.jellyfin.database.Server +import dev.jdtech.jellyfin.database.ServerDatabaseDao +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import timber.log.Timber +import java.util.* +import javax.inject.Inject + +@HiltViewModel +class MainViewModel +@Inject +constructor( + private val sharedPreferences: SharedPreferences, + private val database: ServerDatabaseDao, + private val jellyfinApi: JellyfinApi, +) : ViewModel() { + + private val _doneLoading = MutableLiveData() + val doneLoading: LiveData = _doneLoading + + private val _navigateToAddServer = MutableLiveData() + val navigateToAddServer: LiveData = _navigateToAddServer + + init { + Timber.d("Start Main") + viewModelScope.launch { + val servers: List + withContext(Dispatchers.IO) { + servers = database.getAllServersSync() + } + if (servers.isEmpty()) { + _navigateToAddServer.value = true + } else { + val serverId = sharedPreferences.getString("selectedServer", null) + val selectedServer = servers.find { server -> server.id == serverId } + Timber.d("Selected server: $selectedServer") + if (selectedServer != null) { + jellyfinApi.apply { + api.baseUrl = selectedServer.address + api.accessToken = selectedServer.accessToken + userId = UUID.fromString(selectedServer.userId) + } + Timber.d("Finish Main") + } + _doneLoading.value = true + } + } + } + + fun doneNavigateToAddServer() { + _navigateToAddServer.value = false + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt index 268646a0..c459f477 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt @@ -1,5 +1,6 @@ package dev.jdtech.jellyfin.viewmodels +import android.content.SharedPreferences import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -18,6 +19,7 @@ import javax.inject.Inject class ServerSelectViewModel @Inject constructor( + private val sharedPreferences: SharedPreferences, private val jellyfinApi: JellyfinApi, private val database: ServerDatabaseDao, ) : ViewModel() { @@ -42,6 +44,10 @@ constructor( } fun connectToServer(server: Server) { + val spEdit = sharedPreferences.edit() + spEdit.putString("selectedServer", server.id) + spEdit.apply() + jellyfinApi.apply { api.baseUrl = server.address api.accessToken = server.accessToken diff --git a/app/src/main/res/layout/activity_setup.xml b/app/src/main/res/layout/activity_setup.xml deleted file mode 100644 index 846d3c56..00000000 --- a/app/src/main/res/layout/activity_setup.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/fragment_initializing.xml b/app/src/main/res/layout/fragment_initializing.xml new file mode 100644 index 00000000..ce899850 --- /dev/null +++ b/app/src/main/res/layout/fragment_initializing.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 854dc67c..246fe4ca 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -2,12 +2,12 @@ diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index 7a2a1246..7211b4a3 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -3,10 +3,10 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_navigation" - app:startDestination="@+id/navigation_home"> + app:startDestination="@+id/initializingFragment"> @@ -29,7 +29,7 @@ app:destination="@id/episodeBottomSheetFragment" /> @@ -54,9 +54,13 @@ + android:label="@string/title_settings" > + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/setup_navigation.xml b/app/src/main/res/navigation/setup_navigation.xml deleted file mode 100644 index 8af205de..00000000 --- a/app/src/main/res/navigation/setup_navigation.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d50289ca..e359f722 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,4 +44,7 @@ Language Preferred audio language Preferred subtitle language + Initializing… + Servers + Switch server \ No newline at end of file diff --git a/app/src/main/res/xml/fragment_settings.xml b/app/src/main/res/xml/fragment_settings.xml index bdef52f9..62ed5ede 100644 --- a/app/src/main/res/xml/fragment_settings.xml +++ b/app/src/main/res/xml/fragment_settings.xml @@ -21,5 +21,12 @@ + + + + + \ No newline at end of file