Tweak code
This commit is contained in:
@@ -9,22 +9,26 @@ import android.os.Build
|
||||
import android.os.PowerManager
|
||||
import androidx.core.content.getSystemService
|
||||
|
||||
|
||||
inline fun <reified T> Context.intent(): Intent =
|
||||
Intent(this@Context, T::class.java)
|
||||
|
||||
inline fun <reified T: BroadcastReceiver> Context.broadCastPendingIntent(
|
||||
inline fun <reified T : BroadcastReceiver> Context.broadCastPendingIntent(
|
||||
requestCode: Int = 0,
|
||||
flags: Int = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0,
|
||||
): PendingIntent =
|
||||
PendingIntent.getBroadcast(this, requestCode, intent<T>(), flags)
|
||||
|
||||
inline fun <reified T: Activity> Context.activityPendingIntent(
|
||||
inline fun <reified T : Activity> Context.activityPendingIntent(
|
||||
requestCode: Int = 0,
|
||||
flags: Int = 0,
|
||||
block: Intent.() -> Unit = {},
|
||||
): PendingIntent =
|
||||
PendingIntent.getActivity(this, requestCode, intent<T>().apply(block), (if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0) or flags)
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
requestCode,
|
||||
intent<T>().apply(block),
|
||||
(if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0) or flags
|
||||
)
|
||||
|
||||
val Context.isIgnoringBatteryOptimizations: Boolean
|
||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
||||
@@ -24,6 +24,11 @@ fun DrawScope.drawCircle(
|
||||
it.colorFilter = colorFilter
|
||||
it.style = style
|
||||
}.asFrameworkPaint().also {
|
||||
it.setShadowLayer(shadow.blurRadius, shadow.offset.x, shadow.offset.y, shadow.color.toArgb())
|
||||
it.setShadowLayer(
|
||||
shadow.blurRadius,
|
||||
shadow.offset.x,
|
||||
shadow.offset.y,
|
||||
shadow.color.toArgb()
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
||||
|
||||
// https://stackoverflow.com/q/53502244/16885569
|
||||
// I found four ways to make the system not kill the stopped foreground service: e.g. when
|
||||
// the player is paused:
|
||||
|
||||
@@ -4,15 +4,14 @@ import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.Timeline
|
||||
|
||||
|
||||
val Timeline.mediaItems: List<MediaItem>
|
||||
get() = (0 until windowCount).map { index ->
|
||||
getWindow(index, Timeline.Window()).mediaItem
|
||||
get() = List(windowCount) {
|
||||
getWindow(it, Timeline.Window()).mediaItem
|
||||
}
|
||||
|
||||
val Timeline.windows: List<Timeline.Window>
|
||||
get() = (0 until windowCount).map { index ->
|
||||
getWindow(index, Timeline.Window())
|
||||
inline val Timeline.windows: List<Timeline.Window>
|
||||
get() = List(windowCount) {
|
||||
getWindow(it, Timeline.Window())
|
||||
}
|
||||
|
||||
val Player.shouldBePlaying: Boolean
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
package it.vfsfitvnm.vimusic.utils
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.DisposableEffectResult
|
||||
import androidx.compose.runtime.DisposableEffectScope
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
@@ -9,7 +16,6 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
context(DisposableEffectScope)
|
||||
fun Player.listener(listener: Player.Listener): DisposableEffectResult {
|
||||
addListener(listener)
|
||||
@@ -27,11 +33,13 @@ fun rememberMediaItemIndex(player: Player): State<Int> {
|
||||
DisposableEffect(player) {
|
||||
player.listener(object : Player.Listener {
|
||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||
mediaItemIndexState.value = if (player.mediaItemCount == 0) -1 else player.currentMediaItemIndex
|
||||
mediaItemIndexState.value =
|
||||
if (player.mediaItemCount == 0) -1 else player.currentMediaItemIndex
|
||||
}
|
||||
|
||||
override fun onTimelineChanged(timeline: Timeline, reason: Int) {
|
||||
mediaItemIndexState.value = if (player.mediaItemCount == 0) -1 else player.currentMediaItemIndex
|
||||
mediaItemIndexState.value =
|
||||
if (player.mediaItemCount == 0) -1 else player.currentMediaItemIndex
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -187,6 +195,7 @@ fun rememberError(player: Player): State<PlaybackException?> {
|
||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||
errorState.value = player.playerError
|
||||
}
|
||||
|
||||
override fun onPlayerError(playbackException: PlaybackException) {
|
||||
errorState.value = playbackException
|
||||
}
|
||||
@@ -194,4 +203,4 @@ fun rememberError(player: Player): State<PlaybackException?> {
|
||||
}
|
||||
|
||||
return errorState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ package it.vfsfitvnm.vimusic.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.SnapshotMutationPolicy
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.content.edit
|
||||
|
||||
|
||||
const val colorPaletteModeKey = "colorPaletteMode"
|
||||
const val thumbnailRoundnessKey = "thumbnailRoundness"
|
||||
const val coilDiskCacheMaxSizeKey = "coilDiskCacheMaxSize"
|
||||
@@ -36,14 +39,15 @@ inline fun <reified T : Enum<T>> SharedPreferences.getEnum(
|
||||
}
|
||||
} ?: defaultValue
|
||||
|
||||
inline fun <reified T : Enum<T>> SharedPreferences.Editor.putEnum(key: String, value: T) =
|
||||
inline fun <reified T : Enum<T>> SharedPreferences.Editor.putEnum(
|
||||
key: String,
|
||||
value: T
|
||||
): SharedPreferences.Editor =
|
||||
putString(key, value.name)
|
||||
|
||||
|
||||
val Context.preferences: SharedPreferences
|
||||
get() = getSharedPreferences("preferences", Context.MODE_PRIVATE)
|
||||
|
||||
|
||||
@Composable
|
||||
fun rememberPreference(key: String, defaultValue: Boolean): MutableState<Boolean> {
|
||||
val context = LocalContext.current
|
||||
@@ -65,7 +69,7 @@ fun rememberPreference(key: String, defaultValue: String): MutableState<String>
|
||||
}
|
||||
|
||||
@Composable
|
||||
inline fun <reified T: Enum<T>> rememberPreference(key: String, defaultValue: T): MutableState<T> {
|
||||
inline fun <reified T : Enum<T>> rememberPreference(key: String, defaultValue: T): MutableState<T> {
|
||||
val context = LocalContext.current
|
||||
return remember {
|
||||
mutableStatePreferenceOf(context.preferences.getEnum(key, defaultValue)) {
|
||||
@@ -74,7 +78,10 @@ inline fun <reified T: Enum<T>> rememberPreference(key: String, defaultValue: T)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> mutableStatePreferenceOf(value: T, crossinline onStructuralInequality: (newValue: T) -> Unit) =
|
||||
inline fun <T> mutableStatePreferenceOf(
|
||||
value: T,
|
||||
crossinline onStructuralInequality: (newValue: T) -> Unit
|
||||
) =
|
||||
mutableStateOf(
|
||||
value = value,
|
||||
policy = object : SnapshotMutationPolicy<T> {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@file:OptIn(InternalComposeApi::class)
|
||||
|
||||
package it.vfsfitvnm.vimusic.utils
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.InternalComposeApi
|
||||
import androidx.compose.runtime.LaunchedEffectImpl
|
||||
import androidx.compose.runtime.NonRestartableComposable
|
||||
import androidx.compose.runtime.currentComposer
|
||||
import androidx.compose.runtime.remember
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
interface TimerJob {
|
||||
val millisLeft: StateFlow<Long?>
|
||||
fun cancel()
|
||||
@@ -16,14 +15,12 @@ interface TimerJob {
|
||||
|
||||
fun CoroutineScope.timer(delayMillis: Long, onCompletion: () -> Unit): TimerJob {
|
||||
val millisLeft = MutableStateFlow<Long?>(delayMillis)
|
||||
|
||||
val job = launch {
|
||||
while (isActive && millisLeft.value != null) {
|
||||
delay(1000)
|
||||
millisLeft.emit(millisLeft.value?.minus(1000)?.takeIf { it > 0 })
|
||||
}
|
||||
}
|
||||
|
||||
val disposableHandle = job.invokeOnCompletion {
|
||||
if (it == null) {
|
||||
onCompletion()
|
||||
|
||||
@@ -5,7 +5,6 @@ import it.vfsfitvnm.youtubemusic.YouTube
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
data class YouTubeRadio(
|
||||
private val videoId: String? = null,
|
||||
private val playlistId: String? = null,
|
||||
|
||||
@@ -21,4 +21,4 @@ fun rememberHapticFeedback(): HapticFeedback {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user