Selaa lähdekoodia

Move sleep timer to PlayerView menu (#98)

vfsfitvnm 3 vuotta sitten
vanhempi
commit
78cbd9d129

+ 132 - 7
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/MediaItemMenu.kt

@@ -1,18 +1,22 @@
 package it.vfsfitvnm.vimusic.ui.components.themed
 
+import android.text.format.DateUtils
 import androidx.compose.animation.AnimatedContentScope
 import androidx.compose.animation.ExperimentalAnimationApi
 import androidx.compose.animation.with
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.*
 import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
 import androidx.media3.common.MediaItem
 import it.vfsfitvnm.route.RouteHandler
 import it.vfsfitvnm.route.empty
@@ -21,13 +25,18 @@ import it.vfsfitvnm.vimusic.R
 import it.vfsfitvnm.vimusic.models.DetailedSong
 import it.vfsfitvnm.vimusic.models.Playlist
 import it.vfsfitvnm.vimusic.models.SongPlaylistMap
+import it.vfsfitvnm.vimusic.ui.components.ChunkyButton
 import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
+import it.vfsfitvnm.vimusic.ui.components.Pager
 import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
 import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
 import it.vfsfitvnm.vimusic.ui.screens.rememberCreatePlaylistRoute
+import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
+import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
 import it.vfsfitvnm.vimusic.utils.*
 import it.vfsfitvnm.youtubemusic.models.NavigationEndpoint
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.flowOf
 
 
 @ExperimentalAnimationApi
@@ -361,12 +370,128 @@ fun MediaItemMenu(
                     }
 
                     onSetSleepTimer?.let { onSetSleepTimer ->
+                        val binder = LocalPlayerServiceBinder.current
+                        val typography = LocalTypography.current
+                        val colorPalette = LocalColorPalette.current
+
+                        var isShowingSleepTimerDialog by remember {
+                            mutableStateOf(false)
+                        }
+
+                        val sleepTimerMillisLeft by (binder?.sleepTimerMillisLeft ?: flowOf(null))
+                            .collectAsState(initial = null)
+
+                        if (isShowingSleepTimerDialog) {
+                            if (sleepTimerMillisLeft != null) {
+                                ConfirmationDialog(
+                                    text = "Do you want to stop the sleep timer?",
+                                    cancelText = "No",
+                                    confirmText = "Stop",
+                                    onDismiss = {
+                                        isShowingSleepTimerDialog = false
+                                    },
+                                    onConfirm = {
+                                        binder?.cancelSleepTimer()
+                                    }
+                                )
+                            } else {
+                                DefaultDialog(
+                                    onDismiss = {
+                                        isShowingSleepTimerDialog = false
+                                    }
+                                ) {
+                                    var hours by remember {
+                                        mutableStateOf(0)
+                                    }
+
+                                    var minutes by remember {
+                                        mutableStateOf(0)
+                                    }
+
+                                    BasicText(
+                                        text = "Set sleep timer",
+                                        style = typography.s.semiBold,
+                                        modifier = Modifier
+                                            .padding(vertical = 8.dp, horizontal = 24.dp)
+                                    )
+
+                                    Row(
+                                        verticalAlignment = Alignment.CenterVertically,
+                                        modifier = Modifier
+                                            .padding(vertical = 16.dp)
+                                    ) {
+                                        Pager(
+                                            selectedIndex = hours,
+                                            onSelectedIndex = {
+                                                hours = it
+                                            },
+                                            orientation = Orientation.Vertical,
+                                            modifier = Modifier
+                                                .padding(horizontal = 8.dp)
+                                                .height(92.dp)
+                                        ) {
+                                            repeat(12) {
+                                                BasicText(
+                                                    text = "$it h",
+                                                    style = typography.xs.semiBold
+                                                )
+                                            }
+                                        }
+
+                                        Pager(
+                                            selectedIndex = minutes,
+                                            onSelectedIndex = {
+                                                minutes = it
+                                            },
+                                            orientation = Orientation.Vertical,
+                                            modifier = Modifier
+                                                .padding(horizontal = 8.dp)
+                                                .height(72.dp)
+                                        ) {
+                                            repeat(4) {
+                                                BasicText(
+                                                    text = "${it * 15} m",
+                                                    style = typography.xs.semiBold
+                                                )
+                                            }
+                                        }
+                                    }
+
+                                    Row(
+                                        horizontalArrangement = Arrangement.SpaceEvenly,
+                                        modifier = Modifier
+                                            .fillMaxWidth()
+                                    ) {
+                                        ChunkyButton(
+                                            backgroundColor = Color.Transparent,
+                                            text = "Cancel",
+                                            textStyle = typography.xs.semiBold,
+                                            shape = RoundedCornerShape(36.dp),
+                                            onClick = { isShowingSleepTimerDialog = false }
+                                        )
+
+                                        ChunkyButton(
+                                            backgroundColor = colorPalette.primaryContainer,
+                                            text = "Set",
+                                            textStyle = typography.xs.semiBold.color(colorPalette.onPrimaryContainer),
+                                            shape = RoundedCornerShape(36.dp),
+                                            isEnabled = hours > 0 || minutes > 0,
+                                            onClick = {
+                                                binder?.startSleepTimer((hours * 60 + minutes * 15) * 60 * 1000L)
+                                                isShowingSleepTimerDialog = false
+                                            }
+                                        )
+                                    }
+                                }
+                            }
+                        }
+
                         MenuEntry(
-                            icon = R.drawable.time,
+                            icon = R.drawable.alarm,
                             text = "Sleep timer",
+                            secondaryText = sleepTimerMillisLeft?.let { "${DateUtils.formatElapsedTime(it / 1000)} left" },
                             onClick = {
-                                onDismiss()
-                                onSetSleepTimer()
+                                isShowingSleepTimerDialog = true
                             }
                         )
                     }

+ 1 - 134
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/PlayerSettingsScreen.kt

@@ -2,19 +2,15 @@ package it.vfsfitvnm.vimusic.ui.screens.settings
 
 import android.content.Intent
 import android.media.audiofx.AudioEffect
-import android.text.format.DateUtils
 import android.widget.Toast
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.compose.animation.ExperimentalAnimationApi
 import androidx.compose.foundation.*
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.text.BasicText
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.ColorFilter
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
@@ -22,18 +18,12 @@ import androidx.compose.ui.unit.dp
 import it.vfsfitvnm.route.RouteHandler
 import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
 import it.vfsfitvnm.vimusic.R
-import it.vfsfitvnm.vimusic.ui.components.ChunkyButton
-import it.vfsfitvnm.vimusic.ui.components.Pager
 import it.vfsfitvnm.vimusic.ui.components.TopAppBar
-import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
-import it.vfsfitvnm.vimusic.ui.components.themed.DefaultDialog
 import it.vfsfitvnm.vimusic.ui.screens.*
 import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
 import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
 import it.vfsfitvnm.vimusic.utils.LocalPreferences
-import it.vfsfitvnm.vimusic.utils.color
 import it.vfsfitvnm.vimusic.utils.semiBold
-import kotlinx.coroutines.flow.flowOf
 
 
 @ExperimentalAnimationApi
@@ -68,118 +58,6 @@ fun PlayerSettingsScreen() {
                 rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                 }
 
-            val sleepTimerMillisLeft by (binder?.sleepTimerMillisLeft
-                ?: flowOf(null)).collectAsState(initial = null)
-
-            var isShowingSleepTimerDialog by remember {
-                mutableStateOf(false)
-            }
-
-            if (isShowingSleepTimerDialog) {
-                if (sleepTimerMillisLeft != null) {
-                    ConfirmationDialog(
-                        text = "Do you want to stop the sleep timer?",
-                        cancelText = "No",
-                        confirmText = "Stop",
-                        onDismiss = {
-                            isShowingSleepTimerDialog = false
-                        },
-                        onConfirm = {
-                            binder?.cancelSleepTimer()
-                        }
-                    )
-                } else {
-                    DefaultDialog(
-                        onDismiss = {
-                            isShowingSleepTimerDialog = false
-                        },
-                        modifier = Modifier
-                    ) {
-                        var hours by remember {
-                            mutableStateOf(0)
-                        }
-
-                        var minutes by remember {
-                            mutableStateOf(0)
-                        }
-
-                        BasicText(
-                            text = "Set sleep timer",
-                            style = typography.s.semiBold,
-                            modifier = Modifier
-                                .padding(vertical = 8.dp, horizontal = 24.dp)
-                        )
-
-                        Row(
-                            modifier = Modifier
-                                .padding(vertical = 16.dp)
-                        ) {
-                            Pager(
-                                selectedIndex = hours,
-                                onSelectedIndex = {
-                                    hours = it
-                                },
-                                orientation = Orientation.Vertical,
-                                modifier = Modifier
-                                    .padding(horizontal = 8.dp)
-                                    .height(72.dp)
-                            ) {
-                                repeat(12) {
-                                    BasicText(
-                                        text = "$it h",
-                                        style = typography.xs.semiBold
-                                    )
-                                }
-                            }
-
-                            Pager(
-                                selectedIndex = minutes,
-                                onSelectedIndex = {
-                                    minutes = it
-                                },
-                                orientation = Orientation.Vertical,
-                                modifier = Modifier
-                                    .padding(horizontal = 8.dp)
-                                    .height(72.dp)
-                            ) {
-                                repeat(4) {
-                                    BasicText(
-                                        text = "${it * 15} m",
-                                        style = typography.xs.semiBold
-                                    )
-                                }
-                            }
-                        }
-
-                        Row(
-                            horizontalArrangement = Arrangement.SpaceEvenly,
-                            modifier = Modifier
-                                .fillMaxWidth()
-                        ) {
-                            ChunkyButton(
-                                backgroundColor = Color.Transparent,
-                                text = "Cancel",
-                                textStyle = typography.xs.semiBold,
-                                shape = RoundedCornerShape(36.dp),
-                                onClick = { isShowingSleepTimerDialog = false }
-                            )
-
-                            ChunkyButton(
-                                backgroundColor = colorPalette.primaryContainer,
-                                text = "Set",
-                                textStyle = typography.xs.semiBold.color(colorPalette.onPrimaryContainer),
-                                shape = RoundedCornerShape(36.dp),
-                                isEnabled = hours > 0 || minutes > 0,
-                                onClick = {
-                                    binder?.startSleepTimer((hours * 60 + minutes * 15) * 60 * 1000L)
-                                    isShowingSleepTimerDialog = false
-                                }
-                            )
-                        }
-                    }
-                }
-            }
-
             Column(
                 modifier = Modifier
                     .background(colorPalette.background)
@@ -262,17 +140,6 @@ fun PlayerSettingsScreen() {
                         }
                     }
                 )
-
-                SettingsEntryGroupText(title = "OTHER")
-
-                SettingsEntry(
-                    title = "Sleep timer",
-                    text = sleepTimerMillisLeft?.let { "${DateUtils.formatElapsedTime(it / 1000)} left" }
-                        ?: "Stop the music after a period of time",
-                    onClick = {
-                        isShowingSleepTimerDialog = true
-                    }
-                )
             }
         }
     }

+ 1 - 1
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt

@@ -75,7 +75,6 @@ fun PlayerView(
     player ?: return
     playerState?.mediaItem ?: return
 
-
     BottomSheet(
         state = layoutState,
         modifier = modifier,
@@ -288,6 +287,7 @@ fun PlayerView(
                                             .show()
                                     }
                                 },
+                                onSetSleepTimer = {},
                                 onDismiss = menuState::hide,
                                 onGlobalRouteEmitted = layoutState.collapse,
                             )

+ 15 - 0
app/src/main/res/drawable/alarm.xml

@@ -0,0 +1,15 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="512dp"
+    android:height="512dp"
+    android:viewportWidth="512"
+    android:viewportHeight="512">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M153.59,110.46A21.41,21.41 0,0 0,152.48 79h0A62.67,62.67 0,0 0,112 64l-3.27,0.09 -0.48,0C74.4,66.15 48,95.55 48.07,131c0,19 8,29.06 14.32,37.11a20.61,20.61 0,0 0,14.7 7.8c0.26,0 0.7,0.05 2,0.05a19.06,19.06 0,0 0,13.75 -5.89Z"/>
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M403.79,64.11l-3.27,-0.1H400a62.67,62.67 0,0 0,-40.52 15,21.41 21.41,0 0,0 -1.11,31.44l60.77,59.65A19.06,19.06 0,0 0,432.93 176c1.28,0 1.72,0 2,-0.05a20.61,20.61 0,0 0,14.69 -7.8c6.36,-8.05 14.28,-18.08 14.32,-37.11C464,95.55 437.6,66.15 403.79,64.11Z"/>
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M256.07,96c-97,0 -176,78.95 -176,176a175.23,175.23 0,0 0,40.81 112.56L84.76,420.69a16,16 0,1 0,22.63 22.62l36.12,-36.12a175.63,175.63 0,0 0,225.12 0l36.13,36.12a16,16 0,1 0,22.63 -22.62l-36.13,-36.13A175.17,175.17 0,0 0,432.07 272C432.07,175 353.12,96 256.07,96ZM272.07,272a16,16 0,0 1,-16 16h-80a16,16 0,0 1,0 -32h64L240.07,160a16,16 0,0 1,32 0Z"/>
+</vector>