@@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.height
1616import androidx.compose.foundation.layout.padding
1717import androidx.compose.foundation.layout.safeDrawingPadding
1818import androidx.compose.foundation.shape.CircleShape
19- import androidx.compose.foundation.shape.RoundedCornerShape
2019import androidx.compose.material.Icon
2120import androidx.compose.material.IconButton
2221import androidx.compose.material.LocalTextStyle
@@ -31,14 +30,12 @@ import androidx.compose.ui.Alignment
3130import androidx.compose.ui.Modifier
3231import androidx.compose.ui.draw.clip
3332import androidx.compose.ui.geometry.Offset
34- import androidx.compose.ui.graphics.Brush
3533import androidx.compose.ui.graphics.Color
3634import androidx.compose.ui.graphics.Shadow
3735import androidx.compose.ui.layout.ContentScale
3836import androidx.compose.ui.platform.LocalContext
3937import androidx.compose.ui.res.painterResource
4038import androidx.compose.ui.res.stringResource
41- import androidx.compose.ui.text.TextStyle
4239import androidx.compose.ui.text.font.FontWeight
4340import androidx.compose.ui.text.style.LineBreak
4441import androidx.compose.ui.text.style.TextAlign
@@ -52,19 +49,12 @@ import coil3.request.error
5249import coil3.toBitmap
5350import io.newm.core.resources.R
5451import io.newm.core.theme.Black
55- import io.newm.core.theme.DarkPink
56- import io.newm.core.theme.DarkViolet
57- import io.newm.core.theme.Gray500
58- import io.newm.core.theme.GraySuit
5952import io.newm.core.theme.White
6053import io.newm.core.theme.inter
6154import io.newm.core.ui.ZoomableImage
6255import io.newm.core.ui.utils.SwipeDirection
6356import io.newm.core.ui.utils.SwipeableWrapper
64- import io.newm.core.ui.utils.drawWithBrush
65- import io.newm.core.ui.utils.millisToMinutesSecondsString
66- import io.newm.feature.musicplayer.models.PlaybackRepeatMode
67- import io.newm.feature.musicplayer.models.PlaybackState
57+ import io.newm.feature.musicplayer.components.MusicPlayerControls
6858import io.newm.feature.musicplayer.models.PlaybackStatus
6959import io.newm.feature.musicplayer.models.Track
7060import io.newm.feature.musicplayer.share.ShareButton
@@ -73,18 +63,6 @@ import kotlinx.coroutines.Dispatchers
7363import kotlinx.coroutines.launch
7464import kotlinx.coroutines.withContext
7565
76- private val playbackTimeStyle
77- @Composable
78- get() =
79- TextStyle (
80- fontSize = 12 .sp,
81- fontFamily = inter,
82- fontWeight = FontWeight .Normal ,
83- color = GraySuit ,
84- )
85-
86- internal val MusicPlayerBrush = Brush .horizontalGradient(listOf (DarkViolet , DarkPink ))
87-
8866@Composable
8967internal fun MusicPlayerViewer (
9068 modifier : Modifier = Modifier ,
@@ -196,206 +174,6 @@ internal fun MusicPlayerViewer(
196174 }
197175}
198176
199- @Composable
200- private fun MusicPlayerControls (
201- playbackStatus : PlaybackStatus ,
202- onEvent : (PlaybackUiEvent ) -> Unit ,
203- ) {
204- Box {
205- PlaybackControlPanel (playbackStatus = playbackStatus, onEvent = onEvent)
206- if (playbackStatus.duration != null ) {
207- MusicPlayerSlider (
208- value = playbackStatus.elapsedFraction,
209- onValueChange = {
210- onEvent(
211- PlaybackUiEvent .Seek (
212- (it * playbackStatus.duration.inWholeMilliseconds).toLong(),
213- ),
214- )
215- },
216- colors = SliderDefaults .colors(thumbColor = White , inactiveTrackColor = Gray500 ),
217- modifier = Modifier .fillMaxWidth().padding(horizontal = 12 .dp).height(4 .dp),
218- )
219- }
220- }
221- }
222-
223- @Composable
224- fun PlaybackControlPanel (
225- playbackStatus : PlaybackStatus ,
226- onEvent : (PlaybackUiEvent ) -> Unit ,
227- ) {
228- Box (
229- modifier =
230- Modifier
231- .height(102 .dp)
232- .fillMaxWidth()
233- .padding(horizontal = 16 .dp)
234- .padding()
235- .clip(shape = RoundedCornerShape (bottomEnd = 8 .dp, bottomStart = 8 .dp)),
236- ) {
237- Column (modifier = Modifier .background(Black ).fillMaxSize()) {
238- Row (modifier = Modifier .padding(horizontal = 12 .dp).padding(top = 8 .dp)) {
239- Text (
240- text = playbackStatus.position.millisToMinutesSecondsString(),
241- style = playbackTimeStyle,
242- )
243- Spacer (modifier = Modifier .weight(1f ))
244- Text (
245- text =
246- if (playbackStatus.duration == null ) {
247- " -:--"
248- } else {
249- playbackStatus.duration.inWholeMilliseconds
250- .millisToMinutesSecondsString()
251- },
252- style = playbackTimeStyle,
253- )
254- }
255- Spacer (modifier = Modifier .weight(1f ))
256- Row (modifier = Modifier .padding(12 .dp)) {
257- RepeatButton (
258- playbackStatus.repeatMode,
259- onClick = { onEvent(PlaybackUiEvent .Repeat ) },
260- )
261- Spacer (modifier = Modifier .weight(1f ))
262- PreviousTrackButton (
263- modifier = Modifier .padding(horizontal = 12 .dp),
264- onClick = { onEvent(PlaybackUiEvent .Previous ) },
265- )
266- PlayOrPauseButton (playbackStatus = playbackStatus, onEvent = onEvent)
267- NextTrackButton (
268- modifier = Modifier .padding(horizontal = 12 .dp),
269- onClick = { onEvent(PlaybackUiEvent .Next ) },
270- )
271- Spacer (modifier = Modifier .weight(1f ))
272- ShuffleButton (
273- enabled = playbackStatus.state == PlaybackState .PLAYING ,
274- shuffleMode = playbackStatus.shuffleMode,
275- onClick = { onEvent(PlaybackUiEvent .ToggleShuffle ) },
276- )
277- }
278- }
279- }
280- }
281-
282- @Composable
283- fun ShuffleButton (
284- onClick : () -> Unit ,
285- shuffleMode : Boolean ,
286- enabled : Boolean ,
287- ) {
288- IconButton (onClick = onClick, enabled = enabled) {
289- Icon (
290- painter = painterResource(R .drawable.ic_music_player_shuffle),
291- contentDescription = stringResource(R .string.music_player_shuffle_description),
292- tint =
293- when {
294- enabled.not () -> Gray500
295- shuffleMode -> DarkViolet
296- else -> White
297- },
298- )
299- }
300- }
301-
302- @Composable
303- private fun PlayOrPauseButton (
304- playbackStatus : PlaybackStatus ,
305- onEvent : (PlaybackUiEvent ) -> Unit ,
306- ) {
307- when (playbackStatus.state) {
308- PlaybackState .PLAYING ,
309- PlaybackState .BUFFERING ,
310- -> {
311- PauseButton (onClick = { onEvent(PlaybackUiEvent .Pause ) })
312- }
313-
314- PlaybackState .PAUSED ,
315- PlaybackState .STOPPED ,
316- -> {
317- PlayButton (onClick = { onEvent(PlaybackUiEvent .Play ) })
318- }
319- }
320- }
321-
322- @Composable
323- private fun PreviousTrackButton (
324- onClick : () -> Unit ,
325- modifier : Modifier = Modifier ,
326- ) {
327- IconButton (modifier = modifier, onClick = onClick) {
328- Icon (
329- painter = painterResource(id = R .drawable.ic_prev_track_default),
330- contentDescription = stringResource(R .string.music_player_prev_track_description),
331- tint = Color .White ,
332- )
333- }
334- }
335-
336- @Composable
337- private fun PlayButton (
338- onClick : () -> Unit ,
339- modifier : Modifier = Modifier ,
340- ) {
341- IconButton (modifier = modifier, onClick = onClick) {
342- Icon (
343- painter = painterResource(id = R .drawable.ic_play),
344- contentDescription = stringResource(R .string.music_player_play_description),
345- modifier = Modifier .drawWithBrush(MusicPlayerBrush ),
346- )
347- }
348- }
349-
350- @Composable
351- fun PauseButton (
352- onClick : () -> Unit ,
353- modifier : Modifier = Modifier ,
354- ) {
355- IconButton (modifier = modifier, onClick = onClick) {
356- Icon (
357- painter = painterResource(id = R .drawable.ic_pause),
358- contentDescription = stringResource(R .string.music_player_pause_description),
359- modifier = Modifier .drawWithBrush(MusicPlayerBrush ),
360- )
361- }
362- }
363-
364- @Composable
365- fun NextTrackButton (
366- onClick : () -> Unit ,
367- modifier : Modifier = Modifier ,
368- ) {
369- IconButton (modifier = modifier, onClick = onClick) {
370- Icon (
371- painter = painterResource(id = R .drawable.ic_next_track_default),
372- contentDescription = stringResource(R .string.music_player_next_track_description),
373- tint = Color .White ,
374- )
375- }
376- }
377-
378- @Composable
379- fun RepeatButton (
380- repeatMode : PlaybackRepeatMode ,
381- onClick : () -> Unit ,
382- modifier : Modifier = Modifier ,
383- ) {
384- val imageRes =
385- when (repeatMode) {
386- PlaybackRepeatMode .REPEAT_OFF -> R .drawable.ic_repeat_off
387- PlaybackRepeatMode .REPEAT_ONE -> R .drawable.ic_music_player_repeat_one
388- PlaybackRepeatMode .REPEAT_ALL -> R .drawable.ic_music_player_repeat_all
389- }
390- IconButton (modifier = modifier, onClick = onClick) {
391- Icon (
392- painter = painterResource(id = imageRes),
393- contentDescription = stringResource(R .string.music_player_repeat_description),
394- tint = if (repeatMode == PlaybackRepeatMode .REPEAT_OFF ) White else DarkViolet ,
395- )
396- }
397- }
398-
399177val Palette .dominantColor: Color ?
400178 get() {
401179 val swatch = dominantSwatch ? : vibrantSwatch ? : lightVibrantSwatch ? : darkVibrantSwatch
0 commit comments