mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Preferences update, play theme song volume
This commit is contained in:
parent
3a255fcd8a
commit
628771211d
8 changed files with 206 additions and 37 deletions
|
|
@ -176,15 +176,16 @@ sealed interface AppPreference<T> {
|
||||||
)
|
)
|
||||||
|
|
||||||
val PlayThemeMusic =
|
val PlayThemeMusic =
|
||||||
AppSwitchPreference(
|
AppChoicePreference<ThemeSongVolume>(
|
||||||
title = R.string.play_theme_music,
|
title = R.string.play_theme_music,
|
||||||
defaultValue = true,
|
defaultValue = ThemeSongVolume.MEDIUM,
|
||||||
getter = { it.interfacePreferences.playThemeSongs },
|
getter = { it.interfacePreferences.playThemeSongs },
|
||||||
setter = { prefs, value ->
|
setter = { prefs, value ->
|
||||||
prefs.updateInterfacePreferences { playThemeSongs = value }
|
prefs.updateInterfacePreferences { playThemeSongs = value }
|
||||||
},
|
},
|
||||||
summaryOn = R.string.enabled,
|
displayValues = R.array.theme_song_volume,
|
||||||
summaryOff = R.string.disabled,
|
indexToValue = { ThemeSongVolume.forNumber(it) },
|
||||||
|
valueToIndex = { it.number },
|
||||||
)
|
)
|
||||||
|
|
||||||
val PlaybackDebugInfo =
|
val PlaybackDebugInfo =
|
||||||
|
|
@ -199,6 +200,12 @@ sealed interface AppPreference<T> {
|
||||||
summaryOff = R.string.hide,
|
summaryOff = R.string.hide,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val InstalledVersion =
|
||||||
|
AppClickablePreference(
|
||||||
|
title = R.string.installed_version,
|
||||||
|
getter = { },
|
||||||
|
setter = { prefs, _ -> prefs },
|
||||||
|
)
|
||||||
// val AutoCheckForUpdates =
|
// val AutoCheckForUpdates =
|
||||||
// AppSwitchPreference(
|
// AppSwitchPreference(
|
||||||
// title = R.string.check_for_updates,
|
// title = R.string.check_for_updates,
|
||||||
|
|
@ -237,17 +244,29 @@ val basicPreferences =
|
||||||
title = R.string.basic_interface,
|
title = R.string.basic_interface,
|
||||||
preferences =
|
preferences =
|
||||||
listOf(
|
listOf(
|
||||||
AppPreference.SkipForward,
|
|
||||||
AppPreference.SkipBack,
|
|
||||||
AppPreference.ControllerTimeout,
|
|
||||||
AppPreference.SeekBarSteps,
|
|
||||||
AppPreference.HomePageItems,
|
AppPreference.HomePageItems,
|
||||||
AppPreference.RewatchNextUp,
|
AppPreference.RewatchNextUp,
|
||||||
AppPreference.PlayThemeMusic,
|
AppPreference.PlayThemeMusic,
|
||||||
AppPreference.OssLicenseInfo,
|
),
|
||||||
|
),
|
||||||
|
PreferenceGroup(
|
||||||
|
title = R.string.playback,
|
||||||
|
preferences =
|
||||||
|
listOf(
|
||||||
|
AppPreference.SkipForward,
|
||||||
|
AppPreference.SkipBack,
|
||||||
|
AppPreference.ControllerTimeout,
|
||||||
AppPreference.PlaybackDebugInfo,
|
AppPreference.PlaybackDebugInfo,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
PreferenceGroup(
|
||||||
|
title = R.string.about,
|
||||||
|
preferences =
|
||||||
|
listOf(
|
||||||
|
AppPreference.InstalledVersion,
|
||||||
|
AppPreference.OssLicenseInfo,
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
val uiPreferences = listOf<PreferenceGroup>()
|
val uiPreferences = listOf<PreferenceGroup>()
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ fun SeriesDetails(
|
||||||
viewModel: SeriesViewModel = hiltViewModel(),
|
viewModel: SeriesViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.init(destination.itemId, destination.item, null, null)
|
viewModel.init(preferences, destination.itemId, destination.item, null, null)
|
||||||
}
|
}
|
||||||
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
|
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import com.github.damontecres.dolphin.data.model.BaseItem
|
||||||
import com.github.damontecres.dolphin.data.model.Person
|
import com.github.damontecres.dolphin.data.model.Person
|
||||||
import com.github.damontecres.dolphin.data.model.Video
|
import com.github.damontecres.dolphin.data.model.Video
|
||||||
import com.github.damontecres.dolphin.hilt.AuthOkHttpClient
|
import com.github.damontecres.dolphin.hilt.AuthOkHttpClient
|
||||||
|
import com.github.damontecres.dolphin.preferences.ThemeSongVolume
|
||||||
|
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.dolphin.ui.letNotEmpty
|
import com.github.damontecres.dolphin.ui.letNotEmpty
|
||||||
import com.github.damontecres.dolphin.util.ApiRequestPager
|
import com.github.damontecres.dolphin.util.ApiRequestPager
|
||||||
import com.github.damontecres.dolphin.util.ExceptionHandler
|
import com.github.damontecres.dolphin.util.ExceptionHandler
|
||||||
|
|
@ -59,6 +61,7 @@ class SeriesViewModel
|
||||||
val people = MutableLiveData<List<Person>>(listOf())
|
val people = MutableLiveData<List<Person>>(listOf())
|
||||||
|
|
||||||
fun init(
|
fun init(
|
||||||
|
prefs: UserPreferences,
|
||||||
itemId: UUID,
|
itemId: UUID,
|
||||||
potential: BaseItem?,
|
potential: BaseItem?,
|
||||||
season: Int?,
|
season: Int?,
|
||||||
|
|
@ -89,7 +92,7 @@ class SeriesViewModel
|
||||||
people.map { Person.fromDto(it, api) }
|
people.map { Person.fromDto(it, api) }
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
}
|
}
|
||||||
maybePlayThemeSong()
|
maybePlayThemeSong(prefs.appPreferences.interfacePreferences.playThemeSongs)
|
||||||
} else {
|
} else {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
seasons.value = ItemListAndMapping.empty()
|
seasons.value = ItemListAndMapping.empty()
|
||||||
|
|
@ -101,8 +104,19 @@ class SeriesViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
private fun maybePlayThemeSong() {
|
private fun maybePlayThemeSong(playThemeSongs: ThemeSongVolume) {
|
||||||
// TODO user preference to enable/disable this
|
val volume =
|
||||||
|
when (playThemeSongs) {
|
||||||
|
ThemeSongVolume.UNRECOGNIZED,
|
||||||
|
ThemeSongVolume.DISABLED,
|
||||||
|
-> return
|
||||||
|
|
||||||
|
ThemeSongVolume.LOWEST -> .1f
|
||||||
|
ThemeSongVolume.LOW -> .25f
|
||||||
|
ThemeSongVolume.MEDIUM -> .5f
|
||||||
|
ThemeSongVolume.HIGH -> .75f
|
||||||
|
ThemeSongVolume.HIGHEST -> 1f
|
||||||
|
}
|
||||||
viewModelScope.launch(ExceptionHandler()) {
|
viewModelScope.launch(ExceptionHandler()) {
|
||||||
val themeSongs = api.libraryApi.getThemeSongs(seriesId).content
|
val themeSongs = api.libraryApi.getThemeSongs(seriesId).content
|
||||||
themeSongs.items.firstOrNull()?.let { theme ->
|
themeSongs.items.firstOrNull()?.let { theme ->
|
||||||
|
|
@ -123,7 +137,7 @@ class SeriesViewModel
|
||||||
),
|
),
|
||||||
).build()
|
).build()
|
||||||
.apply {
|
.apply {
|
||||||
volume = .1f
|
this.volume = volume
|
||||||
playWhenReady = true
|
playWhenReady = true
|
||||||
this@SeriesViewModel.player = this
|
this@SeriesViewModel.player = this
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ fun SeriesOverview(
|
||||||
OneTimeLaunchedEffect {
|
OneTimeLaunchedEffect {
|
||||||
Timber.v("SeriesDetailParent: itemId=${destination.itemId}, initialSeasonEpisode=$initialSeasonEpisode")
|
Timber.v("SeriesDetailParent: itemId=${destination.itemId}, initialSeasonEpisode=$initialSeasonEpisode")
|
||||||
viewModel.init(
|
viewModel.init(
|
||||||
|
preferences,
|
||||||
destination.itemId,
|
destination.itemId,
|
||||||
destination.item,
|
destination.item,
|
||||||
initialSeasonEpisode?.season,
|
initialSeasonEpisode?.season,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
|
@ -76,7 +77,8 @@ fun PreferencesContent(
|
||||||
}
|
}
|
||||||
|
|
||||||
val movementSounds = true
|
val movementSounds = true
|
||||||
val installedVersion = remember { "v1.0.0" }
|
val installedVersion =
|
||||||
|
remember { context.packageManager.getPackageInfo(context.packageName, 0).versionName }
|
||||||
var updateVersion by remember { mutableStateOf<Release?>(null) }
|
var updateVersion by remember { mutableStateOf<Release?>(null) }
|
||||||
val updateAvailable = false
|
val updateAvailable = false
|
||||||
// remember(updateVersion) { updateVersion?.version?.isGreaterThan(installedVersion) == true }
|
// remember(updateVersion) { updateVersion?.version?.isGreaterThan(installedVersion) == true }
|
||||||
|
|
@ -188,27 +190,27 @@ fun PreferencesContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (pref) {
|
when (pref) {
|
||||||
// AppPreference.InstalledVersion -> {
|
AppPreference.InstalledVersion -> {
|
||||||
// var clickCount by remember { mutableIntStateOf(0) }
|
var clickCount by remember { mutableIntStateOf(0) }
|
||||||
// ClickPreference(
|
ClickPreference(
|
||||||
// title = stringResource(R.string.installed_version),
|
title = stringResource(R.string.installed_version),
|
||||||
// onClick = {
|
onClick = {
|
||||||
// if (movementSounds) playOnClickSound(context)
|
if (movementSounds) playOnClickSound(context)
|
||||||
// if (clickCount++ >= 2) {
|
if (clickCount++ >= 2) {
|
||||||
// clickCount = 0
|
clickCount = 0
|
||||||
// // navigationManager.navigateTo(Destination.Debug)
|
// navigationManager.navigateTo(Destination.Debug)
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// summary = installedVersion.toString(),
|
summary = installedVersion.toString(),
|
||||||
// interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
// modifier =
|
modifier =
|
||||||
// Modifier
|
Modifier
|
||||||
// .ifElse(
|
.ifElse(
|
||||||
// groupIndex == focusedIndex.first && prefIndex == focusedIndex.second,
|
groupIndex == focusedIndex.first && prefIndex == focusedIndex.second,
|
||||||
// Modifier.focusRequester(focusRequester),
|
Modifier.focusRequester(focusRequester),
|
||||||
// ),
|
),
|
||||||
// )
|
)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// AppPreference.Update -> {
|
// AppPreference.Update -> {
|
||||||
// ClickPreference(
|
// ClickPreference(
|
||||||
|
|
|
||||||
112
app/src/main/java/com/github/damontecres/dolphin/util/Version.kt
Normal file
112
app/src/main/java/com/github/damontecres/dolphin/util/Version.kt
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com.github.damontecres.dolphin.util
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Version(
|
||||||
|
val major: Int,
|
||||||
|
val minor: Int,
|
||||||
|
val patch: Int,
|
||||||
|
val numCommits: Int? = null,
|
||||||
|
val hash: String? = null,
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Is this version at least the given version
|
||||||
|
*/
|
||||||
|
fun isAtLeast(version: Version): Boolean {
|
||||||
|
if (this.major > version.major) {
|
||||||
|
return true
|
||||||
|
} else if (this.major == version.major) {
|
||||||
|
if (this.minor > version.minor) {
|
||||||
|
return true
|
||||||
|
} else if (this.minor == version.minor) {
|
||||||
|
if (this.patch > version.patch) {
|
||||||
|
return true
|
||||||
|
} else if (this.patch == version.patch) {
|
||||||
|
if (this.compareNumCommits(version) >= 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this greater than the given version (and not equal to!)
|
||||||
|
*/
|
||||||
|
fun isGreaterThan(version: Version): Boolean {
|
||||||
|
if (this.major > version.major) {
|
||||||
|
return true
|
||||||
|
} else if (this.major == version.major) {
|
||||||
|
if (this.minor > version.minor) {
|
||||||
|
return true
|
||||||
|
} else if (this.minor == version.minor) {
|
||||||
|
if (this.patch > version.patch) {
|
||||||
|
return true
|
||||||
|
} else if (this.patch == version.patch) {
|
||||||
|
if (this.compareNumCommits(version) > 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this less than the given version (and not equal to!)
|
||||||
|
*/
|
||||||
|
fun isLessThan(version: Version): Boolean = this != version && isEqualOrBefore(version)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this equal to or before the specified version
|
||||||
|
*/
|
||||||
|
fun isEqualOrBefore(version: Version): Boolean = !isGreaterThan(version)
|
||||||
|
|
||||||
|
private fun compareNumCommits(version: Version): Int = (this.numCommits ?: 0) - (version.numCommits ?: 0)
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
if (numCommits != null && hash != null) {
|
||||||
|
"v$major.$minor.$patch-$numCommits-g$hash"
|
||||||
|
} else {
|
||||||
|
"v$major.$minor.$patch"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val VERSION_REGEX = Regex("v?(\\d+)\\.(\\d+)\\.(\\d+)(-(\\d+)-g([a-zA-Z0-9]+))?")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a version string throwing if it is invalid
|
||||||
|
*/
|
||||||
|
fun fromString(version: String): Version {
|
||||||
|
val v = tryFromString(version)
|
||||||
|
if (v == null) {
|
||||||
|
throw IllegalArgumentException(version)
|
||||||
|
} else {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to parse a version string or else return null
|
||||||
|
*/
|
||||||
|
fun tryFromString(version: String?): Version? {
|
||||||
|
if (version == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val m = VERSION_REGEX.matchEntire(version)
|
||||||
|
return if (m == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
val major = m.groups[1]!!.value.toInt()
|
||||||
|
val minor = m.groups[2]!!.value.toInt()
|
||||||
|
val patch = m.groups[3]!!.value.toInt()
|
||||||
|
// group 4 is the optional commit info
|
||||||
|
val numCommits = m.groups[5]?.value?.toInt()
|
||||||
|
val hash = m.groups[6]?.value
|
||||||
|
Version(major, minor, patch, numCommits, hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,17 @@ message HomePagePreferences{
|
||||||
bool enable_rewatching_next_up = 2;
|
bool enable_rewatching_next_up = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ThemeSongVolume {
|
||||||
|
DISABLED = 0;
|
||||||
|
LOWEST = 1;
|
||||||
|
LOW = 2;
|
||||||
|
MEDIUM = 3;
|
||||||
|
HIGH = 4;
|
||||||
|
HIGHEST = 5;
|
||||||
|
}
|
||||||
|
|
||||||
message InterfacePreferences {
|
message InterfacePreferences {
|
||||||
bool play_theme_songs = 1;
|
ThemeSongVolume play_theme_songs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AppPreferences {
|
message AppPreferences {
|
||||||
|
|
|
||||||
12
app/src/main/res/values/preferences.xml
Normal file
12
app/src/main/res/values/preferences.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string-array name="theme_song_volume">
|
||||||
|
<item>Disabled</item>
|
||||||
|
<item>Lowest</item>
|
||||||
|
<item>Low</item>
|
||||||
|
<item>Medium</item>
|
||||||
|
<item>High</item>
|
||||||
|
<item>Full</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
</resources>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue