Reintroduce "loop none" option (#276)

This commit is contained in:
vfsfitvnm 2022-10-19 14:22:34 +02:00
parent 720c73d9fb
commit fc569ea5f9
4 changed files with 67 additions and 37 deletions

View file

@ -27,7 +27,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat.startForegroundService
import androidx.core.content.edit
import androidx.core.content.getSystemService
import androidx.core.net.toUri
import androidx.core.text.isDigitsOnly
@ -63,6 +62,10 @@ import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.extractor.ExtractorsFactory
import androidx.media3.extractor.mkv.MatroskaExtractor
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.NavigationEndpoint
import it.vfsfitvnm.innertube.models.bodies.PlayerBody
import it.vfsfitvnm.innertube.requests.player
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.MainActivity
import it.vfsfitvnm.vimusic.R
@ -88,15 +91,12 @@ import it.vfsfitvnm.vimusic.utils.isShowingThumbnailInLockscreenKey
import it.vfsfitvnm.vimusic.utils.mediaItems
import it.vfsfitvnm.vimusic.utils.persistentQueueKey
import it.vfsfitvnm.vimusic.utils.preferences
import it.vfsfitvnm.vimusic.utils.repeatModeKey
import it.vfsfitvnm.vimusic.utils.queueLoopEnabledKey
import it.vfsfitvnm.vimusic.utils.shouldBePlaying
import it.vfsfitvnm.vimusic.utils.skipSilenceKey
import it.vfsfitvnm.vimusic.utils.timer
import it.vfsfitvnm.vimusic.utils.trackLoopEnabledKey
import it.vfsfitvnm.vimusic.utils.volumeNormalizationKey
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.NavigationEndpoint
import it.vfsfitvnm.innertube.models.bodies.PlayerBody
import it.vfsfitvnm.innertube.requests.player
import kotlin.math.roundToInt
import kotlin.system.exitProcess
import kotlinx.coroutines.CoroutineScope
@ -219,10 +219,12 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
.setUsePlatformDiagnostics(false)
.build()
player.repeatMode = when (preferences.getInt(repeatModeKey, Player.REPEAT_MODE_ALL)) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ONE
else -> Player.REPEAT_MODE_ALL
player.repeatMode = when {
preferences.getBoolean(trackLoopEnabledKey, false) -> Player.REPEAT_MODE_ONE
preferences.getBoolean(queueLoopEnabledKey, true) -> Player.REPEAT_MODE_ALL
else -> Player.REPEAT_MODE_OFF
}
player.skipSilenceEnabled = preferences.getBoolean(skipSilenceKey, false)
player.addListener(this)
player.addAnalyticsListener(PlaybackStatsListener(false, this))
@ -456,10 +458,6 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
else -> PlaybackState.STATE_NONE
}
override fun onRepeatModeChanged(repeatMode: Int) {
preferences.edit { putInt(repeatModeKey, repeatMode) }
}
override fun onEvents(player: Player, events: Player.Events) {
if (player.duration != C.TIME_UNSET) {
metadataBuilder
@ -540,6 +538,13 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
isShowingThumbnailInLockscreen = sharedPreferences.getBoolean(key, true)
maybeShowSongCoverInLockScreen()
}
trackLoopEnabledKey, queueLoopEnabledKey -> {
player.repeatMode = when {
preferences.getBoolean(trackLoopEnabledKey, false) -> Player.REPEAT_MODE_ONE
preferences.getBoolean(queueLoopEnabledKey, true) -> Player.REPEAT_MODE_ALL
else -> Player.REPEAT_MODE_OFF
}
}
}
}

View file

@ -44,13 +44,14 @@ import it.vfsfitvnm.vimusic.ui.components.SeekBar
import it.vfsfitvnm.vimusic.ui.components.themed.IconButton
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.favoritesIcon
import it.vfsfitvnm.vimusic.utils.DisposableListener
import it.vfsfitvnm.vimusic.utils.bold
import it.vfsfitvnm.vimusic.utils.forceSeekToNext
import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
import it.vfsfitvnm.vimusic.utils.formatAsDuration
import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.trackLoopEnabledKey
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
@ -70,17 +71,7 @@ fun Controls(
val binder = LocalPlayerServiceBinder.current
binder?.player ?: return
var repeatMode by remember {
mutableStateOf(binder.player.repeatMode)
}
binder.player.DisposableListener {
object : Player.Listener {
override fun onRepeatModeChanged(newRepeatMode: Int) {
repeatMode = newRepeatMode
}
}
}
var trackLoopEnabled by rememberPreference(trackLoopEnabledKey, defaultValue = false)
var scrubbingPosition by remember(mediaId) {
mutableStateOf<Long?>(null)
@ -277,17 +268,8 @@ fun Controls(
IconButton(
icon = R.drawable.infinite,
color = if (repeatMode == Player.REPEAT_MODE_ONE) {
colorPalette.text
} else {
colorPalette.textDisabled
},
onClick = {
binder.player.repeatMode = when (binder.player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
else -> Player.REPEAT_MODE_ONE
}
},
color = if (trackLoopEnabled) colorPalette.text else colorPalette.textDisabled,
onClick = { trackLoopEnabled = !trackLoopEnabled },
modifier = Modifier
.weight(1f)
.size(24.dp)

View file

@ -1,7 +1,11 @@
package it.vfsfitvnm.vimusic.ui.screens.player
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.fadeIn
@ -14,6 +18,7 @@ import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
@ -37,6 +42,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
@ -69,6 +75,8 @@ import it.vfsfitvnm.vimusic.ui.styling.onOverlay
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.utils.DisposableListener
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.queueLoopEnabledKey
import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.shouldBePlaying
import it.vfsfitvnm.vimusic.utils.shuffleQueue
import it.vfsfitvnm.vimusic.utils.smoothScrollToTop
@ -120,6 +128,8 @@ fun Queue(
val player = binder.player
var queueLoopEnabled by rememberPreference(queueLoopEnabledKey, defaultValue = true)
val menuState = LocalMenuState.current
val thumbnailSizeDp = Dimensions.thumbnails.song
@ -340,6 +350,38 @@ fun Queue(
.align(Alignment.Center)
.size(18.dp)
)
Row(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.clickable { queueLoopEnabled = !queueLoopEnabled }
.background(colorPalette.background1)
.padding(horizontal = 16.dp, vertical = 8.dp)
.align(Alignment.CenterEnd)
.animateContentSize()
) {
BasicText(
text = "Queue loop ",
style = typography.xxs.medium,
)
AnimatedContent(
targetState = queueLoopEnabled,
transitionSpec = {
val slideDirection = if (targetState) AnimatedContentScope.SlideDirection.Up else AnimatedContentScope.SlideDirection.Down
ContentTransform(
targetContentEnter = slideIntoContainer(slideDirection) + fadeIn(),
initialContentExit = slideOutOfContainer(slideDirection) + fadeOut(),
)
}
) {
BasicText(
text = if (it) "on" else "off",
style = typography.xxs.medium,
)
}
}
}
}
}

View file

@ -25,7 +25,8 @@ const val albumSortOrderKey = "albumSortOrder"
const val albumSortByKey = "albumSortBy"
const val artistSortOrderKey = "artistSortOrder"
const val artistSortByKey = "artistSortBy"
const val repeatModeKey = "repeatMode"
const val trackLoopEnabledKey = "trackLoopEnabled"
const val queueLoopEnabledKey = "queueLoopEnabled"
const val skipSilenceKey = "skipSilence"
const val volumeNormalizationKey = "volumeNormalization"
const val persistentQueueKey = "persistentQueue"