Add SettingsColumn composable and clean up formatting
This commit is contained in:
committed by
Niels van Velzen
parent
c6e0badbae
commit
d714d58fef
@@ -0,0 +1,17 @@
|
||||
package org.jellyfin.androidtv.ui.settings.composable
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SettingsColumn(content: LazyListScope.() -> Unit) = LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
content = content,
|
||||
)
|
||||
@@ -1,20 +1,13 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen
|
||||
|
||||
import android.text.format.Formatter
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableLongStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil3.ImageLoader
|
||||
import org.jellyfin.androidtv.BuildConfig
|
||||
import org.jellyfin.androidtv.R
|
||||
@@ -25,6 +18,7 @@ import org.jellyfin.androidtv.ui.base.form.Checkbox
|
||||
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.jellyfin.androidtv.util.isTvDevice
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@@ -36,30 +30,29 @@ fun SettingsDeveloperScreen() {
|
||||
val isTvDevice = remember(context) { context.isTvDevice() }
|
||||
val isDeveloperBuild = BuildConfig.DEVELOPMENT
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.settings).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.pref_developer_link)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_developer_link_description)) },
|
||||
)
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.settings).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.pref_developer_link)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_developer_link_description)) },
|
||||
)
|
||||
}
|
||||
|
||||
// Legacy debug flag
|
||||
// Not in use by much components anymore
|
||||
var debuggingEnabled by rememberPreference(userPreferences, UserPreferences.debuggingEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.lbl_enable_debug)) },
|
||||
trailingContent = { Checkbox(checked = debuggingEnabled) },
|
||||
captionContent = { Text(stringResource(R.string.desc_debug)) },
|
||||
onClick = { debuggingEnabled = !debuggingEnabled }
|
||||
)
|
||||
item {
|
||||
// Legacy debug flag
|
||||
// Not in use by much components anymore
|
||||
var debuggingEnabled by rememberPreference(userPreferences, UserPreferences.debuggingEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.lbl_enable_debug)) },
|
||||
trailingContent = { Checkbox(checked = debuggingEnabled) },
|
||||
captionContent = { Text(stringResource(R.string.desc_debug)) },
|
||||
onClick = { debuggingEnabled = !debuggingEnabled }
|
||||
)
|
||||
}
|
||||
|
||||
// UI Mode toggle
|
||||
if (!isTvDevice) {
|
||||
if (!isTvDevice) item {
|
||||
var disableUiModeWarning by rememberPreference(systemPreferences, SystemPreferences.disableUiModeWarning)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.disable_ui_mode_warning)) },
|
||||
@@ -69,7 +62,7 @@ fun SettingsDeveloperScreen() {
|
||||
}
|
||||
|
||||
// Playback rewrite - only show in debug mode
|
||||
if (isDeveloperBuild) {
|
||||
if (isDeveloperBuild) item {
|
||||
var playbackRewriteVideoEnabled by rememberPreference(userPreferences, UserPreferences.playbackRewriteVideoEnabled)
|
||||
ListButton(
|
||||
// String is hardcoded because it's for development only
|
||||
@@ -80,42 +73,48 @@ fun SettingsDeveloperScreen() {
|
||||
)
|
||||
}
|
||||
|
||||
// Trick play
|
||||
var trickPlayEnabled by rememberPreference(userPreferences, UserPreferences.trickPlayEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.preference_enable_trickplay)) },
|
||||
trailingContent = { Checkbox(checked = trickPlayEnabled) },
|
||||
captionContent = { Text(stringResource(R.string.enable_playback_module_description)) },
|
||||
onClick = { trickPlayEnabled = !trickPlayEnabled }
|
||||
)
|
||||
item {
|
||||
// Trick play
|
||||
var trickPlayEnabled by rememberPreference(userPreferences, UserPreferences.trickPlayEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.preference_enable_trickplay)) },
|
||||
trailingContent = { Checkbox(checked = trickPlayEnabled) },
|
||||
captionContent = { Text(stringResource(R.string.enable_playback_module_description)) },
|
||||
onClick = { trickPlayEnabled = !trickPlayEnabled }
|
||||
)
|
||||
}
|
||||
|
||||
// FFmpeg audio extension
|
||||
var preferExoPlayerFfmpeg by rememberPreference(userPreferences, UserPreferences.preferExoPlayerFfmpeg)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.prefer_exoplayer_ffmpeg)) },
|
||||
trailingContent = { Checkbox(checked = preferExoPlayerFfmpeg) },
|
||||
captionContent = { Text(stringResource(R.string.prefer_exoplayer_ffmpeg_content)) },
|
||||
onClick = { preferExoPlayerFfmpeg = !preferExoPlayerFfmpeg }
|
||||
)
|
||||
item {
|
||||
// FFmpeg audio extension
|
||||
var preferExoPlayerFfmpeg by rememberPreference(userPreferences, UserPreferences.preferExoPlayerFfmpeg)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.prefer_exoplayer_ffmpeg)) },
|
||||
trailingContent = { Checkbox(checked = preferExoPlayerFfmpeg) },
|
||||
captionContent = { Text(stringResource(R.string.prefer_exoplayer_ffmpeg_content)) },
|
||||
onClick = { preferExoPlayerFfmpeg = !preferExoPlayerFfmpeg }
|
||||
)
|
||||
}
|
||||
|
||||
// Image cache
|
||||
val imageLoader = koinInject<ImageLoader>()
|
||||
var imageCacheSize by remember { mutableLongStateOf(imageLoader.diskCache?.size ?: 0L) }
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.clear_image_cache)) },
|
||||
captionContent = {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.clear_image_cache_content,
|
||||
Formatter.formatFileSize(context, imageCacheSize)
|
||||
item {
|
||||
// Image cache
|
||||
val imageLoader = koinInject<ImageLoader>()
|
||||
var imageCacheSize by remember { mutableLongStateOf(imageLoader.diskCache?.size ?: 0L) }
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.clear_image_cache)) },
|
||||
captionContent = {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.clear_image_cache_content,
|
||||
Formatter.formatFileSize(context, imageCacheSize)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
imageLoader.memoryCache?.clear()
|
||||
imageLoader.diskCache?.clear()
|
||||
imageCacheSize = imageLoader.diskCache?.size ?: 0L
|
||||
}
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
imageLoader.memoryCache?.clear()
|
||||
imageLoader.diskCache?.clear()
|
||||
imageCacheSize = imageLoader.diskCache?.size ?: 0L
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jellyfin.androidtv.R
|
||||
import org.jellyfin.androidtv.ui.base.Icon
|
||||
import org.jellyfin.androidtv.ui.base.Text
|
||||
@@ -19,88 +12,70 @@ import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.ActivityDestinations
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.Routes
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
|
||||
@Composable
|
||||
fun SettingsMainScreen() {
|
||||
val context = LocalContext.current
|
||||
val router = LocalRouter.current
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.app_name).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.settings)) },
|
||||
captionContent = { Text(stringResource(R.string.settings_description)) },
|
||||
)
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.app_name).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.settings)) },
|
||||
captionContent = { Text(stringResource(R.string.settings_description)) },
|
||||
)
|
||||
}
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_users),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_login)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_login_description)) },
|
||||
onClick = { router.push(Routes.AUTHENTICATION) }
|
||||
)
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_users), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_login)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_login_description)) },
|
||||
onClick = { router.push(Routes.AUTHENTICATION) }
|
||||
)
|
||||
}
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_adjust),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_customization)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_customization_description)) },
|
||||
onClick = {
|
||||
context.startActivity(ActivityDestinations.customizationPreferences(context))
|
||||
}
|
||||
)
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_adjust), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_customization)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_customization_description)) },
|
||||
onClick = { context.startActivity(ActivityDestinations.customizationPreferences(context)) }
|
||||
)
|
||||
}
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_next),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_playback)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_playback_description)) },
|
||||
onClick = {
|
||||
context.startActivity(ActivityDestinations.playbackPreferences(context))
|
||||
}
|
||||
)
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_next), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_playback)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_playback_description)) },
|
||||
onClick = { context.startActivity(ActivityDestinations.playbackPreferences(context)) }
|
||||
)
|
||||
}
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_error),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_telemetry_category)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_telemetry_description)) },
|
||||
onClick = { router.push(Routes.TELEMETRY) }
|
||||
)
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_error), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_telemetry_category)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_telemetry_description)) },
|
||||
onClick = { router.push(Routes.TELEMETRY) }
|
||||
)
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_flask),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_developer_link)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_developer_link_description)) },
|
||||
onClick = { router.push(Routes.DEVELOPER) }
|
||||
)
|
||||
}
|
||||
|
||||
SettingsMainScreenAbout()
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_flask), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_developer_link)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_developer_link_description)) },
|
||||
onClick = { router.push(Routes.DEVELOPER) }
|
||||
)
|
||||
}
|
||||
|
||||
settingsAboutItems(
|
||||
openLicenses = { router.push(Routes.LICENSES) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import org.jellyfin.androidtv.BuildConfig
|
||||
@@ -10,48 +10,34 @@ import org.jellyfin.androidtv.ui.base.Icon
|
||||
import org.jellyfin.androidtv.ui.base.Text
|
||||
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.Routes
|
||||
|
||||
@Composable
|
||||
fun SettingsMainScreenAbout() {
|
||||
val router = LocalRouter.current
|
||||
fun LazyListScope.settingsAboutItems(
|
||||
openLicenses: () -> Unit,
|
||||
) {
|
||||
item { ListSection(headingContent = { Text(stringResource(R.string.pref_about_title)) }) }
|
||||
|
||||
ListSection(
|
||||
headingContent = { Text(stringResource(R.string.pref_about_title)) },
|
||||
)
|
||||
item {
|
||||
ListSection(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_jellyfin), contentDescription = null) },
|
||||
headingContent = { Text("Jellyfin app version") },
|
||||
captionContent = { Text("jellyfin-androidtv ${BuildConfig.VERSION_NAME} ${BuildConfig.BUILD_TYPE}") },
|
||||
)
|
||||
}
|
||||
|
||||
ListSection(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_jellyfin),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text("Jellyfin app version") },
|
||||
captionContent = { Text("jellyfin-androidtv ${BuildConfig.VERSION_NAME} ${BuildConfig.BUILD_TYPE}") },
|
||||
)
|
||||
item {
|
||||
ListSection(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_tv), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.pref_device_model)) },
|
||||
captionContent = { Text("${Build.MANUFACTURER} ${Build.MODEL}") },
|
||||
)
|
||||
}
|
||||
|
||||
ListSection(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_tv),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.pref_device_model)) },
|
||||
captionContent = { Text("${Build.MANUFACTURER} ${Build.MODEL}") },
|
||||
)
|
||||
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_guide),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headingContent = { Text(stringResource(R.string.licenses_link)) },
|
||||
captionContent = { Text(stringResource(R.string.licenses_link_description)) },
|
||||
onClick = { router.push(Routes.LICENSES) }
|
||||
)
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_guide), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.licenses_link)) },
|
||||
captionContent = { Text(stringResource(R.string.licenses_link_description)) },
|
||||
onClick = { openLicenses() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jellyfin.androidtv.R
|
||||
import org.jellyfin.androidtv.preference.TelemetryPreferences
|
||||
import org.jellyfin.androidtv.ui.base.Text
|
||||
@@ -18,58 +11,46 @@ import org.jellyfin.androidtv.ui.base.form.Checkbox
|
||||
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
fun SettingsTelemetryScreen() {
|
||||
val telemetryPreferences = koinInject<TelemetryPreferences>()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.settings).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.pref_telemetry_category)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_telemetry_description)) },
|
||||
)
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.settings).uppercase()) },
|
||||
headingContent = { Text(stringResource(R.string.pref_telemetry_category)) },
|
||||
captionContent = { Text(stringResource(R.string.pref_telemetry_description)) },
|
||||
)
|
||||
}
|
||||
|
||||
var crashReportEnabled by rememberPreference(telemetryPreferences, TelemetryPreferences.crashReportEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.pref_crash_reports)) },
|
||||
trailingContent = {
|
||||
Checkbox(
|
||||
checked = crashReportEnabled,
|
||||
)
|
||||
},
|
||||
captionContent = {
|
||||
if (crashReportEnabled) {
|
||||
Text(stringResource(R.string.pref_crash_reports_enabled))
|
||||
} else {
|
||||
Text(stringResource(R.string.pref_crash_reports_disabled))
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
crashReportEnabled = !crashReportEnabled
|
||||
}
|
||||
)
|
||||
item {
|
||||
var crashReportEnabled by rememberPreference(telemetryPreferences, TelemetryPreferences.crashReportEnabled)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.pref_crash_reports)) },
|
||||
trailingContent = { Checkbox(checked = crashReportEnabled) },
|
||||
captionContent = {
|
||||
if (crashReportEnabled) Text(stringResource(R.string.pref_crash_reports_enabled))
|
||||
else Text(stringResource(R.string.pref_crash_reports_disabled))
|
||||
},
|
||||
onClick = { crashReportEnabled = !crashReportEnabled }
|
||||
)
|
||||
}
|
||||
|
||||
var crashReportIncludeLogs by rememberPreference(telemetryPreferences, TelemetryPreferences.crashReportIncludeLogs)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.pref_crash_report_logs)) },
|
||||
trailingContent = { Checkbox(checked = crashReportIncludeLogs) },
|
||||
captionContent = {
|
||||
if (crashReportIncludeLogs) {
|
||||
Text(stringResource(R.string.pref_crash_report_logs_enabled))
|
||||
} else {
|
||||
Text(stringResource(R.string.pref_crash_report_logs_disabled))
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
crashReportIncludeLogs = !crashReportIncludeLogs
|
||||
}
|
||||
)
|
||||
item {
|
||||
var crashReportIncludeLogs by rememberPreference(telemetryPreferences, TelemetryPreferences.crashReportIncludeLogs)
|
||||
ListButton(
|
||||
headingContent = { Text(stringResource(R.string.pref_crash_report_logs)) },
|
||||
trailingContent = { Checkbox(checked = crashReportIncludeLogs) },
|
||||
captionContent = {
|
||||
if (crashReportIncludeLogs) Text(stringResource(R.string.pref_crash_report_logs_enabled))
|
||||
else Text(stringResource(R.string.pref_crash_report_logs_disabled))
|
||||
},
|
||||
onClick = { crashReportIncludeLogs = !crashReportIncludeLogs }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.authentication
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -35,6 +32,7 @@ import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
@@ -54,11 +52,7 @@ fun SettingsAuthenticationAutoSignInScreen() {
|
||||
|
||||
val storedServers by serverRepository.storedServers.collectAsState()
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.pref_login).uppercase()) },
|
||||
@@ -91,11 +85,7 @@ fun SettingsAuthenticationAutoSignInScreen() {
|
||||
}
|
||||
|
||||
for (server in storedServers) {
|
||||
item {
|
||||
ListSection(
|
||||
headingContent = { Text(server.name) },
|
||||
)
|
||||
}
|
||||
item { ListSection(headingContent = { Text(server.name) }) }
|
||||
|
||||
val users = serverUserRepository.getStoredServerUsers(server)
|
||||
val serverId = server.id.toString()
|
||||
@@ -108,10 +98,7 @@ fun SettingsAuthenticationAutoSignInScreen() {
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
if (!userImageVisible) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_user),
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(imageVector = ImageVector.vectorResource(R.drawable.ic_user), contentDescription = null)
|
||||
} else {
|
||||
Image(
|
||||
painter = userImagePainter,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.authentication
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -10,10 +7,8 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jellyfin.androidtv.R
|
||||
import org.jellyfin.androidtv.auth.repository.ServerRepository
|
||||
import org.jellyfin.androidtv.auth.repository.ServerUserRepository
|
||||
@@ -27,7 +22,8 @@ import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.Routes
|
||||
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||
import org.jellyfin.androidtv.ui.settings.screen.SettingsMainScreenAbout
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.jellyfin.androidtv.ui.settings.screen.settingsAboutItems
|
||||
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@@ -38,17 +34,11 @@ fun SettingsAuthenticationScreen(launchedFromLogin: Boolean = false) {
|
||||
val serverUserRepository = koinInject<ServerUserRepository>()
|
||||
val authenticationPreferences = koinInject<AuthenticationPreferences>()
|
||||
|
||||
LaunchedEffect(serverRepository) {
|
||||
serverRepository.loadStoredServers()
|
||||
}
|
||||
LaunchedEffect(serverRepository) { serverRepository.loadStoredServers() }
|
||||
|
||||
val storedServers by serverRepository.storedServers.collectAsState()
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
if (launchedFromLogin) item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.app_name).uppercase()) },
|
||||
@@ -98,15 +88,11 @@ fun SettingsAuthenticationScreen(launchedFromLogin: Boolean = false) {
|
||||
}
|
||||
|
||||
if (storedServers.isNotEmpty()) {
|
||||
item {
|
||||
ListSection(
|
||||
headingContent = { Text(stringResource(R.string.lbl_manage_servers)) },
|
||||
)
|
||||
}
|
||||
item { ListSection(headingContent = { Text(stringResource(R.string.lbl_manage_servers)) }) }
|
||||
|
||||
items(storedServers) { server ->
|
||||
ListButton(
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_house), contentDescription = server.name) },
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_house), contentDescription = null) },
|
||||
headingContent = { Text(server.name) },
|
||||
captionContent = { Text(server.address) },
|
||||
onClick = {
|
||||
@@ -124,11 +110,7 @@ fun SettingsAuthenticationScreen(launchedFromLogin: Boolean = false) {
|
||||
// Disallow changing the "always authenticate" option from the login screen
|
||||
// because that could allow a kid to disable the function to access a parent's account
|
||||
if (!launchedFromLogin) {
|
||||
item {
|
||||
ListSection(
|
||||
headingContent = { Text(stringResource(R.string.advanced_settings)) },
|
||||
)
|
||||
}
|
||||
item { ListSection(headingContent = { Text(stringResource(R.string.advanced_settings)) }) }
|
||||
|
||||
item {
|
||||
var alwaysAuthenticate by rememberPreference(authenticationPreferences, AuthenticationPreferences.alwaysAuthenticate)
|
||||
@@ -141,8 +123,8 @@ fun SettingsAuthenticationScreen(launchedFromLogin: Boolean = false) {
|
||||
}
|
||||
}
|
||||
|
||||
if (launchedFromLogin) item {
|
||||
SettingsMainScreenAbout()
|
||||
}
|
||||
if (launchedFromLogin) settingsAboutItems(
|
||||
openLicenses = { router.push(Routes.LICENSES) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.authentication
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -37,6 +34,7 @@ import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.Routes
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.koin.compose.koinInject
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
@@ -53,23 +51,15 @@ fun SettingsAuthenticationServerScreen(serverId: UUID) {
|
||||
val serverUserRepository = koinInject<ServerUserRepository>()
|
||||
val authenticationRepository = koinInject<AuthenticationRepository>()
|
||||
|
||||
LaunchedEffect(serverRepository) {
|
||||
serverRepository.loadStoredServers()
|
||||
}
|
||||
LaunchedEffect(serverRepository) { serverRepository.loadStoredServers() }
|
||||
|
||||
val server by remember(serverRepository.storedServers) {
|
||||
serverRepository.storedServers.map { it.find { server -> server.id == serverId } }
|
||||
}.collectAsState(null)
|
||||
|
||||
val users = remember(server) {
|
||||
server?.let(serverUserRepository::getStoredServerUsers)
|
||||
}
|
||||
val users = remember(server) { server?.let(serverUserRepository::getStoredServerUsers) }
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.pref_login).uppercase()) },
|
||||
@@ -79,11 +69,7 @@ fun SettingsAuthenticationServerScreen(serverId: UUID) {
|
||||
}
|
||||
|
||||
if (!users.isNullOrEmpty()) {
|
||||
item {
|
||||
ListSection(
|
||||
headingContent = { Text(stringResource(R.string.pref_accounts)) },
|
||||
)
|
||||
}
|
||||
item { ListSection(headingContent = { Text(stringResource(R.string.pref_accounts)) }) }
|
||||
|
||||
items(users) { user ->
|
||||
val userImagePainter = rememberAsyncImagePainter(authenticationRepository.getUserImageUrl(server!!, user))
|
||||
@@ -93,10 +79,7 @@ fun SettingsAuthenticationServerScreen(serverId: UUID) {
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
if (!userImageVisible) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_user),
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(imageVector = ImageVector.vectorResource(R.drawable.ic_user), contentDescription = null)
|
||||
} else {
|
||||
Image(
|
||||
painter = userImagePainter,
|
||||
@@ -136,20 +119,11 @@ fun SettingsAuthenticationServerScreen(serverId: UUID) {
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
ListSection(
|
||||
headingContent = { Text(stringResource(R.string.lbl_server)) },
|
||||
)
|
||||
}
|
||||
item { ListSection(headingContent = { Text(stringResource(R.string.lbl_server)) }) }
|
||||
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_delete),
|
||||
contentDescription = stringResource(R.string.lbl_remove_server)
|
||||
)
|
||||
},
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_delete), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.lbl_remove_server)) },
|
||||
captionContent = { Text(stringResource(R.string.lbl_remove_users)) },
|
||||
onClick = {
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.authentication
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -25,6 +20,7 @@ import org.jellyfin.androidtv.ui.base.Text
|
||||
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.koin.compose.koinInject
|
||||
import java.util.UUID
|
||||
|
||||
@@ -36,23 +32,15 @@ fun SettingsAuthenticationServerUserScreen(serverId: UUID, userId: UUID) {
|
||||
val serverUserRepository = koinInject<ServerUserRepository>()
|
||||
val authenticationRepository = koinInject<AuthenticationRepository>()
|
||||
|
||||
LaunchedEffect(serverRepository) {
|
||||
serverRepository.loadStoredServers()
|
||||
}
|
||||
LaunchedEffect(serverRepository) { serverRepository.loadStoredServers() }
|
||||
|
||||
val server by remember(serverRepository.storedServers) {
|
||||
serverRepository.storedServers.map { it.find { server -> server.id == serverId } }
|
||||
}.collectAsState(null)
|
||||
|
||||
val user = remember(server) {
|
||||
server?.let(serverUserRepository::getStoredServerUsers)?.find { user -> user.id == userId }
|
||||
}
|
||||
val user = remember(server) { server?.let(serverUserRepository::getStoredServerUsers)?.find { user -> user.id == userId } }
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(server?.name?.uppercase().orEmpty()) },
|
||||
@@ -62,12 +50,7 @@ fun SettingsAuthenticationServerUserScreen(serverId: UUID, userId: UUID) {
|
||||
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_logout),
|
||||
contentDescription = stringResource(R.string.lbl_sign_out)
|
||||
)
|
||||
},
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_logout), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.lbl_sign_out)) },
|
||||
captionContent = { Text(stringResource(R.string.lbl_sign_out_content)) },
|
||||
onClick = {
|
||||
@@ -81,12 +64,7 @@ fun SettingsAuthenticationServerUserScreen(serverId: UUID, userId: UUID) {
|
||||
|
||||
item {
|
||||
ListButton(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_delete),
|
||||
contentDescription = stringResource(R.string.lbl_remove)
|
||||
)
|
||||
},
|
||||
leadingContent = { Icon(painterResource(R.drawable.ic_delete), contentDescription = null) },
|
||||
headingContent = { Text(stringResource(R.string.lbl_remove)) },
|
||||
captionContent = { Text(stringResource(R.string.lbl_remove_user_content)) },
|
||||
onClick = {
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.authentication
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jellyfin.androidtv.R
|
||||
import org.jellyfin.androidtv.auth.model.AuthenticationSortBy
|
||||
import org.jellyfin.androidtv.auth.store.AuthenticationPreferences
|
||||
@@ -19,6 +14,7 @@ import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
@@ -27,11 +23,7 @@ fun SettingsAuthenticationSortByScreen() {
|
||||
val authenticationPreferences = koinInject<AuthenticationPreferences>()
|
||||
var sortBy by rememberPreference(authenticationPreferences, AuthenticationPreferences.sortBy)
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.pref_login).uppercase()) },
|
||||
|
||||
@@ -3,18 +3,13 @@ package org.jellyfin.androidtv.ui.settings.screen.license
|
||||
import android.content.ClipData
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
@@ -24,6 +19,7 @@ import org.jellyfin.androidtv.R
|
||||
import org.jellyfin.androidtv.ui.base.Text
|
||||
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
|
||||
@Composable
|
||||
fun SettingsLicenseScreen(artifactId: String) {
|
||||
@@ -53,11 +49,8 @@ fun SettingsLicenseScreen(artifactId: String) {
|
||||
library.developers.forEach { developer -> add(stringResource(R.string.license_author) to developer.name) }
|
||||
library.licenses.forEach { license -> add(stringResource(R.string.license_license) to license.name) }
|
||||
}
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.licenses_link).uppercase()) },
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
package org.jellyfin.androidtv.ui.settings.screen.license
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.util.withContext
|
||||
import org.jellyfin.androidtv.R
|
||||
@@ -18,6 +13,7 @@ import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||
import org.jellyfin.androidtv.ui.settings.Routes
|
||||
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||
|
||||
@Composable
|
||||
fun SettingsLicensesScreen() {
|
||||
@@ -32,11 +28,7 @@ fun SettingsLicensesScreen() {
|
||||
libs.libraries.sortedBy { it.name.lowercase() }
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
SettingsColumn {
|
||||
item {
|
||||
ListSection(
|
||||
overlineContent = { Text(stringResource(R.string.settings).uppercase()) },
|
||||
|
||||
Reference in New Issue
Block a user