Compare commits

..

1 Commits

Author SHA1 Message Date
lm41
11a41f30e4 Temp 2025-08-02 00:27:30 +02:00
104 changed files with 721 additions and 1009 deletions

View File

@@ -200,7 +200,6 @@ dependencies {
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.runtime)
implementation(libs.cache4k)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.coroutines)
implementation(libs.kotlinx.serialization.json)
implementation(libs.mikepenz.aboutlibraries.core)
@@ -213,7 +212,6 @@ dependencies {
implementation(project(":lib:android"))
implementation(project(":lib:color"))
implementation(project(":lib:compose"))
implementation(project(":lib:kotlin"))
implementation(project(":lib:native"))
implementation(project(":lib:snygg"))

View File

@@ -608,12 +608,6 @@
"authors": [ "waelwindows" ],
"direction": "ltr"
},
{
"id": "czech",
"label": "Czech",
"authors": [ "bmondream" ],
"direction": "ltr"
},
{
"id": "devanagari",
"label": "Devanagari",

View File

@@ -1,119 +0,0 @@
[
[
{ "$": "shift_state_selector",
"default": {
"code": 43, "label": "+", "type": "numeric", "popup": {
"main": { "code": 49, "label": "1" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 282, "label": "Ě", "type": "numeric", "popup": {
"main": { "code": 50, "label": "2" }
}
},
"default": {
"code": 283, "label": "ě", "type": "numeric", "popup": {
"main": { "code": 50, "label": "2" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 352, "label": "Š", "type": "numeric", "popup": {
"main": { "code": 51, "label": "3" }
}
},
"default": {
"code": 353, "label": "š", "type": "numeric", "popup": {
"main": { "code": 51, "label": "3" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 268, "label": "Č", "type": "numeric", "popup": {
"main": { "code": 52, "label": "4" }
}
},
"default": {
"code": 269, "label": "č", "type": "numeric", "popup": {
"main": { "code": 52, "label": "4" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 344, "label": "Ř", "type": "numeric", "popup": {
"main": { "code": 53, "label": "5" }
}
},
"default": {
"code": 345, "label": "ř", "type": "numeric", "popup": {
"main": { "code": 53, "label": "5" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 381, "label": "Ž", "type": "numeric", "popup": {
"main": { "code": 54, "label": "6" }
}
},
"default": {
"code": 382, "label": "ž", "type": "numeric", "popup": {
"main": { "code": 54, "label": "6" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 221, "label": "Ý", "type": "numeric", "popup": {
"main": { "code": 55, "label": "7" }
}
},
"default": {
"code": 253, "label": "ý", "type": "numeric", "popup": {
"main": { "code": 55, "label": "7" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 193, "label": "Á", "type": "numeric", "popup": {
"main": { "code": 56, "label": "8" }
}
},
"default": {
"code": 225, "label": "á", "type": "numeric", "popup": {
"main": { "code": 56, "label": "8" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 205, "label": "Í", "type": "numeric", "popup": {
"main": { "code": 57, "label": "9" }
}
},
"default": {
"code": 237, "label": "í", "type": "numeric", "popup": {
"main": { "code": 57, "label": "9" }
}
}
},
{ "$": "shift_state_selector",
"shiftedManual": {
"code": 201, "label": "É", "type": "numeric", "popup": {
"main": { "code": 48, "label": "0" }
}
},
"default": {
"code": 233, "label": "é", "type": "numeric", "popup": {
"main": { "code": 48, "label": "0" }
}
}
}
]
]

View File

@@ -34,7 +34,9 @@
]
},
"h": {
"main": { "$": "auto_text_key", "code": 7717, "label": "ḥ" }
"relevant": [
{ "$": "auto_text_key", "code": 7717, "label": "ḥ" }
]
},
"i": {
"main": { "$": "auto_text_key", "code": 237, "label": "í" },
@@ -47,11 +49,13 @@
]
},
"l": {
"main": { "$": "auto_text_key", "code": 7735, "label": "ḷ" }
"relevant": [
{ "$": "auto_text_key", "code": 7735, "label": "ḷ" }
]
},
"n": {
"main": { "$": "auto_text_key", "code": 241, "label": "ñ" },
"relevant": [
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
{ "$": "auto_text_key", "code": 324, "label": "ń" }
]
},
@@ -69,7 +73,9 @@
]
},
"r": {
"main": { "$": "auto_text_key", "code": 691, "label": "ʳ" }
"relevant": [
{ "$": "auto_text_key", "code": 691, "label": "ʳ" }
]
},
"s": {
"relevant": [
@@ -106,4 +112,4 @@
}
}
}

View File

@@ -102,6 +102,7 @@ import dev.patrickgold.florisboard.ime.text.TextInputLayout
import dev.patrickgold.florisboard.ime.theme.FlorisImeTheme
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.ime.theme.WallpaperChangeReceiver
import dev.patrickgold.florisboard.lib.compose.ProvideLocalizedResources
import dev.patrickgold.florisboard.lib.compose.SystemUiIme
import dev.patrickgold.florisboard.lib.devtools.LogTopic
import dev.patrickgold.florisboard.lib.devtools.flogError
@@ -120,8 +121,6 @@ import org.florisboard.lib.android.isOrientationPortrait
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.showShortToastSync
import org.florisboard.lib.android.systemServiceOrNull
import org.florisboard.lib.compose.ProvideLocalizedResources
import org.florisboard.lib.kotlin.collectLatestIn
import org.florisboard.lib.kotlin.collectIn
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggButton
@@ -573,10 +572,7 @@ class FlorisImeService : LifecycleInputMethodService() {
@Composable
private fun ImeUiWrapper() {
ProvideLocalizedResources(
resourcesContext,
appName = R.string.app_name,
) {
ProvideLocalizedResources(resourcesContext) {
ProvideKeyboardRowBaseHeight {
CompositionLocalProvider(LocalInputFeedbackController provides inputFeedbackController) {
FlorisImeTheme {
@@ -713,11 +709,7 @@ class FlorisImeService : LifecycleInputMethodService() {
val keyboardManager by context.keyboardManager()
val state by keyboardManager.activeState.collectAsState()
ProvideLocalizedResources(
resourcesContext,
appName = R.string.app_name,
forceLayoutDirection = LayoutDirection.Ltr,
) {
ProvideLocalizedResources(resourcesContext, forceLayoutDirection = LayoutDirection.Ltr) {
FlorisImeTheme {
BottomSheetHostUi(
isShowing = state.isBottomSheetShowing() || state.isSubtypeSelectionShowing(),
@@ -769,11 +761,7 @@ class FlorisImeService : LifecycleInputMethodService() {
@Composable
fun Content() {
ProvideLocalizedResources(
resourcesContext,
appName = R.string.app_name,
forceLayoutDirection = LayoutDirection.Ltr,
) {
ProvideLocalizedResources(resourcesContext, forceLayoutDirection = LayoutDirection.Ltr) {
FlorisImeTheme {
val activeEditorInfo by editorInstance.activeInfoFlow.collectAsState()
SnyggBox(FlorisImeUi.ExtractedLandscapeInputLayout.elementName) {

View File

@@ -20,7 +20,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import dev.patrickgold.florisboard.app.settings.theme.ColorPreferenceSerializer
import dev.patrickgold.florisboard.app.settings.theme.DisplayKbdAfterDialogs
import dev.patrickgold.florisboard.app.settings.theme.SnyggLevel
import dev.patrickgold.florisboard.app.setup.NotificationPermissionState
@@ -54,6 +53,7 @@ import dev.patrickgold.florisboard.ime.text.key.UtilityKeyAction
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.theme.ThemeMode
import dev.patrickgold.florisboard.ime.theme.extCoreTheme
import dev.patrickgold.florisboard.lib.compose.ColorPreferenceSerializer
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
import dev.patrickgold.florisboard.lib.observeAsTransformingState
import dev.patrickgold.florisboard.lib.util.VersionName

View File

@@ -42,10 +42,10 @@ import dev.patrickgold.florisboard.ime.text.gestures.SwipeAction
import dev.patrickgold.florisboard.ime.text.key.KeyHintMode
import dev.patrickgold.florisboard.ime.text.key.UtilityKeyAction
import dev.patrickgold.florisboard.ime.theme.ThemeMode
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.ListPreferenceEntry
import dev.patrickgold.jetpref.datastore.ui.listPrefEntries
import dev.patrickgold.jetpref.material.ui.ColorRepresentation
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.curlyFormat
import kotlin.reflect.KClass

View File

@@ -51,16 +51,16 @@ import dev.patrickgold.florisboard.cacheManager
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.LocalPreviewFieldController
import dev.patrickgold.florisboard.lib.compose.PreviewKeyboardField
import dev.patrickgold.florisboard.lib.compose.ProvideLocalizedResources
import dev.patrickgold.florisboard.lib.compose.conditional
import dev.patrickgold.florisboard.lib.compose.rememberPreviewFieldController
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.util.AppVersionUtils
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.ProvideDefaultDialogPrefStrings
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.hideAppIcon
import org.florisboard.lib.android.showAppIcon
import org.florisboard.lib.compose.ProvideLocalizedResources
import org.florisboard.lib.compose.conditional
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.collectIn
import java.util.concurrent.atomic.AtomicBoolean
@@ -121,10 +121,7 @@ class FlorisAppActivity : ComponentActivity() {
}
AppVersionUtils.updateVersionOnInstallAndLastUse(this, prefs)
setContent {
ProvideLocalizedResources(
resourcesContext,
appName = R.string.app_name,
) {
ProvideLocalizedResources(resourcesContext) {
FlorisAppTheme(theme = appTheme) {
Surface(color = MaterialTheme.colorScheme.background) {
AppContent()
@@ -197,7 +194,7 @@ class FlorisAppActivity : ComponentActivity() {
Routes.AppNavHost(
modifier = Modifier.weight(1.0f),
navController = navController,
startDestination = if (isImeSetUp) Routes.Settings.Home::class else Routes.Setup.Screen::class,
startDestination = if (isImeSetUp) Routes.Settings.Home else Routes.Setup.Screen,
)
PreviewKeyboardField(previewFieldController)
}

View File

@@ -17,17 +17,12 @@
package dev.patrickgold.florisboard.app
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.unit.IntOffset
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavGraphBuilder
@@ -35,7 +30,6 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
import androidx.navigation.toRoute
import dev.patrickgold.florisboard.app.devtools.AndroidLocalesScreen
import dev.patrickgold.florisboard.app.devtools.AndroidSettingsScreen
import dev.patrickgold.florisboard.app.devtools.DevtoolsScreen
@@ -76,185 +70,113 @@ import dev.patrickgold.florisboard.app.settings.theme.ThemeManagerScreenAction
import dev.patrickgold.florisboard.app.settings.theme.ThemeScreen
import dev.patrickgold.florisboard.app.settings.typing.TypingScreen
import dev.patrickgold.florisboard.app.setup.SetupScreen
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.reflect.KClass
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Deeplink(val path: String)
inline fun <reified T : Any> NavGraphBuilder.composableWithDeepLink(
kClass: KClass<T>,
noinline content: @Composable (AnimatedContentScope.(NavBackStackEntry) -> Unit),
) {
val deeplink = requireNotNull(kClass.annotations.firstOrNull { it is Deeplink } as? Deeplink) {
"faulty class: $kClass with annotations ${kClass.annotations}"
}
composable<T>(
deepLinks = listOf(navDeepLink<T>(basePath = "ui://florisboard/${deeplink.path}")),
content = content,
)
}
import org.florisboard.lib.kotlin.curlyFormat
@Suppress("FunctionName", "ConstPropertyName")
object Routes {
object Setup {
@Serializable
object Screen
const val Screen = "setup"
}
object Settings {
@Serializable
@Deeplink("settings/home")
object Home
const val Home = "settings"
@Serializable
@Deeplink("settings/localization")
object Localization
const val Localization = "settings/localization"
const val SelectLocale = "settings/localization/select-locale"
const val LanguagePackManager = "settings/localization/language-pack-manage/{action}"
fun LanguagePackManager(action: LanguagePackManagerScreenAction) =
LanguagePackManager.curlyFormat("action" to action.id)
const val SubtypeAdd = "settings/localization/subtype/add"
const val SubtypeEdit = "settings/localization/subtype/edit/{id}"
fun SubtypeEdit(id: Long) = SubtypeEdit.curlyFormat("id" to id)
@Serializable
@Deeplink("settings/localization/select-locale")
object SelectLocale
const val Theme = "settings/theme"
const val ThemeManager = "settings/theme/manage/{action}"
fun ThemeManager(action: ThemeManagerScreenAction) = ThemeManager.curlyFormat("action" to action.id)
@Serializable
@Deeplink("settings/localization/language-pack-manage")
data class LanguagePackManager(val action: LanguagePackManagerScreenAction)
const val Keyboard = "settings/keyboard"
const val InputFeedback = "settings/keyboard/input-feedback"
@Serializable
@Deeplink("settings/localization/subtype/add")
object SubtypeAdd
const val Smartbar = "settings/smartbar"
@Serializable
@Deeplink("settings/localization/subtype/edit")
data class SubtypeEdit(val id: Long)
const val Typing = "settings/typing"
@Serializable
@Deeplink("settings/theme")
object Theme
const val Dictionary = "settings/dictionary"
const val UserDictionary = "settings/dictionary/user-dictionary/{type}"
fun UserDictionary(type: UserDictionaryType) = UserDictionary.curlyFormat("type" to type.id)
@Serializable
@Deeplink("settings/theme/manage")
data class ThemeManager(val action: ThemeManagerScreenAction)
const val Gestures = "settings/gestures"
@Serializable
@Deeplink("settings/keyboard")
object Keyboard
const val Clipboard = "settings/clipboard"
@Serializable
@Deeplink("settings/keyboard/input-feedback")
object InputFeedback
const val Media = "settings/media"
@Serializable
@Deeplink("settings/smartbar")
object Smartbar
const val Other = "settings/other"
const val PhysicalKeyboard = "settings/other/physical-keyboard"
const val Backup = "settings/other/backup"
const val Restore = "settings/other/restore"
@Serializable
@Deeplink("settings/typing")
object Typing
@Serializable
@Deeplink("settings/dictionary")
object Dictionary
@Serializable
@Deeplink("settings/dictionary/user-dictionary")
data class UserDictionary(val type: UserDictionaryType)
@Serializable
@Deeplink("settings/gestures")
object Gestures
@Serializable
@Deeplink("settings/clipboard")
object Clipboard
@Serializable
@Deeplink("settings/media")
object Media
@Serializable
@Deeplink("settings/other")
object Other
@Serializable
@Deeplink("settings/other/physical-keyboard")
object PhysicalKeyboard
@Serializable
@Deeplink("settings/other/backup")
object Backup
@Serializable
@Deeplink("settings/other/restore")
object Restore
@Serializable
@Deeplink("settings/about")
object About
@Serializable
@Deeplink("settings/about/project-license")
object ProjectLicense
@Serializable
@Deeplink("settings/about/third-party-licenses")
object ThirdPartyLicenses
const val About = "settings/about"
const val ProjectLicense = "settings/about/project-license"
const val ThirdPartyLicenses = "settings/about/third-party-licenses"
}
object Devtools {
@Serializable
@Deeplink("devtools")
object Home
const val Home = "devtools"
@Serializable
@Deeplink("devtools/android/locales")
object AndroidLocales
const val AndroidLocales = "devtools/android/locales"
const val AndroidSettings = "devtools/android/settings/{name}"
fun AndroidSettings(name: String) = AndroidSettings.curlyFormat("name" to name)
@Serializable
@Deeplink("devtools/android/settings")
data class AndroidSettings(val name: String)
@Serializable
@Deeplink("export-debug-log")
object ExportDebugLog
const val ExportDebugLog = "export-debug-log"
}
object Ext {
@Serializable
@Deeplink("ext")
object Home
const val Home = "ext"
@Serializable
@Deeplink("ext/list")
data class List(val type: ExtensionListScreenType, val showUpdate: Boolean? = null)
const val List = "ext/list/{type}?showUpdate={showUpdate}"
fun List(
type: ExtensionListScreenType,
showUpdate: Boolean
) = List.curlyFormat("type" to type.id, "showUpdate" to showUpdate)
@Serializable
@Deeplink("ext/edit")
data class Edit(val id: String, @SerialName("create") val serialType: String? = null)
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 ?: ""))
}
@Serializable
@Deeplink("ext/export")
data class Export(val id: String)
const val Export = "ext/export/{id}"
fun Export(id: String) = Export.curlyFormat("id" to id)
@Serializable
@Deeplink("ext/import")
data class Import(val type: ExtensionImportScreenType, val uuid: String? = null)
const val Import = "ext/import/{type}?uuid={uuid}"
fun Import(
type: ExtensionImportScreenType,
uuid: String?,
) = Import.curlyFormat("type" to type.id, "uuid" to uuid.toString())
@Serializable
@Deeplink("ext/view")
data class View(val id: String)
const val View = "ext/view/{id}"
fun View(id: String) = View.curlyFormat("id" to id)
@Serializable
@Deeplink("ext/check-updates")
object CheckUpdates
const val CheckUpdates = "ext/check-updates"
}
@Composable
fun AppNavHost(
modifier: Modifier,
navController: NavHostController,
startDestination: KClass<*>,
startDestination: String,
) {
fun NavGraphBuilder.composableWithDeepLink(
route: String,
content: @Composable (AnimatedContentScope.(NavBackStackEntry) -> Unit),
) {
composable(
route = route,
deepLinks = listOf(navDeepLink { uriPattern = "ui://florisboard/$route" }),
content = content,
)
}
NavHost(
modifier = modifier,
navController = navController,
@@ -265,103 +187,109 @@ object Routes {
exitTransition = {
slideOut { IntOffset(-it.width, 0) } + fadeOut()
},
popEnterTransition = { EnterTransition.None },
popExitTransition = {
scaleOut(
targetScale = 0.85F,
transformOrigin = TransformOrigin(pivotFractionX = 0.8f, pivotFractionY = 0.5f)
) + fadeOut(spring(stiffness = Spring.StiffnessMedium))
popEnterTransition = {
slideIn { IntOffset(-it.width, 0) } + fadeIn()
},
popExitTransition = {
slideOut { IntOffset(it.width, 0) } + fadeOut()
}
) {
composable<Setup.Screen> { SetupScreen() }
composable(Setup.Screen) { SetupScreen() }
composableWithDeepLink(Settings.Home::class) { HomeScreen() }
composableWithDeepLink(Settings.Home) { HomeScreen() }
composableWithDeepLink(Settings.Localization::class) { LocalizationScreen() }
composableWithDeepLink(Settings.SelectLocale::class) { SelectLocaleScreen() }
composableWithDeepLink(Settings.LanguagePackManager::class) { navBackStack ->
val payload = navBackStack.toRoute<Settings.LanguagePackManager>()
LanguagePackManagerScreen(payload.action)
composableWithDeepLink(Settings.Localization) { LocalizationScreen() }
composableWithDeepLink(Settings.SelectLocale) { SelectLocaleScreen() }
composableWithDeepLink(Settings.LanguagePackManager) { navBackStack ->
val action = navBackStack.arguments?.getString("action")?.let { actionId ->
LanguagePackManagerScreenAction.entries.firstOrNull { it.id == actionId }
}
LanguagePackManagerScreen(action)
}
composableWithDeepLink(Settings.SubtypeAdd::class) { SubtypeEditorScreen(null) }
composableWithDeepLink(Settings.SubtypeEdit::class) { navBackStack ->
val payload = navBackStack.toRoute<Settings.SubtypeEdit>()
SubtypeEditorScreen(payload.id)
composableWithDeepLink(Settings.SubtypeAdd) { SubtypeEditorScreen(null) }
composableWithDeepLink(Settings.SubtypeEdit) { navBackStack ->
val id = navBackStack.arguments?.getString("id")?.toLongOrNull()
SubtypeEditorScreen(id)
}
composableWithDeepLink(Settings.Theme::class) { ThemeScreen() }
composableWithDeepLink(Settings.ThemeManager::class) { navBackStack ->
val payload = navBackStack.toRoute<Settings.ThemeManager>()
ThemeManagerScreen(payload.action)
composableWithDeepLink(Settings.Theme) { ThemeScreen() }
composableWithDeepLink(Settings.ThemeManager) { navBackStack ->
val action = navBackStack.arguments?.getString("action")?.let { actionId ->
ThemeManagerScreenAction.entries.firstOrNull { it.id == actionId }
}
ThemeManagerScreen(action)
}
composableWithDeepLink(Settings.Keyboard::class) { KeyboardScreen() }
composableWithDeepLink(Settings.InputFeedback::class) { InputFeedbackScreen() }
composableWithDeepLink(Settings.Keyboard) { KeyboardScreen() }
composableWithDeepLink(Settings.InputFeedback) { InputFeedbackScreen() }
composableWithDeepLink(Settings.Smartbar::class) { SmartbarScreen() }
composableWithDeepLink(Settings.Smartbar) { SmartbarScreen() }
composableWithDeepLink(Settings.Typing::class) { TypingScreen() }
composableWithDeepLink(Settings.Typing) { TypingScreen() }
composableWithDeepLink(Settings.Dictionary::class) { DictionaryScreen() }
composableWithDeepLink(Settings.UserDictionary::class) { navBackStack ->
val payload = navBackStack.toRoute<Settings.UserDictionary>()
UserDictionaryScreen(payload.type)
composableWithDeepLink(Settings.Dictionary) { DictionaryScreen() }
composableWithDeepLink(Settings.UserDictionary) { navBackStack ->
val type = navBackStack.arguments?.getString("type")?.let { typeId ->
UserDictionaryType.entries.firstOrNull { it.id == typeId }
}
UserDictionaryScreen(type!!)
}
composableWithDeepLink(Settings.Gestures::class) { GesturesScreen() }
composableWithDeepLink(Settings.Gestures) { GesturesScreen() }
composableWithDeepLink(Settings.Clipboard::class) { ClipboardScreen() }
composableWithDeepLink(Settings.Clipboard) { ClipboardScreen() }
composableWithDeepLink(Settings.Media::class) { MediaScreen() }
composableWithDeepLink(Settings.Media) { MediaScreen() }
composableWithDeepLink(Settings.Other::class) { OtherScreen() }
composableWithDeepLink(Settings.PhysicalKeyboard::class) { PhysicalKeyboardScreen() }
composableWithDeepLink(Settings.Backup::class) { BackupScreen() }
composableWithDeepLink(Settings.Restore::class) { RestoreScreen() }
composableWithDeepLink(Settings.Other) { OtherScreen() }
composableWithDeepLink(Settings.PhysicalKeyboard) { PhysicalKeyboardScreen() }
composableWithDeepLink(Settings.Backup) { BackupScreen() }
composableWithDeepLink(Settings.Restore) { RestoreScreen() }
composableWithDeepLink(Settings.About::class) { AboutScreen() }
composableWithDeepLink(Settings.ProjectLicense::class) { ProjectLicenseScreen() }
composableWithDeepLink(Settings.ThirdPartyLicenses::class) { ThirdPartyLicensesScreen() }
composableWithDeepLink(Settings.About) { AboutScreen() }
composableWithDeepLink(Settings.ProjectLicense) { ProjectLicenseScreen() }
composableWithDeepLink(Settings.ThirdPartyLicenses) { ThirdPartyLicensesScreen() }
composableWithDeepLink(Devtools.Home::class) { DevtoolsScreen() }
composableWithDeepLink(Devtools.AndroidLocales::class) { AndroidLocalesScreen() }
composableWithDeepLink(Devtools.AndroidSettings::class) { navBackStack ->
val payload = navBackStack.toRoute<Devtools.AndroidSettings>()
AndroidSettingsScreen(payload.name)
composableWithDeepLink(Devtools.Home) { DevtoolsScreen() }
composableWithDeepLink(Devtools.AndroidLocales) { AndroidLocalesScreen() }
composableWithDeepLink(Devtools.AndroidSettings) { navBackStack ->
val name = navBackStack.arguments?.getString("name")
AndroidSettingsScreen(name)
}
composableWithDeepLink(Devtools.ExportDebugLog::class) { ExportDebugLogScreen() }
composableWithDeepLink(Devtools.ExportDebugLog) { ExportDebugLogScreen() }
composableWithDeepLink(Ext.Home::class) { ExtensionHomeScreen() }
composableWithDeepLink(Ext.List::class) { navBackStack ->
val payload = navBackStack.toRoute<Ext.List>()
val showUpdate = payload.showUpdate != null && payload.showUpdate
ExtensionListScreen(payload.type, showUpdate)
composableWithDeepLink(Ext.Home) { ExtensionHomeScreen() }
composableWithDeepLink(Ext.List) { navBackStack ->
val type = navBackStack.arguments?.getString("type")?.let { typeId ->
ExtensionListScreenType.entries.firstOrNull { it.id == typeId }
} ?: error("unknown type")
val showUpdate = navBackStack.arguments?.getString("showUpdate")
ExtensionListScreen(type, showUpdate == "true")
}
composableWithDeepLink(Ext.Edit::class) { navBackStack ->
val payload = navBackStack.toRoute<Ext.Edit>()
val extensionId = payload.id
val serialType = payload.serialType
composableWithDeepLink(Ext.Edit) { navBackStack ->
val extensionId = navBackStack.arguments?.getString("id")
val serialType = navBackStack.arguments?.getString("serial_type")
ExtensionEditScreen(
id = extensionId,
id = extensionId.toString(),
createSerialType = serialType.takeIf { !it.isNullOrBlank() },
)
}
composableWithDeepLink(Ext.Export::class) { navBackStack ->
val payload = navBackStack.toRoute<Ext.Export>()
val extensionId = payload.id
ExtensionExportScreen(id = extensionId)
composableWithDeepLink(Ext.Export) { navBackStack ->
val extensionId = navBackStack.arguments?.getString("id")
ExtensionExportScreen(id = extensionId.toString())
}
composableWithDeepLink(Ext.Import::class) { navBackStack ->
val payload = navBackStack.toRoute<Ext.Import>()
val uuid = payload.uuid
ExtensionImportScreen(payload.type, uuid)
composableWithDeepLink(Ext.Import) { navBackStack ->
val type = navBackStack.arguments?.getString("type")?.let { typeId ->
ExtensionImportScreenType.entries.firstOrNull { it.id == typeId }
} ?: ExtensionImportScreenType.EXT_ANY
val uuid = navBackStack.arguments?.getString("uuid")?.takeIf { it != "null" }
ExtensionImportScreen(type, uuid)
}
composableWithDeepLink(Ext.View::class) { navBackStack ->
val payload = navBackStack.toRoute<Ext.View>()
val extensionId = payload.id
ExtensionViewScreen(id = extensionId)
composableWithDeepLink(Ext.View) { navBackStack ->
val extensionId = navBackStack.arguments?.getString("id")
ExtensionViewScreen(id = extensionId.toString())
}
composableWithDeepLink(Ext.CheckUpdates::class) {
composableWithDeepLink(Ext.CheckUpdates) {
CheckUpdatesScreen()
}
}

View File

@@ -32,11 +32,12 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.core.DisplayLanguageNamesIn
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.io.subDir
import org.florisboard.lib.kotlin.io.subFile
import java.util.Locale

View File

@@ -27,11 +27,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import dev.patrickgold.florisboard.R
import org.florisboard.lib.android.AndroidSettings
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import org.florisboard.lib.android.AndroidSettings
import org.florisboard.lib.compose.stringRes
@Composable
fun AndroidSettingsScreen(name: String?) = FlorisScreen {

View File

@@ -29,17 +29,18 @@ import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.ime.dictionary.DictionaryManager
import dev.patrickgold.florisboard.ime.dictionary.FlorisUserDictionaryDatabase
import dev.patrickgold.florisboard.ime.smartbar.quickaction.QuickActionArrangement
import dev.patrickgold.florisboard.ime.smartbar.quickaction.QuickActionJsonConfig
import org.florisboard.lib.android.AndroidSettings
import org.florisboard.lib.android.showLongToast
import dev.patrickgold.florisboard.lib.compose.FlorisConfirmDeleteDialog
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.android.AndroidSettings
import kotlinx.coroutines.launch
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.android.showLongToastSync
class DebugOnPurposeCrashException : Exception(

View File

@@ -40,13 +40,13 @@ import androidx.compose.ui.unit.sp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.clipboardManager
import dev.patrickgold.florisboard.lib.compose.FlorisButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.devtools.Devtools
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.compose.FlorisButton
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.android.showShortToastSync
// TODO: This screen is just a quick thrown-together thing and needs further enhancing in the UI

View File

@@ -35,13 +35,13 @@ import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
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.Extension
import dev.patrickgold.florisboard.lib.ext.generateUpdateUrl
import dev.patrickgold.florisboard.lib.util.launchUrl
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisTextButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.curlyFormat
@Composable

View File

@@ -21,7 +21,7 @@ import androidx.compose.ui.platform.LocalContext
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.stringRes
@Composable
fun CheckUpdatesScreen() = FlorisScreen {

View File

@@ -40,13 +40,13 @@ import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.nlp.LanguagePackComponent
import dev.patrickgold.florisboard.ime.theme.ThemeExtensionComponent
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionComponent
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
import dev.patrickgold.florisboard.lib.ext.ExtensionMeta
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisTextButton
import org.florisboard.lib.compose.stringRes
@Composable
fun ExtensionComponentNoneFoundView() {

View File

@@ -48,7 +48,9 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import dev.patrickgold.jetpref.material.ui.JetPrefTextField
@@ -60,8 +62,6 @@ import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.showShortToastSync
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.io.parentDir
import org.florisboard.lib.kotlin.io.subDir
import org.florisboard.lib.kotlin.io.subFile

View File

@@ -42,9 +42,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.LocalNavController
@@ -62,9 +60,15 @@ import dev.patrickgold.florisboard.ime.theme.ThemeExtensionComponentImpl
import dev.patrickgold.florisboard.ime.theme.ThemeExtensionEditor
import dev.patrickgold.florisboard.lib.ValidationResult
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisButtonBar
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
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.FlorisUnsavedChangesDialog
import dev.patrickgold.florisboard.lib.compose.Validation
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.Extension
import dev.patrickgold.florisboard.lib.ext.ExtensionComponent
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
@@ -81,15 +85,11 @@ import dev.patrickgold.florisboard.lib.io.ZipUtils
import dev.patrickgold.florisboard.lib.rememberValidationResult
import dev.patrickgold.florisboard.themeManager
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.vectorResource
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import dev.patrickgold.jetpref.material.ui.JetPrefTextField
import java.util.*
import org.florisboard.lib.compose.FlorisButtonBar
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.FlorisInfoCard
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.kotlin.io.deleteContentsRecursively
import org.florisboard.lib.kotlin.io.subDir
@@ -353,7 +353,7 @@ private fun EditScreen(
)
Preference(
onClick = { workspace.currentAction = EditorAction.ManageFiles },
icon = ImageVector.vectorResource(R.drawable.ic_file_blank),
icon = vectorResource(R.drawable.ic_file_blank),
title = stringRes(R.string.ext__editor__files__title),
)
}

View File

@@ -27,8 +27,8 @@ import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
import org.florisboard.lib.compose.stringRes
@Composable
fun ExtensionHomeScreen() = FlorisScreen {

View File

@@ -50,16 +50,17 @@ 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.NATIVE_NULLPTR
import org.florisboard.lib.android.showLongToast
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisBulletSpacer
import dev.patrickgold.florisboard.lib.compose.FlorisButtonBar
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.io.FileRegistry
import org.florisboard.lib.compose.FlorisBulletSpacer
import org.florisboard.lib.compose.FlorisButtonBar
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisOutlinedButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.kotlin.resultOk

View File

@@ -20,7 +20,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.florisboard.lib.compose.FlorisChip
import dev.patrickgold.florisboard.lib.compose.FlorisChip
@Composable
fun ExtensionKeywordChip(

View File

@@ -52,14 +52,14 @@ import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.extensionManager
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.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionManager
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisTextButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.stringRes
enum class ExtensionListScreenType(
val id: String,

View File

@@ -30,10 +30,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.lib.compose.FlorisChip
import dev.patrickgold.florisboard.lib.ext.ExtensionMaintainer
import dev.patrickgold.florisboard.lib.util.launchUrl
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import org.florisboard.lib.compose.FlorisChip
@Composable
fun ExtensionMaintainerChip(

View File

@@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.stringRes
@Composable
internal fun ExtensionNotFoundScreen(id: String) = FlorisScreen {

View File

@@ -51,17 +51,18 @@ import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.ime.nlp.LanguagePackExtension
import dev.patrickgold.florisboard.ime.theme.ThemeExtension
import dev.patrickgold.florisboard.ime.theme.ThemeExtensionComponentImpl
import org.florisboard.lib.android.showLongToast
import dev.patrickgold.florisboard.lib.compose.FlorisConfirmDeleteDialog
import dev.patrickgold.florisboard.lib.compose.FlorisHyperlinkText
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.Extension
import dev.patrickgold.florisboard.lib.ext.ExtensionMaintainer
import dev.patrickgold.florisboard.lib.ext.ExtensionMeta
import dev.patrickgold.florisboard.lib.io.FlorisRef
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.compose.FlorisOutlinedButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.stringRes
@Composable
fun ExtensionViewScreen(id: String) {

View File

@@ -37,13 +37,13 @@ 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.compose.FlorisErrorCard
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.FlorisWarningCard
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.util.InputMethodUtils
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.Preference
import org.florisboard.lib.compose.FlorisErrorCard
import org.florisboard.lib.compose.FlorisWarningCard
import org.florisboard.lib.compose.stringRes
@Composable
fun HomeScreen() = FlorisScreen {

View File

@@ -41,12 +41,12 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.clipboardManager
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.util.launchUrl
import dev.patrickgold.jetpref.datastore.ui.Preference
import org.florisboard.lib.android.stringRes
import org.florisboard.lib.compose.FlorisCanvasIcon
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.FlorisCanvasIcon
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
@Composable
fun AboutScreen() = FlorisScreen {

View File

@@ -29,11 +29,11 @@ import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.compose.florisVerticalScroll
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.io.FlorisRef
import dev.patrickgold.florisboard.lib.io.loadTextAsset
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.compose.florisVerticalScroll
import org.florisboard.lib.compose.stringRes
@Composable
fun ProjectLicenseScreen() = FlorisScreen {

View File

@@ -26,8 +26,8 @@ import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import com.mikepenz.aboutlibraries.ui.compose.m3.libraryColors
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.stringRes
@Composable
fun ThirdPartyLicensesScreen() = FlorisScreen {

View File

@@ -50,7 +50,12 @@ import dev.patrickgold.florisboard.clipboardManager
import dev.patrickgold.florisboard.ime.clipboard.provider.ClipboardFileStorage
import dev.patrickgold.florisboard.ime.clipboard.provider.ItemType
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisButtonBar
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.devtools.flogError
import dev.patrickgold.florisboard.lib.ext.ExtensionManager
import dev.patrickgold.florisboard.lib.io.FileRegistry
@@ -64,11 +69,6 @@ import kotlinx.serialization.Serializable
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.android.writeFromFile
import org.florisboard.lib.compose.FlorisButtonBar
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.io.subDir
import org.florisboard.lib.kotlin.io.subFile
import org.florisboard.lib.kotlin.io.writeJson

View File

@@ -27,9 +27,7 @@ import androidx.compose.material.icons.filled.SettingsBackupRestore
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.AppTheme
import dev.patrickgold.florisboard.app.LocalNavController
@@ -38,6 +36,7 @@ import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.core.DisplayLanguageNamesIn
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.ColorPickerPreference
import dev.patrickgold.jetpref.datastore.ui.ListPreference
@@ -46,9 +45,9 @@ import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import dev.patrickgold.jetpref.datastore.ui.isMaterialYou
import dev.patrickgold.jetpref.datastore.ui.listPrefEntries
import dev.patrickgold.jetpref.datastore.ui.vectorResource
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.color.ColorMappings
import org.florisboard.lib.compose.stringRes
@Composable
@@ -157,7 +156,7 @@ fun OtherScreen() = FlorisScreen {
enabledIf = { AndroidVersion.ATMOST_API28_P },
)
Preference(
icon = ImageVector.vectorResource(R.drawable.ic_keyboard_keys),
icon = vectorResource(R.drawable.ic_keyboard_keys),
title = stringRes(R.string.physical_keyboard__title),
onClick = { navController.navigate(Routes.Settings.PhysicalKeyboard) },
)

View File

@@ -28,9 +28,9 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.compose.stringRes
@Composable
fun PhysicalKeyboardScreen() = FlorisScreen {

View File

@@ -52,32 +52,32 @@ import dev.patrickgold.florisboard.ime.clipboard.provider.ClipboardFileStorage
import dev.patrickgold.florisboard.ime.clipboard.provider.ClipboardItem
import dev.patrickgold.florisboard.ime.clipboard.provider.ItemType
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisButtonBar
import dev.patrickgold.florisboard.lib.compose.FlorisCardDefaults
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
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.io.ZipUtils
import dev.patrickgold.jetpref.datastore.runtime.AndroidAppDataStorage
import dev.patrickgold.jetpref.datastore.runtime.FileBasedStorage
import dev.patrickgold.jetpref.datastore.runtime.ImportStrategy
import dev.patrickgold.jetpref.datastore.ui.Preference
import java.io.FileNotFoundException
import java.text.DateFormat
import java.util.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.florisboard.lib.android.readToFile
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.compose.FlorisButtonBar
import org.florisboard.lib.compose.FlorisCardDefaults
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisOutlinedButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.io.deleteContentsRecursively
import org.florisboard.lib.kotlin.io.readJson
import org.florisboard.lib.kotlin.io.subDir
import org.florisboard.lib.kotlin.io.subFile
import java.io.FileNotFoundException
import java.text.DateFormat
import java.util.*
object Restore {
const val MIN_VERSION_CODE = 64

View File

@@ -20,13 +20,13 @@ import androidx.compose.runtime.Composable
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.clipboard.CLIPBOARD_HISTORY_NUM_GRID_COLUMNS_AUTO
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.pluralsRes
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.DialogSliderPreference
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.compose.pluralsRes
import org.florisboard.lib.compose.stringRes
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable

View File

@@ -21,9 +21,9 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.compose.stringRes
@Composable
fun DictionaryScreen() = FlorisScreen {

View File

@@ -55,8 +55,11 @@ import dev.patrickgold.florisboard.ime.dictionary.UserDictionaryDao
import dev.patrickgold.florisboard.ime.dictionary.UserDictionaryEntry
import dev.patrickgold.florisboard.ime.dictionary.UserDictionaryValidation
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.Validation
import dev.patrickgold.florisboard.lib.compose.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.rememberValidationResult
import dev.patrickgold.florisboard.lib.util.launchActivity
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
@@ -67,9 +70,6 @@ import kotlinx.coroutines.launch
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.android.stringRes
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.compose.stringRes
private val AllLanguagesLocale = FlorisLocale.from(language = "zz")
private val UserDictionaryEntryToAdd = UserDictionaryEntry(id = 0, "", 255, null, null)

View File

@@ -23,13 +23,14 @@ import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.text.gestures.SwipeAction
import dev.patrickgold.florisboard.lib.compose.FlorisInfoCard
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
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.PreferenceGroup
import org.florisboard.lib.compose.FlorisInfoCard
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable

View File

@@ -23,6 +23,7 @@ import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.input.HapticVibrationMode
import dev.patrickgold.florisboard.ime.input.InputFeedbackActivationMode
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.DialogSliderPreference
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
import dev.patrickgold.jetpref.datastore.ui.ListPreference
@@ -30,7 +31,6 @@ import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.android.systemVibratorOrNull
import org.florisboard.lib.android.vibrate
import org.florisboard.lib.compose.stringRes
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable

View File

@@ -29,13 +29,13 @@ import dev.patrickgold.florisboard.ime.smartbar.IncognitoDisplayMode
import dev.patrickgold.florisboard.ime.text.key.KeyHintMode
import dev.patrickgold.florisboard.ime.text.key.UtilityKeyAction
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
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
import org.florisboard.lib.compose.stringRes
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable

View File

@@ -47,20 +47,20 @@ import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.app.ext.ExtensionImportScreenType
import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.ime.nlp.LanguagePackComponent
import org.florisboard.lib.android.showLongToast
import dev.patrickgold.florisboard.lib.compose.FlorisConfirmDeleteDialog
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.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.Extension
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.material.ui.JetPrefListItem
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.FlorisTextButton
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.android.showLongToastSync
enum class LanguagePackManagerScreenAction(val id: String) {

View File

@@ -45,6 +45,8 @@ import dev.patrickgold.florisboard.ime.core.Subtype
import dev.patrickgold.florisboard.ime.keyboard.LayoutType
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.FlorisWarningCard
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import dev.patrickgold.florisboard.subtypeManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
@@ -53,9 +55,8 @@ import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.florisboard.lib.compose.FlorisWarningCard
import org.florisboard.lib.compose.stringRes
internal val SubtypeSaver = Saver<MutableState<Subtype?>, String>(
save = {

View File

@@ -49,10 +49,10 @@ import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.ime.core.DisplayLanguageNamesIn
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.material.ui.JetPrefListItem
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.stringRes
const val SelectLocaleScreenResultLanguageTag = "SelectLocaleScreen.languageTag"

View File

@@ -37,7 +37,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ShapeDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -75,20 +74,18 @@ import dev.patrickgold.florisboard.ime.nlp.han.HanShapeBasedLanguageProvider
import dev.patrickgold.florisboard.ime.nlp.latin.LatinLanguageProvider
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.FlorisButtonBar
import dev.patrickgold.florisboard.lib.compose.FlorisDropdownLikeButton
import dev.patrickgold.florisboard.lib.compose.FlorisDropdownMenu
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import dev.patrickgold.florisboard.subtypeManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import dev.patrickgold.jetpref.material.ui.JetPrefDropdown
import dev.patrickgold.jetpref.material.ui.JetPrefDropdownMenuDefaults
import dev.patrickgold.jetpref.material.ui.JetPrefListItem
import org.florisboard.lib.compose.FlorisButtonBar
import org.florisboard.lib.compose.FlorisDropdownLikeButton
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.stringRes
private val SelectComponentName = ExtensionComponentName("00", "00")
private val SelectNlpProviderId = SelectComponentName.toString()
@@ -368,7 +365,6 @@ fun SubtypeEditorScreen(id: Long?) = FlorisScreen {
onClick = {
navController.navigate(Routes.Settings.SelectLocale)
},
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
)
}
SubtypeProperty(stringRes(R.string.settings__localization__subtype_popup_mapping)) {
@@ -378,15 +374,16 @@ fun SubtypeEditorScreen(id: Long?) = FlorisScreen {
val popupMappingLabels = remember(popupMappings) {
selectListValues + popupMappings.values.map { it.label }
}
val expanded = remember { mutableStateOf(false) }
var expanded by remember { mutableStateOf(false) }
val selectedIndex = popupMappingIds.indexOf(popupMapping).coerceAtLeast(0)
JetPrefDropdown(
options = popupMappingLabels,
FlorisDropdownMenu(
items = popupMappingLabels,
expanded = expanded,
selectedOptionIndex = selectedIndex,
selectedIndex = selectedIndex,
isError = showSelectAsError && selectedIndex == 0,
onSelectOption = { popupMapping = popupMappingIds[it] },
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
onSelectItem = { popupMapping = popupMappingIds[it] },
onExpandRequest = { expanded = true },
onDismissRequest = { expanded = false },
)
}
SubtypePropertyDropdown(stringRes(R.string.settings__localization__subtype_characters_layout), LayoutType.CHARACTERS)
@@ -407,18 +404,19 @@ fun SubtypeEditorScreen(id: Long?) = FlorisScreen {
val nlpProviderMappingLabels = remember(nlpProviderMappings) {
selectListValues + nlpProviderMappings.values.map { it }
}
val expanded = remember { mutableStateOf(false) }
var expanded by remember { mutableStateOf(false) }
val selectedIndex = nlpProviderMappingIds.indexOf(nlpProviders.suggestion).coerceAtLeast(0)
JetPrefDropdown(
options = nlpProviderMappingLabels,
FlorisDropdownMenu(
items = nlpProviderMappingLabels,
expanded = expanded,
selectedOptionIndex = selectedIndex,
selectedIndex = selectedIndex,
isError = showSelectAsError && selectedIndex == 0,
onSelectOption = { nlpProviders = SubtypeNlpProviderMap(
onSelectItem = { nlpProviders = SubtypeNlpProviderMap(
suggestion = nlpProviderMappingIds[it],
spelling = nlpProviderMappingIds[it]
) },
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
onExpandRequest = { expanded = true },
onDismissRequest = { expanded = false },
)
}
@@ -434,14 +432,15 @@ fun SubtypeEditorScreen(id: Long?) = FlorisScreen {
val composerNames = remember(composers) {
selectListValues + composers.values.map { it.label }
}
val expanded = remember { mutableStateOf(false) }
JetPrefDropdown(
options = composerNames,
var expanded by remember { mutableStateOf(false) }
FlorisDropdownMenu(
items = composerNames,
expanded = expanded,
selectedOptionIndex = composerIds.indexOf(composer).coerceAtLeast(0),
selectedIndex = composerIds.indexOf(composer).coerceAtLeast(0),
isError = showSelectAsError && composer == SelectComponentName,
onSelectOption = { composer = composerIds[it] },
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
onSelectItem = { composer = composerIds[it] },
onExpandRequest = { expanded = true },
onDismissRequest = { expanded = false },
)
}
SubtypeProperty(stringRes(R.string.settings__localization__subtype_currency_set)) {
@@ -451,14 +450,15 @@ fun SubtypeEditorScreen(id: Long?) = FlorisScreen {
val currencySetNames = remember(currencySets) {
selectListValues + currencySets.values.map { it.label }
}
val expanded = remember { mutableStateOf(false) }
JetPrefDropdown(
options = currencySetNames,
var expanded by remember { mutableStateOf(false) }
FlorisDropdownMenu(
items = currencySetNames,
expanded = expanded,
selectedOptionIndex = currencySetIds.indexOf(currencySet).coerceAtLeast(0),
selectedIndex = currencySetIds.indexOf(currencySet).coerceAtLeast(0),
isError = showSelectAsError && currencySet == SelectComponentName,
onSelectOption = { currencySet = currencySetIds[it] },
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
onSelectItem = { currencySet = currencySetIds[it] },
onExpandRequest = { expanded = true },
onDismissRequest = { expanded = false },
)
}
@@ -556,15 +556,16 @@ private fun SubtypeLayoutDropdown(
val layoutIds = remember(layouts) { SelectListKeys + layouts.keys.toList() }
val layoutLabels = remember(layouts) { selectListValues + layouts.values.map { it.label } }
val layoutId = remember(layoutMap) { layoutMap[layoutType] }
val expanded = remember { mutableStateOf(false) }
var expanded by remember { mutableStateOf(false) }
val selectedIndex = layoutIds.indexOf(layoutId).coerceAtLeast(0)
JetPrefDropdown(
options = layoutLabels,
FlorisDropdownMenu(
items = layoutLabels,
expanded = expanded,
selectedOptionIndex = selectedIndex,
selectedIndex = selectedIndex,
isError = showSelectAsError && selectedIndex == 0,
onSelectOption = { onLayoutMapChanged(layoutMap.copy(layoutType = layoutType, componentName = layoutIds[it])!!) },
appearance = JetPrefDropdownMenuDefaults.outlined(shape = ShapeDefaults.Small),
onSelectItem = { onLayoutMapChanged(layoutMap.copy(layoutType, layoutIds[it])!!) },
onExpandRequest = { expanded = true },
onDismissRequest = { expanded = false },
)
}

View File

@@ -34,6 +34,8 @@ import dev.patrickgold.florisboard.ime.media.emoji.EmojiHistoryHelper
import dev.patrickgold.florisboard.ime.media.emoji.EmojiSkinTone
import dev.patrickgold.florisboard.ime.media.emoji.EmojiSuggestionType
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.pluralsRes
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.DialogSliderPreference
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
import dev.patrickgold.jetpref.datastore.ui.ListPreference
@@ -42,8 +44,6 @@ import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import kotlinx.coroutines.launch
import org.florisboard.lib.compose.pluralsRes
import org.florisboard.lib.compose.stringRes
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable

View File

@@ -24,10 +24,10 @@ import dev.patrickgold.florisboard.ime.smartbar.CandidatesDisplayMode
import dev.patrickgold.florisboard.ime.smartbar.ExtendedActionsPlacement
import dev.patrickgold.florisboard.ime.smartbar.SmartbarLayout
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.ListPreference
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import org.florisboard.lib.compose.stringRes
@Composable
fun SmartbarScreen() = FlorisScreen {

View File

@@ -77,7 +77,13 @@ import dev.patrickgold.florisboard.app.ext.FONTS
import dev.patrickgold.florisboard.app.ext.IMAGES
import dev.patrickgold.florisboard.lib.ValidationResult
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.DpSizeSaver
import dev.patrickgold.florisboard.lib.compose.FlorisChip
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
import dev.patrickgold.florisboard.lib.compose.Validation
import dev.patrickgold.florisboard.lib.compose.florisVerticalScroll
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionValidation
import dev.patrickgold.florisboard.lib.rememberValidationResult
import dev.patrickgold.jetpref.material.ui.ColorRepresentation
@@ -88,14 +94,7 @@ import dev.patrickgold.jetpref.material.ui.JetPrefDropdown
import dev.patrickgold.jetpref.material.ui.JetPrefListItem
import dev.patrickgold.jetpref.material.ui.JetPrefTextField
import dev.patrickgold.jetpref.material.ui.rememberJetPrefColorPickerState
import java.io.File
import org.florisboard.lib.color.ColorPalette
import org.florisboard.lib.compose.DpSizeSaver
import org.florisboard.lib.compose.FlorisChip
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.FlorisTextButton
import org.florisboard.lib.compose.florisVerticalScroll
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.curlyFormat
import org.florisboard.lib.kotlin.io.subDir
import org.florisboard.lib.kotlin.toStringWithoutDotZero
@@ -132,6 +131,7 @@ import org.florisboard.lib.snygg.value.SnyggUndefinedValue
import org.florisboard.lib.snygg.value.SnyggUriValue
import org.florisboard.lib.snygg.value.SnyggValue
import org.florisboard.lib.snygg.value.SnyggValueEncoder
import java.io.File
internal val SnyggEmptyPropertyInfoForAdding = PropertyInfo(
rule = SnyggEmptyRuleForAdding,

View File

@@ -85,7 +85,11 @@ import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.NATIVE_NULLPTR
import dev.patrickgold.florisboard.lib.compose.FlorisChip
import dev.patrickgold.florisboard.lib.compose.FlorisHyperlinkText
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.util.InputMethodUtils
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import dev.patrickgold.jetpref.material.ui.JetPrefDropdown
@@ -94,10 +98,6 @@ import dev.patrickgold.jetpref.material.ui.JetPrefTextFieldDefaults
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.showShortToastSync
import org.florisboard.lib.android.stringRes
import org.florisboard.lib.compose.FlorisChip
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.curlyFormat
import org.florisboard.lib.snygg.SnyggAnnotationRule
import org.florisboard.lib.snygg.SnyggAttributes

View File

@@ -22,11 +22,11 @@ import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.ui.ListPreference
import dev.patrickgold.jetpref.datastore.ui.PreferenceLayout
import dev.patrickgold.jetpref.material.ui.ColorRepresentation
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import org.florisboard.lib.compose.stringRes
private val FineTuneContentPadding = PaddingValues(horizontal = 8.dp)

View File

@@ -80,10 +80,16 @@ import dev.patrickgold.florisboard.ime.theme.ThemeExtensionEditor
import dev.patrickgold.florisboard.ime.theme.ThemeManager
import dev.patrickgold.florisboard.ime.theme.extPreviewTheme
import dev.patrickgold.florisboard.lib.cache.CacheManager
import dev.patrickgold.florisboard.lib.compose.FlorisIconButton
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.PreviewKeyboardField
import dev.patrickgold.florisboard.lib.compose.Validation
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.florisVerticalScroll
import dev.patrickgold.florisboard.lib.compose.rememberPreviewFieldController
import dev.patrickgold.florisboard.lib.compose.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionValidation
import dev.patrickgold.florisboard.lib.rememberValidationResult
import dev.patrickgold.florisboard.themeManager
@@ -94,13 +100,7 @@ import dev.patrickgold.jetpref.material.ui.JetPrefTextField
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.florisVerticalScroll
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.android.showLongToastSync
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.io.subFile
import org.florisboard.lib.snygg.SnyggAnnotationRule
import org.florisboard.lib.snygg.SnyggElementRule

View File

@@ -36,16 +36,16 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.extensionManager
import dev.patrickgold.florisboard.ime.theme.ThemeExtensionComponent
import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
import dev.patrickgold.florisboard.lib.compose.rippleClickable
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.material.ui.JetPrefListItem
import org.florisboard.lib.compose.FlorisOutlinedBox
import org.florisboard.lib.compose.defaultFlorisOutlinedBox
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.compose.stringRes
import kotlinx.coroutines.launch
enum class ThemeManagerScreenAction(val id: String) {

View File

@@ -37,6 +37,7 @@ import dev.patrickgold.florisboard.app.ext.ExtensionListScreenType
import dev.patrickgold.florisboard.ime.theme.ThemeManager
import dev.patrickgold.florisboard.ime.theme.ThemeMode
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
import dev.patrickgold.florisboard.themeManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
@@ -46,7 +47,6 @@ import dev.patrickgold.jetpref.datastore.ui.LocalTimePickerPreference
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.isMaterialYou
import org.florisboard.lib.color.ColorMappings
import org.florisboard.lib.compose.stringRes
@Composable
fun ThemeScreen() = FlorisScreen {

View File

@@ -34,14 +34,14 @@ 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.lib.compose.FlorisCanvasIcon
import dev.patrickgold.florisboard.lib.compose.FlorisErrorCard
import dev.patrickgold.florisboard.lib.compose.FlorisSimpleCard
import dev.patrickgold.florisboard.lib.compose.FlorisWarningCard
import dev.patrickgold.florisboard.lib.compose.observeAsState
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.util.launchActivity
import org.florisboard.lib.android.AndroidSettings
import org.florisboard.lib.compose.FlorisCanvasIcon
import org.florisboard.lib.compose.FlorisErrorCard
import org.florisboard.lib.compose.FlorisSimpleCard
import org.florisboard.lib.compose.FlorisWarningCard
import org.florisboard.lib.compose.observeAsState
import org.florisboard.lib.compose.stringRes
@Composable
fun SpellCheckerServiceSelector(florisSpellCheckerEnabled: MutableState<Boolean>) {

View File

@@ -30,8 +30,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.LocalNavController
@@ -39,17 +37,19 @@ import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.keyboard.IncognitoMode
import dev.patrickgold.florisboard.ime.nlp.SpellingLanguageMode
import dev.patrickgold.florisboard.lib.compose.FlorisErrorCard
import dev.patrickgold.florisboard.lib.compose.FlorisHyperlinkText
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
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
import dev.patrickgold.jetpref.datastore.ui.vectorResource
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.compose.FlorisErrorCard
import org.florisboard.lib.compose.stringRes
@OptIn(ExperimentalJetPrefDatastoreUi::class)
@Composable
@@ -89,7 +89,7 @@ fun TypingScreen() = FlorisScreen {
)
ListPreference(
prefs.suggestion.incognitoMode,
icon = ImageVector.vectorResource(id = R.drawable.ic_incognito),
icon = vectorResource(id = R.drawable.ic_incognito),
title = stringRes(R.string.pref__suggestion__incognito_mode__label),
entries = enumDisplayEntriesOf(IncognitoMode::class),
)

View File

@@ -46,8 +46,13 @@ import dev.patrickgold.florisboard.app.FlorisPreferenceModel
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.lib.compose.FlorisBulletSpacer
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.FlorisScreenScope
import dev.patrickgold.florisboard.lib.compose.FlorisStep
import dev.patrickgold.florisboard.lib.compose.FlorisStepLayout
import dev.patrickgold.florisboard.lib.compose.FlorisStepState
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.util.InputMethodUtils
import dev.patrickgold.florisboard.lib.util.launchActivity
import dev.patrickgold.florisboard.lib.util.launchUrl
@@ -57,11 +62,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.compose.FlorisBulletSpacer
import org.florisboard.lib.compose.FlorisStep
import org.florisboard.lib.compose.FlorisStepLayout
import org.florisboard.lib.compose.FlorisStepState
import org.florisboard.lib.compose.stringRes
@Composable
fun SetupScreen() = FlorisScreen {

View File

@@ -102,11 +102,16 @@ import dev.patrickgold.florisboard.ime.smartbar.VerticalExitTransition
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.LocalLocalizedDateTimeFormatter
import dev.patrickgold.florisboard.lib.compose.autoMirrorForRtl
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.compose.florisVerticalScroll
import dev.patrickgold.florisboard.lib.compose.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import dev.patrickgold.florisboard.lib.observeAsTransformingState
import dev.patrickgold.florisboard.lib.util.NetworkUtils
import dev.patrickgold.jetpref.datastore.model.observeAsState
import java.time.Instant
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.florisboard.lib.android.AndroidKeyguardManager
@@ -114,12 +119,6 @@ import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.showShortToastSync
import org.florisboard.lib.android.systemService
import org.florisboard.lib.compose.LocalLocalizedDateTimeFormatter
import org.florisboard.lib.compose.autoMirrorForRtl
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.compose.florisVerticalScroll
import org.florisboard.lib.compose.rippleClickable
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.snygg.SnyggQueryAttributes
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggButton
@@ -129,6 +128,7 @@ import org.florisboard.lib.snygg.ui.SnyggIcon
import org.florisboard.lib.snygg.ui.SnyggIconButton
import org.florisboard.lib.snygg.ui.SnyggRow
import org.florisboard.lib.snygg.ui.SnyggText
import java.time.Instant
private val ItemWidth = 200.dp
private val DialogWidth = 240.dp

View File

@@ -49,13 +49,13 @@ import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.app.apptheme.FlorisAppTheme
import dev.patrickgold.florisboard.lib.compose.ProvideLocalizedResources
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.android.AndroidClipboardManager
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.stringRes
import org.florisboard.lib.android.systemService
import org.florisboard.lib.compose.ProvideLocalizedResources
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.mimeTypeFilterOf
class FlorisCopyToClipboardActivity : ComponentActivity() {
@@ -136,11 +136,7 @@ class FlorisCopyToClipboardActivity : ComponentActivity() {
@Composable
private fun Content() {
val prefs by FlorisPreferenceStore
ProvideLocalizedResources(
resourcesContext = this,
appName = R.string.app_name,
forceLayoutDirection = LayoutDirection.Ltr,
) {
ProvideLocalizedResources(this, forceLayoutDirection = LayoutDirection.Ltr) {
val theme by prefs.other.settingsTheme.observeAsState()
FlorisAppTheme(theme) {
BottomSheet {

View File

@@ -35,8 +35,8 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.keyboard.KeyboardState
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.subtypeManager
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggColumn
import org.florisboard.lib.snygg.ui.SnyggListItem

View File

@@ -55,7 +55,7 @@ import dev.patrickgold.florisboard.ime.input.InputShiftState
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.key.KeyType
import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.compose.vectorResource
import dev.patrickgold.jetpref.datastore.ui.vectorResource
interface ComputingEvaluator {
val version: Int

View File

@@ -38,8 +38,6 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.GenericShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
@@ -54,7 +52,6 @@ import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
@@ -63,7 +60,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -91,14 +87,14 @@ import dev.patrickgold.florisboard.ime.keyboard.FlorisImeSizing
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
import dev.patrickgold.florisboard.lib.compose.header
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
import kotlinx.coroutines.launch
import org.florisboard.lib.android.AndroidKeyguardManager
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.systemService
import org.florisboard.lib.compose.florisScrollbar
import org.florisboard.lib.compose.header
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.snygg.SnyggSelector
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggIcon
@@ -173,6 +169,7 @@ fun EmojiPaletteView(
}
}
var recentlyUsedVersion by remember { mutableIntStateOf(0) }
val lazyListState = rememberLazyGridState()
val scope = rememberCoroutineScope()
@Composable
@@ -207,111 +204,22 @@ fun EmojiPaletteView(
)
}
fun calculatePageNumbers(): Int {
return when {
!emojiHistoryEnabled -> EmojiCategoryValues.size - 1
else -> EmojiCategoryValues.size
}
}
fun pageNumberToCategory(pageNumber: Int): EmojiCategory {
return when {
!emojiHistoryEnabled -> EmojiCategoryValues[pageNumber + 1]
else -> EmojiCategoryValues[pageNumber]
}
}
fun categoryToPageNumber(category: EmojiCategory): Int {
return if (emojiHistoryEnabled) {
EmojiCategoryValues.indexOf(category)
} else {
EmojiCategoryValues.indexOf(category) - 1
}
}
@Composable
fun EmojiCategoriesTabRow(
activeCategory: EmojiCategory,
onCategoryChange: (EmojiCategory) -> Unit,
) {
val inputFeedbackController = LocalInputFeedbackController.current
val selectedTabIndex = categoryToPageNumber(activeCategory)
val style = rememberSnyggThemeQuery(FlorisImeUi.MediaEmojiTab.elementName)
TabRow(
modifier = Modifier
.fillMaxWidth()
.height(FlorisImeSizing.smartbarHeight),
selectedTabIndex = selectedTabIndex,
containerColor = Color.Transparent,
contentColor = style.foreground(),
indicator = { tabPositions ->
val style = rememberSnyggThemeQuery(
elementName = FlorisImeUi.MediaEmojiTab.elementName,
selector = SnyggSelector.FOCUS,
)
TabRowDefaults.PrimaryIndicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]),
height = 4.dp,
color = style.foreground(),
)
},
) {
for (category in EmojiCategoryValues) {
if (category == EmojiCategory.RECENTLY_USED && !emojiHistoryEnabled) {
continue
}
Tab(
onClick = {
inputFeedbackController.keyPress(TextKeyData.UNSPECIFIED)
onCategoryChange(category)
},
selected = activeCategory == category,
icon = { SnyggIcon(
elementName = FlorisImeUi.MediaEmojiTab.elementName,
selector = if (activeCategory == category) SnyggSelector.FOCUS else SnyggSelector.NONE,
modifier = Modifier.size(ButtonDefaults.IconSize),
imageVector = category.icon(),
) },
)
}
}
}
Column(
modifier = modifier
) {
val pagerState = rememberPagerState(
pageCount = { calculatePageNumbers() }
)
// Reset the pager to the first page when emojiHistory is enabled
LaunchedEffect(emojiHistoryEnabled) {
pagerState.animateScrollToPage(0)
}
Column(modifier = modifier) {
EmojiCategoriesTabRow(
activeCategory = activeCategory,
onCategoryChange = { category ->
scope.launch { lazyListState.scrollToItem(0) }
activeCategory = category
scope.launch { pagerState.animateScrollToPage(categoryToPageNumber(activeCategory)) }
},
emojiHistoryEnabled = emojiHistoryEnabled,
)
HorizontalPager(pagerState, beyondViewportPageCount = 1) { page ->
// Every page needs its own lazyGridState in order to scroll correctly
val lazyGridState = rememberLazyGridState()
// Update the lazyGridState and active category on scroll
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.currentPage }.collect { page ->
lazyGridState.scrollToItem(0)
activeCategory = pageNumberToCategory(page)
recentlyUsedVersion++
}
}
val category = pageNumberToCategory(page)
val emojiMapping = if (category == EmojiCategory.RECENTLY_USED) {
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
) {
val emojiMapping = if (activeCategory == EmojiCategory.RECENTLY_USED) {
// Purposely using remember here to prevent recomposition, as this would cause rapid
// emoji changes for the user when in recently used category.
remember(recentlyUsedVersion) {
@@ -326,68 +234,63 @@ fun EmojiPaletteView(
EmojiMappingForView(
pinned = emptyList(),
recent = emptyList(),
simple = emojiMappings[category]!!,
simple = emojiMappings[activeCategory]!!,
)
}
val isEmojiHistoryEmpty = emojiMapping.pinned.isEmpty() && emojiMapping.recent.isEmpty()
when (category) {
EmojiCategory.RECENTLY_USED if deviceLocked -> {
Column(
if (activeCategory == EmojiCategory.RECENTLY_USED && deviceLocked) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 8.dp),
) {
Text(
text = stringRes(R.string.emoji__history__phone_locked_message),
)
}
} else if (activeCategory == EmojiCategory.RECENTLY_USED && isEmojiHistoryEmpty) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 8.dp),
) {
Text(
text = stringRes(R.string.emoji__history__empty_message),
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = stringRes(R.string.emoji__history__usage_tip),
fontStyle = FontStyle.Italic,
)
}
} else key(emojiMapping) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
LazyVerticalGrid(
modifier = Modifier
.fillMaxSize()
.padding(all = 8.dp),
.florisScrollbar(lazyListState),
columns = GridCells.Adaptive(minSize = EmojiBaseWidth),
state = lazyListState,
) {
Text(
text = stringRes(R.string.emoji__history__phone_locked_message),
)
}
}
EmojiCategory.RECENTLY_USED if isEmojiHistoryEmpty -> {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 8.dp),
) {
Text(
text = stringRes(R.string.emoji__history__empty_message),
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = stringRes(R.string.emoji__history__usage_tip),
fontStyle = FontStyle.Italic,
)
}
}
else -> key(emojiMapping) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
LazyVerticalGrid(
modifier = Modifier
.fillMaxSize()
.florisScrollbar(lazyGridState),
columns = GridCells.Adaptive(minSize = EmojiBaseWidth),
state = lazyGridState,
) {
if (emojiMapping.pinned.isNotEmpty()) {
header("header_pinned") {
GridHeader(text = stringRes(R.string.emoji__history__pinned))
}
items(emojiMapping.pinned) { emojiSet ->
EmojiKeyWrapper(emojiSet, isPinned = true)
}
if (emojiMapping.pinned.isNotEmpty()) {
header("header_pinned") {
GridHeader(text = stringRes(R.string.emoji__history__pinned))
}
if (emojiMapping.recent.isNotEmpty()) {
header("header_recent") {
GridHeader(text = stringRes(R.string.emoji__history__recent))
}
items(emojiMapping.recent) { emojiSet ->
EmojiKeyWrapper(emojiSet, isRecent = true)
}
items(emojiMapping.pinned) { emojiSet ->
EmojiKeyWrapper(emojiSet, isPinned = true)
}
if (emojiMapping.simple.isNotEmpty()) {
items(emojiMapping.simple) { emojiSet ->
EmojiKeyWrapper(emojiSet)
}
}
if (emojiMapping.recent.isNotEmpty()) {
header("header_recent") {
GridHeader(text = stringRes(R.string.emoji__history__recent))
}
items(emojiMapping.recent) { emojiSet ->
EmojiKeyWrapper(emojiSet, isRecent = true)
}
}
if (emojiMapping.simple.isNotEmpty()) {
items(emojiMapping.simple) { emojiSet ->
EmojiKeyWrapper(emojiSet)
}
}
}
@@ -397,6 +300,59 @@ fun EmojiPaletteView(
}
}
@Composable
private fun EmojiCategoriesTabRow(
activeCategory: EmojiCategory,
onCategoryChange: (EmojiCategory) -> Unit,
emojiHistoryEnabled: Boolean,
) {
val inputFeedbackController = LocalInputFeedbackController.current
val selectedTabIndex = if (emojiHistoryEnabled) {
EmojiCategoryValues.indexOf(activeCategory)
} else {
EmojiCategoryValues.indexOf(activeCategory) - 1
}
val style = rememberSnyggThemeQuery(FlorisImeUi.MediaEmojiTab.elementName)
TabRow(
modifier = Modifier
.fillMaxWidth()
.height(FlorisImeSizing.smartbarHeight),
selectedTabIndex = selectedTabIndex,
containerColor = Color.Transparent,
contentColor = style.foreground(),
indicator = { tabPositions ->
val style = rememberSnyggThemeQuery(
elementName = FlorisImeUi.MediaEmojiTab.elementName,
selector = SnyggSelector.FOCUS,
)
TabRowDefaults.PrimaryIndicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]),
height = 4.dp,
color = style.foreground(),
)
},
) {
for (category in EmojiCategoryValues) {
if (category == EmojiCategory.RECENTLY_USED && !emojiHistoryEnabled) {
continue
}
Tab(
onClick = {
inputFeedbackController.keyPress(TextKeyData.UNSPECIFIED)
onCategoryChange(category)
},
selected = activeCategory == category,
icon = { SnyggIcon(
elementName = FlorisImeUi.MediaEmojiTab.elementName,
selector = if (activeCategory == category) SnyggSelector.FOCUS else SnyggSelector.NONE,
modifier = Modifier.size(ButtonDefaults.IconSize),
imageVector = category.icon(),
) },
)
}
}
}
@Composable
private fun EmojiKey(
emojiSet: EmojiSet,

View File

@@ -34,7 +34,7 @@ import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.ime.input.LocalInputFeedbackController
import dev.patrickgold.florisboard.ime.keyboard.FlorisImeSizing
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.stringRes
import kotlinx.coroutines.launch
import org.florisboard.lib.snygg.ui.SnyggColumn
import org.florisboard.lib.snygg.ui.SnyggIcon

View File

@@ -28,6 +28,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.zIndex
import dev.patrickgold.florisboard.ime.keyboard.Key
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import org.florisboard.lib.snygg.SnyggQueryAttributes
@@ -58,7 +59,7 @@ fun PopupBaseBox(
.align(Alignment.TopCenter),
) {
SnyggText(
modifier = Modifier.align(Alignment.Center),
modifier = Modifier.align(Alignment.Center).zIndex(100f),
text = label,
)
}

View File

@@ -31,6 +31,7 @@ import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.zIndex
import dev.patrickgold.florisboard.ime.keyboard.ComputingEvaluator
import dev.patrickgold.florisboard.ime.keyboard.DefaultComputingEvaluator
import dev.patrickgold.florisboard.ime.keyboard.Key
@@ -38,6 +39,7 @@ import dev.patrickgold.florisboard.ime.keyboard.KeyData
import dev.patrickgold.florisboard.ime.keyboard.computeImageVector
import dev.patrickgold.florisboard.ime.keyboard.computeLabel
import dev.patrickgold.florisboard.ime.media.emoji.EmojiSet
import dev.patrickgold.florisboard.ime.smartbar.Temp
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.key.KeyHintConfiguration
import dev.patrickgold.florisboard.ime.text.keyboard.TextKey
@@ -452,11 +454,12 @@ class PopupUiController(
FlorisImeUi.Attr.Mode to evaluator.keyboard.mode.toString(),
FlorisImeUi.Attr.ShiftState to evaluator.state.inputShiftState.toString(),
)
Temp = !(baseRenderInfo != null || extRenderInfo != null)
baseRenderInfo?.let { renderInfo ->
PopupBaseBox(
modifier = Modifier
.requiredSize(renderInfo.bounds.size.toDpSize())
.absoluteOffset { renderInfo.bounds.topLeft.toIntOffset() },
.absoluteOffset { renderInfo.bounds.topLeft.toIntOffset() }.zIndex(100f),
attributes = attributes,
key = renderInfo.key,
shouldIndicateExtendedPopups = renderInfo.shouldIndicateExtendedPopups && extRenderInfo == null,

View File

@@ -31,7 +31,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import dev.patrickgold.florisboard.ime.keyboard.KeyboardState
import org.florisboard.lib.compose.conditional
import dev.patrickgold.florisboard.lib.compose.conditional
private val SheetOutOfBoundsBgColorInactive = Color(0x00000000)
private val SheetOutOfBoundsBgColorActive = Color(0x52000000)

View File

@@ -44,11 +44,11 @@ import dev.patrickgold.florisboard.ime.nlp.ClipboardSuggestionCandidate
import dev.patrickgold.florisboard.ime.nlp.SuggestionCandidate
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.conditional
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.nlpManager
import dev.patrickgold.florisboard.subtypeManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.compose.conditional
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.snygg.SnyggSelector
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggColumn

View File

@@ -16,8 +16,11 @@
package dev.patrickgold.florisboard.ime.smartbar
import android.graphics.PixelFormat
import android.os.Build
import android.view.SurfaceView
import androidx.annotation.RequiresApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.rememberScrollState
@@ -32,15 +35,18 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.forEach
import dev.patrickgold.florisboard.ime.nlp.NlpInlineAutofillSuggestion
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.lib.compose.florisHorizontalScroll
import dev.patrickgold.florisboard.lib.toIntOffset
import org.florisboard.lib.compose.florisHorizontalScroll
import org.florisboard.lib.snygg.SnyggSinglePropertySet
import org.florisboard.lib.snygg.ui.rememberSnyggThemeQuery
var CachedInlineSuggestionsChipStyleSet: SnyggSinglePropertySet? = null
var Temp: Boolean = false
@Composable
fun InlineSuggestionsStyleCache() {
val chipStyleSet = rememberSnyggThemeQuery(FlorisImeUi.InlineAutofillChip.elementName)
@@ -58,13 +64,16 @@ fun InlineSuggestionsUi(
val scrollState = rememberScrollState()
val almostEmptyRect = remember { android.graphics.Rect(0, 0, 1, 1) }
val backgroundColor = rememberSnyggThemeQuery(FlorisImeUi.SmartbarCandidatesRow.elementName).background()
Row(
modifier
.fillMaxSize()
.florisHorizontalScroll(
state = scrollState,
scrollbarHeight = CandidatesRowScrollbarHeight,
),
)
.background(backgroundColor),
) {
val xMin = scrollState.value
val xMax = scrollState.value + scrollState.viewportSize
@@ -72,6 +81,16 @@ fun InlineSuggestionsUi(
if (inlineSuggestion.view == null) {
continue
}
//inlineSuggestion.view.background = ColorDrawable(backgroundColor.toArgb())
inlineSuggestion.view.forEach {
with (it as SurfaceView) {
//this.setBackgroundColor(backgroundColor.toArgb())
setZOrderOnTop(false)
holder.setFormat(PixelFormat.OPAQUE)
}
}
var chipPos by remember { mutableStateOf(IntOffset.Zero) }
AndroidView(
modifier = Modifier.onGloballyPositioned { chipPos = it.positionInParent().toIntOffset() },

View File

@@ -49,9 +49,7 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.FlorisPreferenceStore
@@ -62,12 +60,13 @@ import dev.patrickgold.florisboard.ime.smartbar.quickaction.QuickActionsRow
import dev.patrickgold.florisboard.ime.smartbar.quickaction.ToggleOverflowPanelAction
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.horizontalTween
import dev.patrickgold.florisboard.lib.compose.verticalTween
import dev.patrickgold.florisboard.nlpManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.vectorResource
import kotlinx.coroutines.launch
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.compose.horizontalTween
import org.florisboard.lib.compose.verticalTween
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggColumn
import org.florisboard.lib.snygg.ui.SnyggIcon
@@ -143,6 +142,7 @@ private fun SmartbarMainRow(modifier: Modifier = Modifier) {
val prefs by FlorisPreferenceStore
val context = LocalContext.current
val keyboardManager by context.keyboardManager()
val activeEvaluator by keyboardManager.activeEvaluator.collectAsState()
val nlpManager by context.nlpManager()
val scope = rememberCoroutineScope()
@@ -187,7 +187,7 @@ private fun SmartbarMainRow(modifier: Modifier = Modifier) {
} else {
Icons.AutoMirrored.Default.KeyboardArrowRight
}
val incognitoIcon = ImageVector.vectorResource(id = R.drawable.ic_incognito)
val incognitoIcon = vectorResource(id = R.drawable.ic_incognito)
val incognitoDisplayMode = prefs.keyboard.incognitoDisplayMode.observeAsState()
val isIncognitoMode = keyboardManager.activeState.isIncognitoMode
val icon = if (isIncognitoMode) {

View File

@@ -25,9 +25,9 @@ import dev.patrickgold.florisboard.ime.keyboard.KeyData
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.stringRes
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.florisboard.lib.compose.stringRes
@Serializable
sealed class QuickAction {

View File

@@ -58,8 +58,8 @@ import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.toIntOffset
import org.florisboard.lib.compose.stringRes
import kotlinx.coroutines.launch
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggColumn

View File

@@ -34,10 +34,10 @@ import dev.patrickgold.florisboard.app.FlorisPreferenceStore
import dev.patrickgold.florisboard.ime.keyboard.FlorisImeSizing
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.snygg.ui.SnyggBox
import dev.patrickgold.florisboard.lib.compose.stringRes
import org.florisboard.lib.snygg.ui.SnyggButton
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggText
@Composable

View File

@@ -78,6 +78,7 @@ import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.FlorisRect
import dev.patrickgold.florisboard.lib.Pointer
import dev.patrickgold.florisboard.lib.PointerMap
import dev.patrickgold.florisboard.lib.compose.DisposableLifecycleEffect
import dev.patrickgold.florisboard.lib.devtools.LogTopic
import dev.patrickgold.florisboard.lib.devtools.flogDebug
import dev.patrickgold.florisboard.lib.observeAsTransformingState
@@ -87,7 +88,6 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.onFailure
import kotlinx.coroutines.isActive
import org.florisboard.lib.android.isOrientationLandscape
import org.florisboard.lib.compose.DisposableLifecycleEffect
import org.florisboard.lib.snygg.SnyggSelector
import org.florisboard.lib.snygg.ui.SnyggBox
import org.florisboard.lib.snygg.ui.SnyggIcon

View File

@@ -19,7 +19,7 @@ package dev.patrickgold.florisboard.lib
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import org.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.lib.compose.stringRes
import org.florisboard.lib.kotlin.CurlyArg
import org.florisboard.lib.kotlin.curlyFormat
import kotlin.contracts.contract

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package dev.patrickgold.florisboard.app.settings.theme
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.ui.graphics.Color
import dev.patrickgold.jetpref.datastore.model.PreferenceSerializer

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.runtime.saveable.Saver
import androidx.compose.ui.unit.Dp

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -29,7 +29,7 @@ import androidx.compose.ui.text.style.TextOverflow
@Composable
fun FlorisAppBar(
title: String,
navigationIcon: (@Composable () -> Unit)?,
navigationIcon: FlorisScreenNavigationIcon?,
actions: @Composable RowScope.() -> Unit = { },
scrollBehavior: TopAppBarScrollBehavior
) {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding

View File

@@ -14,8 +14,9 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import androidx.annotation.DrawableRes
@@ -25,7 +26,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.createBitmap
@Composable
fun FlorisCanvasIcon(
@@ -52,9 +52,9 @@ fun FlorisCanvasIcon(
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
val bitmap = createBitmap(
width = drawable.intrinsicWidth,
height = drawable.intrinsicHeight,
val bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth, drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -35,6 +35,7 @@ import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding

View File

@@ -21,7 +21,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import dev.patrickgold.florisboard.R
import dev.patrickgold.jetpref.material.ui.JetPrefAlertDialog
import org.florisboard.lib.compose.stringRes
@Composable
fun FlorisConfirmDeleteDialog(

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2021-2025 The FlorisBoard Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.ShapeDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
//TODO: Use JetPrefDropDownMenu instead
@Composable
fun <T : Any> FlorisDropdownMenu(
items: List<T>,
expanded: Boolean,
selectedIndex: Int,
modifier: Modifier = Modifier,
enabled: Boolean = true,
isError: Boolean = false,
labelProvider: (@Composable (T) -> String)? = null,
onSelectItem: (Int) -> Unit = { },
onExpandRequest: () -> Unit = { },
onDismissRequest: () -> Unit = { },
) {
@Composable
fun asString(v: T): String {
return labelProvider?.invoke(v) ?: v.toString()
}
Box(modifier = modifier.wrapContentSize(Alignment.TopStart)) {
val indicatorRotation by animateFloatAsState(targetValue = if (expanded) 180f else 0f)
val index = selectedIndex.coerceIn(items.indices)
val color = if (!enabled) {
MaterialTheme.colorScheme.outline
} else if (isError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.onBackground
}
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
border = if (isError && enabled) {
BorderStroke(ButtonDefaults.outlinedButtonBorder.width, MaterialTheme.colorScheme.error)
} else {
ButtonDefaults.outlinedButtonBorder
},
shape = ShapeDefaults.ExtraSmall,
enabled = enabled,
onClick = onExpandRequest,
) {
Text(
modifier = Modifier.weight(1.0f),
text = asString(items[index]),
textAlign = TextAlign.Start,
fontWeight = FontWeight.Normal,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
color = color,
)
Icon(
modifier = Modifier.rotate(indicatorRotation),
imageVector = Icons.Filled.KeyboardArrowDown,
tint = if (enabled) {
color.copy(alpha = 0.74f) //Also test 0.60f
} else {
color
},
contentDescription = "Dropdown indicator",
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
) {
for ((n, item) in items.withIndex()) {
DropdownMenuItem(
text = {
Text(text = asString(item))
},
onClick = {
onSelectItem(n)
onDismissRequest()
},
)
}
}
}
}
@Composable
fun FlorisDropdownLikeButton(
item: String,
modifier: Modifier = Modifier,
isError: Boolean = false,
onClick: () -> Unit = { },
) {
Box(modifier = modifier.wrapContentSize(Alignment.TopStart)) {
val color = if (isError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.onBackground
}
OutlinedButton(
modifier = Modifier
.fillMaxWidth(),
border = if (isError) {
BorderStroke(ButtonDefaults.outlinedButtonBorder.width, MaterialTheme.colorScheme.error)
} else {
ButtonDefaults.outlinedButtonBorder
},
shape = ShapeDefaults.ExtraSmall,
onClick = onClick,
) {
Text(
modifier = Modifier.weight(1.0f),
text = item,
textAlign = TextAlign.Start,
fontWeight = FontWeight.Normal,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
color = color,
)
Icon(
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
tint = color.copy(alpha = 0.74f), //Also test 0.60f
contentDescription = "Dropdown indicator",
)
}
}
}

View File

@@ -43,10 +43,6 @@ import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.jetpref.datastore.ui.PreferenceLayout
import dev.patrickgold.jetpref.datastore.ui.PreferenceUiContent
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.compose.FlorisAppBar
import org.florisboard.lib.compose.FlorisIconButton
import org.florisboard.lib.compose.autoMirrorForRtl
import org.florisboard.lib.compose.florisVerticalScroll
@Composable
fun FlorisScreen(builder: @Composable FlorisScreenScope.() -> Unit) {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2025 The FlorisBoard Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.patrickgold.florisboard.lib.compose
import android.content.Context
import androidx.annotation.DrawableRes
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
fun Context.vectorResource(@DrawableRes id: Int): ImageVector? {
val theme = this.theme
return try {
ImageVector.vectorResource(theme = theme, resId = id, res = this.resources)
} catch (_: Exception) {
null
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridItemScope

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

View File

@@ -54,11 +54,9 @@ import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import org.florisboard.lib.android.showShortToast
import dev.patrickgold.florisboard.lib.util.InputMethodUtils
import org.florisboard.lib.android.showShortToastSync
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.compose.stringRes
import org.florisboard.lib.compose.verticalTween
private const val AnimationDuration = 200

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import android.content.Context
import android.view.View
@@ -27,12 +27,13 @@ import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import dev.patrickgold.florisboard.R
import org.florisboard.lib.kotlin.CurlyArg
import org.florisboard.lib.kotlin.curlyFormat
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.*
import org.florisboard.lib.kotlin.CurlyArg
import org.florisboard.lib.kotlin.curlyFormat
private val LocalResourcesContext = staticCompositionLocalOf<Context> {
error("resources context not initialized!!")
@@ -42,7 +43,7 @@ private val LocalAppNameString = staticCompositionLocalOf {
"FlorisBoard"
}
val LocalLocalizedDateTimeFormatter = staticCompositionLocalOf {
internal val LocalLocalizedDateTimeFormatter = staticCompositionLocalOf {
DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.ROOT)
@@ -52,7 +53,6 @@ val LocalLocalizedDateTimeFormatter = staticCompositionLocalOf {
@Composable
fun ProvideLocalizedResources(
resourcesContext: Context,
@StringRes appName: Int,
forceLayoutDirection: LayoutDirection? = null,
content: @Composable () -> Unit,
) {
@@ -72,7 +72,7 @@ fun ProvideLocalizedResources(
LocalResourcesContext provides resourcesContext,
LocalLocalizedDateTimeFormatter provides dateTimeFormatter,
LocalLayoutDirection provides layoutDirection,
LocalAppNameString provides stringResource(appName),
LocalAppNameString provides stringResource(R.string.floris_app_name),
) {
content()
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.animateFloatAsState

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.florisboard.lib.compose
package dev.patrickgold.florisboard.lib.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect

View File

@@ -29,12 +29,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.lib.compose.observeAsState
import dev.patrickgold.florisboard.lib.devtools.flogDebug
import kotlinx.coroutines.delay
import org.florisboard.lib.android.AndroidSettings
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.systemServiceOrNull
import org.florisboard.lib.compose.observeAsState
private const val DELIMITER = ':'
private const val IME_SERVICE_CLASS_NAME = "dev.patrickgold.florisboard.FlorisImeService"

View File

@@ -631,7 +631,6 @@
<string name="clipboard__cleared_primary_clip">Clip principal borrado</string>
<string name="clipboard__cleared_history">Historial borrado</string>
<string name="clipboard__cleared_full_history">Historial completo borrado</string>
<string name="clipboard__confirm_clear_history__message">¿Estás seguro de que quieres limpiar el historial del portapapeles? Esto limpiará todos los ítems excepto los fijados, sin tener en cuenta los filtros activos.</string>
<string name="settings__clipboard__title">Portapapeles</string>
<string name="pref__clipboard__use_internal_clipboard__label">Usar portapapeles interno</string>
<string name="pref__clipboard__use_internal_clipboard__summary">Usar portapapeles interno en vez del portapapeles del sistema</string>

View File

@@ -11,5 +11,5 @@ projectMinSdk=26
projectTargetSdk=35
projectCompileSdk=35
projectVersionCode=111
projectVersionName=0.5.0-beta03
projectVersionCode=110
projectVersionName=0.5.0-beta02

View File

@@ -20,7 +20,7 @@ kotlinx-serialization-json = "1.9.0"
ksp = "2.2.0-2.0.2"
mikepenz-aboutlibraries = "12.1.2"
patrickgold-compose-tooltip = "0.2.0-rc02"
patrickgold-jetpref = "0.3.0-beta02"
patrickgold-jetpref = "0.3.0-beta01"
# Testing
androidx-benchmark = "1.3.4"
@@ -57,7 +57,6 @@ androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "
cache4k = { module = "io.github.reactivecircus.cache4k:cache4k", version.ref = "cache4k" }
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
mikepenz-aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "mikepenz-aboutlibraries" }

View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) 2025 The FlorisBoard Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
alias(libs.plugins.agp.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.plugin.compose)
}
val projectMinSdk: String by project
val projectCompileSdk: String by project
android {
namespace = "org.florisboard.lib.compose"
compileSdk = projectCompileSdk.toInt()
defaultConfig {
minSdk = projectMinSdk.toInt()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildFeatures {
compose = true
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
create("beta") {
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = listOf(
"-Xconsistent-data-class-copy-visibility",
"-Xwhen-guards",
)
}
}
dependencies {
implementation(project(":lib:android"))
implementation(project(":lib:color"))
implementation(project(":lib:kotlin"))
val composeBom = platform(libs.androidx.compose.bom)
implementation(composeBom)
// testImplementation(composeBom)
// androidTestImplementation(composeBom)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.material.icons)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.kotlinx.serialization.json)
implementation(libs.patrickgold.jetpref.material.ui)
testImplementation(libs.kotlin.test.junit5)
}

Some files were not shown because too many files have changed in this diff Show More