Skip to content

Commit

Permalink
Twelve: Run write requests on view lifecycle instead of VM one
Browse files Browse the repository at this point in the history
If the request didn't complete in time the VM gets shutdown

Change-Id: I73f4dfb375f7446781f24f55cbce6664b4fbfa3d
  • Loading branch information
SebaUbuntu committed Nov 5, 2024
1 parent 999cd83 commit 5417d16
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.lineageos.twelve.models.Playlist
import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.dialogs.EditTextMaterialAlertDialogBuilder
import org.lineageos.twelve.ui.recyclerview.SimpleListAdapter
import org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
import org.lineageos.twelve.ui.views.ListItem
import org.lineageos.twelve.utils.PermissionsChecker
import org.lineageos.twelve.utils.PermissionsUtils
Expand All @@ -47,6 +48,7 @@ class AddOrRemoveFromPlaylistsFragment : Fragment(R.layout.fragment_add_or_remov

// Views
private val createNewPlaylistButton by getViewProperty<Button>(R.id.createNewPlaylistButton)
private val fullscreenLoadingProgressBar by getViewProperty<FullscreenLoadingProgressBar>(R.id.fullscreenLoadingProgressBar)
private val linearProgressIndicator by getViewProperty<LinearProgressIndicator>(R.id.linearProgressIndicator)
private val noElementsLinearLayout by getViewProperty<LinearLayout>(R.id.noElementsLinearLayout)
private val recyclerView by getViewProperty<RecyclerView>(R.id.recyclerView)
Expand All @@ -64,9 +66,13 @@ class AddOrRemoveFromPlaylistsFragment : Fragment(R.layout.fragment_add_or_remov
item?.let {
when (it === addNewPlaylistItem) {
true -> openCreateNewPlaylistDialog()
false -> when (it.second) {
true -> viewModel.removeFromPlaylist(it.first.uri)
false -> viewModel.addToPlaylist(it.first.uri)
false -> viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
when (it.second) {
true -> viewModel.removeFromPlaylist(it.first.uri)
false -> viewModel.addToPlaylist(it.first.uri)
}
}
}
}
}
Expand Down Expand Up @@ -175,7 +181,11 @@ class AddOrRemoveFromPlaylistsFragment : Fragment(R.layout.fragment_add_or_remov
private fun openCreateNewPlaylistDialog() {
EditTextMaterialAlertDialogBuilder(requireContext())
.setPositiveButton(R.string.create_playlist_confirm) { text ->
viewModel.createPlaylist(text)
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.createPlaylist(text)
}
}
}
.setTitle(R.string.create_playlist)
.setNegativeButton(android.R.string.cancel, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getParcelable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
import org.lineageos.twelve.ui.views.ListItem
import org.lineageos.twelve.utils.PermissionsChecker
import org.lineageos.twelve.utils.PermissionsUtils
Expand All @@ -43,6 +44,7 @@ class AudioBottomSheetDialogFragment : BottomSheetDialogFragment(
private val addToQueueListItem by getViewProperty<ListItem>(R.id.addToQueueListItem)
private val artistNameTextView by getViewProperty<TextView>(R.id.artistNameTextView)
private val albumTitleTextView by getViewProperty<TextView>(R.id.albumTitleTextView)
private val fullscreenLoadingProgressBar by getViewProperty<FullscreenLoadingProgressBar>(R.id.fullscreenLoadingProgressBar)
private val openAlbumListItem by getViewProperty<ListItem>(R.id.openAlbumListItem)
private val openArtistListItem by getViewProperty<ListItem>(R.id.openArtistListItem)
private val playNextListItem by getViewProperty<ListItem>(R.id.playNextListItem)
Expand All @@ -69,11 +71,15 @@ class AudioBottomSheetDialogFragment : BottomSheetDialogFragment(

removeFromPlaylistListItem.isVisible = playlistUri != null
removeFromPlaylistListItem.setOnClickListener {
playlistUri?.let {
viewModel.removeFromPlaylist(it)
}
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
playlistUri?.let {
viewModel.removeFromPlaylist(it)

findNavController().navigateUp()
findNavController().navigateUp()
}
}
}
}

addOrRemoveFromPlaylistsListItem.setOnClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import org.lineageos.twelve.models.ProviderArgument.Companion.validateArgument
import org.lineageos.twelve.models.ProviderType
import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.recyclerview.SimpleListAdapter
import org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
import org.lineageos.twelve.viewmodels.ManageProviderViewModel

/**
Expand All @@ -51,6 +52,7 @@ class ManageProviderFragment : Fragment(R.layout.fragment_manage_provider) {
private val argumentsRecyclerView by getViewProperty<RecyclerView>(R.id.argumentsRecyclerView)
private val confirmMaterialButton by getViewProperty<MaterialButton>(R.id.confirmMaterialButton)
private val deleteMaterialButton by getViewProperty<MaterialButton>(R.id.deleteMaterialButton)
private val fullscreenLoadingProgressBar by getViewProperty<FullscreenLoadingProgressBar>(R.id.fullscreenLoadingProgressBar)
private val providerNameTextInputLayout by getViewProperty<TextInputLayout>(R.id.providerNameTextInputLayout)
private val providerTypeAutoCompleteTextView by getViewProperty<MaterialAutoCompleteTextView>(R.id.providerTypeAutoCompleteTextView)
private val providerTypeTextInputLayout by getViewProperty<TextInputLayout>(R.id.providerTypeTextInputLayout)
Expand Down Expand Up @@ -181,13 +183,17 @@ class ManageProviderFragment : Fragment(R.layout.fragment_manage_provider) {
return@setOnClickListener
}

if (viewModel.inEditMode.value) {
viewModel.updateProvider(name, providerArguments)
} else {
viewModel.addProvider(providerType, name, providerArguments)
}
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
if (viewModel.inEditMode.value) {
viewModel.updateProvider(name, providerArguments)
} else {
viewModel.addProvider(providerType, name, providerArguments)
}

findNavController().navigateUp()
findNavController().navigateUp()
}
}
}

deleteMaterialButton.setOnClickListener {
Expand Down Expand Up @@ -331,7 +337,11 @@ class ManageProviderFragment : Fragment(R.layout.fragment_manage_provider) {
MaterialAlertDialogBuilder(requireContext())
.setMessage(R.string.delete_provider_confirmation)
.setPositiveButton(android.R.string.ok) { _, _ ->
viewModel.deleteProvider()
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.deleteProvider()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
// Do nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.dialogs.EditTextMaterialAlertDialogBuilder
import org.lineageos.twelve.ui.recyclerview.SimpleListAdapter
import org.lineageos.twelve.ui.recyclerview.UniqueItemDiffCallback
import org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
import org.lineageos.twelve.ui.views.ListItem
import org.lineageos.twelve.utils.PermissionsChecker
import org.lineageos.twelve.utils.PermissionsUtils
Expand All @@ -55,6 +56,7 @@ class PlaylistFragment : Fragment(R.layout.fragment_playlist) {
private val viewModel by viewModels<PlaylistViewModel>()

// Views
private val fullscreenLoadingProgressBar by getViewProperty<FullscreenLoadingProgressBar>(R.id.fullscreenLoadingProgressBar)
private val infoNestedScrollView by getViewProperty<NestedScrollView?>(R.id.infoNestedScrollView)
private val linearProgressIndicator by getViewProperty<LinearProgressIndicator>(R.id.linearProgressIndicator)
private val noElementsNestedScrollView by getViewProperty<NestedScrollView>(R.id.noElementsNestedScrollView)
Expand Down Expand Up @@ -291,7 +293,11 @@ class PlaylistFragment : Fragment(R.layout.fragment_playlist) {
EditTextMaterialAlertDialogBuilder(requireContext())
.setText(toolbar.title.toString())
.setPositiveButton(R.string.rename_playlist_positive) { text ->
viewModel.renamePlaylist(text)
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.renamePlaylist(text)
}
}
}
.setTitle(R.string.rename_playlist)
.setNegativeButton(android.R.string.cancel, null)
Expand All @@ -303,7 +309,11 @@ class PlaylistFragment : Fragment(R.layout.fragment_playlist) {
.setTitle(R.string.delete_playlist)
.setMessage(R.string.delete_playlist_message)
.setPositiveButton(android.R.string.ok) { _, _ ->
viewModel.deletePlaylist()
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.deletePlaylist()
}
}
}
.setNegativeButton(android.R.string.cancel, null)
.show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.dialogs.EditTextMaterialAlertDialogBuilder
import org.lineageos.twelve.ui.recyclerview.SimpleListAdapter
import org.lineageos.twelve.ui.recyclerview.UniqueItemDiffCallback
import org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
import org.lineageos.twelve.ui.views.ListItem
import org.lineageos.twelve.utils.PermissionsChecker
import org.lineageos.twelve.utils.PermissionsUtils
Expand All @@ -44,6 +45,7 @@ class PlaylistsFragment : Fragment(R.layout.fragment_playlists) {

// Views
private val createNewPlaylistButton by getViewProperty<Button>(R.id.createNewPlaylistButton)
private val fullscreenLoadingProgressBar by getViewProperty<FullscreenLoadingProgressBar>(R.id.fullscreenLoadingProgressBar)
private val linearProgressIndicator by getViewProperty<LinearProgressIndicator>(R.id.linearProgressIndicator)
private val noElementsLinearLayout by getViewProperty<LinearLayout>(R.id.noElementsLinearLayout)
private val recyclerView by getViewProperty<RecyclerView>(R.id.recyclerView)
Expand Down Expand Up @@ -153,7 +155,11 @@ class PlaylistsFragment : Fragment(R.layout.fragment_playlists) {
private fun openCreateNewPlaylistDialog() {
EditTextMaterialAlertDialogBuilder(requireContext())
.setPositiveButton(R.string.create_playlist_confirm) { text ->
viewModel.createPlaylist(text)
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.createPlaylist(text)
}
}
}
.setTitle(R.string.create_playlist)
.setNegativeButton(android.R.string.cancel, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.lineageos.twelve.models.RequestStatus

class AddOrRemoveFromPlaylistsViewModel(application: Application) : AudioViewModel(application) {
Expand All @@ -34,10 +35,12 @@ class AddOrRemoveFromPlaylistsViewModel(application: Application) : AudioViewMod
/**
* Create a new playlist in the same provider as the audio.
*/
fun createPlaylist(name: String) = viewModelScope.launch {
audioUri.value?.let {
mediaRepository.getProviderOfMediaItems(it)?.let { provider ->
mediaRepository.createPlaylist(provider, name)
suspend fun createPlaylist(name: String) {
withContext(Dispatchers.IO) {
audioUri.value?.let {
mediaRepository.getProviderOfMediaItems(it)?.let { provider ->
mediaRepository.createPlaylist(provider, name)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.lineageos.twelve.models.Audio
import org.lineageos.twelve.models.RequestStatus

Expand All @@ -40,11 +41,11 @@ open class AudioViewModel(application: Application) : TwelveViewModel(applicatio
this.audioUri.value = audioUri
}

fun addToQueue(audio: Audio) = viewModelScope.launch {
fun addToQueue(audio: Audio) {
mediaController.value?.addMediaItem(audio.toMedia3MediaItem())
}

fun playNext(audio: Audio) = viewModelScope.launch {
fun playNext(audio: Audio) {
mediaController.value?.let { controller ->
controller.addMediaItem(
controller.currentMediaItemIndex + 1,
Expand All @@ -53,15 +54,19 @@ open class AudioViewModel(application: Application) : TwelveViewModel(applicatio
}
}

fun addToPlaylist(playlistUri: Uri) = viewModelScope.launch {
suspend fun addToPlaylist(playlistUri: Uri) {
audioUri.value?.let {
mediaRepository.addAudioToPlaylist(playlistUri, it)
withContext(Dispatchers.IO) {
mediaRepository.addAudioToPlaylist(playlistUri, it)
}
}
}

fun removeFromPlaylist(playlistUri: Uri) = viewModelScope.launch {
suspend fun removeFromPlaylist(playlistUri: Uri) {
audioUri.value?.let {
mediaRepository.removeAudioFromPlaylist(playlistUri, it)
withContext(Dispatchers.IO) {
mediaRepository.removeAudioFromPlaylist(playlistUri, it)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.models.ProviderType
import org.lineageos.twelve.models.RequestStatus
Expand Down Expand Up @@ -137,27 +138,33 @@ class ManageProviderViewModel(application: Application) : ProvidersViewModel(app
/**
* Add a new provider.
*/
fun addProvider(
suspend fun addProvider(
providerType: ProviderType, name: String, arguments: Bundle
) = viewModelScope.launch {
mediaRepository.addProvider(providerType, name, arguments)
) {
withContext(Dispatchers.IO) {
mediaRepository.addProvider(providerType, name, arguments)
}
}

/**
* Update the provider.
*/
fun updateProvider(name: String, arguments: Bundle) = viewModelScope.launch {
val (providerType, providerTypeId) = providerIds.value ?: return@launch
suspend fun updateProvider(name: String, arguments: Bundle) {
val (providerType, providerTypeId) = providerIds.value ?: return

mediaRepository.updateProvider(providerType, providerTypeId, name, arguments)
withContext(Dispatchers.IO) {
mediaRepository.updateProvider(providerType, providerTypeId, name, arguments)
}
}

/**
* Delete the provider.
*/
fun deleteProvider() = viewModelScope.launch {
val (providerType, providerTypeId) = providerIds.value ?: return@launch
suspend fun deleteProvider() {
val (providerType, providerTypeId) = providerIds.value ?: return

mediaRepository.deleteProvider(providerType, providerTypeId)
withContext(Dispatchers.IO) {
mediaRepository.deleteProvider(providerType, providerTypeId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.lineageos.twelve.models.RequestStatus

class PlaylistViewModel(application: Application) : TwelveViewModel(application) {
Expand All @@ -39,15 +40,19 @@ class PlaylistViewModel(application: Application) : TwelveViewModel(application)
this.playlistUri.value = playlistUri
}

fun renamePlaylist(name: String) = viewModelScope.launch {
suspend fun renamePlaylist(name: String) {
playlistUri.value?.let { playlistUri ->
mediaRepository.renamePlaylist(playlistUri, name)
withContext(Dispatchers.IO) {
mediaRepository.renamePlaylist(playlistUri, name)
}
}
}

fun deletePlaylist() = viewModelScope.launch {
suspend fun deletePlaylist() {
playlistUri.value?.let { playlistUri ->
mediaRepository.deletePlaylist(playlistUri)
withContext(Dispatchers.IO) {
mediaRepository.deletePlaylist(playlistUri)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.lineageos.twelve.models.RequestStatus

class PlaylistsViewModel(application: Application) : TwelveViewModel(application) {
Expand All @@ -23,7 +23,9 @@ class PlaylistsViewModel(application: Application) : TwelveViewModel(application
RequestStatus.Loading()
)

fun createPlaylist(name: String) = viewModelScope.launch {
mediaRepository.createPlaylist(mediaRepository.navigationProvider.value, name)
suspend fun createPlaylist(name: String) {
withContext(Dispatchers.IO) {
mediaRepository.createPlaylist(mediaRepository.navigationProvider.value, name)
}
}
}
7 changes: 7 additions & 0 deletions app/src/main/res/layout-land/fragment_playlist.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,11 @@

</FrameLayout>

<org.lineageos.twelve.ui.views.FullscreenLoadingProgressBar
android:id="@+id/fullscreenLoadingProgressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:visibility="gone" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
Loading

0 comments on commit 5417d16

Please sign in to comment.