Several small fixes (#1455)

## Description
- Fix crash on license info page for release builds (#1437)
- Fix configuring which ratings to show by default (#1407)
- When re-ordering nav drawer items, ensure the one that was just moved
is always visible (#886 )
- Fix app losing focus when switching between list layout types (#1428)
- If the version doesn't have any additional commits, don't show the git
hash info (ie `v0.6.4-0-gabc1234` shows as `v0.6.4`)
- Adds tests for Version comparisons & toString

### Related issues
See above

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-05-25 13:27:04 -04:00 committed by GitHub
parent cb853b2db8
commit ebcc2f324a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 128 additions and 6 deletions

View file

@ -99,6 +99,8 @@ class AppPreferencesSerializer
showClock = AppPreference.ShowClock.defaultValue showClock = AppPreference.ShowClock.defaultValue
backdropStyle = AppPreference.BackdropStylePref.defaultValue backdropStyle = AppPreference.BackdropStylePref.defaultValue
showLogos = AppPreference.ShowLogos.defaultValue showLogos = AppPreference.ShowLogos.defaultValue
clearDisplayToggles()
addAllDisplayToggles(AppPreference.DisplayTogglesPref.defaultValue)
searchPreferences = searchPreferences =
SearchPreferences SearchPreferences

View file

@ -341,5 +341,14 @@ class AppUpgradeHandler
it.updateSearchPreferences { showVoiceSearchButton = true } it.updateSearchPreferences { showVoiceSearchButton = true }
} }
} }
if (previous.isEqualOrBefore(Version.fromString("0.6.4-26-g0"))) {
appPreferences.updateData {
it.updateInterfacePreferences {
clearDisplayToggles()
addAllDisplayToggles(AppPreference.DisplayTogglesPref.defaultValue)
}
}
}
} }
} }

View file

@ -57,7 +57,6 @@ import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.GetItemsFilter import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.LocalImageUrlService import com.github.damontecres.wholphin.ui.LocalImageUrlService
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
import com.github.damontecres.wholphin.ui.cards.FavoriteIndicator import com.github.damontecres.wholphin.ui.cards.FavoriteIndicator
import com.github.damontecres.wholphin.ui.cards.WatchedIcon import com.github.damontecres.wholphin.ui.cards.WatchedIcon
import com.github.damontecres.wholphin.ui.data.SortAndDirection import com.github.damontecres.wholphin.ui.data.SortAndDirection
@ -115,7 +114,9 @@ fun CollectionFolderList(
val gridFocusRequester = remember { FocusRequester() } val gridFocusRequester = remember { FocusRequester() }
if (pager?.isNotEmpty() == true) { if (pager?.isNotEmpty() == true) {
RequestOrRestoreFocus(gridFocusRequester) LaunchedEffect(viewOptions.type) {
gridFocusRequester.tryRequestFocus()
}
} else { } else {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
(focusRequesterOnEmpty ?: headerRowFocusRequester).tryRequestFocus() (focusRequesterOnEmpty ?: headerRowFocusRequester).tryRequestFocus()

View file

@ -16,11 +16,14 @@ import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.foundation.relocation.bringIntoViewRequester
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
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.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -64,6 +67,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.ApiClient
import javax.inject.Inject import javax.inject.Inject
@ -153,6 +157,8 @@ fun NavDrawerPreferenceDialog(
onMoveUp: (Int) -> Unit, onMoveUp: (Int) -> Unit,
onMoveDown: (Int) -> Unit, onMoveDown: (Int) -> Unit,
) { ) {
val scope = rememberCoroutineScope()
val bringIntoViewRequesters = remember { List(items.size) { BringIntoViewRequester() } }
BasicDialog( BasicDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
elevation = 3.dp, elevation = 3.dp,
@ -169,6 +175,13 @@ fun NavDrawerPreferenceDialog(
modifier = Modifier.padding(bottom = 8.dp), modifier = Modifier.padding(bottom = 8.dp),
) )
val listState = rememberLazyListState() val listState = rememberLazyListState()
fun ensureVisible(index: Int) {
val idx = index.coerceIn(items.indices)
scope.launch {
bringIntoViewRequesters[idx].bringIntoView()
}
}
LazyColumn( LazyColumn(
state = listState, state = listState,
verticalArrangement = Arrangement.spacedBy(0.dp), verticalArrangement = Arrangement.spacedBy(0.dp),
@ -180,9 +193,18 @@ fun NavDrawerPreferenceDialog(
moveUpAllowed = index > 0, moveUpAllowed = index > 0,
moveDownAllowed = index < items.lastIndex, moveDownAllowed = index < items.lastIndex,
onClick = { onClick.invoke(index) }, onClick = { onClick.invoke(index) },
onMoveUp = { onMoveUp.invoke(index) }, onMoveUp = {
onMoveDown = { onMoveDown.invoke(index) }, onMoveUp.invoke(index)
modifier = Modifier.animateItem(), ensureVisible(index - 1)
},
onMoveDown = {
onMoveDown.invoke(index)
ensureVisible(index + 1)
},
modifier =
Modifier
.animateItem()
.bringIntoViewRequester(bringIntoViewRequesters[index]),
) )
} }
} }

View file

@ -70,7 +70,7 @@ data class Version(
private fun compareNumCommits(version: Version): Int = (this.numCommits ?: 0) - (version.numCommits ?: 0) private fun compareNumCommits(version: Version): Int = (this.numCommits ?: 0) - (version.numCommits ?: 0)
override fun toString(): String = override fun toString(): String =
if (numCommits != null && hash != null) { if (numCommits != null && numCommits > 0 && hash != null) {
"v$major.$minor.$patch-$numCommits-g$hash" "v$major.$minor.$patch-$numCommits-g$hash"
} else { } else {
"v$major.$minor.$patch" "v$major.$minor.$patch"

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@raw/aboutlibraries" />

View file

@ -0,0 +1,85 @@
package com.github.damontecres.wholphin.test
import com.github.damontecres.wholphin.util.Version
import org.junit.Assert
import org.junit.Test
class VersionCompareTests {
companion object {
val V_0_2_0 = Version.fromString("v0.2.0")
val V_0_1_0 = Version.fromString("v0.1.0")
val V_0_1_1 = Version.fromString("v0.1.1")
val V_0_2_0_0 = Version.fromString("v0.2.0-0-gabc1234")
val V_0_2_0_7 = Version.fromString("v0.2.0-7-gabc1234")
val V_0_1_0_7 = Version.fromString("v0.1.0-7-gabc1234")
val V_0_1_0_6 = Version.fromString("v0.1.0-6-gabc1234")
val V_0_1_1_4 = Version.fromString("v0.1.1-4-gabc1234")
val V_0_1_1_5 = Version.fromString("v0.1.1-5-gabc1234")
}
@Test
fun testIsAtLeast() {
Assert.assertTrue(V_0_2_0.isAtLeast(V_0_2_0))
Assert.assertTrue(V_0_2_0.isAtLeast(V_0_1_0))
Assert.assertTrue(V_0_1_1.isAtLeast(V_0_1_0))
Assert.assertFalse(V_0_1_0.isAtLeast(V_0_2_0))
Assert.assertFalse(V_0_1_1.isAtLeast(V_0_2_0))
Assert.assertTrue(V_0_2_0.isAtLeast(V_0_2_0_0))
Assert.assertTrue(V_0_2_0_0.isAtLeast(V_0_2_0))
Assert.assertTrue(V_0_1_0_7.isAtLeast(V_0_1_0_7))
Assert.assertTrue(V_0_1_0_7.isAtLeast(V_0_1_0_6))
Assert.assertFalse(V_0_1_0_6.isAtLeast(V_0_1_0_7))
}
@Test
fun testisGreaterThan() {
Assert.assertFalse(V_0_2_0.isGreaterThan(V_0_2_0))
Assert.assertTrue(V_0_2_0.isGreaterThan(V_0_1_0))
Assert.assertTrue(V_0_1_1.isGreaterThan(V_0_1_0))
Assert.assertFalse(V_0_1_0.isGreaterThan(V_0_2_0))
Assert.assertFalse(V_0_2_0.isGreaterThan(V_0_2_0_0))
Assert.assertFalse(V_0_2_0_0.isGreaterThan(V_0_2_0))
Assert.assertFalse(V_0_1_0_7.isGreaterThan(V_0_1_0_7))
Assert.assertTrue(V_0_1_0_7.isGreaterThan(V_0_1_0_6))
Assert.assertTrue(V_0_2_0_7.isGreaterThan(V_0_2_0_0))
Assert.assertTrue(V_0_1_1_4.isGreaterThan(V_0_1_0_6))
Assert.assertTrue(V_0_1_1_4.isGreaterThan(V_0_1_0))
Assert.assertFalse(V_0_1_1_4.isGreaterThan(V_0_1_1_5))
Assert.assertTrue(V_0_1_1_5.isGreaterThan(V_0_1_1_4))
}
@Test
fun testEqualOrBefore() {
Assert.assertTrue(V_0_2_0.isEqualOrBefore(V_0_2_0))
Assert.assertTrue(V_0_1_1.isEqualOrBefore(V_0_2_0))
Assert.assertTrue(V_0_1_1.isEqualOrBefore(V_0_1_1_5))
Assert.assertTrue(V_0_1_1_4.isEqualOrBefore(V_0_1_1_5))
Assert.assertFalse(V_0_2_0.isEqualOrBefore(V_0_1_1))
}
@Test
fun testLessThan() {
Assert.assertFalse(V_0_2_0.isLessThan(V_0_2_0))
Assert.assertTrue(V_0_1_1.isLessThan(V_0_2_0))
Assert.assertTrue(V_0_1_1.isLessThan(V_0_1_1_5))
Assert.assertTrue(V_0_1_1_4.isLessThan(V_0_1_1_5))
Assert.assertFalse(V_0_2_0.isLessThan(V_0_1_1))
}
@Test
fun testToString() {
Assert.assertEquals("v0.2.0", V_0_2_0.toString())
Assert.assertEquals("v0.2.0", V_0_2_0_0.toString())
Assert.assertEquals("v0.3.0", Version(0, 3, 0, null).toString())
Assert.assertEquals("v0.3.0", Version(0, 3, 0, 0, "abc1234").toString())
Assert.assertEquals("v0.2.0-1-gabc1234", Version(0, 2, 0, 1, "abc1234").toString())
Assert.assertEquals("v0.2.0-7-gabc1234", V_0_2_0_7.toString())
}
}