mirror of
https://github.com/florisboard/florisboard.git
synced 2024-09-19 19:42:20 +02:00
Add barebones implementation for addons screen
This commit is contained in:
parent
e520a9c335
commit
f1d60d9958
@ -27,8 +27,11 @@ import dev.patrickgold.florisboard.app.devtools.DevtoolsScreen
|
||||
import dev.patrickgold.florisboard.app.devtools.ExportDebugLogScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionEditScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionExportScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionHomeScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionImportScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionImportScreenType
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionListScreen
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionListScreenType
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionViewScreen
|
||||
import dev.patrickgold.florisboard.app.settings.HomeScreen
|
||||
import dev.patrickgold.florisboard.app.settings.about.AboutScreen
|
||||
@ -58,7 +61,7 @@ import dev.patrickgold.florisboard.app.settings.typing.TypingScreen
|
||||
import dev.patrickgold.florisboard.app.setup.SetupScreen
|
||||
import org.florisboard.lib.kotlin.curlyFormat
|
||||
|
||||
@Suppress("FunctionName")
|
||||
@Suppress("FunctionName", "ConstPropertyName")
|
||||
object Routes {
|
||||
object Setup {
|
||||
const val Screen = "setup"
|
||||
@ -117,6 +120,13 @@ object Routes {
|
||||
}
|
||||
|
||||
object Ext {
|
||||
const val Home = "ext"
|
||||
|
||||
const val List = "ext/list/{type}"
|
||||
fun List(
|
||||
type: ExtensionListScreenType,
|
||||
) = List.curlyFormat("type" to type.id)
|
||||
|
||||
const val Edit = "ext/edit/{id}?create={serial_type}"
|
||||
fun Edit(id: String, serialType: String? = null): String {
|
||||
return Edit.curlyFormat("id" to id, "serial_type" to (serialType ?: ""))
|
||||
@ -209,12 +219,19 @@ object Routes {
|
||||
}
|
||||
composable(Devtools.ExportDebugLog) { ExportDebugLogScreen() }
|
||||
|
||||
composable(Ext.Home) { ExtensionHomeScreen() }
|
||||
composable(Ext.List) { navBackStack ->
|
||||
val type = navBackStack.arguments?.getString("type")?.let { typeId ->
|
||||
ExtensionListScreenType.entries.firstOrNull { it.id == typeId }
|
||||
} ?: error("unknown type")
|
||||
ExtensionListScreen(type)
|
||||
}
|
||||
composable(Ext.Edit) { navBackStack ->
|
||||
val extensionId = navBackStack.arguments?.getString("id")
|
||||
val serialType = navBackStack.arguments?.getString("serial_type")
|
||||
ExtensionEditScreen(
|
||||
id = extensionId.toString(),
|
||||
createSerialType = serialType.takeIf { it != null && it.isNotBlank() },
|
||||
createSerialType = serialType.takeIf { !it.isNullOrBlank() },
|
||||
)
|
||||
}
|
||||
composable(Ext.Export) { navBackStack ->
|
||||
|
@ -0,0 +1,129 @@
|
||||
package dev.patrickgold.florisboard.app.ext
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.Input
|
||||
import androidx.compose.material.icons.filled.Keyboard
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.Palette
|
||||
import androidx.compose.material.icons.filled.Shop
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.app.LocalNavController
|
||||
import dev.patrickgold.florisboard.app.Routes
|
||||
import dev.patrickgold.florisboard.lib.android.launchUrl
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
|
||||
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.stringRes
|
||||
import dev.patrickgold.jetpref.datastore.ui.Preference
|
||||
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
|
||||
import org.florisboard.lib.kotlin.curlyFormat
|
||||
|
||||
@Composable
|
||||
fun ExtensionHomeScreen() = FlorisScreen {
|
||||
title = stringRes(R.string.ext__home__title)
|
||||
previewFieldVisible = false
|
||||
|
||||
val context = LocalContext.current
|
||||
val navController = LocalNavController.current
|
||||
|
||||
content {
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 4.dp),
|
||||
text = "You can download and install extensions from the FlorisBoard Addons Store or import any extension file you have downloaded from the internet.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
//context.launchUrl("https://beta.addons.florisboard.org")
|
||||
context.launchUrl("https://fladdonstest.patrickgold.dev")
|
||||
},
|
||||
icon = Icons.Default.Shop,
|
||||
text = "Visit Addons Store",//stringRes(R.string.action__edit),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Import(ExtensionImportScreenType.EXT_ANY, null))
|
||||
},
|
||||
icon = Icons.AutoMirrored.Filled.Input,
|
||||
text = stringRes(R.string.action__import),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PreferenceGroup(title = "Manage installed extensions") {
|
||||
Preference(
|
||||
icon = Icons.Default.Palette,
|
||||
title = stringRes(R.string.ext__list__ext_theme),
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.List(ExtensionListScreenType.EXT_THEME))
|
||||
},
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.Keyboard,
|
||||
title = stringRes(R.string.ext__list__ext_keyboard),
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.List(ExtensionListScreenType.EXT_KEYBOARD))
|
||||
},
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.Language,
|
||||
title = stringRes(R.string.ext__list__ext_languagepack),
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.List(ExtensionListScreenType.EXT_LANGUAGEPACK))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AddonManagementReferenceBox() {
|
||||
val navController = LocalNavController.current
|
||||
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
title = "Managing extensions"
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
text = "All tasks related to importing, exporting, creating, customizing, and removing extensions can be handled through the centralized addon manager.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Home)
|
||||
},
|
||||
icon = Icons.Default.Shop,
|
||||
text = "Go to {ext_home_title}".curlyFormat(
|
||||
"ext_home_title" to stringRes(R.string.ext__home__title),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
* Copyright (C) 2024 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,84 +16,134 @@
|
||||
|
||||
package dev.patrickgold.florisboard.app.ext
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.FloatingActionButtonDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.app.LocalNavController
|
||||
import dev.patrickgold.florisboard.app.Routes
|
||||
import dev.patrickgold.florisboard.extensionManager
|
||||
import dev.patrickgold.florisboard.ime.keyboard.KeyboardExtension
|
||||
import dev.patrickgold.florisboard.ime.nlp.LanguagePackExtension
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeExtension
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
|
||||
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.stringRes
|
||||
import dev.patrickgold.florisboard.lib.ext.ExtensionManager
|
||||
import dev.patrickgold.florisboard.lib.observeAsNonNullState
|
||||
|
||||
enum class ExtensionListScreenType(
|
||||
val id: String,
|
||||
@StringRes val titleResId: Int,
|
||||
val getExtensionIndex: (ExtensionManager) -> ExtensionManager.ExtensionIndex<*>,
|
||||
val launchExtensionCreate: ((NavController) -> Unit)?,
|
||||
) {
|
||||
EXT_THEME(
|
||||
id = "ext-theme",
|
||||
titleResId = R.string.ext__list__ext_theme,
|
||||
getExtensionIndex = { it.themes },
|
||||
launchExtensionCreate = { it.navigate(Routes.Ext.Edit("null", ThemeExtension.SERIAL_TYPE)) },
|
||||
),
|
||||
EXT_KEYBOARD(
|
||||
id = "ext-keyboard",
|
||||
titleResId = R.string.ext__list__ext_keyboard,
|
||||
getExtensionIndex = { it.keyboardExtensions },
|
||||
launchExtensionCreate = null,//{ it.navigate(Routes.Ext.Edit("null", KeyboardExtension.SERIAL_TYPE)) },
|
||||
),
|
||||
EXT_LANGUAGEPACK(
|
||||
id = "ext-languagepack",
|
||||
titleResId = R.string.ext__list__ext_languagepack,
|
||||
getExtensionIndex = { it.languagePacks },
|
||||
launchExtensionCreate = null,//{ it.navigate(Routes.Ext.Edit("null", LanguagePackExtension.SERIAL_TYPE)) },
|
||||
);
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExtensionListScreen() = FlorisScreen {
|
||||
title = stringRes(R.string.about__title)
|
||||
fun ExtensionListScreen(type: ExtensionListScreenType) = FlorisScreen {
|
||||
title = stringRes(type.titleResId)
|
||||
previewFieldVisible = false
|
||||
|
||||
/*val navController = LocalNavController.current
|
||||
val context = LocalContext.current
|
||||
val extensionManager = ExtensionManager.def
|
||||
val navController = LocalNavController.current
|
||||
val extensionManager by context.extensionManager()
|
||||
val extensionIndex by type.getExtensionIndex(extensionManager).observeAsNonNullState()
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 24.dp, bottom = 32.dp)
|
||||
) {
|
||||
FlorisAppIcon()
|
||||
Text(
|
||||
text = stringRes(R.string.floris_app_name),
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
)
|
||||
}
|
||||
Preference(
|
||||
icon = R.drawable.ic_info,
|
||||
title = stringRes(R.string.about__version__title),
|
||||
summary = appVersion,
|
||||
onClick = {
|
||||
try {
|
||||
val isImeSelected = InputMethodUtils.checkIsFlorisboardSelected(context)
|
||||
if (isImeSelected) {
|
||||
FlorisClipboardManager.getInstance().addNewPlaintext(appVersion)
|
||||
} else {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Florisboard version", appVersion)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
content {
|
||||
for (ext in extensionIndex) {
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
title = ext.meta.title,
|
||||
subtitle = ext.meta.id,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
text = ext.meta.description ?: "",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.View(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Outlined.Info,
|
||||
text = "View details",//stringRes(R.string.action__add),
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Edit(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Default.Edit,
|
||||
text = stringRes(R.string.action__edit),
|
||||
enabled = extensionManager.canDelete(ext),
|
||||
)
|
||||
}
|
||||
Toast.makeText(context, R.string.about__version_copied__title, Toast.LENGTH_SHORT).show()
|
||||
} catch (e: Throwable) {
|
||||
Toast.makeText(
|
||||
context, context.getString(R.string.about__version_copied__error, e.message), Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
},
|
||||
)
|
||||
Preference(
|
||||
icon = R.drawable.ic_history,
|
||||
title = stringRes(R.string.about__changelog__title),
|
||||
summary = stringRes(R.string.about__changelog__summary),
|
||||
onClick = { launchUrl(context, R.string.florisboard__changelog_url, arrayOf(BuildConfig.VERSION_NAME)) },
|
||||
)
|
||||
Preference(
|
||||
icon = R.drawable.ic_code,
|
||||
title = stringRes(R.string.about__repository__title),
|
||||
summary = stringRes(R.string.about__repository__summary),
|
||||
onClick = { launchUrl(context, R.string.florisboard__repo_url) },
|
||||
)
|
||||
Preference(
|
||||
icon = R.drawable.ic_policy,
|
||||
title = stringRes(R.string.about__privacy_policy__title),
|
||||
summary = stringRes(R.string.about__privacy_policy__summary),
|
||||
onClick = { launchUrl(context, R.string.florisboard__privacy_policy_url) },
|
||||
)
|
||||
Preference(
|
||||
icon = R.drawable.ic_description,
|
||||
title = stringRes(R.string.about__project_license__title),
|
||||
summary = stringRes(R.string.about__project_license__summary, "license_name" to "Apache 2.0"),
|
||||
onClick = { navController.navigate(Routes.Settings.ProjectLicense) },
|
||||
)
|
||||
Preference(
|
||||
icon = R.drawable.ic_description,
|
||||
title = stringRes(id = R.string.about__third_party_licenses__title),
|
||||
summary = stringRes(id = R.string.about__third_party_licenses__summary),
|
||||
onClick = { navController.navigate(Routes.Settings.ThirdPartyLicenses) },
|
||||
)*/
|
||||
}
|
||||
}
|
||||
|
||||
if (type.launchExtensionCreate != null) {
|
||||
floatingActionButton {
|
||||
ExtendedFloatingActionButton(
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "Create extension",
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = "Create extension",
|
||||
)
|
||||
},
|
||||
shape = FloatingActionButtonDefaults.extendedFabShape,
|
||||
onClick = { type.launchExtensionCreate.invoke(navController) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,14 +18,13 @@ package dev.patrickgold.florisboard.app.settings
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Adb
|
||||
import androidx.compose.material.icons.automirrored.outlined.Assignment
|
||||
import androidx.compose.material.icons.filled.Extension
|
||||
import androidx.compose.material.icons.filled.Gesture
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.LibraryBooks
|
||||
import androidx.compose.material.icons.filled.SentimentSatisfiedAlt
|
||||
import androidx.compose.material.icons.filled.SmartButton
|
||||
import androidx.compose.material.icons.filled.Spellcheck
|
||||
import androidx.compose.material.icons.outlined.Assignment
|
||||
import androidx.compose.material.icons.outlined.Build
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.Keyboard
|
||||
@ -131,18 +130,13 @@ fun HomeScreen() = FlorisScreen {
|
||||
title = stringRes(R.string.settings__typing__title),
|
||||
onClick = { navController.navigate(Routes.Settings.Typing) },
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.LibraryBooks,
|
||||
title = stringRes(R.string.settings__dictionary__title),
|
||||
onClick = { navController.navigate(Routes.Settings.Dictionary) },
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.Gesture,
|
||||
title = stringRes(R.string.settings__gestures__title),
|
||||
onClick = { navController.navigate(Routes.Settings.Gestures) },
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Outlined.Assignment,
|
||||
icon = Icons.AutoMirrored.Outlined.Assignment,
|
||||
title = stringRes(R.string.settings__clipboard__title),
|
||||
onClick = { navController.navigate(Routes.Settings.Clipboard) },
|
||||
)
|
||||
@ -152,9 +146,9 @@ fun HomeScreen() = FlorisScreen {
|
||||
onClick = { navController.navigate(Routes.Settings.Media) },
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.Adb,
|
||||
title = stringRes(R.string.devtools__title),
|
||||
onClick = { navController.navigate(Routes.Devtools.Home) },
|
||||
icon = Icons.Default.Extension,
|
||||
title = stringRes(R.string.ext__home__title),
|
||||
onClick = { navController.navigate(Routes.Ext.Home) },
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Outlined.Build,
|
||||
|
@ -17,6 +17,7 @@
|
||||
package dev.patrickgold.florisboard.app.settings.advanced
|
||||
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Adb
|
||||
import androidx.compose.material.icons.filled.Archive
|
||||
import androidx.compose.material.icons.filled.FormatPaint
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
@ -166,6 +167,11 @@ fun AdvancedScreen() = FlorisScreen {
|
||||
title = stringRes(R.string.pref__advanced__incognito_mode__label),
|
||||
entries = IncognitoMode.listEntries(),
|
||||
)
|
||||
Preference(
|
||||
icon = Icons.Default.Adb,
|
||||
title = stringRes(R.string.devtools__title),
|
||||
onClick = { navController.navigate(Routes.Devtools.Home) },
|
||||
)
|
||||
|
||||
PreferenceGroup(title = stringRes(R.string.backup_and_restore__title)) {
|
||||
Preference(
|
||||
|
@ -16,26 +16,13 @@
|
||||
|
||||
package dev.patrickgold.florisboard.app.settings.theme
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.Input
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.BrightnessAuto
|
||||
import androidx.compose.material.icons.filled.DarkMode
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.filled.LightMode
|
||||
import androidx.compose.material.icons.filled.Shop
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -43,25 +30,17 @@ import androidx.compose.ui.unit.dp
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.app.LocalNavController
|
||||
import dev.patrickgold.florisboard.app.Routes
|
||||
import dev.patrickgold.florisboard.app.ext.ExtensionImportScreenType
|
||||
import dev.patrickgold.florisboard.extensionManager
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeExtension
|
||||
import dev.patrickgold.florisboard.app.ext.AddonManagementReferenceBox
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeManager
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeMode
|
||||
import dev.patrickgold.florisboard.lib.android.launchUrl
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisInfoCard
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
|
||||
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.stringRes
|
||||
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
|
||||
import dev.patrickgold.florisboard.lib.observeAsNonNullState
|
||||
import dev.patrickgold.florisboard.themeManager
|
||||
import dev.patrickgold.jetpref.datastore.model.observeAsState
|
||||
import dev.patrickgold.jetpref.datastore.ui.ListPreference
|
||||
import dev.patrickgold.jetpref.datastore.ui.Preference
|
||||
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
|
||||
|
||||
@Composable
|
||||
fun ThemeScreen() = FlorisScreen {
|
||||
@ -70,7 +49,6 @@ fun ThemeScreen() = FlorisScreen {
|
||||
|
||||
val context = LocalContext.current
|
||||
val navController = LocalNavController.current
|
||||
val extensionManager by context.extensionManager()
|
||||
val themeManager by context.themeManager()
|
||||
|
||||
@Composable
|
||||
@ -129,99 +107,6 @@ fun ThemeScreen() = FlorisScreen {
|
||||
},
|
||||
)
|
||||
|
||||
PreferenceGroup(title = stringRes(R.string.settings__theme_manager__title_manage), iconSpaceReserved = false) {
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 4.dp),
|
||||
text = "You can download and install additional themes from the FlorisBoard Addons Store or import any theme extension file you have downloaded from the internet.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
context.launchUrl("https://beta.addons.florisboard.org")
|
||||
},
|
||||
icon = Icons.Default.Shop,
|
||||
text = "Visit Addons Store",//stringRes(R.string.action__edit),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Import(ExtensionImportScreenType.EXT_THEME, null))
|
||||
},
|
||||
icon = Icons.AutoMirrored.Filled.Input,
|
||||
text = stringRes(R.string.action__import),
|
||||
)
|
||||
}
|
||||
}
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 4.dp),
|
||||
text = "If you are a more advanced user you can also choose to create and share your own theme extension using the stylesheet editor.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Edit("null", ThemeExtension.SERIAL_TYPE))
|
||||
},
|
||||
icon = Icons.Default.Add,
|
||||
text = stringRes(R.string.ext__editor__title_create_theme),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PreferenceGroup(title = "All installed themes", iconSpaceReserved = false) {
|
||||
val indexedThemeExtensions by extensionManager.themes.observeAsNonNullState()
|
||||
for (ext in indexedThemeExtensions) key(ext.meta.id) {
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
title = ext.meta.title,
|
||||
subtitle = ext.meta.id,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
text = ext.meta.description ?: "",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.View(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Outlined.Info,
|
||||
text = "View details",//stringRes(R.string.action__add),
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Edit(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Default.Edit,
|
||||
text = stringRes(R.string.action__edit),
|
||||
enabled = extensionManager.canDelete(ext),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AddonManagementReferenceBox()
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,9 @@ package dev.patrickgold.florisboard.app.settings.typing
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.LibraryBooks
|
||||
import androidx.compose.material.icons.filled.Contacts
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.LibraryBooks
|
||||
import androidx.compose.material.icons.filled.SpaceBar
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
@ -32,6 +32,8 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.app.LocalNavController
|
||||
import dev.patrickgold.florisboard.app.Routes
|
||||
import dev.patrickgold.florisboard.ime.nlp.SpellingLanguageMode
|
||||
import dev.patrickgold.florisboard.lib.android.AndroidVersion
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisErrorCard
|
||||
@ -42,6 +44,7 @@ import dev.patrickgold.jetpref.datastore.model.observeAsState
|
||||
import dev.patrickgold.jetpref.datastore.ui.DialogSliderPreference
|
||||
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
|
||||
import dev.patrickgold.jetpref.datastore.ui.ListPreference
|
||||
import dev.patrickgold.jetpref.datastore.ui.Preference
|
||||
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
|
||||
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
|
||||
|
||||
@ -51,6 +54,8 @@ fun TypingScreen() = FlorisScreen {
|
||||
title = stringRes(R.string.settings__typing__title)
|
||||
previewFieldVisible = true
|
||||
|
||||
val navController = LocalNavController.current
|
||||
|
||||
content {
|
||||
// This card is temporary and is therefore not using a string resource
|
||||
FlorisErrorCard(
|
||||
@ -159,12 +164,20 @@ fun TypingScreen() = FlorisScreen {
|
||||
)
|
||||
SwitchPreference(
|
||||
prefs.spelling.useUdmEntries,
|
||||
icon = Icons.Default.LibraryBooks,
|
||||
icon = Icons.AutoMirrored.Filled.LibraryBooks,
|
||||
title = stringRes(R.string.pref__spelling__use_udm_entries__label),
|
||||
summary = stringRes(R.string.pref__spelling__use_udm_entries__summary),
|
||||
enabledIf = { florisSpellCheckerEnabled.value },
|
||||
visibleIf = { false }, // For now
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceGroup(title = stringRes(R.string.settings__dictionary__title)) {
|
||||
Preference(
|
||||
icon = Icons.AutoMirrored.Filled.LibraryBooks,
|
||||
title = stringRes(R.string.settings__dictionary__title),
|
||||
onClick = { navController.navigate(Routes.Settings.Dictionary) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -616,6 +616,10 @@
|
||||
|
||||
|
||||
<!-- Extension strings -->
|
||||
<string name="ext__home__title">Addons & Extensions</string>
|
||||
<string name="ext__list__ext_theme">Theme extensions</string>
|
||||
<string name="ext__list__ext_keyboard">Keyboard extensions</string>
|
||||
<string name="ext__list__ext_languagepack">Language pack extensions</string>
|
||||
<string name="ext__meta__authors">Authors</string>
|
||||
<string name="ext__meta__components">Bundled components</string>
|
||||
<string name="ext__meta__components_theme">Bundled themes</string>
|
||||
|
Loading…
Reference in New Issue
Block a user