diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 1abfa90..0a31caf 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -12,6 +12,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 6acc884..e469532 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.lighttigerxiv.simple.mp" minSdk 26 targetSdk 33 - versionCode 15 - versionName "BETA-1.6.3" + versionCode 16 + versionName "BETA-1.6.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/release/app-release.apk b/app/release/SimpleMP-BETA-1.6.4.apk similarity index 94% rename from app/release/app-release.apk rename to app/release/SimpleMP-BETA-1.6.4.apk index 4257454..8b0eb8c 100644 Binary files a/app/release/app-release.apk and b/app/release/SimpleMP-BETA-1.6.4.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 775ace2..d48af47 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 15, - "versionName": "BETA-1.6.3", + "versionCode": 16, + "versionName": "BETA-1.6.4", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/ActivityMain.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/ActivityMain.kt index 5f54606..d3838e8 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/ActivityMain.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/ActivityMain.kt @@ -16,15 +16,19 @@ import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext @@ -38,6 +42,7 @@ import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.activities.setup.ActivitySetup import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.Routes +import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.functions.getSurfaceColor @@ -58,7 +63,9 @@ import com.lighttigerxiv.simple.mp.compose.screens.main.settings.SettingsScreen import com.lighttigerxiv.simple.mp.compose.screens.main.settings.SettingsScreenVM import com.lighttigerxiv.simple.mp.compose.screens.main.settings.themes.ThemesScreen import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer import com.lighttigerxiv.simple.mp.compose.ui.theme.ComposeSimpleMPTheme import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking @@ -102,6 +109,8 @@ class MainActivity : ComponentActivity() { val rootNavController = rememberNavController() val loadingSongs = vm.loadingSongs.collectAsState().value + val songCount = vm.songCount.collectAsState().value + val indexedSongsCount = vm.indexedSongsCount.collectAsState().value val context = LocalContext.current @@ -110,7 +119,7 @@ class MainActivity : ComponentActivity() { .fillMaxSize() .background(vm.surfaceColor.collectAsState().value) ) { - if(loadingSongs){ + if (loadingSongs) { rememberSystemUiController().setStatusBarColor(vm.surfaceColor.collectAsState().value) @@ -127,21 +136,48 @@ class MainActivity : ComponentActivity() { modifier = Modifier .width(200.dp) .height(200.dp), - bitmap = remember{ getImage(context,R.drawable.play_empty, ImageSizes.LARGE).asImageBitmap() }, + bitmap = remember { getImage(context, R.drawable.play_empty, ImageSizes.LARGE).asImageBitmap() }, contentDescription = null, colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary) ) - SmallHeightSpacer() + SmallVerticalSpacer() - LinearProgressIndicator( - modifier = Modifier.width(200.dp), - color = MaterialTheme.colorScheme.primary, - trackColor = MaterialTheme.colorScheme.surfaceVariant - ) + Row( + modifier = Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.surfaceVariant) + .padding(SMALL_SPACING), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + + if(indexedSongsCount != songCount){ + CustomText(text = indexedSongsCount.toString()) + + SmallHorizontalSpacer() + + LinearProgressIndicator( + modifier = Modifier.width(120.dp), + color = MaterialTheme.colorScheme.primary, + trackColor = MaterialTheme.colorScheme.surfaceVariant + ) + + SmallHorizontalSpacer() + + CustomText(text = songCount.toString()) + } else{ + + LinearProgressIndicator( + modifier = Modifier.width(200.dp), + color = MaterialTheme.colorScheme.primary, + trackColor = MaterialTheme.colorScheme.surfaceVariant + ) + } + } } - } else{ + } else { NavHost( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/MainVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/MainVM.kt index 4b6a54e..eeda10c 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/MainVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/activities/main/MainVM.kt @@ -6,8 +6,13 @@ import android.appwidget.AppWidgetManager import android.content.* import android.content.res.Configuration import android.graphics.Bitmap +import android.media.MediaMetadataRetriever +import android.net.Uri +import android.os.Build import android.os.IBinder +import android.provider.MediaStore import android.util.Log +import android.util.Size import androidx.compose.material.BottomSheetState import androidx.compose.material.BottomSheetValue import androidx.compose.material.ExperimentalMaterialApi @@ -16,11 +21,12 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.lighttigerxiv.simple.mp.compose.* +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Album +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Artist import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song -import com.lighttigerxiv.simple.mp.compose.data.data_classes.SongCover -import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts -import com.lighttigerxiv.simple.mp.compose.functions.getAllAlbumsImages -import com.lighttigerxiv.simple.mp.compose.functions.getSongs +import com.lighttigerxiv.simple.mp.compose.data.data_classes.SongsData +import com.lighttigerxiv.simple.mp.compose.data.mongodb.getMongoRealm +import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.CacheQueries import com.lighttigerxiv.simple.mp.compose.services.SimpleMPService import com.lighttigerxiv.simple.mp.compose.widgets.SimpleMPWidget import kotlinx.coroutines.Dispatchers @@ -31,7 +37,9 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.burnoutcrew.reorderable.ItemPosition +import java.io.File import java.util.* +import kotlin.collections.ArrayList class MainVM(application: Application) : AndroidViewModel(application) { @@ -42,9 +50,13 @@ class MainVM(application: Application) : AndroidViewModel(application) { private val context = application + private val mainVM = this + private val _loadingSongs = MutableStateFlow(true) val loadingSongs = _loadingSongs.asStateFlow() + private val cachedQueries = CacheQueries(getMongoRealm()) + @SuppressLint("StaticFieldLeak") private var smpService: SimpleMPService? = null @@ -55,15 +67,14 @@ class MainVM(application: Application) : AndroidViewModel(application) { _surfaceColor.update { newValue } } + private val _songsData = MutableStateFlow(null) + val songsData = _songsData.asStateFlow() - private val _songs = MutableStateFlow?>(null) - val songs = _songs.asStateFlow() - - private val _songsCovers = MutableStateFlow?>(null) - val songsCovers = _songsCovers.asStateFlow() + private val _songCount = MutableStateFlow(0) + val songCount = _songCount.asStateFlow() - private val _compressedSongsCovers = MutableStateFlow?>(null) - val compressedSongsCovers = _compressedSongsCovers.asStateFlow() + private val _indexedSongsCount = MutableStateFlow(0) + val indexedSongsCount = _indexedSongsCount.asStateFlow() private val _queue = MutableStateFlow?>(null) val queue = _queue.asStateFlow() @@ -129,7 +140,7 @@ class MainVM(application: Application) : AndroidViewModel(application) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { viewModelScope.launch { - withContext(Dispatchers.IO){ + withContext(Dispatchers.IO) { delay(1) @@ -138,37 +149,24 @@ class MainVM(application: Application) : AndroidViewModel(application) { smpService?.let { smp -> + smp.mainVM = mainVM _musicPlaying.update { smp.musicPlaying() } - _queueShuffled.update { smp.queueShuffled } - _songOnRepeat.update { smp.songOnRepeat } - - _songs.update { getSongs(context, Sorts.RECENT) } - - _songsCovers.update { getAllAlbumsImages(songs.value, context) } - - _compressedSongsCovers.update { getAllAlbumsImages(songs.value, context, compressed = true) } - + getSongsData() if (smp.isMusicPlayingOrPaused()) { _selectedSong.update { smp.currentSong } - - _songAlbumArt.update { getAlbumArt() } - + _songAlbumArt.update { getAlbumArt(songsData.value!!.songs, currentSong.value!!.albumID) } _songSeconds.update { (smp.mediaPlayer.currentPosition / 1000).toFloat() } - _songMinutesAndSecondsText.update { getMinutesAndSeconds(currentSong.value!!.duration / 1000) } - _currentSongMinutesAndSecondsText.update { getMinutesAndSeconds(smp.mediaPlayer.currentPosition / 1000) } updateMiniPlayerPeekHeight() _queue.update { smp.getQueue() } - _upNextQueue.update { smp.getUpNextQueue() } - _songPosition.update { smp.currentSongPosition } onSongSelected() @@ -178,21 +176,15 @@ class MainVM(application: Application) : AndroidViewModel(application) { smp.onSongSelected = { song -> _selectedSong.update { song } - _songSeconds.update { (smp.mediaPlayer.currentPosition / 1000).toFloat() } - _songMinutesAndSecondsText.update { getMinutesAndSeconds(currentSong.value!!.duration / 1000) } - - _songAlbumArt.update { getAlbumArt() } - + _songAlbumArt.update { getAlbumArt(songsData.value!!.songs, song.albumID) } _songOnRepeat.update { smp.songOnRepeat } updateMiniPlayerPeekHeight() _queue.update { smp.getQueue() } - _upNextQueue.update { smp.getUpNextQueue() } - _songPosition.update { smp.currentSongPosition } onSongSelected() @@ -209,11 +201,8 @@ class MainVM(application: Application) : AndroidViewModel(application) { smp.onQueueShuffle = { _queueShuffled.update { smp.queueShuffled } - _queue.update { smp.getQueue() } - _upNextQueue.update { smp.getUpNextQueue() } - _songPosition.update { smp.currentSongPosition } } @@ -221,7 +210,6 @@ class MainVM(application: Application) : AndroidViewModel(application) { smp.onPause = { _musicPlaying.update { smp.musicPlaying() } - updateWidget() } @@ -229,9 +217,7 @@ class MainVM(application: Application) : AndroidViewModel(application) { smp.onResume = { _musicPlaying.update { smp.musicPlaying() } - _songPosition.update { smp.currentSongPosition } - updateWidget() } @@ -243,9 +229,7 @@ class MainVM(application: Application) : AndroidViewModel(application) { smp.onStop = { _selectedSong.update { null } - updateMiniPlayerPeekHeight() - onFinish() } @@ -261,6 +245,252 @@ class MainVM(application: Application) : AndroidViewModel(application) { } } + @SuppressLint("Range") + suspend fun getSongsData() { + + val songs = ArrayList() + val cachedSongs = cachedQueries.getSongs() + val artists = ArrayList() + val cachedArtists = cachedQueries.getArtists() + val albums = ArrayList() + val cachedAlbums = cachedQueries.getAlbums() + + + //Shows Cached Data if it exists + if (cachedSongs.isNotEmpty() && cachedAlbums.isNotEmpty() && cachedArtists.isNotEmpty()) { + + _songCount.update { cachedSongs.size } + + cachedSongs.forEach { cachedSong -> + + songs.add( + Song( + id = cachedSong.id, + path = cachedSong.path, + title = cachedSong.title, + albumID = cachedSong.albumID, + duration = cachedSong.duration, + artistID = cachedSong.artistID, + year = cachedSong.year, + genre = cachedSong.genre, + modificationDate = cachedSong.modificationDate + ) + ) + + _indexedSongsCount.update { indexedSongsCount.value + 1 } + } + + cachedArtists.forEach { cachedArtist -> + artists.add( + Artist( + id = cachedArtist.id, + name = cachedArtist.name, + cover = null + ) + ) + } + + cachedAlbums.forEach { cachedAlbum -> + albums.add( + Album( + id = cachedAlbum.id, + title = cachedAlbum.title, + art = null, + artistID = cachedAlbum.artistID + ) + ) + } + + _songsData.update { + SongsData( + songs, + artists, + albums + ) + } + + val newAlbums = ArrayList() + + albums.forEach { album -> + + val newAlbum = album.copy(art = getAlbumArt(songs, album.id)) + newAlbums.add(newAlbum) + } + + _songsData.update { + SongsData( + songs, + artists, + newAlbums + ) + } + + _indexedSongsCount.update { 0 } + _songCount.update { 0 } + + } else { + + //Gets all songs from the device + indexSongs() + } + } + + @SuppressLint("Range") + suspend fun indexSongs(onFinish: () -> Unit = {}) { + + _indexedSongsCount.update { 0 } + cachedQueries.clear() + + + val songs = ArrayList() + val artists = ArrayList() + val albums = ArrayList() + val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + var cursor = context.contentResolver.query(uri, null, null, null, null) + var count = 0 + + if (cursor != null) { + while (cursor.moveToNext()) { + count += 1 + } + } + + cursor?.close() + + _songCount.update { count } + + cursor = context.contentResolver.query(uri, null, null, null, null) + + if (cursor != null) { + while (cursor.moveToNext()) { + + try { + + val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)) + val songPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)) + + val retriever = MediaMetadataRetriever() + retriever.setDataSource(songPath) + + var title = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + var albumTitle = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) + val albumID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)) + var duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) + var artistName = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST) + val artistID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID)) + var genre = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE) + val modificationDate = File(songPath).lastModified() + + + if (title == null) { + title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)) + } + + if (albumTitle == null) { + albumTitle = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM)) + } + + if (duration == null) { + duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)) + } + + if (artistName == null) { + artistName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Artists.ARTIST)) + } + + if (!artists.any { it.id == artistID }) { + + val artist = Artist( + artistID, + artistName ?: "", + null + ) + + artists.add(artist) + + cachedQueries.addArtist(artist) + } + + if (!albums.any { it.id == albumID }) { + + val album = Album( + albumID, + albumTitle ?: "", + null, + artistID + ) + + albums.add(album) + + cachedQueries.addAlbum(album) + } + + + if (genre == null) genre = context.getString(R.string.Undefined) + val year = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.YEAR)) + + + + if (title != null && duration != null) { + + val song = Song(id, songPath, title, albumID, duration.toInt(), artistID, year, genre, modificationDate) + val filterDuration = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE).getString("FilterAudio", "60")!!.toInt() * 1000 + if (duration.toInt() > filterDuration) songs.add(song) + + cachedQueries.addSong(song) + + _indexedSongsCount.update { indexedSongsCount.value + 1 } + } + + } catch (e: Exception) { + Log.e("Song Error", "Exception while getting song. Details -> ${e.message}") + } + } + } + + cursor?.close() + + _songsData.update { + SongsData( + songs, + artists, + albums + ) + } + + //Gets Albums Images + val newAlbums = ArrayList() + + albums.forEach { album -> + + val newAlbum = album.copy(art = getAlbumArt(songs, album.id)) + newAlbums.add(newAlbum) + } + + _songsData.update { + SongsData( + songs, + artists, + newAlbums + ) + } + + onFinish() + + _indexedSongsCount.update { 0 } + _songCount.update { 0 } + } + + fun getSongArt(song: Song): Bitmap? { + + return songsData.value?.albums?.first { it.id == song.albumID }?.art + } + + fun getSongArtist(song: Song): Artist { + + return songsData.value!!.artists.first { it.id == song.artistID } + } + private fun updateWidget() { val intent = Intent(context, SimpleMPWidget::class.java).apply { action = AppWidgetManager.ACTION_APPWIDGET_UPDATE @@ -290,17 +520,35 @@ class MainVM(application: Application) : AndroidViewModel(application) { return "$minutes:$stringSeconds" } - private fun getAlbumArt(compressed: Boolean = false): Bitmap? { + private fun loadSongsCover() { - return when (compressed) { + songsData.value?.songs?.forEach { song -> + Log.d("Song ID", song.id.toString()) + } + } - true -> { - compressedSongsCovers.value?.first { it.albumID == currentSong.value?.albumID }?.albumArt - } + private fun getAlbumArt(songs: List, id: Long): Bitmap? { + + val songWithAlbumID = songs.first { it.albumID == id }.id - false -> { - songsCovers.value?.first { it.albumID == currentSong.value?.albumID }?.albumArt + return try { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + + val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + val songWithAlbumUri = ContentUris.withAppendedId(uri, songWithAlbumID) + + context.contentResolver.loadThumbnail(songWithAlbumUri, Size(400, 400), null) + } else { + + val sArtWorkUri = Uri.parse("content://media/external/audio/albumart") + val albumArtUri = ContentUris.withAppendedId(sArtWorkUri, id) + + MediaStore.Images.Media.getBitmap(context.contentResolver, albumArtUri) } + + } catch (e: Exception) { + null } } @@ -333,21 +581,21 @@ class MainVM(application: Application) : AndroidViewModel(application) { } } - fun updateMiniPlayerPeekHeight(){ + fun updateMiniPlayerPeekHeight() { val isPortrait = context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT - smpService?.let{ - if(isPortrait && !smpService!!.isMusicPlayingOrPaused()){ + smpService?.let { + if (isPortrait && !smpService!!.isMusicPlayingOrPaused()) { _miniPlayerPeekHeight.update { 55.dp } } - if(isPortrait && smpService!!.isMusicPlayingOrPaused()){ + if (isPortrait && smpService!!.isMusicPlayingOrPaused()) { _miniPlayerPeekHeight.update { 115.dp } } - if(!isPortrait && !smpService!!.isMusicPlayingOrPaused()){ + if (!isPortrait && !smpService!!.isMusicPlayingOrPaused()) { _miniPlayerPeekHeight.update { 0.dp } } - if(!isPortrait && smpService!!.isMusicPlayingOrPaused()){ + if (!isPortrait && smpService!!.isMusicPlayingOrPaused()) { _miniPlayerPeekHeight.update { 55.dp } } } @@ -369,7 +617,7 @@ class MainVM(application: Application) : AndroidViewModel(application) { _songMinutesAndSecondsText.update { getMinutesAndSeconds(currentSong.value!!.duration / 1000) } - _songAlbumArt.update { getAlbumArt() } + _songAlbumArt.update { getAlbumArt(songsData.value!!.songs, currentSong.value!!.albumID) } _queue.update { smp.getQueue() } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Album.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Album.kt new file mode 100644 index 0000000..ced1495 --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Album.kt @@ -0,0 +1,10 @@ +package com.lighttigerxiv.simple.mp.compose.data.data_classes + +import android.graphics.Bitmap + +data class Album( + val id: Long, + val title: String, + val art: Bitmap?, + val artistID: Long +) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Artist.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Artist.kt new file mode 100644 index 0000000..f8c3bb3 --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Artist.kt @@ -0,0 +1,9 @@ +package com.lighttigerxiv.simple.mp.compose.data.data_classes + +import android.graphics.Bitmap + +data class Artist( + val id: Long, + val name: String, + val cover: Bitmap? +) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Song.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Song.kt index 5785099..f2c3b0c 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Song.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/Song.kt @@ -5,10 +5,8 @@ data class Song( val id: Long, var path: String, val title: String, - val album: String, val albumID: Long, val duration: Int, - val artist: String, val artistID: Long, val year: Int, val genre: String, diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/SongsData.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/SongsData.kt new file mode 100644 index 0000000..1dc7b94 --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/data_classes/SongsData.kt @@ -0,0 +1,7 @@ +package com.lighttigerxiv.simple.mp.compose.data.data_classes + +data class SongsData( + val songs: List, + val artists: List, + val albums: List +) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/MongoRealm.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/MongoRealm.kt index 3f39eff..5e55aaf 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/MongoRealm.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/MongoRealm.kt @@ -1,6 +1,9 @@ package com.lighttigerxiv.simple.mp.compose.data.mongodb import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.Artist +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedAlbum +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedArtist +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedSong import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.Playlist import io.realm.kotlin.Realm import io.realm.kotlin.RealmConfiguration @@ -10,10 +13,13 @@ fun getMongoRealm(): Realm{ val config = RealmConfiguration.Builder( schema = setOf( Playlist::class, - Artist::class + Artist::class, + CachedAlbum::class, + CachedArtist::class, + CachedSong::class ) ) - .schemaVersion(7) + .schemaVersion(9) .compactOnLaunch() .build() diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedAlbum.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedAlbum.kt new file mode 100644 index 0000000..ae94fbb --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedAlbum.kt @@ -0,0 +1,11 @@ +package com.lighttigerxiv.simple.mp.compose.data.mongodb.items + +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey + +class CachedAlbum: RealmObject { + @PrimaryKey + var id: Long = 0 + var title: String = "" + var artistID: Long = 0 +} \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedArtist.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedArtist.kt new file mode 100644 index 0000000..6bf4c6d --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedArtist.kt @@ -0,0 +1,10 @@ +package com.lighttigerxiv.simple.mp.compose.data.mongodb.items + +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey + +class CachedArtist : RealmObject { + @PrimaryKey + var id: Long = 0 + var name: String = "" +} \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedSong.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedSong.kt new file mode 100644 index 0000000..dc939bc --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/items/CachedSong.kt @@ -0,0 +1,17 @@ +package com.lighttigerxiv.simple.mp.compose.data.mongodb.items + +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey + +class CachedSong : RealmObject { + @PrimaryKey + var id: Long = 0 + var path: String = "" + var title: String = "" + var albumID: Long = 0 + var duration: Int = 0 + var artistID: Long = 0 + var year: Int = 0 + var genre: String = "" + var modificationDate: Long = 0 +} \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsQueries.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsCoversQueries.kt similarity index 97% rename from app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsQueries.kt rename to app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsCoversQueries.kt index 2a0522c..1c28ca8 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsQueries.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/ArtistsCoversQueries.kt @@ -4,7 +4,7 @@ import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.Artist import io.realm.kotlin.Realm import io.realm.kotlin.ext.query -class ArtistsQueries( +class ArtistsCoversQueries( private val realm: Realm ) { diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/CacheQueries.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/CacheQueries.kt new file mode 100644 index 0000000..4d1e1e9 --- /dev/null +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/CacheQueries.kt @@ -0,0 +1,80 @@ +package com.lighttigerxiv.simple.mp.compose.data.mongodb.queries + +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Album +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Artist +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedAlbum +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedArtist +import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.CachedSong +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query + +class CacheQueries( + private val realm: Realm +) { + + fun getSongs(): List{ + return realm.query().find() + } + + fun getArtists(): List{ + return realm.query().find() + } + + fun getAlbums(): List{ + return realm.query().find() + } + + fun addSong(song: Song){ + + val cachedSong = CachedSong() + cachedSong.id = song.id + cachedSong.path = song.path + cachedSong.title = song.title + cachedSong.albumID = song.albumID + cachedSong.duration = song.duration + cachedSong.artistID = song.artistID + cachedSong.year = song.year + cachedSong.genre = song.genre + cachedSong.modificationDate = song.modificationDate + + realm.writeBlocking { + this.copyToRealm(cachedSong) + } + } + + fun addArtist(artist: Artist){ + + val cachedArtist = CachedArtist() + cachedArtist.id = artist.id + cachedArtist.name = artist.name + + realm.writeBlocking { + this.copyToRealm(cachedArtist) + } + } + + fun addAlbum(album: Album){ + + val cachedAlbum = CachedAlbum() + cachedAlbum.id = album.id + cachedAlbum.title = album.title + cachedAlbum.artistID = album.artistID + + realm.writeBlocking { + this.copyToRealm(cachedAlbum) + } + } + + suspend fun clear(){ + realm.write { + val songs = this.query().find() + val artists = this.query().find() + val albums = this.query().find() + + delete(songs) + delete(artists) + delete(albums) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/PlaylistsQueries.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/PlaylistsQueries.kt index cbe6996..2f55858 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/PlaylistsQueries.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/data/mongodb/queries/PlaylistsQueries.kt @@ -10,7 +10,6 @@ import org.mongodb.kbson.BsonObjectId class PlaylistsQueries( private val realm: Realm ) { - private fun String.getMongoID(): BsonObjectId { val bsonId = BsonObjectId(this) @@ -57,26 +56,6 @@ class PlaylistsQueries( } } - suspend fun deletePlaylistImage(playlist: Playlist){ - - realm.write { - - val queryPlaylist = this.query("_id == $0", playlist._id).find().first() - - queryPlaylist.image = null - } - } - - suspend fun updatePlaylistImage(playlist: Playlist, bitmapString: String){ - - realm.write { - - val queryPlaylist = this.query("_id == $0", playlist._id).find().first() - - queryPlaylist.image = bitmapString - } - } - suspend fun updatePlaylist(playlist: Playlist) { realm.write { diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/functions/Functions.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/functions/Functions.kt index 94c50ff..24fb21e 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/functions/Functions.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/functions/Functions.kt @@ -1,17 +1,14 @@ package com.lighttigerxiv.simple.mp.compose.functions -import android.annotation.SuppressLint import android.content.ContentUris import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas -import android.media.MediaMetadataRetriever import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.net.Uri import android.os.Build import android.provider.MediaStore -import android.util.Log import android.util.Size import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme @@ -21,12 +18,7 @@ import androidx.compose.ui.graphics.Color import androidx.core.content.ContextCompat import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController -import com.lighttigerxiv.simple.mp.compose.R -import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song -import com.lighttigerxiv.simple.mp.compose.data.data_classes.SongCover -import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM -import java.io.File import java.text.Normalizer @@ -35,114 +27,6 @@ import java.text.Normalizer //************************************************ -@SuppressLint("Range") -fun getSongs(context: Context, sortType: String): List { - - val songs = ArrayList() - val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI - val cursor = context.contentResolver.query(uri, null, null, null, null) - - if (cursor != null) { - while (cursor.moveToNext()) { - - try { - - val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)) - val songPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)) - - val retriever = MediaMetadataRetriever() - retriever.setDataSource(songPath) - - var title = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) - var albumName = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) - val albumID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)) - var duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) - var artistName = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST) - val artistID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID)) - var genre = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE) - val modificationDate = File(songPath).lastModified() - - - if(title == null){ - title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)) - } - - if(albumName == null){ - albumName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM)) - } - - if(duration == null){ - duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)) - } - - if(artistName == null){ - artistName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Artists.ARTIST)) - } - - - if (genre == null) genre = context.getString(R.string.Undefined) - val year = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.YEAR)) - - if (title != null && albumName != null && artistName != null && duration != null) { - - val song = Song(id, songPath, title, albumName, albumID, duration.toInt(), artistName, artistID, year, genre, modificationDate ) - val filterDuration = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE).getString("FilterAudio", "60")!!.toInt() * 1000 - if (duration.toInt() > filterDuration) songs.add(song) - - } - - } catch (e: Exception) { - Log.e("Song Error", "Exception while getting song. Details -> ${e.message}") - } - } - } - - cursor?.close() - - when (sortType) { - Sorts.RECENT -> songs.sortByDescending { it.modificationDate } - Sorts.OLDEST -> songs.sortBy { it.modificationDate } - Sorts.ASCENDENT -> songs.sortBy { it.title } - Sorts.DESCENDENT -> songs.sortByDescending { it.title } - } - - return songs -} - -fun getAllAlbumsImages(songs: List?, context: Context, compressed: Boolean = false): ArrayList { - - val songsImagesList = ArrayList() - - songs?.forEach { song -> - - when { - - compressed -> { - - val uncompressedAlbumArt = getSongAlbumArt(context, song.id, song.albumID) - val compressedAlbumArt = uncompressedAlbumArt?.let { Bitmap.createScaledBitmap(it, uncompressedAlbumArt.width / 3, uncompressedAlbumArt.height / 3, false) } - - songsImagesList.add( - SongCover( - albumID = song.albumID, - albumArt = compressedAlbumArt - ) - ) - } - else -> { - - songsImagesList.add( - SongCover( - albumID = song.albumID, - albumArt = getSongAlbumArt(context, song.id, song.albumID) - ) - ) - } - } - } - - return songsImagesList -} @Suppress("DEPRECATION") fun getSongAlbumArt(context: Context, songID: Long, albumID: Long): Bitmap? { @@ -172,6 +56,7 @@ fun getSongAlbumArt(context: Context, songID: Long, albumID: Long): Bitmap? { } + //************************************************ // Network Related //************************************************ @@ -185,20 +70,18 @@ fun isNetworkAvailable(context: Context): Boolean { if (capabilities != null) { if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) return true - else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) return true - else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) return true } return false } -fun isOnMobileData(context: Context): Boolean{ +fun isOnMobileData(context: Context): Boolean { val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) - if(capabilities != null){ + if (capabilities != null) { if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) return true } return false @@ -222,7 +105,7 @@ fun getImage(context: Context, drawableId: Int, imageSize: Int): Bitmap { return bitmap } -fun getAppString(context: Context, id: Int): String{ +fun getAppString(context: Context, id: Int): String { return context.getString(id) } @@ -234,7 +117,7 @@ fun CharSequence.unaccent(): String { } @Composable -fun getSurfaceColor(settingsVM: SettingsVM): Color{ +fun getSurfaceColor(settingsVM: SettingsVM): Color { val themeMode = settingsVM.themeModeSetting.collectAsState().value val themeAccent = settingsVM.themeAccentSetting.collectAsState().value @@ -271,7 +154,7 @@ fun getSurfaceColor(settingsVM: SettingsVM): Color{ } } -fun openScreen(navController: NavHostController, route: String){ +fun openScreen(navController: NavHostController, route: String) { navController.navigate(route) { popUpTo(navController.graph.findStartDestination().id) { diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/about/AboutScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/about/AboutScreen.kt index 6bf86f9..4c70931 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/about/AboutScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/about/AboutScreen.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember @@ -23,12 +24,14 @@ import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer @Composable fun AboutScreen( mainVM: MainVM, - onBackClick:() -> Unit, -){ + onBackClick: () -> Unit, +) { val context = LocalContext.current @@ -37,11 +40,12 @@ fun AboutScreen( .fillMaxSize() .background(mainVM.surfaceColor.collectAsState().value) .padding(SCREEN_PADDING) + .verticalScroll(rememberScrollState()) ) { CustomToolbar( backText = remember { getAppString(context, R.string.Home) }, - onBackClick = {onBackClick()} + onBackClick = { onBackClick() } ) Column( @@ -53,7 +57,7 @@ fun AboutScreen( ) { - Spacer(modifier = Modifier.height(20.dp)) + MediumVerticalSpacer() CustomText( text = remember { getAppString(context, R.string.AppVersion) }, @@ -61,17 +65,28 @@ fun AboutScreen( ) CustomText( - text = remember{BuildConfig.VERSION_NAME} + text = remember { BuildConfig.VERSION_NAME } ) - Spacer(modifier = Modifier.height(20.dp)) + MediumVerticalSpacer() CustomText( - text = remember { getAppString(context, R.string.AppSource) }, + text = remember { getAppString(context, R.string.Changelog) }, weight = FontWeight.Bold ) - Spacer(modifier = Modifier.height(10.dp)) + Text( + color = MaterialTheme.colorScheme.onSurface, + text = "- Drastically improved loading speed\n" + + "- Added more info in about screen" + ) + + MediumVerticalSpacer() + + CustomText( + text = remember { getAppString(context, R.string.AppSource) }, + weight = FontWeight.Bold + ) Row( modifier = Modifier @@ -112,6 +127,137 @@ fun AboutScreen( ) } } + + MediumVerticalSpacer() + + CustomText( + text = remember { getAppString(context, R.string.Download) }, + weight = FontWeight.Bold + ) + + Row( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(14.dp)) + .background(MaterialTheme.colorScheme.surfaceVariant) + .clickable { + val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://github.com/lighttigerXIV/SimpleMP-Compose/releases") } + context.startActivity(intent) + } + .padding(14.dp), + verticalAlignment = Alignment.CenterVertically + ) { + + Image( + modifier = Modifier + .height(30.dp) + .width(30.dp), + painter = painterResource(id = R.drawable.icon_github), + contentDescription = null + ) + + Spacer(modifier = Modifier.width(14.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .weight(1f, fill = true) + ) { + + CustomText( + text = remember{ getAppString(context, R.string.GitHubReleases)}, + weight = FontWeight.Bold + ) + + CustomText( + text = remember { getAppString(context, R.string.DownloadInGitHubReleases) }, + ) + } + } + + SmallVerticalSpacer() + + Row( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(14.dp)) + .background(MaterialTheme.colorScheme.surfaceVariant) + .clickable { + val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://play.google.com/store/apps/details?id=com.lighttigerxiv.simple.mp") } + context.startActivity(intent) + } + .padding(14.dp), + verticalAlignment = Alignment.CenterVertically + ) { + + Image( + modifier = Modifier + .height(30.dp) + .width(30.dp), + painter = painterResource(id = R.drawable.icon_play_store), + contentDescription = null + ) + + Spacer(modifier = Modifier.width(14.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .weight(1f, fill = true) + ) { + + CustomText( + text = remember{ getAppString(context, R.string.PlayStore)}, + weight = FontWeight.Bold + ) + + CustomText( + text = remember { getAppString(context, R.string.DownloadInPlayStore) }, + ) + } + } + + SmallVerticalSpacer() + + Row( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(14.dp)) + .background(MaterialTheme.colorScheme.surfaceVariant) + .clickable { + val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://f-droid.org/en/packages/com.lighttigerxiv.simple.mp/") } + context.startActivity(intent) + } + .padding(14.dp), + verticalAlignment = Alignment.CenterVertically + ) { + + Image( + modifier = Modifier + .height(30.dp) + .width(30.dp), + painter = painterResource(id = R.drawable.icon_fdroid), + contentDescription = null + ) + + Spacer(modifier = Modifier.width(14.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .weight(1f, fill = true) + ) { + + CustomText( + text = remember{ getAppString(context, R.string.FDroid)}, + weight = FontWeight.Bold + ) + + CustomText( + text = remember { getAppString(context, R.string.DownloadInFDroid) }, + ) + } + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/add_song_to_playlist/AddSongToPlaylistScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/add_song_to_playlist/AddSongToPlaylistScreen.kt index ce4e94b..5ba2f3e 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/add_song_to_playlist/AddSongToPlaylistScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/add_song_to_playlist/AddSongToPlaylistScreen.kt @@ -30,8 +30,8 @@ import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage @@ -148,7 +148,7 @@ fun AddToPlaylistScreen( BottomSheetHandle() - SmallHeightSpacer() + SmallVerticalSpacer() Text( text = "Playlist Name", @@ -164,7 +164,7 @@ fun AddToPlaylistScreen( textType = "text" ) - SmallHeightSpacer() + SmallVerticalSpacer() Row( horizontalArrangement = Arrangement.End, @@ -206,7 +206,7 @@ fun AddToPlaylistScreen( ) { if (screenLoaded) { - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( modifier = Modifier.fillMaxSize(), @@ -266,7 +266,7 @@ fun AddToPlaylistScreen( .padding(5.dp) ) - SmallHeightSpacer() + SmallHorizontalSpacer() Text( text = playlist.name, diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreen.kt index 3af21c4..686d7a7 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreen.kt @@ -27,7 +27,7 @@ import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.functions.getImage -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -151,7 +151,7 @@ fun AlbumsScreen( } } - MediumHeightSpacer() + MediumVerticalSpacer() LazyVerticalGrid( columns = GridCells.Fixed(gridCellsCount), @@ -164,18 +164,16 @@ fun AlbumsScreen( items( items = albums!!, - key = { album -> album.albumID }, + key = { album -> album.id }, ) { album -> - val albumArt = mainVM.songsCovers.collectAsState().value?.first { it.albumID == album.albumID }?.albumArt - ImageCard( modifier = Modifier.animateItemPlacement(), - cardImage = remember { albumArt ?: getImage(context, R.drawable.cd, ImageSizes.MEDIUM) }, - imageTint = if (albumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, - cardText = remember { album.album }, + cardImage = remember { album.art ?: getImage(context, R.drawable.cd, ImageSizes.MEDIUM) }, + imageTint = if (album.art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + cardText = remember { album.title }, onCardClicked = { - onAlbumClicked(album.albumID) + onAlbumClicked(album.id) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreenVM.kt index 11ce585..f938f1a 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/AlbumsScreenVM.kt @@ -3,13 +3,17 @@ package com.lighttigerxiv.simple.mp.compose.screens.main.albums import android.app.Application import android.content.Context import androidx.lifecycle.AndroidViewModel -import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song +import androidx.lifecycle.viewModelScope import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Album import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.functions.unaccent +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class AlbumsScreenVM(application: Application) : AndroidViewModel(application) { @@ -38,22 +42,22 @@ class AlbumsScreenVM(application: Application) : AndroidViewModel(application) { _menuExpanded.update { newValue } } - private val _currentAlbums = MutableStateFlow?>(null) + private val _currentAlbums = MutableStateFlow?>(null) val currentAlbums = _currentAlbums.asStateFlow() - fun updateCurrentAlbums(newValue: List?){ + fun updateCurrentAlbums(newValue: List?){ _currentAlbums.update { newValue } } - private val _recentAlbums = MutableStateFlow?>(null) + private val _recentAlbums = MutableStateFlow?>(null) val recentAlbums = _recentAlbums.asStateFlow() - private val _oldestAlbums = MutableStateFlow?>(null) + private val _oldestAlbums = MutableStateFlow?>(null) val oldestAlbums = _oldestAlbums.asStateFlow() - private val _ascendentAlbums = MutableStateFlow?>(null) + private val _ascendentAlbums = MutableStateFlow?>(null) val ascendentAlbums = _ascendentAlbums.asStateFlow() - private val _descendentAlbums = MutableStateFlow?>(null) + private val _descendentAlbums = MutableStateFlow?>(null) val descendentAlbums = _descendentAlbums.asStateFlow() @@ -64,40 +68,51 @@ class AlbumsScreenVM(application: Application) : AndroidViewModel(application) { fun loadScreen(mainVM: MainVM) { - val sortType = preferences.getString("AlbumsSortType", Sorts.RECENT) - val songs = mainVM.songs.value + fun load(){ + val sortType = preferences.getString("AlbumsSortType", Sorts.RECENT) + val albums = mainVM.songsData.value?.albums - if (songs != null) { + if (albums != null) { - val albums = songs.distinctBy { it.albumID } + _recentAlbums.update { albums } - _recentAlbums.update { albums } + _oldestAlbums.update { albums.reversed() } - _oldestAlbums.update { albums.reversed() } + _ascendentAlbums.update { albums.sortedBy { it.title } } - _ascendentAlbums.update { albums.sortedBy { it.album } } + _descendentAlbums.update { albums.sortedByDescending { it.title } } - _descendentAlbums.update { albums.sortedByDescending { it.album } } - - _currentAlbums.update { - when (sortType) { - Sorts.RECENT -> recentAlbums.value - Sorts.OLDEST -> oldestAlbums.value - Sorts.ASCENDENT -> ascendentAlbums.value - else -> descendentAlbums.value + _currentAlbums.update { + when (sortType) { + Sorts.RECENT -> recentAlbums.value + Sorts.OLDEST -> oldestAlbums.value + Sorts.ASCENDENT -> ascendentAlbums.value + else -> descendentAlbums.value + } } + + _screenLoaded.update { true } } + } - _screenLoaded.update { true } + load() + + viewModelScope.launch{ + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() + filterAlbums() + } + } } } fun filterAlbums() { when (preferences.getString("AlbumsSortType", Sorts.RECENT)) { - Sorts.RECENT -> _currentAlbums.update { recentAlbums.value!!.filter { it.album.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.OLDEST -> _currentAlbums.update { oldestAlbums.value!!.filter { it.album.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.ASCENDENT -> _currentAlbums.update { ascendentAlbums.value!!.filter { it.album.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.DESCENDENT -> _currentAlbums.update { descendentAlbums.value!!.filter { it.album.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.RECENT -> _currentAlbums.update { recentAlbums.value!!.filter { it.title.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.OLDEST -> _currentAlbums.update { oldestAlbums.value!!.filter { it.title.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.ASCENDENT -> _currentAlbums.update { ascendentAlbums.value!!.filter { it.title.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.DESCENDENT -> _currentAlbums.update { descendentAlbums.value!!.filter { it.title.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreen.kt index 010e3a7..2162b55 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreen.kt @@ -25,13 +25,13 @@ import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.modifyIf -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -49,13 +49,11 @@ fun AlbumScreen( val inPortrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT val surfaceColor = mainVM.surfaceColor.collectAsState().value val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant - val selectedSong = mainVM.currentSong.collectAsState().value val screenLoaded = albumVM.screenLoaded.collectAsState().value val albumArt = albumVM.albumArt.collectAsState().value - val albumName = albumVM.albumName.collectAsState().value + val albumName = albumVM.albumTitle.collectAsState().value val artistName = albumVM.artistName.collectAsState().value val songs = albumVM.albumSongs.collectAsState().value - val songsCovers = mainVM.songsCovers.collectAsState().value if (!screenLoaded) { @@ -84,7 +82,7 @@ fun AlbumScreen( CustomToolbar(backText = stringResource(id = R.string.Albums), onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Image( bitmap = (albumArt ?: getImage(context, R.drawable.cd, ImageSizes.LARGE)).asImageBitmap(), @@ -103,7 +101,7 @@ fun AlbumScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( text = albumName, @@ -115,7 +113,7 @@ fun AlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -136,7 +134,7 @@ fun AlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -150,7 +148,7 @@ fun AlbumScreen( content = { item { - MediumHeightSpacer() + MediumVerticalSpacer() } items( @@ -158,10 +156,9 @@ fun AlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsCovers?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } @@ -183,7 +180,7 @@ fun AlbumScreen( CustomToolbar(backText = stringResource(id = R.string.Albums), onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -216,7 +213,7 @@ fun AlbumScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( text = albumName, @@ -228,7 +225,7 @@ fun AlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -250,7 +247,7 @@ fun AlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -260,7 +257,7 @@ fun AlbumScreen( } } - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( verticalArrangement = Arrangement.spacedBy(5.dp), @@ -271,10 +268,9 @@ fun AlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsCovers?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreenVM.kt index a54a66d..9b21eb6 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/albums/album/AlbumScreenVM.kt @@ -24,8 +24,8 @@ class AlbumScreenVM(application: Application) : AndroidViewModel(application) { private val _albumArt = MutableStateFlow(null) val albumArt = _albumArt.asStateFlow() - private val _albumName = MutableStateFlow("") - val albumName = _albumName.asStateFlow() + private val _albumTitle = MutableStateFlow("") + val albumTitle = _albumTitle.asStateFlow() private val _artistName = MutableStateFlow("") val artistName = _artistName.asStateFlow() @@ -41,28 +41,32 @@ class AlbumScreenVM(application: Application) : AndroidViewModel(application) { fun loadScreen(mainVM: MainVM, albumID: Long) { - val songs = mainVM.songs.value - val songsImages = mainVM.songsCovers.value + val songsData = mainVM.songsData.value + val songs = songsData?.songs + val albums = songsData?.albums + val artists = songsData?.artists + if (songs != null && albums != null && artists != null){ + val album = albums.first { it.id == albumID } - _albumArt.update { songsImages?.find { it.albumID == albumID }?.albumArt } + _albumArt.update { album.art } - _albumSongs.update { songs?.filter { it.albumID == albumID } } + _albumSongs.update { songs.filter { it.albumID == albumID } } - _albumName.update { albumSongs.value!![0].album } + _albumTitle.update { album.title } - _artistName.update { albumSongs.value!![0].artist } - - _screenLoaded.update { true } + _artistName.update { artists.first { it.id == album.artistID }.name } + _screenLoaded.update { true } + } } fun clearScreen() { _albumArt.update { null } - _albumName.update { "" } + _albumTitle.update { "" } _artistName.update { "" } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreen.kt index 82cbc01..2ccc37f 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreen.kt @@ -35,20 +35,21 @@ import com.lighttigerxiv.simple.mp.compose.* import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Album import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.modifyIf import com.lighttigerxiv.simple.mp.compose.ui.composables.ImageCard +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem import kotlinx.coroutines.launch import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -72,7 +73,6 @@ fun ArtistScreen( val surfaceColor = mainVM.surfaceColor.collectAsState().value val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant val screenLoaded = vm.screenLoaded.collectAsState().value - val currentSong = mainVM.currentSong.collectAsState().value val artistName = vm.artistName.collectAsState().value val artistCover = vm.artistCover.collectAsState().value val tintCover = vm.tintCover.collectAsState().value @@ -113,7 +113,7 @@ fun ArtistScreen( artistID ) - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier @@ -140,7 +140,7 @@ fun ArtistScreen( ) } - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( modifier = Modifier.fillMaxWidth(), @@ -150,7 +150,7 @@ fun ArtistScreen( weight = FontWeight.Bold ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -165,7 +165,6 @@ fun ArtistScreen( surfaceColor, songs, albums, - currentSong, gridCellsCount ) } @@ -189,7 +188,7 @@ fun ArtistScreen( artistID ) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -223,7 +222,7 @@ fun ArtistScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( modifier = Modifier.fillMaxWidth(), @@ -233,7 +232,7 @@ fun ArtistScreen( weight = FontWeight.Bold ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -253,7 +252,6 @@ fun ArtistScreen( surfaceColor, songs, albums, - currentSong, gridCellsCount ) } @@ -344,10 +342,9 @@ fun ArtistSongsAndAlbums( pagerState: PagerState, surfaceColor: Color, songs: List?, - albums: List?, - currentSong: Song?, + albums: List?, gridCellsCount: Int -){ +) { val context = LocalContext.current val scope = rememberCoroutineScope() @@ -402,7 +399,7 @@ fun ArtistSongsAndAlbums( ) } - MediumHeightSpacer() + MediumVerticalSpacer() HorizontalPager( state = pagerState, @@ -431,7 +428,7 @@ fun ArtistSongsAndAlbums( } ) - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( verticalArrangement = Arrangement.spacedBy(5.dp), @@ -442,10 +439,9 @@ fun ArtistSongsAndAlbums( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = mainVM.songsCovers.collectAsState().value?.find { it.albumID == song.albumID }!!.albumArt, - highlight = song.path == currentSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } @@ -470,24 +466,17 @@ fun ArtistSongsAndAlbums( items( items = albums!!, - key = { album -> album.albumID }, + key = { album -> album.id }, ) { album -> - val albumSongAlbumID = album.albumID - val albumName = album.album - val albumArt = mainVM.songsCovers.collectAsState().value?.first { it.albumID == albumSongAlbumID }?.albumArt - - ImageCard( - cardImage = remember { (albumArt ?: getImage(context, R.drawable.cd, ImageSizes.MEDIUM)) }, - cardText = albumName, - imageTint = if (albumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + cardImage = remember { (album.art ?: getImage(context, R.drawable.cd, ImageSizes.MEDIUM)) }, + cardText = album.title, + imageTint = if (album.art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, onCardClicked = { - vm.openAlbumScreen(activityContext, navController, album.albumID) - }, - - ) - + vm.openAlbumScreen(activityContext, navController, album.id) + } + ) } } ) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreenVM.kt index 0a02182..95a4128 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/ArtistScreenVM.kt @@ -10,6 +10,7 @@ import android.widget.Toast import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner +import androidx.lifecycle.viewModelScope import androidx.navigation.NavHostController import com.bumptech.glide.Glide import com.bumptech.glide.request.target.CustomTarget @@ -17,10 +18,11 @@ import com.bumptech.glide.request.transition.Transition import com.google.gson.Gson import com.lighttigerxiv.simple.mp.compose.* import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Album import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM import com.lighttigerxiv.simple.mp.compose.data.mongodb.getMongoRealm -import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsQueries +import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsCoversQueries import com.lighttigerxiv.simple.mp.compose.data.responses.DiscogsResponse import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.Routes @@ -34,6 +36,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import retrofit2.Call @@ -49,7 +52,7 @@ class ArtistScreenVM(application: Application) : AndroidViewModel(application) { private val context = application - private val artistsQueries = ArtistsQueries(getMongoRealm()) + private val artistsCoversQueries = ArtistsCoversQueries(getMongoRealm()) private val _screenLoaded = MutableStateFlow(false) val screenLoaded = _screenLoaded.asStateFlow() @@ -65,20 +68,20 @@ class ArtistScreenVM(application: Application) : AndroidViewModel(application) { private val _artistCover = MutableStateFlow(getImage(context, R.drawable.person, ImageSizes.LARGE)) val artistCover = _artistCover.asStateFlow() - fun updateArtistCover(newValue: Bitmap){ + fun updateArtistCover(newValue: Bitmap) { _artistCover.update { newValue } } private val _tintCover = MutableStateFlow(true) val tintCover = _tintCover.asStateFlow() - fun updateTintCover(newValue: Boolean){ + fun updateTintCover(newValue: Boolean) { _tintCover.update { newValue } } private val _artistSongs = MutableStateFlow?>(null) val artistSongs = _artistSongs.asStateFlow() - private val _artistAlbums = MutableStateFlow?>(null) + private val _artistAlbums = MutableStateFlow?>(null) val artistAlbums = _artistAlbums.asStateFlow() @@ -88,124 +91,152 @@ class ArtistScreenVM(application: Application) : AndroidViewModel(application) { fun loadScreen(artistID: Long, mainVM: MainVM, settingsVM: SettingsVM) { - val songs = mainVM.songs.value + fun load(){ + val songsData = mainVM.songsData.value + val songs = songsData?.songs + val artists = songsData?.artists + val albums = songsData?.albums - _artistName.update { songs!!.first { it.artistID == artistID }.artist } + if (songs != null && artists != null && albums != null) { - var artist = artistsQueries.getArtist(artistID) + val artist = artists.first { it.id == artistID } - if (artist == null) { + _artistName.update { artist.name } - artistsQueries.addArtist(artistID) - } + var artistQuery = artistsCoversQueries.getArtist(artistID) - artist = artistsQueries.getArtist(artistID) + if (artistQuery == null) { - _artistSongs.update { songs!!.filter { it.artistID == artistID } } + artistsCoversQueries.addArtist(artistID) + } - _artistAlbums.update { artistSongs.value!!.distinctBy { it.albumID } } + artistQuery = artistsCoversQueries.getArtist(artistID) - _screenLoaded.update { true } + _artistSongs.update { songs.filter { it.artistID == artistID } } - //Loads Artist Image - if (artist!!.alreadyRequested) { + val newAlbums = ArrayList() - if (artist.image != null) { + artistSongs.value?.forEach { song -> + if( !newAlbums.any { it.id == song.albumID}){ + newAlbums.add(albums.first { it.id == song.albumID }) + } + } - val imageBytes = Base64.decode(artist.image, Base64.DEFAULT) + _artistAlbums.update { newAlbums } - _tintCover.update { false } + _screenLoaded.update { true } - _artistCover.update { BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) } - } - } else { + //Loads Artist Image + if (artistQuery!!.alreadyRequested) { - val canDownloadArtistCover = settingsVM.downloadArtistCoverSetting.value - val isInternetAvailable = isNetworkAvailable(context) - val canDownloadOverData = settingsVM.downloadOverDataSetting.value - val isMobileDataEnabled = isOnMobileData(context) + if (artistQuery.image != null) { - if (isInternetAvailable && canDownloadArtistCover) { - if ((canDownloadOverData && isMobileDataEnabled) || (!canDownloadOverData && !isMobileDataEnabled)) { - getDiscogsRetrofit() - .getArtistCover( - token = "Discogs token=addIURHUBwvyDlSqWcNqPWkHXUbMgUzNgbpZGZnd", - artist = artistName.value - ) - .enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.code() == 200) { + val imageBytes = Base64.decode(artistQuery.image, Base64.DEFAULT) - try { + _tintCover.update { false } - val data = Gson().fromJson(response.body(), DiscogsResponse::class.java) + _artistCover.update { BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) } + } + } else { - if (data.results.isNotEmpty()) { + val canDownloadArtistCover = settingsVM.downloadArtistCoverSetting.value + val isInternetAvailable = isNetworkAvailable(context) + val canDownloadOverData = settingsVM.downloadOverDataSetting.value + val isMobileDataEnabled = isOnMobileData(context) - val imageUrl = data.results[0].cover_image + if (isInternetAvailable && canDownloadArtistCover) { + if ((canDownloadOverData && isMobileDataEnabled) || (!canDownloadOverData && !isMobileDataEnabled)) { + getDiscogsRetrofit() + .getArtistCover( + token = "Discogs token=addIURHUBwvyDlSqWcNqPWkHXUbMgUzNgbpZGZnd", + artist = artistName.value + ) + .enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.code() == 200) { - if (imageUrl.endsWith(".gif")) { + try { - runBlocking { - withContext(Dispatchers.IO) { - artistsQueries.updateArtistCover(artistID, null) - artistsQueries.updateArtistAlreadyRequested(artistID) - } - } + val data = Gson().fromJson(response.body(), DiscogsResponse::class.java) - } else { - Glide.with(context) - .asBitmap() - .load(imageUrl) - .into(object : CustomTarget() { - override fun onResourceReady(resource: Bitmap, transition: Transition?) { + if (data.results.isNotEmpty()) { - val baos = ByteArrayOutputStream() + val imageUrl = data.results[0].cover_image - resource.compress(Bitmap.CompressFormat.PNG, 50, baos) + if (imageUrl.endsWith(".gif")) { - val b = baos.toByteArray() + runBlocking { + withContext(Dispatchers.IO) { + artistsCoversQueries.updateArtistCover(artistID, null) + artistsCoversQueries.updateArtistAlreadyRequested(artistID) + } + } - val imageString = Base64.encodeToString(b, Base64.DEFAULT) + } else { + Glide.with(context) + .asBitmap() + .load(imageUrl) + .into(object : CustomTarget() { + override fun onResourceReady(resource: Bitmap, transition: Transition?) { - runBlocking { - withContext(Dispatchers.IO) { - artistsQueries.updateArtistCover(artistID, imageString) - artistsQueries.updateArtistAlreadyRequested(artistID) - } - } + val baos = ByteArrayOutputStream() - _tintCover.update { false } + resource.compress(Bitmap.CompressFormat.PNG, 50, baos) - _artistCover.update { resource } - } + val b = baos.toByteArray() + + val imageString = Base64.encodeToString(b, Base64.DEFAULT) - override fun onLoadCleared(placeholder: Drawable?) {} - }) + runBlocking { + withContext(Dispatchers.IO) { + artistsCoversQueries.updateArtistCover(artistID, imageString) + artistsCoversQueries.updateArtistAlreadyRequested(artistID) + } + } + + _tintCover.update { false } + + _artistCover.update { resource } + } + + override fun onLoadCleared(placeholder: Drawable?) {} + }) + } + } + } catch (exc: Exception) { + + Toast.makeText(context, exc.message.toString(), Toast.LENGTH_LONG).show() } } - } catch (exc: Exception) { + } - Toast.makeText(context, exc.message.toString(), Toast.LENGTH_LONG).show() + override fun onFailure(call: Call, t: Throwable) { + Log.e("Discogs Error", "Error while getting artist cover") } - } - } + }) + } + } + } + } + } + + load() - override fun onFailure(call: Call, t: Throwable) { - Log.e("Discogs Error", "Error while getting artist cover") - } - }) + viewModelScope.launch { + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() } } } } - fun openAlbumScreen(activityContext: ViewModelStoreOwner, navController: NavHostController, id: Long){ + fun openAlbumScreen(activityContext: ViewModelStoreOwner, navController: NavHostController, id: Long) { ViewModelProvider(activityContext)[ArtistAlbumScreenVM::class.java].clearScreen() navController.navigate("${Routes.Main.ARTIST_ALBUM}${id}") } - fun openSelectArtistCoverScreen(activityContext: ViewModelStoreOwner, navController: NavHostController, name: String, id: Long){ + fun openSelectArtistCoverScreen(activityContext: ViewModelStoreOwner, navController: NavHostController, name: String, id: Long) { ViewModelProvider(activityContext)[SelectArtistCoverScreenVM::class.java].clearScreen() navController.navigate("${Routes.Main.SELECT_ARTIST_COVER}name=${name}&id=${id}") } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreen.kt index b8d09a6..ed240b3 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -29,10 +28,10 @@ import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.modifyIf import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -49,12 +48,10 @@ fun ArtistAlbumScreen( val surfaceColor = mainVM.surfaceColor.collectAsState().value val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant val screenLoaded = albumVM.screenLoaded.collectAsState().value - val selectedSong = mainVM.currentSong.collectAsState().value val albumArt = albumVM.albumArt.collectAsState().value val albumName = albumVM.albumName.collectAsState().value val artistName = albumVM.artistName.collectAsState().value val songs = albumVM.albumSongs.collectAsState().value - val songsImages = mainVM.songsCovers.collectAsState().value if (!screenLoaded) { @@ -84,7 +81,7 @@ fun ArtistAlbumScreen( CustomToolbar(backText = "Albums", onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Image( bitmap = (albumArt ?: getImage(context, R.drawable.cd, ImageSizes.LARGE)).asImageBitmap(), @@ -103,7 +100,7 @@ fun ArtistAlbumScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( text = albumName, @@ -115,7 +112,7 @@ fun ArtistAlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -136,7 +133,7 @@ fun ArtistAlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -150,7 +147,7 @@ fun ArtistAlbumScreen( content = { item { - MediumHeightSpacer() + MediumVerticalSpacer() } items( @@ -158,10 +155,9 @@ fun ArtistAlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsImages?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } @@ -174,7 +170,7 @@ fun ArtistAlbumScreen( CustomToolbar(backText = "Albums", onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -206,7 +202,7 @@ fun ArtistAlbumScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() CustomText( text = albumName, @@ -218,7 +214,7 @@ fun ArtistAlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -241,7 +237,7 @@ fun ArtistAlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -256,7 +252,7 @@ fun ArtistAlbumScreen( content = { item { - MediumHeightSpacer() + MediumVerticalSpacer() } items( @@ -264,10 +260,9 @@ fun ArtistAlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsImages?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreenVM.kt index 4e7d921..43fec87 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_album/ArtistAlbumScreenVM.kt @@ -3,11 +3,15 @@ package com.lighttigerxiv.simple.mp.compose.screens.main.artist.artist_album import android.app.Application import android.graphics.Bitmap import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class ArtistAlbumScreenVM(application: Application) : AndroidViewModel(application) { @@ -41,20 +45,34 @@ class ArtistAlbumScreenVM(application: Application) : AndroidViewModel(applicati fun loadScreen(mainVM: MainVM, albumID: Long){ - val songs = mainVM.songs.value - val songsImages = mainVM.songsCovers.value + fun load(){ + val songsData = mainVM.songsData.value + val songs = songsData?.songs + val albums = songsData?.albums + val artists = songsData?.artists - if(songs != null && songsImages != null){ + if(songs != null && artists != null && albums != null){ - _albumArt.update { songsImages.find { it.albumID == albumID }?.albumArt } + val album = albums.first { it.id == albumID } - _albumSongs.update { songs.filter { it.albumID == albumID } } + _albumArt.update { album.art } - _albumName.update { albumSongs.value!![0].album } + _albumSongs.update { songs.filter { it.albumID == albumID } } - _artistName.update { albumSongs.value!![0].artist } + _albumName.update { album.title } - _screenLoaded.update { true } + _artistName.update { artists.first { it.id == album.artistID }.name } + + _screenLoaded.update { true } + } + } + + viewModelScope.launch { + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() + } + } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreen.kt index a8131b6..0804ce3 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreen.kt @@ -33,8 +33,8 @@ import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.artist.ArtistScreenVM @@ -80,7 +80,7 @@ fun SelectArtistCoverScreen( onBackClick = {onGoBack()}, ) - MediumHeightSpacer() + MediumVerticalSpacer() if(screenLoaded){ @@ -108,7 +108,7 @@ fun SelectArtistCoverScreen( ) } - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier @@ -128,7 +128,7 @@ fun SelectArtistCoverScreen( ) } - MediumHeightSpacer() + MediumVerticalSpacer() if(covers != null){ diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreenVM.kt index 22ce251..3e3c57e 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artist/artist_select_cover/SelectArtistCoverScreenVM.kt @@ -9,7 +9,7 @@ import androidx.lifecycle.AndroidViewModel import com.google.gson.Gson import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.data.mongodb.getMongoRealm -import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsQueries +import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsCoversQueries import com.lighttigerxiv.simple.mp.compose.data.responses.DiscogsResponse import com.lighttigerxiv.simple.mp.compose.functions.isNetworkAvailable import com.lighttigerxiv.simple.mp.compose.functions.isOnMobileData @@ -33,7 +33,7 @@ class SelectArtistCoverScreenVM(application: Application) : AndroidViewModel(app private val context = application - private val artistsQueries = ArtistsQueries(getMongoRealm()) + private val artistsCoversQueries = ArtistsCoversQueries(getMongoRealm()) private val _screenLoaded = MutableStateFlow(false) val screenLoaded = _screenLoaded.asStateFlow() @@ -101,9 +101,9 @@ class SelectArtistCoverScreenVM(application: Application) : AndroidViewModel(app runBlocking { withContext(Dispatchers.IO){ - artistsQueries.updateArtistCover(artistID, bitmapString) + artistsCoversQueries.updateArtistCover(artistID, bitmapString) - val artist = artistsQueries.getArtist(artistID) + val artist = artistsCoversQueries.getArtist(artistID) val imageBytes = Base64.decode(artist!!.image, Base64.DEFAULT) @@ -121,7 +121,7 @@ class SelectArtistCoverScreenVM(application: Application) : AndroidViewModel(app runBlocking { withContext(Dispatchers.IO){ - artistsQueries.updateArtistCover(artistID, null) + artistsCoversQueries.updateArtistCover(artistID, null) artistVM!!.updateTintCover(true) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreen.kt index 1cf6bef..10869f2 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreen.kt @@ -25,7 +25,7 @@ import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomTextField import com.lighttigerxiv.simple.mp.compose.ui.composables.ImageCard -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import kotlinx.coroutines.delay @@ -166,7 +166,7 @@ fun ArtistsScreen( } } - MediumHeightSpacer() + MediumVerticalSpacer() LazyVerticalGrid( columns = GridCells.Fixed(gridCellsCount), @@ -179,18 +179,16 @@ fun ArtistsScreen( items( items = artists!!, - key = { artist -> artist.artistID }, + key = { artist -> artist.id }, ) { artist -> - val albumArt = mainVM.songsCovers.collectAsState().value?.first { it.albumID == artist.albumID }?.albumArt - ImageCard( modifier = Modifier.animateItemPlacement(), - cardImage = remember { albumArt ?: getImage(context, R.drawable.person, ImageSizes.MEDIUM) }, - imageTint = if (albumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, - cardText = remember { artist.artist }, + cardImage = remember { getImage(context, R.drawable.person, ImageSizes.MEDIUM) }, + imageTint = ColorFilter.tint(MaterialTheme.colorScheme.primary), + cardText = remember { artist.name }, onCardClicked = { - vm.openArtist(activityContext, navController, artist.artistID) + vm.openArtist(activityContext, navController, artist.id) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreenVM.kt index 6882524..795f256 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/artists/ArtistsScreenVM.kt @@ -5,16 +5,20 @@ import android.content.Context import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner +import androidx.lifecycle.viewModelScope import androidx.navigation.NavHostController -import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM +import com.lighttigerxiv.simple.mp.compose.data.data_classes.Artist import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.functions.unaccent import com.lighttigerxiv.simple.mp.compose.screens.main.artist.ArtistScreenVM +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class ArtistsScreenVM(application: Application) : AndroidViewModel(application) { @@ -42,22 +46,22 @@ class ArtistsScreenVM(application: Application) : AndroidViewModel(application) _menuExpanded.update { newValue } } - private val _currentArtists = MutableStateFlow?>(null) + private val _currentArtists = MutableStateFlow?>(null) val currentArtists = _currentArtists.asStateFlow() - fun updateCurrentArtists(newValue: List?){ + fun updateCurrentArtists(newValue: List?){ _currentArtists.update { newValue } } - private val _recentArtists = MutableStateFlow?>(null) + private val _recentArtists = MutableStateFlow?>(null) val recentArtists = _recentArtists.asStateFlow() - private val _oldestArtists = MutableStateFlow?>(null) + private val _oldestArtists = MutableStateFlow?>(null) val oldestArtists = _oldestArtists.asStateFlow() - private val _ascendentArtists = MutableStateFlow?>(null) + private val _ascendentArtists = MutableStateFlow?>(null) val ascendentArtists = _ascendentArtists.asStateFlow() - private val _descendentArtists = MutableStateFlow?>(null) + private val _descendentArtists = MutableStateFlow?>(null) val descendentArtists = _descendentArtists.asStateFlow() @@ -68,32 +72,42 @@ class ArtistsScreenVM(application: Application) : AndroidViewModel(application) fun loadScreen(mainVM: MainVM) { - val sortType = preferences.getString("ArtistsSortType", Sorts.RECENT) - val songs = mainVM.songs.value + fun load(){ + val sortType = preferences.getString("ArtistsSortType", Sorts.RECENT) + val artists = mainVM.songsData.value?.artists - if (songs != null) { + artists?.let{ - val artists = songs.distinctBy { it.artistID } + _recentArtists.update { artists } - _recentArtists.update { artists } + _oldestArtists.update { artists.reversed() } - _oldestArtists.update { artists.reversed() } + _ascendentArtists.update { artists.sortedBy { it.name } } - _ascendentArtists.update { artists.sortedBy { it.artist } } + _descendentArtists.update { artists.sortedByDescending { it.name } } - _descendentArtists.update { artists.sortedByDescending { it.artist } } + _currentArtists.update { + when (sortType) { + Sorts.RECENT -> recentArtists.value + Sorts.OLDEST -> oldestArtists.value + Sorts.ASCENDENT -> ascendentArtists.value + else -> descendentArtists.value + } + } + _screenLoaded.update { true } + } + } - _currentArtists.update { - when (sortType) { - Sorts.RECENT -> recentArtists.value - Sorts.OLDEST -> oldestArtists.value - Sorts.ASCENDENT -> ascendentArtists.value - else -> descendentArtists.value + load() + + viewModelScope.launch { + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() + filterArtists() } } - - _screenLoaded.update { true } } } @@ -101,10 +115,10 @@ class ArtistsScreenVM(application: Application) : AndroidViewModel(application) when (preferences.getString("ArtistsSortType", Sorts.RECENT)) { - Sorts.RECENT -> _currentArtists.update { recentArtists.value!!.filter { it.artist.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.OLDEST -> _currentArtists.update { oldestArtists.value!!.filter { it.artist.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.ASCENDENT -> _currentArtists.update { ascendentArtists.value!!.filter { it.artist.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } - Sorts.DESCENDENT -> _currentArtists.update { descendentArtists.value!!.filter { it.artist.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.RECENT -> _currentArtists.update { recentArtists.value!!.filter { it.name.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.OLDEST -> _currentArtists.update { oldestArtists.value!!.filter { it.name.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.ASCENDENT -> _currentArtists.update { ascendentArtists.value!!.filter { it.name.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } + Sorts.DESCENDENT -> _currentArtists.update { descendentArtists.value!!.filter { it.name.unaccent().lowercase().trim().contains(searchText.value.unaccent().lowercase().trim()) } } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreen.kt index cc1ca81..17b0326 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -29,10 +28,10 @@ import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.modifyIf import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -49,12 +48,10 @@ fun FloatingAlbumScreen( val surfaceColor = mainVM.surfaceColor.collectAsState().value val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant val screenLoaded = albumVM.screenLoaded.collectAsState().value - val selectedSong = mainVM.currentSong.collectAsState().value val albumArt = albumVM.albumArt.collectAsState().value - val albumName = albumVM.albumName.collectAsState().value + val albumName = albumVM.albumTitle.collectAsState().value val artistName = albumVM.artistName.collectAsState().value val songs = albumVM.albumSongs.collectAsState().value - val songsImages = mainVM.songsCovers.collectAsState().value if (!screenLoaded) { @@ -86,7 +83,7 @@ fun FloatingAlbumScreen( CustomToolbar(backText = "Albums", onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Image( bitmap = (albumArt ?: getImage(context, R.drawable.cd, ImageSizes.LARGE)).asImageBitmap(), @@ -105,7 +102,7 @@ fun FloatingAlbumScreen( } ) - SmallHeightSpacer() + SmallVerticalSpacer() CustomText( text = albumName, @@ -117,7 +114,7 @@ fun FloatingAlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -138,7 +135,7 @@ fun FloatingAlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -152,7 +149,7 @@ fun FloatingAlbumScreen( content = { item { - MediumHeightSpacer() + MediumVerticalSpacer() } items( @@ -160,10 +157,9 @@ fun FloatingAlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsImages?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } @@ -182,7 +178,7 @@ fun FloatingAlbumScreen( CustomToolbar(backText = "Albums", onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -214,7 +210,7 @@ fun FloatingAlbumScreen( } ) - SmallHeightSpacer() + SmallVerticalSpacer() CustomText( text = albumName, @@ -226,7 +222,7 @@ fun FloatingAlbumScreen( text = artistName ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -247,7 +243,7 @@ fun FloatingAlbumScreen( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() PlayAndShuffleRow( surfaceColor = surfaceColor, @@ -261,7 +257,7 @@ fun FloatingAlbumScreen( content = { item { - MediumHeightSpacer() + MediumVerticalSpacer() } items( @@ -269,10 +265,9 @@ fun FloatingAlbumScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = remember { songsImages?.first { it.albumID == song.albumID }?.albumArt }, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreenVM.kt index e5d307d..9e3a4a7 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_album/FloatingAlbumScreenVM.kt @@ -24,8 +24,8 @@ class FloatingAlbumScreenVM(application: Application) : AndroidViewModel(applica private val _albumArt = MutableStateFlow(null) val albumArt = _albumArt.asStateFlow() - private val _albumName = MutableStateFlow("") - val albumName = _albumName.asStateFlow() + private val _albumTitle = MutableStateFlow("") + val albumTitle = _albumTitle.asStateFlow() private val _artistName = MutableStateFlow("") val artistName = _artistName.asStateFlow() @@ -41,18 +41,22 @@ class FloatingAlbumScreenVM(application: Application) : AndroidViewModel(applica fun loadScreen(mainVM: MainVM, albumID: Long){ - val songs = mainVM.songs.value - val songsImages = mainVM.songsCovers.value + val songsData = mainVM.songsData.value + val songs = songsData?.songs + val artists = songsData?.artists + val albums = songsData?.albums - if(songs != null && songsImages != null){ + if(songs != null && artists != null && albums != null){ - _albumArt.update { songsImages.find { it.albumID == albumID }?.albumArt } + val album = albums.first { it.id == albumID } + + _albumArt.update { album.art } _albumSongs.update { songs.filter { it.albumID == albumID } } - _albumName.update { albumSongs.value!![0].album } + _albumTitle.update { album.title } - _artistName.update { albumSongs.value!![0].artist } + _artistName.update { artists.first { it.id == album.artistID }.name } _screenLoaded.update { true } } @@ -62,7 +66,7 @@ class FloatingAlbumScreenVM(application: Application) : AndroidViewModel(applica _albumArt.update { null } - _albumName.update { "" } + _albumTitle.update { "" } _artistName.update { "" } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreen.kt index 95f4a65..d3c6842 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreen.kt @@ -30,11 +30,11 @@ import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.modifyIf +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -53,7 +53,6 @@ fun FloatingArtistScreen( val surfaceColor = mainVM.surfaceColor.collectAsState().value val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant val screenLoaded = vm.screenLoaded.collectAsState().value - val selectedSong = mainVM.currentSong.collectAsState().value val artistName = vm.artistName.collectAsState().value val artistCover = vm.artistCover.collectAsState().value val tintCover = vm.tintCover.collectAsState().value @@ -88,7 +87,7 @@ fun FloatingArtistScreen( onBackClick = { onBackClicked() } ) - SmallHeightSpacer() + SmallVerticalSpacer() Image( bitmap = artistCover.asImageBitmap(), @@ -117,7 +116,7 @@ fun FloatingArtistScreen( weight = FontWeight.Bold ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -138,7 +137,7 @@ fun FloatingArtistScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( verticalArrangement = Arrangement.spacedBy(5.dp), @@ -149,10 +148,9 @@ fun FloatingArtistScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = mainVM.songsCovers.collectAsState().value?.find { it.albumID == song.albumID }!!.albumArt, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } @@ -173,7 +171,7 @@ fun FloatingArtistScreen( onBackClick = { onBackClicked() } ) - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier @@ -215,7 +213,7 @@ fun FloatingArtistScreen( weight = FontWeight.Bold ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -235,7 +233,7 @@ fun FloatingArtistScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( verticalArrangement = Arrangement.spacedBy(5.dp), @@ -246,10 +244,9 @@ fun FloatingArtistScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = mainVM.songsCovers.collectAsState().value?.find { it.albumID == song.albumID }!!.albumArt, - highlight = song.path == selectedSong?.path, onSongClick = { mainVM.selectSong(songs, songs.indexOf(song)) } ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreenVM.kt index a661a74..8437d94 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/floating_artist/FloatingArtistScreenVM.kt @@ -17,7 +17,7 @@ import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM import com.lighttigerxiv.simple.mp.compose.data.mongodb.getMongoRealm -import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsQueries +import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.ArtistsCoversQueries import com.lighttigerxiv.simple.mp.compose.data.responses.DiscogsResponse import com.lighttigerxiv.simple.mp.compose.functions.isNetworkAvailable import com.lighttigerxiv.simple.mp.compose.functions.isOnMobileData @@ -41,7 +41,7 @@ class FloatingArtistScreenVM(application: Application) : AndroidViewModel(applic private val context = application - private val artistsQueries = ArtistsQueries(getMongoRealm()) + private val artistsCoversQueries = ArtistsCoversQueries(getMongoRealm()) private val _screenLoaded = MutableStateFlow(false) val screenLoaded = _screenLoaded.asStateFlow() @@ -67,111 +67,118 @@ class FloatingArtistScreenVM(application: Application) : AndroidViewModel(applic fun loadScreen(artistID: Long, mainVM: MainVM, settingsVM: SettingsVM) { - val songs = mainVM.songs.value + val songsData = mainVM.songsData.value + val songs = songsData?.songs + val artists = songsData?.artists - _artistName.update { songs!!.first { it.artistID == artistID }.artist } + if(songs != null && artists != null){ - var artist = artistsQueries.getArtist(artistID) + val artist = artists.first { it.id == artistID } - if (artist == null) { + _artistName.update { artist.name } - artistsQueries.addArtist(artistID) - } + var artistQuery = artistsCoversQueries.getArtist(artistID) + + if (artistQuery == null) { - artist = artistsQueries.getArtist(artistID) + artistsCoversQueries.addArtist(artistID) + } - _artistSongs.update { songs!!.filter { it.artistID == artistID } } + artistQuery = artistsCoversQueries.getArtist(artistID) - _screenLoaded.update { true } + _artistSongs.update { songs.filter { it.artistID == artistID } } - //Loads Artist Image - if (artist!!.alreadyRequested) { + _screenLoaded.update { true } - if (artist.image != null) { + //Loads Artist Image + if (artistQuery!!.alreadyRequested) { - val imageBytes = Base64.decode(artist.image, Base64.DEFAULT) + if (artistQuery.image != null) { - _tintCover.update { false } + val imageBytes = Base64.decode(artistQuery.image, Base64.DEFAULT) - _artistCover.update { BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) } - } - } else { + _tintCover.update { false } - val canDownloadArtistCover = settingsVM.downloadArtistCoverSetting.value - val isInternetAvailable = isNetworkAvailable(context) - val canDownloadOverData = settingsVM.downloadOverDataSetting.value - val isMobileDataEnabled = isOnMobileData(context) + _artistCover.update { BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) } + } + } else { + + val canDownloadArtistCover = settingsVM.downloadArtistCoverSetting.value + val isInternetAvailable = isNetworkAvailable(context) + val canDownloadOverData = settingsVM.downloadOverDataSetting.value + val isMobileDataEnabled = isOnMobileData(context) - if (isInternetAvailable && canDownloadArtistCover) { - if ((canDownloadOverData && isMobileDataEnabled) || (!canDownloadOverData && !isMobileDataEnabled)) { - getDiscogsRetrofit() - .getArtistCover( - token = "Discogs token=addIURHUBwvyDlSqWcNqPWkHXUbMgUzNgbpZGZnd", - artist = artistName.value - ) - .enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.code() == 200) { + if (isInternetAvailable && canDownloadArtistCover) { + if ((canDownloadOverData && isMobileDataEnabled) || (!canDownloadOverData && !isMobileDataEnabled)) { + getDiscogsRetrofit() + .getArtistCover( + token = "Discogs token=addIURHUBwvyDlSqWcNqPWkHXUbMgUzNgbpZGZnd", + artist = artistName.value + ) + .enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.code() == 200) { - try { + try { - val data = Gson().fromJson(response.body(), DiscogsResponse::class.java) + val data = Gson().fromJson(response.body(), DiscogsResponse::class.java) - if (data.results.isNotEmpty()) { + if (data.results.isNotEmpty()) { - val imageUrl = data.results[0].cover_image + val imageUrl = data.results[0].cover_image - if (imageUrl.endsWith(".gif")) { + if (imageUrl.endsWith(".gif")) { - runBlocking { - withContext(Dispatchers.IO) { - artistsQueries.updateArtistCover(artistID, null) - artistsQueries.updateArtistAlreadyRequested(artistID) + runBlocking { + withContext(Dispatchers.IO) { + artistsCoversQueries.updateArtistCover(artistID, null) + artistsCoversQueries.updateArtistAlreadyRequested(artistID) + } } - } - } else { - Glide.with(context) - .asBitmap() - .load(imageUrl) - .into(object : CustomTarget() { - override fun onResourceReady(resource: Bitmap, transition: Transition?) { + } else { + Glide.with(context) + .asBitmap() + .load(imageUrl) + .into(object : CustomTarget() { + override fun onResourceReady(resource: Bitmap, transition: Transition?) { - val baos = ByteArrayOutputStream() + val baos = ByteArrayOutputStream() - resource.compress(Bitmap.CompressFormat.PNG, 50, baos) + resource.compress(Bitmap.CompressFormat.PNG, 50, baos) - val b = baos.toByteArray() + val b = baos.toByteArray() - val imageString = Base64.encodeToString(b, Base64.DEFAULT) + val imageString = Base64.encodeToString(b, Base64.DEFAULT) - runBlocking { - withContext(Dispatchers.IO) { - artistsQueries.updateArtistCover(artistID, imageString) - artistsQueries.updateArtistAlreadyRequested(artistID) + runBlocking { + withContext(Dispatchers.IO) { + artistsCoversQueries.updateArtistCover(artistID, imageString) + artistsCoversQueries.updateArtistAlreadyRequested(artistID) + } } - } - _tintCover.update { false } + _tintCover.update { false } - _artistCover.update { resource } - } + _artistCover.update { resource } + } - override fun onLoadCleared(placeholder: Drawable?) {} - }) + override fun onLoadCleared(placeholder: Drawable?) {} + }) + } } - } - } catch (exc: Exception) { + } catch (exc: Exception) { - Toast.makeText(context, exc.message.toString(), Toast.LENGTH_LONG).show() + Toast.makeText(context, exc.message.toString(), Toast.LENGTH_LONG).show() + } } } - } - override fun onFailure(call: Call, t: Throwable) { - Log.e("Discogs Error", "Error while getting artist cover") - } - }) + override fun onFailure(call: Call, t: Throwable) { + Log.e("Discogs Error", "Error while getting artist cover") + } + }) + } } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreen.kt index b3496f8..90c653f 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreen.kt @@ -8,21 +8,32 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomTextField import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.Routes +import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.functions.getAppString +import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -36,16 +47,19 @@ fun HomeScreen( ) { val scope = rememberCoroutineScope() + val context = LocalContext.current val screenLoaded = vm.screenLoaded.collectAsState().value val searchText = vm.searchText.collectAsState().value val menuExpanded = vm.menuExpanded.collectAsState().value - val songs = mainVM.songs.collectAsState().value + val songs = mainVM.songsData.collectAsState().value?.songs val currentSongs = vm.currentSongs.collectAsState().value val recentSongs = vm.recentSongs.collectAsState().value val oldestSongs = vm.oldestSongs.collectAsState().value val ascendentSongs = vm.ascendentSongs.collectAsState().value val descendentSongs = vm.descendentSongs.collectAsState().value - val selectedSong = mainVM.currentSong.collectAsState().value + val showReloadSongs = vm.showReloadSongsDialog.collectAsState().value + val songCount = mainVM.songCount.collectAsState().value + val indexedSongsCount = mainVM.indexedSongsCount.collectAsState().value if (!screenLoaded) { vm.loadScreen(mainVM) @@ -195,6 +209,15 @@ fun HomeScreen( } ) + DropdownMenuItem( + text = { + Text(text = stringResource(id = R.string.ReloadSongs)) + }, + onClick = { + vm.reloadSongs(mainVM) + } + ) + DropdownMenuItem( text = { Text(text = stringResource(id = R.string.Settings)) @@ -220,7 +243,7 @@ fun HomeScreen( } } - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( modifier = Modifier @@ -233,11 +256,10 @@ fun HomeScreen( key = { song -> song.id } ) { song -> - SongItem( + NewSongItem( modifier = Modifier.animateItemPlacement(), song = song, - songAlbumArt = mainVM.compressedSongsCovers.collectAsState().value?.find { it.albumID == song.albumID }?.albumArt, - highlight = song.path == selectedSong?.path, + mainVM = mainVM, menuEntries = menuEntries, onMenuClicked = { option -> @@ -256,6 +278,57 @@ fun HomeScreen( ) } } + + if (showReloadSongs) { + + Dialog( + onDismissRequest = { vm.updateShowReloadSongsDialog(false) }, + properties = DialogProperties( + dismissOnClickOutside = false, + dismissOnBackPress = false + ) + ) { + + Surface(shape = RoundedCornerShape(14.dp)) { + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(SMALL_SPACING) + ) { + + CustomText(text = getAppString(context, R.string.ReloadingSongs), weight = FontWeight.Bold) + + Text(color = MaterialTheme.colorScheme.onSurface, text = getAppString(context, R.string.DontCloseAppWhileReloading)) + + SmallVerticalSpacer() + + Row( + verticalAlignment = Alignment.CenterVertically + ) { + + CustomText(text = indexedSongsCount.toString()) + + SmallHorizontalSpacer() + + LinearProgressIndicator( + modifier = Modifier.fillMaxWidth().weight(1f, fill = true), + color = MaterialTheme.colorScheme.primary, + trackColor = MaterialTheme.colorScheme.surfaceVariant + ) + + SmallHorizontalSpacer() + + CustomText(text = songCount.toString()) + } + + SmallVerticalSpacer() + + + } + } + } + } } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreenVM.kt index 5568817..cf9b103 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/home/HomeScreenVM.kt @@ -3,13 +3,17 @@ package com.lighttigerxiv.simple.mp.compose.screens.main.home import android.app.Application import android.content.Context import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.Sorts import com.lighttigerxiv.simple.mp.compose.functions.unaccent +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class HomeScreenVM(application: Application) : AndroidViewModel(application) { @@ -56,6 +60,11 @@ class HomeScreenVM(application: Application) : AndroidViewModel(application) { private val _descendentSongs = MutableStateFlow?>(null) val descendentSongs = _descendentSongs.asStateFlow() + private val _showReloadSongsDialog = MutableStateFlow(false) + val showReloadSongsDialog= _showReloadSongsDialog.asStateFlow() + fun updateShowReloadSongsDialog(newValue:Boolean) { + _showReloadSongsDialog.update { newValue } + } //************************************************ // Functions @@ -64,30 +73,46 @@ class HomeScreenVM(application: Application) : AndroidViewModel(application) { fun loadScreen(mainVM: MainVM) { - val sortType = preferences.getString("HomeSongsSortType", Sorts.RECENT) - val songs = mainVM.songs.value + fun load(){ + val sortType = preferences.getString("HomeSongsSortType", Sorts.RECENT) + val songs = mainVM.songsData.value?.songs - if (songs != null) { + if (songs != null) { - _recentSongs.update { songs } + _recentSongs.update { songs } - _oldestSongs.update { songs.reversed() } + _oldestSongs.update { songs!!.reversed() } - _ascendentSongs.update { songs.sortedBy { it.title } } + _ascendentSongs.update { songs!!.sortedBy { it.title } } - _descendentSongs.update { songs.sortedByDescending { it.title } } + _descendentSongs.update { songs!!.sortedByDescending { it.title } } - _currentSongs.update { - when (sortType) { - Sorts.RECENT -> recentSongs.value - Sorts.OLDEST -> oldestSongs.value - Sorts.ASCENDENT -> ascendentSongs.value - else -> descendentSongs.value + _currentSongs.update { + when (sortType) { + Sorts.RECENT -> recentSongs.value + Sorts.OLDEST -> oldestSongs.value + Sorts.ASCENDENT -> ascendentSongs.value + else -> descendentSongs.value + } } + + _screenLoaded.update { true } } + } + + load() - _screenLoaded.update { true } + //Reloads the songs in case + viewModelScope.launch { + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() + filterSongs() + } + } } + + } fun filterSongs() { @@ -118,4 +143,19 @@ class HomeScreenVM(application: Application) : AndroidViewModel(application) { mainVM.selectSong(newQueue, newQueue.indexOf(song)) } + + fun reloadSongs(mainVM: MainVM){ + + viewModelScope.launch { + withContext(Dispatchers.IO){ + + _menuExpanded.update { false } + _showReloadSongsDialog.update { true } + + mainVM.indexSongs(onFinish = { + _showReloadSongsDialog.update { false } + }) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/player/PlayerScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/player/PlayerScreen.kt index b704e94..9b53e26 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/player/PlayerScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/player/PlayerScreen.kt @@ -31,7 +31,6 @@ import com.google.accompanist.pager.rememberPagerState import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song -import com.lighttigerxiv.simple.mp.compose.data.data_classes.SongCover import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING @@ -44,7 +43,7 @@ import com.lighttigerxiv.simple.mp.compose.ui.composables.BottomSheetHandle import com.lighttigerxiv.simple.mp.compose.ui.composables.ClickableMediumIcon import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.ReorderableSongItem -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.drop @@ -73,8 +72,6 @@ fun Player( val currentSongMinutesAndSecondsText = mainVM.currentSongMinutesAndSecondsText.collectAsState().value val songAndQueuePager = rememberPagerState(2) val songsCoversPager = rememberPagerState(pageCount = queue?.size ?: 0) - val compressedSongsCovers = mainVM.compressedSongsCovers.collectAsState().value - val songsCovers = mainVM.songsCovers.collectAsState().value val musicPlaying = mainVM.musicPlayling.collectAsState().value val queueShuffled = mainVM.queueShuffled.collectAsState().value val songOnRepeat = mainVM.songOnRepeat.collectAsState().value @@ -156,8 +153,6 @@ fun Player( mainVM, surfaceColor, selectedSong, - songsCovers, - compressedSongsCovers, queue, upNextQueue, musicPlaying, @@ -181,8 +176,6 @@ fun Player( mainVM, surfaceColor, selectedSong, - songsCovers, - compressedSongsCovers, queue, upNextQueue, musicPlaying, @@ -212,9 +205,7 @@ fun PortraitPlayer( vm: PlayerScreenVM, mainVM: MainVM, surfaceColor: Color, - selectedSong: Song, - songsCovers: List?, - compressedSongsCovers: List?, + currentSong: Song, queue: List?, upNextQueue: List?, musicPlaying: Boolean, @@ -332,7 +323,7 @@ fun PortraitPlayer( itemSpacing = SMALL_SPACING ) { currentCoverIndex-> - val songAlbumArt = songsCovers?.first { it.albumID == queue!![currentCoverIndex].albumID }?.albumArt + val songAlbumArt = mainVM.getSongArt(queue!![currentCoverIndex]) Image( modifier = Modifier @@ -371,14 +362,14 @@ fun PortraitPlayer( ) { CustomText( - text = selectedSong.title, + text = currentSong.title, size = 18.sp, weight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary ) CustomText( - text = selectedSong.artist, + text = mainVM.getSongArtist(currentSong).name, size = 18.sp ) } @@ -414,7 +405,7 @@ fun PortraitPlayer( }, onClick = { - onOpenPage("${Routes.Root.FLOATING_ARTIST}${selectedSong.artistID}") + onOpenPage("${Routes.Root.FLOATING_ARTIST}${currentSong.artistID}") vm.updateShowMenu(false) } ) @@ -425,7 +416,7 @@ fun PortraitPlayer( }, onClick = { - onOpenPage("${Routes.Root.FLOATING_ALBUM}${selectedSong.albumID}") + onOpenPage("${Routes.Root.FLOATING_ALBUM}${currentSong.albumID}") vm.updateShowMenu(false) } ) @@ -436,7 +427,7 @@ fun PortraitPlayer( }, onClick = { - onOpenPage("${Routes.Root.ADD_SONG_TO_PLAYLIST}${selectedSong.id}") + onOpenPage("${Routes.Root.ADD_SONG_TO_PLAYLIST}${currentSong.id}") vm.updateShowMenu(false) } @@ -460,7 +451,7 @@ fun PortraitPlayer( mainVM.seekSongSeconds(secondsSliderValue.toInt()) }, - valueRange = 1f..(selectedSong.duration / 1000).toFloat(), + valueRange = 1f..(currentSong.duration / 1000).toFloat(), colors = SliderDefaults.colors( thumbColor = MaterialTheme.colorScheme.primary, activeTrackColor = MaterialTheme.colorScheme.primary, @@ -618,7 +609,7 @@ fun PortraitPlayer( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() CustomText(text = stringResource(id = R.string.Shrug)) } @@ -638,7 +629,6 @@ fun PortraitPlayer( ReorderableSongItem( mainVM = mainVM, song = song, - songAlbumArt = remember { compressedSongsCovers?.find { it.albumID == song.albumID }?.albumArt }, state = state, isDragging = isDragging ) @@ -660,9 +650,7 @@ fun LandscapePlayer( vm: PlayerScreenVM, mainVM: MainVM, surfaceColor: Color, - selectedSong: Song, - songsCovers: List?, - compressedSongsCovers: List?, + currentSong: Song, queue: List?, upNextQueue: List?, musicPlaying: Boolean, @@ -782,7 +770,7 @@ fun LandscapePlayer( itemSpacing = SMALL_SPACING ) { currentCoverIndex-> - val songAlbumArt = songsCovers?.first { it.albumID == queue!![currentCoverIndex].albumID }?.albumArt + val songAlbumArt = mainVM.getSongArt(queue!![currentCoverIndex]) Image( modifier = Modifier @@ -824,14 +812,14 @@ fun LandscapePlayer( ) { CustomText( - text = selectedSong.title, + text = currentSong.title, size = 18.sp, weight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary ) CustomText( - text = selectedSong.artist, + text = mainVM.getSongArtist(currentSong).name, size = 18.sp ) } @@ -867,7 +855,7 @@ fun LandscapePlayer( }, onClick = { - onOpenPage("${Routes.Root.FLOATING_ARTIST}${selectedSong.artistID}") + onOpenPage("${Routes.Root.FLOATING_ARTIST}${currentSong.artistID}") vm.updateShowMenu(false) } ) @@ -878,7 +866,7 @@ fun LandscapePlayer( }, onClick = { - onOpenPage("${Routes.Root.FLOATING_ALBUM}${selectedSong.albumID}") + onOpenPage("${Routes.Root.FLOATING_ALBUM}${currentSong.albumID}") vm.updateShowMenu(false) } ) @@ -889,7 +877,7 @@ fun LandscapePlayer( }, onClick = { - onOpenPage("${Routes.Root.ADD_SONG_TO_PLAYLIST}${selectedSong.id}") + onOpenPage("${Routes.Root.ADD_SONG_TO_PLAYLIST}${currentSong.id}") vm.updateShowMenu(false) } @@ -913,7 +901,7 @@ fun LandscapePlayer( mainVM.seekSongSeconds(secondsSliderValue.toInt()) }, - valueRange = 1f..(selectedSong.duration / 1000).toFloat(), + valueRange = 1f..(currentSong.duration / 1000).toFloat(), colors = SliderDefaults.colors( thumbColor = MaterialTheme.colorScheme.primary, activeTrackColor = MaterialTheme.colorScheme.primary, @@ -1071,7 +1059,7 @@ fun LandscapePlayer( horizontalAlignment = Alignment.CenterHorizontally ) { - SmallHeightSpacer() + SmallVerticalSpacer() CustomText(text = stringResource(id = R.string.Shrug)) } @@ -1091,7 +1079,6 @@ fun LandscapePlayer( ReorderableSongItem( mainVM = mainVM, song = song, - songAlbumArt = remember { compressedSongsCovers?.find { it.albumID == song.albumID }?.albumArt }, state = state, isDragging = isDragging ) diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreen.kt index bde8a4a..c5f3519 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreen.kt @@ -36,7 +36,7 @@ import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING import com.lighttigerxiv.simple.mp.compose.ui.composables.SheetDraggingBar -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import kotlinx.coroutines.launch @@ -218,7 +218,7 @@ fun PlaylistsScreen( SheetDraggingBar() - MediumHeightSpacer() + MediumVerticalSpacer() Text( text = remember { getAppString(context, R.string.PlaylistName) }, @@ -234,7 +234,7 @@ fun PlaylistsScreen( textType = "text" ) - MediumHeightSpacer() + MediumVerticalSpacer() Row( horizontalArrangement = Arrangement.End, @@ -301,7 +301,7 @@ fun PlaylistsScreen( ) } - MediumHeightSpacer() + MediumVerticalSpacer() LazyVerticalGrid( state = userPlaylistsGridState, diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreenVM.kt index e02edc9..29772b5 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/PlaylistsScreenVM.kt @@ -4,6 +4,7 @@ import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner +import androidx.lifecycle.viewModelScope import androidx.navigation.NavHostController import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.mongodb.getMongoRealm @@ -12,9 +13,12 @@ import com.lighttigerxiv.simple.mp.compose.data.mongodb.queries.PlaylistsQueries import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.functions.unaccent import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.PlaylistScreenVM +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.net.URLEncoder class PlaylistsScreenVM(application: Application) : AndroidViewModel(application) { @@ -64,22 +68,35 @@ class PlaylistsScreenVM(application: Application) : AndroidViewModel(application fun loadScreen(mainVM: MainVM) { - val songs = mainVM.songs.value - val newGenres = ArrayList() + fun load(){ + val songs = mainVM.songsData.value?.songs + val newGenres = ArrayList() - if (songs != null) { + if (songs != null) { - songs.forEach { - newGenres.add(it.genre) - } + songs.forEach { + newGenres.add(it.genre) + } + + _genres.update { newGenres.distinctBy { it }.sortedBy { it } } + + _playlists.update { playlistsQueries.getPlaylists() } - _genres.update { newGenres.distinctBy { it }.sortedBy { it } } + _currentPlaylists.update { playlists.value } - _playlists.update { playlistsQueries.getPlaylists() } + _screenLoaded.update { true } + } + } - _currentPlaylists.update { playlists.value } + load() - _screenLoaded.update { true } + viewModelScope.launch{ + withContext(Dispatchers.IO){ + mainVM.songsData.collect{ + load() + filterPlaylists() + } + } } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/genre_playlists/GenrePlaylistScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/genre_playlists/GenrePlaylistScreen.kt index d15e056..46872d3 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/genre_playlists/GenrePlaylistScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/genre_playlists/GenrePlaylistScreen.kt @@ -24,12 +24,12 @@ import androidx.compose.ui.unit.sp import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar import com.lighttigerxiv.simple.mp.compose.ui.composables.PlayAndShuffleRow -import com.lighttigerxiv.simple.mp.compose.ui.composables.SongItem import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.NewSongItem +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import moe.tlaster.nestedscrollview.VerticalNestedScrollView import moe.tlaster.nestedscrollview.rememberNestedScrollViewState @@ -43,9 +43,7 @@ fun GenrePlaylistScreen( val configuration = LocalConfiguration.current val inPortrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT val surfaceColor = mainVM.surfaceColor.collectAsState().value - val selectedSong = mainVM.currentSong.collectAsState().value - val songs = mainVM.songs.collectAsState().value - val songsImages = mainVM.songsCovers.collectAsState().value + val songs = mainVM.songsData.collectAsState().value?.songs val playlist = songs?.filter { it.genre == genre } @@ -73,7 +71,7 @@ fun GenrePlaylistScreen( onBackClick = {onBackClicked()} ) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -93,7 +91,7 @@ fun GenrePlaylistScreen( ) } - SmallHeightSpacer() + SmallVerticalSpacer() Text( text = genre, @@ -104,7 +102,7 @@ fun GenrePlaylistScreen( modifier = Modifier.fillMaxWidth() ) - MediumHeightSpacer() + MediumVerticalSpacer() } }, content = { @@ -119,7 +117,7 @@ fun GenrePlaylistScreen( onSuffleClick = {mainVM.shuffleAndPlay(playlist)} ) - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( content = { @@ -128,10 +126,9 @@ fun GenrePlaylistScreen( items = playlist, key = { _, song -> song.id} ){ index, song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = songsImages?.find { song.albumID == it.albumID }?.albumArt, - highlight = song.path == selectedSong?.path, onSongClick = {mainVM.selectSong(playlist, position = index)} ) } @@ -151,7 +148,7 @@ fun GenrePlaylistScreen( CustomToolbar(backText = stringResource(id = R.string.Albums), onBackClick = { onBackClicked() }) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -181,7 +178,7 @@ fun GenrePlaylistScreen( ) - SmallHeightSpacer() + SmallVerticalSpacer() Text( text = genre, @@ -192,7 +189,7 @@ fun GenrePlaylistScreen( modifier = Modifier.fillMaxWidth() ) - MediumHeightSpacer() + MediumVerticalSpacer() } Column( @@ -208,7 +205,7 @@ fun GenrePlaylistScreen( onSuffleClick = {mainVM.shuffleAndPlay(playlist)} ) - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( content = { @@ -217,10 +214,9 @@ fun GenrePlaylistScreen( items = playlist, key = { _, song -> song.id} ){ index, song -> - SongItem( + NewSongItem( + mainVM = mainVM, song = song, - songAlbumArt = songsImages?.find { song.albumID == it.albumID }?.albumArt, - highlight = song.path == selectedSong?.path, onSongClick = {mainVM.selectSong(playlist, position = index)} ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreen.kt index 524eeec..cb9f18d 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreen.kt @@ -35,7 +35,6 @@ import com.lighttigerxiv.simple.mp.compose.* import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song -import com.lighttigerxiv.simple.mp.compose.data.data_classes.SongCover import com.lighttigerxiv.simple.mp.compose.data.mongodb.items.Playlist import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING @@ -79,8 +78,6 @@ fun PlaylistScreen( val onEditMode = vm.onEditMode.collectAsState().value val playlistNameText = vm.playlistNameText.collectAsState().value val currentSong = mainVM.currentSong.collectAsState().value - val songsCovers = mainVM.songsCovers.collectAsState().value - if (!screenLoaded) { vm.loadScreen(playlistID, mainVM, playlistsVM) @@ -114,7 +111,7 @@ fun PlaylistScreen( text = stringResource(id = R.string.SelectImage) ) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -140,7 +137,7 @@ fun PlaylistScreen( ) } - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier @@ -169,7 +166,7 @@ fun PlaylistScreen( } ) { bottomSheetScaffoldPadding -> - if(inPortrait){ + if (inPortrait) { VerticalNestedScrollView( modifier = Modifier .background(surfaceColor) @@ -195,7 +192,7 @@ fun PlaylistScreen( showDeleteDialog ) - MediumHeightSpacer() + MediumVerticalSpacer() PlaylistCoverAndName( vm, @@ -220,10 +217,10 @@ fun PlaylistScreen( surfaceColor, surfaceVariantColor, currentSong, - songsCovers + //songsCovers ) } - }else{ + } else { Column( modifier = Modifier @@ -243,9 +240,9 @@ fun PlaylistScreen( showDeleteDialog ) - MediumHeightSpacer() + MediumVerticalSpacer() - if(screenLoaded){ + if (screenLoaded) { Row( modifier = Modifier @@ -288,20 +285,13 @@ fun PlaylistScreen( onEditMode, surfaceColor, surfaceVariantColor, - currentSong, - songsCovers + currentSong ) } } } } - - - - } - - } } } @@ -319,7 +309,7 @@ fun PlaylistToolbar( saveButtonEnabled: Boolean, showMenu: Boolean, showDeleteDialog: Boolean -){ +) { val scope = rememberCoroutineScope() val context = LocalContext.current @@ -502,13 +492,13 @@ fun PlaylistToolbar( color = MaterialTheme.colorScheme.primary ) - SmallHeightSpacer() + SmallVerticalSpacer() Text( text = stringResource(id = R.string.ConfirmDeletePlaylist) ) - MediumHeightSpacer() + MediumVerticalSpacer() Row( modifier = Modifier @@ -579,7 +569,7 @@ fun PlaylistCoverAndName( playlistNameText: String, playlist: Playlist?, -){ + ) { val scope = rememberCoroutineScope() @@ -591,7 +581,7 @@ fun PlaylistCoverAndName( horizontalArrangement = Arrangement.Center ) { - if(inPortrait){ + if (inPortrait) { Image( bitmap = playlistImage!!, contentDescription = null, @@ -617,7 +607,7 @@ fun PlaylistCoverAndName( } } ) - }else{ + } else { Image( bitmap = playlistImage!!, contentDescription = null, @@ -646,7 +636,7 @@ fun PlaylistCoverAndName( } } - SmallHeightSpacer() + SmallVerticalSpacer() when (onEditMode) { @@ -663,6 +653,7 @@ fun PlaylistCoverAndName( } ) } + false -> { Text( @@ -676,7 +667,7 @@ fun PlaylistCoverAndName( } } - MediumHeightSpacer() + MediumVerticalSpacer() } } @@ -691,8 +682,8 @@ fun PlaylistSongs( surfaceColor: Color, surfaceVariantColor: Color, currentSong: Song?, - songsCovers: List? -){ + //songsCovers: List? +) { val context = LocalContext.current @@ -725,7 +716,7 @@ fun PlaylistSongs( } } - MediumHeightSpacer() + MediumVerticalSpacer() LazyColumn( content = { @@ -736,9 +727,9 @@ fun PlaylistSongs( ) { index, song -> val songTitle = remember { song.title } - val songArtist = remember { song.artist } + val songArtist = remember { mainVM.getSongArtist(song).name } val highlight = song.path == currentSong?.path - val songAlbumArt = songsCovers?.find { it.albumID == song.albumID }?.albumArt + val songAlbumArt = remember { mainVM.getSongArt(song) } val titleColor = when (highlight) { diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreenVM.kt index ca6ce88..a6f49f1 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/PlaylistScreenVM.kt @@ -145,8 +145,8 @@ class PlaylistScreenVM(application: Application) : AndroidViewModel(application) val newSongs = ArrayList() songsIDS.forEach { songID -> - if (mainVM.songs.value!!.any { it.id == songID }) { - newSongs.add(mainVM.songs.value!!.first { it.id == songID }) + if (mainVM.songsData.value?.songs!!.any { it.id == songID }) { + newSongs.add(mainVM.songsData.value?.songs!!.first { it.id == songID }) } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreen.kt index f9d3e1d..18f0850 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreen.kt @@ -29,7 +29,7 @@ import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomText import com.lighttigerxiv.simple.mp.compose.ui.composables.CustomToolbar -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.XSmallHeightSpacer import com.lighttigerxiv.simple.mp.compose.screens.main.playlists.playlist.PlaylistScreenVM @@ -52,7 +52,7 @@ fun AddSongsScreen( val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant val screenLoaded = addSongsVM.screenLoaded.collectAsState().value val songs = addSongsVM.songs.collectAsState().value - val songsCovers = mainVM.compressedSongsCovers.collectAsState().value + val songsData = mainVM.songsData.collectAsState().value if (!screenLoaded) { addSongsVM.loadScreen(playlistID, mainVM) @@ -72,7 +72,7 @@ fun AddSongsScreen( } ) - MediumHeightSpacer() + MediumVerticalSpacer() if (screenLoaded) { @@ -87,7 +87,8 @@ fun AddSongsScreen( key = { it.id } ) { song -> - val songAlbumArt = songsCovers?.find { it.albumID == song.albumID }?.albumArt + val art = remember { songsData?.albums?.first { it.id == song.albumID }?.art } + val artistName = remember { songsData?.artists?.first { it.id == song.artistID }?.name ?: "" } Column { Row( @@ -103,17 +104,17 @@ fun AddSongsScreen( ) { AsyncImage( - model = remember { songAlbumArt ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, + model = remember { art ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, contentDescription = null, - colorFilter = if (songAlbumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + colorFilter = if (art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, modifier = Modifier .clip(RoundedCornerShape(14.dp)) .height(70.dp) .width(70.dp) - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { background(surfaceVariantColor) } - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { padding(5.dp) } ) @@ -132,7 +133,7 @@ fun AddSongsScreen( ) CustomText( - text = song.artist + text = artistName ) } @@ -152,7 +153,7 @@ fun AddSongsScreen( } } - MediumHeightSpacer() + MediumVerticalSpacer() Button( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreenVM.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreenVM.kt index e39ccf0..cb8e685 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreenVM.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/playlists/playlist/add_songs/AddSongsScreenVM.kt @@ -22,7 +22,7 @@ class AddSongsScreenVM(application: Application) : AndroidViewModel(application) val title: String, val selected: Boolean, val albumID: Long, - val artist: String + val artistID: Long ) @@ -30,8 +30,6 @@ class AddSongsScreenVM(application: Application) : AndroidViewModel(application) // Variables //************************************************ - private val context = application - private val playlistsQueries = PlaylistsQueries(getMongoRealm()) private val _screenLoaded = MutableStateFlow(false) @@ -50,7 +48,7 @@ class AddSongsScreenVM(application: Application) : AndroidViewModel(application) val playlist = playlistsQueries.getPlaylist(playlistID) - val songs = mainVM.songs.value + val songs = mainVM.songsData.value?.songs val temp = ArrayList() @@ -62,7 +60,7 @@ class AddSongsScreenVM(application: Application) : AndroidViewModel(application) title = song.title, selected = false, albumID = song.albumID, - artist = song.artist + artistID = song.artistID )) } @@ -107,7 +105,7 @@ class AddSongsScreenVM(application: Application) : AndroidViewModel(application) val newSongs = ArrayList() - val songs = mainVM.songs.value + val songs = mainVM.songsData.value?.songs songs!!.forEach {song-> playlistSongsIDS.forEach { playlistSongID-> diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/SettingsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/SettingsScreen.kt index 878f192..217d65c 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/SettingsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/SettingsScreen.kt @@ -26,7 +26,7 @@ import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.data.variables.SettingsValues import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer @Composable fun SettingsScreen( @@ -72,7 +72,7 @@ fun SettingsScreen( onBackClick = { onBackPressed() } ) - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier.fillMaxWidth() @@ -88,7 +88,7 @@ fun SettingsScreen( ) } - SmallHeightSpacer() + SmallVerticalSpacer() Column( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/themes/ThemesScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/themes/ThemesScreen.kt index 16460b5..3c6d14c 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/themes/ThemesScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/main/settings/themes/ThemesScreen.kt @@ -14,7 +14,7 @@ import com.lighttigerxiv.simple.mp.compose.ui.composables.ThemeSelector import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer @Composable fun ThemesScreen( @@ -39,7 +39,7 @@ fun ThemesScreen( onBackClick = { onBackClick() } ) - MediumHeightSpacer() + MediumVerticalSpacer() Column( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/other/OtherScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/other/OtherScreen.kt index 07a3921..4875879 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/other/OtherScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/other/OtherScreen.kt @@ -42,8 +42,8 @@ import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.functions.getImage import com.lighttigerxiv.simple.mp.compose.screens.main.settings.SwitchSettingItem import com.lighttigerxiv.simple.mp.compose.settings.SettingsVM -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.text.TitleMedium @Composable @@ -91,7 +91,7 @@ fun OtherScreen( colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary) ) - SmallHeightSpacer() + SmallVerticalSpacer() TitleMedium( text = stringResource(id = R.string.OtherSettings), @@ -103,7 +103,7 @@ fun OtherScreen( Column( modifier = Modifier ) { - MediumHeightSpacer() + MediumVerticalSpacer() Column( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/permissions/PermissionsScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/permissions/PermissionsScreen.kt index a9ed9fe..1d5d894 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/permissions/PermissionsScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/permissions/PermissionsScreen.kt @@ -29,8 +29,8 @@ import com.lighttigerxiv.simple.mp.compose.data.variables.MEDIUM_RADIUS import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHorizontalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.text.TitleMedium import com.lighttigerxiv.simple.mp.compose.functions.getAppString @@ -101,7 +101,7 @@ fun PermissionsScreen( colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary) ) - SmallHeightSpacer() + SmallVerticalSpacer() TitleMedium( text = stringResource(id = R.string.Permissions), @@ -113,7 +113,7 @@ fun PermissionsScreen( Column( modifier = Modifier ) { - MediumHeightSpacer() + MediumVerticalSpacer() //Storage Permission Card Row( @@ -177,7 +177,7 @@ fun PermissionsScreen( onResult = { granted -> permissionsVM.updateNotificationsPermissionGranted(granted) } ) - SmallHeightSpacer() + SmallVerticalSpacer() Row( modifier = Modifier diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/themes/ThemesScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/themes/ThemesScreen.kt index 2c716c6..de90645 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/themes/ThemesScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/themes/ThemesScreen.kt @@ -23,8 +23,8 @@ import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING import com.lighttigerxiv.simple.mp.compose.activities.main.MainActivity import com.lighttigerxiv.simple.mp.compose.ui.composables.ThemeSelector -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.SmallVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.text.TitleMedium import com.lighttigerxiv.simple.mp.compose.functions.getAppString import com.lighttigerxiv.simple.mp.compose.activities.setup.ActivitySetupVM @@ -81,7 +81,7 @@ fun ThemesScreen( colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary) ) - SmallHeightSpacer() + SmallVerticalSpacer() TitleMedium( text = stringResource(id = R.string.Theming), @@ -89,7 +89,7 @@ fun ThemesScreen( ) } - MediumHeightSpacer() + MediumVerticalSpacer() ThemeSelector( selectedTheme = selectedTheme, diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/welcome/WelcomeScreen.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/welcome/WelcomeScreen.kt index c074cbf..557efc3 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/screens/setup/welcome/WelcomeScreen.kt @@ -19,7 +19,7 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import com.lighttigerxiv.simple.mp.compose.data.variables.Routes import com.lighttigerxiv.simple.mp.compose.data.variables.SCREEN_PADDING -import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumHeightSpacer +import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.MediumVerticalSpacer import com.lighttigerxiv.simple.mp.compose.ui.composables.text.TitleMedium @Composable @@ -60,7 +60,7 @@ fun WelcomeScreen( ) } - MediumHeightSpacer() + MediumVerticalSpacer() TitleMedium( text = stringResource(id = R.string.WelcomeToSimpleMP), diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/services/SimpleMPService.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/services/SimpleMPService.kt index f5135b1..83813a3 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/services/SimpleMPService.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/services/SimpleMPService.kt @@ -3,7 +3,6 @@ package com.lighttigerxiv.simple.mp.compose.services import android.app.* import android.appwidget.AppWidgetManager import android.content.* -import android.graphics.Bitmap import android.media.* import android.media.AudioManager.OnAudioFocusChangeListener import android.os.Binder @@ -19,9 +18,9 @@ import androidx.core.app.NotificationCompat import com.lighttigerxiv.simple.mp.compose.R import com.lighttigerxiv.simple.mp.compose.data.data_classes.Song import com.lighttigerxiv.simple.mp.compose.activities.main.MainActivity +import com.lighttigerxiv.simple.mp.compose.activities.main.MainVM import com.lighttigerxiv.simple.mp.compose.data.variables.ImageSizes import com.lighttigerxiv.simple.mp.compose.functions.getImage -import com.lighttigerxiv.simple.mp.compose.functions.getSongAlbumArt import com.lighttigerxiv.simple.mp.compose.widgets.SimpleMPWidget import org.burnoutcrew.reorderable.ItemPosition @@ -39,6 +38,8 @@ class SimpleMPService : Service() { private lateinit var audioManager: AudioManager val mediaPlayer = MediaPlayer() + lateinit var mainVM: MainVM + //Listeners var onSongSelected: (song: Song) -> Unit = {} @@ -169,13 +170,13 @@ class SimpleMPService : Service() { return upNextQueueList } - fun updateQueue(from: ItemPosition, to: ItemPosition){ + fun updateQueue(from: ItemPosition, to: ItemPosition) { queueList = queueList.apply { add(queueList.indexOfFirst { it.id == to.key }, removeAt(queueList.indexOfFirst { it.id == from.key })) } - if(queueShuffled){ + if (queueShuffled) { shuffledQueueList = shuffledQueueList.apply { add(shuffledQueueList.indexOfFirst { it.id == to.key }, removeAt(shuffledQueueList.indexOfFirst { it.id == from.key })) } @@ -339,133 +340,116 @@ class SimpleMPService : Service() { serviceStarted = true musicStarted = true - val songTitle: String - val songArtist: String - val songID: Long - val songAlbumID: Long - var songAlbumArt: Bitmap? - val songDuration: Int + val songsData = mainVM.songsData.value + val artists = songsData?.artists + if (artists != null) { - if (!queueShuffled) { + currentSong = getQueue()[currentSongPosition] - songTitle = queueList[currentSongPosition].title - songArtist = queueList[currentSongPosition].artist - songID = queueList[currentSongPosition].id - songAlbumID = queueList[currentSongPosition].albumID - songAlbumArt = getSongAlbumArt(context, songID, songAlbumID) - songDuration = queueList[currentSongPosition].duration - } else { + val art = if (mainVM.getSongArt(currentSong!!) != null) { + mainVM.getSongArt(currentSong!!) + } else { + getImage(context, R.drawable.cd_filled, ImageSizes.LARGE) + } - songTitle = shuffledQueueList[currentSongPosition].title - songArtist = shuffledQueueList[currentSongPosition].artist - songID = shuffledQueueList[currentSongPosition].id - songAlbumID = shuffledQueueList[currentSongPosition].albumID - songAlbumArt = getSongAlbumArt(context, songID, songAlbumID) - songDuration = shuffledQueueList[currentSongPosition].duration - } + mediaPlayer.reset() + mediaPlayer.setDataSource(currentSong!!.path) + mediaPlayer.prepareAsync() + mediaPlayer.setOnPreparedListener { - if (songAlbumArt == null) { - songAlbumArt = getImage(context, R.drawable.cd_filled, ImageSizes.LARGE) - } + audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager - currentSong = getQueue()[currentSongPosition] + requestPlayWithFocus() - mediaPlayer.reset() - mediaPlayer.setDataSource(currentSong!!.path) - mediaPlayer.prepareAsync() - mediaPlayer.setOnPreparedListener { + //Open App + val openAppIntent = Intent(context, MainActivity::class.java) + val pendingOpenAppIntent = TaskStackBuilder.create(context).run { - audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager + addNextIntentWithParentStack(openAppIntent) + getPendingIntent(0, PendingIntent.FLAG_IMMUTABLE) + } - requestPlayWithFocus() + //Stop Service + val stopIntent = Intent(context, ReceiverStop::class.java) + val pendingStopIntent = PendingIntent.getBroadcast(context, 1, stopIntent, PendingIntent.FLAG_IMMUTABLE) - //Open App - val openAppIntent = Intent(context, MainActivity::class.java) - val pendingOpenAppIntent = TaskStackBuilder.create(context).run { - addNextIntentWithParentStack(openAppIntent) - getPendingIntent(0, PendingIntent.FLAG_IMMUTABLE) - } + //Previous Music + val previousSongIntent = Intent(context, ReceiverPreviousSong::class.java) + val pendingPreviousSongIntent = PendingIntent.getBroadcast(context, 1, previousSongIntent, PendingIntent.FLAG_IMMUTABLE) - //Stop Service - val stopIntent = Intent(context, ReceiverStop::class.java) - val pendingStopIntent = PendingIntent.getBroadcast(context, 1, stopIntent, PendingIntent.FLAG_IMMUTABLE) + //Pauses/Plays music + val playPauseIntent = Intent(context, ReceiverPlayPause::class.java) + val pendingPlayPauseIntent = PendingIntent.getBroadcast(context, 1, playPauseIntent, PendingIntent.FLAG_IMMUTABLE) - //Previous Music - val previousSongIntent = Intent(context, ReceiverPreviousSong::class.java) - val pendingPreviousSongIntent = PendingIntent.getBroadcast(context, 1, previousSongIntent, PendingIntent.FLAG_IMMUTABLE) + //Skips to next music + val skipSongIntent = Intent(context, ReceiverSkipSong::class.java) + val pendingSkipSongIntent = PendingIntent.getBroadcast(context, 1, skipSongIntent, PendingIntent.FLAG_IMMUTABLE) - //Pauses/Plays music - val playPauseIntent = Intent(context, ReceiverPlayPause::class.java) - val pendingPlayPauseIntent = PendingIntent.getBroadcast(context, 1, playPauseIntent, PendingIntent.FLAG_IMMUTABLE) - //Skips to next music - val skipSongIntent = Intent(context, ReceiverSkipSong::class.java) - val pendingSkipSongIntent = PendingIntent.getBroadcast(context, 1, skipSongIntent, PendingIntent.FLAG_IMMUTABLE) + notification = NotificationCompat.Builder(context, "Playback") + .setContentIntent(pendingOpenAppIntent) + .setStyle( + androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(mediaSession.sessionToken) + .setShowActionsInCompactView(0, 1, 2, 3) + ) + .setSmallIcon(R.drawable.icon) + .addAction(R.drawable.icon_x_solid, "Stop Player", pendingStopIntent) + .addAction(R.drawable.icon_previous_notification, "Previous Music", pendingPreviousSongIntent) + .addAction(R.drawable.icon_pause_notification, "Play Pause Music", pendingPlayPauseIntent) + .addAction(R.drawable.icon_next_notification, "Next Music", pendingSkipSongIntent) + .build() + mediaSession.setMetadata( + MediaMetadataCompat.Builder() - notification = NotificationCompat.Builder(context, "Playback") - .setContentIntent(pendingOpenAppIntent) - .setStyle( - androidx.media.app.NotificationCompat.MediaStyle() - .setMediaSession(mediaSession.sessionToken) - .setShowActionsInCompactView(0, 1, 2, 3) + .putString(MediaMetadata.METADATA_KEY_TITLE, currentSong!!.title) + .putString(MediaMetadata.METADATA_KEY_ARTIST, artists.first { it.id == currentSong!!.artistID }.name) + .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, art) + .putLong(MediaMetadata.METADATA_KEY_DURATION, currentSong!!.duration.toLong()) + .build() ) - .setSmallIcon(R.drawable.icon) - .addAction(R.drawable.icon_x_solid, "Stop Player", pendingStopIntent) - .addAction(R.drawable.icon_previous_notification, "Previous Music", pendingPreviousSongIntent) - .addAction(R.drawable.icon_pause_notification, "Play Pause Music", pendingPlayPauseIntent) - .addAction(R.drawable.icon_next_notification, "Next Music", pendingSkipSongIntent) - .build() - - - mediaSession.setMetadata( - MediaMetadataCompat.Builder() - - .putString(MediaMetadata.METADATA_KEY_TITLE, songTitle) - .putString(MediaMetadata.METADATA_KEY_ARTIST, songArtist) - .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, songAlbumArt) - .putLong(MediaMetadata.METADATA_KEY_DURATION, songDuration.toLong()) - .build() - ) - startForeground(2, notification) - notificationManager.notify(2, notification) - } + startForeground(2, notification) + notificationManager.notify(2, notification) + } - handleSongFinished(context) + handleSongFinished(context) - onSongSelected(currentSong!!) - onSongSelectedForPlayer(currentSong!!) - onSongSelectedForWidget(currentSong!!) + onSongSelected(currentSong!!) + onSongSelectedForPlayer(currentSong!!) + onSongSelectedForWidget(currentSong!!) - val bluetoothReceiver = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) - context.registerReceiver(bluetoothBroadcastReceiver, bluetoothReceiver) + val bluetoothReceiver = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) + context.registerReceiver(bluetoothBroadcastReceiver, bluetoothReceiver) - val mainHandler = Handler(Looper.getMainLooper()) - mainHandler.post(object : Runnable { - override fun run() { + val mainHandler = Handler(Looper.getMainLooper()) + mainHandler.post(object : Runnable { + override fun run() { - if (musicPlaying()) { + if (musicPlaying()) { - onSecondPassed() - setPlaybackState(PlaybackStateCompat.STATE_PLAYING) + onSecondPassed() + setPlaybackState(PlaybackStateCompat.STATE_PLAYING) + } + mainHandler.postDelayed(this, 1000) } - mainHandler.postDelayed(this, 1000) - } - }) + }) + } - } catch (exc:Exception){ + + } catch (exc: Exception) { Log.e("Service Error", exc.toString()) selectNextSong(context) } @@ -486,7 +470,7 @@ class SimpleMPService : Service() { mediaSession.setPlaybackState(stateBuilder.build()) - } catch (exc:Exception){ + } catch (exc: Exception) { Log.e("Service Error", exc.toString()) } } @@ -610,7 +594,7 @@ class SimpleMPService : Service() { startForeground(2, notification) notificationManager.notify(2, notification) - }catch (exc:Exception){ + } catch (exc: Exception) { Log.e("Service Error", exc.toString()) } } @@ -670,6 +654,7 @@ class SimpleMPService : Service() { true } + else -> false } } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/MiniPlayer.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/MiniPlayer.kt index ec20379..4ca11b5 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/MiniPlayer.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/MiniPlayer.kt @@ -28,13 +28,12 @@ fun MiniPlayer( mainVM: MainVM ) { - val context = LocalContext.current - val selectedSong = mainVM.currentSong.collectAsState().value - val songAlbumArt = mainVM.currentSongAlbumArt.collectAsState().value - val musicPlaying = mainVM.musicPlayling.collectAsState().value + val song = mainVM.currentSong.collectAsState().value + val art = mainVM.currentSongAlbumArt.collectAsState().value + val musicIsPlaying = mainVM.musicPlayling.collectAsState().value val surfaceColor = mainVM.surfaceColor.collectAsState().value - val playPauseIcon = if (musicPlaying) { + val playPauseIcon = if (musicIsPlaying) { remember { getImage(context, R.drawable.icon_pause_solid, ImageSizes.SMALL) } } else { remember { getImage(context, R.drawable.icon_play_solid, ImageSizes.SMALL) } @@ -48,19 +47,21 @@ fun MiniPlayer( .padding(SMALL_SPACING) ) { - if (selectedSong != null) { + if (song != null) { + + val artistName = mainVM.getSongArtist(song).name Image( - bitmap = (songAlbumArt ?: getImage(context, R.drawable.cd, ImageSizes.SMALL)).asImageBitmap(), - colorFilter = if (songAlbumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + bitmap = (art ?: getImage(context, R.drawable.cd, ImageSizes.SMALL)).asImageBitmap(), + colorFilter = if (art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, contentDescription = "Song Album Art", modifier = Modifier .fillMaxHeight() .clip(RoundedCornerShape(7.dp)) - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { background(surfaceColor) } - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { padding(5.dp) } ) @@ -75,13 +76,13 @@ fun MiniPlayer( ) { CustomText( - text = selectedSong.title, + text = song.title, weight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary ) CustomText( - text = selectedSong.artist + text = artistName ) } diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/SongItem.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/SongItem.kt index 083efd8..7fd9136 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/SongItem.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/SongItem.kt @@ -1,6 +1,5 @@ package com.lighttigerxiv.simple.mp.compose.ui.composables -import android.graphics.Bitmap import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -33,21 +32,24 @@ import com.lighttigerxiv.simple.mp.compose.ui.composables.spacers.XSmallHeightSp import org.burnoutcrew.reorderable.ReorderableLazyListState import org.burnoutcrew.reorderable.detectReorder + + @OptIn(ExperimentalFoundationApi::class) @Composable -fun SongItem( +fun NewSongItem( modifier: Modifier = Modifier, + mainVM: MainVM, song: Song, - songAlbumArt: Bitmap?, - highlight: Boolean = false, menuEntries: ArrayList = ArrayList(), onSongClick: () -> Unit = {}, onMenuClicked: (option: String) -> Unit = {} ) { val context = LocalContext.current - val songTitle = remember { song.title } - val songArtist = remember { song.artist } + val title = remember { song.title } + val artistName = remember { mainVM.getSongArtist(song).name } + val art = remember{ mainVM.getSongArt(song) } + val highlight = song.path == mainVM.currentSong.collectAsState().value?.path val isPopupMenuExpanded = remember { mutableStateOf(false) } val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant @@ -57,7 +59,7 @@ fun SongItem( } - val titleWeight = when (highlight){ + val titleWeight = when (highlight) { true -> FontWeight.Medium else -> FontWeight.Normal } @@ -75,17 +77,17 @@ fun SongItem( ) { AsyncImage( - model = remember{ songAlbumArt ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, + model = remember { art ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, contentDescription = "", - colorFilter = if(songAlbumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + colorFilter = if (art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, modifier = Modifier .clip(RoundedCornerShape(20)) .height(70.dp) .width(70.dp) - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { background(surfaceVariantColor) } - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { padding(5.dp) } ) @@ -104,7 +106,7 @@ fun SongItem( ) { Text( - text = songTitle, + text = title, fontSize = 16.sp, color = titleColor, maxLines = 1, @@ -113,7 +115,7 @@ fun SongItem( ) Text( - text = songArtist, + text = artistName, fontSize = 16.sp, color = MaterialTheme.colorScheme.onSurface, maxLines = 1, @@ -165,41 +167,43 @@ fun SongItem( } } + @Composable fun ReorderableSongItem( mainVM: MainVM, modifier: Modifier = Modifier, song: Song, - songAlbumArt: Bitmap?, state: ReorderableLazyListState, isDragging: Boolean ) { val context = LocalContext.current - val songTitle = remember { song.title } - val songArtist = remember { song.artist } + val title = remember { song.title } + val artistName = remember { mainVM.getSongArtist(song).name } val surfaceColor = mainVM.surfaceColor.collectAsState().value + val art = remember{ mainVM.getSongArt(song) } - Column{ - Row(modifier = modifier - .fillMaxWidth() - .height(70.dp) - .clip(RoundedCornerShape(14.dp)) - .background(if (isDragging) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceVariant) + Column { + Row( + modifier = modifier + .fillMaxWidth() + .height(70.dp) + .clip(RoundedCornerShape(14.dp)) + .background(if (isDragging) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceVariant) ) { AsyncImage( - model = remember{ songAlbumArt ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, + model = remember { art ?: getImage(context, R.drawable.cd, ImageSizes.SMALL) }, contentDescription = "", - colorFilter = if(songAlbumArt == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, + colorFilter = if (art == null) ColorFilter.tint(MaterialTheme.colorScheme.primary) else null, modifier = Modifier .clip(RoundedCornerShape(20)) .height(70.dp) .width(70.dp) - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { background(surfaceColor) } - .modifyIf(songAlbumArt == null) { + .modifyIf(art == null) { padding(5.dp) } ) @@ -218,7 +222,7 @@ fun ReorderableSongItem( ) { Text( - text = songTitle, + text = title, fontSize = 16.sp, color = MaterialTheme.colorScheme.onSurface, maxLines = 1, @@ -227,7 +231,7 @@ fun ReorderableSongItem( ) Text( - text = songArtist, + text = artistName, fontSize = 16.sp, color = MaterialTheme.colorScheme.onSurface, maxLines = 1, diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumHeightSpacer.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumVerticalSpacer.kt similarity index 93% rename from app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumHeightSpacer.kt rename to app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumVerticalSpacer.kt index 2030d91..cee846e 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumHeightSpacer.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/MediumVerticalSpacer.kt @@ -7,6 +7,6 @@ import androidx.compose.ui.Modifier import com.lighttigerxiv.simple.mp.compose.data.variables.MEDIUM_SPACING @Composable -fun MediumHeightSpacer(){ +fun MediumVerticalSpacer(){ Spacer(modifier = Modifier.height(MEDIUM_SPACING)) } \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallHeightSpacer.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallVerticalSpacer.kt similarity index 93% rename from app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallHeightSpacer.kt rename to app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallVerticalSpacer.kt index e9970d4..85aab26 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallHeightSpacer.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/ui/composables/spacers/SmallVerticalSpacer.kt @@ -7,6 +7,6 @@ import androidx.compose.ui.Modifier import com.lighttigerxiv.simple.mp.compose.data.variables.SMALL_SPACING @Composable -fun SmallHeightSpacer(){ +fun SmallVerticalSpacer(){ Spacer(modifier = Modifier.height(SMALL_SPACING)) } \ No newline at end of file diff --git a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/widgets/SimpleMPWidget.kt b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/widgets/SimpleMPWidget.kt index eb8ff9c..f6a623a 100644 --- a/app/src/main/java/com/lighttigerxiv/simple/mp/compose/widgets/SimpleMPWidget.kt +++ b/app/src/main/java/com/lighttigerxiv/simple/mp/compose/widgets/SimpleMPWidget.kt @@ -87,7 +87,7 @@ internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManage val song = smpService.currentSong!! views.setTextViewText(R.id.title_Widget, song.title) - views.setTextViewText(R.id.artist_Widget, song.artist) + views.setTextViewText(R.id.artist_Widget, "banana") views.setImageViewBitmap(R.id.albumArt_Widget, getSongAlbumArt(context, song.id, song.albumID)) if(smpService.musicPlaying()) diff --git a/app/src/main/res/drawable/icon_fdroid.xml b/app/src/main/res/drawable/icon_fdroid.xml new file mode 100644 index 0000000..c5470ad --- /dev/null +++ b/app/src/main/res/drawable/icon_fdroid.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_play_store.xml b/app/src/main/res/drawable/icon_play_store.xml new file mode 100644 index 0000000..c2356d1 --- /dev/null +++ b/app/src/main/res/drawable/icon_play_store.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 7b7346e..7643c12 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -93,4 +93,12 @@ Selecionar Selecionar Imagem Eliminar Imagem + Mudanças + Transferir + Transferir no GitHub Releases + Transferir na Play Store + Transferir na F-Droid + Recarregar músicas + Não feche a aplicação enquanto as músicas recarregam + A recarregar músicas \ 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 b57cd74..c58a853 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -102,4 +102,15 @@ Select Image Delete Image ¯\\_(ツ)_/¯ + Changelog + Download + GitHub Releases + Download in GitHub Releases + Play Store + Download in Play Store + F-Droid + Download in F-Droid + Reload Songs + Don\'t close the app while reloading the songs!! + Reloading Songs \ No newline at end of file