diff --git a/app/src/main/java/com/github/damontecres/wholphin/preferences/AppPreferencesSerializer.kt b/app/src/main/java/com/github/damontecres/wholphin/preferences/AppPreferencesSerializer.kt index 99145371..59b9a6ea 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/preferences/AppPreferencesSerializer.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/preferences/AppPreferencesSerializer.kt @@ -99,6 +99,8 @@ class AppPreferencesSerializer showClock = AppPreference.ShowClock.defaultValue backdropStyle = AppPreference.BackdropStylePref.defaultValue showLogos = AppPreference.ShowLogos.defaultValue + clearDisplayToggles() + addAllDisplayToggles(AppPreference.DisplayTogglesPref.defaultValue) searchPreferences = SearchPreferences diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/AppUpgradeHandler.kt b/app/src/main/java/com/github/damontecres/wholphin/services/AppUpgradeHandler.kt index 7ba190de..281eddc2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/AppUpgradeHandler.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/AppUpgradeHandler.kt @@ -341,5 +341,14 @@ class AppUpgradeHandler it.updateSearchPreferences { showVoiceSearchButton = true } } } + + if (previous.isEqualOrBefore(Version.fromString("0.6.4-26-g0"))) { + appPreferences.updateData { + it.updateInterfacePreferences { + clearDisplayToggles() + addAllDisplayToggles(AppPreference.DisplayTogglesPref.defaultValue) + } + } + } } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderList.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderList.kt index bb4378fe..f34b2b6d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderList.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderList.kt @@ -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.preferences.UserPreferences 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.WatchedIcon import com.github.damontecres.wholphin.ui.data.SortAndDirection @@ -115,7 +114,9 @@ fun CollectionFolderList( val gridFocusRequester = remember { FocusRequester() } if (pager?.isNotEmpty() == true) { - RequestOrRestoreFocus(gridFocusRequester) + LaunchedEffect(viewOptions.type) { + gridFocusRequester.tryRequestFocus() + } } else { LaunchedEffect(Unit) { (focusRequesterOnEmpty ?: headerRowFocusRequester).tryRequestFocus() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt index bd8a95be..e8c768a4 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt @@ -16,11 +16,14 @@ import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed 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.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -64,6 +67,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.api.client.ApiClient import javax.inject.Inject @@ -153,6 +157,8 @@ fun NavDrawerPreferenceDialog( onMoveUp: (Int) -> Unit, onMoveDown: (Int) -> Unit, ) { + val scope = rememberCoroutineScope() + val bringIntoViewRequesters = remember { List(items.size) { BringIntoViewRequester() } } BasicDialog( onDismissRequest = onDismissRequest, elevation = 3.dp, @@ -169,6 +175,13 @@ fun NavDrawerPreferenceDialog( modifier = Modifier.padding(bottom = 8.dp), ) val listState = rememberLazyListState() + + fun ensureVisible(index: Int) { + val idx = index.coerceIn(items.indices) + scope.launch { + bringIntoViewRequesters[idx].bringIntoView() + } + } LazyColumn( state = listState, verticalArrangement = Arrangement.spacedBy(0.dp), @@ -180,9 +193,18 @@ fun NavDrawerPreferenceDialog( moveUpAllowed = index > 0, moveDownAllowed = index < items.lastIndex, onClick = { onClick.invoke(index) }, - onMoveUp = { onMoveUp.invoke(index) }, - onMoveDown = { onMoveDown.invoke(index) }, - modifier = Modifier.animateItem(), + onMoveUp = { + onMoveUp.invoke(index) + ensureVisible(index - 1) + }, + onMoveDown = { + onMoveDown.invoke(index) + ensureVisible(index + 1) + }, + modifier = + Modifier + .animateItem() + .bringIntoViewRequester(bringIntoViewRequesters[index]), ) } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/Version.kt b/app/src/main/java/com/github/damontecres/wholphin/util/Version.kt index b670326b..d3248935 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/util/Version.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/util/Version.kt @@ -70,7 +70,7 @@ data class Version( private fun compareNumCommits(version: Version): Int = (this.numCommits ?: 0) - (version.numCommits ?: 0) override fun toString(): String = - if (numCommits != null && hash != null) { + if (numCommits != null && numCommits > 0 && hash != null) { "v$major.$minor.$patch-$numCommits-g$hash" } else { "v$major.$minor.$patch" diff --git a/app/src/main/res/raw/keep.xml b/app/src/main/res/raw/keep.xml new file mode 100644 index 00000000..5714801d --- /dev/null +++ b/app/src/main/res/raw/keep.xml @@ -0,0 +1,3 @@ + + diff --git a/app/src/test/java/com/github/damontecres/wholphin/test/VersionCompareTests.kt b/app/src/test/java/com/github/damontecres/wholphin/test/VersionCompareTests.kt new file mode 100644 index 00000000..e7e63acd --- /dev/null +++ b/app/src/test/java/com/github/damontecres/wholphin/test/VersionCompareTests.kt @@ -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()) + } +}