Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions composeApp/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
<string name="playback">Playback</string>
<string name="save_playback_state">Save Playback State</string>
<string name="save_shuffle_and_repeat_mode">Save shuffle and repeat mode</string>
<string name="double_press_to_seek">Double press on image to ±5sec</string>
<string name="double_press_to_seek_description">Double tap on left/right of the image to seek back/forward 5 seconds</string>
<string name="skip_silent">Skip Silent</string>
<string name="skip_no_music_part">Skip no music part</string>
<string name="time_out_check_internet_connection_or_change_piped_instance_in_settings">Time out, check internet connection (%1$s)</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Forward5
import androidx.compose.material.icons.rounded.PauseCircle
import androidx.compose.material.icons.rounded.PlayCircle
import androidx.compose.material.icons.rounded.Repeat
import androidx.compose.material.icons.rounded.RepeatOne
import androidx.compose.material.icons.rounded.Replay5
import androidx.compose.material.icons.rounded.Shuffle
import androidx.compose.material.icons.rounded.SkipNext
import androidx.compose.material.icons.rounded.SkipPrevious
Expand Down Expand Up @@ -111,6 +113,29 @@ fun PlayerControlLayout(
)
}
}
Box(Modifier.weight(1f), contentAlignment = Alignment.Center) {
Box(
modifier =
Modifier
.background(transparent)
.size(smallIcon.second)
.aspectRatio(1f)
.clip(
CircleShape,
)
.clickable {
onUIEvent(UIEvent.Backward5)
},
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.Rounded.Replay5,
tint = Color.White,
contentDescription = "",
modifier = Modifier.size(smallIcon.first),
)
}
}
Box(Modifier.weight(1f), contentAlignment = Alignment.Center) {
Box(
modifier =
Expand Down Expand Up @@ -145,6 +170,29 @@ fun PlayerControlLayout(
}
}
}
Box(Modifier.weight(1f), contentAlignment = Alignment.Center) {
Box(
modifier =
Modifier
.background(transparent)
.size(mediumIcon.second)
.aspectRatio(1f)
.clip(
CircleShape,
)
.clickable {
onUIEvent(UIEvent.Forward5)
},
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.Rounded.Forward5,
tint = Color.White,
contentDescription = "",
modifier = Modifier.size(mediumIcon.first),
)
}
}
Box(Modifier.weight(1f), contentAlignment = Alignment.Center) {
Box(
modifier =
Expand Down Expand Up @@ -217,4 +265,4 @@ fun PlayerControlLayout(
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ import simpmusic.composeapp.generated.resources.save_all_your_playlist_data
import simpmusic.composeapp.generated.resources.save_last_played
import simpmusic.composeapp.generated.resources.save_last_played_track_and_queue
import simpmusic.composeapp.generated.resources.save_playback_state
import simpmusic.composeapp.generated.resources.double_press_to_seek
import simpmusic.composeapp.generated.resources.double_press_to_seek_description
import simpmusic.composeapp.generated.resources.save_shuffle_and_repeat_mode
import simpmusic.composeapp.generated.resources.send_back_listening_data_to_google
import simpmusic.composeapp.generated.resources.set
Expand Down Expand Up @@ -413,6 +415,7 @@ fun SettingScreen(
val normalizeVolume by viewModel.normalizeVolume.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
val skipSilent by viewModel.skipSilent.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
val savePlaybackState by viewModel.savedPlaybackState.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
val doublePressToSeek by viewModel.doublePressToSeek.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
val saveLastPlayed by viewModel.saveRecentSongAndQueue.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
val killServiceOnExit by viewModel.killServiceOnExit.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = true)
val mainLyricsProvider by viewModel.mainLyricsProvider.collectAsStateWithLifecycle()
Expand Down Expand Up @@ -970,6 +973,11 @@ fun SettingScreen(
subtitle = stringResource(Res.string.save_shuffle_and_repeat_mode),
switch = (savePlaybackState to { viewModel.setSavedPlaybackState(it) }),
)
SettingItem(
title = stringResource(Res.string.double_press_to_seek),
subtitle = stringResource(Res.string.double_press_to_seek_description),
switch = (doublePressToSeek to { viewModel.setDoublePressToSeek(it) }),
)
SettingItem(
title = stringResource(Res.string.save_last_played),
subtitle = stringResource(Res.string.save_last_played_track_and_queue),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Forward5
import androidx.compose.material.icons.filled.FullscreenExit
import androidx.compose.material.icons.filled.KeyboardDoubleArrowLeft
import androidx.compose.material.icons.filled.KeyboardDoubleArrowRight
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Replay5
Expand Down Expand Up @@ -91,7 +89,6 @@ import org.koin.compose.koinInject
import simpmusic.composeapp.generated.resources.Res
import simpmusic.composeapp.generated.resources.baseline_arrow_back_ios_new_24
import simpmusic.composeapp.generated.resources.baseline_more_vert_24
import simpmusic.composeapp.generated.resources.five_seconds
import kotlin.math.roundToLong

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -121,6 +118,7 @@ fun FullscreenPlayer(
val nowPlayingState by sharedViewModel.nowPlayingScreenData.collectAsStateWithLifecycle()
val controllerState by sharedViewModel.controllerState.collectAsStateWithLifecycle()
val timelineState by sharedViewModel.timeline.collectAsStateWithLifecycle()
val doublePressToSeek by sharedViewModel.doublePressToSeek.collectAsStateWithLifecycle()

var showBottom by rememberSaveable { mutableStateOf(false) }
var isSliding by rememberSaveable {
Expand Down Expand Up @@ -154,10 +152,8 @@ fun FullscreenPlayer(
// For double tap effect
val coroutineScope = rememberCoroutineScope()

var doubleBackwardTapped by remember { mutableStateOf(false) }
val interactionSourceBackward = remember { MutableInteractionSource() }

var doubleForwardTapped by remember { mutableStateOf(false) }
val interactionSourceForward = remember { MutableInteractionSource() }

var showBackwardText by remember { mutableStateOf(false) }
Expand Down Expand Up @@ -216,14 +212,14 @@ fun FullscreenPlayer(
showHideFullscreenOverlay = !showHideFullscreenOverlay
},
onDoubleTap = { offset ->
coroutineScope.launch {
doubleBackwardTapped = true
val press = PressInteraction.Press(offset)
interactionSourceBackward.emit(press)
sharedViewModel.onUIEvent(UIEvent.Backward)
showBackwardText = true
interactionSourceBackward.emit(PressInteraction.Release(press))
doubleBackwardTapped = false
if (doublePressToSeek) {
coroutineScope.launch {
val press = PressInteraction.Press(offset)
interactionSourceBackward.emit(press)
sharedViewModel.onUIEvent(UIEvent.Backward5)
showBackwardText = true
interactionSourceBackward.emit(PressInteraction.Release(press))
}
}
},
)
Expand All @@ -234,17 +230,16 @@ fun FullscreenPlayer(
if (it) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.background(Color.Black.copy(alpha = 0.5f), RoundedCornerShape(16.dp))
.padding(horizontal = 14.dp, vertical = 8.dp),
) {
Icon(
Icons.Filled.KeyboardDoubleArrowLeft,
Icons.Filled.Replay5,
"",
tint = Color.White,
)
Spacer(Modifier.width(4.dp))
Text(
stringResource(Res.string.five_seconds),
color = Color.White,
style = typo().bodyMedium,
modifier = Modifier.size(36.dp),
)
}
}
Expand All @@ -268,14 +263,14 @@ fun FullscreenPlayer(
showHideFullscreenOverlay = !showHideFullscreenOverlay
},
onDoubleTap = { offset ->
coroutineScope.launch {
doubleForwardTapped = true
val press = PressInteraction.Press(offset)
interactionSourceForward.emit(press)
sharedViewModel.onUIEvent(UIEvent.Forward)
showForwardText = true
interactionSourceForward.emit(PressInteraction.Release(press))
doubleForwardTapped = false
if (doublePressToSeek) {
coroutineScope.launch {
val press = PressInteraction.Press(offset)
interactionSourceForward.emit(press)
sharedViewModel.onUIEvent(UIEvent.Forward5)
showForwardText = true
interactionSourceForward.emit(PressInteraction.Release(press))
}
}
},
)
Expand All @@ -286,17 +281,16 @@ fun FullscreenPlayer(
if (it) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.background(Color.Black.copy(alpha = 0.5f), RoundedCornerShape(16.dp))
.padding(horizontal = 14.dp, vertical = 8.dp),
) {
Text(
stringResource(Res.string.five_seconds),
color = Color.White,
style = typo().bodyMedium,
)
Spacer(Modifier.width(4.dp))
Icon(
Icons.Filled.KeyboardDoubleArrowRight,
Icons.Filled.Forward5,
"",
tint = Color.White,
modifier = Modifier.size(36.dp),
)
}
}
Expand Down Expand Up @@ -765,4 +759,4 @@ fun FullscreenPlayer(
expect fun FullScreenRotationImmersive(
onLaunch: () -> Unit = {},
onDispose: () -> Unit = {},
)
)
Loading