diff --git a/README.md b/README.md index 4af0030..9690e77 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ The app is high network data consumption, since it streams songs at 320 kbps. I - [UAMP](https://github.com/android/uamp) for media player sample using ExoPlayer. - Every other person that motivated me and helped with testing. -## Contibutors +## Contributors Contributors are way more than welcomed, especially for iOS development. ## Contact diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 2d5b615..af55526 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -8,36 +8,32 @@ plugins { dependencies { implementation(project(":shared")) - implementation("com.google.android.material:material:1.6.0") - implementation("androidx.appcompat:appcompat:1.4.1") + implementation("com.google.android.material:material:1.6.1") + implementation("androidx.appcompat:appcompat:1.4.2") implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.4.1") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-rc01") implementation("androidx.activity:activity-compose:1.4.0") implementation("androidx.palette:palette-ktx:1.0.0") - implementation("androidx.compose.ui:ui-util:1.2.0-beta02") - implementation("androidx.compose.material:material:1.2.0-beta02") - implementation("androidx.compose.ui:ui:1.2.0-beta02") + implementation("androidx.compose.ui:ui-util:1.2.0-beta03") + implementation("androidx.compose.material:material:1.2.0-beta03") + implementation("androidx.compose.ui:ui:1.2.0-beta03") implementation("androidx.compose.animation:animation:1.1.1") debugImplementation("androidx.compose.ui:ui-tooling:1.1.1") implementation("androidx.compose.ui:ui-tooling-preview:1.1.1") - implementation("com.google.android.exoplayer:exoplayer:2.17.1") - implementation("com.google.android.exoplayer:extension-mediasession:2.17.1") - implementation("com.google.android.exoplayer:extension-cast:2.17.1") - + implementation ("com.google.android.exoplayer:exoplayer-core:2.17.1") + implementation ("com.google.android.exoplayer:extension-mediasession:2.17.1") + implementation ("com.google.android.exoplayer:exoplayer-ui:2.17.1") implementation("androidx.lifecycle:lifecycle-process:2.4.1") implementation("io.coil-kt:coil-compose:2.1.0") - implementation("com.google.dagger:hilt-android:2.38.1") - kapt("com.google.dagger:hilt-android-compiler:2.38.1") + implementation("com.google.dagger:hilt-android:2.42") + kapt("com.google.dagger:hilt-android-compiler:2.42") implementation("com.google.accompanist:accompanist-swiperefresh:0.24.1-alpha") implementation("androidx.core:core-splashscreen:1.0.0-rc01") - - androidTestImplementation("androidx.compose.ui:ui-test-junit4:${rootProject.extra["compose_version"]}") - debugImplementation("androidx.compose.ui:ui-tooling:${rootProject.extra["compose_version"]}") debugImplementation("com.squareup.leakcanary:leakcanary-android:2.7") } @@ -51,8 +47,8 @@ android { applicationId = "com.rld.justlisten.android" minSdk = 21 targetSdk = 32 - versionCode = 15 - versionName = "1.0.3" + versionCode = 16 + versionName = "1.0.4" vectorDrawables { useSupportLibrary = true } @@ -79,7 +75,7 @@ android { compose = true } composeOptions { - kotlinCompilerExtensionVersion = "1.2.0-alpha08" + kotlinCompilerExtensionVersion = "1.2.0-beta03" } packagingOptions { @@ -88,4 +84,12 @@ android { } } namespace = "com.rld.justlisten.android" +} + +sourceSets { + android { + kotlinOptions { + freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn") + } + } } \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt index 50ac73b..360f181 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt @@ -7,6 +7,7 @@ import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.MediaDescriptionCompat import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaSessionCompat +import androidx.compose.runtime.mutableStateOf import androidx.media.MediaBrowserServiceCompat import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.Player @@ -33,7 +34,7 @@ class MusicService : MediaBrowserServiceCompat() { @Inject lateinit var exoPlayer: ExoPlayer - lateinit var musicNotificationManager: MusicNotificationManager + private lateinit var musicNotificationManager: MusicNotificationManager private val serviceJob = SupervisorJob() private val serviceScope = CoroutineScope(Dispatchers.Main + serviceJob) @@ -57,6 +58,7 @@ class MusicService : MediaBrowserServiceCompat() { companion object { var curSongDuration = 0L private set + val songHasRepeated = mutableStateOf(false) } override fun onCreate() { @@ -93,7 +95,9 @@ class MusicService : MediaBrowserServiceCompat() { musicNotificationManager.showNotification(exoPlayer) - musicPlayerEventListener = MusicPlayerEventListener(this, musicNotificationManager, exoPlayer) + musicPlayerEventListener = MusicPlayerEventListener(this, musicNotificationManager, exoPlayer) { + songHasRepeated.value = true + } exoPlayer.addListener(musicPlayerEventListener) } diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt index 9e5dab6..5079527 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt @@ -4,13 +4,15 @@ import android.widget.Toast import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.PlaybackException import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AUTO_TRANSITION import com.rld.justlisten.android.exoplayer.MusicNotificationManager import com.rld.justlisten.android.exoplayer.MusicService class MusicPlayerEventListener( private val musicService: MusicService, private val notificationManager: MusicNotificationManager, - private val exoPlayer: ExoPlayer + private val exoPlayer: ExoPlayer, + val songHasRepeated: () -> Unit ) : Player.Listener { override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) { super.onPlayWhenReadyChanged(playWhenReady, reason) @@ -22,7 +24,11 @@ class MusicPlayerEventListener( override fun onPlayerError(error: PlaybackException) { super.onPlayerError(error) - Toast.makeText(musicService, "Unfortunately this song has issues, try another one", Toast.LENGTH_SHORT).show() + Toast.makeText( + musicService, + "Unfortunately this song has issues, try another one", + Toast.LENGTH_SHORT + ).show() } override fun onPlaybackStateChanged(playbackState: Int) { @@ -36,4 +42,17 @@ class MusicPlayerEventListener( } } } + + override fun onPositionDiscontinuity( + oldPosition: Player.PositionInfo, + newPosition: Player.PositionInfo, + reason: Int + ) { + + if (exoPlayer.repeatMode == Player.REPEAT_MODE_ONE) { + if (reason == DISCONTINUITY_REASON_AUTO_TRANSITION) { + songHasRepeated() + } + } + } } \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/OnePane.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/OnePane.kt index e2e5c6b..f1871c6 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/OnePane.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/OnePane.kt @@ -16,7 +16,7 @@ import coil.annotation.ExperimentalCoilApi import com.rld.justlisten.Navigation import com.rld.justlisten.android.exoplayer.MusicServiceConnection import com.rld.justlisten.android.exoplayer.library.extension.id -import com.rld.justlisten.android.ui.bottombars.Level1BottomBar +import com.rld.justlisten.android.ui.bottombars.bottombarnav.Level1BottomBar import com.rld.justlisten.android.ui.bottombars.playbar.PlayerBarSheetContent import com.rld.justlisten.android.ui.extensions.fraction import com.rld.justlisten.android.ui.screenpicker.ScreenPicker diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/AddPlaylistScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/AddPlaylistScreen.kt index 76a7b13..580e56a 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/AddPlaylistScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/AddPlaylistScreen.kt @@ -1,30 +1,17 @@ package com.rld.justlisten.android.ui.addplaylistscreen -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.material.Divider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusDirection -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.input.key.key -import androidx.compose.ui.input.key.onPreviewKeyEvent -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.rld.justlisten.android.R -import com.rld.justlisten.datalayer.localdb.addplaylistscreen.AddPlaylist +import com.rld.justlisten.android.ui.addplaylistscreen.components.AddPlaylistDialog +import com.rld.justlisten.android.ui.addplaylistscreen.components.AddPlaylistRow +import com.rld.justlisten.android.ui.addplaylistscreen.components.PlaylistViewItem import com.rld.justlisten.viewmodel.screens.addplaylist.AddPlaylistState @Composable @@ -38,149 +25,9 @@ fun AddPlaylistScreen( item { AddPlaylistRow(openDialog) } item { Divider(thickness = 2.dp) } item { AddPlaylistDialog(openDialog, onAddPlaylistClicked) } - itemsIndexed(addPlaylistState.playlistsCreated) { index, playlist -> + itemsIndexed(addPlaylistState.playlistsCreated) { _, playlist -> PlaylistViewItem(playlist, clickedToAddSongToPlaylist) } } } -@Composable -fun AddPlaylistRow(openDialog: MutableState) { - Row( - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable(onClick = { openDialog.value = true }) - ) { - Icon( - painterResource(id = R.drawable.ic_add_to_playlist_foreground), - contentDescription = null, - modifier = Modifier.height(75.dp) - ) - Text("New Playlist", modifier = Modifier.fillMaxWidth()) - } -} - -@Composable -fun PlaylistViewItem( - playlist: AddPlaylist, - clickedToAddSongToPlaylist: (String, String?, List) -> Unit -) { - Row( - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable(onClick = { - clickedToAddSongToPlaylist( - playlist.playlistName, - playlist.playlistDescription, - playlist.songsList ?: emptyList() - ) - }) - ) { - Icon( - painterResource(id = R.drawable.ic_playlist_icon), - contentDescription = null, - modifier = Modifier.height(75.dp) - ) - Spacer(modifier = Modifier.width(10.dp)) - Text(playlist.playlistName, modifier = Modifier.fillMaxWidth()) - } -} - -@OptIn(ExperimentalComposeUiApi::class) -@Composable -fun AddPlaylistDialog( - openDialog: MutableState, - onAddPlaylistClicked: (String, String?) -> Unit -) { - val focusManager = LocalFocusManager.current - val keyboardController = LocalSoftwareKeyboardController.current - - var title by remember { mutableStateOf("") } - var description by remember { mutableStateOf("") } - if (openDialog.value) { - AlertDialog( - onDismissRequest = { - openDialog.value = false - }, - title = null, - text = { - Column { - Text( - text = "Add New Playlist", - fontWeight = FontWeight.ExtraBold, - fontSize = 20.sp, - ) - Spacer(modifier = Modifier.height(20.dp)) - TextField( - singleLine = true, - modifier = Modifier.onPreviewKeyEvent { - if (it.key == Key.Tab) { - focusManager.moveFocus(FocusDirection.Down) - true - } else { - false - } - }, - maxLines = 1, - value = title, - onValueChange = { - if (it.length <= 15) - title = it - }, - label = { Text(text = "Title") }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Text, - imeAction = ImeAction.Next - ) - ) - TextField( - maxLines = 2, - modifier = Modifier.padding(top = 5.dp), - value = description.toString(), - onValueChange = { - if (it.length <= 144) - description = it - }, - label = { Text(text = "Description") }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Text, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { - focusManager.clearFocus() - keyboardController?.hide() - openDialog.value = false - onAddPlaylistClicked(title, description) - description = "" - title = "" - } - ) - ) - } - }, - confirmButton = { - Row( - modifier = Modifier.padding(all = 8.dp), - horizontalArrangement = Arrangement.Center - ) { - Button( - modifier = Modifier.fillMaxWidth(), - onClick = { - focusManager.clearFocus() - keyboardController?.hide() - openDialog.value = false - onAddPlaylistClicked(title, description) - description = "" - title = "" - } - ) { - Text("Add") - } - } - } - ) - } -} diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistDialog.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistDialog.kt new file mode 100644 index 0000000..749c659 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistDialog.kt @@ -0,0 +1,120 @@ +package com.rld.justlisten.android.ui.addplaylistscreen.components + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.AlertDialog +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.material.TextField +import androidx.compose.runtime.* +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +fun AddPlaylistDialog( + openDialog: MutableState, + onAddPlaylistClicked: (String, String?) -> Unit +) { + val focusManager = LocalFocusManager.current + val keyboardController = LocalSoftwareKeyboardController.current + + var title by remember { mutableStateOf("") } + var description by remember { mutableStateOf("") } + if (openDialog.value) { + AlertDialog( + onDismissRequest = { + openDialog.value = false + }, + title = null, + text = { + Column { + Text( + text = "Add New Playlist", + fontWeight = FontWeight.ExtraBold, + fontSize = 20.sp, + ) + Spacer(modifier = Modifier.height(20.dp)) + TextField( + singleLine = true, + modifier = Modifier.onPreviewKeyEvent { + if (it.key == Key.Tab) { + focusManager.moveFocus(FocusDirection.Down) + true + } else { + false + } + }, + maxLines = 1, + value = title, + onValueChange = { + if (it.length <= 15) + title = it + }, + label = { Text(text = "Title") }, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Next + ) + ) + TextField( + maxLines = 2, + modifier = Modifier.padding(top = 5.dp), + value = description.toString(), + onValueChange = { + if (it.length <= 144) + description = it + }, + label = { Text(text = "Description") }, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { + focusManager.clearFocus() + keyboardController?.hide() + openDialog.value = false + onAddPlaylistClicked(title, description) + description = "" + title = "" + } + ) + ) + } + }, + confirmButton = { + Row( + modifier = Modifier.padding(all = 8.dp), + horizontalArrangement = Arrangement.Center + ) { + Button( + modifier = Modifier.fillMaxWidth(), + onClick = { + focusManager.clearFocus() + keyboardController?.hide() + openDialog.value = false + onAddPlaylistClicked(title, description) + description = "" + title = "" + } + ) { + Text("Add") + } + } + } + ) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistRow.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistRow.kt new file mode 100644 index 0000000..338284a --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/AddPlaylistRow.kt @@ -0,0 +1,33 @@ +package com.rld.justlisten.android.ui.addplaylistscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.rld.justlisten.android.R + +@Composable +fun AddPlaylistRow(openDialog: MutableState) { + Row( + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .clickable(onClick = { openDialog.value = true }) + ) { + Icon( + painterResource(id = R.drawable.ic_add_to_playlist_foreground), + contentDescription = null, + modifier = Modifier.height(75.dp) + ) + Text("New Playlist", modifier = Modifier.fillMaxWidth()) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/PlaylistViewItem.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/PlaylistViewItem.kt new file mode 100644 index 0000000..f23e94c --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/addplaylistscreen/components/PlaylistViewItem.kt @@ -0,0 +1,40 @@ +package com.rld.justlisten.android.ui.addplaylistscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.rld.justlisten.android.R +import com.rld.justlisten.datalayer.localdb.addplaylistscreen.AddPlaylist + +@Composable +fun PlaylistViewItem( + playlist: AddPlaylist, + clickedToAddSongToPlaylist: (String, String?, List) -> Unit +) { + Row( + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .clickable(onClick = { + clickedToAddSongToPlaylist( + playlist.playlistName, + playlist.playlistDescription, + playlist.songsList ?: emptyList() + ) + }) + ) { + Icon( + painterResource(id = R.drawable.ic_playlist_icon), + contentDescription = null, + modifier = Modifier.height(75.dp) + ) + Spacer(modifier = Modifier.width(10.dp)) + Text(playlist.playlistName, modifier = Modifier.fillMaxWidth()) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/Level1BottomBar.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/bottombarnav/Level1BottomBar.kt similarity index 98% rename from androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/Level1BottomBar.kt rename to androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/bottombarnav/Level1BottomBar.kt index 2e6cd35..41e344e 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/Level1BottomBar.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/bottombarnav/Level1BottomBar.kt @@ -1,4 +1,4 @@ -package com.rld.justlisten.android.ui.bottombars +package com.rld.justlisten.android.ui.bottombars.bottombarnav import androidx.compose.foundation.background import androidx.compose.foundation.layout.BoxWithConstraints diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBarSheetContent.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBarSheetContent.kt index cfede5d..7f2e24d 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBarSheetContent.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBarSheetContent.kt @@ -7,9 +7,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import coil.annotation.ExperimentalCoilApi import com.rld.justlisten.android.exoplayer.MusicServiceConnection -import com.rld.justlisten.android.ui.bottombars.playbar.components.addplaylist.AddPlaylistOption -import com.rld.justlisten.android.ui.bottombars.playbar.components.more.PlayBarMoreAction -import com.rld.justlisten.android.ui.bottombars.sheetcontent.BottomSheetScreen +import com.rld.justlisten.android.ui.bottombars.playbar.components.PlayerBottomBar +import com.rld.justlisten.android.ui.bottombars.sheets.BottomSheetScreen +import com.rld.justlisten.android.ui.bottombars.sheets.SheetLayout import com.rld.justlisten.datalayer.localdb.addplaylistscreen.AddPlaylist import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel @@ -112,35 +112,3 @@ fun PlayerBarSheetContent( } } -@Composable -fun SheetLayout( - currentScreen: BottomSheetScreen, - onCloseBottomSheet: () -> Unit, - title: String, - mutablePainter: MutableState, - openSheet: (BottomSheetScreen) -> Unit, - addPlaylistList: List, - onAddPlaylistClicked: (String, String?) -> Unit, - getLatestPlaylist: () -> Unit, - clickedToAddSongToPlaylist: (String, String?, List) -> Unit -) { - when (currentScreen) { - BottomSheetScreen.AddPlaylist -> { - AddPlaylistOption( - title, - mutablePainter, - addPlaylistList, - onAddPlaylistClicked, - clickedToAddSongToPlaylist - ) - getLatestPlaylist() - } - BottomSheetScreen.More -> PlayBarMoreAction( - title, - mutablePainter, - ) { - onCloseBottomSheet() - openSheet(BottomSheetScreen.AddPlaylist) - } - } -} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMinimized.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMinimized.kt index 736f898..dc59818 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMinimized.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMinimized.kt @@ -17,7 +17,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.rld.justlisten.android.R import com.rld.justlisten.android.exoplayer.MusicServiceConnection -import com.rld.justlisten.android.ui.bottombars.playbar.IsLoading import com.rld.justlisten.android.ui.theme.typography import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBottomBar.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayerBottomBar.kt similarity index 92% rename from androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBottomBar.kt rename to androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayerBottomBar.kt index 5c6a6dd..0d4d164 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/PlayerBottomBar.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayerBottomBar.kt @@ -1,4 +1,4 @@ -package com.rld.justlisten.android.ui.bottombars.playbar +package com.rld.justlisten.android.ui.bottombars.playbar.components import androidx.compose.foundation.layout.* import androidx.compose.material.CircularProgressIndicator @@ -17,9 +17,6 @@ import androidx.compose.ui.unit.dp import com.rld.justlisten.android.R import com.rld.justlisten.android.exoplayer.MusicService.Companion.curSongDuration import com.rld.justlisten.android.exoplayer.MusicServiceConnection -import com.rld.justlisten.android.ui.bottombars.playbar.components.PlayBarActionsMaximized -import com.rld.justlisten.android.ui.bottombars.playbar.components.PlayBarSwipeActions -import com.rld.justlisten.android.ui.bottombars.playbar.components.PlayBarTopSection import com.rld.justlisten.android.ui.extensions.noRippleClickable import com.rld.justlisten.android.ui.theme.modifiers.verticalGradientBackgroundColor import com.rld.justlisten.datalayer.models.SongIconList diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/addplaylist/AddPlaylistOption.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/addplaylist/AddPlaylistOption.kt index ee77b6a..2930ca5 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/addplaylist/AddPlaylistOption.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/addplaylist/AddPlaylistOption.kt @@ -12,9 +12,9 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.dp -import com.rld.justlisten.android.ui.addplaylistscreen.AddPlaylistDialog -import com.rld.justlisten.android.ui.addplaylistscreen.AddPlaylistRow -import com.rld.justlisten.android.ui.addplaylistscreen.PlaylistViewItem +import com.rld.justlisten.android.ui.addplaylistscreen.components.AddPlaylistDialog +import com.rld.justlisten.android.ui.addplaylistscreen.components.AddPlaylistRow +import com.rld.justlisten.android.ui.addplaylistscreen.components.PlaylistViewItem import com.rld.justlisten.android.ui.bottombars.playbar.components.more.TopSection import com.rld.justlisten.datalayer.localdb.addplaylistscreen.AddPlaylist @@ -33,7 +33,7 @@ fun AddPlaylistOption( TopSection(title, painter) Divider(thickness = 2.dp) } - itemsIndexed(items = addPlaylistList) { index, playlist -> + itemsIndexed(items = addPlaylistList) { _, playlist -> PlaylistViewItem(playlist, clickedToAddSongToPlaylist) } item { diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/more/PlayBarMoreAction.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/more/PlayBarMoreAction.kt index 2924a48..0dc19e2 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/more/PlayBarMoreAction.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/more/PlayBarMoreAction.kt @@ -17,7 +17,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.rld.justlisten.android.R -import com.rld.justlisten.android.ui.bottombars.sheetcontent.BottomSheetScreen @Composable fun PlayBarMoreAction( diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheetcontent/BottomSheetScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/BottomSheetScreen.kt similarity index 65% rename from androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheetcontent/BottomSheetScreen.kt rename to androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/BottomSheetScreen.kt index 5228a6c..f956071 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheetcontent/BottomSheetScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/BottomSheetScreen.kt @@ -1,4 +1,4 @@ -package com.rld.justlisten.android.ui.bottombars.sheetcontent +package com.rld.justlisten.android.ui.bottombars.sheets sealed class BottomSheetScreen { object More: BottomSheetScreen() diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/SheetLayout.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/SheetLayout.kt new file mode 100644 index 0000000..f7217b2 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/sheets/SheetLayout.kt @@ -0,0 +1,41 @@ +package com.rld.justlisten.android.ui.bottombars.sheets + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.ui.graphics.painter.Painter +import com.rld.justlisten.android.ui.bottombars.playbar.components.addplaylist.AddPlaylistOption +import com.rld.justlisten.android.ui.bottombars.playbar.components.more.PlayBarMoreAction +import com.rld.justlisten.datalayer.localdb.addplaylistscreen.AddPlaylist + +@Composable +fun SheetLayout( + currentScreen: BottomSheetScreen, + onCloseBottomSheet: () -> Unit, + title: String, + mutablePainter: MutableState, + openSheet: (BottomSheetScreen) -> Unit, + addPlaylistList: List, + onAddPlaylistClicked: (String, String?) -> Unit, + getLatestPlaylist: () -> Unit, + clickedToAddSongToPlaylist: (String, String?, List) -> Unit +) { + when (currentScreen) { + BottomSheetScreen.AddPlaylist -> { + AddPlaylistOption( + title, + mutablePainter, + addPlaylistList, + onAddPlaylistClicked, + clickedToAddSongToPlaylist + ) + getLatestPlaylist() + } + BottomSheetScreen.More -> PlayBarMoreAction( + title, + mutablePainter, + ) { + onCloseBottomSheet() + openSheet(BottomSheetScreen.AddPlaylist) + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/donationscreen/DonationScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/donationscreen/DonationScreen.kt index 7bda7c6..f3d3450 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/donationscreen/DonationScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/donationscreen/DonationScreen.kt @@ -4,23 +4,17 @@ import android.widget.Toast import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.text.BasicText -import androidx.compose.material.* +import androidx.compose.material.Divider +import androidx.compose.material.Text +import androidx.compose.material.TextField +import androidx.compose.material.TextFieldDefaults import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.rld.justlisten.android.R @Composable fun DonationScreen() { @@ -97,5 +91,25 @@ fun DonationScreen() { colors = TextFieldDefaults.textFieldColors(unfocusedIndicatorColor = Color.Transparent) ) } + + Row( + Modifier + .fillMaxWidth() + .padding(10.dp) + ) { + TextField( + "0x3A9b38ba07D4E9263c5595C2DbF1dD13a43b577C", modifier = Modifier.clickable( + onClick = { + clipboardManager.setText(AnnotatedString(("0x3A9b38ba07D4E9263c5595C2DbF1dD13a43b577C"))) + Toast.makeText(context, "Copied Audius Address", Toast.LENGTH_SHORT) + .show() + }), + onValueChange = {}, + enabled = false, + label = { Text(text = "Audius Address") }, + shape = CircleShape, + colors = TextFieldDefaults.textFieldColors(unfocusedIndicatorColor = Color.Transparent) + ) + } } } \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/LibraryScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/LibraryScreen.kt index 5b4b11e..218200e 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/LibraryScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/LibraryScreen.kt @@ -1,27 +1,17 @@ package com.rld.justlisten.android.ui.libraryscreen -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.Divider -import androidx.compose.material.Icon -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.FavoriteBorder -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.rld.justlisten.android.R import com.rld.justlisten.android.exoplayer.MusicServiceConnection -import com.rld.justlisten.android.ui.playlistdetailscreen.playMusicFromId +import com.rld.justlisten.android.ui.libraryscreen.components.FavoritePlaylist +import com.rld.justlisten.android.ui.libraryscreen.components.MostPlayedSongs +import com.rld.justlisten.android.ui.libraryscreen.components.PlaylistView +import com.rld.justlisten.android.ui.libraryscreen.components.RowListOfRecentActivity import com.rld.justlisten.android.ui.playlistscreen.Header -import com.rld.justlisten.android.ui.playlistscreen.components.PlaylistRowItem +import com.rld.justlisten.android.ui.utils.playMusicFromId import com.rld.justlisten.datalayer.models.PlayListModel import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel @@ -32,7 +22,8 @@ import com.rld.justlisten.viewmodel.screens.search.TrackItem fun LibraryScreen( musicServiceConnection: MusicServiceConnection, libraryState: LibraryState, - onPlaylistPressed: (String, String, String, String) -> Unit, + onFavoritePlaylistPressed: (String, String, String, String) -> Unit, + onMostPlaylistPressed: (String, String, String, String) -> Unit, onPlayListViewClicked: () -> Unit, lasItemReached: (Int) -> Unit ) { @@ -63,99 +54,9 @@ fun LibraryScreen( Divider(thickness = 1.dp) PlaylistView(onPlayListViewClicked) Spacer(modifier = Modifier.height(10.dp)) - FavoritePlaylist(libraryState, onPlaylistPressed) - } - } -} - -@Composable -fun RowListOfRecentActivity( - libraryState: LibraryState, - onPlaylistClicked: (String, String, String, String, Boolean) -> Unit, - lastIndexReached: Boolean, - lasItemReached: (Int) -> Unit -) { - val fetchMore = remember { mutableStateOf(false) } - - LazyRow { - itemsIndexed(items = libraryState.recentSongsItems) { index, playlistItem -> - - if (index == libraryState.recentSongsItems.lastIndex && !lastIndexReached) { - LaunchedEffect(key1 =libraryState.recentSongsItems.lastIndex ) { - lasItemReached(libraryState.recentSongsItems.size + 20) - fetchMore.value = true - } - } - - if (lastIndexReached) { - fetchMore.value = false - } - - PlaylistRowItem( - playlistItem = playlistItem, - onPlaylistClicked = onPlaylistClicked, - ) - } - - if (fetchMore.value) { - item { - CircularProgressIndicator() - } + FavoritePlaylist(libraryState, onFavoritePlaylistPressed) + Spacer(modifier = Modifier.height(10.dp)) + MostPlayedSongs(libraryState, onMostPlaylistPressed) } } -} - -@Composable -fun PlaylistView(onPlayListViewClicked: () -> Unit) { - Row( - Modifier - .fillMaxWidth() - .padding(top = 15.dp) - .clickable(onClick = onPlayListViewClicked), - verticalAlignment = Alignment.CenterVertically - ) { - Icon(painter = painterResource(id = R.drawable.ic_playlist), contentDescription = null) - Text( - modifier = Modifier.padding(start = 5.dp), - text = "Playlists", - fontWeight = FontWeight.ExtraBold, - fontSize = 20.sp - ) - } -} - -@Composable -fun FavoritePlaylist( - libraryState: LibraryState, - onPlaylistPressed: (String, String, String, String) -> Unit -) { - val songIcon = - if (libraryState.favoritePlaylistItems.isNotEmpty()) - libraryState.favoritePlaylistItems[0].songIconList.songImageURL480px - else - "" - Row( - Modifier - .fillMaxWidth() - .padding(top = 15.dp) - .clickable( - onClick = { - onPlaylistPressed( - "Favorite", - songIcon, - "Favorite", - "You" - ) - } - ), - verticalAlignment = Alignment.CenterVertically - ) { - Icon(imageVector = Icons.Default.FavoriteBorder, contentDescription = null) - Text( - modifier = Modifier.padding(start = 5.dp), - text = "Favorite Playlist", - fontWeight = FontWeight.ExtraBold, - fontSize = 20.sp - ) - } } \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/FavoritePlaylist.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/FavoritePlaylist.kt new file mode 100644 index 0000000..6993e77 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/FavoritePlaylist.kt @@ -0,0 +1,53 @@ +package com.rld.justlisten.android.ui.libraryscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.rld.justlisten.viewmodel.screens.library.LibraryState + +@Composable +fun FavoritePlaylist( + libraryState: LibraryState, + onPlaylistPressed: (String, String, String, String) -> Unit +) { + val songIcon = + if (libraryState.favoritePlaylistItems.isNotEmpty()) + libraryState.favoritePlaylistItems[0].songIconList.songImageURL480px + else + "" + Row( + Modifier + .fillMaxWidth() + .padding(top = 15.dp) + .clickable( + onClick = { + onPlaylistPressed( + "Favorite", + songIcon, + "Favorite", + "You" + ) + } + ), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(imageVector = Icons.Default.FavoriteBorder, contentDescription = null) + Text( + modifier = Modifier.padding(start = 5.dp), + text = "Favorite Playlist", + fontWeight = FontWeight.ExtraBold, + fontSize = 20.sp + ) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/MostPlayedSongs.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/MostPlayedSongs.kt new file mode 100644 index 0000000..dd806c1 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/MostPlayedSongs.kt @@ -0,0 +1,53 @@ +package com.rld.justlisten.android.ui.libraryscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.rld.justlisten.android.R +import com.rld.justlisten.viewmodel.screens.library.LibraryState + +@Composable +fun MostPlayedSongs( + libraryState: LibraryState, + onPlaylistPressed: (String, String, String, String) -> Unit +) { + val songIcon = + if (libraryState.mostPlayedSongs.isNotEmpty()) + libraryState.mostPlayedSongs[0].songIconList.songImageURL480px + else + "" + Row( + Modifier + .fillMaxWidth() + .padding(top = 15.dp) + .clickable( + onClick = { + onPlaylistPressed( + "Most Played", + songIcon, + "Most Played", + "You" + ) + } + ), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(painterResource(id = R.drawable.ic_most_played) , contentDescription = null) + Text( + modifier = Modifier.padding(start = 5.dp), + text = "Most Played Songs", + fontWeight = FontWeight.ExtraBold, + fontSize = 20.sp + ) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/PlaylistView.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/PlaylistView.kt new file mode 100644 index 0000000..69ef1f1 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/PlaylistView.kt @@ -0,0 +1,35 @@ +package com.rld.justlisten.android.ui.libraryscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.rld.justlisten.android.R + +@Composable +fun PlaylistView(onPlayListViewClicked: () -> Unit) { + Row( + Modifier + .fillMaxWidth() + .padding(top = 15.dp) + .clickable(onClick = onPlayListViewClicked), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(painter = painterResource(id = R.drawable.ic_playlist), contentDescription = null) + Text( + modifier = Modifier.padding(start = 5.dp), + text = "Playlists", + fontWeight = FontWeight.ExtraBold, + fontSize = 20.sp + ) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/RowListOfRecentActivity.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/RowListOfRecentActivity.kt new file mode 100644 index 0000000..fa054e4 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/libraryscreen/components/RowListOfRecentActivity.kt @@ -0,0 +1,41 @@ +package com.rld.justlisten.android.ui.libraryscreen.components + +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import com.rld.justlisten.android.ui.playlistscreen.components.PlaylistRowItem +import com.rld.justlisten.viewmodel.screens.library.LibraryState + +@Composable +fun RowListOfRecentActivity( + libraryState: LibraryState, + onPlaylistClicked: (String, String, String, String, Boolean) -> Unit, + lastIndexReached: Boolean, + lasItemReached: (Int) -> Unit +) { + val fetchMore = remember { mutableStateOf(false) } + + LazyRow { + itemsIndexed(items = libraryState.recentSongsItems) { index, playlistItem -> + + if (index == libraryState.recentSongsItems.lastIndex && !lastIndexReached) { + LaunchedEffect(key1 = libraryState.recentSongsItems.lastIndex) { + lasItemReached(libraryState.recentSongsItems.size + 20) + fetchMore.value = true + } + } + + if (lastIndexReached) { + fetchMore.value = false + } + + PlaylistRowItem( + playlistItem = playlistItem, + onPlaylistClicked = onPlaylistClicked, + ) + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/PlaylistDetailScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/PlaylistDetailScreen.kt index 18ef093..c32778f 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/PlaylistDetailScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/PlaylistDetailScreen.kt @@ -1,40 +1,29 @@ package com.rld.justlisten.android.ui.playlistdetailscreen import android.graphics.drawable.ColorDrawable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Icon +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.ui.Alignment +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.rld.justlisten.android.ui.playlistdetailscreen.components.SongListScrollingSection -import com.rld.justlisten.android.ui.theme.modifiers.horizontalGradientBackground -import android.support.v4.media.MediaBrowserCompat -import androidx.compose.material.IconButton -import androidx.compose.material.icons.filled.Search -import androidx.compose.runtime.* import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.nestedScroll -import coil.compose.AsyncImagePainter +import androidx.compose.ui.platform.LocalContext import coil.compose.rememberAsyncImagePainter import coil.request.ImageRequest import com.rld.justlisten.android.exoplayer.MusicServiceConnection -import com.rld.justlisten.android.exoplayer.utils.Constants import com.rld.justlisten.android.ui.loadingscreen.LoadingScreen +import com.rld.justlisten.android.ui.playlistdetailscreen.components.AnimatedToolBar +import com.rld.justlisten.android.ui.playlistdetailscreen.components.BottomScrollableContent +import com.rld.justlisten.android.ui.utils.playMusic import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel -import com.rld.justlisten.viewmodel.interfaces.Item -import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem import com.rld.justlisten.viewmodel.screens.playlistdetail.PlaylistDetailState @Composable @@ -103,92 +92,3 @@ fun PlaylistDetailScreen( } } -@Composable -fun AnimatedToolBar( - playlistDetailState: PlaylistDetailState, - scrollState: MutableState, - onBackButtonPressed: (Boolean) -> Unit -) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .horizontalGradientBackground( - if (Dp(-scrollState.value) < 1080.dp) - listOf( - Color.Transparent, - Color.Transparent - ) else listOf(MaterialTheme.colors.background, MaterialTheme.colors.background) - ) - .padding(horizontal = 8.dp, vertical = 4.dp) - ) { - IconButton(onClick = { onBackButtonPressed(true) }) { - Icon( - imageVector = Icons.Default.ArrowBack, - contentDescription = null, - ) - } - Text( - text = playlistDetailState.playlistName, - modifier = Modifier - .alpha(((-scrollState.value + 0.010f) / 1000).coerceIn(0f, 1f)) - ) - Icon( - imageVector = Icons.Default.Search, - contentDescription = null, - modifier = Modifier.alpha(0f) - ) - } -} - -@Composable -fun BottomScrollableContent( - playlistDetailState: PlaylistDetailState, - scrollState: MutableState, - playlist: List, - onSongClicked: (String) -> Unit, - onShuffleClicked: () -> Unit, - onFavoritePressed: (String, String, UserModel, SongIconList, Boolean) -> Unit, - painter: AsyncImagePainter -) { - SongListScrollingSection( - painter = painter, - playlistDetailState = playlistDetailState, - scrollState = scrollState, - playlist = playlist, - onSongClicked = onSongClicked, - onShuffleClicked = onShuffleClicked, - onFavoritePressed = onFavoritePressed, - ) -} - -fun playMusicFromId( - musicServiceConnection: MusicServiceConnection, - playlist: List, - songId: String, - isPlayerReady: Boolean -) { - if (isPlayerReady) { - musicServiceConnection.transportControls.playFromMediaId(songId, null) - } else { - playMusic(musicServiceConnection, playlist, isPlayerReady, songId) - } -} - -fun playMusic( - musicServiceConnection: MusicServiceConnection, - playlist: List, - isPlayerReady: Boolean, - playFromId: String = "" -) { - if (!isPlayerReady) { - musicServiceConnection.updatePlaylist(playlist) - musicServiceConnection.subscribe( - Constants.CLICKED_PLAYLIST, - object : MediaBrowserCompat.SubscriptionCallback() {}) - } - if (playFromId != "") { - musicServiceConnection.transportControls.playFromMediaId(playFromId, null) - } -} diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/AnimatedToolBar.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/AnimatedToolBar.kt new file mode 100644 index 0000000..f502815 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/AnimatedToolBar.kt @@ -0,0 +1,59 @@ +package com.rld.justlisten.android.ui.playlistdetailscreen.components + +import androidx.compose.foundation.layout.* +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Search +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.rld.justlisten.android.ui.theme.modifiers.horizontalGradientBackground +import com.rld.justlisten.viewmodel.screens.playlistdetail.PlaylistDetailState + +@Composable +fun AnimatedToolBar( + playlistDetailState: PlaylistDetailState, + scrollState: MutableState, + onBackButtonPressed: (Boolean) -> Unit +) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .horizontalGradientBackground( + if (Dp(-scrollState.value) < 1080.dp) + listOf( + Color.Transparent, + Color.Transparent + ) else listOf(MaterialTheme.colors.background, MaterialTheme.colors.background) + ) + .padding(horizontal = 8.dp, vertical = 4.dp) + ) { + IconButton(modifier = Modifier.size(48.dp), onClick = { onBackButtonPressed(true) }) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = null, + ) + } + Text( + text = playlistDetailState.playlistName, + modifier = Modifier + .alpha(((-scrollState.value + 0.010f) / 1000).coerceIn(0f, 1f)) + ) + Icon( + imageVector = Icons.Default.Search, + contentDescription = null, + modifier = Modifier.alpha(0f) + ) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BottomScrollableContent.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BottomScrollableContent.kt new file mode 100644 index 0000000..c0963b1 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BottomScrollableContent.kt @@ -0,0 +1,30 @@ +package com.rld.justlisten.android.ui.playlistdetailscreen.components + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import coil.compose.AsyncImagePainter +import com.rld.justlisten.datalayer.models.SongIconList +import com.rld.justlisten.datalayer.models.UserModel +import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem +import com.rld.justlisten.viewmodel.screens.playlistdetail.PlaylistDetailState + +@Composable +fun BottomScrollableContent( + playlistDetailState: PlaylistDetailState, + scrollState: MutableState, + playlist: List, + onSongClicked: (String) -> Unit, + onShuffleClicked: () -> Unit, + onFavoritePressed: (String, String, UserModel, SongIconList, Boolean) -> Unit, + painter: AsyncImagePainter +) { + SongListScrollingSection( + painter = painter, + playlistDetailState = playlistDetailState, + scrollState = scrollState, + playlist = playlist, + onSongClicked = onSongClicked, + onShuffleClicked = onShuffleClicked, + onFavoritePressed = onFavoritePressed, + ) +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt index f9113c7..b0da0b7 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt @@ -41,7 +41,7 @@ fun BoxTopSection(scrollState: MutableState, playlistDetailState: Playlis .padding(8.dp) ) Text( - text = playlistDetailState.playListCreatedBy, + text = playlistDetailState.playlistName, style = typography.subtitle2.copy(fontWeight = FontWeight.ExtraBold), maxLines = 1, textAlign = TextAlign.Center, @@ -59,7 +59,7 @@ fun BoxTopSection(scrollState: MutableState, playlistDetailState: Playlis .padding(vertical = 4.dp, horizontal = 24.dp) ) Text( - text = "Created by ${playlistDetailState.playlistName}", + text = "Created by ${playlistDetailState.playListCreatedBy}", maxLines = 1, textAlign = TextAlign.Center, style = typography.subtitle2, diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListItem.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListItem.kt index 16f1966..4d626d0 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListItem.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListItem.kt @@ -35,7 +35,8 @@ import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem @Composable fun SongListItem( playlistItem: PlaylistItem, onSongClicked: (String) -> Unit, - onFavoritePressed: (String, String, UserModel, SongIconList, Boolean) -> Unit + onFavoritePressed: (String, String, UserModel, SongIconList, Boolean) -> Unit, + playlist: String ) { Row( modifier = Modifier @@ -78,8 +79,12 @@ fun SongListItem( ) } + if (playlist == "Most Played") { + Text(text = playlistItem.songCounter) + } + var isFavorite by rememberSaveable { mutableStateOf(playlistItem.isFavorite) } - Icon(imageVector = if (isFavorite) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder, + Icon(imageVector = if (isFavorite) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder, contentDescription = null, tint = Color.Red, modifier = Modifier diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListScrollingSection.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListScrollingSection.kt index 50ba1c1..6c2aa8d 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListScrollingSection.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/SongListScrollingSection.kt @@ -46,6 +46,7 @@ fun SongListScrollingSection( itemsIndexed(playlist) { index, playlistItem -> SongListItem( + playlist = playlistDetailState.playlistName, playlistItem = playlistItem, onSongClicked = onSongClicked, onFavoritePressed = onFavoritePressed, diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/PlaylistScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/PlaylistScreen.kt index bc57821..22ae3aa 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/PlaylistScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/PlaylistScreen.kt @@ -18,16 +18,15 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEachIndexed +import com.google.accompanist.swiperefresh.SwipeRefresh +import com.google.accompanist.swiperefresh.rememberSwipeRefreshState +import com.rld.justlisten.android.ui.extensions.customTabIndicatorOffset import com.rld.justlisten.android.ui.loadingscreen.LoadingScreen import com.rld.justlisten.android.ui.playlistscreen.components.PlaylistRowItem +import com.rld.justlisten.android.ui.searchscreen.components.SearchGridTracks import com.rld.justlisten.android.ui.theme.modifiers.horizontalGradientBackground import com.rld.justlisten.android.ui.theme.typography -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState -import com.rld.justlisten.android.ui.extensions.customTabIndicatorOffset -import com.rld.justlisten.android.ui.searchscreen.SearchGridTracks import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.utils.Constants.list import com.rld.justlisten.viewmodel.Events @@ -70,6 +69,7 @@ fun PlaylistScreen( PlayListEnum.CURRENT_PLAYLIST -> TODO() PlayListEnum.FAVORITE -> TODO() PlayListEnum.CREATED_BY_USER -> TODO() + PlayListEnum.MOST_PLAYED -> TODO() } }, scrollState = scrollState, diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/components/PlaylistRowItem.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/components/PlaylistRowItem.kt index 881ab22..f4ad575 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/components/PlaylistRowItem.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistscreen/components/PlaylistRowItem.kt @@ -44,8 +44,8 @@ fun PlaylistRowItem( onPlaylistClicked( playlistItem.id, playlistItem.songIconList.songImageURL480px, - playlistItem.user, playlistItem.playlistTitle, + playlistItem.user, playlistItem.isFavorite ) } diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt index 6d7652d..41c3fd7 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.ExperimentalComposeUiApi import com.rld.justlisten.Navigation import com.rld.justlisten.ScreenIdentifier +import com.rld.justlisten.android.exoplayer.MusicService import com.rld.justlisten.android.exoplayer.MusicServiceConnection import com.rld.justlisten.android.exoplayer.library.extension.displayIconUri import com.rld.justlisten.android.exoplayer.library.extension.id @@ -13,10 +14,10 @@ import com.rld.justlisten.android.ui.addplaylistscreen.AddPlaylistScreen import com.rld.justlisten.android.ui.donationscreen.DonationScreen import com.rld.justlisten.android.ui.libraryscreen.LibraryScreen import com.rld.justlisten.android.ui.playlistdetailscreen.PlaylistDetailScreen -import com.rld.justlisten.android.ui.playlistdetailscreen.playMusicFromId import com.rld.justlisten.android.ui.playlistscreen.PlaylistScreen import com.rld.justlisten.android.ui.searchscreen.SearchScreen import com.rld.justlisten.android.ui.settingsscreen.SettingsScreen +import com.rld.justlisten.android.ui.utils.playMusicFromId import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel import com.rld.justlisten.viewmodel.screens.Screen.* @@ -25,6 +26,7 @@ import com.rld.justlisten.viewmodel.screens.addplaylist.addPlaylist import com.rld.justlisten.viewmodel.screens.addplaylist.updatePlaylist import com.rld.justlisten.viewmodel.screens.library.getLastPlayed import com.rld.justlisten.viewmodel.screens.library.saveSongToFavorites +import com.rld.justlisten.viewmodel.screens.library.saveSongToMostPlayed import com.rld.justlisten.viewmodel.screens.library.saveSongToRecent import com.rld.justlisten.viewmodel.screens.playlist.PlayListEnum.* import com.rld.justlisten.viewmodel.screens.playlist.PlaylistState @@ -68,18 +70,47 @@ fun Navigation.ScreenPicker( } } + if (MusicService.songHasRepeated.value) { + LaunchedEffect(key1 = MusicService.songHasRepeated) { + val title = musicServiceConnection.currentPlayingSong.value?.title ?: "title" + val newId = musicServiceConnection.currentPlayingSong.value?.id ?: "id" + val user = UserModel("asd") + val songIcon = + musicServiceConnection.currentPlayingSong.value?.displayIconUri.toString() + val icon = SongIconList( + songImageURL150px = songIcon, + songImageURL480px = songIcon, + songImageURL1000px = songIcon.replace("480", "1000") + ) + events.saveSongToMostPlayed(newId, title, user, icon) + MusicService.songHasRepeated.value = false + } + } + when (screenIdentifier.screen) { Library -> LibraryScreen( musicServiceConnection = musicServiceConnection, libraryState = stateProvider.get(screenIdentifier), - onPlaylistPressed = { playlistId, playlistIcon, playlistTitle, playlistCreatedBy -> + onFavoritePlaylistPressed = { playlistId, playlistIcon, playlistTitle, playlistCreatedBy -> + navigate( + PlaylistDetail, + PlaylistDetailParams( + playlistId = playlistId, playlistIcon = playlistIcon, playlistTitle = playlistTitle, + playlistCreatedBy = playlistCreatedBy, + playlistEnum = FAVORITE + ) + ) + events.playMusicFromPlaylist(playlistId = playlistId) + }, + onMostPlaylistPressed = { + playlistId, playlistIcon, playlistTitle, playlistCreatedBy -> navigate( PlaylistDetail, PlaylistDetailParams( playlistId, playlistIcon, playlistTitle, playlistCreatedBy, - FAVORITE + MOST_PLAYED ) ) events.playMusicFromPlaylist(playlistId = playlistId) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/SearchScreen.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/SearchScreen.kt index 3add004..fe39415 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/SearchScreen.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/SearchScreen.kt @@ -1,46 +1,29 @@ package com.rld.justlisten.android.ui.searchscreen import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.runtime.* +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment +import androidx.compose.runtime.setValue import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach -import com.rld.justlisten.android.R import com.rld.justlisten.android.ui.extensions.noRippleClickable import com.rld.justlisten.android.ui.loadingscreen.LoadingScreen -import com.rld.justlisten.android.ui.playlistscreen.Header -import com.rld.justlisten.android.ui.playlistscreen.components.PlaylistRowItem -import com.rld.justlisten.android.ui.playlistscreen.components.TrackGridItem +import com.rld.justlisten.android.ui.searchscreen.components.AnimatedToolBar +import com.rld.justlisten.android.ui.searchscreen.components.ShowPreviousSearches +import com.rld.justlisten.android.ui.searchscreen.components.ShowSearchResults import com.rld.justlisten.datalayer.models.SongIconList -import com.rld.justlisten.viewmodel.interfaces.Item -import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem import com.rld.justlisten.viewmodel.screens.search.SearchScreenState -import com.rld.justlisten.viewmodel.screens.search.TrackItem -import com.rld.justlisten.android.ui.searchscreen.components.VerticalGrid @ExperimentalComposeUiApi @Composable @@ -68,14 +51,13 @@ fun SearchScreen( .verticalScroll(scrollState) ) { AnimatedToolBar( - onBackPressed, - requester, - onSearchPressed, - searchScreenState, + onBackPressed = onBackPressed, + requester = requester, + onSearchPressed = onSearchPressed, updateSearch = { updateSearch -> searchFor = updateSearch.trimStart { it == '0' } }, - searchFor + searchFor = searchFor ) when { searchScreenState.isLoading -> { @@ -96,144 +78,4 @@ fun SearchScreen( } } } -} - -@ExperimentalComposeUiApi -@Composable -fun AnimatedToolBar( - onBackPressed: (Boolean) -> Unit, - requester: FocusRequester, - onSearchPressed: (String) -> Unit, - searchedFor: SearchScreenState, - updateSearch: (String) -> Unit, - searchFor: String -) { - - val keyboardController = LocalSoftwareKeyboardController.current - - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - ) { - IconButton(modifier = Modifier.weight(0.2f), onClick = { onBackPressed(true) }) { - Icon( - imageVector = Icons.Default.ArrowBack, - contentDescription = null, - ) - } - TextField(modifier = Modifier - .weight(0.6f) - .focusRequester(requester), - value = searchFor, - singleLine = true, - onValueChange = { newInput -> - updateSearch(newInput) - }, - label = { - Text(text = "Search") - }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Text, - imeAction = ImeAction.Search - ), - leadingIcon = { - Icon( - imageVector = Icons.Default.Search, - contentDescription = null - ) - }, - keyboardActions = KeyboardActions( - onSearch = { - onSearchPressed(searchFor) - keyboardController?.hide() - } - ), - ) - IconButton(modifier = Modifier - .weight(0.2f) - .graphicsLayer { - alpha = if (searchFor.isNotEmpty()) 1f else 0f - }, - onClick = { - updateSearch("") - keyboardController?.show() - }) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = null - ) - } - } - - LaunchedEffect(Unit) { - if (searchFor.isEmpty()) { - requester.requestFocus() - } - } -} - -@Composable -fun ShowPreviousSearches(listOfSearches: List, onPreviousSearchedPressed: (String) ->Unit) { - listOfSearches.fastForEach { itemSearched -> - ItemRowSearch(itemSearched, onPreviousSearchedPressed) - } -} - -@Composable -fun ItemRowSearch(itemSearched: String, onPreviousSearchedPressed: (String) -> Unit) { - Row( - Modifier - .fillMaxWidth() - .padding(top = 10.dp) - .clickable(onClick = { onPreviousSearchedPressed(itemSearched) }) - ) { - Icon(imageVector = Icons.Default.Search, contentDescription = null) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - Text(modifier = Modifier.padding(start = 5.dp), text = itemSearched) - Icon( - painter = painterResource(id = R.drawable.ic_baseline_north_west_24), - contentDescription = null - ) - } - } -} - - -@Composable -fun ShowSearchResults( - searchResultTracks: List, - searchResultPlaylist: List, - onSongPressed: (String, String, String, SongIconList) -> Unit, - onPlaylistPressed: (String, String, String, String, Boolean) -> Unit) { - Column(Modifier.fillMaxSize()) { - Header(text = "Top Find") - SearchGridTracks(list = searchResultTracks, onSongPressed) - Header(text = "Playlist", modifier = Modifier.padding(top = 10.dp)) - PlaylistResult(playlist = searchResultPlaylist, onPlaylistPressed) - } -} - -@Composable -fun SearchGridTracks(list: List, onSongPressed: (String, String, String, SongIconList) -> Unit) { - VerticalGrid { - list.fastForEach { item -> - TrackGridItem(item, onSongPressed) - } - } -} - -@Composable -fun PlaylistResult( - playlist: List, - onPlaylistPressed: (String, String, String, String, Boolean) -> Unit) { - LazyRow{ - itemsIndexed(items = playlist) { _, playlistItem -> - PlaylistRowItem( - playlistItem = playlistItem, - onPlaylistClicked = onPlaylistPressed) - } - } -} - +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/AnimatedToolBar.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/AnimatedToolBar.kt new file mode 100644 index 0000000..ed8ba49 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/AnimatedToolBar.kt @@ -0,0 +1,102 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.material.TextField +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Search +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType + +@ExperimentalComposeUiApi +@Composable +fun AnimatedToolBar( + onBackPressed: (Boolean) -> Unit, + requester: FocusRequester, + onSearchPressed: (String) -> Unit, + updateSearch: (String) -> Unit, + searchFor: String +) { + + val keyboardController = LocalSoftwareKeyboardController.current + + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + ) { + IconButton(modifier = Modifier.weight(0.2f), onClick = { onBackPressed(true) }) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = null, + ) + } + TextField( + modifier = Modifier + .weight(0.6f) + .focusRequester(requester), + value = searchFor, + singleLine = true, + onValueChange = { newInput -> + updateSearch(newInput) + }, + label = { + Text(text = "Search") + }, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Search + ), + leadingIcon = { + Icon( + imageVector = Icons.Default.Search, + contentDescription = null + ) + }, + keyboardActions = KeyboardActions( + onSearch = { + onSearchPressed(searchFor) + keyboardController?.hide() + } + ), + ) + IconButton(modifier = Modifier + .weight(0.2f) + .graphicsLayer { + alpha = if (searchFor.isNotEmpty()) 1f else 0f + }, + onClick = { + updateSearch("") + keyboardController?.show() + }) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = null + ) + } + } + + LaunchedEffect(Unit) { + if (searchFor.isEmpty()) { + requester.requestFocus() + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ItemRowSearch.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ItemRowSearch.kt new file mode 100644 index 0000000..389468f --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ItemRowSearch.kt @@ -0,0 +1,35 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Search +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.rld.justlisten.android.R + +@Composable +fun ItemRowSearch(itemSearched: String, onPreviousSearchedPressed: (String) -> Unit) { + Row( + Modifier + .fillMaxWidth() + .padding(top = 10.dp) + .clickable(onClick = { onPreviousSearchedPressed(itemSearched) }) + ) { + Icon(imageVector = Icons.Default.Search, contentDescription = null) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + Text(modifier = Modifier.padding(start = 5.dp), text = itemSearched) + Icon( + painter = painterResource(id = R.drawable.ic_baseline_north_west_24), + contentDescription = null + ) + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/PlaylistResult.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/PlaylistResult.kt new file mode 100644 index 0000000..131dd2f --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/PlaylistResult.kt @@ -0,0 +1,21 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.runtime.Composable +import com.rld.justlisten.android.ui.playlistscreen.components.PlaylistRowItem +import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem + +@Composable +fun PlaylistResult( + playlist: List, + onPlaylistPressed: (String, String, String, String, Boolean) -> Unit) { + LazyRow { + itemsIndexed(items = playlist) { _, playlistItem -> + PlaylistRowItem( + playlistItem = playlistItem, + onPlaylistClicked = onPlaylistPressed + ) + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/SearchGridTracks.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/SearchGridTracks.kt new file mode 100644 index 0000000..2999ff8 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/SearchGridTracks.kt @@ -0,0 +1,16 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.util.fastForEach +import com.rld.justlisten.android.ui.playlistscreen.components.TrackGridItem +import com.rld.justlisten.datalayer.models.SongIconList +import com.rld.justlisten.viewmodel.interfaces.Item + +@Composable +fun SearchGridTracks(list: List, onSongPressed: (String, String, String, SongIconList) -> Unit) { + VerticalGrid { + list.fastForEach { item -> + TrackGridItem(item, onSongPressed) + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowPreviousSearches.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowPreviousSearches.kt new file mode 100644 index 0000000..c199159 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowPreviousSearches.kt @@ -0,0 +1,11 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.util.fastForEach + +@Composable +fun ShowPreviousSearches(listOfSearches: List, onPreviousSearchedPressed: (String) ->Unit) { + listOfSearches.fastForEach { itemSearched -> + ItemRowSearch(itemSearched, onPreviousSearchedPressed) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowSearchResults.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowSearchResults.kt new file mode 100644 index 0000000..58f0364 --- /dev/null +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/searchscreen/components/ShowSearchResults.kt @@ -0,0 +1,26 @@ +package com.rld.justlisten.android.ui.searchscreen.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.rld.justlisten.android.ui.playlistscreen.Header +import com.rld.justlisten.datalayer.models.SongIconList +import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem +import com.rld.justlisten.viewmodel.screens.search.TrackItem + +@Composable +fun ShowSearchResults( + searchResultTracks: List, + searchResultPlaylist: List, + onSongPressed: (String, String, String, SongIconList) -> Unit, + onPlaylistPressed: (String, String, String, String, Boolean) -> Unit) { + Column(Modifier.fillMaxSize()) { + Header(text = "Top Find") + SearchGridTracks(list = searchResultTracks, onSongPressed) + Header(text = "Playlist", modifier = Modifier.padding(top = 10.dp)) + PlaylistResult(playlist = searchResultPlaylist, onPlaylistPressed) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/utils/Utils.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/utils/Utils.kt index 1eb187b..06c2685 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/utils/Utils.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/utils/Utils.kt @@ -1,6 +1,10 @@ package com.rld.justlisten.android.ui.utils +import android.support.v4.media.MediaBrowserCompat +import com.rld.justlisten.android.exoplayer.MusicServiceConnection +import com.rld.justlisten.android.exoplayer.utils.Constants import com.rld.justlisten.android.ui.theme.ColorPallet +import com.rld.justlisten.viewmodel.interfaces.Item fun getColorPallet(pallet: String): ColorPallet { return when(pallet) { @@ -12,4 +16,34 @@ fun getColorPallet(pallet: String): ColorPallet { "Pink" -> ColorPallet.Pink else -> ColorPallet.Dark } -} \ No newline at end of file +} + +fun playMusicFromId( + musicServiceConnection: MusicServiceConnection, + playlist: List, + songId: String, + isPlayerReady: Boolean +) { + if (isPlayerReady) { + musicServiceConnection.transportControls.playFromMediaId(songId, null) + } else { + playMusic(musicServiceConnection, playlist, isPlayerReady, songId) + } +} + +fun playMusic( + musicServiceConnection: MusicServiceConnection, + playlist: List, + isPlayerReady: Boolean, + playFromId: String = "" +) { + if (!isPlayerReady) { + musicServiceConnection.updatePlaylist(playlist) + musicServiceConnection.subscribe( + Constants.CLICKED_PLAYLIST, + object : MediaBrowserCompat.SubscriptionCallback() {}) + } + if (playFromId != "") { + musicServiceConnection.transportControls.playFromMediaId(playFromId, null) + } +} diff --git a/androidApp/src/main/res/drawable-anydpi/ic_most_played.xml b/androidApp/src/main/res/drawable-anydpi/ic_most_played.xml new file mode 100644 index 0000000..8abdbed --- /dev/null +++ b/androidApp/src/main/res/drawable-anydpi/ic_most_played.xml @@ -0,0 +1,11 @@ + + + diff --git a/androidApp/src/main/res/drawable-hdpi/ic_most_played.png b/androidApp/src/main/res/drawable-hdpi/ic_most_played.png new file mode 100644 index 0000000..6660d87 Binary files /dev/null and b/androidApp/src/main/res/drawable-hdpi/ic_most_played.png differ diff --git a/androidApp/src/main/res/drawable-mdpi/ic_most_played.png b/androidApp/src/main/res/drawable-mdpi/ic_most_played.png new file mode 100644 index 0000000..657477d Binary files /dev/null and b/androidApp/src/main/res/drawable-mdpi/ic_most_played.png differ diff --git a/androidApp/src/main/res/drawable-xhdpi/ic_most_played.png b/androidApp/src/main/res/drawable-xhdpi/ic_most_played.png new file mode 100644 index 0000000..f2869a1 Binary files /dev/null and b/androidApp/src/main/res/drawable-xhdpi/ic_most_played.png differ diff --git a/androidApp/src/main/res/drawable-xxhdpi/ic_most_played.png b/androidApp/src/main/res/drawable-xxhdpi/ic_most_played.png new file mode 100644 index 0000000..87cc12a Binary files /dev/null and b/androidApp/src/main/res/drawable-xxhdpi/ic_most_played.png differ diff --git a/androidApp/src/main/res/drawable/adele21.png b/androidApp/src/main/res/drawable/adele21.png deleted file mode 100644 index a1453a2..0000000 Binary files a/androidApp/src/main/res/drawable/adele21.png and /dev/null differ diff --git a/androidApp/src/main/res/drawable/bp.jpg b/androidApp/src/main/res/drawable/bp.jpg deleted file mode 100644 index c4abd78..0000000 Binary files a/androidApp/src/main/res/drawable/bp.jpg and /dev/null differ diff --git a/androidApp/src/main/res/drawable/camelia.jpeg b/androidApp/src/main/res/drawable/camelia.jpeg deleted file mode 100644 index d5bec2b..0000000 Binary files a/androidApp/src/main/res/drawable/camelia.jpeg and /dev/null differ diff --git a/androidApp/src/main/res/drawable/ed2.jpg b/androidApp/src/main/res/drawable/ed2.jpg deleted file mode 100644 index 7305fbb..0000000 Binary files a/androidApp/src/main/res/drawable/ed2.jpg and /dev/null differ diff --git a/androidApp/src/main/res/drawable/edsheeran.jpeg b/androidApp/src/main/res/drawable/edsheeran.jpeg deleted file mode 100644 index 0d3b012..0000000 Binary files a/androidApp/src/main/res/drawable/edsheeran.jpeg and /dev/null differ diff --git a/androidApp/src/main/res/drawable/eminem.jpeg b/androidApp/src/main/res/drawable/eminem.jpeg deleted file mode 100644 index 4befc12..0000000 Binary files a/androidApp/src/main/res/drawable/eminem.jpeg and /dev/null differ diff --git a/build.gradle.kts b/build.gradle.kts index f2713b8..54c467a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,16 @@ buildscript { - val compose_version by extra("1.2.0-alpha08") repositories { gradlePluginPortal() google() mavenCentral() } - val kotlin_version = "1.6.20" + val kotlin_version = "1.6.21" dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") - classpath("com.android.tools.build:gradle:7.2.0") - classpath("com.squareup.sqldelight:gradle-plugin:1.5.0") + classpath("com.android.tools.build:gradle:7.2.1") + classpath("com.squareup.sqldelight:gradle-plugin:1.5.3") classpath ("com.google.dagger:hilt-android-gradle-plugin:2.40.1") } @@ -26,4 +25,11 @@ allprojects { tasks.register("clean", Delete::class) { delete(rootProject.buildDir) -} \ No newline at end of file +} + +/* +tasks.withType{ + kotlinOptions { + freeCompilerArgs = listOf("-Xuse-k2") + } +}*/ diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index df22627..ea495f6 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -44,7 +44,7 @@ kotlin { val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-android:$ktor_version") - implementation("com.squareup.sqldelight:android-driver:1.5.0") + implementation("com.squareup.sqldelight:android-driver:1.5.3") } } @@ -57,7 +57,7 @@ kotlin { val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-ios:$ktor_version") - implementation("com.squareup.sqldelight:native-driver:1.5.0") + implementation("com.squareup.sqldelight:native-driver:1.5.3") } } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/library/LibraryCalls.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/library/LibraryCalls.kt index f8e8f3e..10509b9 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/library/LibraryCalls.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/library/LibraryCalls.kt @@ -1,10 +1,7 @@ package com.rld.justlisten.datalayer.datacalls.library import com.rld.justlisten.datalayer.Repository -import com.rld.justlisten.datalayer.localdb.libraryscreen.getFavoritePlaylist -import com.rld.justlisten.datalayer.localdb.libraryscreen.getRecentPlayed -import com.rld.justlisten.datalayer.localdb.libraryscreen.saveSongRecentSongs -import com.rld.justlisten.datalayer.localdb.libraryscreen.saveSongToFavorites +import com.rld.justlisten.datalayer.localdb.libraryscreen.* import com.rld.justlisten.datalayer.models.PlayListModel import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel @@ -19,10 +16,19 @@ fun Repository.saveSongToRecent(id: String, title : String, user: UserModel, son localDb.saveSongRecentSongs(id, title, user, songImgList, playlistName) } +fun Repository.saveSongToMostPlayed(id: String, title : String, user: UserModel, songImgList: SongIconList, + playlistName: String) { + localDb.saveMostPlayedSongs(id, title, user, songImgList, playlistName) +} + fun Repository.getFavoritePlaylist(): List { return localDb.getFavoritePlaylist() } +fun Repository.getMostPlayedSongs(numberOfLines: Long): List { + return localDb.getMostPlayedSongs(numberOfLines) +} + fun Repository.getRecentSongs(numberOfLines: Long): List { return localDb.getRecentPlayed(numberOfLines) } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/playlist/PlaylistCalls.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/playlist/PlaylistCalls.kt index 9a5d0ec..30b81fa 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/playlist/PlaylistCalls.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/datacalls/playlist/PlaylistCalls.kt @@ -4,46 +4,67 @@ import com.rld.justlisten.datalayer.Repository import com.rld.justlisten.datalayer.localdb.libraryscreen.getCustomPlaylistSongs import com.rld.justlisten.datalayer.localdb.libraryscreen.getFavoritePlaylist import com.rld.justlisten.datalayer.localdb.libraryscreen.getFavoritePlaylistWithId -import com.rld.justlisten.datalayer.localdb.playlistdetail.getPlaylistDetail +import com.rld.justlisten.datalayer.localdb.libraryscreen.getMostPlayedSongs import com.rld.justlisten.datalayer.webservices.apis.playlistcalls.fetchPlaylist import com.rld.justlisten.datalayer.webservices.apis.playlistcalls.getTracks -import com.rld.justlisten.datalayer.webservices.apis.searchcalls.searchFor import com.rld.justlisten.viewmodel.screens.playlist.PlayListEnum import com.rld.justlisten.viewmodel.screens.playlist.PlayListEnum.* import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem -import com.rld.justlisten.viewmodel.screens.search.SearchEnum import com.rld.justlisten.viewmodel.screens.search.TrackItem -suspend fun Repository.getPlaylist(index: Int, playListEnum: PlayListEnum, playlistId: String= "DOPRl", -songsList: List = emptyList(), queryPlaylist: String = "Rock"): List { +suspend fun Repository.getPlaylist( + index: Int, playListEnum: PlayListEnum, playlistId: String = "DOPRl", + songsList: List = emptyList(), queryPlaylist: String = "Rock" +): List { return when (playListEnum) { TOP_PLAYLIST -> webservices.fetchPlaylist(index, TOP_PLAYLIST)?.data?.map { playlistModel -> PlaylistItem(_data = playlistModel) } ?: emptyList() - REMIX -> webservices.fetchPlaylist(index, REMIX, queryPlaylist = queryPlaylist)?.data?.map { playlistModel -> + REMIX -> webservices.fetchPlaylist( + index, + REMIX, + queryPlaylist = queryPlaylist + )?.data?.map { playlistModel -> PlaylistItem(_data = playlistModel) } ?: emptyList() - CURRENT_PLAYLIST -> { webservices.fetchPlaylist(index, CURRENT_PLAYLIST, playlistId)?.data?.map { playlistModel -> - val hasFavorite = localDb.getFavoritePlaylistWithId(playlistModel.id) - val isFavorite = !hasFavorite.isNullOrEmpty() - PlaylistItem(_data = playlistModel, isFavorite) - } ?: emptyList()} + CURRENT_PLAYLIST -> { + webservices.fetchPlaylist( + index, + CURRENT_PLAYLIST, + playlistId + )?.data?.map { playlistModel -> + val hasFavorite = localDb.getFavoritePlaylistWithId(playlistModel.id) + val isFavorite = !hasFavorite.isNullOrEmpty() + PlaylistItem(_data = playlistModel, isFavorite) + } ?: emptyList() + } - HOT -> webservices.fetchPlaylist(index, HOT, queryPlaylist = queryPlaylist)?.data?.map { playlistModel -> + HOT -> webservices.fetchPlaylist( + index, + HOT, + queryPlaylist = queryPlaylist + )?.data?.map { playlistModel -> PlaylistItem(_data = playlistModel) } ?: emptyList() FAVORITE -> { - localDb.getFavoritePlaylist().map {playlistModel -> + localDb.getFavoritePlaylist().map { playlistModel -> + val hasFavorite = localDb.getFavoritePlaylistWithId(playlistModel.id) + val isFavorite = !hasFavorite.isNullOrEmpty() + PlaylistItem(playlistModel, isFavorite) + }.toList() + } + MOST_PLAYED -> { + localDb.getMostPlayedSongs(20).map { playlistModel -> val hasFavorite = localDb.getFavoritePlaylistWithId(playlistModel.id) val isFavorite = !hasFavorite.isNullOrEmpty() PlaylistItem(playlistModel, isFavorite) }.toList() } CREATED_BY_USER -> { - localDb.getCustomPlaylistSongs(songsList).map {playlistModel -> + localDb.getCustomPlaylistSongs(songsList).map { playlistModel -> val hasFavorite = localDb.getFavoritePlaylistWithId(playlistModel.id) val isFavorite = !hasFavorite.isNullOrEmpty() PlaylistItem(playlistModel, isFavorite) @@ -52,13 +73,7 @@ songsList: List = emptyList(), queryPlaylist: String = "Rock"): List = withRepoContext { - localDb.getPlaylistDetail().map { - elem->PlaylistItem(_data = elem) - }.toList() -} - -suspend fun Repository.getTracks(limit: Int, category: String, timeRange: String) : List { +suspend fun Repository.getTracks(limit: Int, category: String, timeRange: String): List { return webservices.getTracks(limit, category, timeRange)?.data?.map { playlistModel -> TrackItem(playlistModel) }?.toList() ?: emptyList() diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/Library.sq b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/Library.sq index a9e7747..92fce19 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/Library.sq +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/Library.sq @@ -9,7 +9,8 @@ CREATE TABLE Library ( playlistName TEXT NOT NULL, recentPlayed INTEGER AS Boolean DEFAULT 0, favoriteSong INTEGER AS Boolean DEFAULT 0, - recentIncrement INTEGER + recentIncrement INTEGER, + songCounter Integer ); getFavoritePlaylist: @@ -24,14 +25,27 @@ SELECT * FROM Library WHERE recentPlayed = 1 ORDER BY recentIncrement DESC LIMIT getCustomPlaylistSongs: SELECT * FROM Library WHERE id IN :songsList; +getMostPlayed: +SELECT * FROM Library WHERE songCounter NOT NULL ORDER BY songCounter DESC LIMIT :numberOfSongs; + upsertLibraryFavorite { - INSERT OR REPLACE INTO Library(id, title, user, songImgList, playlistName, favoriteSong, recentPlayed, recentIncrement) + INSERT OR REPLACE INTO Library(id, title, user, songImgList, playlistName, favoriteSong, recentPlayed, recentIncrement, songCounter) VALUES(:id, :title, :user, :songImgList, :playlistName,:favoriteSong, - (SELECT recentPlayed FROM Library WHERE id = :id), (SELECT recentIncrement FROM Library WHERE id= :id)); + (SELECT recentPlayed FROM Library WHERE id = :id), + (SELECT recentIncrement FROM Library WHERE id= :id), + (SELECT songCounter FROM Library WHERE id= :id)); } upsertLibraryRecent { - INSERT OR REPLACE INTO Library(id, title, user, songImgList, playlistName, recentPlayed, favoriteSong, recentIncrement) + INSERT OR REPLACE INTO Library(id, title, user, songImgList, playlistName, recentPlayed, favoriteSong, recentIncrement, songCounter) + VALUES(:id, :title, :user, :songImgList, :playlistName, 1, + (SELECT favoriteSong FROM Library WHERE id= :id), (SELECT IFNULL(MAX(recentIncrement), 0) +1 FROM Library WHERE recentPlayed = 1), + IFNULL((SELECT songCounter FROM Library WHERE id = :id), 0) + 1); +} + +upsertLibraryMostPlayed { + INSERT OR REPLACE INTO Library(id, title, user, songImgList, playlistName, recentPlayed, favoriteSong, recentIncrement, songCounter) VALUES(:id, :title, :user, :songImgList, :playlistName, 1, - (SELECT favoriteSong FROM Library WHERE id= :id), (SELECT IFNULL(MAX(recentIncrement), 0) +1 FROM Library WHERE recentPlayed = 1)); + (SELECT favoriteSong FROM Library WHERE id= :id), (SELECT recentIncrement FROM Library WHERE id= :id), + (SELECT IFNULL(songCounter, 0) +1 FROM Library WHERE id = : id)); } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/LibraryFunctions.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/LibraryFunctions.kt index f6e9977..625f9ce 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/LibraryFunctions.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/libraryscreen/LibraryFunctions.kt @@ -23,7 +23,7 @@ fun LocalDb.saveSongToFavorites( } fun LocalDb.getFavoritePlaylist(): List { - return libraryQueries.getFavoritePlaylist(mapper = { id, title, user, songImgList, _, _, _,_ -> + return libraryQueries.getFavoritePlaylist(mapper = { id, title, user, songImgList, _, _, _, _, _ -> PlayListModel( id = id, playlistTitle = title, @@ -36,7 +36,7 @@ fun LocalDb.getFavoritePlaylist(): List { fun LocalDb.getCustomPlaylistSongs(songsList: List): List { return libraryQueries.getCustomPlaylistSongs( - songsList, mapper = { id, title, user, songImgList, playlistName, _, _, _ + songsList, mapper = { id, title, user, songImgList, _, _, _, _, _ -> PlayListModel(id, title, title, songImgList, user) }).executeAsList() @@ -55,9 +55,18 @@ fun LocalDb.saveSongRecentSongs( } } +fun LocalDb.saveMostPlayedSongs( + id: String, title: String, user: UserModel, songImgList: SongIconList, + playlistName: String +) { + libraryQueries.transaction { + libraryQueries.upsertLibraryMostPlayed(id, title, user, songImgList, playlistName) + } +} + fun LocalDb.getRecentPlayed(numberOfLines: Long): List { return libraryQueries.getRecentPlayed( - mapper = { id, title, user, songImgList, _, _, isFavorite, _ -> + mapper = { id, title, user, songImgList, _, _, isFavorite, _, _ -> PlayListModel( id = id, playlistTitle = title, @@ -69,4 +78,18 @@ fun LocalDb.getRecentPlayed(numberOfLines: Long): List { }, numberOfSongs = numberOfLines ).executeAsList() +} + +fun LocalDb.getMostPlayedSongs(numberOfSongs: Long): List { + return libraryQueries.getMostPlayed(numberOfSongs = numberOfSongs, + mapper = { id, title, user, songImgList, _, _, _, _, songCounter -> + PlayListModel( + id = id, + playlistTitle = title, + title = title, + user = user, + songImgList = songImgList, + songCounter = songCounter.toString() + ) + }).executeAsList() } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/migration/1.sqm b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/migration/1.sqm new file mode 100644 index 0000000..044a58d --- /dev/null +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/migration/1.sqm @@ -0,0 +1 @@ +ALTER TABLE Library ADD songCounter INTEGER; \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/settingsscreen/SettingsScreen.sq b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/settingsscreen/SettingsScreen.sq index bd82c49..fffa876 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/settingsscreen/SettingsScreen.sq +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/localdb/settingsscreen/SettingsScreen.sq @@ -5,7 +5,7 @@ CREATE TABLE SettingsInfo ( palletColor TEXT NOT NULL ); -INSERT INTO SettingsInfo(hasNavigationDonationOn, isDarkThemeOn, palletColor) VALUES (1, 1, "Dark"); +INSERT INTO SettingsInfo(hasNavigationDonationOn, isDarkThemeOn, palletColor) VALUES (0, 1, "Dark"); getSettingsInfo: SELECT * FROM SettingsInfo; diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/models/PlayListModel.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/models/PlayListModel.kt index c983bee..d2b1a4d 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/models/PlayListModel.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/models/PlayListModel.kt @@ -12,5 +12,6 @@ data class PlayListModel( @SerialName("artwork") val songImgList: SongIconList = SongIconList(), @SerialName("user") val user: UserModel = UserModel(), @SerialName("is_playlist") val isPlaylist: Boolean = false, - @Transient val isFavorite: Boolean = false + @Transient val isFavorite: Boolean = false, + @Transient val songCounter: String = "" ) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/apis/playlistcalls/FetchTopPlaylist.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/apis/playlistcalls/FetchTopPlaylist.kt index bc62cfe..81a86f7 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/apis/playlistcalls/FetchTopPlaylist.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/apis/playlistcalls/FetchTopPlaylist.kt @@ -16,6 +16,7 @@ suspend fun ApiClient.fetchPlaylist(index: Int, playListEnum: PlayListEnum, play HOT -> getResponse("/playlists/search?query=${queryPlaylist}&limit=${index}&app_name=$appName") FAVORITE -> TODO() CREATED_BY_USER -> TODO() + MOST_PLAYED -> TODO() } } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/interfaces/Item.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/interfaces/Item.kt index 2a00e00..05f22a8 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/interfaces/Item.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/interfaces/Item.kt @@ -3,10 +3,11 @@ package com.rld.justlisten.viewmodel.interfaces import com.rld.justlisten.datalayer.models.SongIconList interface Item { - val user : String - val title : String - val playlistTitle : String - val id : String + val user: String + val title: String + val playlistTitle: String + val id: String var isFavorite: Boolean - val songIconList : SongIconList + val songIconList: SongIconList + val songCounter: String } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryEvents.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryEvents.kt index 66f9abd..697f5ec 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryEvents.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryEvents.kt @@ -2,6 +2,7 @@ package com.rld.justlisten.viewmodel.screens.library import com.rld.justlisten.datalayer.datacalls.library.getRecentSongs import com.rld.justlisten.datalayer.datacalls.library.saveSongToFavorites +import com.rld.justlisten.datalayer.datacalls.library.saveSongToMostPlayed import com.rld.justlisten.datalayer.datacalls.library.saveSongToRecent import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.datalayer.models.UserModel @@ -30,6 +31,16 @@ fun Events.saveSongToRecent( dataRepository.saveSongToRecent(id, title, user, songImgList, playListName) } +fun Events.saveSongToMostPlayed( + id: String, + title: String, + user: UserModel, + songImgList: SongIconList, + playListName: String = "Most Played" +) = screenCoroutine { + dataRepository.saveSongToMostPlayed(id, title, user, songImgList, playListName) +} + fun Events.getLastPlayed(numberOfSongs: Long) = screenCoroutine { stateManager.updateScreen(LibraryState::class) { diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryInit.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryInit.kt index 4e82096..38d2ac3 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryInit.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryInit.kt @@ -3,6 +3,7 @@ package com.rld.justlisten.viewmodel.screens.library import com.rld.justlisten.Navigation import com.rld.justlisten.ScreenParams import com.rld.justlisten.datalayer.datacalls.library.getFavoritePlaylist +import com.rld.justlisten.datalayer.datacalls.library.getMostPlayedSongs import com.rld.justlisten.datalayer.datacalls.library.getRecentSongs import com.rld.justlisten.viewmodel.screens.ScreenInitSettings import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem @@ -21,9 +22,15 @@ fun Navigation.initLibrary(params: LibraryParams) = ScreenInitSettings( val favoritePlaylist = dataRepository.getFavoritePlaylist().map { playlistModel -> PlaylistItem(playlistModel) }.toList() + val mostPlayedSongs = dataRepository.getMostPlayedSongs(20).map { playlistModel -> + PlaylistItem(playlistModel) + } stateManager.updateScreen(LibraryState::class) { - it.copy(isLoading = false, favoritePlaylistItems = favoritePlaylist, - recentSongsItems = recentSongs) + it.copy( + isLoading = false, favoritePlaylistItems = favoritePlaylist, + mostPlayedSongs = mostPlayedSongs, + recentSongsItems = recentSongs + ) } }, reinitOnEachNavigation = true diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryState.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryState.kt index 1941dc0..7e86218 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryState.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/library/LibraryState.kt @@ -6,6 +6,7 @@ import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem data class LibraryState( val isLoading: Boolean = false, val favoritePlaylistItems: List = emptyList(), + val mostPlayedSongs: List = emptyList(), val recentSongsItems: List = emptyList(), var lastIndexReached: Boolean = false ): ScreenState \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEnum.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEnum.kt index 937eba9..5b93658 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEnum.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEnum.kt @@ -6,5 +6,6 @@ enum class PlayListEnum { HOT, CURRENT_PLAYLIST, FAVORITE, + MOST_PLAYED, CREATED_BY_USER } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEvents.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEvents.kt index e333848..dc419dd 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEvents.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistEvents.kt @@ -54,6 +54,7 @@ fun Events.fetchPlaylist(index: Int, playlistEnum: PlayListEnum, queryPlaylist: CURRENT_PLAYLIST -> TODO() CREATED_BY_USER -> TODO() FAVORITE -> it.copy(currentPlaylist = dataRepository.getPlaylist(0, playlistEnum)) + MOST_PLAYED -> TODO() } } } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistState.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistState.kt index ff55469..17a90f0 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistState.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistState.kt @@ -32,5 +32,6 @@ data class PlaylistItem( override val playlistTitle = _data.playlistTitle override val id = _data.id override val songIconList = _data.songImgList + override val songCounter = _data.songCounter } diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenState.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenState.kt index 5fc62ad..f7d4e07 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenState.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenState.kt @@ -2,7 +2,6 @@ package com.rld.justlisten.viewmodel.screens.search import com.rld.justlisten.ScreenState import com.rld.justlisten.datalayer.models.PlayListModel -import com.rld.justlisten.datalayer.models.SongIconList import com.rld.justlisten.viewmodel.interfaces.Item import com.rld.justlisten.viewmodel.screens.playlist.PlaylistItem @@ -21,4 +20,6 @@ data class TrackItem(val _data: PlayListModel, override var isFavorite: Boolean override val playlistTitle = _data.playlistTitle override val id = _data.id override val songIconList = _data.songImgList + override val songCounter: String + get() = TODO("Not yet implemented") } \ No newline at end of file