Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.kitshn.ui.component.settings

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
Expand All @@ -12,6 +13,7 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
Expand Down Expand Up @@ -40,15 +42,17 @@ fun SettingsListItem(
trailingContent: @Composable () -> Unit = {},
alternativeColors: Boolean = false,
selected: Boolean = false,
containerColor: Color? = null,
onClick: () -> Unit = {}
) {
val containerColor = if(selected) {
MaterialTheme.colorScheme.primaryContainer
} else if(alternativeColors) {
MaterialTheme.colorScheme.surfaceContainerLow
} else {
MaterialTheme.colorScheme.surfaceContainer
}
val finalContainerColor = containerColor
?: if(selected) {
MaterialTheme.colorScheme.primaryContainer
} else if(alternativeColors) {
MaterialTheme.colorScheme.surfaceContainerLow
} else {
MaterialTheme.colorScheme.surfaceContainer
}

ListItem(
modifier = modifier
Expand Down Expand Up @@ -106,10 +110,10 @@ fun SettingsListItem(
.alpha(if(enabled) 1f else 0.5f)
.clickable { if(enabled) onClick() },
colors = ListItemDefaults.colors(
containerColor = containerColor,
leadingIconColor = MaterialTheme.colorScheme.contentColorFor(containerColor),
headlineColor = MaterialTheme.colorScheme.contentColorFor(containerColor),
supportingColor = MaterialTheme.colorScheme.contentColorFor(containerColor)
containerColor = finalContainerColor,
leadingIconColor = MaterialTheme.colorScheme.contentColorFor(finalContainerColor),
headlineColor = MaterialTheme.colorScheme.contentColorFor(finalContainerColor),
supportingColor = MaterialTheme.colorScheme.contentColorFor(finalContainerColor)
.copy(alpha = 0.8f)
),
overlineContent = overlineContent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp
import com.mikepenz.aboutlibraries.ui.compose.produceLibraries
import com.mikepenz.aboutlibraries.ui.compose.rememberLibraries
import com.mikepenz.aboutlibraries.ui.compose.util.author
import de.kitshn.launchWebsiteHandler
Expand Down Expand Up @@ -63,7 +64,7 @@ fun ViewSettingsAbout(
val launchWebsite = launchWebsiteHandler()
val uriHandler = LocalUriHandler.current

val libs by rememberLibraries {
val libs by produceLibraries {
Res.readBytes("files/aboutlibraries.json").decodeToString()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package de.kitshn.ui.view.settings

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.Logout
import androidx.compose.material.icons.rounded.AccountCircle
Expand Down Expand Up @@ -34,6 +36,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withLink
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import de.kitshn.api.tandoor.TandoorRequestState
import de.kitshn.closeAppHandler
import de.kitshn.launchWebsiteHandler
Expand All @@ -42,6 +45,7 @@ import de.kitshn.ui.component.settings.SettingsListItem
import de.kitshn.ui.component.settings.SettingsListItemPosition
import de.kitshn.ui.dialog.version.TandoorServerVersionCompatibilityDialog
import de.kitshn.ui.view.ViewParameters
import de.kitshn.version.TandoorServerVersionCompatibility
import kitshn.composeapp.generated.resources.Res
import kitshn.composeapp.generated.resources.action_sign_out
import kitshn.composeapp.generated.resources.action_sign_out_description
Expand Down Expand Up @@ -70,6 +74,9 @@ fun ViewSettingsServer(
val launchWebsiteHandler = launchWebsiteHandler()
val closeAppHandler = closeAppHandler()

val serverVersion = p.vm.tandoorClient?.container?.serverSettings?.version
val compatibilityState = TandoorServerVersionCompatibility.getCompatibilityStateOfVersion(serverVersion ?: "")

var showVersionCompatibilityBottomSheet by remember { mutableStateOf(false) }

var showDataManagementDialog by remember { mutableStateOf(false) }
Expand Down Expand Up @@ -129,13 +136,22 @@ fun ViewSettingsServer(
label = { Text(stringResource(Res.string.common_version)) },
description = {
Text(
p.vm.tandoorClient?.container?.serverSettings?.version
?: stringResource(Res.string.common_unknown)
serverVersion ?: stringResource(Res.string.common_unknown)
)
},
icon = Icons.Rounded.Numbers,
enabled = p.vm.tandoorClient?.container?.serverSettings?.version != null,
contentDescription = stringResource(Res.string.common_version)
trailingContent = {
Icon(
modifier = Modifier
.padding(4.dp),
imageVector = compatibilityState.icon,
contentDescription = compatibilityState.label.toString(),
tint = compatibilityState.iconTint()
)
},
containerColor = compatibilityState.tint().copy(alpha = 0.1f),
enabled = serverVersion != null,
contentDescription = stringResource(Res.string.common_version),
) {
coroutineScope.launch {
showVersionCompatibilityBottomSheet = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum class TandoorServerVersionCompatibilityState(
val description: StringResource,
val icon: ImageVector,
val iconTint: @Composable () -> Color,
val tint: @Composable () -> Color,
val hideCompatibleVersionsList: Boolean = false,
val disableDismiss: Boolean = false
) {
Expand All @@ -35,32 +36,37 @@ enum class TandoorServerVersionCompatibilityState(
description = Res.string.tandoor_compatibility_incompatible_description,
icon = Icons.Rounded.Block,
iconTint = { MaterialTheme.colorScheme.error },
tint = { MaterialTheme.colorScheme.error },
disableDismiss = true
),
UNKNOWN(
label = Res.string.tandoor_compatibility_unknown_label,
description = Res.string.tandoor_compatibility_unknown_description,
icon = Icons.Rounded.QuestionMark,
iconTint = { Color.Gray },
tint = { Color.Gray }
),
MIXED_COMPATIBILITY(
label = Res.string.tandoor_compatibility_mixed_compatibility_label,
description = Res.string.tandoor_compatibility_mixed_compatibility_description,
icon = Icons.Rounded.WarningAmber,
iconTint = { Color.Yellow }
iconTint = { Color(0xFFBA8E23) }, // darker yellow
tint = { Color.Yellow }
),
FULL_COMPATIBILITY(
label = Res.string.tandoor_compatibility_full_compatibility_label,
description = Res.string.tandoor_compatibility_full_compatibility_description,
icon = Icons.Rounded.Check,
iconTint = { Color.Green },
iconTint = { Color(0xFF06402B) }, // darker green
tint = { Color.Green },
hideCompatibleVersionsList = true
),
UNKNOWN(
label = Res.string.tandoor_compatibility_unknown_label,
description = Res.string.tandoor_compatibility_unknown_description,
icon = Icons.Rounded.QuestionMark,
iconTint = { Color.Gray }
),
NOT_CHECKABLE(
label = Res.string.tandoor_compatibility_not_checkable_label,
description = Res.string.tandoor_compatibility_not_checkable_description,
icon = Icons.Rounded.QuestionMark,
iconTint = { Color.Gray }
iconTint = { Color.Gray },
tint = { Color.Gray }
)
}

Expand Down Expand Up @@ -112,11 +118,40 @@ enum class TandoorServerVersionCompatibility(
}

fun getCompatibilityStateOfVersion(version: String): TandoorServerVersionCompatibilityState {
return try {
parseVersion(version).state
} catch(e: NullPointerException) {
TandoorServerVersionCompatibilityState.UNKNOWN
// versions precedence:
// 1. Version found in version matrix -> use that
// 2. walk patch to 0 -> if found something use that
// 3. walk minor to 0 (including patches) -> at least MIXED_COMPATIBILITY or worse
// else Unknown

val parts = version.split(".").map { it.toIntOrNull() ?: return TandoorServerVersionCompatibilityState.UNKNOWN }
if (parts.size != 3) return TandoorServerVersionCompatibilityState.UNKNOWN

val (major, minor, patch) = parts

try { return parseVersion(version).state } catch (_: NullPointerException) {}

// walk down bugfix and use that
for (p in (patch - 1) downTo 0){
try { return parseVersion("$major.$minor.$p").state } catch (_: NullPointerException) {}
}

// walk down minor and if found anything return at least MIXED or the more severe state
for (m in (minor - 1) downTo 0) {
for (p in (patch - 1) downTo 0){
try {
val state = parseVersion("$major.$m.$p").state

return if (state == TandoorServerVersionCompatibilityState.FULL_COMPATIBILITY) {
TandoorServerVersionCompatibilityState.MIXED_COMPATIBILITY
} else {
state
}
} catch (_: NullPointerException) {}
}
}

return TandoorServerVersionCompatibilityState.UNKNOWN
}
}
}