Restructure settings
This commit is contained in:
parent
971b015d9a
commit
dfe1c83c80
@ -1,6 +1,7 @@
|
||||
package de.mm20.launcher2.ui.launcher.sheets
|
||||
|
||||
import WidgetsService
|
||||
import android.app.Application
|
||||
import android.appwidget.AppWidgetProviderInfo
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
@ -10,6 +11,7 @@ import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
@ -32,11 +34,9 @@ import org.koin.core.component.get
|
||||
|
||||
class WidgetPickerSheetVM(
|
||||
private val widgetsService: WidgetsService,
|
||||
private val context: Context,
|
||||
private val packageManager: PackageManager,
|
||||
) : ViewModel() {
|
||||
|
||||
private val packageManager = context.packageManager
|
||||
|
||||
val searchQuery = MutableStateFlow("")
|
||||
|
||||
private val enabledWidgets = widgetsService.getWidgets()
|
||||
|
||||
@ -23,10 +23,9 @@ import de.mm20.launcher2.ui.locals.LocalCardStyle
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
||||
import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.integrations.IntegrationsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.backup.BackupSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.badges.BadgeSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.buildinfo.BuildInfoSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.calendarwidget.CalendarWidgetSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.cards.CardsSettingsScreen
|
||||
@ -41,17 +40,17 @@ import de.mm20.launcher2.ui.settings.favorites.FavoritesSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.filesearch.FileSearchSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.gestures.GestureSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.hiddenitems.HiddenItemsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.layout.LayoutSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.homescreen.HomescreenSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.icons.IconsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.license.LicenseScreen
|
||||
import de.mm20.launcher2.ui.settings.log.LogScreen
|
||||
import de.mm20.launcher2.ui.settings.main.MainSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.media.MediaIntegrationSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.searchactions.SearchActionsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.tags.TagsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.unitconverter.UnitConverterSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.weather.WeatherIntegrationSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.wikipedia.WikipediaSettingsScreen
|
||||
import de.mm20.launcher2.ui.theme.LauncherTheme
|
||||
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
|
||||
@ -101,8 +100,11 @@ class SettingsActivity : BaseActivity() {
|
||||
composable("settings/appearance") {
|
||||
AppearanceSettingsScreen()
|
||||
}
|
||||
composable("settings/appearance/layout") {
|
||||
LayoutSettingsScreen()
|
||||
composable("settings/homescreen") {
|
||||
HomescreenSettingsScreen()
|
||||
}
|
||||
composable("settings/icons") {
|
||||
IconsSettingsScreen()
|
||||
}
|
||||
composable("settings/appearance/colorscheme") {
|
||||
ColorSchemeSettingsScreen()
|
||||
@ -137,29 +139,23 @@ class SettingsActivity : BaseActivity() {
|
||||
composable("settings/search/tags") {
|
||||
TagsSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets") {
|
||||
WidgetsSettingsScreen()
|
||||
composable("settings/integrations/weather") {
|
||||
WeatherIntegrationSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/weather") {
|
||||
WeatherWidgetSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/music") {
|
||||
MusicWidgetSettingsScreen()
|
||||
composable("settings/integrations/media") {
|
||||
MediaIntegrationSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/calendar") {
|
||||
CalendarWidgetSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/clock") {
|
||||
composable("settings/homescreen/clock") {
|
||||
ClockWidgetSettingsScreen()
|
||||
}
|
||||
composable("settings/favorites") {
|
||||
FavoritesSettingsScreen()
|
||||
}
|
||||
composable("settings/badges") {
|
||||
BadgeSettingsScreen()
|
||||
}
|
||||
composable("settings/accounts") {
|
||||
AccountsSettingsScreen()
|
||||
composable("settings/integrations") {
|
||||
IntegrationsSettingsScreen()
|
||||
}
|
||||
composable("settings/about") {
|
||||
AboutSettingsScreen()
|
||||
|
||||
@ -86,13 +86,6 @@ fun AppearanceSettingsScreen() {
|
||||
PreferenceScreen(title = stringResource(id = R.string.preference_screen_appearance)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
Preference(
|
||||
title = stringResource(id = R.string.preference_layout),
|
||||
summary = stringResource(id = R.string.preference_layout_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/appearance/layout")
|
||||
}
|
||||
)
|
||||
val theme by viewModel.theme.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(id = R.string.preference_theme),
|
||||
@ -147,466 +140,6 @@ fun AppearanceSettingsScreen() {
|
||||
}
|
||||
)
|
||||
}
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_grid)) {
|
||||
val iconSize by viewModel.iconSize.observeAsState(48)
|
||||
SliderPreference(
|
||||
title = stringResource(R.string.preference_grid_icon_size),
|
||||
value = iconSize,
|
||||
step = 8,
|
||||
min = 32,
|
||||
max = 64,
|
||||
onValueChanged = {
|
||||
viewModel.setIconSize(it)
|
||||
}
|
||||
)
|
||||
val showLabels by viewModel.showLabels.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_grid_labels),
|
||||
summary = stringResource(R.string.preference_grid_labels_summary),
|
||||
value = showLabels == true,
|
||||
onValueChanged = {
|
||||
viewModel.setShowLabels(it)
|
||||
}
|
||||
)
|
||||
val columnCount by viewModel.columnCount.observeAsState(5)
|
||||
SliderPreference(
|
||||
title = stringResource(R.string.preference_grid_column_count),
|
||||
value = columnCount,
|
||||
min = 3,
|
||||
max = 8,
|
||||
onValueChanged = {
|
||||
viewModel.setColumnCount(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceCategory(stringResource(id = R.string.preference_category_wallpaper)) {
|
||||
Preference(
|
||||
title = stringResource(R.string.wallpaper),
|
||||
summary = stringResource(R.string.preference_wallpaper_summary),
|
||||
onClick = {
|
||||
viewModel.openWallpaperChooser(context as AppCompatActivity)
|
||||
}
|
||||
)
|
||||
val dimWallpaper by viewModel.dimWallpaper.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_dim_wallpaper),
|
||||
summary = stringResource(R.string.preference_dim_wallpaper_summary),
|
||||
value = dimWallpaper == true,
|
||||
onValueChanged = {
|
||||
viewModel.setDimWallpaper(it)
|
||||
}
|
||||
)
|
||||
val isBlurSupported = remember { viewModel.isBlurAvailable(context) }
|
||||
if (isBlurSupported) {
|
||||
val blurWallpaper by viewModel.blurWallpaper.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_blur_wallpaper),
|
||||
summary = stringResource(
|
||||
if (isBlurSupported) R.string.preference_blur_wallpaper_summary
|
||||
else R.string.preference_blur_wallpaper_unsupported
|
||||
),
|
||||
value = blurWallpaper == true && isBlurSupported,
|
||||
onValueChanged = {
|
||||
viewModel.setBlurWallpaper(it)
|
||||
},
|
||||
enabled = isBlurSupported
|
||||
)
|
||||
}
|
||||
}
|
||||
PreferenceCategory(stringResource(R.string.preference_category_icons)) {
|
||||
val iconShape by viewModel.iconShape.observeAsState(IconSettings.IconShape.PlatformDefault)
|
||||
IconShapePreference(
|
||||
title = stringResource(R.string.preference_icon_shape),
|
||||
summary = getShapeName(iconShape),
|
||||
value = iconShape,
|
||||
onValueChanged = {
|
||||
viewModel.setIconShape(it)
|
||||
}
|
||||
)
|
||||
val adaptifyLegacyIcons by viewModel.adaptifyLegacyIcons.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_enforce_icon_shape),
|
||||
summary = stringResource(R.string.preference_enforce_icon_shape_summary),
|
||||
value = adaptifyLegacyIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setAdaptifyLegacyIcons(it)
|
||||
}
|
||||
)
|
||||
val themedIcons by viewModel.themedIcons.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_themed_icons),
|
||||
summary = stringResource(R.string.preference_themed_icons_summary),
|
||||
value = themedIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setThemedIcons(it)
|
||||
}
|
||||
)
|
||||
val forceThemedIcons by viewModel.forceThemedIcons.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_force_themed_icons),
|
||||
summary = stringResource(R.string.preference_force_themed_icons_summary),
|
||||
value = forceThemedIcons == true,
|
||||
enabled = themedIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setForceThemedIcons(it)
|
||||
}
|
||||
)
|
||||
|
||||
val iconPackPackage by viewModel.iconPack.observeAsState()
|
||||
val iconPackThemed by viewModel.iconPackThemed.collectAsState(true)
|
||||
val installedIconPacks by viewModel.installedIconPacks.collectAsState(emptyList())
|
||||
val iconPack by remember {
|
||||
derivedStateOf { installedIconPacks.firstOrNull { it.packageName == iconPackPackage } }
|
||||
}
|
||||
val items = installedIconPacks.map {
|
||||
it.name to it
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = (Alignment.CenterVertically)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_icon_pack),
|
||||
items = items,
|
||||
summary = if (items.size <= 1) {
|
||||
stringResource(R.string.preference_icon_pack_summary_empty)
|
||||
} else {
|
||||
iconPack?.name ?: "System"
|
||||
},
|
||||
enabled = installedIconPacks.size > 1,
|
||||
value = iconPack,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setIconPack(it.packageName)
|
||||
},
|
||||
itemLabel = {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = it.label,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (it.value?.themed == true) {
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.extraSmall,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.padding(end = 4.dp),
|
||||
imageVector = Icons.Rounded.FormatPaint,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.icon_pack_dynamic_colors),
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (iconPack?.themed == true) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(36.dp)
|
||||
.width(1.dp)
|
||||
.alpha(0.38f)
|
||||
.background(LocalContentColor.current)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(12.dp)
|
||||
) {
|
||||
PlainTooltipBox(tooltip = { Text(stringResource(R.string.icon_pack_dynamic_colors)) }) {
|
||||
FilledIconToggleButton(
|
||||
modifier = Modifier.tooltipAnchor(),
|
||||
checked = iconPackThemed,
|
||||
onCheckedChange = {
|
||||
viewModel.setIconPackThemed(it)
|
||||
}) {
|
||||
Icon(
|
||||
Icons.Rounded.FormatPaint,
|
||||
stringResource(R.string.icon_pack_dynamic_colors)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PreferenceCategory(stringResource(R.string.preference_category_searchbar)) {
|
||||
val searchBarStyle by viewModel.searchBarStyle.observeAsState()
|
||||
SearchBarStylePreference(
|
||||
title = stringResource(R.string.preference_search_bar_style),
|
||||
summary = stringResource(R.string.preference_search_bar_style_summary),
|
||||
value = searchBarStyle,
|
||||
onValueChanged = {
|
||||
viewModel.setSearchBarStyle(it)
|
||||
}
|
||||
)
|
||||
AnimatedVisibility(searchBarStyle == SearchBarStyle.Transparent) {
|
||||
val searchBarColor by viewModel.searchBarColor.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_search_bar_color),
|
||||
value = searchBarColor,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to SearchBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to SearchBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to SearchBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setSearchBarColor(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
PreferenceCategory(stringResource(R.string.preference_category_system_bars)) {
|
||||
val lightStatusBar by viewModel.statusBarIcons.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_status_bar_icons),
|
||||
value = lightStatusBar,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to SystemBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to SystemBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to SystemBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setLightStatusBar(it)
|
||||
}
|
||||
)
|
||||
val lightNavBar by viewModel.navBarIcons.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_nav_bar_icons),
|
||||
value = lightNavBar,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to SystemBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to SystemBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to SystemBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setLightNavBar(it)
|
||||
}
|
||||
)
|
||||
val hideStatusBar by viewModel.hideStatusBar.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_hide_status_bar),
|
||||
value = hideStatusBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setHideStatusBar(it)
|
||||
}
|
||||
)
|
||||
val hideNavBar by viewModel.hideNavBar.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_hide_nav_bar),
|
||||
value = hideNavBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setHideNavBar(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchBarStylePreference(
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
value: SearchBarSettings.SearchBarStyle?,
|
||||
onValueChanged: (SearchBarSettings.SearchBarStyle) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(title = title, summary = summary, onClick = { showDialog = true })
|
||||
if (showDialog && value != null) {
|
||||
val styles = remember {
|
||||
SearchBarSettings.SearchBarStyle.values()
|
||||
.filter { it != SearchBarSettings.SearchBarStyle.UNRECOGNIZED }
|
||||
}
|
||||
val pagerState = rememberPagerState(styles.indexOf(value))
|
||||
|
||||
var level by remember { mutableStateOf(SearchBarLevel.Resting) }
|
||||
var previewSearchValue by remember { mutableStateOf("") }
|
||||
LaunchedEffect(null) {
|
||||
while (isActive) {
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Active
|
||||
delay(1000)
|
||||
previewSearchValue = "A"
|
||||
delay(100)
|
||||
previewSearchValue = "AB"
|
||||
delay(100)
|
||||
previewSearchValue = "ABC"
|
||||
delay(800)
|
||||
level = SearchBarLevel.Raised
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Resting
|
||||
previewSearchValue = ""
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
showDialog = false
|
||||
onValueChanged(styles[pagerState.currentPage])
|
||||
}) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.ok),
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showDialog = false }) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
text = {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
HorizontalPager(
|
||||
count = styles.size,
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.height(150.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
.background(MaterialTheme.colorScheme.secondary)
|
||||
) {
|
||||
SearchBar(
|
||||
modifier = Modifier.padding(8.dp),
|
||||
level = level,
|
||||
style = styles[it],
|
||||
value = previewSearchValue,
|
||||
onValueChange = {}
|
||||
)
|
||||
}
|
||||
HorizontalPagerIndicator(pagerState = pagerState)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconShapePreference(
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
value: IconSettings.IconShape?,
|
||||
onValueChanged: (IconSettings.IconShape) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(title = title, summary = summary, onClick = { showDialog = true })
|
||||
|
||||
if (showDialog && value != null) {
|
||||
val shapes = remember {
|
||||
IconSettings.IconShape.values()
|
||||
.filter { it != IconSettings.IconShape.UNRECOGNIZED && it != IconSettings.IconShape.EasterEgg }
|
||||
}
|
||||
Dialog(onDismissRequest = { showDialog = false }) {
|
||||
Surface(
|
||||
tonalElevation = 16.dp,
|
||||
shadowElevation = 16.dp,
|
||||
shape = MaterialTheme.shapes.extraLarge,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier.padding(
|
||||
start = 24.dp, end = 24.dp, top = 16.dp, bottom = 8.dp
|
||||
)
|
||||
)
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(96.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp, start = 16.dp, end = 16.dp)
|
||||
) {
|
||||
items(shapes) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
ShapedLauncherIcon(
|
||||
size = 48.dp,
|
||||
icon = {
|
||||
StaticLauncherIcon(
|
||||
foregroundLayer = StaticIconLayer(
|
||||
icon = ContextCompat.getDrawable(
|
||||
context,
|
||||
R.mipmap.ic_launcher_foreground
|
||||
)!!,
|
||||
scale = 1.5f,
|
||||
),
|
||||
backgroundLayer = StaticIconLayer(
|
||||
icon = ColorDrawable(
|
||||
context.getColor(R.color.ic_launcher_background)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onValueChanged(it)
|
||||
showDialog = false
|
||||
},
|
||||
shape = getShape(it)
|
||||
)
|
||||
Text(
|
||||
getShapeName(it) ?: "",
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun getShapeName(shape: IconSettings.IconShape?): String? {
|
||||
return stringResource(
|
||||
when (shape) {
|
||||
IconSettings.IconShape.Triangle -> R.string.preference_icon_shape_triangle
|
||||
IconSettings.IconShape.Hexagon -> R.string.preference_icon_shape_hexagon
|
||||
IconSettings.IconShape.RoundedSquare -> R.string.preference_icon_shape_rounded_square
|
||||
IconSettings.IconShape.Squircle -> R.string.preference_icon_shape_squircle
|
||||
IconSettings.IconShape.Square -> R.string.preference_icon_shape_square
|
||||
IconSettings.IconShape.Pentagon -> R.string.preference_icon_shape_pentagon
|
||||
IconSettings.IconShape.PlatformDefault -> R.string.preference_icon_shape_platform
|
||||
IconSettings.IconShape.Circle -> R.string.preference_icon_shape_circle
|
||||
IconSettings.IconShape.Teardrop -> R.string.preference_icon_shape_teardrop
|
||||
IconSettings.IconShape.Pebble -> R.string.preference_icon_shape_pebble
|
||||
else -> return null
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -62,248 +62,4 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val columnCount = dataStore.data.map { it.grid.columnCount }.asLiveData()
|
||||
fun setColumnCount(columnCount: Int) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setColumnCount(columnCount))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconSize = dataStore.data.map { it.grid.iconSize }.asLiveData()
|
||||
fun setIconSize(iconSize: Int) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setIconSize(iconSize))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val showLabels = dataStore.data.map { it.grid.showLabels }.asLiveData()
|
||||
fun setShowLabels(showLabels: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setShowLabels(showLabels))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dimWallpaper = dataStore.data.map { it.appearance.dimWallpaper }.asLiveData()
|
||||
fun setDimWallpaper(dimWallpaper: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setAppearance(it.appearance.toBuilder().setDimWallpaper(dimWallpaper))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isBlurAvailable(context: Context): Boolean {
|
||||
if (!isAtLeastApiLevel(31)) return false
|
||||
return context.getSystemService<WindowManager>()?.isCrossWindowBlurEnabled == true
|
||||
}
|
||||
|
||||
val blurWallpaper = dataStore.data.map { it.appearance.blurWallpaper }.asLiveData()
|
||||
fun setBlurWallpaper(blurWallpaper: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setAppearance(it.appearance.toBuilder().setBlurWallpaper(blurWallpaper))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun openWallpaperChooser(context: AppCompatActivity) {
|
||||
context.startActivity(Intent.createChooser(Intent(Intent.ACTION_SET_WALLPAPER), null))
|
||||
}
|
||||
|
||||
val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }.asLiveData()
|
||||
fun setSearchBarStyle(searchBarStyle: SearchBarSettings.SearchBarStyle) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSearchBar(
|
||||
it.searchBar.toBuilder()
|
||||
.setSearchBarStyle(searchBarStyle)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconShape = dataStore.data.map { it.icons.shape }.asLiveData()
|
||||
fun setIconShape(iconShape: Settings.IconSettings.IconShape) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setShape(iconShape)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val adaptifyLegacyIcons = dataStore.data.map { it.icons.adaptify }.asLiveData()
|
||||
fun setAdaptifyLegacyIcons(adaptify: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setAdaptify(adaptify)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val themedIcons = dataStore.data.map { it.icons.themedIcons }.asLiveData()
|
||||
fun setThemedIcons(themedIcons: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setThemedIcons(themedIcons)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val forceThemedIcons = dataStore.data.map { it.icons.forceThemed }.asLiveData()
|
||||
fun setForceThemedIcons(forceThemedIcons: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setForceThemed(forceThemedIcons)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installedIconPacks: Flow<List<IconPack>> = iconService.getInstalledIconPacks().map {
|
||||
listOf(
|
||||
IconPack(
|
||||
name = "System",
|
||||
packageName = "",
|
||||
version = "",
|
||||
)
|
||||
) + it
|
||||
}
|
||||
|
||||
val iconPackThemed = dataStore.data.map { it.icons.iconPackThemed }
|
||||
fun setIconPackThemed(iconPackThemed: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons
|
||||
.toBuilder()
|
||||
.setIconPackThemed(iconPackThemed)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconPack = dataStore.data.map { it.icons.iconPack }.asLiveData()
|
||||
fun setIconPack(iconPack: String) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setIconPack(iconPack)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val searchBarColor = dataStore.data.map { it.searchBar.color }.asLiveData()
|
||||
fun setSearchBarColor(color: SearchBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSearchBar(
|
||||
it.searchBar.toBuilder()
|
||||
.setColor(color)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val statusBarIcons = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
|
||||
fun setLightStatusBar(statusBarColor: SystemBarsSettings.SystemBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setStatusBarColor(statusBarColor)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val navBarIcons = dataStore.data.map { it.systemBars.navBarColor }.asLiveData()
|
||||
fun setLightNavBar(navBarColors: SystemBarsSettings.SystemBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setNavBarColor(navBarColors)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }.asLiveData()
|
||||
fun setHideStatusBar(hideStatusBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setHideStatusBar(hideStatusBar)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }.asLiveData()
|
||||
fun setHideNavBar(hideNavBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setHideNavBar(hideNavBar)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,77 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.badges
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.MissingPermissionBanner
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
|
||||
@Composable
|
||||
fun BadgeSettingsScreen() {
|
||||
val viewModel: BadgeSettingsScreenVM = viewModel()
|
||||
val context = LocalContext.current
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_badges)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val notifications by viewModel.notifications.observeAsState()
|
||||
val hasNotificationsPermission by viewModel.hasNotificationsPermission.observeAsState()
|
||||
AnimatedVisibility(hasNotificationsPermission == false) {
|
||||
MissingPermissionBanner(
|
||||
text = stringResource(R.string.missing_permission_notification_badges),
|
||||
onClick = {
|
||||
viewModel.requestNotificationsPermission(context as AppCompatActivity)
|
||||
},
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_notification_badges),
|
||||
summary = stringResource(R.string.preference_notification_badges_summary),
|
||||
enabled = hasNotificationsPermission != false,
|
||||
value = notifications == true && hasNotificationsPermission == true,
|
||||
onValueChanged = {
|
||||
viewModel.setNotifications(it)
|
||||
}
|
||||
)
|
||||
val cloudFiles by viewModel.cloudFiles.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_cloud_badges),
|
||||
summary = stringResource(R.string.preference_cloud_badges_summary),
|
||||
value = cloudFiles == true,
|
||||
onValueChanged = {
|
||||
viewModel.setCloudFiles(it)
|
||||
}
|
||||
)
|
||||
val suspendedApps by viewModel.suspendedApps.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_suspended_badges),
|
||||
summary = stringResource(R.string.preference_suspended_badges_summary),
|
||||
value = suspendedApps == true,
|
||||
onValueChanged = {
|
||||
viewModel.setSuspendedApps(it)
|
||||
}
|
||||
)
|
||||
val shortcuts by viewModel.shortcuts.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_shortcut_badges),
|
||||
summary = stringResource(R.string.preference_shortcut_badges_summary),
|
||||
value = shortcuts == true,
|
||||
onValueChanged = {
|
||||
viewModel.setShortcuts(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.badges
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class BadgeSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
private val permissionsManager: PermissionsManager by inject()
|
||||
|
||||
val hasNotificationsPermission = permissionsManager.hasPermission(PermissionGroup.Notifications).asLiveData()
|
||||
|
||||
val notifications = dataStore.data.map { it.badges.notifications }.asLiveData()
|
||||
fun setNotifications(notifications: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setNotifications(notifications)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun requestNotificationsPermission(context: AppCompatActivity) {
|
||||
permissionsManager.requestPermission(context, PermissionGroup.Notifications)
|
||||
}
|
||||
|
||||
val cloudFiles = dataStore.data.map { it.badges.cloudFiles }.asLiveData()
|
||||
fun setCloudFiles(cloudFiles: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setCloudFiles(cloudFiles)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val shortcuts = dataStore.data.map { it.badges.shortcuts }.asLiveData()
|
||||
fun setShortcuts(shortcuts: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setShortcuts(shortcuts)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val suspendedApps = dataStore.data.map { it.badges.suspendedApps }.asLiveData()
|
||||
fun setSuspendedApps(suspendedApps: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setSuspendedApps(suspendedApps)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,7 @@ import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
@ -35,7 +36,6 @@ import de.mm20.launcher2.ui.common.SearchablePicker
|
||||
import de.mm20.launcher2.ui.component.MissingPermissionBanner
|
||||
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||
import de.mm20.launcher2.ui.component.preferences.ListPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
@ -44,8 +44,8 @@ import de.mm20.launcher2.ui.ktx.toPixels
|
||||
fun GestureSettingsScreen() {
|
||||
val viewModel: GestureSettingsScreenVM = viewModel()
|
||||
|
||||
val layout by viewModel.layout.observeAsState()
|
||||
val hasPermission by viewModel.hasPermission.observeAsState()
|
||||
val layout by viewModel.baseLayout.collectAsStateWithLifecycle(null)
|
||||
val hasPermission by viewModel.hasPermission.collectAsStateWithLifecycle(null)
|
||||
|
||||
val options = buildList {
|
||||
add(stringResource(R.string.gesture_action_none) to GestureAction.None)
|
||||
@ -60,10 +60,26 @@ fun GestureSettingsScreen() {
|
||||
|
||||
val context = LocalContext.current
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_gestures)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val baseLayout by viewModel.baseLayout.collectAsStateWithLifecycle(null)
|
||||
ListPreference(title = stringResource(R.string.preference_layout_open_search),
|
||||
items = listOf(
|
||||
stringResource(R.string.open_search_pull_down) to Layout.PullDown,
|
||||
stringResource(R.string.open_search_swipe_left) to Layout.Pager,
|
||||
stringResource(R.string.open_search_swipe_right) to Layout.PagerReversed,
|
||||
),
|
||||
value = baseLayout,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setBaseLayout(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
val appIconSize = 32.dp.toPixels()
|
||||
PreferenceCategory {
|
||||
val doubleTap by viewModel.doubleTap.observeAsState()
|
||||
val doubleTap by viewModel.doubleTap.collectAsStateWithLifecycle(null)
|
||||
AnimatedVisibility(hasPermission == false && requiresAccessibilityService(doubleTap)) {
|
||||
MissingPermissionBanner(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
@ -86,7 +102,7 @@ fun GestureSettingsScreen() {
|
||||
onAppChanged = { viewModel.setDoubleTapApp(it) }
|
||||
)
|
||||
|
||||
val longPress by viewModel.longPress.observeAsState()
|
||||
val longPress by viewModel.longPress.collectAsStateWithLifecycle(null)
|
||||
AnimatedVisibility(hasPermission == false && requiresAccessibilityService(longPress)) {
|
||||
MissingPermissionBanner(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
@ -109,7 +125,7 @@ fun GestureSettingsScreen() {
|
||||
onAppChanged = { viewModel.setLongPressApp(it) }
|
||||
)
|
||||
|
||||
val swipeDown by viewModel.swipeDown.observeAsState()
|
||||
val swipeDown by viewModel.swipeDown.collectAsStateWithLifecycle(null)
|
||||
val swipeDownIsSearch = layout == Layout.PullDown
|
||||
AnimatedVisibility(hasPermission == false && requiresAccessibilityService(swipeDown) && !swipeDownIsSearch) {
|
||||
MissingPermissionBanner(
|
||||
@ -133,7 +149,7 @@ fun GestureSettingsScreen() {
|
||||
onAppChanged = { viewModel.setSwipeDownApp(it) }
|
||||
)
|
||||
|
||||
val swipeLeft by viewModel.swipeLeft.observeAsState()
|
||||
val swipeLeft by viewModel.swipeLeft.collectAsStateWithLifecycle(null)
|
||||
val swipeLeftIsSearch = layout == Layout.Pager
|
||||
AnimatedVisibility(hasPermission == false && requiresAccessibilityService(swipeLeft) && !swipeLeftIsSearch) {
|
||||
MissingPermissionBanner(
|
||||
@ -157,7 +173,7 @@ fun GestureSettingsScreen() {
|
||||
onAppChanged = { viewModel.setSwipeLeftApp(it) }
|
||||
)
|
||||
|
||||
val swipeRight by viewModel.swipeRight.observeAsState()
|
||||
val swipeRight by viewModel.swipeRight.collectAsStateWithLifecycle(null)
|
||||
val swipeRightIsSearch = layout == Layout.PagerReversed
|
||||
AnimatedVisibility(hasPermission == false && requiresAccessibilityService(swipeRight) && !swipeRightIsSearch) {
|
||||
MissingPermissionBanner(
|
||||
|
||||
@ -10,6 +10,7 @@ import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.GestureSettings.GestureAction
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -27,15 +28,25 @@ class GestureSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val searchableRepository: SearchableRepository by inject()
|
||||
private val iconService: IconService by inject()
|
||||
|
||||
val hasPermission = permissionsManager.hasPermission(PermissionGroup.Accessibility).asLiveData()
|
||||
val hasPermission = permissionsManager.hasPermission(PermissionGroup.Accessibility)
|
||||
|
||||
val layout = dataStore.data.map { it.layout.baseLayout }.asLiveData()
|
||||
val baseLayout = dataStore.data.map { it.layout.baseLayout }
|
||||
|
||||
val swipeDown = dataStore.data.map { it.gestures.swipeDown }.asLiveData()
|
||||
val swipeLeft = dataStore.data.map { it.gestures.swipeLeft }.asLiveData()
|
||||
val swipeRight = dataStore.data.map { it.gestures.swipeRight }.asLiveData()
|
||||
val doubleTap = dataStore.data.map { it.gestures.doubleTap }.asLiveData()
|
||||
val longPress = dataStore.data.map { it.gestures.longPress }.asLiveData()
|
||||
fun setBaseLayout(baseLayout: Settings.LayoutSettings.Layout) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setBaseLayout(baseLayout))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val swipeDown = dataStore.data.map { it.gestures.swipeDown }
|
||||
val swipeLeft = dataStore.data.map { it.gestures.swipeLeft }
|
||||
val swipeRight = dataStore.data.map { it.gestures.swipeRight }
|
||||
val doubleTap = dataStore.data.map { it.gestures.doubleTap }
|
||||
val longPress = dataStore.data.map { it.gestures.longPress }
|
||||
|
||||
fun setSwipeDown(action: GestureAction) {
|
||||
viewModelScope.launch {
|
||||
|
||||
@ -0,0 +1,303 @@
|
||||
package de.mm20.launcher2.ui.settings.homescreen
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.google.accompanist.pager.HorizontalPagerIndicator
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.SearchBar
|
||||
import de.mm20.launcher2.ui.component.SearchBarLevel
|
||||
import de.mm20.launcher2.ui.component.preferences.ListPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
@Composable
|
||||
fun HomescreenSettingsScreen() {
|
||||
val viewModel: HomescreenSettingsScreenVM =
|
||||
viewModel(factory = HomescreenSettingsScreenVM.Factory)
|
||||
|
||||
val navController = LocalNavController.current
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
val fixedRotation by viewModel.fixedRotation.collectAsStateWithLifecycle(null)
|
||||
val editButton by viewModel.widgetEditButton.collectAsStateWithLifecycle(null)
|
||||
val searchBarStyle by viewModel.searchBarStyle.collectAsStateWithLifecycle(null)
|
||||
val searchBarColor by viewModel.searchBarColor.collectAsStateWithLifecycle(null)
|
||||
val bottomSearchBar by viewModel.bottomSearchBar.collectAsStateWithLifecycle(null)
|
||||
val fixedSearchBar by viewModel.fixedSearchBar.collectAsStateWithLifecycle(null)
|
||||
val lightStatusBar by viewModel.statusBarIcons.collectAsStateWithLifecycle(null)
|
||||
val dimWallpaper by viewModel.dimWallpaper.collectAsStateWithLifecycle(false)
|
||||
val blurWallpaper by viewModel.blurWallpaper.collectAsStateWithLifecycle(false)
|
||||
val lightNavBar by viewModel.navBarIcons.collectAsStateWithLifecycle(null)
|
||||
val hideStatusBar by viewModel.hideStatusBar.collectAsStateWithLifecycle(null)
|
||||
val hideNavBar by viewModel.hideNavBar.collectAsStateWithLifecycle(null)
|
||||
|
||||
PreferenceScreen(title = stringResource(id = R.string.preference_screen_homescreen)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_layout_fixed_rotation),
|
||||
summary = stringResource(R.string.preference_layout_fixed_rotation_summary),
|
||||
value = fixedRotation == true,
|
||||
onValueChanged = {
|
||||
viewModel.setFixedRotation(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(
|
||||
title = stringResource(id = R.string.preference_category_widgets)
|
||||
) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_clockwidget),
|
||||
summary = stringResource(R.string.preference_screen_clockwidget_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/homescreen/clock")
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(id = R.string.preference_edit_button),
|
||||
summary = stringResource(id = R.string.preference_widgets_edit_button_summary),
|
||||
value = editButton == true,
|
||||
onValueChanged = {
|
||||
viewModel.setWidgetEditButton(it)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(stringResource(R.string.preference_category_searchbar)) {
|
||||
SearchBarStylePreference(
|
||||
title = stringResource(R.string.preference_search_bar_style),
|
||||
summary = stringResource(R.string.preference_search_bar_style_summary),
|
||||
value = searchBarStyle,
|
||||
onValueChanged = {
|
||||
viewModel.setSearchBarStyle(it)
|
||||
}
|
||||
)
|
||||
AnimatedVisibility(searchBarStyle == Settings.SearchBarSettings.SearchBarStyle.Transparent) {
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_search_bar_color),
|
||||
value = searchBarColor,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to Settings.SearchBarSettings.SearchBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to Settings.SearchBarSettings.SearchBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to Settings.SearchBarSettings.SearchBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setSearchBarColor(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_layout_search_bar_position),
|
||||
items = listOf(
|
||||
stringResource(R.string.search_bar_position_top) to false,
|
||||
stringResource(R.string.search_bar_position_bottom) to true,
|
||||
),
|
||||
value = bottomSearchBar,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setBottomSearchBar(it)
|
||||
},
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_layout_fixed_search_bar),
|
||||
summary = stringResource(R.string.preference_layout_fixed_search_bar_summary),
|
||||
value = fixedSearchBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setFixedSearchBar(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(stringResource(id = R.string.preference_category_wallpaper)) {
|
||||
Preference(
|
||||
title = stringResource(R.string.wallpaper),
|
||||
summary = stringResource(R.string.preference_wallpaper_summary),
|
||||
onClick = {
|
||||
viewModel.openWallpaperChooser(context as AppCompatActivity)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_dim_wallpaper),
|
||||
summary = stringResource(R.string.preference_dim_wallpaper_summary),
|
||||
value = dimWallpaper,
|
||||
onValueChanged = {
|
||||
viewModel.setDimWallpaper(it)
|
||||
}
|
||||
)
|
||||
val isBlurSupported = remember { viewModel.isBlurAvailable(context) }
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_blur_wallpaper),
|
||||
summary = stringResource(
|
||||
if (isBlurSupported) R.string.preference_blur_wallpaper_summary
|
||||
else R.string.preference_blur_wallpaper_unsupported
|
||||
),
|
||||
value = blurWallpaper && isBlurSupported,
|
||||
onValueChanged = {
|
||||
viewModel.setBlurWallpaper(it)
|
||||
},
|
||||
enabled = isBlurSupported
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
|
||||
PreferenceCategory(stringResource(R.string.preference_category_system_bars)) {
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_status_bar_icons),
|
||||
value = lightStatusBar,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to Settings.SystemBarsSettings.SystemBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to Settings.SystemBarsSettings.SystemBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to Settings.SystemBarsSettings.SystemBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setLightStatusBar(it)
|
||||
}
|
||||
)
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_nav_bar_icons),
|
||||
value = lightNavBar,
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_system_bar_icons_auto) to Settings.SystemBarsSettings.SystemBarColors.Auto,
|
||||
stringResource(R.string.preference_system_bar_icons_light) to Settings.SystemBarsSettings.SystemBarColors.Light,
|
||||
stringResource(R.string.preference_system_bar_icons_dark) to Settings.SystemBarsSettings.SystemBarColors.Dark,
|
||||
),
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setLightNavBar(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_hide_status_bar),
|
||||
value = hideStatusBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setHideStatusBar(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_hide_nav_bar),
|
||||
value = hideNavBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setHideNavBar(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchBarStylePreference(
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
value: Settings.SearchBarSettings.SearchBarStyle?,
|
||||
onValueChanged: (Settings.SearchBarSettings.SearchBarStyle) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(title = title, summary = summary, onClick = { showDialog = true })
|
||||
if (showDialog && value != null) {
|
||||
val styles = remember {
|
||||
Settings.SearchBarSettings.SearchBarStyle.values()
|
||||
.filter { it != Settings.SearchBarSettings.SearchBarStyle.UNRECOGNIZED }
|
||||
}
|
||||
val pagerState = rememberPagerState(styles.indexOf(value))
|
||||
|
||||
var level by remember { mutableStateOf(SearchBarLevel.Resting) }
|
||||
var previewSearchValue by remember { mutableStateOf("") }
|
||||
LaunchedEffect(null) {
|
||||
while (isActive) {
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Active
|
||||
delay(1000)
|
||||
previewSearchValue = "A"
|
||||
delay(100)
|
||||
previewSearchValue = "AB"
|
||||
delay(100)
|
||||
previewSearchValue = "ABC"
|
||||
delay(800)
|
||||
level = SearchBarLevel.Raised
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Resting
|
||||
previewSearchValue = ""
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
showDialog = false
|
||||
onValueChanged(styles[pagerState.currentPage])
|
||||
}) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.ok),
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showDialog = false }) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
text = {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
HorizontalPager(
|
||||
pageCount = styles.size,
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.height(150.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
.background(MaterialTheme.colorScheme.secondary)
|
||||
) {
|
||||
SearchBar(
|
||||
modifier = Modifier.padding(8.dp),
|
||||
level = level,
|
||||
style = styles[it],
|
||||
value = previewSearchValue,
|
||||
onValueChange = {}
|
||||
)
|
||||
}
|
||||
HorizontalPagerIndicator(pagerState = pagerState, pageCount = styles.size)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
package de.mm20.launcher2.ui.settings.homescreen
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
|
||||
class HomescreenSettingsScreenVM(
|
||||
private val dataStore: LauncherDataStore,
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
val dimWallpaper = dataStore.data.map { it.appearance.dimWallpaper }
|
||||
fun setDimWallpaper(dimWallpaper: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setAppearance(
|
||||
it.appearance.toBuilder()
|
||||
.setDimWallpaper(dimWallpaper)
|
||||
).build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val blurWallpaper = dataStore.data.map { it.appearance.blurWallpaper }
|
||||
fun setBlurWallpaper(blurWallpaper: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setAppearance(
|
||||
it.appearance.toBuilder()
|
||||
.setBlurWallpaper(blurWallpaper)
|
||||
).build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun openWallpaperChooser(context: AppCompatActivity) {
|
||||
context.startActivity(Intent.createChooser(Intent(Intent.ACTION_SET_WALLPAPER), null))
|
||||
}
|
||||
|
||||
fun isBlurAvailable(context: Context): Boolean {
|
||||
if (!isAtLeastApiLevel(31)) return false
|
||||
return context.getSystemService<WindowManager>()?.isCrossWindowBlurEnabled == true
|
||||
}
|
||||
|
||||
val statusBarIcons = dataStore.data.map { it.systemBars.statusBarColor }
|
||||
fun setLightStatusBar(statusBarColor: Settings.SystemBarsSettings.SystemBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setStatusBarColor(statusBarColor)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val navBarIcons = dataStore.data.map { it.systemBars.navBarColor }
|
||||
fun setLightNavBar(navBarColors: Settings.SystemBarsSettings.SystemBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setNavBarColor(navBarColors)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }
|
||||
fun setHideStatusBar(hideStatusBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setHideStatusBar(hideStatusBar)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }
|
||||
fun setHideNavBar(hideNavBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSystemBars(
|
||||
it.systemBars.toBuilder()
|
||||
.setHideNavBar(hideNavBar)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val searchBarColor = dataStore.data.map { it.searchBar.color }
|
||||
fun setSearchBarColor(color: Settings.SearchBarSettings.SearchBarColors) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSearchBar(
|
||||
it.searchBar.toBuilder()
|
||||
.setColor(color)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }
|
||||
fun setSearchBarStyle(searchBarStyle: Settings.SearchBarSettings.SearchBarStyle) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSearchBar(
|
||||
it.searchBar.toBuilder()
|
||||
.setSearchBarStyle(searchBarStyle)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }
|
||||
fun setFixedSearchBar(fixedSearchBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setFixedSearchBar(fixedSearchBar))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }
|
||||
fun setBottomSearchBar(bottomSearchBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setBottomSearchBar(bottomSearchBar))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fixedRotation = dataStore.data.map { it.layout.fixedRotation }
|
||||
fun setFixedRotation(fixedRotation: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setFixedRotation(fixedRotation))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val widgetEditButton = dataStore.data.map { it.widgets.editButton }
|
||||
fun setWidgetEditButton(editButton: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setWidgets(
|
||||
it.widgets.toBuilder()
|
||||
.setEditButton(editButton)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object : KoinComponent {
|
||||
val Factory = viewModelFactory {
|
||||
initializer {
|
||||
HomescreenSettingsScreenVM(
|
||||
dataStore = get()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,406 @@
|
||||
package de.mm20.launcher2.ui.settings.icons
|
||||
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.FormatPaint
|
||||
import androidx.compose.material3.FilledIconToggleButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.PlainTooltipBox
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.icons.StaticIconLayer
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.MissingPermissionBanner
|
||||
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||
import de.mm20.launcher2.ui.component.getShape
|
||||
import de.mm20.launcher2.ui.component.preferences.ListPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SliderPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.label
|
||||
import de.mm20.launcher2.ui.component.preferences.value
|
||||
|
||||
@Composable
|
||||
fun IconsSettingsScreen() {
|
||||
val viewModel: IconsSettingsScreenVM = viewModel(factory = IconsSettingsScreenVM.Factory)
|
||||
val context = LocalContext.current
|
||||
|
||||
val iconSize by viewModel.iconSize.collectAsStateWithLifecycle(48)
|
||||
val showLabels by viewModel.showLabels.collectAsStateWithLifecycle(null)
|
||||
val columnCount by viewModel.columnCount.collectAsStateWithLifecycle(5)
|
||||
val iconShape by viewModel.iconShape.collectAsStateWithLifecycle(Settings.IconSettings.IconShape.PlatformDefault)
|
||||
val adaptifyLegacyIcons by viewModel.adaptifyLegacyIcons.collectAsStateWithLifecycle(null)
|
||||
val themedIcons by viewModel.themedIcons.collectAsStateWithLifecycle(null)
|
||||
|
||||
val iconPackPackage by viewModel.iconPack.collectAsStateWithLifecycle(null)
|
||||
val iconPackThemed by viewModel.iconPackThemed.collectAsState(true)
|
||||
val installedIconPacks by viewModel.installedIconPacks.collectAsState(emptyList())
|
||||
val forceThemedIcons by viewModel.forceThemedIcons.collectAsStateWithLifecycle(null)
|
||||
|
||||
val hasNotificationsPermission by viewModel.hasNotificationsPermission.collectAsStateWithLifecycle(null)
|
||||
|
||||
val notificationBadges by viewModel.notificationBadges.collectAsStateWithLifecycle(null)
|
||||
val cloudFileBadges by viewModel.cloudFileBadges.collectAsStateWithLifecycle(null)
|
||||
val suspendedAppBadges by viewModel.suspendedAppBadges.collectAsStateWithLifecycle(null)
|
||||
val shortcutBadges by viewModel.shortcutBadges.collectAsStateWithLifecycle(null)
|
||||
|
||||
PreferenceScreen(title = stringResource(id = R.string.preference_screen_icons)) {
|
||||
item {
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_grid)) {
|
||||
SliderPreference(
|
||||
title = stringResource(R.string.preference_grid_icon_size),
|
||||
value = iconSize,
|
||||
step = 8,
|
||||
min = 32,
|
||||
max = 64,
|
||||
onValueChanged = {
|
||||
viewModel.setIconSize(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_grid_labels),
|
||||
summary = stringResource(R.string.preference_grid_labels_summary),
|
||||
value = showLabels == true,
|
||||
onValueChanged = {
|
||||
viewModel.setShowLabels(it)
|
||||
}
|
||||
)
|
||||
SliderPreference(
|
||||
title = stringResource(R.string.preference_grid_column_count),
|
||||
value = columnCount,
|
||||
min = 3,
|
||||
max = 8,
|
||||
onValueChanged = {
|
||||
viewModel.setColumnCount(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(stringResource(R.string.preference_category_icons)) {
|
||||
IconShapePreference(
|
||||
title = stringResource(R.string.preference_icon_shape),
|
||||
summary = getShapeName(iconShape),
|
||||
value = iconShape,
|
||||
onValueChanged = {
|
||||
viewModel.setIconShape(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_enforce_icon_shape),
|
||||
summary = stringResource(R.string.preference_enforce_icon_shape_summary),
|
||||
value = adaptifyLegacyIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setAdaptifyLegacyIcons(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_themed_icons),
|
||||
summary = stringResource(R.string.preference_themed_icons_summary),
|
||||
value = themedIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setThemedIcons(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_force_themed_icons),
|
||||
summary = stringResource(R.string.preference_force_themed_icons_summary),
|
||||
value = forceThemedIcons == true,
|
||||
enabled = themedIcons == true,
|
||||
onValueChanged = {
|
||||
viewModel.setForceThemedIcons(it)
|
||||
}
|
||||
)
|
||||
val iconPack by remember {
|
||||
derivedStateOf { installedIconPacks.firstOrNull { it.packageName == iconPackPackage } }
|
||||
}
|
||||
val items = installedIconPacks.map {
|
||||
it.name to it
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = (Alignment.CenterVertically)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_icon_pack),
|
||||
items = items,
|
||||
summary = if (items.size <= 1) {
|
||||
stringResource(R.string.preference_icon_pack_summary_empty)
|
||||
} else {
|
||||
iconPack?.name ?: "System"
|
||||
},
|
||||
enabled = installedIconPacks.size > 1,
|
||||
value = iconPack,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setIconPack(it.packageName)
|
||||
},
|
||||
itemLabel = {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = it.label,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (it.value?.themed == true) {
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.extraSmall,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.padding(end = 4.dp),
|
||||
imageVector = Icons.Rounded.FormatPaint,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.icon_pack_dynamic_colors),
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (iconPack?.themed == true) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(36.dp)
|
||||
.width(1.dp)
|
||||
.alpha(0.38f)
|
||||
.background(LocalContentColor.current)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(12.dp)
|
||||
) {
|
||||
PlainTooltipBox(tooltip = { Text(stringResource(R.string.icon_pack_dynamic_colors)) }) {
|
||||
FilledIconToggleButton(
|
||||
modifier = Modifier.tooltipAnchor(),
|
||||
checked = iconPackThemed,
|
||||
onCheckedChange = {
|
||||
viewModel.setIconPackThemed(it)
|
||||
}) {
|
||||
Icon(
|
||||
Icons.Rounded.FormatPaint,
|
||||
stringResource(R.string.icon_pack_dynamic_colors)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(
|
||||
title = stringResource(R.string.preference_category_badges),
|
||||
) {
|
||||
AnimatedVisibility(hasNotificationsPermission == false) {
|
||||
MissingPermissionBanner(
|
||||
text = stringResource(R.string.missing_permission_notification_badges),
|
||||
onClick = {
|
||||
viewModel.requestNotificationsPermission(context as AppCompatActivity)
|
||||
},
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_notification_badges),
|
||||
summary = stringResource(R.string.preference_notification_badges_summary),
|
||||
enabled = hasNotificationsPermission != false,
|
||||
value = notificationBadges == true && hasNotificationsPermission == true,
|
||||
onValueChanged = {
|
||||
viewModel.setNotifications(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_cloud_badges),
|
||||
summary = stringResource(R.string.preference_cloud_badges_summary),
|
||||
value = cloudFileBadges == true,
|
||||
onValueChanged = {
|
||||
viewModel.setCloudFiles(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_suspended_badges),
|
||||
summary = stringResource(R.string.preference_suspended_badges_summary),
|
||||
value = suspendedAppBadges == true,
|
||||
onValueChanged = {
|
||||
viewModel.setSuspendedApps(it)
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_shortcut_badges),
|
||||
summary = stringResource(R.string.preference_shortcut_badges_summary),
|
||||
value = shortcutBadges == true,
|
||||
onValueChanged = {
|
||||
viewModel.setShortcuts(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
fun IconShapePreference(
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
value: Settings.IconSettings.IconShape?,
|
||||
onValueChanged: (Settings.IconSettings.IconShape) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(title = title, summary = summary, onClick = { showDialog = true })
|
||||
|
||||
if (showDialog && value != null) {
|
||||
val shapes = remember {
|
||||
Settings.IconSettings.IconShape.values()
|
||||
.filter { it != Settings.IconSettings.IconShape.UNRECOGNIZED && it != Settings.IconSettings.IconShape.EasterEgg }
|
||||
}
|
||||
Dialog(onDismissRequest = { showDialog = false }) {
|
||||
Surface(
|
||||
tonalElevation = 16.dp,
|
||||
shadowElevation = 16.dp,
|
||||
shape = MaterialTheme.shapes.extraLarge,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier.padding(
|
||||
start = 24.dp, end = 24.dp, top = 16.dp, bottom = 8.dp
|
||||
)
|
||||
)
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(96.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp, start = 16.dp, end = 16.dp)
|
||||
) {
|
||||
items(shapes) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
ShapedLauncherIcon(
|
||||
size = 48.dp,
|
||||
icon = {
|
||||
StaticLauncherIcon(
|
||||
foregroundLayer = StaticIconLayer(
|
||||
icon = ContextCompat.getDrawable(
|
||||
context,
|
||||
R.mipmap.ic_launcher_foreground
|
||||
)!!,
|
||||
scale = 1.5f,
|
||||
),
|
||||
backgroundLayer = StaticIconLayer(
|
||||
icon = ColorDrawable(
|
||||
context.getColor(R.color.ic_launcher_background)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onValueChanged(it)
|
||||
showDialog = false
|
||||
},
|
||||
shape = getShape(it)
|
||||
)
|
||||
Text(
|
||||
getShapeName(it) ?: "",
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun getShapeName(shape: Settings.IconSettings.IconShape?): String? {
|
||||
return stringResource(
|
||||
when (shape) {
|
||||
Settings.IconSettings.IconShape.Triangle -> R.string.preference_icon_shape_triangle
|
||||
Settings.IconSettings.IconShape.Hexagon -> R.string.preference_icon_shape_hexagon
|
||||
Settings.IconSettings.IconShape.RoundedSquare -> R.string.preference_icon_shape_rounded_square
|
||||
Settings.IconSettings.IconShape.Squircle -> R.string.preference_icon_shape_squircle
|
||||
Settings.IconSettings.IconShape.Square -> R.string.preference_icon_shape_square
|
||||
Settings.IconSettings.IconShape.Pentagon -> R.string.preference_icon_shape_pentagon
|
||||
Settings.IconSettings.IconShape.PlatformDefault -> R.string.preference_icon_shape_platform
|
||||
Settings.IconSettings.IconShape.Circle -> R.string.preference_icon_shape_circle
|
||||
Settings.IconSettings.IconShape.Teardrop -> R.string.preference_icon_shape_teardrop
|
||||
Settings.IconSettings.IconShape.Pebble -> R.string.preference_icon_shape_pebble
|
||||
else -> return null
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -0,0 +1,229 @@
|
||||
package de.mm20.launcher2.ui.settings.icons
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import de.mm20.launcher2.icons.IconPack
|
||||
import de.mm20.launcher2.icons.IconService
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
|
||||
class IconsSettingsScreenVM(
|
||||
private val dataStore: LauncherDataStore,
|
||||
private val iconService: IconService,
|
||||
private val permissionsManager: PermissionsManager,
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
val columnCount = dataStore.data.map { it.grid.columnCount }
|
||||
fun setColumnCount(columnCount: Int) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setColumnCount(columnCount))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconSize = dataStore.data.map { it.grid.iconSize }
|
||||
fun setIconSize(iconSize: Int) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setIconSize(iconSize))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val showLabels = dataStore.data.map { it.grid.showLabels }
|
||||
fun setShowLabels(showLabels: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setGrid(it.grid.toBuilder().setShowLabels(showLabels))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconShape = dataStore.data.map { it.icons.shape }
|
||||
fun setIconShape(iconShape: Settings.IconSettings.IconShape) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setShape(iconShape)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val adaptifyLegacyIcons = dataStore.data.map { it.icons.adaptify }
|
||||
fun setAdaptifyLegacyIcons(adaptify: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setAdaptify(adaptify)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val themedIcons = dataStore.data.map { it.icons.themedIcons }
|
||||
fun setThemedIcons(themedIcons: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setThemedIcons(themedIcons)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val forceThemedIcons = dataStore.data.map { it.icons.forceThemed }
|
||||
fun setForceThemedIcons(forceThemedIcons: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setForceThemed(forceThemedIcons)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installedIconPacks: Flow<List<IconPack>> = iconService.getInstalledIconPacks().map {
|
||||
listOf(
|
||||
IconPack(
|
||||
name = "System",
|
||||
packageName = "",
|
||||
version = "",
|
||||
)
|
||||
) + it
|
||||
}
|
||||
|
||||
val iconPackThemed = dataStore.data.map { it.icons.iconPackThemed }
|
||||
fun setIconPackThemed(iconPackThemed: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons
|
||||
.toBuilder()
|
||||
.setIconPackThemed(iconPackThemed)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iconPack = dataStore.data.map { it.icons.iconPack }
|
||||
fun setIconPack(iconPack: String) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setIcons(
|
||||
it.icons.toBuilder()
|
||||
.setIconPack(iconPack)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hasNotificationsPermission = permissionsManager.hasPermission(PermissionGroup.Notifications)
|
||||
|
||||
val notificationBadges = dataStore.data.map { it.badges.notifications }
|
||||
fun setNotifications(notifications: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setNotifications(notifications)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun requestNotificationsPermission(context: AppCompatActivity) {
|
||||
permissionsManager.requestPermission(context, PermissionGroup.Notifications)
|
||||
}
|
||||
|
||||
val cloudFileBadges = dataStore.data.map { it.badges.cloudFiles }
|
||||
fun setCloudFiles(cloudFiles: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setCloudFiles(cloudFiles)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val shortcutBadges = dataStore.data.map { it.badges.shortcuts }
|
||||
fun setShortcuts(shortcuts: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setShortcuts(shortcuts)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val suspendedAppBadges = dataStore.data.map { it.badges.suspendedApps }
|
||||
fun setSuspendedApps(suspendedApps: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setBadges(
|
||||
it.badges.toBuilder()
|
||||
.setSuspendedApps(suspendedApps)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object : KoinComponent {
|
||||
val Factory = viewModelFactory {
|
||||
initializer {
|
||||
IconsSettingsScreenVM(
|
||||
dataStore = get(),
|
||||
iconService = get(),
|
||||
permissionsManager = get(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,24 @@
|
||||
package de.mm20.launcher2.ui.settings.accounts
|
||||
package de.mm20.launcher2.ui.settings.integrations
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.LightMode
|
||||
import androidx.compose.material.icons.rounded.PlayCircleOutline
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -31,12 +38,14 @@ import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
|
||||
@Composable
|
||||
fun AccountsSettingsScreen() {
|
||||
val viewModel: AccountsSettingsScreenVM = viewModel()
|
||||
fun IntegrationsSettingsScreen() {
|
||||
val viewModel: IntegrationsSettingsScreenVM = viewModel()
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
val navController = LocalNavController.current
|
||||
|
||||
LaunchedEffect(null) {
|
||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
@ -44,76 +53,91 @@ fun AccountsSettingsScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
val loading by viewModel.loading.observeAsState(true)
|
||||
val owncloudUser by viewModel.owncloudUser
|
||||
val nextcloudUser by viewModel.nextcloudUser
|
||||
val msUser by viewModel.msUser
|
||||
val googleUser by viewModel.googleUser
|
||||
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_services)) {
|
||||
val loading by viewModel.loading
|
||||
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_integrations)) {
|
||||
if (loading) {
|
||||
item {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
return@PreferenceScreen
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_services_nextcloud)) {
|
||||
val account by viewModel.nextcloudUser.observeAsState()
|
||||
Preference(
|
||||
title = if (account != null) {
|
||||
stringResource(R.string.preference_signin_logout)
|
||||
title = stringResource(R.string.preference_weather_integration),
|
||||
icon = Icons.Rounded.LightMode,
|
||||
onClick = {
|
||||
navController?.navigate("settings/integrations/weather")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_media_integration),
|
||||
icon = Icons.Rounded.PlayCircleOutline,
|
||||
onClick = {
|
||||
navController?.navigate("settings/integrations/media")
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(
|
||||
title = stringResource(id = R.string.preference_category_accounts)
|
||||
) {
|
||||
|
||||
Preference(
|
||||
title = if (nextcloudUser != null) {
|
||||
stringResource(R.string.preference_nextcloud)
|
||||
} else {
|
||||
stringResource(R.string.preference_nextcloud_signin)
|
||||
},
|
||||
summary = account?.let {
|
||||
summary = nextcloudUser?.let {
|
||||
stringResource(R.string.preference_signin_user, it.userName)
|
||||
} ?: stringResource(R.string.preference_nextcloud_signin_summary),
|
||||
onClick = {
|
||||
if (account != null) {
|
||||
if (nextcloudUser != null) {
|
||||
viewModel.signOut(AccountType.Nextcloud)
|
||||
} else {
|
||||
viewModel.signIn(context as AppCompatActivity, AccountType.Nextcloud)
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = !loading,
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_services_owncloud)) {
|
||||
val account by viewModel.owncloudUser.observeAsState()
|
||||
|
||||
Preference(
|
||||
title = if (account != null) {
|
||||
stringResource(R.string.preference_signin_logout)
|
||||
title = if (owncloudUser != null) {
|
||||
stringResource(R.string.preference_owncloud)
|
||||
} else {
|
||||
stringResource(R.string.preference_owncloud_signin)
|
||||
},
|
||||
summary = account?.let {
|
||||
summary = owncloudUser?.let {
|
||||
stringResource(R.string.preference_signin_user, it.userName)
|
||||
} ?: stringResource(R.string.preference_owncloud_signin_summary),
|
||||
onClick = {
|
||||
if (account != null) {
|
||||
if (owncloudUser != null) {
|
||||
viewModel.signOut(AccountType.Owncloud)
|
||||
} else {
|
||||
viewModel.signIn(context as AppCompatActivity, AccountType.Owncloud)
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = !loading,
|
||||
)
|
||||
}
|
||||
}
|
||||
if (viewModel.isMicrosoftAvailable) {
|
||||
item {
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_services_microsoft)) {
|
||||
val account by viewModel.msUser.observeAsState()
|
||||
Preference(
|
||||
title = if (account != null) {
|
||||
stringResource(R.string.preference_signin_logout)
|
||||
title = if (msUser != null) {
|
||||
stringResource(R.string.preference_microsoft)
|
||||
} else {
|
||||
stringResource(R.string.preference_ms_signin)
|
||||
},
|
||||
summary = account?.let {
|
||||
summary = msUser?.let {
|
||||
stringResource(R.string.preference_signin_user, it.userName)
|
||||
} ?: stringResource(R.string.preference_ms_signin_summary),
|
||||
onClick = {
|
||||
if (account != null) {
|
||||
if (msUser != null) {
|
||||
viewModel.signOut(AccountType.Microsoft)
|
||||
} else {
|
||||
viewModel.signIn(
|
||||
@ -121,43 +145,36 @@ fun AccountsSettingsScreen() {
|
||||
AccountType.Microsoft
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = !loading,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewModel.isGoogleAvailable) {
|
||||
item {
|
||||
PreferenceCategory(title = stringResource(R.string.preference_category_services_google)) {
|
||||
val account by viewModel.googleUser.observeAsState()
|
||||
if (account == null) {
|
||||
Box(modifier = Modifier
|
||||
.padding(start = 56.dp)
|
||||
.padding(16.dp)) {
|
||||
GoogleSigninButton(
|
||||
Preference(
|
||||
title = if (googleUser != null) {
|
||||
stringResource(R.string.preference_google)
|
||||
} else {
|
||||
stringResource(R.string.preference_google_signin)
|
||||
},
|
||||
summary = googleUser?.let {
|
||||
stringResource(R.string.preference_signin_user, it.userName)
|
||||
} ?: stringResource(R.string.preference_google_signin_summary),
|
||||
onClick = {
|
||||
if (googleUser != null) {
|
||||
viewModel.signOut(AccountType.Google)
|
||||
} else {
|
||||
viewModel.signIn(
|
||||
context as AppCompatActivity,
|
||||
AccountType.Google
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_signin_logout),
|
||||
summary = account?.userName?.let {
|
||||
stringResource(R.string.preference_signin_user, it)
|
||||
},
|
||||
onClick = {
|
||||
viewModel.signOut(AccountType.Google)
|
||||
}
|
||||
enabled = !loading,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -1,6 +1,7 @@
|
||||
package de.mm20.launcher2.ui.settings.accounts
|
||||
package de.mm20.launcher2.ui.settings.integrations
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@ -11,18 +12,18 @@ import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class AccountsSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
class IntegrationsSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val accountsRepository: AccountsRepository by inject()
|
||||
|
||||
val isGoogleAvailable = accountsRepository.isSupported(AccountType.Google)
|
||||
val isMicrosoftAvailable = accountsRepository.isSupported(AccountType.Microsoft)
|
||||
|
||||
val googleUser = MutableLiveData<Account?>(null)
|
||||
val msUser= MutableLiveData<Account?>(null)
|
||||
val nextcloudUser = MutableLiveData<Account?>(null)
|
||||
val owncloudUser = MutableLiveData<Account?>(null)
|
||||
val googleUser = mutableStateOf<Account?>(null)
|
||||
val msUser= mutableStateOf<Account?>(null)
|
||||
val nextcloudUser = mutableStateOf<Account?>(null)
|
||||
val owncloudUser = mutableStateOf<Account?>(null)
|
||||
|
||||
val loading = MutableLiveData(true)
|
||||
val loading = mutableStateOf(true)
|
||||
|
||||
fun onResume() {
|
||||
viewModelScope.launch {
|
||||
@ -1,79 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.layout
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.preferences.Settings.LayoutSettings.Layout
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.ListPreference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
|
||||
@Composable
|
||||
fun LayoutSettingsScreen() {
|
||||
val viewModel: LayoutSettingsScreenVM = viewModel()
|
||||
PreferenceScreen(
|
||||
title = stringResource(id = R.string.preference_layout)
|
||||
) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val baseLayout by viewModel.baseLayout.observeAsState()
|
||||
ListPreference(title = stringResource(R.string.preference_layout_open_search),
|
||||
items = listOf(
|
||||
stringResource(R.string.open_search_pull_down) to Layout.PullDown,
|
||||
stringResource(R.string.open_search_swipe_left) to Layout.Pager,
|
||||
stringResource(R.string.open_search_swipe_right) to Layout.PagerReversed,
|
||||
),
|
||||
value = baseLayout,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setBaseLayout(it)
|
||||
},
|
||||
)
|
||||
val bottomSearchBar by viewModel.bottomSearchBar.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_layout_search_bar_position),
|
||||
items = listOf(
|
||||
stringResource(R.string.search_bar_position_top) to false,
|
||||
stringResource(R.string.search_bar_position_bottom) to true,
|
||||
),
|
||||
value = bottomSearchBar,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setBottomSearchBar(it)
|
||||
},
|
||||
)
|
||||
val fixedSearchBar by viewModel.fixedSearchBar.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_layout_fixed_search_bar),
|
||||
summary = stringResource(R.string.preference_layout_fixed_search_bar_summary),
|
||||
value = fixedSearchBar == true,
|
||||
onValueChanged = {
|
||||
viewModel.setFixedSearchBar(it)
|
||||
},
|
||||
)
|
||||
val reverseSearchResults by viewModel.reverseSearchResults.observeAsState()
|
||||
ListPreference(title = stringResource(R.string.preference_layout_search_results),
|
||||
items = listOf(
|
||||
stringResource(R.string.search_results_order_top_down) to false,
|
||||
stringResource(R.string.search_results_order_bottom_up) to true,
|
||||
),
|
||||
value = reverseSearchResults,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setReverseSearchResults(it)
|
||||
},
|
||||
)
|
||||
val fixedRotation by viewModel.fixedRotation.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_layout_fixed_rotation),
|
||||
summary = stringResource(R.string.preference_layout_fixed_rotation_summary),
|
||||
value = fixedRotation == true,
|
||||
onValueChanged = {
|
||||
viewModel.setFixedRotation(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.layout
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings.LayoutSettings.Layout
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class LayoutSettingsScreenVM: ViewModel(), KoinComponent {
|
||||
|
||||
private val dataStore : LauncherDataStore by inject()
|
||||
|
||||
val baseLayout = dataStore.data.map { it.layout.baseLayout }.asLiveData()
|
||||
fun setBaseLayout(baseLayout: Layout) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setBaseLayout(baseLayout))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }.asLiveData()
|
||||
fun setBottomSearchBar(bottomSearchBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setBottomSearchBar(bottomSearchBar))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }.asLiveData()
|
||||
fun setReverseSearchResults(reverseSearchResults: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setReverseSearchResults(reverseSearchResults))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }.asLiveData()
|
||||
fun setFixedSearchBar(fixedSearchBar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setFixedSearchBar(fixedSearchBar))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val fixedRotation = dataStore.data.map { it.layout.fixedRotation }.asLiveData()
|
||||
fun setFixedRotation(fixedRotation: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setFixedRotation(fixedRotation))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,21 @@
|
||||
package de.mm20.launcher2.ui.settings.main
|
||||
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.AccountBox
|
||||
import androidx.compose.material.icons.rounded.Apps
|
||||
import androidx.compose.material.icons.rounded.BugReport
|
||||
import androidx.compose.material.icons.rounded.Gesture
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material.icons.rounded.Info
|
||||
import androidx.compose.material.icons.rounded.Palette
|
||||
import androidx.compose.material.icons.rounded.Power
|
||||
import androidx.compose.material.icons.rounded.Search
|
||||
import androidx.compose.material.icons.rounded.SettingsBackupRestore
|
||||
import androidx.compose.material.icons.rounded.Widgets
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.icons.NotificationBadge
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
|
||||
@Composable
|
||||
@ -34,6 +34,22 @@ fun MainSettingsScreen() {
|
||||
navController?.navigate("settings/appearance")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.Home,
|
||||
title = stringResource(id = R.string.preference_screen_homescreen),
|
||||
summary = stringResource(id = R.string.preference_screen_homescreen_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/homescreen")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.Apps,
|
||||
title = stringResource(id = R.string.preference_screen_icons),
|
||||
summary = stringResource(id = R.string.preference_screen_icons_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/icons")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.Search,
|
||||
title = stringResource(id = R.string.preference_screen_search),
|
||||
@ -42,14 +58,6 @@ fun MainSettingsScreen() {
|
||||
navController?.navigate("settings/search")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.Widgets,
|
||||
title = stringResource(id = R.string.preference_screen_widgets),
|
||||
summary = stringResource(id = R.string.preference_screen_widgets_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.Gesture,
|
||||
title = stringResource(id = R.string.preference_screen_gestures),
|
||||
@ -59,19 +67,11 @@ fun MainSettingsScreen() {
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.NotificationBadge,
|
||||
title = stringResource(id = R.string.preference_screen_badges),
|
||||
summary = stringResource(id = R.string.preference_screen_badges_summary),
|
||||
icon = Icons.Rounded.Power,
|
||||
title = stringResource(id = R.string.preference_screen_integrations),
|
||||
summary = stringResource(id = R.string.preference_screen_integrations_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/badges")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Rounded.AccountBox,
|
||||
title = stringResource(id = R.string.preference_screen_services),
|
||||
summary = stringResource(id = R.string.preference_screen_services_summary),
|
||||
onClick = {
|
||||
navController?.navigate("settings/accounts")
|
||||
navController?.navigate("settings/integrations")
|
||||
}
|
||||
)
|
||||
Preference(
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package de.mm20.launcher2.ui.settings.musicwidget
|
||||
package de.mm20.launcher2.ui.settings.media
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
@ -20,9 +20,9 @@ import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
|
||||
@Composable
|
||||
fun MusicWidgetSettingsScreen() {
|
||||
fun MediaIntegrationSettingsScreen() {
|
||||
val context = LocalContext.current
|
||||
val viewModel: MusicWidgetSettingsScreenVM = viewModel()
|
||||
val viewModel: MediaIntegrationSettingsScreenVM = viewModel()
|
||||
val hasPermission by viewModel.hasPermission.observeAsState()
|
||||
PreferenceScreen(
|
||||
stringResource(R.string.preference_screen_musicwidget),
|
||||
@ -1,4 +1,4 @@
|
||||
package de.mm20.launcher2.ui.settings.musicwidget
|
||||
package de.mm20.launcher2.ui.settings.media
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.ViewModel
|
||||
@ -13,7 +13,7 @@ import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class MusicWidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
class MediaIntegrationSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val permissionsManager: PermissionsManager by inject()
|
||||
private val musicService: MusicService by inject()
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.ui.R
|
||||
@ -31,7 +32,7 @@ fun SearchSettingsScreen() {
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_search)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val favorites by viewModel.favorites.observeAsState()
|
||||
val favorites by viewModel.favorites.collectAsStateWithLifecycle(null)
|
||||
PreferenceWithSwitch(
|
||||
title = stringResource(R.string.preference_search_favorites),
|
||||
summary = stringResource(R.string.preference_search_favorites_summary),
|
||||
@ -54,7 +55,7 @@ fun SearchSettingsScreen() {
|
||||
}
|
||||
)
|
||||
|
||||
val hasContactsPermission by viewModel.hasContactsPermission.observeAsState()
|
||||
val hasContactsPermission by viewModel.hasContactsPermission.collectAsStateWithLifecycle(null)
|
||||
AnimatedVisibility(hasContactsPermission == false) {
|
||||
MissingPermissionBanner(
|
||||
text = stringResource(R.string.missing_permission_contact_search_settings),
|
||||
@ -64,7 +65,7 @@ fun SearchSettingsScreen() {
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
val contacts by viewModel.contacts.observeAsState()
|
||||
val contacts by viewModel.contacts.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_contacts),
|
||||
summary = stringResource(R.string.preference_search_contacts_summary),
|
||||
@ -76,7 +77,7 @@ fun SearchSettingsScreen() {
|
||||
enabled = hasContactsPermission == true
|
||||
)
|
||||
|
||||
val hasCalendarPermission by viewModel.hasCalendarPermission.observeAsState()
|
||||
val hasCalendarPermission by viewModel.hasCalendarPermission.collectAsStateWithLifecycle(null)
|
||||
AnimatedVisibility(hasCalendarPermission == false) {
|
||||
MissingPermissionBanner(
|
||||
text = stringResource(R.string.missing_permission_calendar_search_settings),
|
||||
@ -86,7 +87,7 @@ fun SearchSettingsScreen() {
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
val calendar by viewModel.calendar.observeAsState()
|
||||
val calendar by viewModel.calendar.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_calendar),
|
||||
summary = stringResource(R.string.preference_search_calendar_summary),
|
||||
@ -98,7 +99,7 @@ fun SearchSettingsScreen() {
|
||||
enabled = hasCalendarPermission == true
|
||||
)
|
||||
|
||||
val hasAppShortcutsPermission by viewModel.hasAppShortcutPermission.observeAsState()
|
||||
val hasAppShortcutsPermission by viewModel.hasAppShortcutPermission.collectAsStateWithLifecycle(null)
|
||||
AnimatedVisibility(hasAppShortcutsPermission == false) {
|
||||
MissingPermissionBanner(
|
||||
text = stringResource(
|
||||
@ -111,7 +112,7 @@ fun SearchSettingsScreen() {
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
val appShortcuts by viewModel.appShortcuts.observeAsState()
|
||||
val appShortcuts by viewModel.appShortcuts.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_appshortcuts),
|
||||
summary = stringResource(R.string.preference_search_appshortcuts_summary),
|
||||
@ -123,7 +124,7 @@ fun SearchSettingsScreen() {
|
||||
enabled = hasAppShortcutsPermission == true
|
||||
)
|
||||
|
||||
val calculator by viewModel.calculator.observeAsState()
|
||||
val calculator by viewModel.calculator.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_calculator),
|
||||
summary = stringResource(R.string.preference_search_calculator_summary),
|
||||
@ -134,7 +135,7 @@ fun SearchSettingsScreen() {
|
||||
}
|
||||
)
|
||||
|
||||
val unitConverter by viewModel.unitConverter.observeAsState()
|
||||
val unitConverter by viewModel.unitConverter.collectAsStateWithLifecycle(null)
|
||||
PreferenceWithSwitch(
|
||||
title = stringResource(R.string.preference_search_unitconverter),
|
||||
summary = stringResource(R.string.preference_search_unitconverter_summary),
|
||||
@ -148,7 +149,7 @@ fun SearchSettingsScreen() {
|
||||
}
|
||||
)
|
||||
|
||||
val wikipedia by viewModel.wikipedia.observeAsState()
|
||||
val wikipedia by viewModel.wikipedia.collectAsStateWithLifecycle(null)
|
||||
PreferenceWithSwitch(
|
||||
title = stringResource(R.string.preference_search_wikipedia),
|
||||
summary = stringResource(R.string.preference_search_wikipedia_summary),
|
||||
@ -162,7 +163,7 @@ fun SearchSettingsScreen() {
|
||||
}
|
||||
)
|
||||
|
||||
val websites by viewModel.websites.observeAsState()
|
||||
val websites by viewModel.websites.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_websites),
|
||||
summary = stringResource(R.string.preference_search_websites_summary),
|
||||
@ -183,43 +184,6 @@ fun SearchSettingsScreen() {
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val autoFocus by viewModel.autoFocus.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_bar_auto_focus),
|
||||
summary = stringResource(R.string.preference_search_bar_auto_focus_summary),
|
||||
icon = Icons.Rounded.Keyboard,
|
||||
value = autoFocus == true,
|
||||
onValueChanged = {
|
||||
viewModel.setAutoFocus(it)
|
||||
}
|
||||
)
|
||||
val launchOnEnter by viewModel.launchOnEnter.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_bar_launch_on_enter),
|
||||
summary = stringResource(R.string.preference_search_bar_launch_on_enter_summary),
|
||||
icon = Icons.Rounded.ArrowRightAlt,
|
||||
value = launchOnEnter == true,
|
||||
onValueChanged = {
|
||||
viewModel.setLaunchOnEnter(it)
|
||||
}
|
||||
)
|
||||
val searchResultOrdering by viewModel.searchResultOrdering.observeAsState()
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_search_result_ordering),
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_search_result_ordering_alphabetic) to Settings.SearchResultOrderingSettings.Ordering.Alphabetic,
|
||||
stringResource(R.string.preference_search_result_ordering_weighted) to Settings.SearchResultOrderingSettings.Ordering.Weighted
|
||||
),
|
||||
value = searchResultOrdering,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setSearchResultOrdering(it)
|
||||
},
|
||||
icon = Icons.Rounded.Sort
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory {
|
||||
Preference(
|
||||
@ -240,5 +204,57 @@ fun SearchSettingsScreen() {
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val autoFocus by viewModel.autoFocus.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_bar_auto_focus),
|
||||
summary = stringResource(R.string.preference_search_bar_auto_focus_summary),
|
||||
icon = Icons.Rounded.Keyboard,
|
||||
value = autoFocus == true,
|
||||
onValueChanged = {
|
||||
viewModel.setAutoFocus(it)
|
||||
}
|
||||
)
|
||||
val launchOnEnter by viewModel.launchOnEnter.collectAsStateWithLifecycle(null)
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_search_bar_launch_on_enter),
|
||||
summary = stringResource(R.string.preference_search_bar_launch_on_enter_summary),
|
||||
value = launchOnEnter == true,
|
||||
onValueChanged = {
|
||||
viewModel.setLaunchOnEnter(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val searchResultOrdering by viewModel.searchResultOrdering.collectAsStateWithLifecycle(null)
|
||||
ListPreference(
|
||||
title = stringResource(R.string.preference_search_result_ordering),
|
||||
items = listOf(
|
||||
stringResource(R.string.preference_search_result_ordering_alphabetic) to Settings.SearchResultOrderingSettings.Ordering.Alphabetic,
|
||||
stringResource(R.string.preference_search_result_ordering_weighted) to Settings.SearchResultOrderingSettings.Ordering.Weighted
|
||||
),
|
||||
value = searchResultOrdering,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setSearchResultOrdering(it)
|
||||
},
|
||||
icon = Icons.Rounded.Sort
|
||||
)
|
||||
|
||||
val reverseSearchResults by viewModel.reverseSearchResults.collectAsStateWithLifecycle(null)
|
||||
ListPreference(title = stringResource(R.string.preference_layout_search_results),
|
||||
items = listOf(
|
||||
stringResource(R.string.search_results_order_top_down) to false,
|
||||
stringResource(R.string.search_results_order_bottom_up) to true,
|
||||
),
|
||||
value = reverseSearchResults,
|
||||
onValueChanged = {
|
||||
if (it != null) viewModel.setReverseSearchResults(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,7 +18,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
private val permissionsManager: PermissionsManager by inject()
|
||||
|
||||
val favorites = dataStore.data.map { it.favorites.enabled }.asLiveData()
|
||||
val favorites = dataStore.data.map { it.favorites.enabled }
|
||||
fun setFavorites(favorites: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -30,8 +30,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
|
||||
|
||||
val hasContactsPermission = permissionsManager.hasPermission(PermissionGroup.Contacts).asLiveData()
|
||||
val contacts = dataStore.data.map { it.contactsSearch.enabled }.asLiveData()
|
||||
val hasContactsPermission = permissionsManager.hasPermission(PermissionGroup.Contacts)
|
||||
val contacts = dataStore.data.map { it.contactsSearch.enabled }
|
||||
fun setContacts(contacts: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -46,8 +46,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
permissionsManager.requestPermission(activity, PermissionGroup.Contacts)
|
||||
}
|
||||
|
||||
val hasCalendarPermission = permissionsManager.hasPermission(PermissionGroup.Calendar).asLiveData()
|
||||
val calendar = dataStore.data.map { it.calendarSearch.enabled }.asLiveData()
|
||||
val hasCalendarPermission = permissionsManager.hasPermission(PermissionGroup.Calendar)
|
||||
val calendar = dataStore.data.map { it.calendarSearch.enabled }
|
||||
fun setCalendar(calendar: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -62,7 +62,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
permissionsManager.requestPermission(activity, PermissionGroup.Calendar)
|
||||
}
|
||||
|
||||
val calculator = dataStore.data.map { it.calculatorSearch.enabled }.asLiveData()
|
||||
val calculator = dataStore.data.map { it.calculatorSearch.enabled }
|
||||
fun setCalculator(calculator: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -73,7 +73,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }.asLiveData()
|
||||
val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }
|
||||
fun setUnitConverter(unitConverter: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -84,7 +84,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }.asLiveData()
|
||||
val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }
|
||||
fun setWikipedia(wikipedia: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -95,7 +95,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val websites = dataStore.data.map { it.websiteSearch.enabled }.asLiveData()
|
||||
val websites = dataStore.data.map { it.websiteSearch.enabled }
|
||||
fun setWebsites(websites: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -106,7 +106,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val webSearch = dataStore.data.map { it.webSearch.enabled }.asLiveData()
|
||||
val webSearch = dataStore.data.map { it.webSearch.enabled }
|
||||
fun setWebSearch(webSearch: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -117,7 +117,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val autoFocus = dataStore.data.map { it.searchBar.autoFocus }.asLiveData()
|
||||
val autoFocus = dataStore.data.map { it.searchBar.autoFocus }
|
||||
fun setAutoFocus(autoFocus: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -128,7 +128,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val launchOnEnter = dataStore.data.map { it.searchBar.launchOnEnter }.asLiveData()
|
||||
val launchOnEnter = dataStore.data.map { it.searchBar.launchOnEnter }
|
||||
fun setLaunchOnEnter(launchOnEnter: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -139,8 +139,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val hasAppShortcutPermission = permissionsManager.hasPermission(PermissionGroup.AppShortcuts).asLiveData()
|
||||
val appShortcuts = dataStore.data.map { it.appShortcutSearch.enabled }.asLiveData()
|
||||
val hasAppShortcutPermission = permissionsManager.hasPermission(PermissionGroup.AppShortcuts)
|
||||
val appShortcuts = dataStore.data.map { it.appShortcutSearch.enabled }
|
||||
fun setAppShortcuts(appShortcuts: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -151,7 +151,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
val searchResultOrdering = dataStore.data.map { it.resultOrdering.ordering }.asLiveData()
|
||||
val searchResultOrdering = dataStore.data.map { it.resultOrdering.ordering }
|
||||
fun setSearchResultOrdering(searchResultOrdering: Settings.SearchResultOrderingSettings.Ordering) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
@ -162,6 +162,18 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }
|
||||
fun setReverseSearchResults(reverseSearchResults: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setLayout(it.layout.toBuilder().setReverseSearchResults(reverseSearchResults))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun requestAppShortcutsPermission(activity: AppCompatActivity) {
|
||||
permissionsManager.requestPermission(activity, PermissionGroup.AppShortcuts)
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package de.mm20.launcher2.ui.settings.weatherwidget
|
||||
package de.mm20.launcher2.ui.settings.weather
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
@ -19,8 +19,8 @@ import de.mm20.launcher2.ui.component.preferences.*
|
||||
import de.mm20.launcher2.weather.WeatherLocation
|
||||
|
||||
@Composable
|
||||
fun WeatherWidgetSettingsScreen() {
|
||||
val viewModel: WeatherWidgetSettingsScreenVM = viewModel()
|
||||
fun WeatherIntegrationSettingsScreen() {
|
||||
val viewModel: WeatherIntegrationSettingsScreenVM = viewModel()
|
||||
val context = LocalContext.current
|
||||
|
||||
PreferenceScreen(
|
||||
@ -1,4 +1,4 @@
|
||||
package de.mm20.launcher2.ui.settings.weatherwidget
|
||||
package de.mm20.launcher2.ui.settings.weather
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.map
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class WeatherWidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
class WeatherIntegrationSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val repository: WeatherRepository by inject()
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
private val permissionsManager: PermissionsManager by inject()
|
||||
@ -75,7 +75,7 @@ class WeatherWidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
if (autoLoc) lastLoc
|
||||
else loc
|
||||
}.collectLatest {
|
||||
this@WeatherWidgetSettingsScreenVM.location.postValue(it)
|
||||
this@WeatherIntegrationSettingsScreenVM.location.postValue(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.widgets
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.widgets.CalendarWidget
|
||||
import de.mm20.launcher2.widgets.FavoritesWidget
|
||||
import de.mm20.launcher2.widgets.MusicWidget
|
||||
import de.mm20.launcher2.widgets.WeatherWidget
|
||||
import de.mm20.launcher2.widgets.WidgetRepository
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class WidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
|
||||
|
||||
private val widgetRepository: WidgetRepository by inject()
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
|
||||
val calendarWidget = widgetRepository.exists(CalendarWidget.Type).asLiveData()
|
||||
val musicWidget = widgetRepository.exists(MusicWidget.Type).asLiveData()
|
||||
val weatherWidget = widgetRepository.exists(WeatherWidget.Type).asLiveData()
|
||||
val favoritesWidget = widgetRepository.exists(FavoritesWidget.Type).asLiveData()
|
||||
val editButton = dataStore.data.map { it.widgets.editButton }.asLiveData()
|
||||
fun setEditButton(editButton: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setWidgets(
|
||||
it.widgets.toBuilder()
|
||||
.setEditButton(editButton)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
package de.mm20.launcher2.ui.settings.widgets
|
||||
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Audiotrack
|
||||
import androidx.compose.material.icons.rounded.LightMode
|
||||
import androidx.compose.material.icons.rounded.Schedule
|
||||
import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.material.icons.rounded.Today
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
|
||||
@Composable
|
||||
fun WidgetsSettingsScreen() {
|
||||
val navController = LocalNavController.current
|
||||
val viewModel: WidgetSettingsScreenVM = viewModel()
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_widgets)) {
|
||||
item {
|
||||
PreferenceCategory {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_clockwidget),
|
||||
icon = Icons.Rounded.Schedule,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/clock")
|
||||
}
|
||||
)
|
||||
|
||||
val weatherWidget by viewModel.weatherWidget.observeAsState()
|
||||
if (weatherWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_weatherwidget),
|
||||
icon = Icons.Rounded.LightMode,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/weather")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val musicWidget by viewModel.musicWidget.observeAsState()
|
||||
if (musicWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_musicwidget),
|
||||
icon = Icons.Rounded.Audiotrack,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/music")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val calendarWidget by viewModel.calendarWidget.observeAsState()
|
||||
if (calendarWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_calendarwidget),
|
||||
icon = Icons.Rounded.Today,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/calendar")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val favoritesWidget by viewModel.favoritesWidget.observeAsState()
|
||||
if (favoritesWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.favorites),
|
||||
icon = Icons.Rounded.Star,
|
||||
onClick = {
|
||||
navController?.navigate("settings/favorites")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val editButton by viewModel.editButton.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(id = R.string.preference_edit_button),
|
||||
summary = stringResource(id = R.string.preference_widgets_edit_button_summary),
|
||||
value = editButton == true,
|
||||
onValueChanged = {
|
||||
viewModel.setEditButton(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,7 +302,7 @@
|
||||
<string name="preference_icon_shape_triangle">Reuleauxův trojúhelník</string>
|
||||
<string name="preference_icon_shape_circle">Kruh</string>
|
||||
<string name="preference_icon_shape_hexagon">Šestihran</string>
|
||||
<string name="preference_screen_services">Služby</string>
|
||||
<string name="preference_screen_integrations">Služby</string>
|
||||
<string name="preference_theme_system">Podle systému</string>
|
||||
<string name="preference_themed_icons">Tématické ikony</string>
|
||||
<string name="preference_themed_icons_summary">Barevné ikony s barevným schématem aplikace</string>
|
||||
@ -310,8 +310,8 @@
|
||||
<string name="preference_category_system_bars">Systémové lišty</string>
|
||||
<string name="preference_hide_status_bar">Skrýt stavovou lištu</string>
|
||||
<string name="preference_hide_nav_bar">Skrýt navigační lištu</string>
|
||||
<string name="preference_screen_services_summary">Spravovat připojené účty a služby</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Spravovat připojené účty a služby</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Přihlášen jako %1$s</string>
|
||||
<string name="preference_signin_logout">Odhlásit se</string>
|
||||
<string name="preference_icon_shape_pentagon">Pentagon</string>
|
||||
@ -321,7 +321,7 @@
|
||||
<string name="preference_blur_wallpaper">Rozmazat pozadí</string>
|
||||
<string name="preference_blur_wallpaper_summary">Použít na pozadí efekt rozmazání</string>
|
||||
<string name="preference_wallpaper_summary">Vybrat pozadí</string>
|
||||
<string name="preference_screen_badges">Puntíky</string>
|
||||
<string name="preference_category_badges">Puntíky</string>
|
||||
<string name="preference_screen_badges_summary">Nastavit puntíky ikon</string>
|
||||
<string name="preference_notification_badges">Puntíky oznámení</string>
|
||||
<string name="preference_notification_badges_summary">Zobrazit puntík u aplikací s nepřečtenými oznámeními</string>
|
||||
@ -330,12 +330,12 @@
|
||||
<string name="preference_cloud_badges">Ikony cloudu</string>
|
||||
<string name="preference_shortcut_badges">Ikony záložek</string>
|
||||
<string name="preference_shortcut_badges_summary">Zobrazit ikonu značící aplikaci, ke které patří záložka</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Přihlásit se pomocí Microsoftu</string>
|
||||
<string name="preference_nextcloud_signin">Přihlásit se k Nextcloudu</string>
|
||||
<string name="preference_nextcloud_signin_summary">Přihlaste se pro prohledání vašeho Nextcloud serveru</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Přihlásit se k Owncloudu</string>
|
||||
<string name="preference_about_telegram">Telegram skupina</string>
|
||||
<string name="preference_about_fdroid">F-Droid repozitář</string>
|
||||
@ -347,7 +347,7 @@
|
||||
<string name="preference_grid_icon_size">Velikost ikon</string>
|
||||
<string name="preference_grid_column_count">Počet sloupců</string>
|
||||
<string name="preference_screen_debug">Ladění</string>
|
||||
<string name="preference_screen_widgets">Widgety</string>
|
||||
<string name="preference_category_widgets">Widgety</string>
|
||||
<string name="preference_screen_weatherwidget">Počasí</string>
|
||||
<string name="preference_screen_musicwidget">Hudba</string>
|
||||
<string name="preference_screen_clockwidget">Hodiny</string>
|
||||
|
||||
@ -87,7 +87,7 @@
|
||||
<string name="file_meta_app_min_sdk">Min-SDK-Version: %1$s</string>
|
||||
<string name="file_meta_location">Ort: %1$s</string>
|
||||
<string name="file_meta_owner">Eigentümer: %1$s</string>
|
||||
<string name="preference_screen_services">Dienste</string>
|
||||
<string name="preference_screen_integrations">Dienste</string>
|
||||
<string name="default_websearch_1_name">Google</string>
|
||||
<string name="default_websearch_2_name">YouTube</string>
|
||||
<string name="default_websearch_3_name">Google Play</string>
|
||||
@ -121,8 +121,8 @@
|
||||
<string name="menu_app_info">App-Info</string>
|
||||
<string name="menu_launch">Starten</string>
|
||||
<string name="menu_open_file">Öffnen</string>
|
||||
<string name="preference_screen_services_summary">Verbundene Accounts und Dienste verwalten</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Verbundene Accounts und Dienste verwalten</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Angemeldet als %1$s</string>
|
||||
<string name="preference_signin_logout">Abmelden</string>
|
||||
<string name="file_type_drawing">Zeichnung</string>
|
||||
@ -206,7 +206,7 @@
|
||||
<string name="preference_wallpaper_summary">Hintergrundbild auswählen</string>
|
||||
<string name="preference_dim_wallpaper">Hintergrund dimmen</string>
|
||||
<string name="preference_dim_wallpaper_summary">Hintergrundbild bei Verwendung von dunklen Designs abdunkeln</string>
|
||||
<string name="preference_screen_badges">Plaketten</string>
|
||||
<string name="preference_category_badges">Plaketten</string>
|
||||
<string name="preference_screen_badges_summary">Symbolplaketten konfigurieren</string>
|
||||
<string name="preference_notification_badges">Benachrichtigungsplaketten</string>
|
||||
<string name="preference_notification_badges_summary">Plaketten für Anwendungen mit ungelesenen Benachrichtigungen anzeigen</string>
|
||||
@ -217,7 +217,7 @@
|
||||
<string name="preference_cloud_badges_summary">Eine Plakette für Dateien, die in einer Cloud gespeichert sind anzeigen</string>
|
||||
<string name="preference_shortcut_badges_summary">Für Shortcuts anzeigen, zu welcher App diese gehören</string>
|
||||
<string name="preference_icon_shape_platform">Systemstandard</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Bei Microsoft anmelden</string>
|
||||
<string name="preference_ms_signin_summary">Anmelden, um OneDrive durchsuchen zu können</string>
|
||||
<string name="preference_nextcloud_signin">Bei Nextcloud anmelden</string>
|
||||
@ -231,11 +231,11 @@
|
||||
<string name="login_flow_continue">Weiter</string>
|
||||
<string name="nextcloud_server_url">Nextcloud-Server-URL</string>
|
||||
<string name="nextcloud_server_url_empty">Server-URL darf nicht leer sein</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="nextcloud_server_invalid_url">Diese URL verweist auf keine gültige Nextcloud-Installation</string>
|
||||
<string name="login_flow_login">Anmelden</string>
|
||||
<string name="owncloud_server_url">Owncloud-Server-URL</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="owncloud_server_invalid_url">Diese URL verweist auf keine gültige Owncloud-Installation</string>
|
||||
<string name="owncloud_password">Passwort</string>
|
||||
<string name="owncloud_username">Benutzername</string>
|
||||
@ -289,7 +289,7 @@
|
||||
<string name="weather_widget_set_location">Standort festlegen</string>
|
||||
<string name="preference_screen_debug">Debug</string>
|
||||
<string name="preference_screen_debug_summary">Werkzeuge zur Fehlerbehebung</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Widgets konfigurieren</string>
|
||||
<string name="preference_screen_weatherwidget">Wetter</string>
|
||||
<string name="preference_screen_musicwidget">Musik</string>
|
||||
|
||||
@ -203,8 +203,8 @@
|
||||
<string name="preference_system_bar_icons_auto">Αυτόματο</string>
|
||||
<string name="preference_system_bar_icons_dark">Σκοτεινό</string>
|
||||
<string name="preference_hide_nav_bar">Απόκρυψη γραμμής πλοήγησης</string>
|
||||
<string name="preference_screen_services_summary">Διαχείριση συνδεδεμένων λογαριασμών και υπηρεσιών</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Διαχείριση συνδεδεμένων λογαριασμών και υπηρεσιών</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_logout">Αποσύνδεση</string>
|
||||
<string name="preference_icon_shape_pentagon">Πεντάγωνο</string>
|
||||
<string name="preference_dim_wallpaper_summary">Σε σκούρα θέματα, σκοτείνιασμα ταπετσαρίας</string>
|
||||
@ -212,24 +212,24 @@
|
||||
<string name="preference_dim_wallpaper">Σκοτείνιασμα ταπετσαρίας</string>
|
||||
<string name="preference_category_wallpaper">Ταπετσαρία</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">Δεν υποστηρίζεται σε αυτήν τη συσκευή</string>
|
||||
<string name="preference_screen_badges">Σήματα</string>
|
||||
<string name="preference_category_badges">Σήματα</string>
|
||||
<string name="preference_screen_badges_summary">Παραμετροποίηση σημάτων εικονιδίων</string>
|
||||
<string name="preference_notification_badges">Σήματα ειδοποιήσεων</string>
|
||||
<string name="preference_suspended_badges">Εφαρμογές σε αναστολή</string>
|
||||
<string name="preference_cloud_badges_summary">Εμφάνιση σήματος για αρχεία που είναι αποθηκευμένα στο cloud</string>
|
||||
<string name="preference_shortcut_badges">Σήματα συντομεύσεων</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_nextcloud_signin">Σύνδεση σε Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Σύνδεση για αναζήτηση σε Nextcloud server</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Σύνδεση σε Owncloud</string>
|
||||
<string name="preference_about_telegram">Ομάδα Telegram</string>
|
||||
<string name="preference_about_license_summary">Άδεια χρήσης υπό την άδεια GNU General Public License 3.0</string>
|
||||
<string name="preference_grid_labels">Εμφάνιση ταμπελών</string>
|
||||
<string name="preference_screen_debug">Αποσφαλμάτωση</string>
|
||||
<string name="preference_screen_debug_summary">Εργαλεία αντιμετώπισης προβλημάτων</string>
|
||||
<string name="preference_screen_widgets">Γραφικά στοιχεία</string>
|
||||
<string name="preference_category_widgets">Γραφικά στοιχεία</string>
|
||||
<string name="preference_screen_musicwidget">Μουσική</string>
|
||||
<string name="preference_screen_clockwidget">Ρολόι</string>
|
||||
<string name="preference_clockwidget_layout">Διάταξη</string>
|
||||
@ -424,7 +424,7 @@
|
||||
<string name="preference_enforce_icon_shape_summary">Εφαρμογή σχήματος σε όλα τα εικονίδια, συμπεριλαμβανομένων εκείνων που κανονικά δεν θα το υποστήριζαν</string>
|
||||
<string name="preference_icon_shape_hexagon">Εξάγωνο</string>
|
||||
<string name="preference_category_license">Άδεια χρήσης</string>
|
||||
<string name="preference_screen_services">Υπηρεσίες</string>
|
||||
<string name="preference_screen_integrations">Υπηρεσίες</string>
|
||||
<string name="preference_about_license">Αυτή η εφαρμογή αποτελεί ελεύθερο λογισμικό.</string>
|
||||
<string name="preference_themed_icons">Θεματικά εικονίδια</string>
|
||||
<string name="preference_category_grid">Πλέγμα</string>
|
||||
|
||||
@ -162,7 +162,7 @@
|
||||
<string name="preference_cards_corner_radius">Radio de esquina</string>
|
||||
<string name="preference_cards_opacity">Opacidad</string>
|
||||
<string name="preference_category_searchbar">Barra de búsqueda</string>
|
||||
<string name="preference_screen_services">Servicios</string>
|
||||
<string name="preference_screen_integrations">Servicios</string>
|
||||
<plurals name="calendar_widget_running_events">
|
||||
<item quantity="one">+%1$d evento en ejecución de días anteriores</item>
|
||||
<item quantity="many">+%1$d eventos en ejecución de días anteriores</item>
|
||||
@ -234,8 +234,8 @@
|
||||
<string name="preference_widgets_edit_button_summary">Mostar botón para añadir, eliminar y reordenar widgets</string>
|
||||
<string name="battery_part_charging">Cargando</string>
|
||||
<string name="preference_icon_pack">Paquete de iconos</string>
|
||||
<string name="preference_screen_badges">Insignias</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_category_badges">Insignias</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_nextcloud_signin">Registrarse a NextCloud</string>
|
||||
<string name="preference_ms_signin_summary">Registrate para buscar en OneDrive</string>
|
||||
<string name="preference_logs_summary">Visualizar y exportar registros de aplicación</string>
|
||||
@ -248,14 +248,14 @@
|
||||
<string name="create_search_action_type_web">Buscar en internet</string>
|
||||
<string name="search_action_app">Aplicación</string>
|
||||
<string name="icon_picker_title">Elija icono</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Registrarse a Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Registrate para buscar en tu server Owncloud</string>
|
||||
<string name="preference_about_fdroid">Repositorio de F-Droid</string>
|
||||
<string name="preference_enforce_icon_shape">Forzar forma</string>
|
||||
<string name="preference_themed_icons_summary">Iconos con esquema de color de la aplicación</string>
|
||||
<string name="preference_category_system_bars">Barras de sistema</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_icon_shape_pentagon">Pentágono</string>
|
||||
<string name="preference_clockwidget_layout_horizontal">Compacto</string>
|
||||
<string name="preference_clock_widget_style">Estilo</string>
|
||||
@ -299,7 +299,7 @@
|
||||
<string name="preference_system_bar_icons_auto">Auto</string>
|
||||
<string name="preference_system_bar_icons_light">Claro</string>
|
||||
<string name="preference_system_bar_icons_dark">Oscuro</string>
|
||||
<string name="preference_screen_services_summary">Administrar cuentas y servicios conectados</string>
|
||||
<string name="preference_screen_integrations_summary">Administrar cuentas y servicios conectados</string>
|
||||
<string name="preference_signin_logout">Cerrar sesión</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">No soportado en este dispositivo</string>
|
||||
<string name="preference_suspended_badges_summary">Mostrar una insignia en aplicaciones suspendidas</string>
|
||||
@ -316,7 +316,7 @@
|
||||
<string name="preference_grid_labels">Mostrar etiquetas</string>
|
||||
<string name="preference_grid_labels_summary">Mostrar el nombre de la aplicación debajo del icono</string>
|
||||
<string name="preference_screen_debug">Depuración</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_weatherwidget">Tiempo</string>
|
||||
<string name="preference_screen_clockwidget">Reloj</string>
|
||||
<string name="preference_clock_widget_style_summary">Selecciona un reloj</string>
|
||||
@ -413,7 +413,7 @@
|
||||
<string name="preference_search_bar_auto_focus_summary">Mostrar el teclado automáticamente al abrir la búsqueda</string>
|
||||
<string name="preference_ms_signin">Registrarse con Microsoft</string>
|
||||
<string name="preference_hidden_items_summary">Administrar aplicaciones y resultados de búsqueda ocultos</string>
|
||||
<string name="preference_category_services_nextcloud">NextCloud</string>
|
||||
<string name="preference_nextcloud">NextCloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Registrate para buscar en tu servidor NextCloud</string>
|
||||
<string name="no_account_owncloud">Aun no te has conectado a una cuenta de Owncloud</string>
|
||||
<string name="preference_about_license">Esta aplicación es software libre.</string>
|
||||
|
||||
@ -115,7 +115,7 @@
|
||||
<string name="file_meta_app_min_sdk">Version min du SDK : %1$s</string>
|
||||
<string name="file_meta_location">Position : %1$s</string>
|
||||
<string name="file_meta_owner">Propriétaire : %1$s</string>
|
||||
<string name="preference_screen_services">Services</string>
|
||||
<string name="preference_screen_integrations">Services</string>
|
||||
<string name="preference_theme_system">Suivre le système</string>
|
||||
<string name="default_websearch_1_name">Google</string>
|
||||
<string name="default_websearch_2_name">YouTube</string>
|
||||
@ -150,8 +150,8 @@
|
||||
<string name="menu_favorites_unpin">Retirer des favoris</string>
|
||||
<string name="menu_back">Retour</string>
|
||||
<string name="menu_app_info">Infos sur l\'appli</string>
|
||||
<string name="preference_screen_services_summary">Gérer les comptes et les services</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Gérer les comptes et les services</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Connecté en tant que %1$s</string>
|
||||
<string name="preference_signin_logout">Se déconnecter</string>
|
||||
<string name="preference_summary_not_logged_in">Vous n\'êtes pas connecté</string>
|
||||
@ -189,7 +189,7 @@
|
||||
<string name="preference_dim_wallpaper">Assombrir le fond d\'écran</string>
|
||||
<string name="preference_dim_wallpaper_summary">Assombrir le fond d\'écran en thème sombre</string>
|
||||
<string name="preference_wallpaper_summary">Choisir un fond d\'écran</string>
|
||||
<string name="preference_screen_badges">Badges</string>
|
||||
<string name="preference_category_badges">Badges</string>
|
||||
<string name="preference_screen_badges_summary">Configurer les badges d\'icône</string>
|
||||
<string name="preference_notification_badges">Badges de notification</string>
|
||||
<string name="preference_notification_badges_summary">Afficher un badge pour les applications avec des notifications non-lues</string>
|
||||
@ -200,7 +200,7 @@
|
||||
<string name="preference_shortcut_badges">Badges de raccourcis</string>
|
||||
<string name="preference_shortcut_badges_summary">Afficher un badge qui indique à quelle application le raccourci appartient</string>
|
||||
<string name="preference_icon_shape_platform">Suivre le système</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Se connecter avec Microsoft</string>
|
||||
<string name="preference_ms_signin_summary">Se connecter pour rechercher dans OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">Se connecter avec Nextcloud</string>
|
||||
@ -214,10 +214,10 @@
|
||||
<string name="login_flow_continue">Suivant</string>
|
||||
<string name="nextcloud_server_url">URL du serveur Nextcloud</string>
|
||||
<string name="nextcloud_server_url_empty">L\'URL ne peut pas être vide</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="nextcloud_server_invalid_url">Cette URL ne dirige pas vers une installation Nextcloud valide</string>
|
||||
<string name="owncloud_server_url">URL du serveur Owncloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="owncloud_server_invalid_url">Cette URL ne dirige pas vers une installation Owncloud valide</string>
|
||||
<string name="owncloud_password">Mot de passe</string>
|
||||
<string name="owncloud_username">Nom d\'utilisateur</string>
|
||||
@ -317,7 +317,7 @@
|
||||
<string name="weather_widget_set_location">Définir la position</string>
|
||||
<string name="preference_screen_debug">Débogage</string>
|
||||
<string name="preference_screen_debug_summary">Outils de débogage</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Configurer les widgets</string>
|
||||
<string name="preference_screen_weatherwidget">Météo</string>
|
||||
<string name="preference_screen_musicwidget">Musique</string>
|
||||
|
||||
@ -253,7 +253,7 @@
|
||||
<string name="preference_icon_shape_circle">Cerchio</string>
|
||||
<string name="preference_icon_shape_hexagon">Esagono</string>
|
||||
<string name="preference_category_searchbar">Barra di ricerca</string>
|
||||
<string name="preference_screen_services">Servizi</string>
|
||||
<string name="preference_screen_integrations">Servizi</string>
|
||||
<string name="preference_theme_system">Segui sistema</string>
|
||||
<string name="preference_themed_icons">Icone a tema</string>
|
||||
<string name="preference_icon_pack_summary_empty">Nessun pacchetto icone installato</string>
|
||||
@ -261,8 +261,8 @@
|
||||
<string name="preference_category_system_bars">Barre di sistema</string>
|
||||
<string name="preference_icon_shape_triangle">Triangolo di Reuleaux</string>
|
||||
<string name="preference_hide_nav_bar">Nascondi barra di navigazione</string>
|
||||
<string name="preference_screen_services_summary">Gestisce account e servizi connessi</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Gestisce account e servizi connessi</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Accesso eseguito come %1$s</string>
|
||||
<string name="preference_signin_logout">Esci</string>
|
||||
<string name="preference_icon_shape_pentagon">Pentagono</string>
|
||||
@ -272,19 +272,19 @@
|
||||
<string name="preference_wallpaper_summary">Scegli uno sfondo</string>
|
||||
<string name="preference_screen_badges_summary">Configura indicatori icona</string>
|
||||
<string name="preference_notification_badges">Indicatori notifica</string>
|
||||
<string name="preference_screen_badges">Indicatori</string>
|
||||
<string name="preference_category_badges">Indicatori</string>
|
||||
<string name="preference_suspended_badges_summary">Mostra un indicatore per le applicazioni sospese</string>
|
||||
<string name="preference_suspended_badges">App sospese</string>
|
||||
<string name="preference_cloud_badges">Indicatori cloud</string>
|
||||
<string name="preference_cloud_badges_summary">Mostra un indicatore per i file archiviati in un cloud</string>
|
||||
<string name="preference_shortcut_badges">Indicatori scorciatoie</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Accedi a Microsoft</string>
|
||||
<string name="preference_ms_signin_summary">Accedi per cercare su OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">Accedi a Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Accedi per cercare sul tuo server Nextcloud</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Accedi a Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Accedi per cercare sul tuo server Owncloud</string>
|
||||
<string name="preference_about_telegram">Gruppo Telegram</string>
|
||||
@ -294,7 +294,7 @@
|
||||
<string name="preference_grid_column_count">Numero colonne</string>
|
||||
<string name="preference_screen_debug">Debug</string>
|
||||
<string name="preference_screen_debug_summary">Strumenti di risoluzione dei problemi</string>
|
||||
<string name="preference_screen_widgets">Widget</string>
|
||||
<string name="preference_category_widgets">Widget</string>
|
||||
<string name="preference_screen_widgets_summary">Configura widget</string>
|
||||
<string name="preference_screen_weatherwidget">Meteo</string>
|
||||
<string name="preference_screen_musicwidget">Musica</string>
|
||||
|
||||
@ -289,7 +289,7 @@
|
||||
<string name="preference_icon_shape_rounded_square">Afgerond vierkant</string>
|
||||
<string name="preference_icon_shape_squircle">Squircle</string>
|
||||
<string name="preference_category_searchbar">Zoekbalk</string>
|
||||
<string name="preference_screen_services">Diensten</string>
|
||||
<string name="preference_screen_integrations">Diensten</string>
|
||||
<string name="edit_favorites_dialog_empty_section">Sleep items naar hier</string>
|
||||
<string name="preference_themed_icons">Iconen met thema</string>
|
||||
<string name="preference_themed_icons_summary">Kleur pictogrammen met het kleurenschema van de toepassing</string>
|
||||
@ -306,8 +306,8 @@
|
||||
<string name="preference_force_themed_icons_summary">Pas het kleurenschema toe op alle iconen, ook wanneer deze dat niet ondersteunen (niet aanbevolen)</string>
|
||||
<string name="preference_icon_pack_summary_empty">Geen pictogrammenpakketten geïnstalleerd</string>
|
||||
<string name="preference_hide_nav_bar">Navigatiebalk verbergen</string>
|
||||
<string name="preference_screen_services_summary">Verbonden accounts en diensten beheren</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Verbonden accounts en diensten beheren</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Ingelogd als %1$s</string>
|
||||
<string name="preference_signin_logout">Uitloggen</string>
|
||||
<string name="preference_dim_wallpaper">Achtergrond dimmen</string>
|
||||
@ -316,7 +316,7 @@
|
||||
<string name="preference_blur_wallpaper_summary">Vervaag de achtergrond</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">Niet ondersteund op dit apparaat</string>
|
||||
<string name="preference_wallpaper_summary">Kies een achtergrond</string>
|
||||
<string name="preference_screen_badges">Badges</string>
|
||||
<string name="preference_category_badges">Badges</string>
|
||||
<string name="preference_screen_badges_summary">Configureer pictogrambadges</string>
|
||||
<string name="preference_notification_badges">Meldingsstipjes</string>
|
||||
<string name="preference_notification_badges_summary">Toon een badge voor applicaties met ongelezen meldingen</string>
|
||||
@ -326,13 +326,13 @@
|
||||
<string name="preference_cloud_badges_summary">Toon een badge voor bestanden in de cloud</string>
|
||||
<string name="preference_shortcut_badges">Snelkoppelingbadges</string>
|
||||
<string name="preference_shortcut_badges_summary">Toon een badge om te tonen tot welke applicatie een snelkoppeling behoort</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Inloggen met Microsoft</string>
|
||||
<string name="preference_ms_signin_summary">Log in om OneDrive te doorzoeken</string>
|
||||
<string name="preference_nextcloud_signin">Inloggen bij Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Log in om jouw Nextcloudserver te doorzoeken</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Inloggen bij Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Log in om jouw Owncloudserver te doorzoeken</string>
|
||||
<string name="preference_about_telegram">Telegramgroep</string>
|
||||
@ -362,7 +362,7 @@
|
||||
<string name="preference_grid_labels_summary">Applicatienaam onder pictrogram tonen</string>
|
||||
<string name="preference_screen_debug">Foutopsporing</string>
|
||||
<string name="preference_screen_debug_summary">Hulpmiddelen</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Widgets configureren</string>
|
||||
<string name="preference_screen_weatherwidget">Weer</string>
|
||||
<string name="preference_clock_widget_fill_height_summary">Extra witruimte toevoegen boven de klok om de volledige schermhoogte te vullen</string>
|
||||
|
||||
@ -177,11 +177,11 @@
|
||||
<string name="preference_icon_shape_square">Kwadrat</string>
|
||||
<string name="preference_icon_shape_rounded_square">Zaokrąglony kwadrat</string>
|
||||
<string name="preference_icon_shape_hexagon">Heksagon</string>
|
||||
<string name="preference_screen_services">Usługi</string>
|
||||
<string name="preference_screen_integrations">Usługi</string>
|
||||
<string name="preference_icon_pack">Paczka ikon</string>
|
||||
<string name="preference_icon_pack_summary_empty">Brak zainstalowanych paczek ikon</string>
|
||||
<string name="preference_category_system_bars">Paski systemowe</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Zalogowany jako %1$s</string>
|
||||
<string name="preference_signin_logout">Wyloguj się</string>
|
||||
<string name="preference_summary_not_logged_in">Nie jesteś zalogowany</string>
|
||||
@ -192,7 +192,7 @@
|
||||
<string name="preference_wallpaper_summary">Wybierz tapetę</string>
|
||||
<string name="preference_ms_signin">Zaloguj się z Microsoft</string>
|
||||
<string name="preference_nextcloud_signin">Zaloguj się do Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Zaloguj się do Owncloud</string>
|
||||
<string name="preference_about_telegram">Grupa Telegram</string>
|
||||
<string name="preference_about_fdroid">Repozytorium F-Droid</string>
|
||||
@ -203,7 +203,7 @@
|
||||
<string name="preference_grid_column_count">Liczba kolumn</string>
|
||||
<string name="preference_screen_debug">Debug</string>
|
||||
<string name="preference_screen_debug_summary">Narzędzia do rozwiązywania problemów</string>
|
||||
<string name="preference_screen_widgets">Widżety</string>
|
||||
<string name="preference_category_widgets">Widżety</string>
|
||||
<string name="preference_screen_widgets_summary">Konfiguruj widżety</string>
|
||||
<string name="preference_screen_weatherwidget">Pogoda</string>
|
||||
<string name="preference_screen_musicwidget">Muzyka</string>
|
||||
@ -271,7 +271,7 @@
|
||||
<string name="error_activity_not_found">Nie można otworzyć %1$s</string>
|
||||
<string name="preference_search_gdrive_summary">Szukaj plików na Dysku Google użytkownika %1$s</string>
|
||||
<string name="default_websearch_2_name">YouTube</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_license">Licencja</string>
|
||||
<string name="default_websearch_3_url">https://play.google.com/store/search\?q=${1}</string>
|
||||
<string name="preference_about_license_summary">Licencjonowana pod GNU General Public License 3.0</string>
|
||||
@ -303,7 +303,7 @@
|
||||
<string name="no_account_owncloud">Konto Owncloud nie zostało jeszcze połączone</string>
|
||||
<string name="weather_details_precipitation">Opad atmosferyczny: %1$s</string>
|
||||
<string name="shortcut_summary">Z %1$s</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="weather_no_data">Brak dostępnych informacji o pogodzie.</string>
|
||||
<string name="nextcloud_server_url">Adres URL serwera Nextcloud</string>
|
||||
<string name="weather_widget_set_location">Ustaw lokalizację</string>
|
||||
@ -325,7 +325,7 @@
|
||||
<string name="preference_icon_shape_circle">Okrąg</string>
|
||||
<string name="preference_imperial_units_summary">Użyj stopni Fahrenheit\'a oraz mil na godzinę</string>
|
||||
<string name="preference_category_searchbar">Pasek wyszukiwania</string>
|
||||
<string name="preference_screen_services_summary">Zarządzaj połączonymi kontami i usługami</string>
|
||||
<string name="preference_screen_integrations_summary">Zarządzaj połączonymi kontami i usługami</string>
|
||||
<string name="preference_ms_signin_summary">Zaloguj się, aby móc przeszukiwać OneDrive</string>
|
||||
<string name="preference_nextcloud_signin_summary">Zaloguj się, aby móc przeszukiwać twój serwer Nextcloud</string>
|
||||
<string name="preference_search_currencyconverter_summary">Cyklicznie pobieraj kurs walut do konwersji walut</string>
|
||||
@ -381,7 +381,7 @@
|
||||
<string name="missing_permission_appshortcuts_search">Ustaw %1$s jako domyślną aplikację ekranu głownego do wyszukiwania skrótów aplikacji.</string>
|
||||
<string name="preference_layout_fixed_rotation">Ustalony obrót ekranu</string>
|
||||
<string name="preference_layout_fixed_rotation_summary">Wymuś tryb portretowy</string>
|
||||
<string name="preference_screen_badges">Plakietki</string>
|
||||
<string name="preference_category_badges">Plakietki</string>
|
||||
<string name="preference_enforce_icon_shape">Wymuś kształt</string>
|
||||
<string name="preference_enforce_icon_shape_summary">Zastosuj kształt do wszystkich ikon, również do tych, które normalnie by go nie obsługiwały</string>
|
||||
<string name="preference_grid_labels">Pokaż etykiety</string>
|
||||
|
||||
@ -207,10 +207,10 @@
|
||||
<string name="preference_screen_appearance">Aparência</string>
|
||||
<string name="preference_dim_wallpaper">Escurecer papel de parede</string>
|
||||
<string name="preference_wallpaper_summary">Escolher o papel de parede</string>
|
||||
<string name="preference_screen_badges">Selos</string>
|
||||
<string name="preference_category_badges">Selos</string>
|
||||
<string name="preference_screen_badges_summary">Configurar os selos dos ícones</string>
|
||||
<string name="preference_notification_badges">Selos de notificação</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_category_wallpaper">Papel de parede</string>
|
||||
<string name="preference_about_telegram">Grupo do Telegram</string>
|
||||
<string name="battery_part_charging">Carregando</string>
|
||||
@ -277,8 +277,8 @@
|
||||
<string name="preference_category_system_bars">Barras do sistema</string>
|
||||
<string name="preference_hide_status_bar">Ocultar a barra de status</string>
|
||||
<string name="preference_hide_nav_bar">Ocultar a barra de navegação</string>
|
||||
<string name="preference_screen_services_summary">Gerenciar as contas e serviços conectados</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Gerenciar as contas e serviços conectados</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Autenticado como %1$s</string>
|
||||
<string name="preference_signin_logout">Desconectar</string>
|
||||
<string name="preference_summary_not_logged_in">Você não está logado</string>
|
||||
@ -287,8 +287,8 @@
|
||||
<string name="preference_ms_signin_summary">Entrar para pesquisar no OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">Entrar com Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Entrar para pesquisar no seu servidor Nextcloud</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Entrar para pesquisar no seu servidor Owncloud</string>
|
||||
<string name="preference_about_fdroid">Repositório F-Droid</string>
|
||||
<string name="preference_category_license">Licença</string>
|
||||
@ -298,7 +298,7 @@
|
||||
<string name="preference_grid_column_count">Número de colunas</string>
|
||||
<string name="preference_screen_debug">Depuração</string>
|
||||
<string name="preference_screen_debug_summary">Ferramentas de solução de problemas</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Configurar widgets</string>
|
||||
<string name="preference_screen_weatherwidget">Clima</string>
|
||||
<string name="preference_screen_musicwidget">Música</string>
|
||||
@ -380,7 +380,7 @@
|
||||
<string name="preference_icon_shape_circle">Círculo</string>
|
||||
<string name="preference_icon_shape_teardrop">Lágrima</string>
|
||||
<string name="preference_category_searchbar">Barra de pesquisa</string>
|
||||
<string name="preference_screen_services">Serviços</string>
|
||||
<string name="preference_screen_integrations">Serviços</string>
|
||||
<string name="preference_themed_icons_summary">Colore os Ícones com o esquema de cores do aplicativo</string>
|
||||
<string name="preference_force_themed_icons">Forçar ícones temáticos</string>
|
||||
<string name="preference_blur_wallpaper_summary">Usa efeito de desfoque no papel de parede</string>
|
||||
|
||||
@ -240,7 +240,7 @@
|
||||
<string name="preference_icon_shape_circle">Cerc</string>
|
||||
<string name="preference_icon_shape_hexagon">Hexagon</string>
|
||||
<string name="preference_category_searchbar">Bară de căutare</string>
|
||||
<string name="preference_screen_services">Servicii</string>
|
||||
<string name="preference_screen_integrations">Servicii</string>
|
||||
<string name="preference_theme_system">Urmează sistemul</string>
|
||||
<string name="preference_themed_icons">Pictograme tematice</string>
|
||||
<string name="preference_icon_pack">Pachet de pictograme</string>
|
||||
@ -248,7 +248,7 @@
|
||||
<string name="preference_category_system_bars">Bare de sistem</string>
|
||||
<string name="preference_hide_status_bar">Ascunde bara de stare</string>
|
||||
<string name="preference_hide_nav_bar">Ascunde bara de navigare</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Conectat ca %1$s</string>
|
||||
<string name="preference_signin_logout">Deconectare</string>
|
||||
<string name="preference_summary_not_logged_in">În prezent, nu sunteți conectat</string>
|
||||
@ -256,20 +256,20 @@
|
||||
<string name="preference_category_wallpaper">Tapet</string>
|
||||
<string name="preference_dim_wallpaper_summary">La teme întunecate, tapet întunecat</string>
|
||||
<string name="preference_wallpaper_summary">Alege un tapet</string>
|
||||
<string name="preference_screen_badges">Insigne</string>
|
||||
<string name="preference_category_badges">Insigne</string>
|
||||
<string name="preference_screen_badges_summary">Configurarea insignelor pictogramelor</string>
|
||||
<string name="preference_suspended_badges">Aplicații suspendate</string>
|
||||
<string name="preference_cloud_badges">Insigne cloud</string>
|
||||
<string name="preference_shortcut_badges">Insigne de scurtătură</string>
|
||||
<string name="preference_shortcut_badges_summary">Afișarea unei insigne care indică aplicația căreia îi aparține o scurtătură</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_dim_wallpaper">Întunecă tapetul</string>
|
||||
<string name="preference_notification_badges">Insigne de notificare</string>
|
||||
<string name="preference_suspended_badges_summary">Afișează o insignă pentru aplicațiile suspendate</string>
|
||||
<string name="preference_ms_signin">Conectează-te cu Microsoft</string>
|
||||
<string name="preference_nextcloud_signin">Conectează-te la Nextcloud</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Conectează-te la Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Conectează-te pentru a căuta în serverul tău Owncloud</string>
|
||||
<string name="preference_about_telegram">Grup Telegram</string>
|
||||
@ -281,7 +281,7 @@
|
||||
<string name="preference_grid_column_count">Numărul de coloane</string>
|
||||
<string name="preference_screen_debug">Depanare</string>
|
||||
<string name="preference_screen_debug_summary">Instrumente de depanare</string>
|
||||
<string name="preference_screen_widgets">Widget-uri</string>
|
||||
<string name="preference_category_widgets">Widget-uri</string>
|
||||
<string name="preference_screen_widgets_summary">Configurarea widget-urilor</string>
|
||||
<string name="preference_screen_weatherwidget">Vreme</string>
|
||||
<string name="preference_screen_musicwidget">Muzică</string>
|
||||
@ -370,7 +370,7 @@
|
||||
\nUltima actualizare: %1$s</string>
|
||||
<string name="missing_permission_calendar_widget_settings">Acest widget necesită permisiunea la calendar</string>
|
||||
<string name="provider_brightsky">Deutscher Wetterdienst (doar Germania)</string>
|
||||
<string name="preference_screen_services_summary">Gestionează conturile și serviciile conectate</string>
|
||||
<string name="preference_screen_integrations_summary">Gestionează conturile și serviciile conectate</string>
|
||||
<string name="weather_condition_lightrainshowersandthunder">Averse ușoare de ploaie și tunete</string>
|
||||
<string name="preference_cards_summary">Particularizarea aspectului cardului</string>
|
||||
<string name="preference_cloud_badges_summary">Afișarea unei insigne pentru fișierele stocate într-un cloud</string>
|
||||
|
||||
@ -195,7 +195,7 @@
|
||||
<string name="preference_icon_shape_triangle">Треугольник Рело</string>
|
||||
<string name="preference_icon_shape_circle">Круг</string>
|
||||
<string name="preference_icon_shape_hexagon">Шестиугольник</string>
|
||||
<string name="preference_screen_services">Службы</string>
|
||||
<string name="preference_screen_integrations">Службы</string>
|
||||
<string name="preference_theme_system">Следовать системе</string>
|
||||
<string name="menu_share_store_link">%1$s ссылка</string>
|
||||
<string name="menu_app_info">Информация о приложении</string>
|
||||
@ -282,22 +282,22 @@
|
||||
<string name="preference_clockwidget_music_part">Медиа</string>
|
||||
<string name="preference_search_files_summary">Поиск локальных файлов и облачных файлов</string>
|
||||
<string name="preference_search_websearch_summary">Показать ярлыки различных поисковых систем</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_hide_status_bar">Скрыть строку состояния</string>
|
||||
<string name="preference_hide_nav_bar">Скрыть панель навигации</string>
|
||||
<string name="preference_category_wallpaper">Обои</string>
|
||||
<string name="preference_dim_wallpaper">Тусклые обои</string>
|
||||
<string name="preference_dim_wallpaper_summary">В темных темах, затемнить обои</string>
|
||||
<string name="preference_wallpaper_summary">Выберите обои</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_about_telegram">Telegram группа</string>
|
||||
<string name="preference_about_fdroid">F-Droid репозиторий</string>
|
||||
<string name="preference_category_license">Лицензия</string>
|
||||
<string name="preference_category_grid">Сетка</string>
|
||||
<string name="preference_grid_column_count">Количество столбцов</string>
|
||||
<string name="preference_screen_debug">Отладка</string>
|
||||
<string name="preference_screen_widgets">Виджеты</string>
|
||||
<string name="preference_category_widgets">Виджеты</string>
|
||||
<string name="preference_screen_weatherwidget">Погода</string>
|
||||
<string name="preference_clock_widget_style">Стиль</string>
|
||||
<string name="preference_clock_widget_style_summary">Выберите часы</string>
|
||||
@ -356,11 +356,11 @@
|
||||
<string name="preference_blur_wallpaper">Размытие фона</string>
|
||||
<string name="preference_blur_wallpaper_summary">Использовать эффект размытия для фона</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">Не поддерживается на вашем устройстве</string>
|
||||
<string name="preference_screen_badges">Значки уведомлений</string>
|
||||
<string name="preference_category_badges">Значки уведомлений</string>
|
||||
<string name="edit_favorites_dialog_new_tag">Создать тег…</string>
|
||||
<string name="preference_font_system">Системный</string>
|
||||
<string name="preference_icon_shape_teardrop">Слезинка</string>
|
||||
<string name="preference_screen_services_summary">Управление подключенными учётными записями и сервисами</string>
|
||||
<string name="preference_screen_integrations_summary">Управление подключенными учётными записями и сервисами</string>
|
||||
<string name="preference_font">Шрифт</string>
|
||||
<string name="preference_status_bar_icons">Цвет значков строки состояния</string>
|
||||
<string name="preference_system_bar_icons_dark">Тёмный</string>
|
||||
@ -453,7 +453,7 @@
|
||||
<string name="icon_pack_dynamic_colors">Динамические цвета</string>
|
||||
<string name="backup_not_included">Подключенные учетные записи и сторонние виджеты не будут включены в резервную копию.</string>
|
||||
<string name="preference_nextcloud_signin">Войти в Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Войдите, для поиска в сервере Nextcloud</string>
|
||||
<string name="preference_owncloud_signin">Войти в Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Войдите, для поиска в сервере Owncloud</string>
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
<string name="file_meta_size">Storlek: %1$s</string>
|
||||
<string name="websearch_dialog_import_error">Den angivna adressen kan inte importeras automatiskt. Du kan försöka med en annan URL eller manuellt ange den nödvändiga datan.</string>
|
||||
<string name="edit_favorites_dialog_pinned_sorted">Fästa – manuellt sorterade</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="file_meta_dimensions">Dimensioner: %1$s</string>
|
||||
<string name="widget_name_music">Musik</string>
|
||||
<string name="websearch_dialog_name">Namn</string>
|
||||
@ -223,7 +223,7 @@
|
||||
<string name="preference_icon_shape_triangle">Reuleaux-triangel</string>
|
||||
<string name="preference_icon_shape_hexagon">Hexagon</string>
|
||||
<string name="preference_category_searchbar">Sökfält</string>
|
||||
<string name="preference_screen_services">Tjänster</string>
|
||||
<string name="preference_screen_integrations">Tjänster</string>
|
||||
<string name="preference_theme_system">Följ systemet</string>
|
||||
<string name="preference_themed_icons">Färglagda ikoner</string>
|
||||
<string name="preference_icon_pack">Ikonpaket</string>
|
||||
@ -231,7 +231,7 @@
|
||||
<string name="preference_category_system_bars">Systemfält</string>
|
||||
<string name="preference_hide_status_bar">Göm statusfält</string>
|
||||
<string name="preference_hide_nav_bar">Göm navigationsfält</string>
|
||||
<string name="preference_screen_services_summary">Hantera anslutna konton och tjänster</string>
|
||||
<string name="preference_screen_integrations_summary">Hantera anslutna konton och tjänster</string>
|
||||
<string name="preference_signin_user">Inloggad som %1$s</string>
|
||||
<string name="preference_signin_logout">Logga ut</string>
|
||||
<string name="preference_icon_shape_pentagon">Pentagon</string>
|
||||
@ -239,7 +239,7 @@
|
||||
<string name="preference_dim_wallpaper">Dämpa bakgrund</string>
|
||||
<string name="preference_dim_wallpaper_summary">Dämpa bakgrunden i mörka teman</string>
|
||||
<string name="preference_wallpaper_summary">Välj en bakgrund</string>
|
||||
<string name="preference_screen_badges">Aviseringsprickar</string>
|
||||
<string name="preference_category_badges">Aviseringsprickar</string>
|
||||
<string name="preference_notification_badges">Aviseringsprickar</string>
|
||||
<string name="preference_notification_badges_summary">Appar med olästa notifikationer märks med en prick</string>
|
||||
<string name="preference_suspended_badges_summary">Visa en prick på avslutade appar</string>
|
||||
@ -247,13 +247,13 @@
|
||||
<string name="preference_cloud_badges">Molnprickar</string>
|
||||
<string name="preference_shortcut_badges">Genvägsprickar</string>
|
||||
<string name="preference_shortcut_badges_summary">Prick som visar vilken app en genväg hör till</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Logga in med Microsoft</string>
|
||||
<string name="preference_ms_signin_summary">Logga in för att söka i OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">Logga in på Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Logga in för att söka i din Nextcloud-server</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Logga in på Owncloud</string>
|
||||
<string name="preference_about_telegram">Telegram-grupp</string>
|
||||
<string name="preference_about_fdroid">F-Droid-kodförråd</string>
|
||||
@ -263,7 +263,7 @@
|
||||
<string name="preference_category_grid">Rutnät</string>
|
||||
<string name="preference_grid_column_count">Antal kolumner</string>
|
||||
<string name="preference_screen_debug">Felsök</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Konfigurera widgets</string>
|
||||
<string name="preference_screen_weatherwidget">Väder</string>
|
||||
<string name="preference_screen_musicwidget">Musik</string>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<string name="preference_dim_wallpaper_summary">在深色主题中,使壁纸变暗</string>
|
||||
<string name="preference_screen_badges_summary">配置图标角标</string>
|
||||
<string name="preference_ms_signin_summary">登陆以查找OneDrive</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud_signin">登陆到Owncloud</string>
|
||||
<string name="preference_about_license">此应用是自由软件。</string>
|
||||
<string name="preference_clock_widget_style_summary">选择一个时钟</string>
|
||||
@ -252,8 +252,8 @@
|
||||
<string name="preference_category_system_bars">系统栏</string>
|
||||
<string name="preference_hide_status_bar">隐藏状态栏</string>
|
||||
<string name="preference_hide_nav_bar">隐藏导航条</string>
|
||||
<string name="preference_screen_services_summary">管理已连接的账户和服务</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">管理已连接的账户和服务</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">以 %1$s 身份登陆</string>
|
||||
<string name="preference_signin_logout">登出</string>
|
||||
<string name="preference_summary_not_logged_in">您当前未登录</string>
|
||||
@ -272,9 +272,9 @@
|
||||
<string name="preference_icon_shape_circle">圆形</string>
|
||||
<string name="preference_icon_shape_hexagon">六边形</string>
|
||||
<string name="preference_category_searchbar">搜索栏</string>
|
||||
<string name="preference_screen_services">服务</string>
|
||||
<string name="preference_screen_integrations">服务</string>
|
||||
<string name="preference_wallpaper_summary">选择一张壁纸</string>
|
||||
<string name="preference_screen_badges">徽章</string>
|
||||
<string name="preference_category_badges">徽章</string>
|
||||
<string name="preference_suspended_badges">已暂停的应用</string>
|
||||
<string name="preference_notification_badges">通知角标</string>
|
||||
<string name="preference_notification_badges_summary">为带有未读通知的应用程序显示角标</string>
|
||||
@ -283,11 +283,11 @@
|
||||
<string name="preference_cloud_badges_summary">为储存在云服务器上的文件显示角标</string>
|
||||
<string name="preference_shortcut_badges">快捷方式角标</string>
|
||||
<string name="preference_shortcut_badges_summary">显示指示快捷方式所属应用的角标</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">使用Microsoft登陆</string>
|
||||
<string name="preference_nextcloud_signin_summary">登陆以查找你的Nextcloud服务</string>
|
||||
<string name="preference_nextcloud_signin">登陆到Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">登陆以查找你的Owncloud服务</string>
|
||||
<string name="preference_about_telegram">Telegram群组</string>
|
||||
<string name="preference_about_fdroid">F-Droid 储存库</string>
|
||||
@ -297,7 +297,7 @@
|
||||
<string name="preference_grid_column_count">列数</string>
|
||||
<string name="preference_screen_debug">调试</string>
|
||||
<string name="preference_screen_debug_summary">故障排除工具</string>
|
||||
<string name="preference_screen_widgets">组件</string>
|
||||
<string name="preference_category_widgets">组件</string>
|
||||
<string name="preference_screen_widgets_summary">配置组件</string>
|
||||
<string name="preference_screen_weatherwidget">天气</string>
|
||||
<string name="preference_screen_musicwidget">音乐</string>
|
||||
|
||||
@ -320,7 +320,7 @@
|
||||
<string name="preference_icon_shape_teardrop">淚滴形</string>
|
||||
<string name="preference_icon_shape_pebble">鵝卵形</string>
|
||||
<string name="preference_icon_shape_hexagon">六邊形</string>
|
||||
<string name="preference_screen_services">服務</string>
|
||||
<string name="preference_screen_integrations">服務</string>
|
||||
<string name="preference_theme_system">跟隨系統</string>
|
||||
<string name="preference_themed_icons">主題圖示</string>
|
||||
<string name="preference_themed_icons_summary">帶有應用程式配色方案的彩色圖示</string>
|
||||
@ -337,8 +337,8 @@
|
||||
<string name="preference_system_bar_icons_dark">深色</string>
|
||||
<string name="preference_hide_status_bar">隱藏狀態列</string>
|
||||
<string name="preference_hide_nav_bar">隱藏導覽列</string>
|
||||
<string name="preference_screen_services_summary">管理已連線的帳戶和服務</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">管理已連線的帳戶和服務</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">以 %1$s 身份登陸</string>
|
||||
<string name="preference_signin_logout">登出</string>
|
||||
<string name="preference_summary_not_logged_in">您當前未登入</string>
|
||||
@ -349,17 +349,17 @@
|
||||
<string name="preference_blur_wallpaper_summary">在桌布上 使用模糊效果</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">在此裝置上不受支援</string>
|
||||
<string name="preference_wallpaper_summary">選擇一張桌布</string>
|
||||
<string name="preference_screen_badges">徽章</string>
|
||||
<string name="preference_category_badges">徽章</string>
|
||||
<string name="preference_screen_badges_summary">組態圖示角標</string>
|
||||
<string name="preference_notification_badges">通知角標</string>
|
||||
<string name="preference_notification_badges_summary">為帶有未讀通知的應用程式顯示角標</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">使用Microsoft登陸</string>
|
||||
<string name="preference_ms_signin_summary">登陸以查詢OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">登陸到Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">登陸以查詢你的Nextcloud服務</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">登陸到Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">登陸以查詢你的Owncloud服務</string>
|
||||
<string name="preference_about_telegram">Telegram群組</string>
|
||||
@ -376,7 +376,7 @@
|
||||
<string name="preference_grid_labels_summary">在圖示底下顯示應用名稱</string>
|
||||
<string name="preference_screen_debug">除錯</string>
|
||||
<string name="preference_screen_debug_summary">故障排除工具</string>
|
||||
<string name="preference_screen_widgets">元件</string>
|
||||
<string name="preference_category_widgets">元件</string>
|
||||
<string name="preference_screen_widgets_summary">組態元件</string>
|
||||
<string name="preference_screen_weatherwidget">天氣</string>
|
||||
<string name="preference_screen_musicwidget">音樂</string>
|
||||
|
||||
@ -480,7 +480,7 @@
|
||||
<string name="preference_icon_shape_pebble">Pebble</string>
|
||||
<string name="preference_icon_shape_hexagon">Hexagon</string>
|
||||
<string name="preference_category_searchbar">Search bar</string>
|
||||
<string name="preference_screen_services">Services</string>
|
||||
<string name="preference_screen_integrations">Integrations</string>
|
||||
<string name="preference_theme_system">Follow system</string>
|
||||
<string name="preference_themed_icons">Themed icons</string>
|
||||
<string name="preference_themed_icons_summary">Color icons with the application\'s color scheme</string>
|
||||
@ -498,8 +498,8 @@
|
||||
<string name="preference_system_bar_icons_dark">Dark</string>
|
||||
<string name="preference_hide_status_bar">Hide status bar</string>
|
||||
<string name="preference_hide_nav_bar">Hide navigation bar</string>
|
||||
<string name="preference_screen_services_summary">Manage connected accounts and services</string>
|
||||
<string name="preference_category_services_google">Google</string>
|
||||
<string name="preference_screen_integrations_summary">Manage connected accounts and services</string>
|
||||
<string name="preference_google">Google</string>
|
||||
<string name="preference_signin_user">Signed in as %1$s</string>
|
||||
<string name="preference_signin_logout">Log out</string>
|
||||
<string name="preference_summary_not_logged_in">You are currently not logged in</string>
|
||||
@ -511,7 +511,7 @@
|
||||
<string name="preference_blur_wallpaper_summary">Use a blur effect on the wallpaper</string>
|
||||
<string name="preference_blur_wallpaper_unsupported">Not supported on this device</string>
|
||||
<string name="preference_wallpaper_summary">Choose a wallpaper</string>
|
||||
<string name="preference_screen_badges">Badges</string>
|
||||
<string name="preference_category_badges">Badges</string>
|
||||
<string name="preference_screen_badges_summary">Configure icon badges</string>
|
||||
<string name="preference_notification_badges">Notification badges</string>
|
||||
<string name="preference_notification_badges_summary">Show a badge for applications with unread notifications</string>
|
||||
@ -521,13 +521,13 @@
|
||||
<string name="preference_cloud_badges_summary">Show a badge for files that are stored in a cloud</string>
|
||||
<string name="preference_shortcut_badges">Shortcut badges</string>
|
||||
<string name="preference_shortcut_badges_summary">Show a badge which indicates to which app a shortcut belongs</string>
|
||||
<string name="preference_category_services_microsoft">Microsoft</string>
|
||||
<string name="preference_microsoft">Microsoft</string>
|
||||
<string name="preference_ms_signin">Sign in with Microsoft</string>
|
||||
<string name="preference_ms_signin_summary">Sign in to search OneDrive</string>
|
||||
<string name="preference_nextcloud_signin">Sign in to Nextcloud</string>
|
||||
<string name="preference_nextcloud_signin_summary">Sign in to search your Nextcloud server</string>
|
||||
<string name="preference_category_services_nextcloud">Nextcloud</string>
|
||||
<string name="preference_category_services_owncloud">Owncloud</string>
|
||||
<string name="preference_nextcloud">Nextcloud</string>
|
||||
<string name="preference_owncloud">Owncloud</string>
|
||||
<string name="preference_owncloud_signin">Sign in to Owncloud</string>
|
||||
<string name="preference_owncloud_signin_summary">Sign in to search your Owncloud server</string>
|
||||
<string name="preference_about_telegram">Telegram group</string>
|
||||
@ -544,11 +544,12 @@
|
||||
<string name="preference_grid_labels_summary">Show the app name below the icon</string>
|
||||
<string name="preference_screen_debug">Debug</string>
|
||||
<string name="preference_screen_debug_summary">Troubleshooting tools</string>
|
||||
<string name="preference_screen_widgets">Widgets</string>
|
||||
<string name="preference_category_widgets">Widgets</string>
|
||||
<string name="preference_screen_widgets_summary">Configure widgets</string>
|
||||
<string name="preference_screen_weatherwidget">Weather</string>
|
||||
<string name="preference_screen_musicwidget">Music</string>
|
||||
<string name="preference_screen_clockwidget">Clock</string>
|
||||
<string name="preference_screen_clockwidget_summary">Configure clock style and components</string>
|
||||
<string name="preference_clockwidget_layout">Layout</string>
|
||||
<string name="preference_clockwidget_layout_vertical">Default</string>
|
||||
<string name="preference_clockwidget_layout_horizontal">Compact</string>
|
||||
@ -579,7 +580,7 @@
|
||||
<string name="preference_logs_summary">View and export application logs</string>
|
||||
<string name="preference_export_log">Export log file</string>
|
||||
<string name="preference_screen_search">Search</string>
|
||||
<string name="preference_screen_search_summary">Configure the search</string>
|
||||
<string name="preference_screen_search_summary">Search, tags, hidden items</string>
|
||||
<string name="preference_search_favorites">Favorites</string>
|
||||
<string name="preference_search_favorites_summary">Show pinned and frequently used items above app grid</string>
|
||||
<string name="preference_search_files">Files</string>
|
||||
@ -644,6 +645,14 @@
|
||||
<string name="preference_edit_button">Edit button</string>
|
||||
<string name="preference_favorites_edit_button_summary">Show a button to rearrange the favorites</string>
|
||||
<string name="preference_widgets_edit_button_summary">Show a button to add, remove and rearrange widgets</string>
|
||||
<string name="preference_screen_homescreen">Home screen</string>
|
||||
<string name="preference_screen_homescreen_summary">Clock, search bar, wallpaper, system bars</string>
|
||||
<string name="preference_screen_icons">Grid & icons</string>
|
||||
<string name="preference_screen_icons_summary">Grid, icon size, icon packs, badges</string>
|
||||
<string name="preference_category_accounts">Accounts</string>
|
||||
<string name="preference_weather_integration">Weather</string>
|
||||
<string name="preference_media_integration">Media control</string>
|
||||
|
||||
<!-- Used in an info banner if a specific feature requires a Nextcloud account -->
|
||||
<string name="no_account_nextcloud">You haven\'t connected a Nextcloud account yet</string>
|
||||
<!-- Used in an info banner if a specific feature requires an Owncloud account -->
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<application>
|
||||
<activity
|
||||
android:name="de.mm20.launcher2.nextcloud.LoginActivity"
|
||||
android:label="@string/preference_category_services_nextcloud"
|
||||
android:label="@string/preference_nextcloud"
|
||||
android:taskAffinity="de.mm20.launcher2.nextcloud"
|
||||
android:theme="@style/NextcloudLoginTheme" />
|
||||
</application>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<application>
|
||||
<activity
|
||||
android:name=".LoginActivity"
|
||||
android:label="@string/preference_category_services_nextcloud"
|
||||
android:label="@string/preference_nextcloud"
|
||||
android:taskAffinity="de.mm20.launcher2.nextcloud"
|
||||
android:parentActivityName="de.mm20.launcher2.ui.settings.SettingsActivity"
|
||||
android:theme="@style/OwncloudLoginTheme" >
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user