refactor: get rid of databinding in ServerSelectFragment

This commit is contained in:
jarnedemeulemeester 2023-07-31 17:34:01 +02:00
parent 16d54781b1
commit a4dc94b310
No known key found for this signature in database
GPG key ID: 1E5C6AFBD622E9F5
5 changed files with 88 additions and 82 deletions

View file

@ -7,13 +7,11 @@ import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load import coil.load
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.models.FindroidEpisode import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.FindroidMovie import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.Server
import dev.jdtech.jellyfin.models.User import dev.jdtech.jellyfin.models.User
import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.BaseItemKind
@ -22,12 +20,6 @@ import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID import java.util.UUID
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@BindingAdapter("servers")
fun bindServers(recyclerView: RecyclerView, data: List<Server>?) {
val adapter = recyclerView.adapter as ServerGridAdapter
adapter.submitList(data)
}
@BindingAdapter("items") @BindingAdapter("items")
fun bindItems(recyclerView: RecyclerView, data: List<FindroidItem>?) { fun bindItems(recyclerView: RecyclerView, data: List<FindroidItem>?) {
val adapter = recyclerView.adapter as ViewItemListAdapter val adapter = recyclerView.adapter as ViewItemListAdapter

View file

@ -16,6 +16,7 @@ import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding
import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment
import dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel import dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
@AndroidEntryPoint @AndroidEntryPoint
class ServerSelectFragment : Fragment() { class ServerSelectFragment : Fragment() {
@ -30,10 +31,6 @@ class ServerSelectFragment : Fragment() {
): View { ): View {
binding = FragmentServerSelectBinding.inflate(inflater) binding = FragmentServerSelectBinding.inflate(inflater)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
binding.serversRecyclerView.adapter = binding.serversRecyclerView.adapter =
ServerGridAdapter( ServerGridAdapter(
ServerGridAdapter.OnClickListener { server -> ServerGridAdapter.OnClickListener { server ->
@ -54,9 +51,19 @@ class ServerSelectFragment : Fragment() {
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.navigateToMain.collect { launch {
if (it) { viewModel.uiState.collect { uiState ->
navigateToMainActivity() Timber.d("$uiState")
when (uiState) {
is ServerSelectViewModel.UiState.Normal -> bindUiStateNormal(uiState)
is ServerSelectViewModel.UiState.Loading -> Unit
is ServerSelectViewModel.UiState.Error -> Unit
}
}
}
launch {
viewModel.navigateToMain.collect {
if (it) navigateToMainActivity()
} }
} }
} }
@ -65,6 +72,12 @@ class ServerSelectFragment : Fragment() {
return binding.root return binding.root
} }
private fun bindUiStateNormal(uiState: ServerSelectViewModel.UiState.Normal) {
uiState.apply {
(binding.serversRecyclerView.adapter as ServerGridAdapter).submitList(servers)
}
}
private fun navigateToAddServerFragment() { private fun navigateToAddServerFragment() {
findNavController().navigate( findNavController().navigate(
ServerSelectFragmentDirections.actionServerSelectFragmentToAddServerFragment(), ServerSelectFragmentDirections.actionServerSelectFragmentToAddServerFragment(),

View file

@ -1,75 +1,64 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.AddServerFragment">
<data>
<variable <ImageView
name="viewModel" android:id="@+id/image_banner"
type="dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel" /> android:layout_width="268dp"
</data> android:layout_height="75dp"
android:layout_marginTop="64dp"
android:contentDescription="@string/jellyfin_banner"
android:src="@drawable/ic_banner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
tools:context=".fragments.AddServerFragment"> android:layout_marginHorizontal="12dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_banner"
app:layout_constraintVertical_bias="0.36">
<TextView
<ImageView android:id="@+id/text_add_server"
android:id="@+id/image_banner"
android:layout_width="268dp"
android:layout_height="75dp"
android:layout_marginTop="64dp"
android:contentDescription="@string/jellyfin_banner"
android:src="@drawable/ic_banner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp" android:layout_marginHorizontal="12dp"
android:orientation="vertical" android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent" android:text="@string/select_server"
app:layout_constraintEnd_toEndOf="parent" android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium"
app:layout_constraintStart_toStartOf="parent" android:textColor="?android:textColorPrimary" />
app:layout_constraintTop_toBottomOf="@+id/image_banner"
app:layout_constraintVertical_bias="0.36">
<TextView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/text_add_server" android:id="@+id/servers_recycler_view"
android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium" android:layout_width="match_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginBottom="32dp"
android:text="@string/select_server"
android:textColor="?android:textColorPrimary" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/servers_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:servers="@{viewModel.servers}"
app:spanCount="@integer/server_columns"
tools:itemCount="4"
tools:listitem="@layout/server_item" />
</LinearLayout>
<Button
android:id="@+id/button_add_server"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:orientation="vertical"
android:text="@string/add_server" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintEnd_toEndOf="parent" app:spanCount="@integer/server_columns"
app:layout_constraintStart_toStartOf="parent" tools:itemCount="4"
app:layout_constraintTop_toBottomOf="@+id/main_content" /> tools:listitem="@layout/server_item" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> <Button
</layout> android:id="@+id/button_add_server"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/add_server"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_content" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -9,7 +9,9 @@ import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.Server import dev.jdtech.jellyfin.models.Server
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@ -21,11 +23,25 @@ constructor(
private val database: ServerDatabaseDao, private val database: ServerDatabaseDao,
private val appPreferences: AppPreferences, private val appPreferences: AppPreferences,
) : ViewModel() { ) : ViewModel() {
val servers = database.getAllServers() private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
private val _navigateToMain = MutableSharedFlow<Boolean>() private val _navigateToMain = MutableSharedFlow<Boolean>()
val navigateToMain = _navigateToMain.asSharedFlow() val navigateToMain = _navigateToMain.asSharedFlow()
sealed class UiState {
data class Normal(val servers: List<Server>) : UiState()
data object Loading : UiState()
data class Error(val error: Exception) : UiState()
}
init {
viewModelScope.launch {
val servers = database.getAllServersSync()
_uiState.emit(UiState.Normal(servers))
}
}
/** /**
* Delete server from database * Delete server from database
* *

View file

@ -1,6 +1,5 @@
package dev.jdtech.jellyfin.database package dev.jdtech.jellyfin.database
import androidx.lifecycle.LiveData
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
@ -59,9 +58,6 @@ abstract class ServerDatabaseDao {
@Query("DELETE FROM servers") @Query("DELETE FROM servers")
abstract fun clear() abstract fun clear()
@Query("SELECT * FROM servers")
abstract fun getAllServers(): LiveData<List<Server>>
@Query("SELECT * FROM servers") @Query("SELECT * FROM servers")
abstract fun getAllServersSync(): List<Server> abstract fun getAllServersSync(): List<Server>