Compare commits

..

20 Commits

Author SHA1 Message Date
Patrick Goldinger
bc5ed3475c Release v0.4.6 2025-03-04 22:47:39 +01:00
Patrick Goldinger
871ff0acb1 Merge branch 'main' into release/0.4 2025-03-04 22:45:30 +01:00
florisboard-bot
34f8fec2f6 Update translations from Crowdin 2025-03-04 22:39:56 +01:00
npnpatidar
7199fcdf12 Devanagari Script and Hindi Language Layout Added (#2723)
* test commit

* hi-IN popupmappings id added

* basic layout

* heart replaces with space

* code corrected

* lots of other keys added

* all characters have been added

* popmappings rearranged

* some positional change

* * and \ won't popup due to क्ष and  ज्ञ

* ओ औ code correced

* some vovels reordered

* Hindi does not capitalization concept
2025-03-04 22:27:16 +01:00
Lars Mühlbauer
8319f563b9 Add support for switching the subtype on space bar long press (#2781)
* Add initial support for switching the subtype on space bar long press

* Fix keyboard presses behind the header panel

* Fix taps behind sheet

* Extract string ressource and refactor code

* Instant select subtype

* Persist suptype change in prefs
2025-03-04 22:23:24 +01:00
Lars Mühlbauer
45efe52159 Add new screenshot generator and update fastlane images (#2787)
* Add new screenshot generator and update fastlane images

* Update featureGraphic.png to match g-play requirements
2025-03-04 21:46:54 +01:00
Lars Mühlbauer
7a286b932b Update snygg dynamic color scheme on wallpaper change (#2778)
* Update snygg dynamic color scheme on wallpaper change

* Move broadcast receiver handling to FlorisImeService and properly unregister the receiver

* Set systembar color on stylesheet change
2025-03-04 21:08:45 +01:00
Lars Mühlbauer
df3f84e96d Fix text being rendered behind the top app bar (#2758)
* Fix text being rendered behind the top app bar

This commit fixes an issue where the text was rendered
behind the top app bar in the crash dialog activity by
removing the top app bar in the style and adding a top
app bar in the layout XML.

* Fix toolbar rendering messed up in crash dialog screen

---------

Co-authored-by: Patrick Goldinger <patrick@patrickgold.dev>
2025-02-14 13:13:44 +01:00
Lars Mühlbauer
4cc2216940 Fix switching back from voice ime (#2684) (#2759)
This commit fixes an issue where the voice ime was
not possible to switch back to FlorisBoard, because
the keyboard subtype was not specified.
2025-02-14 12:23:46 +01:00
Lars Mühlbauer
21fdd31c88 Fix BottomSheetContent drawing behind system nav bar (#2757)
This commit fixes an issue where the BottomSheetContent
was drawn behind the system navigation bar. To fix this
issue, I applied the saveDrawingPadding Modifier to the
AnimatedVisibility. There was a color problem on the
system navigation bar, so I set the background color to
SheetOutOfBoundsBgColorInactive. Now the system nav bar
is colored the right way.
2025-02-14 12:20:13 +01:00
Lars Mühlbauer
53c6cb52ca Fix crash when opening clipboard history (#2756)
This Commit fixes a crash when opening the clipboard history
with a theme which does not provide a sp size for the header
or the clipboard item. The sp value is now saveTimes multiplied
with 1f.
2025-02-14 12:15:39 +01:00
Patrick Goldinger
9b12213b3e Possible fixes for all keys invisible bug (#2743)
* Fix possible race condition in extension manager init

* Fix deprecation warnings in Kotlin contracts

* Fix race condition in KeyboardManagerResources

* Add debug glide.enabled toggle
2025-02-02 22:35:25 +01:00
Patrick Goldinger
659a5062ab Merge pull request #2750 from florisboard/feat/implement-custom-material-you-color
Implement custom material you colors
2025-02-02 20:17:29 +01:00
lm41
086e5f7782 Add new JetPrefColorPicker for the keyboard accent color.
This commit introduces the new color schemes for spoofed
material you themes. The material you themes can now be
used on any android version that is supported by FlorisBoard
and not just on android 12+.
2025-02-02 19:40:04 +01:00
lm41
ae73e64cd2 Add new JetPrefColorPicker for the settings accent color. 2025-02-02 19:35:16 +01:00
lm41
9f5e8cddd5 Add :lib:color package
This package includes a set of material 3 color schemes
and a map of the corresponding colors to the color schemes.
Please visit the packages README.md for information
on how the schemes were created.
2025-02-02 19:30:39 +01:00
Lars Mühlbauer
3724495d4f Remove code duplication in setup screen (#2742)
* Remove code duplication in setup screen

* fixup! Remove code duplication in setup screen
2025-01-16 22:52:25 +01:00
Patrick Goldinger
a146c6f846 Release v0.4.5 2025-01-13 02:10:22 +01:00
Patrick Goldinger
40ad937384 Merge branch 'main' into release/0.4 2025-01-13 02:08:25 +01:00
Patrick Goldinger
15b5dd9e3e Fix issues with all keys invisible detection (#2737) 2025-01-13 02:07:05 +01:00
132 changed files with 5076 additions and 563 deletions

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
import java.io.ByteArrayOutputStream
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
plugins {
alias(libs.plugins.agp.application)
@@ -202,6 +202,7 @@ dependencies {
implementation(libs.patrickgold.jetpref.material.ui)
implementation(project(":lib:android"))
implementation(project(":lib:color"))
implementation(project(":lib:kotlin"))
implementation(project(":lib:native"))
implementation(project(":lib:snygg"))

View File

@@ -49,6 +49,12 @@
"authors": [ "iamrasel" ],
"direction": "ltr"
},
{
"id": "hindi_in",
"label": "हिंदी",
"authors": [ "npnpatidar" ],
"direction": "ltr"
},
{
"id": "bepo",
"label": "BÉPO",

View File

@@ -0,0 +1,42 @@
[
[
{ "$": "case_selector", "lower": { "code": 2335, "label": "ट" }, "upper": { "code": 2336, "label": "ठ" } },
{ "$": "case_selector", "lower": { "code": 2337, "label": "ड" }, "upper": { "code": 2338, "label": "ढ" } },
{ "$": "case_selector", "lower": { "code": 2375, "label": "े" }, "upper": { "code": 2376, "label": "ै" } },
{ "$": "case_selector", "lower": { "code": 2352, "label": "र" }, "upper": { "code": 2371, "label": "ृ" } },
{ "$": "case_selector", "lower": { "code": 2340, "label": "त" }, "upper": { "code": 2341, "label": "थ" } },
{ "$": "case_selector", "lower": { "code": 2351, "label": "य" }, "upper": { "code": 2399, "label": "य़" } },
{ "$": "case_selector", "lower": { "code": 2369, "label": "ु" }, "upper": { "code": 2370, "label": "ू" } },
{ "$": "case_selector", "lower": { "code": 2367, "label": "ि" }, "upper": { "code": 2368, "label": "ी" } },
{ "$": "case_selector", "lower": { "code": 2379, "label": "ो" }, "upper": { "code": 2380, "label": "ौ" } },
{ "$": "case_selector", "lower": { "code": 2346, "label": "प" }, "upper": { "code": 2398, "label": "फ़" } }
],
[
{ "$": "case_selector", "lower": { "code": 2366, "label": "ा" }, "upper": { "code": 2309, "label": "अ" } },
{ "$": "case_selector", "lower": { "code": 2360, "label": "स" }, "upper": { "code": 2358, "label": "श" } },
{ "$": "case_selector", "lower": { "code": 2342, "label": "द" }, "upper": { "code": 2343, "label": "ध" } },
{ "$": "case_selector", "lower": { "code": 2347, "label": "फ" }, "upper": { "code": 2364, "label": " ़" } },
{ "$": "case_selector", "lower": { "code": 2327, "label": "ग" }, "upper": { "code": 2328, "label": "घ" } },
{ "$": "case_selector", "lower": { "code": 2361, "label": "ह" }, "upper": { "code": 2307, "label": "" } },
{ "$": "case_selector", "lower": { "code": 2332, "label": "ज" }, "upper": { "code": 2333, "label": "झ" } },
{ "$": "case_selector", "lower": { "code": 2325, "label": "क" }, "upper": { "code": 2326, "label": "ख" } },
{ "$": "case_selector", "lower": { "code": 2354, "label": "ल" }, "upper": { "code": 2355, "label": "ळ" } }
],
[
{
"$": "case_selector",
"lower": { "$": "multi_text_key", "codePoints": [2332, 2381, 2334], "label": "ज्ञ" },
"upper": { "code": 2395, "label": "ज़" }
},
{
"$": "case_selector",
"lower": { "$": "multi_text_key", "codePoints": [2325, 2381, 2359], "label": "क्ष" },
"upper": { "code": 2359, "label": "ष" }
},
{ "$": "case_selector", "lower": { "code": 2330, "label": "च" }, "upper": { "code": 2331, "label": "छ" } },
{ "$": "case_selector", "lower": { "code": 2357, "label": "व" }, "upper": { "code": 2381, "label": "्" } },
{ "$": "case_selector", "lower": { "code": 2348, "label": "ब" }, "upper": { "code": 2349, "label": "भ" } },
{ "$": "case_selector", "lower": { "code": 2344, "label": "न" }, "upper": { "code": 2339, "label": "ण" } },
{ "$": "case_selector", "lower": { "code": 2350, "label": "म" }, "upper": { "code": 2306, "label": "ं" } }
]
]

View File

@@ -48,6 +48,7 @@
{ "id": "fi", "authors": [ "patrickgold" ] },
{ "id": "fo", "authors": [ "BinFlush" ] },
{ "id": "fr", "authors": [ "patrickgold" ] },
{ "id": "hi-IN", "authors": [ "npnpatidar" ] },
{ "id": "hr", "authors": [ "hedidnothingwrong" ] },
{ "id": "hu", "authors": [ "zoli111, gabik65" ] },
{ "id": "hy", "authors": [ "PJTSearch" ] },
@@ -695,6 +696,16 @@
"numericAdvanced": "org.florisboard.layouts:bengali"
}
},
{
"languageTag": "hi-IN",
"composer": "org.florisboard.composers:appender",
"currencySet": "org.florisboard.currencysets:indian_rupee",
"popupMapping": "org.florisboard.localization:hi-IN",
"preferred": {
"characters": "org.florisboard.layouts:hindi_in",
"numericRow": "org.florisboard.layouts:devanagari"
}
},
{
"languageTag": "ast",
"composer": "org.florisboard.composers:appender",

View File

@@ -0,0 +1,173 @@
{
"all": {
"क": {
"main": { "$": "auto_text_key", "code": 2392, "label": "क़" },
"relevant": [{ "$": "auto_text_key", "code": 2393, "label": "ख़" }]
},
"ग": {
"main": { "$": "auto_text_key", "code": 2394, "label": "ग़" },
"relevant": [{ "$": "auto_text_key", "code": 2427, "label": "ॻ" }]
},
"च": {
"relevant": [
{ "$": "auto_text_key", "code": 2385, "label": " ॑" },
{ "$": "auto_text_key", "code": 2386, "label": " ॒" }
]
},
"ज": {
"main": { "$": "auto_text_key", "code": 2395, "label": "ज़" },
"relevant": [
{ "$": "auto_text_key", "code": 2428, "label": "ॼ" },
{ "$": "auto_text_key", "code": 2425, "label": "ॹ" }
]
},
"ड": {
"main": { "$": "auto_text_key", "code": 2396, "label": "ड़" },
"relevant": [{ "$": "auto_text_key", "code": 2397, "label": "ढ़" }]
},
"त": {
"main": { "$": "multi_text_key", "codePoints": [2340, 2381, 2352], "label": "त्र" }
},
"द": {
"main": { "$": "auto_text_key", "code": 2396, "label": "ड़" },
"relevant": [
{ "$": "auto_text_key", "code": 2430, "label": "ॾ" },
{ "$": "auto_text_key", "code": 2397, "label": "ढ़" },
{ "$": "auto_text_key", "code": 2424, "label": "ॸ" }
]
},
"न": {
"main": { "$": "auto_text_key", "code": 2329, "label": "ङ" },
"relevant": [
{ "$": "auto_text_key", "code": 2345, "label": "ऩ" },
{ "$": "auto_text_key", "code": 2334, "label": "ञ" }
]
},
"फ": {
"main": { "$": "auto_text_key", "code": 2398, "label": "फ़" }
},
"ब": {
"relevant": [
{ "$": "auto_text_key", "code": 2431, "label": "ॿ" },
{ "$": "auto_text_key", "code": 2365, "label": "ऽ" },
{ "$": "auto_text_key", "code": 2416, "label": "॰" }
]
},
"म": {
"main": { "$": "auto_text_key", "code": 2305, "label": "ँ" },
"relevant": [{ "$": "auto_text_key", "code": 2304, "label": "ऀ" }]
},
"य": {
"main": { "$": "auto_text_key", "code": 2426, "label": "ॺ" }
},
"र": {
"main": { "$": "auto_text_key", "code": 2315, "label": "ऋ" },
"relevant": [
{ "$": "auto_text_key", "code": 2400, "label": "ॠ" },
{ "$": "auto_text_key", "code": 2372, "label": "ॄ" },
{ "$": "auto_text_key", "code": 2353, "label": "ऱ" }
]
},
"ल": {
"relevant": [
{ "$": "auto_text_key", "code": 2402, "label": "ॢ" },
{ "$": "auto_text_key", "code": 2403, "label": "ॣ" },
{ "$": "auto_text_key", "code": 2316, "label": "ऌ" },
{ "$": "auto_text_key", "code": 2401, "label": "ॡ" },
{ "$": "auto_text_key", "code": 2356, "label": "ऴ" }
]
},
"व": {
"relevant": [
{ "$": "auto_text_key", "code": 2387, "label": " ॓" },
{ "$": "auto_text_key", "code": 2388, "label": " ॔" }
]
},
"स": {
"main": { "$": "multi_text_key", "codePoints": [2358, 2381, 2352], "label": "श्र" },
"relevant": [{ "$": "auto_text_key", "code": 2359, "label": "ष" }]
},
"ा": {
"main": { "$": "auto_text_key", "code": 2310, "label": "आ" },
"relevant": [
{ "$": "auto_text_key", "code": 2373, "label": "ॅ" },
{ "$": "auto_text_key", "code": 2418, "label": "ॲ" },
{ "$": "auto_text_key", "code": 2308, "label": "ऄ" }
]
},
"ि": {
"main": { "$": "auto_text_key", "code": 2311, "label": "इ" },
"relevant": [{ "$": "auto_text_key", "code": 2312, "label": "ई" }]
},
"ु": {
"main": { "$": "auto_text_key", "code": 2313, "label": "उ" },
"relevant": [
{ "$": "auto_text_key", "code": 2422, "label": "ॶ" },
{ "$": "auto_text_key", "code": 2423, "label": "ॷ" },
{ "$": "auto_text_key", "code": 2390, "label": " ॖ" },
{ "$": "auto_text_key", "code": 2314, "label": "ऊ" },
{ "$": "auto_text_key", "code": 2391, "label": " ॗ" }
]
},
"े": {
"main": { "$": "auto_text_key", "code": 2319, "label": "ए" },
"relevant": [
{ "$": "auto_text_key", "code": 2317, "label": "ऍ" },
{ "$": "auto_text_key", "code": 2318, "label": "ऎ" },
{ "$": "auto_text_key", "code": 2374, "label": " ॆ" },
{ "$": "auto_text_key", "code": 2320, "label": "ऐ" },
{ "$": "auto_text_key", "code": 2382, "label": " ॎ" },
{ "$": "auto_text_key", "code": 2389, "label": " ॕ" }
]
},
"ो": {
"main": { "$": "auto_text_key", "code": 2323, "label": "ओ" },
"relevant": [
{ "$": "auto_text_key", "code": 2322, "label": "ऒ" },
{ "$": "auto_text_key", "code": 2378, "label": " ॊ" },
{ "$": "auto_text_key", "code": 2383, "label": " ॏ" },
{ "$": "auto_text_key", "code": 2421, "label": "ॵ" },
{ "$": "auto_text_key", "code": 2384, "label": "ॐ" },
{ "$": "auto_text_key", "code": 2377, "label": "ॉ" },
{ "$": "auto_text_key", "code": 2419, "label": "ॳ" },
{ "$": "auto_text_key", "code": 2420, "label": "ॴ" },
{ "$": "auto_text_key", "code": 2362, "label": " ऺ" },
{ "$": "auto_text_key", "code": 2363, "label": " ऻ" },
{ "$": "auto_text_key", "code": 2324, "label": "औ" },
{ "$": "auto_text_key", "code": 2321, "label": "ऑ" }
]
},
"~right": {
"main": { "code": 2404, "label": "।" },
"relevant": [
{ "code": 37, "label": "%" },
{ "code": 43, "label": "+" },
{ "code": 45, "label": "-" },
{ "code": 58, "label": ":" },
{ "code": 59, "label": ";" },
{ "code": 47, "label": "/" },
{ "$": "layout_direction_selector", "ltr": { "code": 40, "label": "(" }, "rtl": { "code": 41, "label": "(" } },
{ "$": "layout_direction_selector", "ltr": { "code": 41, "label": ")" }, "rtl": { "code": 40, "label": ")" } },
{ "code": 8205, "label": ">⁞<" },
{ "code": 8204, "label": "<⁞>" },
{ "code": 2417, "label": "ॱ" },
{ "code": 2429, "label": "" },
{ "code": 33, "label": "!" },
{ "code": 63, "label": "?" },
{ "code": 2405, "label": "॥" }
]
}
},
"uri": {
"~right": {
"main": { "code": -255, "label": ".com" },
"relevant": [
{ "code": -255, "label": ".org" },
{ "code": -255, "label": ".net" },
{ "code": -255, "label": ".in" },
{ "code": -255, "label": ".co.in" }
]
}
}
}

View File

@@ -18,6 +18,7 @@ package dev.patrickgold.florisboard
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Configuration
import android.inputmethodservice.ExtractEditText
import android.os.Build
@@ -79,6 +80,8 @@ import dev.patrickgold.florisboard.app.devtools.DevtoolsOverlay
import dev.patrickgold.florisboard.app.florisPreferenceModel
import dev.patrickgold.florisboard.ime.ImeUiMode
import dev.patrickgold.florisboard.ime.clipboard.ClipboardInputLayout
import dev.patrickgold.florisboard.ime.core.SelectSubtypePanel
import dev.patrickgold.florisboard.ime.core.isSubtypeSelectionShowing
import dev.patrickgold.florisboard.ime.editor.EditorRange
import dev.patrickgold.florisboard.ime.editor.FlorisEditorInfo
import dev.patrickgold.florisboard.ime.input.InputFeedbackController
@@ -99,6 +102,7 @@ import dev.patrickgold.florisboard.ime.smartbar.quickaction.QuickActionsEditorPa
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.FlorisButton
import dev.patrickgold.florisboard.lib.compose.ProvideLocalizedResources
import dev.patrickgold.florisboard.lib.compose.SystemUiIme
@@ -232,10 +236,10 @@ class FlorisImeService : LifecycleInputMethodService() {
val imm = ims.systemServiceOrNull(InputMethodManager::class) ?: return false
val list: List<InputMethodInfo> = imm.enabledInputMethodList
for (el in list) {
for (i in 0 until el.subtypeCount){
for (i in 0 until el.subtypeCount) {
if (el.getSubtypeAt(i).mode != "voice") continue
if (AndroidVersion.ATLEAST_API28_P) {
ims.switchInputMethod(el.id)
ims.switchInputMethod(el.id, el.getSubtypeAt(i))
return true
} else {
ims.window.window?.let { window ->
@@ -267,6 +271,8 @@ class FlorisImeService : LifecycleInputMethodService() {
private var isExtractUiShown by mutableStateOf(false)
private var resourcesContext by mutableStateOf(this as Context)
private val wallpaperChangeReceiver = WallpaperChangeReceiver()
init {
setTheme(R.style.FlorisImeTheme)
}
@@ -280,6 +286,8 @@ class FlorisImeService : LifecycleInputMethodService() {
config.setLocale(subtype.primaryLocale.base)
resourcesContext = createConfigurationContext(config)
}
@Suppress("DEPRECATION") // We do not retrieve the wallpaper but only listen to changes
registerReceiver(wallpaperChangeReceiver, IntentFilter(Intent.ACTION_WALLPAPER_CHANGED))
}
override fun onCreateInputView(): View {
@@ -318,6 +326,7 @@ class FlorisImeService : LifecycleInputMethodService() {
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(wallpaperChangeReceiver)
FlorisImeServiceReference = WeakReference(null)
inputWindowView = null
}
@@ -495,7 +504,9 @@ class FlorisImeService : LifecycleInputMethodService() {
outInsets.visibleTopInsets = visibleTopY
outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_REGION
val left = 0
val top = if (keyboardManager.activeState.isBottomSheetShowing()) { 0 } else {
val top = if (keyboardManager.activeState.isBottomSheetShowing() || keyboardManager.activeState.isSubtypeSelectionShowing()) {
0
} else {
visibleTopY - if (needAdditionalOverlay) FlorisImeSizing.Static.smartbarHeightPx else 0
}
val right = inputViewSize.width
@@ -680,12 +691,22 @@ class FlorisImeService : LifecycleInputMethodService() {
ProvideLocalizedResources(resourcesContext, forceLayoutDirection = LayoutDirection.Ltr) {
FlorisImeTheme {
BottomSheetHostUi(
isShowing = state.isBottomSheetShowing(),
isShowing = state.isBottomSheetShowing() || state.isSubtypeSelectionShowing(),
onHide = {
keyboardManager.activeState.isActionsEditorVisible = false
if (state.isBottomSheetShowing()) {
keyboardManager.activeState.isActionsEditorVisible = false
}
if (state.isSubtypeSelectionShowing()) {
keyboardManager.activeState.isSubtypeSelectionVisible = false
}
},
) {
QuickActionsEditorPanel()
if (state.isBottomSheetShowing()) {
QuickActionsEditorPanel()
}
if (state.isSubtypeSelectionShowing()) {
SelectSubtypePanel()
}
}
}
}
@@ -734,7 +755,8 @@ class FlorisImeService : LifecycleInputMethodService() {
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
) {
val fieldColor = fieldStyle.foreground.solidColor(context, FlorisImeTheme.fallbackContentColor())
val fieldColor =
fieldStyle.foreground.solidColor(context, FlorisImeTheme.fallbackContentColor())
AndroidView(
modifier = Modifier
.padding(8.dp)
@@ -770,8 +792,14 @@ class FlorisImeService : LifecycleInputMethodService() {
?: "ACTION",
shape = actionStyle.shape.shape(),
colors = ButtonDefaults.buttonColors(
containerColor = actionStyle.background.solidColor(context, FlorisImeTheme.fallbackContentColor()),
contentColor = actionStyle.foreground.solidColor(context, FlorisImeTheme.fallbackSurfaceColor()),
containerColor = actionStyle.background.solidColor(
context,
FlorisImeTheme.fallbackContentColor()
),
contentColor = actionStyle.foreground.solidColor(
context,
FlorisImeTheme.fallbackSurfaceColor()
),
),
)
}

View File

@@ -18,6 +18,7 @@ package dev.patrickgold.florisboard.app
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.DisplayColorsAs
import dev.patrickgold.florisboard.app.settings.theme.DisplayKbdAfterDialogs
@@ -47,6 +48,7 @@ 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.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
@@ -57,7 +59,9 @@ import dev.patrickgold.jetpref.datastore.model.PreferenceType
import dev.patrickgold.jetpref.datastore.model.observeAsState
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.android.isOrientationPortrait
import org.florisboard.lib.color.DEFAULT_GREEN
import org.florisboard.lib.snygg.SnyggLevel
fun florisPreferenceModel() = JetPref.getOrCreatePreferenceModel(AppPrefs::class, ::AppPrefs)
@@ -69,9 +73,13 @@ class AppPrefs : PreferenceModel("florisboard-app-prefs") {
key = "advanced__settings_theme",
default = AppTheme.AUTO,
)
val useMaterialYou = boolean(
key = "advanced__use_material_you",
default = true,
val accentColor = custom(
key = "advanced__accent_color",
default = when (AndroidVersion.ATLEAST_API31_S) {
true -> Color.Unspecified
false -> DEFAULT_GREEN
},
serializer = ColorPreferenceSerializer,
)
val settingsLanguage = string(
key = "advanced__settings_language",
@@ -166,10 +174,6 @@ class AppPrefs : PreferenceModel("florisboard-app-prefs") {
key = "devtools__enabled",
default = false,
)
val showLastLayoutComputation = boolean(
key = "devtools__show_last_layout_computation",
default = false,
)
val showPrimaryClip = boolean(
key = "devtools__show_primary_clip",
default = false,
@@ -708,6 +712,14 @@ class AppPrefs : PreferenceModel("florisboard-app-prefs") {
default = extCoreTheme("floris_night"),
serializer = ExtensionComponentName.Serializer,
)
val accentColor = custom(
key = "theme__accent_color",
default = when (AndroidVersion.ATLEAST_API31_S) {
true -> Color.Unspecified
false -> DEFAULT_GREEN
},
serializer = ColorPreferenceSerializer,
)
//val sunriseTime = localTime(
// key = "theme__sunrise_time",
// default = LocalTime.of(6, 0),

View File

@@ -542,6 +542,10 @@ private val ENUM_DISPLAY_ENTRIES = mapOf<Pair<KClass<*>, String>, @Composable ()
key = SwipeAction.SHOW_INPUT_METHOD_PICKER,
label = stringRes(R.string.enum__swipe_action__show_input_method_picker),
)
entry(
key = SwipeAction.SHOW_SUBTYPE_PICKER,
label = "Show subtype picker"
)
entry(
key = SwipeAction.SWITCH_TO_PREV_SUBTYPE,
label = stringRes(R.string.enum__swipe_action__switch_to_prev_subtype),

View File

@@ -36,6 +36,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.platform.LocalConfiguration
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
@@ -117,8 +118,8 @@ class FlorisAppActivity : ComponentActivity() {
AppVersionUtils.updateVersionOnInstallAndLastUse(this, prefs)
setContent {
ProvideLocalizedResources(resourcesContext) {
val useMaterialYou by prefs.advanced.useMaterialYou.observeAsState()
FlorisAppTheme(theme = appTheme, isMaterialYouAware = useMaterialYou) {
val accentColor by prefs.advanced.accentColor.observeAsState()
FlorisAppTheme(theme = appTheme, isMaterialYouAware = accentColor.isUnspecified) {
Surface(color = MaterialTheme.colorScheme.background) {
AppContent()
}

View File

@@ -17,19 +17,24 @@
package dev.patrickgold.florisboard.app.apptheme
import android.app.Activity
import android.content.Context
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
import dev.patrickgold.florisboard.app.AppTheme
import dev.patrickgold.florisboard.app.florisPreferenceModel
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.color.ColorMappings
/*private val AmoledDarkColorPalette = darkColorScheme(
primary = Green500,
@@ -70,170 +75,93 @@ private val LightColorPalette = lightColorScheme(
*/
)*/
private val lightScheme = lightColorScheme(
primary = primaryLight,
onPrimary = onPrimaryLight,
primaryContainer = primaryContainerLight,
onPrimaryContainer = onPrimaryContainerLight,
secondary = secondaryLight,
onSecondary = onSecondaryLight,
secondaryContainer = secondaryContainerLight,
onSecondaryContainer = onSecondaryContainerLight,
tertiary = tertiaryLight,
onTertiary = onTertiaryLight,
tertiaryContainer = tertiaryContainerLight,
onTertiaryContainer = onTertiaryContainerLight,
error = errorLight,
onError = onErrorLight,
errorContainer = errorContainerLight,
onErrorContainer = onErrorContainerLight,
background = backgroundLight,
onBackground = onBackgroundLight,
surface = surfaceLight,
onSurface = onSurfaceLight,
surfaceVariant = surfaceVariantLight,
onSurfaceVariant = onSurfaceVariantLight,
outline = outlineLight,
outlineVariant = outlineVariantLight,
scrim = scrimLight,
inverseSurface = inverseSurfaceLight,
inverseOnSurface = inverseOnSurfaceLight,
inversePrimary = inversePrimaryLight,
surfaceDim = surfaceDimLight,
surfaceBright = surfaceBrightLight,
surfaceContainerLowest = surfaceContainerLowestLight,
surfaceContainerLow = surfaceContainerLowLight,
surfaceContainer = surfaceContainerLight,
surfaceContainerHigh = surfaceContainerHighLight,
surfaceContainerHighest = surfaceContainerHighestLight,
)
private val darkScheme = darkColorScheme(
primary = primaryDark,
onPrimary = onPrimaryDark,
primaryContainer = primaryContainerDark,
onPrimaryContainer = onPrimaryContainerDark,
secondary = secondaryDark,
onSecondary = onSecondaryDark,
secondaryContainer = secondaryContainerDark,
onSecondaryContainer = onSecondaryContainerDark,
tertiary = tertiaryDark,
onTertiary = onTertiaryDark,
tertiaryContainer = tertiaryContainerDark,
onTertiaryContainer = onTertiaryContainerDark,
error = errorDark,
onError = onErrorDark,
errorContainer = errorContainerDark,
onErrorContainer = onErrorContainerDark,
background = backgroundDark,
onBackground = onBackgroundDark,
surface = surfaceDark,
onSurface = onSurfaceDark,
surfaceVariant = surfaceVariantDark,
onSurfaceVariant = onSurfaceVariantDark,
outline = outlineDark,
outlineVariant = outlineVariantDark,
scrim = scrimDark,
inverseSurface = inverseSurfaceDark,
inverseOnSurface = inverseOnSurfaceDark,
inversePrimary = inversePrimaryDark,
surfaceDim = surfaceDimDark,
surfaceBright = surfaceBrightDark,
surfaceContainerLowest = surfaceContainerLowestDark,
surfaceContainerLow = surfaceContainerLowDark,
surfaceContainer = surfaceContainerDark,
surfaceContainerHigh = surfaceContainerHighDark,
surfaceContainerHighest = surfaceContainerHighestDark,
)
@Composable
fun getColorScheme(
context: Context,
isMaterialYouAware: Boolean,
themeColor: Color,
theme: AppTheme,
): ColorScheme {
val isDark = isSystemInDarkTheme()
private val amoledScheme = darkScheme.copy(
background = amoledDark,
surface = amoledDark
)
return when (theme) {
AppTheme.AUTO -> {
if (isMaterialYouAware && AndroidVersion.ATLEAST_API31_S) {
when {
isDark -> dynamicDarkColorScheme(context)
else -> dynamicLightColorScheme(context)
}
} else {
ColorMappings.getColorSchemeOrDefault(themeColor, isDark, true)
}
}
AppTheme.DARK -> {
if (isMaterialYouAware && AndroidVersion.ATLEAST_API31_S) {
dynamicDarkColorScheme(context)
} else {
ColorMappings.getColorSchemeOrDefault(themeColor, isDark = true, settings = true)
}
}
AppTheme.LIGHT -> {
if (isMaterialYouAware && AndroidVersion.ATLEAST_API31_S) {
dynamicLightColorScheme(context)
} else {
ColorMappings.getColorSchemeOrDefault(themeColor, isDark = false, settings = true)
}
}
AppTheme.AMOLED_DARK -> {
if (isMaterialYouAware && AndroidVersion.ATLEAST_API31_S) {
dynamicDarkColorScheme(context).amoled()
} else {
ColorMappings.getColorSchemeOrDefault(themeColor, isDark = true, settings = true).amoled()
}
}
AppTheme.AUTO_AMOLED -> {
if (isMaterialYouAware && AndroidVersion.ATLEAST_API31_S) {
when {
isDark -> dynamicDarkColorScheme(context).amoled()
else -> dynamicLightColorScheme(context)
}
} else {
with(ColorMappings.getColorSchemeOrDefault(themeColor, isDark, true)) {
if (isDark) amoled() else this
}
}
}
}
}
fun ColorScheme.amoled(): ColorScheme {
return this.copy(background = Color.Black, surface = Color.Black)
}
@Composable
fun FlorisAppTheme(
theme: AppTheme,
isMaterialYouAware: Boolean,
content: @Composable () -> Unit
content: @Composable () -> Unit,
) {
val prefs by florisPreferenceModel()
val accent by prefs.advanced.accentColor.observeAsState()
val colors = if (AndroidVersion.ATLEAST_API31_S) {
when (theme) {
AppTheme.AUTO -> when {
isMaterialYouAware -> when {
isSystemInDarkTheme() -> dynamicDarkColorScheme(LocalContext.current)
else -> dynamicLightColorScheme(LocalContext.current)
}
else -> {
when {
isSystemInDarkTheme() -> darkScheme
else -> lightScheme
}
}
}
AppTheme.AUTO_AMOLED -> when {
isMaterialYouAware -> when {
isSystemInDarkTheme() -> dynamicDarkColorScheme(LocalContext.current).copy(
background = amoledDark,
surface = amoledDark,
)
else -> dynamicLightColorScheme(LocalContext.current)
}
else -> {
when {
isSystemInDarkTheme() -> amoledScheme
else -> lightScheme
}
}
}
AppTheme.LIGHT -> when {
isMaterialYouAware -> dynamicLightColorScheme(LocalContext.current)
else -> lightScheme
}
AppTheme.DARK -> when {
isMaterialYouAware -> dynamicDarkColorScheme(LocalContext.current)
else -> darkScheme
}
AppTheme.AMOLED_DARK -> when {
isMaterialYouAware -> dynamicDarkColorScheme(LocalContext.current).copy(
background = amoledDark,
surface = amoledDark,
)
else -> amoledScheme
}
}
} else {
when (theme) {
AppTheme.AUTO -> when {
isSystemInDarkTheme() -> darkScheme
else -> lightScheme
}
AppTheme.AUTO_AMOLED -> when {
isSystemInDarkTheme() -> darkScheme
else -> lightScheme
}
AppTheme.LIGHT -> lightScheme
AppTheme.DARK -> darkScheme
AppTheme.AMOLED_DARK -> amoledScheme
}
}
val colors = getColorScheme(
context = LocalContext.current,
theme = theme,
isMaterialYouAware = isMaterialYouAware,
themeColor = accent,
)
val darkTheme =
theme == AppTheme.DARK
|| theme == AppTheme.AMOLED_DARK
|| (theme == AppTheme.AUTO && isSystemInDarkTheme())
|| (theme == AppTheme.AUTO_AMOLED && isSystemInDarkTheme())
|| theme == AppTheme.AMOLED_DARK
|| (theme == AppTheme.AUTO && isSystemInDarkTheme())
|| (theme == AppTheme.AUTO_AMOLED && isSystemInDarkTheme())
val view = LocalView.current
if (!view.isInEditMode) {

View File

@@ -43,6 +43,7 @@ import dev.patrickgold.florisboard.app.florisPreferenceModel
import dev.patrickgold.florisboard.clipboardManager
import dev.patrickgold.florisboard.editorInstance
import dev.patrickgold.florisboard.ime.keyboard.CachedLayout
import dev.patrickgold.florisboard.ime.keyboard.DebugLayoutComputationResult
import dev.patrickgold.florisboard.ime.nlp.NlpInlineAutofill
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.FlorisLocale
@@ -65,7 +66,6 @@ fun DevtoolsOverlay(modifier: Modifier = Modifier) {
val devtoolsEnabled by prefs.devtools.enabled.observeAsState()
val showPrimaryClip by prefs.devtools.showPrimaryClip.observeAsState()
val showInputStateOverlay by prefs.devtools.showInputStateOverlay.observeAsState()
val showLastLayoutComputation by prefs.devtools.showLastLayoutComputation.observeAsState()
val showSpellingOverlay by prefs.devtools.showSpellingOverlay.observeAsState()
val showInlineAutofillOverlay by prefs.devtools.showInlineAutofillOverlay.observeAsState()
@@ -82,8 +82,8 @@ fun DevtoolsOverlay(modifier: Modifier = Modifier) {
if (devtoolsEnabled && showInputStateOverlay) {
DevtoolsInputStateOverlay()
}
if (devtoolsEnabled && showLastLayoutComputation || debugLayoutResult?.allLayoutsSuccess() == false) {
DevtoolsLastLayoutComputationOverlay()
if (debugLayoutResult?.allLayoutsSuccess() == false) {
DevtoolsLastLayoutComputationOverlay(debugLayoutResult)
}
if (devtoolsEnabled && showSpellingOverlay) {
DevtoolsSpellingOverlay()
@@ -137,13 +137,9 @@ private fun DevtoolsInputStateOverlay() {
}
@Composable
private fun DevtoolsLastLayoutComputationOverlay() {
val context = LocalContext.current
val keyboardManager by context.keyboardManager()
val debugLayoutResult by keyboardManager.layoutManager.debugLayoutComputationResultFlow.collectAsState()
private fun DevtoolsLastLayoutComputationOverlay(debugLayoutResult: DebugLayoutComputationResult?) {
@Composable
fun PrintResult(result: Result<CachedLayout>) {
fun PrintResult(result: Result<CachedLayout?>) {
if (result.isSuccess) {
DevtoolsText(text = "loaded: ${result.getOrNull()?.name}")
} else {

View File

@@ -73,12 +73,6 @@ fun DevtoolsScreen() = FlorisScreen {
summary = stringRes(R.string.devtools__show_input_state_overlay__summary),
enabledIf = { prefs.devtools.enabled isEqualTo true },
)
SwitchPreference(
prefs.devtools.showLastLayoutComputation,
title = "Show last layout computation",
summary = "Show the last layout computation in a dialog",
enabledIf = { prefs.devtools.enabled isEqualTo true },
)
SwitchPreference(
prefs.devtools.showSpellingOverlay,
title = stringRes(R.string.devtools__show_spelling_overlay__label),
@@ -128,6 +122,13 @@ fun DevtoolsScreen() = FlorisScreen {
onClick = { navController.navigate(Routes.Devtools.ExportDebugLog) },
enabledIf = { prefs.devtools.enabled isEqualTo true },
)
SwitchPreference(
prefs.glide.enabled,
title = "prefs.glide.enabled (debug)",
summaryOn = "This impacts your performance and may trigger the all keys invisible bug!",
summaryOff = "Recommended to keep this off!",
enabledIf = { prefs.devtools.enabled isEqualTo true },
)
}
PreferenceGroup(title = stringRes(R.string.devtools__group_android__title)) {

View File

@@ -19,13 +19,15 @@ package dev.patrickgold.florisboard.app.settings.advanced
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Adb
import androidx.compose.material.icons.filled.Archive
import androidx.compose.material.icons.filled.FormatPaint
import androidx.compose.material.icons.filled.FormatColorFill
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Preview
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.platform.LocalContext
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.AppTheme
import dev.patrickgold.florisboard.app.LocalNavController
@@ -34,16 +36,20 @@ import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.core.DisplayLanguageNamesIn
import dev.patrickgold.florisboard.ime.keyboard.IncognitoMode
import dev.patrickgold.florisboard.lib.FlorisLocale
import org.florisboard.lib.android.AndroidVersion
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
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.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
@Composable
fun AdvancedScreen() = FlorisScreen {
@@ -51,6 +57,7 @@ fun AdvancedScreen() = FlorisScreen {
previewFieldVisible = false
val navController = LocalNavController.current
val context = LocalContext.current
content {
ListPreference(
@@ -59,13 +66,21 @@ fun AdvancedScreen() = FlorisScreen {
title = stringRes(R.string.pref__advanced__settings_theme__label),
entries = enumDisplayEntriesOf(AppTheme::class),
)
SwitchPreference(
pref = prefs.advanced.useMaterialYou,
icon = Icons.Default.FormatPaint,
title = stringRes(R.string.pref__advanced__settings_material_you__label),
visibleIf = {
AndroidVersion.ATLEAST_API31_S
},
ColorPickerPreference(
pref = prefs.advanced.accentColor,
title = stringRes(R.string.pref__advanced__settings_accent_color__label),
defaultValueLabel = stringRes(R.string.action__default),
icon = Icons.Default.FormatColorFill,
defaultColors = ColorMappings.colors,
showAlphaSlider = false,
enableAdvancedLayout = false,
colorOverride = {
if (it.isMaterialYou(context)) {
Color.Unspecified
} else {
it
}
}
)
ListPreference(
prefs.advanced.settingsLanguage,

View File

@@ -19,12 +19,14 @@ package dev.patrickgold.florisboard.app.settings.theme
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BrightnessAuto
import androidx.compose.material.icons.filled.ColorLens
import androidx.compose.material.icons.filled.DarkMode
import androidx.compose.material.icons.filled.LightMode
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
@@ -41,8 +43,11 @@ 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
import dev.patrickgold.jetpref.datastore.ui.ColorPickerPreference
import dev.patrickgold.jetpref.datastore.ui.ListPreference
import dev.patrickgold.jetpref.datastore.ui.Preference
import dev.patrickgold.jetpref.datastore.ui.isMaterialYou
import org.florisboard.lib.color.ColorMappings
@Composable
fun ThemeScreen() = FlorisScreen {
@@ -108,6 +113,22 @@ fun ThemeScreen() = FlorisScreen {
navController.navigate(Routes.Settings.ThemeManager(ThemeManagerScreenAction.SELECT_NIGHT))
},
)
ColorPickerPreference(
pref = prefs.theme.accentColor,
title = stringRes(R.string.pref__theme__theme_accent_color__label),
defaultValueLabel = stringRes(R.string.action__default),
icon = Icons.Default.ColorLens,
defaultColors = ColorMappings.colors,
showAlphaSlider = false,
enableAdvancedLayout = false,
colorOverride = {
if (it.isMaterialYou(context)) {
Color.Unspecified
} else {
it
}
}
)
AddonManagementReferenceBox(type = ExtensionListScreenType.EXT_THEME)
}

View File

@@ -45,9 +45,6 @@ import dev.patrickgold.florisboard.app.FlorisAppActivity
import dev.patrickgold.florisboard.app.LocalNavController
import dev.patrickgold.florisboard.app.Routes
import dev.patrickgold.florisboard.app.florisPreferenceModel
import org.florisboard.lib.android.AndroidVersion
import dev.patrickgold.florisboard.lib.util.launchActivity
import dev.patrickgold.florisboard.lib.util.launchUrl
import dev.patrickgold.florisboard.lib.compose.FlorisBulletSpacer
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.FlorisScreenScope
@@ -56,9 +53,12 @@ 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
import dev.patrickgold.jetpref.datastore.model.observeAsState
import dev.patrickgold.jetpref.datastore.ui.PreferenceUiScope
import kotlinx.coroutines.delay
import org.florisboard.lib.android.AndroidVersion
@Composable
@@ -105,128 +105,65 @@ private fun FlorisScreenScope.content(
hasNotificationPermission: NotificationPermissionState,
) {
// Show screen without notification permission if the android version is below android 13.
if (AndroidVersion.ATMOST_API32_S_V2) {
val stepState = rememberSaveable(saver = FlorisStepState.Saver) {
val initStep = when {
!isFlorisBoardEnabled -> Steps.EnableIme.id
!isFlorisBoardSelected -> Steps.SelectIme.id
hasNotificationPermission == NotificationPermissionState.NOT_SET && AndroidVersion.ATLEAST_API33_T -> Steps.SelectNotification.id
else -> Steps.FinishUp.id
}
FlorisStepState.new(init = initStep)
}
val stepState = rememberSaveable(saver = FlorisStepState.Saver) {
val initStep = when {
!isFlorisBoardEnabled -> Steps.WithoutNotifications.EnableIme.id
!isFlorisBoardSelected -> Steps.WithoutNotifications.SelectIme.id
else -> Steps.WithoutNotifications.FinishUp.id
}
FlorisStepState.new(init = initStep)
content {
LaunchedEffect(isFlorisBoardEnabled, isFlorisBoardSelected, hasNotificationPermission) {
stepState.setCurrentAuto(
when {
!isFlorisBoardEnabled -> Steps.EnableIme.id
!isFlorisBoardSelected -> Steps.SelectIme.id
hasNotificationPermission == NotificationPermissionState.NOT_SET && AndroidVersion.ATLEAST_API33_T -> Steps.SelectNotification.id
else -> Steps.FinishUp.id
}
)
}
content {
LaunchedEffect(isFlorisBoardEnabled, isFlorisBoardSelected) {
stepState.setCurrentAuto(
when {
!isFlorisBoardEnabled -> Steps.WithoutNotifications.EnableIme.id
!isFlorisBoardSelected -> Steps.WithoutNotifications.SelectIme.id
else -> Steps.WithoutNotifications.FinishUp.id
}
)
}
// Below block allows to return from the system IME enabler activity
// as soon as it gets selected.
LaunchedEffect(Unit) {
while (true) {
delay(200L)
val isEnabled = InputMethodUtils.isFlorisboardEnabled(context)
if (stepState.getCurrentAuto().value == Steps.WithoutNotifications.EnableIme.id &&
stepState.getCurrentManual().value == -1 &&
!isFlorisBoardEnabled &&
!isFlorisBoardSelected &&
isEnabled
) {
context.launchActivity(FlorisAppActivity::class) {
it.flags = (Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
or Intent.FLAG_ACTIVITY_SINGLE_TOP
or Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
// Below block allows to return from the system IME enabler activity
// as soon as it gets selected.
LaunchedEffect(Unit) {
while (true) {
delay(200L)
val isEnabled = InputMethodUtils.isFlorisboardEnabled(context)
if (stepState.getCurrentAuto().value == Steps.EnableIme.id &&
stepState.getCurrentManual().value == -1 &&
!isFlorisBoardEnabled &&
!isFlorisBoardSelected &&
hasNotificationPermission == NotificationPermissionState.NOT_SET &&
isEnabled
) {
context.launchActivity(FlorisAppActivity::class) {
it.flags = (Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
or Intent.FLAG_ACTIVITY_SINGLE_TOP
or Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
}
FlorisStepLayout(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
stepState = stepState,
header = {
StepText(stringRes(R.string.setup__intro_message))
Spacer(modifier = Modifier.height(16.dp))
},
steps = steps(
context, navController, requestNotification
),
footer = {
footer(context)
},
)
}
// Show the screen with notification permission on android 13+
} else {
val stepState = rememberSaveable(saver = FlorisStepState.Saver) {
val initStep = when {
!isFlorisBoardEnabled -> Steps.WithNotifications.EnableIme.id
!isFlorisBoardSelected -> Steps.WithNotifications.SelectIme.id
hasNotificationPermission == NotificationPermissionState.NOT_SET -> Steps.WithNotifications.SelectNotification.id
else -> Steps.WithNotifications.FinishUp.id
}
FlorisStepState.new(init = initStep)
}
content {
LaunchedEffect(isFlorisBoardEnabled, isFlorisBoardSelected, hasNotificationPermission) {
stepState.setCurrentAuto(
when {
!isFlorisBoardEnabled -> Steps.WithNotifications.EnableIme.id
!isFlorisBoardSelected -> Steps.WithNotifications.SelectIme.id
hasNotificationPermission == NotificationPermissionState.NOT_SET -> Steps.WithNotifications.SelectNotification.id
else -> Steps.WithNotifications.FinishUp.id
}
)
}
// Below block allows to return from the system IME enabler activity
// as soon as it gets selected.
LaunchedEffect(Unit) {
while (true) {
delay(200L)
val isEnabled = InputMethodUtils.isFlorisboardEnabled(context)
if (stepState.getCurrentAuto().value == Steps.WithNotifications.EnableIme.id &&
stepState.getCurrentManual().value == -1 &&
!isFlorisBoardEnabled &&
!isFlorisBoardSelected &&
hasNotificationPermission == NotificationPermissionState.NOT_SET &&
isEnabled
) {
context.launchActivity(FlorisAppActivity::class) {
it.flags = (Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
or Intent.FLAG_ACTIVITY_SINGLE_TOP
or Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
}
}
FlorisStepLayout(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
stepState = stepState,
header = {
StepText(stringRes(R.string.setup__intro_message))
Spacer(modifier = Modifier.height(16.dp))
},
steps = steps(
context, navController, requestNotification
),
footer = {
footer(context)
},
)
}
FlorisStepLayout(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
stepState = stepState,
header = {
StepText(stringRes(R.string.setup__intro_message))
Spacer(modifier = Modifier.height(16.dp))
},
steps = steps(
context, navController, requestNotification
),
footer = {
footer(context)
},
)
}
}
@@ -255,105 +192,60 @@ private fun footer(context: Context) {
private fun PreferenceUiScope<AppPrefs>.steps(
context: Context,
navController: NavController,
requestNotification: ManagedActivityResultLauncher<String, Boolean>
requestNotification: ManagedActivityResultLauncher<String, Boolean>,
): List<FlorisStep> {
return if (AndroidVersion.ATMOST_API32_S_V2) {
listOf(
return listOfNotNull(
FlorisStep(
id = Steps.EnableIme.id,
title = stringRes(R.string.setup__enable_ime__title),
) {
StepText(stringRes(R.string.setup__enable_ime__description))
StepButton(label = stringRes(R.string.setup__enable_ime__open_settings_btn)) {
InputMethodUtils.showImeEnablerActivity(context)
}
},
FlorisStep(
id = Steps.SelectIme.id,
title = stringRes(R.string.setup__select_ime__title),
) {
StepText(stringRes(R.string.setup__select_ime__description))
StepButton(label = stringRes(R.string.setup__select_ime__switch_keyboard_btn)) {
InputMethodUtils.showImePicker(context)
}
},
if (AndroidVersion.ATLEAST_API33_T) {
FlorisStep(
id = Steps.WithoutNotifications.EnableIme.id,
title = stringRes(R.string.setup__enable_ime__title),
) {
StepText(stringRes(R.string.setup__enable_ime__description))
StepButton(label = stringRes(R.string.setup__enable_ime__open_settings_btn)) {
InputMethodUtils.showImeEnablerActivity(context)
}
},
FlorisStep(
id = Steps.WithoutNotifications.SelectIme.id,
title = stringRes(R.string.setup__select_ime__title),
) {
StepText(stringRes(R.string.setup__select_ime__description))
StepButton(label = stringRes(R.string.setup__select_ime__switch_keyboard_btn)) {
InputMethodUtils.showImePicker(context)
}
},
FlorisStep(
id = Steps.WithoutNotifications.FinishUp.id,
title = stringRes(R.string.setup__finish_up__title),
) {
StepText(stringRes(R.string.setup__finish_up__description_p1))
StepText(stringRes(R.string.setup__finish_up__description_p2))
StepButton(label = stringRes(R.string.setup__finish_up__finish_btn)) {
this@steps.prefs.internal.isImeSetUp.set(true)
navController.navigate(Routes.Settings.Home) {
popUpTo(Routes.Setup.Screen) {
inclusive = true
}
}
}
},
)
} else {
listOf(
FlorisStep(
id = Steps.WithNotifications.EnableIme.id,
title = stringRes(R.string.setup__enable_ime__title),
) {
StepText(stringRes(R.string.setup__enable_ime__description))
StepButton(label = stringRes(R.string.setup__enable_ime__open_settings_btn)) {
InputMethodUtils.showImeEnablerActivity(context)
}
},
FlorisStep(
id = Steps.WithNotifications.SelectIme.id,
title = stringRes(R.string.setup__select_ime__title),
) {
StepText(stringRes(R.string.setup__select_ime__description))
StepButton(label = stringRes(R.string.setup__select_ime__switch_keyboard_btn)) {
InputMethodUtils.showImePicker(context)
}
},
FlorisStep(
id = Steps.WithNotifications.SelectNotification.id,
title = stringRes(R.string.setup__grant_notification_permission__title)
id = Steps.SelectNotification.id,
title = stringRes(R.string.setup__grant_notification_permission__title),
) {
StepText(stringRes(R.string.setup__grant_notification_permission__description))
StepButton(stringRes(R.string.setup__grant_notification_permission__btn)) {
if (AndroidVersion.ATLEAST_API33_T) {
requestNotification.launch(android.Manifest.permission.POST_NOTIFICATIONS)
requestNotification.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
}
} else null,
FlorisStep(
id = Steps.FinishUp.id,
title = stringRes(R.string.setup__finish_up__title),
) {
StepText(stringRes(R.string.setup__finish_up__description_p1))
StepText(stringRes(R.string.setup__finish_up__description_p2))
StepButton(label = stringRes(R.string.setup__finish_up__finish_btn)) {
this@steps.prefs.internal.isImeSetUp.set(true)
navController.navigate(Routes.Settings.Home) {
popUpTo(Routes.Setup.Screen) {
inclusive = true
}
}
},
FlorisStep(
id = Steps.WithNotifications.FinishUp.id,
title = stringRes(R.string.setup__finish_up__title),
) {
StepText(stringRes(R.string.setup__finish_up__description_p1))
StepText(stringRes(R.string.setup__finish_up__description_p2))
StepButton(label = stringRes(R.string.setup__finish_up__finish_btn)) {
this@steps.prefs.internal.isImeSetUp.set(true)
navController.navigate(Routes.Settings.Home) {
popUpTo(Routes.Setup.Screen) {
inclusive = true
}
}
}
},
)
}
}
}
)
}
private sealed class Steps(val id: Int) {
sealed class WithoutNotifications(id: Int) : Steps(id) {
data object EnableIme : WithoutNotifications(id = 1)
data object SelectIme : WithoutNotifications(id = 2)
data object FinishUp : WithoutNotifications(id = 3)
}
sealed class WithNotifications(id: Int) : Steps(id) {
data object EnableIme : WithNotifications(id = 1)
data object SelectIme : WithNotifications(id = 2)
data object SelectNotification : WithNotifications(id = 3)
data object FinishUp : WithNotifications(id = 4)
}
data object EnableIme : Steps(id = 1)
data object SelectIme : Steps(id = 2)
data object SelectNotification : Steps(id = 3)
data object FinishUp : Steps(id = 4)
}

View File

@@ -214,6 +214,7 @@ fun ClipboardInputLayout(
contentScrollInsteadOfClip: Boolean,
modifier: Modifier = Modifier,
) {
val fontSize = style.fontSize.spSize() safeTimes 1f
SnyggSurface(
modifier = modifier
.fillMaxWidth()
@@ -258,7 +259,7 @@ fun ClipboardInputLayout(
text = bitmap.exceptionOrNull()?.message ?: "Unknown error",
style = TextStyle(textDirection = TextDirection.Ltr),
color = Color.Red,
fontSize = style.fontSize.spSize(),
fontSize = fontSize,
)
}
} else if (item.type == ItemType.VIDEO) {
@@ -305,7 +306,7 @@ fun ClipboardInputLayout(
text = bitmap.exceptionOrNull()?.message ?: "Unknown error",
style = TextStyle(textDirection = TextDirection.Ltr),
color = Color.Red,
fontSize = style.fontSize.spSize(),
fontSize = fontSize,
)
}
} else {
@@ -510,7 +511,7 @@ fun ClipboardInputLayout(
Text(
text = stringRes(R.string.clipboard__empty__message),
color = itemStyle.foreground.solidColor(context),
fontSize = itemStyle.fontSize.spSize(),
fontSize = itemStyle.fontSize.spSize() safeTimes 1f,
textAlign = TextAlign.Center,
)
}
@@ -544,7 +545,7 @@ fun ClipboardInputLayout(
Text(
text = stringRes(R.string.clipboard__disabled__message),
color = itemStyle.foreground.solidColor(context),
fontSize = itemStyle.fontSize.spSize(),
fontSize = itemStyle.fontSize.spSize() safeTimes 1f,
)
SnyggButton(
modifier = Modifier
@@ -578,7 +579,7 @@ fun ClipboardInputLayout(
Text(
text = stringRes(R.string.clipboard__locked__message),
color = itemStyle.foreground.solidColor(context),
fontSize = itemStyle.fontSize.spSize(),
fontSize = itemStyle.fontSize.spSize() safeTimes 1f,
textAlign = TextAlign.Center,
)
}

View File

@@ -43,6 +43,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
@@ -121,8 +122,8 @@ class FlorisCopyToClipboardActivity : ComponentActivity() {
setContent {
ProvideLocalizedResources(this, forceLayoutDirection = LayoutDirection.Ltr) {
val theme by prefs.advanced.settingsTheme.observeAsState()
val isMaterialYouAware by prefs.advanced.useMaterialYou.observeAsState()
FlorisAppTheme(theme, isMaterialYouAware) {
val accentColor by prefs.advanced.accentColor.observeAsState()
FlorisAppTheme(theme, accentColor.isUnspecified) {
BottomSheet {
Row {
Text(
@@ -162,7 +163,9 @@ class FlorisCopyToClipboardActivity : ComponentActivity() {
Column {
content()
Button(
modifier = Modifier.align(Alignment.End).padding(16.dp),
modifier = Modifier
.align(Alignment.End)
.padding(16.dp),
onClick = { finish() },
colors = ButtonDefaults.textButtonColors(
//containerColor = buttonContainer.background.solidColor(context = context),

View File

@@ -0,0 +1,142 @@
/*
* 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.ime.core
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.RadioButtonChecked
import androidx.compose.material.icons.filled.RadioButtonUnchecked
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.keyboard.KeyboardState
import dev.patrickgold.florisboard.ime.theme.FlorisImeTheme
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.keyboardManager
import dev.patrickgold.florisboard.lib.compose.rippleClickable
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.florisboard.subtypeManager
import dev.patrickgold.jetpref.material.ui.JetPrefListItem
import org.florisboard.lib.snygg.ui.snyggBackground
import org.florisboard.lib.snygg.ui.snyggClip
import org.florisboard.lib.snygg.ui.solidColor
import org.florisboard.lib.snygg.ui.spSize
@Composable
fun SelectSubtypePanel(modifier: Modifier = Modifier) {
val context = LocalContext.current
val keyboardManager by context.keyboardManager()
val subtypeManager by context.subtypeManager()
val listState = rememberLazyListState()
val subtypes by subtypeManager.subtypesFlow.collectAsState()
val currentlySelected = subtypeManager.activeSubtype.id
val panelStyle = FlorisImeTheme.style.get(FlorisImeUi.SmartbarActionsEditor)
val headerStyle = FlorisImeTheme.style.get(FlorisImeUi.SmartbarActionsEditorHeader)
val subheaderStyle = FlorisImeTheme.style.get(FlorisImeUi.SmartbarActionsEditorSubheader)
Column(
modifier = modifier
.snyggBackground(context, panelStyle, fallbackColor = FlorisImeTheme.fallbackSurfaceColor())
.snyggClip(panelStyle),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
.snyggBackground(context, headerStyle),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
modifier = Modifier
.weight(1f)
.clickable(false) {},
text = stringRes(R.string.select_subtype_panel__header),
color = headerStyle.foreground.solidColor(
context,
default = FlorisImeTheme.fallbackContentColor()
),
fontSize = headerStyle.fontSize.spSize(),
textAlign = TextAlign.Center,
)
}
Box {
LazyColumn(
state = listState,
) {
items(
subtypes,
key = {
it.id
}
) {
JetPrefListItem(
modifier = Modifier
.fillMaxWidth()
.rippleClickable {
subtypeManager.switchToSubtypeById(it.id)
keyboardManager.activeState.isSubtypeSelectionVisible = false
},
icon = {
if (currentlySelected == it.id) {
Icon(Icons.Default.RadioButtonChecked, null)
} else {
Icon(Icons.Default.RadioButtonUnchecked, null)
}
},
text = it.primaryLocale.displayName(),
colors = ListItemDefaults.colors(
leadingIconColor = subheaderStyle.foreground.solidColor(context),
headlineColor = subheaderStyle.foreground.solidColor(context),
containerColor = subheaderStyle.background.solidColor(context),
)
)
}
}
}
Spacer(Modifier
.systemBarsPadding()
.snyggBackground(context, panelStyle))
}
}
fun KeyboardState.isSubtypeSelectionShowing(): Boolean {
return isSubtypeSelectionVisible
}

View File

@@ -24,7 +24,6 @@ import dev.patrickgold.florisboard.lib.FlorisLocale
import dev.patrickgold.florisboard.lib.devtools.flogDebug
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@@ -227,4 +226,11 @@ class SubtypeManager(context: Context) {
prefs.localization.activeSubtypeId.set(newActiveSubtype.id)
activeSubtype = newActiveSubtype
}
fun switchToSubtypeById(id: Long) {
if (subtypes.any { it.id == id }) {
activeSubtype = getSubtypeById(id)!!
prefs.localization.activeSubtypeId.set(id)
}
}
}

View File

@@ -55,10 +55,6 @@ import dev.patrickgold.florisboard.ime.text.key.KeyType
import dev.patrickgold.florisboard.ime.text.key.UtilityKeyAction
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboardCache
import org.florisboard.lib.android.AndroidKeyguardManager
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.systemService
import dev.patrickgold.florisboard.lib.devtools.LogTopic
import dev.patrickgold.florisboard.lib.devtools.flogError
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
@@ -75,6 +71,10 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.florisboard.lib.android.AndroidKeyguardManager
import org.florisboard.lib.android.showLongToast
import org.florisboard.lib.android.showShortToast
import org.florisboard.lib.android.systemService
import org.florisboard.lib.kotlin.collectIn
import org.florisboard.lib.kotlin.collectLatestIn
import java.lang.ref.WeakReference
@@ -189,7 +189,7 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
keyboardMode = mode,
subtype = subtype,
).await()
}.await()
}
val computingEvaluator = ComputingEvaluatorImpl(
version = activeEvaluatorVersion++,
keyboard = computedKeyboard,
@@ -272,6 +272,7 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
SwipeAction.REDO -> TextKeyData.REDO
SwipeAction.UNDO -> TextKeyData.UNDO
SwipeAction.SHOW_INPUT_METHOD_PICKER -> TextKeyData.SYSTEM_INPUT_METHOD_PICKER
SwipeAction.SHOW_SUBTYPE_PICKER -> TextKeyData.SHOW_SUBTYPE_PICKER
SwipeAction.SWITCH_TO_CLIPBOARD_CONTEXT -> TextKeyData.IME_UI_MODE_CLIPBOARD
SwipeAction.SWITCH_TO_PREV_SUBTYPE -> TextKeyData.IME_PREV_SUBTYPE
SwipeAction.SWITCH_TO_NEXT_SUBTYPE -> TextKeyData.IME_NEXT_SUBTYPE
@@ -742,6 +743,9 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
KeyCode.SHIFT -> handleShiftUp(data)
KeyCode.SPACE -> handleSpace(data)
KeyCode.SYSTEM_INPUT_METHOD_PICKER -> InputMethodUtils.showImePicker(appContext)
KeyCode.SHOW_SUBTYPE_PICKER -> {
appContext.keyboardManager.value.activeState.isSubtypeSelectionVisible = true
}
KeyCode.SYSTEM_PREV_INPUT_METHOD -> FlorisImeService.switchToPrevInputMethod()
KeyCode.SYSTEM_NEXT_INPUT_METHOD -> FlorisImeService.switchToNextInputMethod()
KeyCode.TOGGLE_SMARTBAR_VISIBILITY -> {
@@ -867,17 +871,22 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
val punctuationRules = MutableLiveData<Map<ExtensionComponentName, PunctuationRule>>(emptyMap())
val subtypePresets = MutableLiveData<List<SubtypePreset>>(emptyList())
private val anyChangedGuard = Mutex(locked = false)
val anyChanged = MutableLiveData(Unit)
init {
scope.launch(Dispatchers.Main.immediate) {
extensionManager.keyboardExtensions.observeForever { keyboardExtensions ->
parseKeyboardExtensions(keyboardExtensions)
scope.launch {
anyChangedGuard.withLock {
parseKeyboardExtensions(keyboardExtensions)
}
}
}
}
}
private fun parseKeyboardExtensions(keyboardExtensions: List<KeyboardExtension>) = scope.launch {
private fun parseKeyboardExtensions(keyboardExtensions: List<KeyboardExtension>) {
val localComposers = mutableMapOf<ExtensionComponentName, Composer>()
val localCurrencySets = mutableMapOf<ExtensionComponentName, CurrencySet>()
val localLayouts = mutableMapOf<LayoutType, MutableMap<ExtensionComponentName, LayoutArrangementComponent>>()

View File

@@ -57,6 +57,7 @@ import kotlin.properties.Delegates
*
* <Byte 7> | <Byte 6> | <Byte 5> | <Byte 4> | Description
* ---------|----------|----------|----------|---------------------------------
* | | | 1 | Subtype selection dialog visible
* 1 | | | | Devtools: Show drag&drop helpers
*
* The resulting structure is only relevant during a runtime lifespan and
@@ -91,6 +92,8 @@ open class KeyboardState protected constructor(open var rawValue: ULong) {
const val F_IS_RTL_LAYOUT_DIRECTION: ULong = 0x08000000u
const val F_IS_SUBTYPE_SELECTION_VISIBLE: ULong = 0x1_0000_0000u
const val F_DEBUG_SHOW_DRAG_AND_DROP_HELPERS = 0x01_00_00_00_00_00_00_00uL
const val STATE_ALL_ZERO: ULong = 0uL
@@ -188,6 +191,10 @@ open class KeyboardState protected constructor(open var rawValue: ULong) {
get() = getFlag(F_IS_ACTIONS_EDITOR_VISIBLE)
set(v) { setFlag(F_IS_ACTIONS_EDITOR_VISIBLE, v) }
var isSubtypeSelectionVisible: Boolean
get() = getFlag(F_IS_SUBTYPE_SELECTION_VISIBLE)
set(v) { setFlag(F_IS_SUBTYPE_SELECTION_VISIBLE, v) }
var isComposingEnabled: Boolean
get() = getFlag(F_IS_COMPOSING_ENABLED)
set(v) { setFlag(F_IS_COMPOSING_ENABLED, v) }

View File

@@ -65,9 +65,9 @@ private data class CachedPopupMapping(
)
data class DebugLayoutComputationResult(
val main: Result<CachedLayout>,
val mod: Result<CachedLayout>,
val ext: Result<CachedLayout>,
val main: Result<CachedLayout?>,
val mod: Result<CachedLayout?>,
val ext: Result<CachedLayout?>,
) {
fun allLayoutsSuccess(): Boolean {
return main.isSuccess && mod.isSuccess && ext.isSuccess
@@ -96,8 +96,13 @@ class LayoutManager(context: Context) {
*
* @return A deferred result for a layout.
*/
private fun loadLayoutAsync(ltn: LTN?) = ioScope.runCatchingAsync {
require(ltn != null) { "Invalid argument value for 'ltn': null" }
private fun loadLayoutAsync(ltn: LTN?, allowNullLTN: Boolean) = ioScope.runCatchingAsync {
if (!allowNullLTN) {
requireNotNull(ltn) { "Invalid argument value for 'ltn': null" }
}
if (ltn == null) {
return@runCatchingAsync null
}
layoutCacheGuard.withLock {
val cached = layoutCache[ltn]
if (cached != null) {
@@ -176,7 +181,7 @@ class LayoutManager(context: Context) {
val extendedPopupsDefault = loadPopupMappingAsync()
val extendedPopups = loadPopupMappingAsync(subtype)
val mainLayoutResult = loadLayoutAsync(main).await()
val mainLayoutResult = loadLayoutAsync(main, allowNullLTN = false).await()
val mainLayout = mainLayoutResult.onFailure {
flogWarning { "$keyboardMode - main - $it" }
}.getOrNull()
@@ -196,11 +201,11 @@ class LayoutManager(context: Context) {
} else {
modifier
}
val modifierLayoutResult = loadLayoutAsync(modifierToLoad).await()
val modifierLayoutResult = loadLayoutAsync(modifierToLoad, allowNullLTN = true).await()
val modifierLayout = modifierLayoutResult.onFailure {
flogWarning { "$keyboardMode - mod - $it" }
}.getOrNull()
val extensionLayoutResult = loadLayoutAsync(extension).await()
val extensionLayoutResult = loadLayoutAsync(extension, allowNullLTN = true).await()
val extensionLayout = extensionLayoutResult.onFailure {
flogWarning { "$keyboardMode - ext - $it" }
}.getOrNull()

View File

@@ -21,8 +21,6 @@ import dev.patrickgold.florisboard.lib.FlorisLocale
import io.github.reactivecircus.cache4k.Cache
import org.florisboard.lib.kotlin.GuardedByLock
import org.florisboard.lib.kotlin.guardedByLock
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
open class BreakIteratorGroup {
private val charInstances = Cache.Builder().build<FlorisLocale, GuardedByLock<BreakIterator>>()
@@ -32,19 +30,13 @@ open class BreakIteratorGroup {
private val sentenceInstances = Cache.Builder().build<FlorisLocale, GuardedByLock<BreakIterator>>()
suspend fun <R> character(locale: FlorisLocale, action: (BreakIterator) -> R): R {
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
}
val instance = charInstances.get(locale) {
guardedByLock { BreakIterator.getCharacterInstance(locale.base) }
}
return instance.withLock { action(it) }
return instance.withLock(null, action)
}
suspend fun <R> word(locale: FlorisLocale, action: (BreakIterator) -> R): R {
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
}
val instance = wordInstances.get(locale) {
guardedByLock { BreakIterator.getWordInstance(locale.base) }
}
@@ -52,9 +44,6 @@ open class BreakIteratorGroup {
}
suspend fun <R> sentence(locale: FlorisLocale, action: (BreakIterator) -> R): R {
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
}
val instance = sentenceInstances.get(locale) {
guardedByLock { BreakIterator.getSentenceInstance(locale.base) }
}

View File

@@ -48,7 +48,6 @@ fun BottomSheetHostUi(
val bgColorOutOfBounds by animateColorAsState(
if (isShowing) SheetOutOfBoundsBgColorActive else SheetOutOfBoundsBgColorInactive
)
Column(Modifier.background(bgColorOutOfBounds)) {
Box(
modifier = Modifier

View File

@@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
@@ -352,6 +353,7 @@ fun QuickActionsEditorPanel(modifier: Modifier = Modifier) {
)
}
}
Spacer(Modifier.systemBarsPadding().snyggBackground(context, panelStyle))
}
}

View File

@@ -42,6 +42,7 @@ enum class SwipeAction {
SELECT_WORDS_PRECISELY,
SHIFT,
SHOW_INPUT_METHOD_PICKER,
SHOW_SUBTYPE_PICKER,
SWITCH_TO_PREV_SUBTYPE,
SWITCH_TO_NEXT_SUBTYPE,
SWITCH_TO_CLIPBOARD_CONTEXT,

View File

@@ -95,6 +95,7 @@ object KeyCode {
const val IME_PREV_SUBTYPE = -225
const val IME_NEXT_SUBTYPE = -226
const val LANGUAGE_SWITCH = -227
const val SHOW_SUBTYPE_PICKER = -228
const val IME_SHOW_UI = -231
const val IME_HIDE_UI = -232

View File

@@ -412,6 +412,12 @@ class TextKeyData(
code = KeyCode.SYSTEM_INPUT_METHOD_PICKER,
label = "system_input_method_picker",
)
/** Predefined key data for [KeyCode.SHOW_SUBTYPE_PICKER] */
val SHOW_SUBTYPE_PICKER = TextKeyData(
type = KeyType.FUNCTION,
code = KeyCode.SHOW_SUBTYPE_PICKER,
label = "subtype_picker",
)
/** Predefined key data for [KeyCode.SYSTEM_PREV_INPUT_METHOD] */
val SYSTEM_PREV_INPUT_METHOD = TextKeyData(
type = KeyType.FUNCTION,

View File

@@ -28,6 +28,7 @@ import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import java.util.*
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@@ -42,7 +43,7 @@ import kotlin.contracts.contract
*/
@Suppress("MemberVisibilityCanBePrivate")
class TextKeyboardCache(ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
private val cache: EnumMap<KeyboardMode, SparseArrayCompat<Deferred<TextKeyboard>>> = EnumMap(KeyboardMode::class.java)
private val cache: EnumMap<KeyboardMode, SparseArrayCompat<TextKeyboard>> = EnumMap(KeyboardMode::class.java)
private val scope: CoroutineScope = CoroutineScope(ioDispatcher + SupervisorJob())
init {
@@ -105,7 +106,7 @@ class TextKeyboardCache(ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
* @return The deferred computed keyboard or null if the cache does not have an entry associated with the given
* params.
*/
fun getAsync(mode: KeyboardMode, subtype: Subtype): Deferred<TextKeyboard>? {
fun getAsync(mode: KeyboardMode, subtype: Subtype): TextKeyboard? {
return cache[mode]!![subtype.hashCode()].also {
flogDebug(LogTopic.TEXT_KEYBOARD_VIEW) { "Get keyboard '$mode ${subtype.toShortString()}'" }
}
@@ -122,7 +123,7 @@ class TextKeyboardCache(ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
*
* @return The deferred computed keyboard either from the cache or from [block].
*/
fun getOrElseAsync(mode: KeyboardMode, subtype: Subtype, block: suspend () -> TextKeyboard): Deferred<TextKeyboard> {
fun getOrElseAsync(mode: KeyboardMode, subtype: Subtype, block: suspend () -> TextKeyboard): TextKeyboard {
contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
@@ -130,7 +131,7 @@ class TextKeyboardCache(ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
return if (cachedKeyboard != null) {
cachedKeyboard
} else {
val keyboard = scope.async { block() }
val keyboard = runBlocking { block() }
set(mode, subtype, keyboard)
keyboard
}
@@ -143,7 +144,7 @@ class TextKeyboardCache(ioDispatcher: CoroutineDispatcher = Dispatchers.IO) {
* @param subtype The subtype of the computed keyboard to set.
* @param keyboard The deferred computed keyboard to set for the given params.
*/
fun set(mode: KeyboardMode, subtype: Subtype, keyboard: Deferred<TextKeyboard>) {
fun set(mode: KeyboardMode, subtype: Subtype, keyboard: TextKeyboard) {
flogDebug(LogTopic.TEXT_KEYBOARD_VIEW) { "Set keyboard '$mode ${subtype.toShortString()}'" }
cache[mode]!![subtype.hashCode()] = keyboard
}

View File

@@ -29,13 +29,17 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import dev.patrickgold.florisboard.app.florisPreferenceModel
import dev.patrickgold.florisboard.ime.input.InputShiftState
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.lib.observeAsNonNullState
import dev.patrickgold.florisboard.themeManager
import dev.patrickgold.jetpref.datastore.model.observeAsState
import org.florisboard.lib.android.AndroidVersion
import org.florisboard.lib.color.ColorMappings
import org.florisboard.lib.snygg.Snygg
import org.florisboard.lib.snygg.SnyggStylesheet
import org.florisboard.lib.snygg.ui.ProvideSnyggUiDefaults
@@ -112,20 +116,23 @@ fun FlorisImeTheme(content: @Composable () -> Unit) {
val context = LocalContext.current
val themeManager by context.themeManager()
val prefs by florisPreferenceModel()
val accentColor by prefs.theme.accentColor.observeAsState()
val activeThemeInfo by themeManager.activeThemeInfo.observeAsNonNullState()
val activeConfig = remember(activeThemeInfo) { activeThemeInfo.config }
val activeStyle = remember(activeThemeInfo) { activeThemeInfo.stylesheet }
val materialColors = if (activeConfig.isNightTheme) {
if (AndroidVersion.ATLEAST_API31_S) {
if (AndroidVersion.ATLEAST_API31_S && accentColor.isUnspecified) {
dynamicDarkColorScheme(context)
} else {
MaterialDarkFallbackPalette
ColorMappings.getColorSchemeOrDefault(accentColor, activeConfig.isNightTheme)
}
} else {
if (AndroidVersion.ATLEAST_API31_S) {
if (AndroidVersion.ATLEAST_API31_S && accentColor.isUnspecified) {
dynamicLightColorScheme(context)
} else {
MaterialLightFallbackPalette
ColorMappings.getColorSchemeOrDefault(accentColor, activeConfig.isNightTheme)
}
}
MaterialTheme(materialColors) {

View File

@@ -105,6 +105,9 @@ class ThemeManager(context: Context) {
prefs.theme.mode.observeForever {
updateActiveTheme()
}
prefs.theme.accentColor.observeForever {
updateActiveTheme { MaterialYouColor.updateAccentColor(it) }
}
prefs.theme.dayThemeId.observeForever {
updateActiveTheme()
}

View File

@@ -0,0 +1,35 @@
/*
* 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.ime.theme
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import dev.patrickgold.florisboard.lib.devtools.flogDebug
import dev.patrickgold.florisboard.themeManager
class WallpaperChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null) return
if (context == null) return
@Suppress("DEPRECATION") // We do not retrieve the wallpaper but only listen to changes
if (intent.action == Intent.ACTION_WALLPAPER_CHANGED) {
flogDebug { "Wallpaper changed" }
context.themeManager().value.updateActiveTheme()
}
}
}

View File

@@ -217,7 +217,7 @@ class FlorisLocale private constructor(val base: Locale) {
*/
val supportsCapitalization: Boolean
get() = when (language) {
"zh", "ko", "th", "bn" -> false
"zh", "ko", "th", "bn", "hi" -> false
else -> true
}

View File

@@ -0,0 +1,30 @@
/*
* 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 androidx.compose.ui.graphics.Color
import dev.patrickgold.jetpref.datastore.model.PreferenceSerializer
object ColorPreferenceSerializer : PreferenceSerializer<Color> {
@OptIn(ExperimentalStdlibApi::class)
override fun deserialize(value: String): Color {
return Color(value.hexToULong())
}
@OptIn(ExperimentalStdlibApi::class)
override fun serialize(value: Color): String = value.value.toHexString()
}

View File

@@ -22,7 +22,7 @@ import android.content.ContextWrapper
import android.inputmethodservice.InputMethodService
import android.view.Window
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
@@ -42,7 +42,7 @@ fun SystemUiIme() {
val window = view.context.findWindow()!!
val windowInsetsController = WindowInsetsControllerCompat(window, view)
SideEffect {
LaunchedEffect(backgroundColor) {
if (AndroidVersion.ATLEAST_API26_O) {
window.navigationBarColor = backgroundColor.toArgb()
windowInsetsController.isAppearanceLightNavigationBars = useDarkIcons

View File

@@ -26,6 +26,7 @@ import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import android.widget.Toolbar
import androidx.activity.ComponentActivity
import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.R
@@ -67,6 +68,9 @@ class CrashDialogActivity : ComponentActivity() {
val layout = layoutInflater.inflate(R.layout.crash_dialog, null)
setContentView(layout)
val toolbar = layout.findViewById<Toolbar>(R.id.crash_dialog_toolbar)
setActionBar(toolbar)
stacktraces = CrashUtility.getUnhandledStacktraces(this)
val versionName = buildString {
append("[")

View File

@@ -170,11 +170,6 @@ class ExtensionManager(context: Context) {
init {
value = emptyList()
ioScope.launch {
refreshGuard.withLock {
staticExtensions = indexAssetsModule()
}
}
}
fun init() {
@@ -185,7 +180,10 @@ class ExtensionManager(context: Context) {
internalModuleDir.mkdirs()
// Refresh index to new state
refresh()
refreshGuard.withLock {
staticExtensions = indexAssetsModule()
refresh()
}
// Stop watching on old file observer if one exists and start new observer on new path
fileObserver?.stopWatching()
@@ -193,18 +191,18 @@ class ExtensionManager(context: Context) {
flogDebug(LogTopic.EXT_INDEXING) { "FileObserver.onEvent { event=$event path=$path }" }
if (path == null) return@FileObserver
ioScope.launch {
refresh()
refreshGuard.withLock {
refresh()
}
}
}.also { it.startWatching() }
}
}
}
private suspend fun refresh() {
refreshGuard.withLock {
val dynamicExtensions = staticExtensions + indexInternalModule()
postValue(dynamicExtensions)
}
private fun refresh() {
val dynamicExtensions = staticExtensions + indexInternalModule()
postValue(dynamicExtensions)
}
private fun indexAssetsModule(): List<T> {

View File

@@ -60,7 +60,7 @@ private fun Bundle.debugSummarize(): String {
}
append(key)
append("=")
append(bundle.get(key))
append(bundle.getString(key))
}
append("]")
}

View File

@@ -58,7 +58,7 @@ fun Context.launchUrl(@StringRes url: Int, vararg args: CurlyArg) {
inline fun <T : Any> Context.launchActivity(kClass: KClass<T>, intentModifier: (Intent) -> Unit = { }) {
contract {
callsInPlace(intentModifier, InvocationKind.EXACTLY_ONCE)
callsInPlace(intentModifier, InvocationKind.AT_MOST_ONCE)
}
try {
val intent = Intent(this, kClass.java)
@@ -72,7 +72,7 @@ inline fun <T : Any> Context.launchActivity(kClass: KClass<T>, intentModifier: (
inline fun Context.launchActivity(intentModifier: (Intent) -> Unit) {
contract {
callsInPlace(intentModifier, InvocationKind.EXACTLY_ONCE)
callsInPlace(intentModifier, InvocationKind.AT_MOST_ONCE)
}
try {
val intent = Intent()

View File

@@ -2,9 +2,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp"
android:fitsSystemWindows="true"
android:theme="@style/CrashDialogTheme">
<Toolbar
android:id="@+id/crash_dialog_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:elevation="4dp"/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"

View File

@@ -430,7 +430,6 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">فاتح</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">داكن</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">أسود قاتم</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">استخدام تصميم Material You</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">إعدادات اللغة</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">إظهار أيقونة البرنامج في درج التطبيقات</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">ممكّن دائمًا على اندرويد 10+ فما فوق بسبب قيود النظام</string>

View File

@@ -159,7 +159,6 @@
<string name="pref__gestures__space_bar_title" comment="Preference group title">Xestos de la barra d\'espaciu</string>
<string name="settings__advanced__title" comment="Title of Advanced settings">Configuración avanzada</string>
<string name="pref__advanced__settings_theme__label" comment="Label of Settings theme preference in Advanced">Estilu de la configuración</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Usar «Material You»</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Llingua de la configuración</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Amosar l\'iconu l\'aplicación nel llanzador</string>
<!-- About UI strings -->

View File

@@ -151,6 +151,7 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Време на залез</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Дневна тема</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Нощна тема</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme">Допълнителен цвят (за теми на Material you)</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Управление на теми</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Активи на FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Вътрешно хранилище</string>
@@ -432,7 +433,7 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Светла</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Тъмна</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">Тъмна AMOLED</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Използване на Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced">Допълнителен цвят на настройките</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Език на настройките</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Икона на приложението в стартовия панел</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Винаги видима за Android 10+ поради ограничения на системата</string>

View File

@@ -21,6 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Strategie aktualizace (připnuté)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Strategie aktualizace (nedávné)</string>
<string name="prefs__media__emoji_history_max_size">Maximální počet položek k uchování</string>
<string name="prefs__media__emoji_history_pinned_reset">Resetovat připnuté emotikony</string>
<string name="prefs__media__emoji_history_reset">Resetovat nedávné emotikony</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Návrhy emotikonů</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Povolit návrhy emotikonů</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Poskytovat návrhy emotikonů, zatímco píšete</string>
@@ -149,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Čas západu slunce</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Denní motiv</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Noční motiv</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Barva (motivy Material You)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Spravovat nainstalované motivy</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Podklady aplikace FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Interní úložiště</string>
@@ -430,7 +434,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Světlý</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Tmavý</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Temná</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Použít Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Nastavení barvy
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Jazyk nastavení</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Zobrazit ikonu aplikace na domovské obrazovce</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Vždy povoleno na Android 10+ kvůli omezením systému</string>
@@ -705,6 +710,8 @@
<string name="action__delete">Odstranit</string>
<string name="action__delete_confirm_title">Potvrdit odstranění</string>
<string name="action__delete_confirm_message">Opravdu chcete odstranit \"{name}\"? Tuto operaci nelze po provedení vrátit zpět.</string>
<string name="action__reset_confirm_title">Potvrdit reset</string>
<string name="action__reset_confirm_message">Opravdu chcete resetovat „{name}“? Tuto operaci nelze po provedení vrátit zpět.</string>
<string name="action__discard">Zrušit</string>
<string name="action__discard_confirm_title">Neuložené změny</string>
<string name="action__discard_confirm_message">Opravdu chcete zahodit všechny neuložené změny? Tuto operaci nelze po provedení vrátit zpět.</string>

View File

@@ -21,6 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Update Strategie (gepinnt)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Update Strategie (kürzlich)</string>
<string name="prefs__media__emoji_history_max_size">Maximale zu behaltende Emojis</string>
<string name="prefs__media__emoji_history_pinned_reset">Angepinnte Emojis zurücksetzen</string>
<string name="prefs__media__emoji_history_reset">Zuletzt verwendete Emojis zurücksetzen</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Emoji Vorschläge</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Aktiviere Emoji Vorschläge</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Erhalte Emoji Vorschläge während des Tippens</string>
@@ -149,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Sonnenuntergangszeit</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Helles Design</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Dunkles Design</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Akzentfarbe (Material you designs)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Installierte Designs verwalten</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">FlorisBoard App Ressourcen</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Interner Speicher</string>
@@ -430,7 +434,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Hell</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Dunkel</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Dunkel</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Nutze Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Akzentfarben-Einstellungen
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">App-Sprache</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Zeige die App in der Übersicht</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Immer aktiviert in Android 10+ aufgrund von System-Beschränkungen</string>
@@ -701,6 +706,8 @@
<string name="action__delete">Entfernen</string>
<string name="action__delete_confirm_title">Löschvorgang bestätigen</string>
<string name="action__delete_confirm_message">Bist du sicher, dass du \"{name}\" löschen möchtest? Dieser Vorgang kann nicht rückgängig gemacht werden.</string>
<string name="action__reset_confirm_title">Zurücksetzung bestätigen</string>
<string name="action__reset_confirm_message">Bist du sicher, dass du \"{name}\" zurücksetzen willst? Dies kann nicht rückgängig gemacht werden.</string>
<string name="action__discard">Verwerfen</string>
<string name="action__discard_confirm_title">Nicht gespeicherte Änderungen</string>
<string name="action__discard_confirm_message">Bist du sicher, dass du deine ungespeicherten Änderungen verwerfen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.</string>

View File

@@ -291,7 +291,6 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Hela</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Malhela</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED malhela</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Uzi Material you</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Agordojn lingvo</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Montri aplikaĵo bildeto en aplikaĵolanĉilo</string>
<string name="pref__advanced__incognito_mode__label" comment="Label of Incognito mode preference in Advanced">Inkognita moduso</string>

View File

@@ -13,18 +13,26 @@
<string name="media__tab__emojis" comment="Tab description for emojis in the media UI">Emojis</string>
<string name="media__tab__emoticons" comment="Tab description for emoticons in the media UI">Emoticonos</string>
<string name="media__tab__kaomoji" comment="Tab description for kaomoji in the media UI">Kaomoji</string>
<string name="prefs__media__emoji_preferred_skin_tone">Tono de piel de emoji preferido</string>
<string name="prefs__media__emoji_preferred_hair_style">Estilo de cabello de emoji preferido</string>
<string name="prefs__media__emoji_preferred_skin_tone">Tono de piel preferido de los emojis</string>
<string name="prefs__media__emoji_preferred_hair_style">Estilo del pelo preferido para los emojis</string>
<string name="prefs__media__emoji_history__title" comment="Preference group title">Historial de emojis</string>
<string name="prefs__media__emoji_history_enabled" comment="Preference title">Habilitar historial de emojis</string>
<string name="prefs__media__emoji_history_enabled__summary" comment="Preference summary">Conserva los emojis utilizados recientemente para acceder a ellos rápidamente</string>
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Estrategia de actualización (fijada)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Estrategia de actualización (reciente)</string>
<string name="prefs__media__emoji_history_max_size">Número máximo de artículos a guardar</string>
<string name="prefs__media__emoji_history_pinned_reset">Restablecer emojis fijados</string>
<string name="prefs__media__emoji_history_reset">Restablecer emojis recientes</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Sugerencias de emoticonos</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Habilitar sugerencias de emoticonos</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Proporcionar sugerencias de emoticonos mientras escribes</string>
<string name="prefs__media__emoji_suggestion_type" comment="Preference title">Tipo de acción</string>
<string name="prefs__media__emoji_suggestion_update_history" comment="Preference title">Actualizar el historial de emoticonos</string>
<string name="prefs__media__emoji_suggestion_update_history__summary" comment="Preference summary">Al aceptar emoticonos sugeridos, se añaden al historial de emoticonos</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name" comment="Preference title">Muestra el nombre de emoticono</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name__summary" comment="Preference summary">Las sugerencias de emoticono muestran su nombre junto al emoticono</string>
<string name="prefs__media__emoji_suggestion_query_min_length" comment="Preference title">Longitud mínima de consulta</string>
<string name="prefs__media__emoji_suggestion_candidate_max_count" comment="Preference title">Número máximo de candidatos</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Proporciona sugerencias de emoji mientras escribes</string>
<string name="prefs__media__emoji_suggestion_type" comment="Preference title">Tipo de activador</string>
<string name="prefs__media__emoji_suggestion_update_history" comment="Preference title">Actualizar el historial de emojis</string>
<string name="prefs__media__emoji_suggestion_update_history__summary" comment="Preference summary">Aceptar emojis sugeridos los añade al historial de emojis</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name" comment="Preference title">Mostrar el nombre del emoji</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name__summary" comment="Preference summary">Las sugerencias de los emojis muestran su nombre junto al emoji</string>
<string name="prefs__media__emoji_suggestion_query_min_length" comment="Preference title">Longitud mínima de la consulta</string>
<string name="prefs__media__emoji_suggestion_candidate_max_count" comment="Preference title">Número máximo de sugerencias</string>
<!-- Emoji strings -->
<string name="emoji__category__smileys_emotion" comment="Emoji category name">Smileys &amp; Emociones</string>
<string name="emoji__category__people_body" comment="Emoji category name">Personas &amp; Cuerpo</string>
@@ -35,6 +43,12 @@
<string name="emoji__category__objects" comment="Emoji category name">Objetos</string>
<string name="emoji__category__symbols" comment="Emoji category name">Símbolos</string>
<string name="emoji__category__flags" comment="Emoji category name">Banderas</string>
<string name="emoji__history__empty_message" comment="Message if the emoji history is empty">No se han encontrado emojis que se hayan usado recientemente. Una vez empieces a usar emojis, aparecerán automáticamente aquí.</string>
<string name="emoji__history__phone_locked_message" comment="Message to show if phone is locked">Para acceder a tu historial de emojis, por favor, desbloquea primero tu dispositivo.</string>
<string name="emoji__history__usage_tip" comment="Feature discoverability for actions of emoji history">Consejo: ¡Mantén presionados los emoticonos en el historial de los mismos para fijarlos o eliminarlos!</string>
<string name="emoji__history__removal_success_message" comment="Toast message if user has used the delete action on an emoji in the emoji history">Se ha eliminado {emoji} del historial de emoticonos.</string>
<string name="emoji__history__pinned">Fijado</string>
<string name="emoji__history__recent">Reciente</string>
<!-- Quick action strings -->
<string name="quick_action__arrow_up" maxLength="12">Arriba</string>
<string name="quick_action__arrow_up__tooltip">Realizar flecha hacia arriba</string>
@@ -47,17 +61,17 @@
<string name="quick_action__clipboard_clear_primary_clip" maxLength="12">Borrar clip</string>
<string name="quick_action__clipboard_clear_primary_clip__tooltip">Realizar limpiar portapapeles principal</string>
<string name="quick_action__clipboard_copy" maxLength="12">Copiar</string>
<string name="quick_action__clipboard_copy__tooltip">Realizar copiar portapapeles</string>
<string name="quick_action__clipboard_copy__tooltip">Realizar copia del portapapeles</string>
<string name="quick_action__clipboard_cut" maxLength="12">Cortar</string>
<string name="quick_action__clipboard_cut__tooltip">Realizar cortar portapapeles</string>
<string name="quick_action__clipboard_cut__tooltip">Cortar al portapapeles</string>
<string name="quick_action__clipboard_paste" maxLength="12">Pegar</string>
<string name="quick_action__clipboard_paste__tooltip">Realizar pegar portapapeles</string>
<string name="quick_action__clipboard_select_all" maxLength="12">Seleccionar</string>
<string name="quick_action__clipboard_select_all__tooltip">Realizar seleccionar todo en portapapeles</string>
<string name="quick_action__clipboard_paste__tooltip">Pegar del portapapeles</string>
<string name="quick_action__clipboard_select_all" maxLength="12">Marcar todo</string>
<string name="quick_action__clipboard_select_all__tooltip">Seleccionar todo en el portapapeles</string>
<string name="quick_action__ime_ui_mode_clipboard" maxLength="12">Portapapeles</string>
<string name="quick_action__ime_ui_mode_clipboard__tooltip">Abrir historial del portapapeles</string>
<string name="quick_action__ime_ui_mode_media" maxLength="12">Emoji</string>
<string name="quick_action__ime_ui_mode_media__tooltip">Abre el panel de emojis</string>
<string name="quick_action__ime_ui_mode_media__tooltip">Abrir el panel de emojis</string>
<string name="quick_action__settings" maxLength="12">Ajustes</string>
<string name="quick_action__settings__tooltip">Abrir ajustes</string>
<string name="quick_action__undo" maxLength="12">Deshacer</string>
@@ -65,51 +79,51 @@
<string name="quick_action__redo" maxLength="12">Rehacer</string>
<string name="quick_action__redo__tooltip">Rehacer la última entrada</string>
<string name="quick_action__toggle_actions_overflow" maxLength="12">Más acciones</string>
<string name="quick_action__toggle_actions_overflow__tooltip">Mostrar u ocultar acciones adicionales</string>
<string name="quick_action__toggle_actions_overflow__tooltip">Mostrar u ocultar las operaciones adicionales</string>
<string name="quick_action__toggle_incognito_mode" maxLength="12">Incógnito</string>
<string name="quick_action__toggle_incognito_mode__tooltip">Activar modo incognito</string>
<string name="quick_action__toggle_incognito_mode__tooltip">Activar el modo incógnito</string>
<string name="quick_action__toggle_autocorrect" maxLength="12">Autocorregir</string>
<string name="quick_action__toggle_autocorrect__tooltip">Activar autocorregir</string>
<string name="quick_action__toggle_autocorrect__tooltip">Activar la autocorrección</string>
<string name="quick_action__voice_input" maxLength="12">Entrada voz</string>
<string name="quick_action__voice_input__tooltip" comment="IME stands for Input Method Editor and is indirectly equivalent to 'keyboard'.">Abrir proveedor de entrada de voz</string>
<string name="quick_action__one_handed_mode" maxLength="12">A una mano</string>
<string name="quick_action__one_handed_mode__tooltip">Cambia a modo a una mano</string>
<string name="quick_action__drag_marker" maxLength="12" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Marca arrstr</string>
<string name="quick_action__drag_marker__tooltip" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Posición actual marc. arrstr</string>
<string name="quick_action__one_handed_mode" maxLength="12">Con una mano</string>
<string name="quick_action__one_handed_mode__tooltip">Activar el modo de una mano</string>
<string name="quick_action__drag_marker" maxLength="12" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Arrastrar</string>
<string name="quick_action__drag_marker__tooltip" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Posición actual del cursor</string>
<string name="quick_action__noop" maxLength="12" comment="Noop=no operation; this action is only used as a placeholder in the actions editor drag and drop screen">Ninguno</string>
<string name="quick_action__noop__tooltip" comment="Noop=no operation; this action is only used as a placeholder in the actions editor drag and drop screen">Sin operación</string>
<string name="quick_actions_overflow__customize_actions_button">Reordenar acciones</string>
<string name="quick_actions_editor__header">Personalizar orden de acciones</string>
<string name="quick_action__noop__tooltip" comment="Noop=no operation; this action is only used as a placeholder in the actions editor drag and drop screen">Ninguna operación</string>
<string name="quick_actions_overflow__customize_actions_button">Reorganizar operaciones</string>
<string name="quick_actions_editor__header">Personalizar el orden de las operaciones</string>
<string name="quick_actions_editor__subheader_sticky_action">Acción fijada ({n})</string>
<string name="quick_actions_editor__subheader_dynamic_actions">Acciones dinámicas ({n})</string>
<string name="quick_actions_editor__subheader_hidden_actions">Acciones ocultas ({n})</string>
<!-- Incognito mode strings -->
<string name="incognito_mode__toast_after_enabled">El modo incógnito está activado\n\n{app_name} dejará de aprender las palabras de su entrada mientras este modo esté activado</string>
<string name="incognito_mode__toast_after_enabled">El modo incógnito está activo \n\n{app_name} no aprenderá palabras de tus entradas mientras este modo esté activo</string>
<string name="incognito_mode__toast_after_disabled">El modo incógnito está deshabilitado por defecto</string>
<!-- Settings UI strings -->
<string name="settings__title" comment="Title of Settings">Ajustes</string>
<string name="settings__preview_keyboard" comment="Hint for try your setup box">Pruebe su configuración</string>
<string name="settings__preview_keyboard" comment="Hint for try your setup box">Probar los ajustes</string>
<string name="settings__help" comment="General label for help buttons in Settings">Ayuda</string>
<string name="settings__default" comment="General string which is used when a preference has the default value set">Por defecto</string>
<string name="settings__system_default" comment="General string which is used when a preference has the system default value set">Predeterminado del sistema</string>
<string name="settings__home__title" comment="Title of the Home screen">Bienvenido a {app_name}</string>
<string name="settings__home__ime_not_enabled" comment="Error message shown in Home fragment when FlorisBoard is not enabled in the system">FlorisBoard no está habilitado en el sistema y por lo tanto no estará disponible como método de entrada en el selector de entrada. Haga clic aquí para resolver este problema.</string>
<string name="settings__home__ime_not_selected" comment="Warning message shown in Home fragment when FlorisBoard is not selected as the default keyboard">FlorisBoard no está seleccionado como método de entrada por defecto. Haga clic aquí para resolver este problema.</string>
<string name="settings__home__ime_not_selected" comment="Warning message shown in Home fragment when FlorisBoard is not selected as the default keyboard">FlorisBoard no está seleccionado como método de entrada predeterminado. Haga clic aquí para solucionar este problema.</string>
<string name="settings__localization__title" comment="Title of languages and Layout screen">Idiomas &amp; Distribuciones</string>
<string name="settings__localization__display_language_names_in__label" comment="Label of Display language names in preference">Muestra nombres de idiomas en</string>
<string name="settings__localization__group_subtypes__label" comment="Label of subtypes group">Subtipos</string>
<string name="settings__localization__subtype_add_title" comment="Title of subtype dialog when adding a new subtype">Añadir subtipo</string>
<string name="settings__localization__language_pack_title" comment="Title of the language pack manager screen for managing installed and custom language packs">Gestionar paquetes de idioma instalados</string>
<string name="settings__localization__language_pack_summary" comment="Summary of preference item for adding a new language pack">Experimental: gestionar extensiones que añaden soporte para idiomas específicos (entrada de como basado en forma por ahora)</string>
<string name="settings__localization__language_pack_title" comment="Title of the language pack manager screen for managing installed and custom language packs">Administrar paquetes de idioma instalados</string>
<string name="settings__localization__language_pack_summary" comment="Summary of preference item for adding a new language pack">Experimental: gestión de las extensiones que añaden compatibilidad con determinados idiomas (por ahora, entrada de caracteres chinos)</string>
<string name="settings__localization__subtype_edit_title" comment="Title of subtype dialog when editing an existing subtype">Editar subtipo</string>
<string name="settings__localization__subtype_locale" comment="Label for locale dropdown in subtype dialog">Idioma primario</string>
<string name="settings__localization__subtype_popup_mapping" comment="Label for popup mapping dropdown in subtype screen">Mapeo de emergentes</string>
<string name="settings__localization__subtype_locale" comment="Label for locale dropdown in subtype dialog">Idioma principal</string>
<string name="settings__localization__subtype_popup_mapping" comment="Label for popup mapping dropdown in subtype screen">Gestionar ventanas emergentes</string>
<string name="settings__localization__subtype_characters_layout" comment="Label for layout dropdown in subtype dialog">Disposición de caracteres</string>
<string name="settings__localization__subtype_suggestion_provider" comment="Label for suggestion provider dropdown in subtype dialog">Motor de sugerencias</string>
<string name="settings__localization__subtype_suggestion_provider" comment="Label for suggestion provider dropdown in subtype dialog">Sugerencias</string>
<string name="settings__localization__subtype_symbols_layout" comment="Label for layout dropdown in subtype dialog">Disposición de símbolos primarios</string>
<string name="settings__localization__subtype_symbols2_layout" comment="Label for layout dropdown in subtype dialog">Disposición de símbolos secundarios</string>
<string name="settings__localization__subtype_composer" comment="Label for composer dropdown in subtype dialog.">Compositor</string>
<string name="settings__localization__subtype_currency_set" comment="Label for currency set dropdown in subtype dialog. 'set' is used as a noun here and can be compared to a group of elements (in this case currency symbols).">Establecer moneda</string>
<string name="settings__localization__subtype_composer" comment="Label for composer dropdown in subtype dialog.">Editor</string>
<string name="settings__localization__subtype_currency_set" comment="Label for currency set dropdown in subtype dialog. 'set' is used as a noun here and can be compared to a group of elements (in this case currency symbols).">Tipo de moneda</string>
<string name="settings__localization__subtype_numeric_layout" comment="Label for layout dropdown in subtype dialog">Disposición numérica</string>
<string name="settings__localization__subtype_numeric_advanced_layout" comment="Label for layout dropdown in subtype dialog">Disposición numérica (avanzada)</string>
<string name="settings__localization__subtype_numeric_row_layout" comment="Label for layout dropdown in subtype dialog">Disposición de la fila de números</string>
@@ -137,6 +151,7 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Hora de puesta de sol</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Tema claro</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Tema oscuro</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme">Colores del énfasis (Temas Material You) </string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Gestionar temas instalados</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Recursos de aplicación de FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Almacenamiento interno</string>
@@ -418,7 +433,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Claro</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Oscuro</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Oscuro</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Usar material tú</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced">Ajustes de los colores de énfasis
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Idioma de ajustes</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Mostrar icono de la aplicación en el launcher</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Habilitado siempre en Android 10+ debido a restricciones del sistema</string>
@@ -549,6 +565,8 @@
<string name="pref__clipboard__enable_clipboard_history__summary">Conservar elementos del portapapeles para acceso rápido</string>
<string name="pref__clipboard__clean_up_old__label">Limpiar ítems antiguos</string>
<string name="pref__clipboard__clean_up_after__label">Limpiar ítems antiguos después de</string>
<string name="pref__clipboard__auto_clean_sensitive__label">Limpiar automáticamente elementos sensibles</string>
<string name="pref__clipboard__auto_clean_sensitive_after__label">Limpiar automáticamente elementos sensibles después de</string>
<string name="pref__clipboard__limit_history_size__label">Limite de tamaño del historial</string>
<string name="pref__clipboard__max_history_size__label">Tamaño máximo del historial</string>
<string name="pref__clipboard__clear_primary_clip_deletes_last_item__label">Borrar el clip principal afecta al historial</string>
@@ -567,6 +585,8 @@
<string name="devtools__show_input_state_overlay__summary" comment="Summary of Show input cache overlay in Devtools">Superpone el estado actual de la entrada para la depuración</string>
<string name="devtools__show_spelling_overlay__label" comment="Label of Show spelling overlay in Devtools">Mostrar superposición ortográfica</string>
<string name="devtools__show_spelling_overlay__summary" comment="Summary of Show spelling overlay in Devtools">Superpone los resultados ortográficos actuales para depuración</string>
<string name="devtools__show_inline_autofill_overlay__label">Superponer autocompletar en la línea</string>
<string name="devtools__show_inline_autofill_overlay__summary">Superpone los resultados actuales de autocompletar en línea para la depuración</string>
<string name="devtools__show_key_touch_boundaries__label" comment="Label of Show key touch boundaries in Devtools">Mostrar límites de toque de teclas</string>
<string name="devtools__show_key_touch_boundaries__summary" comment="Summary of Show key touch boundaries in Devtools">Resalte en rojo los límites de los toques clave</string>
<string name="devtools__show_drag_and_drop_helpers__label" comment="Label of Show drag and drop helpers in Devtools">Mostrar ayudas para arrastrar &amp; soltar</string>
@@ -588,9 +608,14 @@
<string name="devtools__debuglog__copy_for_github">Copiar registro (formato GitHub)</string>
<string name="devtools__debuglog__loading">Cargando…</string>
<!-- Extension strings -->
<string name="ext__home__title">Complementos y ampliaciones</string>
<string name="ext__list__ext_theme">Ampliaciones del tema</string>
<string name="ext__list__ext_keyboard">Ampliaciones de teclado</string>
<string name="ext__list__ext_languagepack">Ampliaciones del paquete de idiomas</string>
<string name="ext__meta__authors">Autores</string>
<string name="ext__meta__components">Componentes agrupados</string>
<string name="ext__meta__components_theme">Temas agrupados</string>
<string name="ext__meta__components_language_pack">Paquetes de idiomas incluidos</string>
<string name="ext__meta__components_none_found">Esta extensión de fichero no contiene ningún componente agrupado.</string>
<string name="ext__meta__description">Descripción</string>
<string name="ext__meta__homepage">Página de inicio</string>
@@ -639,6 +664,40 @@
<string name="ext__import__file_skip_ext_not_supported" comment="Reason string when file is loaded in incorrect context">Se esperaba un archivo de medios (imagen, audio, fuente, etc.) pero se encontró un fichero de extensión.</string>
<string name="ext__import__file_skip_media_not_supported" comment="Reason string when file is loaded in incorrect context">Se esperaba un fichero de extensión pero se encontró un archivo de medios (imagen, audio, fuente, etc.).</string>
<string name="ext__import__error_unexpected_exception" comment="Label when an error occurred during import. The error message will be appended below this text view">Ha ocurrido un error inesperado durante la importación. Se proporcionaron los siguientes detalles:</string>
<string name="ext__validation__enter_package_name">Por favor, introduzca el nombre del paquete</string>
<string name="ext__validation__error_package_name">El nombre del paquete no coincide con la expresión regular {id_regex}</string>
<string name="ext__validation__enter_version">Por favor, introduzca una versión</string>
<string name="ext__validation__enter_title">Por favor, introduzca un título</string>
<string name="ext__validation__enter_maintainer">Por favor, ingrese al menos un administrador válido</string>
<string name="ext__validation__enter_license">Por favor, introduzca un identificador de licencia</string>
<string name="ext__validation__enter_component_id">Por favor, introduzca un identificador de componente</string>
<string name="ext__validation__error_component_id">Por favor, introduzca un identificador de componente que coincida con {component_id_regex}</string>
<string name="ext__validation__enter_component_label">Por favor, introduzca una etiqueta de componente</string>
<string name="ext__validation__hint_component_label_to_long">La etiqueta de tu componente es muy larga, lo que podría ocasionar que se vea cortada en la interfaz</string>
<string name="ext__validation__error_author">Por favor, introduzca al menos un autor válido</string>
<string name="ext__validation__error_stylesheet_path_blank">La ruta de la hoja de estilo no puede estar vacía</string>
<string name="ext__validation__error_stylesheet_path">Por favor, introduzca un directorio válido a la hoja de estilos, que coincida con {stylesheet_path_regex}</string>
<string name="ext__validation__enter_property">Por favor, introduzca un nombre de variable</string>
<string name="ext__validation__error_property">Por favor, introduzca un nombre de variable que coincida con {variable_name_regex}</string>
<string name="ext__validation__hint_property" tools:ignore="TypographyDashes">Por convención, los nombres de variables en FlorisCSS inician con dos guiones (--)</string>
<string name="ext__validation__enter_color">Por favor, introduzca una cadena de color</string>
<string name="ext__validation__error_color">Por favor, introduzca una cadena de color válida</string>
<string name="ext__validation__enter_dp_size">Por favor, introduzca un tamaño dp</string>
<string name="ext__validation__enter_valid_number">Por favor, introduce un número válido</string>
<string name="ext__validation__enter_positive_number">Por favor, introduce un número positivo (&gt;=0)</string>
<string name="ext__validation__enter_percent_size">Por favor, introduce un porcentaje</string>
<string name="ext__validation__enter_number_between_0_100">Por favor, introduce un número entre 0 y 100</string>
<string name="ext__validation__hint_value_above_50_percent">Cualquier valor superior al 50% se comportará como si fuese el 50%, considere la posibilidad de disminuir el porcentaje</string>
<string name="ext__update_box__internet_permission_hint">Ya que esta aplicación no tiene permisos para acceder a Internet, las actualizaciones de las extensiones instaladas deben verificarse manualmente.</string>
<string name="ext__update_box__search_for_updates">Buscar actualizaciones</string>
<string name="ext__addon_management_box__managing_placeholder">Gestionando {extensions}</string>
<string name="ext__addon_management_box__addon_manager_info">Todas las tareas relacionadas con la importación, exportación, creación, personalización y eliminación de extensiones pueden ser manejadas a través del administrador de complementos centralizado.</string>
<string name="ext__addon_management_box__go_to_page">Ir a {ext_home_title}</string>
<string name="ext__home__info">Puede descargar e instalar extensiones de la tienda FlorisBoard Addons o importar cualquier archivo de extensión que haya descargado de internet.</string>
<string name="ext__home__visit_store">Visita la tienda de complementos</string>
<string name="ext__home__manage_extensions">Administrar las extensiones instaladas</string>
<string name="ext__list__view_details">Ver detalles</string>
<string name="ext__check_updates__title">Verificar actualizaciones</string>
<!-- Action strings -->
<string name="action__add">Añadir</string>
<string name="action__apply">Aplicar</string>
@@ -649,6 +708,8 @@
<string name="action__delete">Eliminar</string>
<string name="action__delete_confirm_title">Confirmar borrado</string>
<string name="action__delete_confirm_message">¿Está seguro de querer borrar \"{name}\"? Esta acción no se puede deshacer una vez realizada.</string>
<string name="action__reset_confirm_title">Confirme el reinicio</string>
<string name="action__reset_confirm_message">¿Estás seguro de que quieres restablecer \"{name}\"? Esta acción no se puede deshacer una vez ejecutada.</string>
<string name="action__discard">Descartar</string>
<string name="action__discard_confirm_title">Cambios sin guardar</string>
<string name="action__discard_confirm_message">¿Está seguro de que desea descartar los cambios no guardados? Esta acción no se puede deshacer una vez ejecutada.</string>
@@ -693,6 +754,7 @@
<string name="enum__candidates_display_mode__dynamic" comment="Enum value label">Ancho dinámico</string>
<string name="enum__candidates_display_mode__dynamic_scrollable" comment="Enum value label">Ancho dinámico &amp; desplazable</string>
<string name="enum__capitalization_behavior__capslock_by_double_tap" comment="Enum value label">Permitr Bloq May haciendo doble toque en mayúscula</string>
<string name="enum__capitalization_behavior__capslock_by_cycle" comment="Enum value label">Cambiar modo de capitalización cada vez que se pulsa la tecla Mayús</string>
<string name="enum__display_colors_as__hex8" comment="Enum value label">Hexadecimal</string>
<string name="enum__display_colors_as__rgba" comment="Enum value label">Rojo Verde Azul Alfa</string>
<string name="enum__display_kbd_after_dialogs__always" comment="Enum value label">Mostrar siempre</string>
@@ -705,6 +767,14 @@
<string name="enum__display_language_names_in__system_locale__description" comment="Enum value description">Los nombres de los idiomas en la aplicación y el teclado se muestran en la configuración regional establecida para todo el dispositivo</string>
<string name="enum__display_language_names_in__native_locale" comment="Enum value label">Región nativa</string>
<string name="enum__display_language_names_in__native_locale__description" comment="Enum value description">Los nombres de los idiomas en la aplicación y la interfaz de usuario del teclado se muestran en la configuración regional a la que se refieren</string>
<string name="enum__emoji_history_update_strategy__auto_sort_prepend" comment="Enum value label">Ordenar automáticamente (anteponer)</string>
<string name="enum__emoji_history_update_strategy__auto_sort_prepend__description" comment="Enum value description">Reordena automáticamente los emoticonos según su uso. Se añaden nuevos emoticonos al inicio.</string>
<string name="enum__emoji_history_update_strategy__auto_sort_append" comment="Enum value label">Ordenar automáticamente (anexar)</string>
<string name="enum__emoji_history_update_strategy__auto_sort_append__description" comment="Enum value description">Reordena automáticamente los emoticonos según su uso. Los nuevos emoticonos se añaden al final.</string>
<string name="enum__emoji_history_update_strategy__manual_sort_prepend" comment="Enum value label">Ordenar manualmente (anteponer)</string>
<string name="enum__emoji_history_update_strategy__manual_sort_prepend__description" comment="Enum value description">No reordenar automáticamente los emoticonos según se usan. Los nuevos emoticonos se añaden al principio.</string>
<string name="enum__emoji_history_update_strategy__manual_sort_append" comment="Enum value label">Ordenar manualmente (anexar)</string>
<string name="enum__emoji_history_update_strategy__manual_sort_append__description" comment="Enum value description">No reordenar automáticamente los emoticonos según se usan. Los nuevos emoticonos se añaden al final.</string>
<string name="enum__emoji_skin_tone__default" comment="Enum value label">{emoji} Tono de piel predeterminado</string>
<string name="enum__emoji_skin_tone__light_skin_tone" comment="Enum value label">{emoji} Piel clara</string>
<string name="enum__emoji_skin_tone__medium_light_skin_tone" comment="Enum value label">{emoji} Piel clara intermedia</string>
@@ -716,7 +786,16 @@
<string name="enum__emoji_hair_style__curly_hair" comment="Enum value label">{emoji} Cabello rizado</string>
<string name="enum__emoji_hair_style__white_hair" comment="Enum value label">{emoji} Cabello blanco</string>
<string name="enum__emoji_hair_style__bald" comment="Enum value label">{emoji} Calvo</string>
<string name="enum__emoji_suggestion_type__leading_colon">Los dos puntos</string>
<string name="enum__emoji_suggestion_type__leading_colon__description" comment="Keep the :emoji_name while translating, this is a syntax guide">Sugerir emoticonos utilizando :emoji_name</string>
<string name="enum__emoji_suggestion_type__inline_text">Texto en línea</string>
<string name="enum__emoji_suggestion_type__inline_text__description">Sugerir emoticonos simplemente escribiendo el nombre del emoticono</string>
<string name="enum__extended_actions_placement__above_candidates" comment="Enum value label">Sobre las sugerencias</string>
<string name="enum__extended_actions_placement__above_candidates__description" comment="Enum value description">Coloca la fila de acciones extendida entre la interfaz de usuario de la aplicación y la fila de las sugerencias</string>
<string name="enum__extended_actions_placement__below_candidates" comment="Enum value label">Debajo de las sugerencias</string>
<string name="enum__extended_actions_placement__below_candidates__description" comment="Enum value description">Coloca la fila de acciones extendidas entre la fila de las sugerencias y el teclado</string>
<string name="enum__extended_actions_placement__overlay_app_ui" comment="Enum value label">Superponer la interfaz de la aplicación</string>
<string name="enum__extended_actions_placement__overlay_app_ui__description" comment="Enum value description">Coloca la fila de acciones extendidas como una superposición sobre la interfaz de usuario de la aplicación, sin afectar la altura de la interfaz de usuario del teclado resultante. Tenga en cuenta que esta ubicación puede hacer que el campo de entrada de la aplicación se sobre dibuje parcialmente</string>
<string name="enum__haptic_vibration_mode__use_vibrator_directly" comment="Enum value label">Usar motor de vibración directamente</string>
<string name="enum__haptic_vibration_mode__use_vibrator_directly__description" comment="Enum value description">{app_name} interactúa directamente con el motor de vibración predeterminado. Esto ofrece mayor control sobre la duración y la intensidad de la vibración aunque puede que no sea tan fluida y optimizada como usar la interfaz de reacción háptica</string>
<string name="enum__haptic_vibration_mode__use_haptic_feedback_interface" comment="Enum value label">Usar interfaz de reacción háptica</string>
@@ -738,6 +817,7 @@
<string name="enum__input_feedback_activation_mode__audio_respect_system_settings" comment="Enum value label">Reproducción dinámica de sonidos para eventos de entrada, según la configuración del sistema</string>
<string name="enum__input_feedback_activation_mode__audio_ignore_system_settings" comment="Enum value label">Reproducir siempre los sonidos de los eventos de entrada, independientemente de la configuración del sistema</string>
<string name="enum__input_feedback_activation_mode__haptic_respect_system_settings" comment="Enum value label">Vibración dinámica para eventos de entrada, dependiendo de la configuración del sistema</string>
<string name="enum__input_feedback_activation_mode__haptic_ignore_system_settings" comment="Enum value label">Vibrar siempre, independientemente de la configuración del sistema</string>
<string name="enum__input_shift_state__unshifted" comment="Enum value label">Sin desplazar</string>
<string name="enum__input_shift_state__shifted_manual" comment="Enum value label">Cambio (manual)</string>
<string name="enum__input_shift_state__shifted_automatic" comment="Enum value label">Cambio (automático)</string>
@@ -749,6 +829,9 @@
<string name="enum__one_handed_mode__start" comment="Enum value label">Modo para zurdos</string>
<string name="enum__one_handed_mode__end" comment="Enum value label">Modo para diestros</string>
<string name="enum__shape_corner__top_start" comment="Enum value label">Inicio superior</string>
<string name="enum__shape_corner__top_end" comment="Enum value label">Parte superior</string>
<string name="enum__shape_corner__bottom_end" comment="Enum value label">Parte inferior</string>
<string name="enum__shape_corner__bottom_start" comment="Enum value label">Empezar por el final</string>
<string name="enum__smartbar_layout__suggestions_only" comment="Enum value label">Solo sugerencias</string>
<string name="enum__smartbar_layout__suggestions_only__description" comment="Enum value description">Muestra solo la barra de sugerencias, sin ningún botón/fila de acción ni acción fija</string>
<string name="enum__smartbar_layout__actions_only" comment="Enum value label">Solo acciones</string>
@@ -763,6 +846,9 @@
<string name="enum__snygg_level__advanced__description" comment="Enum value description">Se muestran todas las propiedades, se traducen las propiedades y las reglas.</string>
<string name="enum__snygg_level__developer" comment="Enum value label">Desarrollador</string>
<string name="enum__snygg_level__developer__description" comment="Enum value description">Se muestran todas las propiedades, las propiedades y las reglas se muestran tal y como están escritas en el propio archivo de la hoja de estilos.</string>
<string name="enum__space_bar_mode__nothing" comment="Enum value label">Sin etiqueta</string>
<string name="enum__space_bar_mode__current_language" comment="Enum value label">Idioma actual</string>
<string name="enum__space_bar_mode__space_bar_key" comment="Enum value label"></string>
<string name="enum__spelling_language_mode__use_system_languages" comment="Enum value label">Usar idiomas del sistema</string>
<string name="enum__spelling_language_mode__use_keyboard_subtypes" comment="Enum value label">Usar subtipos de teclado</string>
<string name="enum__swipe_action__no_action" comment="Enum value label">Sin acción</string>
@@ -819,4 +905,12 @@
<item quantity="one">{v} ítem</item>
<item quantity="other">{v} ítems</item>
</plurals>
<plurals name="unit__characters__written">
<item quantity="one">{v} carácter</item>
<item quantity="other">{v} caracteres</item>
</plurals>
<plurals name="unit__candidates__written">
<item quantity="one">{v} sugerencia</item>
<item quantity="other">{v} sugerencia</item>
</plurals>
</resources>

View File

@@ -21,8 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Stratégie de mise à jour (épinglé)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Stratégie de mise à jour (récent)</string>
<string name="prefs__media__emoji_history_max_size">Nombre d\'éléments maximum à garder</string>
<string name="prefs__media__emoji_history_pinned_reset">Réinit. les emojis épinglés</string>
<string name="prefs__media__emoji_history_reset">Reinit. les émojis récents</string>
<string name="prefs__media__emoji_history_pinned_reset">Réinitialiser les émojis épinglés</string>
<string name="prefs__media__emoji_history_reset">Réinitialiser les émojis récents</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Suggestions d\'émoji</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Activer les suggestions d\'émoji</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Fournit des suggestions d\'émoji lors de la saisie</string>
@@ -151,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Heure de coucher du soleil</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Thème clair</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Thème sombre</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Couleur accentuée (Thèmes Material you)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Gérer les thèmes installés</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Ressources de lapplication FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Stockage interne</string>
@@ -434,7 +436,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Clair</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Sombre</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED sombre</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Utiliser Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Paramètrage de couleur accentuée
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Paramètre de langue</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Afficher l\'icône de l\'application dans le lanceur</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Toujours activé sur Android 10+ en raison des restrictions du système</string>

View File

@@ -21,6 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Frissítési stratégia (kitűzött)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Frissítési stratégia (legutóbbi)</string>
<string name="prefs__media__emoji_history_max_size">Maximálisan megtartandó elem</string>
<string name="prefs__media__emoji_history_pinned_reset">Kitűzött emodzsik visszaállítása</string>
<string name="prefs__media__emoji_history_reset">Legutóbbi emodzsik visszaállítása</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Emodzsijavaslatok</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Emodzsijavaslatok engedélyezése</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Emodzsijavaslatokat biztosít gépelés közben</string>
@@ -149,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Napnyugta ideje</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Nappali téma</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Éjszakai téma</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Kiemelőszín (Material you témák)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Telepített témák kezelése</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">FlorisBoard alkalmazásadatok</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Belső tárhely</string>
@@ -430,7 +434,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Világos</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Sötét</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED sötét</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Material You használata</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Kiemelőszín-beállítások
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Beállítások nyelve</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Alkalmazás megjelenítése a kezdőképernyőn</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Mindig bekapcsolt Android 10+ esetében a rendszer korlátozások miatt</string>
@@ -706,6 +711,8 @@
<string name="action__delete">Törlés</string>
<string name="action__delete_confirm_title">Törlés megerősítése</string>
<string name="action__delete_confirm_message">Biztosan törölni szeretné ezt \"{name}\"? Ezt a műveletet nem lehet visszavonni.</string>
<string name="action__reset_confirm_title">Visszaállítás megerősítése</string>
<string name="action__reset_confirm_message">Biztosan vissza akarja állítani a következőt: „{name}”? Ez a művelet nem vonható vissza, ha egyszer már végrehajtotta.</string>
<string name="action__discard">Elvetés</string>
<string name="action__discard_confirm_title">Nem mentett változtatások</string>
<string name="action__discard_confirm_message">Biztosan el szeretné vetni a mentetlen változtatásokat? Ezt a műveletet nem lehet visszavonni.</string>

View File

@@ -431,7 +431,6 @@ Klik di sini untuk menyelesaikan masalah ini.</string>
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Cerah</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Gelap</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Gelap</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Gunakan Material You</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Bahasa pengaturan</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Tampilkan ikon aplikasi pada peluncur</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Selalu diaktifkan di Android 10+ karena pembatasan sistem</string>

View File

@@ -22,6 +22,17 @@
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Pianifica aggiornamento (recente)</string>
<string name="prefs__media__emoji_history_max_size">Numero massimo di elementi da tenere</string>
<string name="prefs__media__emoji_history_pinned_reset">Reset storico delle emoji appuntate</string>
<string name="prefs__media__emoji_history_reset">Resetta emoji recenti</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Suggerimenti emoji</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Abilita suggerimenti emoji</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Fornisci suggerimenti emoji mentre digiti</string>
<string name="prefs__media__emoji_suggestion_type" comment="Preference title">Tipo di attivazione</string>
<string name="prefs__media__emoji_suggestion_update_history" comment="Preference title">Aggiorna cronologia emoji</string>
<string name="prefs__media__emoji_suggestion_update_history__summary" comment="Preference summary">Accettando le emoji suggerite, queste vengono aggiunte alla cronologia emoji</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name" comment="Preference title">Mostra il nome dell\'emoji</string>
<string name="prefs__media__emoji_suggestion_candidate_show_name__summary" comment="Preference summary">I suggerimenti di emoji mostrano il loro nome accanto all\'emoji</string>
<string name="prefs__media__emoji_suggestion_query_min_length" comment="Preference title">Lunghezza minima della query</string>
<string name="prefs__media__emoji_suggestion_candidate_max_count" comment="Preference title">Numero massimo di candidati</string>
<!-- Emoji strings -->
<string name="emoji__category__smileys_emotion" comment="Emoji category name">Faccine &amp; Emoticons</string>
<string name="emoji__category__people_body" comment="Emoji category name">Persone &amp; Corpo</string>
@@ -77,6 +88,7 @@
<string name="quick_action__voice_input__tooltip" comment="IME stands for Input Method Editor and is indirectly equivalent to 'keyboard'.">Apri fornitore d\'immissione di voce</string>
<string name="quick_action__one_handed_mode" maxLength="12">A una mano</string>
<string name="quick_action__one_handed_mode__tooltip">Attiva o disattiva modalità a una mano</string>
<string name="quick_action__drag_marker" maxLength="12" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Trascina</string>
<string name="quick_action__drag_marker__tooltip" comment="This action is only used as a placeholder in the actions editor drag and drop screen and only visible in debug mode">Posizione dell\'attuale marcatore di trascinamento</string>
<string name="quick_action__noop" maxLength="12" comment="Noop=no operation; this action is only used as a placeholder in the actions editor drag and drop screen">Nessuna</string>
<string name="quick_action__noop__tooltip" comment="Noop=no operation; this action is only used as a placeholder in the actions editor drag and drop screen">Nessuna operazione</string>
@@ -130,6 +142,8 @@
<string name="settings__localization__subtype_error_fields_no_value" comment="Error message shown in subtype editor if at least one field is set to '- select -' (means no value specified)">Almeno un campo non ha un valore selezionato. Scegli un valore per il campo(i campi).</string>
<string name="settings__localization__subtype_error_layout_not_installed" comment="Error message shown in subtype list when a layout is not installed, where %s will be replaced by the layout ID">{layout_id} (non installato)</string>
<string name="settings__localization__group_layouts__label" comment="Label of layouts group">Layout</string>
<string name="settings__localization__subtype_delete_confirmation_title" comment="Title of the subtype delete confirmation dialog">Conferma eliminazione</string>
<string name="settings__localization__subtype_delete_confirmation_warning" comment="Warning message in the confirmation dialog to confirm the user's intent to delete">Sei sicuro di voler eliminare questo sottotipo?</string>
<string name="settings__theme__title" comment="Title of the Theme screen">Tema</string>
<string name="pref__theme__mode__label" comment="Label of the theme mode preference">Modalità tema</string>
<string name="pref__theme__sunrise_time__label" comment="Label of the sunrise time preference">Ora dell\'alba</string>
@@ -557,6 +571,7 @@
<string name="devtools__android_settings_secure__title" comment="Title of Android settings (secure) screen">Impostazioni di sicurezza Android</string>
<string name="devtools__android_settings_system__title" comment="Title of Android settings (system) screen">Impostazioni di sistema Android</string>
<string name="devtools__android_locales__title" comment="Title of Android locales screen">Lingue di sistema</string>
<string name="devtools__debuglog__loading">………Caricamento…</string>
<!-- Extension strings -->
<string name="ext__list__ext_theme">Temi</string>
<string name="ext__list__ext_keyboard">Skins tastiera</string>
@@ -620,6 +635,7 @@
<string name="ext__validation__enter_maintainer">Inserisci un indirzzo e-mail valido</string>
<string name="ext__validation__enter_license">Inserisci un ID per la licenza</string>
<string name="ext__validation__enter_component_id">Inserisci l\'ID corretto</string>
<string name="ext__validation__hint_value_above_50_percent">Qualsiasi valore superiore al 50% si comporterà come se impostassi il 50%, prendi in considerazione di ridurre la dimensione percentuale</string>
<string name="ext__addon_management_box__addon_manager_info">Tutte le attività relative all\'importazione, all\'esportazione, alla creazione, alla personalizzazione e alla rimozione delle estensioni possono essere gestite tramite il gestore interno</string>
<string name="ext__home__info">Puoi scaricare e installare estensioni dallo Store di FlorisBoard o importare qualsiasi addon</string>
<string name="ext__home__visit_store">Vai allo Store degli addons</string>

View File

@@ -145,6 +145,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">일몰 시간</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">라이트 테마</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">다크 테마</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> 강조 색상 (Material You 테마)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">설치한 테마 관리</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">앱 내장</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">내부 저장소</string>
@@ -313,7 +315,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">라이트 테마</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">다크 테마</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">블랙 테마</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Material You 사용</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> 설정 강조 색상
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">앱 설정 언어</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">런처에 앱 아이콘 표시</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Android 10 버전 이상에서는 구조적인 제한으로 인해 항상 켜져 있습니다.</string>

View File

@@ -21,6 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Atjaunināšanas stratēģija (Piesprausta)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Atjaunināšanas stratēģija (Nesena)</string>
<string name="prefs__media__emoji_history_max_size">Lielākais paturamo vienumu skaits</string>
<string name="prefs__media__emoji_history_pinned_reset">Atiestatīt piespraustās emocijzīmes</string>
<string name="prefs__media__emoji_history_reset">Atiestatīt nesenās emocijzīmes</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Emocijzīmju ieteikumi</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Iespējot emocijzīmju ieteikumus</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Rakstīšanas laikā sniegt emocijzīmju ieteikumus</string>
@@ -145,6 +147,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Saulrieta laikā</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Dienas izskats</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Nakts izskats</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Uzsvara krāsa (Material You izskati)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Pārvaldīt uzstādītos izskatus</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">FlorisBoard lietotnes līdzekļi</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Iekšējā krātuve</string>
@@ -426,7 +430,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Gaišs</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Tumšs</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED tumšs</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Izmantot Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Iestatījumu uzsvara krāsa
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Iestatījumu valoda</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Rādīt lietotnes ikonu palaidējā</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Vienmēr iespējots Android 10+ sistēmas ierobežojumu dēļ</string>
@@ -701,6 +706,8 @@
<string name="action__delete">Izdzēst</string>
<string name="action__delete_confirm_title">Apstiprināt izdzēšanu</string>
<string name="action__delete_confirm_message">Vai tiešām izdzēst \"{name}\"? Šī darbība pēc izpildīšanas vairs nevar tikt atsaukta.</string>
<string name="action__reset_confirm_title">Apstiprināt atiestati</string>
<string name="action__reset_confirm_message">Vai tiešām atiestatīt \"{name}\"? Šo darbību pēc izpildīšanas nevar atsaukt.</string>
<string name="action__discard">Atmest</string>
<string name="action__discard_confirm_title">Nesaglabātas izmaiņas</string>
<string name="action__discard_confirm_message">Vai tiešām atmest nesaglabātās izmaiņas? Šī darbība pēc izpildīšanas vairs nevar tikt atsaukta.</string>

View File

@@ -149,6 +149,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Zonsondergang</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Dagthema</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Nachtthema</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Accentkleur (Material you thema\'s)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Geïnstalleerde thema\'s beheren</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Florisboard Apponderdelen</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Intern geheugen</string>
@@ -430,7 +432,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Licht</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Donker</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Donker</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Material You gebruiken</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Instellingen accentkleur
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Instellingen taal</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">App-pictogram in launcher tonen</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Altijd ingeschakeld op Android 10 vanwege systeembeperkingen</string>

View File

@@ -151,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Czas zachodu słońca</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Tryb dzienny</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Tryb nocny</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme"> Kolor akcentujący (motywy Material you)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Zarządzaj zainstalowanymi motywami</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Wbudowane w aplikację FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Pamięć wewnętrzna</string>
@@ -432,7 +434,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Jasny</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Ciemny</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Ciemny</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Używaj Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Ustawienia koloru akcentującego
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Język ustawień</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Pokazuj aplikację w launcherze</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Zawsze włączone na Androidzie 10+ ze względu na ograniczenia systemu</string>

View File

@@ -432,7 +432,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Светлая</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Тёмная</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">Тёмная AMOLED</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Использовать Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Настройки цвета акцента
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Настройки языка</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Показывать значок приложения на рабочем столе</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Всегда включено на Android 10+ из-за системных ограничений</string>

View File

@@ -94,6 +94,7 @@
<string name="settings__preview_keyboard" comment="Hint for try your setup box">Vyskúšaj svoje nastavenie</string>
<string name="settings__help" comment="General label for help buttons in Settings">Pomoc</string>
<string name="settings__default" comment="General string which is used when a preference has the default value set">Predvolené</string>
<string name="settings__system_default" comment="General string which is used when a preference has the system default value set">Podľa systému</string>
<string name="settings__home__title" comment="Title of the Home screen">Víta ťa {app_name}</string>
<string name="settings__home__ime_not_enabled" comment="Error message shown in Home fragment when FlorisBoard is not enabled in the system">Klávesnica FlorisBoard nie je v systéme povolená, a preto sa pri výbere vstupu nebude dať nastaviť ako metóda zadávania. Kliknutím sem tento problém vyriešiš.</string>
<string name="settings__home__ime_not_selected" comment="Warning message shown in Home fragment when FlorisBoard is not selected as the default keyboard">Klávesnica FlorisBoard nie je nastavená ako predvolená metóda zadávania. Kliknutím sem tento problém vyriešiš.</string>
@@ -257,6 +258,13 @@
<string name="pref__gestures__swipe_left__label" comment="Preference title">Potiahnutie vľavo</string>
<string name="pref__gestures__swipe_right__label" comment="Preference title">Potiahnutie vpravo</string>
<string name="settings__advanced__title" comment="Title of Advanced settings">Pokročilé nastavenia</string>
<string name="pref__advanced__settings_theme__label" comment="Label of Settings theme preference in Advanced">Motív nastavení</string>
<string name="pref__advanced__settings_theme__auto_amoled" comment="Possible value of Settings theme preference in Advanced">Podľa systému (AMOLED)</string>
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Svetlý</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Tmavý</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Jazyk nastavení</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Zobraziť ikonu aplikácie v spúšťači aplikácií</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">V Androide 10 alebo novšom je toto nastavenie vždy zapnuté z dôvodu obmedzení systému</string>
<string name="pref__advanced__incognito_mode__label" comment="Label of Incognito mode preference in Advanced">Inkognito režim</string>
<!-- About UI strings -->
<string name="about__title" comment="Title of About activity">O aplikácii</string>
@@ -268,17 +276,17 @@
<string name="about__version__title" comment="Preference title">Verzia</string>
<string name="about__version_copied__title" comment="Title of the toast for copying the version string">Verzia bola skopírovaná do schránky</string>
<string name="about__version_copied__error" comment="Title of the error toast for copying the version string">Vyskytla sa chyba: {error_message}</string>
<string name="about__changelog__title" comment="Preference title">Denník zmien</string>
<string name="about__changelog__title" comment="Preference title">Prehľad zmien</string>
<string name="about__changelog__summary" comment="Preference summary">Čo je nové?</string>
<string name="about__repository__title" comment="Preference title">Repozitár (GitHub)</string>
<string name="about__repository__summary" comment="Preference summary">Zdrojový kód, diskusie, problémy a informácie</string>
<string name="about__privacy_policy__title" comment="Preference title">Zásady ochrany osobných údajov</string>
<string name="about__privacy_policy__summary" comment="Preference summary">Zásady ochrany osobných údajov tohto projektu</string>
<string name="about__project_license__title" comment="Preference title">Licencia na projekt</string>
<string name="about__privacy_policy__summary" comment="Preference summary">Zásady ochrany osobných údajov v rámci tohto projektu</string>
<string name="about__project_license__title" comment="Preference title">Licencia projektu</string>
<string name="about__project_license__summary" comment="Preference summary">FlorisBoard má udelenú licenciu {license_name}</string>
<string name="about__project_license__error_license_text_failed" comment="Error text for license text loading failure">Chyba: Nepodarilo sa načítať text licencie.\n-&gt; Dôvod: {error_message}.</string>
<string name="about__third_party_licenses__title" comment="Preference title">Licencie tretích strán</string>
<string name="about__third_party_licenses__summary" comment="Preference summary">Licencie knižníc tretích strán zahrnutých v tejto aplikácii</string>
<string name="about__third_party_licenses__summary" comment="Preference summary">Licencie knižníc tretích strán, ktoré sú zahrnuté v tejto aplikácii</string>
<!-- Setup UI strings -->
<string name="setup__title" comment="Title of Setup">Vitajte!</string>
<string name="setup__intro_message" comment="Short intro message welcoming new users">Ďakujeme, že ste sa rozhodli pre {app_name}! Toto rýchle nastavenie vás prevedie krokmi potrebnými na to, aby ste {app_name} mohli používať na svojom zariadení.</string>
@@ -290,10 +298,11 @@
<!-- Back up & Restore -->
<string name="backup_and_restore__title">Zálohovanie a obnovenie</string>
<string name="backup_and_restore__back_up__title">Zálohovať dáta</string>
<string name="backup_and_restore__back_up__destination">Vyberte miesto uloženia zálohy</string>
<string name="backup_and_restore__back_up__summary">Vygeneruje záložný archív s predvoľbami a prispôsobením</string>
<string name="backup_and_restore__back_up__destination">Vyber, kam sa má uložiť záloha</string>
<string name="backup_and_restore__back_up__destination_file_sys">Lokálny súborový systém</string>
<string name="backup_and_restore__back_up__destination_share_intent">Aplikácia tretej strany (cez ponuku zdieľania)</string>
<string name="backup_and_restore__back_up__files">Vyberte, čo sa má zálohovať</string>
<string name="backup_and_restore__back_up__files">Vyber, čo sa má zálohovať</string>
<string name="backup_and_restore__back_up__files_jetpref_datastore">Predvoľby</string>
<string name="backup_and_restore__back_up__files_ime_keyboard">Rozšírenia klávesnice</string>
<string name="backup_and_restore__back_up__files_ime_spelling">Pravopisné rozšírenia/slovníky</string>
@@ -305,7 +314,18 @@
<string name="backup_and_restore__back_up__success">Archív zálohy bol úspešne exportovaný!</string>
<string name="backup_and_restore__back_up__failure">Archív zálohy sa nepodarilo exportovať: {error_message}</string>
<string name="backup_and_restore__restore__title">Obnoviť dáta</string>
<string name="backup_and_restore__restore__files">Vyberte, čo sa má obnoviť</string>
<string name="backup_and_restore__restore__summary">Obnoví predvoľby a prispôsobenie zo záložného archívu</string>
<string name="backup_and_restore__restore__files">Vyber, čo sa má obnoviť</string>
<string name="backup_and_restore__restore__metadata">Vybratý záložný archív</string>
<string name="backup_and_restore__restore__metadata_warn_different_version">Tento záložný archív bol vygenerovaný v inej verzii aplikácie, než je tá aktuálna. Aj keď je spomínaná verzia vo všeobecnosti podporovaná, upozorňujeme, že z dôvodu rozdielov vo funkciách sa môžu vyskytnúť drobné problémy alebo sa niektoré predvoľby nemusia preniesť správne.</string>
<string name="backup_and_restore__restore__metadata_warn_different_vendor">Tento záložný archív bol vygenerovaný v aplikácii tretej strany, ktorá vo všeobecnosti nie je podporovaná. Hrozí, že dôjde k strate dát, preto jeho obnovenie dobre zváž!</string>
<string name="backup_and_restore__restore__metadata_error_invalid_metadata">Tento záložný archív obsahuje neplatné metadáta. Buď bol porušený, alebo nesprávne upravený. Obnovenie z tohto archívu nie je možné, preto vyber iný.</string>
<string name="backup_and_restore__restore__metadata_error_nothing_to_restore">Tento záložný archív neobsahuje žiadne súbory, ktoré by sa dali obnoviť. Vyber iný.</string>
<string name="backup_and_restore__restore__mode">Režim obnovenia</string>
<string name="backup_and_restore__restore__mode_merge">Zlúčiť s aktuálnymi dátami</string>
<string name="backup_and_restore__restore__mode_erase_and_overwrite">Vymazať a prepísať aktuálne dáta</string>
<string name="backup_and_restore__restore__success">Dáta boli úspešne obnovené</string>
<string name="backup_and_restore__restore__failure">Dáta sa nepodarilo obnoviť: {error_message}</string>
<!-- Crash Dialog strings -->
<string name="crash_dialog__close" comment="Label of Close button in crash dialog">Zavrieť</string>
<string name="crash_once_notification__title" comment="Title of the notification for a single crash">Aplikácia FlorisBoard prestala pracovať…</string>
@@ -325,25 +345,63 @@
<string name="pref__clipboard__clear_primary_clip_deletes_last_item__summary">Pri vymazaní prvého výstrižku sa odstráni aj najnovší záznam v histórii</string>
<!-- Devtools strings -->
<string name="devtools__title" comment="Title of Devtools screen. Translators: treat this string as 'Developer tools' for translation, except a similar short term is available for your language.">Vývojárske nástroje</string>
<string name="devtools__enabled__label" comment="Label of Enable developer tools in Devtools">Povoliť vývojárske nástroje</string>
<string name="devtools__enabled__summary" comment="Summary of Enable developer tools in Devtools">Nástroje navrhnuté špeciálne na ladenie a odstraňovanie problémov</string>
<string name="devtools__show_primary_clip__label" comment="Label of Show primary clip in Devtools">Zobraziť prvý výstrižok</string>
<string name="devtools__show_primary_clip__summary" comment="Summary of Show primary clip in Devtools">Dá do popredia aktuálny prvý výstrižok v schránke</string>
<string name="devtools__show_input_state_overlay__label" comment="Label of Show input cache overlay in Devtools">Zobrazovať vrstvu so stavom zadávania</string>
<string name="devtools__show_input_state_overlay__summary" comment="Summary of Show input cache overlay in Devtools">Na účely ladenia dá do popredia aktuálny stav zadávania</string>
<string name="devtools__show_spelling_overlay__label" comment="Label of Show spelling overlay in Devtools">Zobrazovať vrstvu s kontrolou pravopisu</string>
<string name="devtools__show_spelling_overlay__summary" comment="Summary of Show spelling overlay in Devtools">Na účely ladenia dá do popredia aktuálne výsledky kontroly pravopisu</string>
<string name="devtools__show_inline_autofill_overlay__label">Zobrazovať vrstvu s automatickým vypĺňaním v riadku</string>
<string name="devtools__show_inline_autofill_overlay__summary">Na účely ladenia dá do popredia aktuálne výsledky vypĺňania v riadku</string>
<string name="devtools__show_key_touch_boundaries__label" comment="Label of Show key touch boundaries in Devtools">Zobrazovať hranice stláčania klávesov</string>
<string name="devtools__show_key_touch_boundaries__summary" comment="Summary of Show key touch boundaries in Devtools">Červenou farbou zvýrazní hranice stláčania klávesov</string>
<string name="devtools__show_drag_and_drop_helpers__label" comment="Label of Show drag and drop helpers in Devtools">Zobrazovať tipy pri presúvaní ťahaním</string>
<string name="devtools__show_drag_and_drop_helpers__summary" comment="Summary of Show drag and drop helpers in Devtools">Na účely ladenia bude zobrazovať v obrazovkách presúvania ťahaním tipy, ktoré sú inak skryté</string>
<string name="devtools__clear_udm_internal_database__label" comment="Label of Clear internal user dictionary database in Devtools">Vymazať interné databázy slovníka používateľa</string>
<string name="devtools__clear_udm_internal_database__summary" comment="Summary of Clear internal user dictionary database in Devtools">Vymaže všetky slová v tabuľke databázy slovníka</string>
<string name="devtools__reset_flag__label" comment="Label of Reset flag preferences in Devtools">Resetovať označenie „{flag_name}“</string>
<string name="devtools__reset_flag_is_ime_set_up__summary" comment="Summary of Reset is IME set up flag in Devtools">Akcia ladenia na opätovné zobrazenie obrazovky nastavenia</string>
<string name="devtools__test_crash_report__label" comment="Label of Test Crash Report in Devtools">Otestovať obrazovku hlásenia o zlyhaní</string>
<string name="devtools__test_crash_report__summary" comment="Summary of Test Crash Report in Devtools">Akcia ladenia na zámerné spôsobenie zlyhania aplikácie</string>
<string name="devtools__group_android__title" comment="Title of Android group in Devtools">Systémové nástroje Androidu</string>
<string name="devtools__android_settings_global__title" comment="Title of Android settings (global) screen">Globálne nastavenia Androidu</string>
<string name="devtools__android_settings_secure__title" comment="Title of Android settings (secure) screen">Nastavenia zabezpečenia Androidu</string>
<string name="devtools__android_settings_system__title" comment="Title of Android settings (system) screen">Systémové nastavenia Androidu</string>
<string name="devtools__android_locales__title" comment="Title of Android locales screen">Jazykové verzie systému</string>
<string name="devtools__debuglog__title">Denník ladenia</string>
<string name="devtools__debuglog__copied_to_clipboard">Denník ladenia bol skopírovaný do schránky</string>
<string name="devtools__debuglog__copy_log">Kopírovať denník</string>
<string name="devtools__debuglog__copy_for_github">Kopírovať denník (formát na GitHub)</string>
<string name="devtools__debuglog__loading">Načítava sa…</string>
<!-- Extension strings -->
<string name="ext__home__title">Doplnky a rozšírenia</string>
<string name="ext__error__not_found_title">Rozšírenie sa nenašlo.</string>
<string name="ext__editor__metadata__title_invalid">Neplatné metadáta</string>
<!-- Action strings -->
<string name="action__back_up">Zálohovať</string>
<string name="action__cancel">Zrušiť</string>
<string name="action__default">Predvolené</string>
<string name="action__delete">Zmazať</string>
<string name="action__discard_confirm_title">Neuložené zmeny</string>
<string name="action__ok">OK</string>
<string name="action__restore">Obnoviť</string>
<string name="action__select_file">Vybrať súbor</string>
<!-- Error strings (generic) -->
<string name="error__title">Chyba</string>
<!-- General strings -->
<!-- Screen orientation strings -->
<!-- State strings -->
<string name="state__disabled">Bezbariérový</string>
<string name="state__no_file_selected">Nie je vybratý žiadny súbor</string>
<!-- Enum label and description strings -->
<string name="enum__incognito_mode__force_off" comment="Enum value label">Vynútené vypnutie</string>
<string name="enum__incognito_mode__force_off__description" comment="Enum value description">Inkognito režimu bude vždy vypnutý bez ohľadu na prevzaté možnosti cieľovej aplikácie. Ak je vybratá táto možnosť, rýchla akcia „Inkognito“ v lište nebude k dispozícii.</string>
<string name="enum__incognito_mode__force_on" comment="Enum value label">Vynútené zapnutie</string>
<string name="enum__incognito_mode__force_on__description" comment="Enum value description">Inkognito režimu bude vždy zapnutý bez ohľadu na prevzaté možnosti cieľovej aplikácie. Ak je vybratá táto možnosť, rýchla akcia „Inkognito“ v lište nebude k dispozícii.</string>
<string name="enum__incognito_mode__dynamic_on_off" comment="Enum value label">Dynamické zapínanie/vypínanie</string>
<string name="enum__incognito_mode__dynamic_on_off__description" comment="Enum value description">Odporúčaná možnosť. Inkognito režim sa bude dynamicky zapínať a vypínať buď podľa prevzatých možností cieľovej aplikácie, alebo manuálne pomocou prepínača rýchlej akcie „Inkognito“ na inteligentnej lište.</string>
<string name="enum__swipe_action__no_action" comment="Enum value label">Žiadna akcia</string>
<string name="enum__swipe_action__delete_character" comment="Enum value label">Zmazať znak pred kurzorom</string>
<string name="enum__swipe_action__delete_characters_precisely" comment="Enum value label">Zmazať znaky presne</string>

View File

@@ -394,7 +394,6 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Aydınlık</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Karanlık</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Siyah</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Material You kullan</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Dili ayarla</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Uygulama simgesini başlatıcıda göster</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Sistem kısıtlamaları dolayısıyla Android 10 ve üstünde her zaman etkin</string>

View File

@@ -21,6 +21,8 @@
<string name="prefs__media__emoji_history_pinned_update_strategy" comment="Preference title">Оновлення стратегії (Закріплено)</string>
<string name="prefs__media__emoji_history_recent_update_strategy" comment="Preference title">Оновлення стратегії (Нещодавно)</string>
<string name="prefs__media__emoji_history_max_size">Максимум речей, які можна зберігати</string>
<string name="prefs__media__emoji_history_pinned_reset">Скинути закріплені емоджі</string>
<string name="prefs__media__emoji_history_reset">Скинути поточні емоджі</string>
<string name="prefs__media__emoji_suggestion__title" comment="Preference group title">Пропозиції емоджі</string>
<string name="prefs__media__emoji_suggestion_enabled" comment="Preference title">Увімкнути пропозиції емоджі</string>
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Підказує емоджі під час введення тексту</string>
@@ -149,6 +151,8 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Час заходу</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Денна тема</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Нічна тема</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme">Акцентний колір (теми Material you)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Керування встановленими темами</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">Ресурси FlorisBoard</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Внутрішня пам\'ять</string>
@@ -430,7 +434,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Світла</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Темна</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">Темний AMOLED</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Використовувати Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced"> Налаштування акцентного кольору
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Налаштування мови</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Показувати значок програми на робочому столі</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Завжди ввімкнено на Android 10+ через обмеження системи</string>
@@ -704,6 +709,8 @@
<string name="action__delete">Видалити</string>
<string name="action__delete_confirm_title">Підтвердити видалення</string>
<string name="action__delete_confirm_message">Ви впевнені, що хочете видалити «{name}»? Ця дія не може бути скасована після виконання.</string>
<string name="action__reset_confirm_title">Підтвердити скидання</string>
<string name="action__reset_confirm_message">Ви впевнені, що хочете скинути «{name}»? Цю дію неможливо скасувати.</string>
<string name="action__discard">Скасувати</string>
<string name="action__discard_confirm_title">Незбережені зміни</string>
<string name="action__discard_confirm_message">Ви впевнені, що хочете скасувати незбережені зміни? Ця дія не може бути скасована після виконання.</string>

View File

@@ -406,7 +406,6 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">浅色</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">深色</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED 纯黑</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">使用 Material You</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">设置语言</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">在启动器中显示应用图标</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">由于系统限制,在安卓 10+ 上始终启用</string>

View File

@@ -101,6 +101,7 @@
<string name="quick_actions_editor__subheader_sticky_action">Sticky action ({n})</string>
<string name="quick_actions_editor__subheader_dynamic_actions">Dynamic actions ({n})</string>
<string name="quick_actions_editor__subheader_hidden_actions">Hidden actions ({n})</string>
<string name="select_subtype_panel__header">Select subtype</string>
<!-- Incognito mode strings -->
<string name="incognito_mode__toast_after_enabled">Incognito mode is now enabled\n\n{app_name} will not learn words from your input while this mode is active</string>
@@ -160,6 +161,9 @@
<string name="pref__theme__sunset_time__label" comment="Label of the sunset time preference">Sunset time</string>
<string name="pref__theme__day" comment="Label of the day group (day means light theme)">Day theme</string>
<string name="pref__theme__night" comment="Label of the night group (night means dark theme)">Night theme</string>
<string name="pref__theme__theme_accent_color__label" comment="Label of accent color preference in Theme">
Accent color (Material you themes)
</string>
<string name="settings__theme_manager__title_manage" comment="Title of the theme manager screen for managing installed and custom themes">Manage installed themes</string>
<string name="pref__theme__source_assets" comment="Label for the theme source field">FlorisBoard App Assets</string>
<string name="pref__theme__source_internal" comment="Label for the theme source field">Internal Storage</string>
@@ -453,7 +457,9 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Light</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Dark</string>
<string name="pref__advanced__settings_theme__amoled_dark" comment="Possible value of Settings theme preference in Advanced">AMOLED Dark</string>
<string name="pref__advanced__settings_material_you__label" comment="Label of Material You preference in Advanced">Use Material You</string>
<string name="pref__advanced__settings_accent_color__label" comment="Label of accent color preference in Advanced">
Settings accent color
</string>
<string name="pref__advanced__settings_language__label" comment="Label of Settings language preference in Advanced">Settings language</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Show app icon in launcher</string>
<string name="pref__advanced__show_app_icon__summary_atleast_q" comment="Summary of Show app icon preference in Advanced for Android 10+">Always enabled on Android 10+ due to restrictions of the system</string>

View File

@@ -24,7 +24,7 @@
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
</style>
<style name="CrashDialogTheme" parent="android:Theme.Material"/>
<style name="CrashDialogTheme" parent="android:style/Theme.Material.NoActionBar"/>
<style name="FlorisImeTheme" parent="android:Theme.Material.InputMethod">
<!-- Need this to prevent Xiaomi devices from messing with our beautiful UI -->

240
fastlane/generate-screenshots.sh Executable file
View File

@@ -0,0 +1,240 @@
#!/bin/zsh
cd staging/images
# Do some image magick to make the screenshots look pretty
mkdir out
FIRST_RATIO=0.25
SECOND_RATIO=0.6
SPLIT_IMAGE_1=settings-ui-keyboard-dark-red.png
SPLIT_IMAGE_2=settings-ui-keyboard-amoled-blue.png
SPLIT_IMAGE_3=settings-ui-keyboard-light-green.png
OUT_FILE=out/settings-ui-out.png
echo "Generating split image 1"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-dark.png
SPLIT_IMAGE_2=keyboard-amoled.png
SPLIT_IMAGE_3=keyboard-light.png
OUT_FILE=out/keyboard-out.png
echo "Generating split image 2"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-bl-dark.png
SPLIT_IMAGE_2=keyboard-bl-amoled.png
SPLIT_IMAGE_3=keyboard-bl-light.png
OUT_FILE=out/keyboard-bl-out.png
echo "Generating split image 3"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-emoji-dark.png
SPLIT_IMAGE_2=keyboard-emoji-amoled.png
SPLIT_IMAGE_3=keyboard-emoji-light.png
OUT_FILE=out/keyboard-emoji-out.png
echo "Generating split image 4"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-clipboard-blue.png
SPLIT_IMAGE_2=keyboard-clipboard-red.png
SPLIT_IMAGE_3=keyboard-clipboard-green.png
OUT_FILE=out/keyboard-clipboard-out.png
echo "Generating split image 5"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-smartbar-blue.png
SPLIT_IMAGE_2=keyboard-smartbar-red.png
SPLIT_IMAGE_3=keyboard-smartbar-green.png
OUT_FILE=out/keyboard-smartbar-out.png
echo "Generating split image 6"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
SPLIT_IMAGE_1=keyboard-fp-dark.png
SPLIT_IMAGE_2=keyboard-fp-amoled.png
SPLIT_IMAGE_3=keyboard-fp-light.png
OUT_FILE=out/keyboard-fp-out.png
echo "Generating split image 7"
magick $SPLIT_IMAGE_1 \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$FIRST_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-SECOND_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_2 +swap -compose over -composite \
\( +clone +level-colors white -fill black -draw "polygon %[fx:int(w*$SECOND_RATIO)],%[fx:h] %[fx:w],%[fx:h] %[fx:w],0 %[fx:int(w*$((1-FIRST_RATIO)))],0" \) \
-alpha off -compose copyopacity -composite $SPLIT_IMAGE_3 +swap -compose over -composite $OUT_FILE
echo "Done ..."
echo "Copying icons to out folder"
cp ../../metadata/androidbeta/en-US/images/icon.png out/icon-preview.png
cp ../../metadata/android/en-US/images/icon.png out/icon-stable.png
cd out
PREVIEW_PATH=../../../metadata/androidbeta/en-US/images
STABLE_PATH=../../../metadata/android/en-US/images
SCREENSHOT_PATH_PREVIEW=$PREVIEW_PATH/phoneScreenshots
SCREENSHOT_PATH_STABLE=$STABLE_PATH/phoneScreenshots
# Create showcase images with screenshots and text
SHADOW_OPACITY=50
SHADOW_RADIUS=50
BORDER_RADIUS=50
SCREENSHOT_SCALE=70 # in percent
SHOWCASE_TEXT_FONT="../../fonts/Roboto-Light.ttf"
SHOWCASE_TEXT=(
"settings-ui-out.png:Highly configurable\nkeyboard"
"keyboard-bl-out.png:Customize the look\nof your keyboard with themes"
"keyboard-out.png:Feature rich theme editor"
"keyboard-emoji-out.png:Emoji support"
"keyboard-clipboard-out.png:Configurable clipboard history"
"keyboard-smartbar-out.png:Customizable smartbar"
)
for t in $SHOWCASE_TEXT; do
echo "Generating $t"
magick -size 1080x1920 xc:white `# Create background`\
\( \
\( \
\( \
${t%:*} `# Src image`\
\( +clone +level-colors black -fill white -draw "roundrectangle 0,0,%[fx:w],%[fx:h],${BORDER_RADIUS},${BORDER_RADIUS}" \) `# Create an alpha mask for rounded corners`\
-alpha off -compose copy-opacity -composite `# Apply alpha mask`\
\) `# Create src image with rounded corners`\
\( +clone -background black -shadow ${SHADOW_OPACITY}x${SHADOW_RADIUS} \) `# Create drop shadow`\
+swap -background none -compose src-over -layers merge +repage `# Combine shadow with image`\
\) \
-resize 65% `# Scale down`\
\) \
-gravity South -geometry +0-20 -composite `# Place the screenshot with shadow over the background`\
\( -gravity Center -size $((1080*0.8))x$((1920*0.2)) -fill black -font ${SHOWCASE_TEXT_FONT} -pointsize 48 label:"${t#*:}" \) `# Create text`\
-gravity North -composite `# Place the screenshot with shadow over the background`\
${t%:*}
echo "Done ..."
done
ICON_SHOWCASE_TEXT=(
"icon-preview.png:FlorisBoard Preview\nGet all (stable, beta and rc) updates"
"icon-stable.png:FlorisBoard Stable\nGet all stable updates"
)
for t in $ICON_SHOWCASE_TEXT; do
echo "Generating $t"
magick -size 1080x1920 xc:white `# Create background`\
\( \
\( \
\( \
${t%:*} `# Src image`\
\( +clone +level-colors black -fill white -draw "roundrectangle 0,0,%[fx:w],%[fx:h],${BORDER_RADIUS},${BORDER_RADIUS}" \) `# Create an alpha mask for rounded corners`\
-alpha off -compose copy-opacity -composite `# Apply alpha mask`\
\) `# Create src image with rounded corners`\
\( +clone -background black -shadow ${SHADOW_OPACITY}x${SHADOW_RADIUS} \) `# Create drop shadow`\
+swap -background none -compose src-over -layers merge +repage `# Combine shadow with image`\
\) \
-resize 100% `# Scale down`\
\) \
-gravity Center -geometry +0-300 -composite `# Place the screenshot with shadow over the background`\
\( \
\( \
\( \
keyboard-fp-out.png `# Src image`\
\( +clone +level-colors black -fill white -draw "roundrectangle 0,0,%[fx:w],%[fx:h],${BORDER_RADIUS},${BORDER_RADIUS}" \) `# Create an alpha mask for rounded corners`\
-alpha off -compose copy-opacity -composite `# Apply alpha mask`\
\) `# Create src image with rounded corners`\
\( +clone -background black -shadow ${SHADOW_OPACITY}x${SHADOW_RADIUS} \) `# Create drop shadow`\
+swap -background none -compose src-over -layers merge +repage `# Combine shadow with image`\
\) \
-resize 90% `# Scale down`\
\) \
-gravity South -composite `# Place the screenshot with shadow over the background`\
\( -gravity Center -size $((1080*0.8))x$((1920*0.2)) -fill black -font ${SHOWCASE_TEXT_FONT} -pointsize 48 label:"${t#*:}" \) `# Create text`\
-gravity North -composite `# Place the screenshot with shadow over the background`\
${t%:*}
echo "Done ..."
done
echo "Moving icons to fastlane folder"
mv icon-preview.png $SCREENSHOT_PATH_PREVIEW/1.png
mv icon-stable.png $SCREENSHOT_PATH_STABLE/1.png
echo "Done ..."
magick -size 1024x500 xc:white `# Create background`\
\( \
\( \
\( \
keyboard-fp-out.png `# Src image`\
\( +clone +level-colors black -fill white -draw "roundrectangle 0,0,%[fx:w],%[fx:h],${BORDER_RADIUS},${BORDER_RADIUS}" \) `# Create an alpha mask for rounded corners`\
-alpha off -compose copy-opacity -composite `# Apply alpha mask`\
\) `# Create src image with rounded corners`\
\( +clone -background black -shadow ${SHADOW_OPACITY}x${SHADOW_RADIUS} \) `# Create drop shadow`\
+swap -background none -compose src-over -layers merge +repage `# Combine shadow with image`\
\) \
-resize 50% `# Scale down`\
\) \
-gravity Center -composite `# Place the screenshot with shadow over the background`\
keyboard-fp-out.png
echo "Done ..."
echo "Moving featureGraphics to fastlane folder"
cp keyboard-fp-out.png $PREVIEW_PATH/featureGraphic.png
cp keyboard-fp-out.png $STABLE_PATH/featureGraphic.png
echo "Done ..."
screenshots=(
"settings-ui-out.png"
"keyboard-bl-out.png"
"keyboard-out.png"
"keyboard-emoji-out.png"
"keyboard-clipboard-out.png"
"keyboard-smartbar-out.png"
)
INDEX=2
for i in $screenshots; do
echo "Copy $i.png to fastlane folder"
cp $i $SCREENSHOT_PATH_PREVIEW/$INDEX.png
cp $i $SCREENSHOT_PATH_STABLE/$INDEX.png
echo "Done ..."
let INDEX=${INDEX}+1
done
echo "Cleanup..."
cd ..
rm -r out
echo "Done"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 698 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 807 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 732 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 672 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 822 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 698 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 807 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 732 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 672 KiB

View File

@@ -0,0 +1,93 @@
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

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