Use database executors instead of compose coroutines to launch database operations
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package it.vfsfitvnm.vimusic.ui.screens
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
@@ -39,6 +38,7 @@ import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
||||
import it.vfsfitvnm.vimusic.models.Playlist
|
||||
import it.vfsfitvnm.vimusic.models.SearchQuery
|
||||
import it.vfsfitvnm.vimusic.models.SongWithInfo
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.InFavoritesMediaItemMenu
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu
|
||||
@@ -50,7 +50,6 @@ import it.vfsfitvnm.vimusic.ui.views.PlaylistPreviewItem
|
||||
import it.vfsfitvnm.vimusic.ui.views.SongItem
|
||||
import it.vfsfitvnm.vimusic.utils.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@@ -60,8 +59,6 @@ fun HomeScreen() {
|
||||
val colorPalette = LocalColorPalette.current
|
||||
val typography = LocalTypography.current
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val intentUriRoute = rememberIntentUriRoute()
|
||||
@@ -86,8 +83,6 @@ fun HomeScreen() {
|
||||
}
|
||||
}.collectAsState(initial = emptyList(), context = Dispatchers.IO)
|
||||
|
||||
Log.d("HomeScreen", "songCollection: ${songCollection.size}")
|
||||
|
||||
RouteHandler(
|
||||
listenToGlobalEmitter = true,
|
||||
transitionSpec = {
|
||||
@@ -122,7 +117,7 @@ fun HomeScreen() {
|
||||
onSearch = { query ->
|
||||
searchResultRoute(query)
|
||||
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.insert(SearchQuery(query = query))
|
||||
}
|
||||
},
|
||||
@@ -173,7 +168,7 @@ fun HomeScreen() {
|
||||
isCreatingANewPlaylist = false
|
||||
},
|
||||
onDone = { text ->
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.insert(Playlist(name = text))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.internal
|
||||
import it.vfsfitvnm.vimusic.models.Playlist
|
||||
import it.vfsfitvnm.vimusic.models.SongInPlaylist
|
||||
import it.vfsfitvnm.vimusic.transaction
|
||||
import it.vfsfitvnm.vimusic.ui.components.Error
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.Message
|
||||
@@ -40,7 +40,6 @@ import it.vfsfitvnm.youtubemusic.Outcome
|
||||
import it.vfsfitvnm.youtubemusic.YouTube
|
||||
import it.vfsfitvnm.youtubemusic.toNullable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@@ -70,7 +69,6 @@ fun IntentUriScreen(uri: Uri) {
|
||||
val density = LocalDensity.current
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val shimmer = rememberShimmer(shimmerBounds = ShimmerBounds.Window)
|
||||
|
||||
var items by remember(uri) {
|
||||
@@ -102,24 +100,22 @@ fun IntentUriScreen(uri: Uri) {
|
||||
onDone = { text ->
|
||||
menuState.hide()
|
||||
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
Database.internal.runInTransaction {
|
||||
val playlistId = Database.insert(Playlist(name = text))
|
||||
transaction {
|
||||
val playlistId = Database.insert(Playlist(name = text))
|
||||
|
||||
items.valueOrNull
|
||||
?.map(YouTube.Item.Song::asMediaItem)
|
||||
?.forEachIndexed { index, mediaItem ->
|
||||
Database.insert(mediaItem)
|
||||
items.valueOrNull
|
||||
?.map(YouTube.Item.Song::asMediaItem)
|
||||
?.forEachIndexed { index, mediaItem ->
|
||||
Database.insert(mediaItem)
|
||||
|
||||
Database.insert(
|
||||
SongInPlaylist(
|
||||
songId = mediaItem.mediaId,
|
||||
playlistId = playlistId,
|
||||
position = index
|
||||
)
|
||||
Database.insert(
|
||||
SongInPlaylist(
|
||||
songId = mediaItem.mediaId,
|
||||
playlistId = playlistId,
|
||||
position = index
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -24,8 +24,7 @@ import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.reordering.rememberReorderingState
|
||||
import it.vfsfitvnm.reordering.verticalDragAfterLongPressToReorder
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.*
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.PlaylistWithSongs
|
||||
import it.vfsfitvnm.vimusic.models.SongInPlaylist
|
||||
@@ -39,7 +38,6 @@ import it.vfsfitvnm.vimusic.ui.views.SongItem
|
||||
import it.vfsfitvnm.vimusic.utils.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@@ -84,8 +82,6 @@ fun LocalPlaylistScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val reorderingState = rememberReorderingState(playlistWithSongs.songs)
|
||||
|
||||
var isRenaming by rememberSaveable {
|
||||
@@ -100,7 +96,7 @@ fun LocalPlaylistScreen(
|
||||
isRenaming = false
|
||||
},
|
||||
onDone = { text ->
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.update(playlistWithSongs.playlist.copy(name = text))
|
||||
}
|
||||
}
|
||||
@@ -118,7 +114,7 @@ fun LocalPlaylistScreen(
|
||||
isDeleting = false
|
||||
},
|
||||
onConfirm = {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.delete(playlistWithSongs.playlist)
|
||||
}
|
||||
pop()
|
||||
@@ -290,7 +286,7 @@ fun LocalPlaylistScreen(
|
||||
)
|
||||
},
|
||||
onDragEnd = { reachedIndex ->
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
transaction {
|
||||
if (index > reachedIndex) {
|
||||
Database.incrementSongPositions(
|
||||
playlistId = playlistWithSongs.playlist.id,
|
||||
|
||||
@@ -31,9 +31,9 @@ import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
||||
import it.vfsfitvnm.vimusic.internal
|
||||
import it.vfsfitvnm.vimusic.models.Playlist
|
||||
import it.vfsfitvnm.vimusic.models.SongInPlaylist
|
||||
import it.vfsfitvnm.vimusic.transaction
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.OutcomeItem
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
@@ -45,7 +45,6 @@ import it.vfsfitvnm.vimusic.utils.*
|
||||
import it.vfsfitvnm.youtubemusic.Outcome
|
||||
import it.vfsfitvnm.youtubemusic.YouTube
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
@@ -164,26 +163,24 @@ fun PlaylistOrAlbumScreen(
|
||||
menuState.hide()
|
||||
|
||||
playlistOrAlbum.valueOrNull?.let { album ->
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
Database.internal.runInTransaction {
|
||||
val playlistId =
|
||||
Database.insert(Playlist(name = album.title ?: "Unknown"))
|
||||
transaction {
|
||||
val playlistId =
|
||||
Database.insert(Playlist(name = album.title ?: "Unknown"))
|
||||
|
||||
album.items?.forEachIndexed { index, song ->
|
||||
song
|
||||
.toMediaItem(browseId, album)
|
||||
?.let { mediaItem ->
|
||||
Database.insert(mediaItem)
|
||||
album.items?.forEachIndexed { index, song ->
|
||||
song
|
||||
.toMediaItem(browseId, album)
|
||||
?.let { mediaItem ->
|
||||
Database.insert(mediaItem)
|
||||
|
||||
Database.insert(
|
||||
SongInPlaylist(
|
||||
songId = mediaItem.mediaId,
|
||||
playlistId = playlistId,
|
||||
position = index
|
||||
)
|
||||
Database.insert(
|
||||
SongInPlaylist(
|
||||
songId = mediaItem.mediaId,
|
||||
playlistId = playlistId,
|
||||
position = index
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import androidx.core.net.toUri
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.ui.components.OutcomeItem
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
|
||||
@@ -44,7 +45,6 @@ import it.vfsfitvnm.youtubemusic.YouTube
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
@@ -107,8 +107,6 @@ fun SearchScreen(
|
||||
val colorPalette = LocalColorPalette.current
|
||||
val typography = LocalTypography.current
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val isOpenableUrl = remember(textFieldValue.text) {
|
||||
Regex("""https://(music|www|m)\.youtube.com/(watch|playlist).*""").matches(textFieldValue.text)
|
||||
}
|
||||
@@ -280,7 +278,7 @@ fun SearchScreen(
|
||||
colorFilter = ColorFilter.tint(colorPalette.darkGray),
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.delete(searchQuery)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,11 @@ import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
@@ -18,10 +21,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.*
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.checkpoint
|
||||
import it.vfsfitvnm.vimusic.internal
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
@@ -32,8 +33,6 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
@@ -67,17 +66,15 @@ fun BackupAndRestoreScreen() {
|
||||
val typography = LocalTypography.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val backupLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("application/vnd.sqlite3")) { uri ->
|
||||
if (uri == null) return@rememberLauncherForActivityResult
|
||||
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
Database.checkpoint()
|
||||
query {
|
||||
Database.internal.checkpoint()
|
||||
context.applicationContext.contentResolver.openOutputStream(uri)
|
||||
?.use { outputStream ->
|
||||
FileInputStream(Database.internal.getOpenHelper().writableDatabase.path).use { inputStream ->
|
||||
FileInputStream(Database.internal.path).use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
}
|
||||
@@ -88,10 +85,10 @@ fun BackupAndRestoreScreen() {
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
|
||||
if (uri == null) return@rememberLauncherForActivityResult
|
||||
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
query {
|
||||
Database.internal.close()
|
||||
|
||||
FileOutputStream(Database.internal.getOpenHelper().writableDatabase.path).use { outputStream ->
|
||||
FileOutputStream(Database.internal.path).use { outputStream ->
|
||||
context.applicationContext.contentResolver.openInputStream(uri)
|
||||
?.use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
|
||||
Reference in New Issue
Block a user