Compare commits
5 Commits
feat/use-n
...
v0.4.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddc4f7f1ba | ||
|
|
afea8c721f | ||
|
|
9cffcea246 | ||
|
|
5acf80db0f | ||
|
|
80fb20885b |
34
ROADMAP.md
34
ROADMAP.md
@@ -2,7 +2,24 @@
|
||||
|
||||
This feature roadmap intents to provide transparency to what is planned to be added to FlorisBoard in the foreseeable future. Note that there are no ETAs for any version milestones down below, experience has shown these won't hold anyways.
|
||||
|
||||
Each major milestone has associated alpha/beta releases, so if you are interested in previewing features quicker, keep an eye out! Each major 0.x release has also patch releases after the initial major release, which will be published on both the stable and preview tracks.
|
||||
Each major milestone has associated alpha/beta releases, so if you are interested in previewing features quicker, keep an eye out! Each major 0.x release has also patch releases after the initial major release, which will be published on both the stable and beta tracks.
|
||||
|
||||
## 0.4
|
||||
|
||||
**Main focus**: Getting the project back on track, see [this announcement](https://github.com/florisboard/florisboard/discussions/2314) for details. Note that this has also replaced the previous roadmap, however this step is necessary for getting the project back on track again.
|
||||
|
||||
This includes, but is not exclusive to:
|
||||
- Fixing the most reported bugs/issues
|
||||
- Merging in the Material You theme PR -> Adds Material You support (v0.4.0-alpha05)
|
||||
- Merging in other external PRs as best as possible
|
||||
- Reworking the Settings UI warning boxes and hiding any UI for features related to word suggestions until they are ready
|
||||
- Remove existing glide/swipe typing (see 0.5 milestone)
|
||||
- Improvements in clipboard / emoji functionality (v0.4.0-beta01/beta02)
|
||||
- Prepare project to have native code implemented in [Rust](https://www.rust-lang.org/) (v0.4.0-beta02)
|
||||
- - Upgrade Settings UI to Material 3 (v0.4.0-beta03)
|
||||
- Add support for importing extensions via system file handler APIs (relevant for Addons store) (v0.4.0-beta03)
|
||||
|
||||
Note that the previous versioning scheme has been dropped in favor of using a major.minor.patch versioning scheme, so versions like `0.3.16` are a thing of the past :)
|
||||
|
||||
## 0.5
|
||||
|
||||
@@ -11,25 +28,25 @@ Each major milestone has associated alpha/beta releases, so if you are intereste
|
||||
- Add new extension type: Language Pack
|
||||
- Basically groups all locale-relevant data (predictive base model, emoji suggestion data, ...)
|
||||
in a dynamically importable extension file
|
||||
- New text processing logic (maybe moved back / split to 0.6)
|
||||
- Add floating keyboard mode
|
||||
- New keyboard layout engine + file syntax based on the upcoming Unicode Keyboard v3 standard
|
||||
- RFC document with technical details will be released later
|
||||
- New text processing logic (maybe moved back to 0.6)
|
||||
- RFC document with technical details will be released later
|
||||
- Add Tablet mode / Optimizations for landscape input based on new keyboard layout engine
|
||||
- Reimplementation of glide typing with the new layout engine and predictive text core
|
||||
- Add support for any remaining new features introduced with Android 13
|
||||
|
||||
## 0.6
|
||||
|
||||
- Complete rework of the Emoji panel
|
||||
- Recently used / Emoji history (already implemented with 0.3.14)
|
||||
- Emoji search
|
||||
- Fully scrollable emoji list (soft category borders)
|
||||
- More granular themeing options
|
||||
- Layout customization (e.g. placement of category buttons)
|
||||
- Emoji suggestions when using :emoji_name: syntax (already implemented with v0.4.0-beta02)
|
||||
- Maybe: consider upgrading to emoji2 for better unified system-wide emoji styles
|
||||
- Reimplementation of glide typing with the new layout engine and predictive text core
|
||||
- Prepare FlorisBoard repository and app store presence for public beta release on Google Play (will go live with stable 0.6)
|
||||
- Rework branding images and texts of FlorisBoard for the app stores
|
||||
- Focus on stability and experience improvements of the app and keyboard
|
||||
- Add support for new features introduced with Android 14 / 15
|
||||
- Add support for new features introduced with Android 14
|
||||
- Not finalized, but planned: raise minimum required Android version from Android 7 (SDK level 24) to Android 8 (SDK level 26)
|
||||
|
||||
## Backlog / Planned (unassigned)
|
||||
@@ -41,6 +58,7 @@ Each major milestone has associated alpha/beta releases, so if you are intereste
|
||||
- Adaptive themes v2
|
||||
- Voice-to-text with Mozilla's open-source voice service (or any other oss voice provider)
|
||||
- Text translation
|
||||
- Floating keyboard
|
||||
- Stickers/GIFs
|
||||
- Kaomoji panel implementation
|
||||
- FlorisBoard landing web page for presentation
|
||||
|
||||
@@ -55,10 +55,6 @@ android {
|
||||
)
|
||||
}
|
||||
|
||||
androidResources {
|
||||
generateLocaleConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.patrickgold.florisboard"
|
||||
minSdk = projectMinSdk.toInt()
|
||||
@@ -193,7 +189,6 @@ dependencies {
|
||||
implementation(libs.androidx.material.icons)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.androidx.profileinstaller)
|
||||
implementation(libs.androidx.appcompat)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.cache4k)
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 3,
|
||||
"identityHash": "145ca5bf4bff8e98f71ebc70ab3b495b",
|
||||
"identityHash": "282a1b421e498fd0e21c055b6a4315e0",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "clipboard_history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `text` TEXT, `uri` TEXT, `creationTimestampMs` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `mimeTypes` TEXT NOT NULL, `isSensitive` INTEGER NOT NULL DEFAULT 0, `isRemoteDevice` INTEGER NOT NULL DEFAULT 0)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `text` TEXT, `uri` TEXT, `creationTimestampMs` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `mimeTypes` TEXT NOT NULL, `isSensitive` INTEGER NOT NULL, `isRemoteDevice` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
@@ -54,15 +54,13 @@
|
||||
"fieldPath": "isSensitive",
|
||||
"columnName": "isSensitive",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isRemoteDevice",
|
||||
"columnName": "isRemoteDevice",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
@@ -88,7 +86,7 @@
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '145ca5bf4bff8e98f71ebc70ab3b495b')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '282a1b421e498fd0e21c055b6a4315e0')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 4,
|
||||
"identityHash": "1dd181d116dcb4530fb5b33451ea9ab5",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "clipboard_history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `text` TEXT, `uri` TEXT, `creationTimestampMs` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `mimeTypes` TEXT NOT NULL, `is_sensitive` INTEGER NOT NULL DEFAULT 0, `is_remote_device` INTEGER NOT NULL DEFAULT 0)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "text",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uri",
|
||||
"columnName": "uri",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "creationTimestampMs",
|
||||
"columnName": "creationTimestampMs",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isPinned",
|
||||
"columnName": "isPinned",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mimeTypes",
|
||||
"columnName": "mimeTypes",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isSensitive",
|
||||
"columnName": "is_sensitive",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "isRemoteDevice",
|
||||
"columnName": "is_remote_device",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_clipboard_history__id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_clipboard_history__id` ON `${TABLE_NAME}` (`_id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1dd181d116dcb4530fb5b33451ea9ab5')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -76,16 +76,6 @@
|
||||
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker"/>
|
||||
</service>
|
||||
|
||||
<!-- Service for Locale handling -->
|
||||
<service
|
||||
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
|
||||
android:enabled="false"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="autoStoreLocales"
|
||||
android:value="true" />
|
||||
</service>
|
||||
|
||||
<!-- Main App Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.app.FlorisAppActivity"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
{ "code": 11816, "label": "⸨" },
|
||||
{ "code": 10214, "label": "⟦" },
|
||||
{ "code": 10216, "label": "⟨" },
|
||||
{ "code": 10218, "label": "⟪" },
|
||||
{ "code": 10218, "label": "⟩" },
|
||||
{ "code": 123, "label": "{" }
|
||||
]
|
||||
} },
|
||||
@@ -72,7 +72,7 @@
|
||||
"relevant": [
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 11817, "label": "⸩" },
|
||||
{ "code": 10215, "label": "⟧" },
|
||||
{ "code": 10215, "label": "⟦" },
|
||||
{ "code": 10217, "label": "⟩" },
|
||||
{ "code": 10219, "label": "⟫" },
|
||||
{ "code": 125, "label": "}" }
|
||||
|
||||
@@ -47,8 +47,10 @@ 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 org.florisboard.lib.android.isOrientationPortrait
|
||||
import dev.patrickgold.florisboard.lib.ext.ExtensionComponentName
|
||||
import dev.patrickgold.florisboard.lib.observeAsTransformingState
|
||||
import org.florisboard.lib.snygg.SnyggLevel
|
||||
import dev.patrickgold.florisboard.lib.util.VersionName
|
||||
import dev.patrickgold.jetpref.datastore.JetPref
|
||||
import dev.patrickgold.jetpref.datastore.model.PreferenceMigrationEntry
|
||||
@@ -57,8 +59,6 @@ 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.isOrientationPortrait
|
||||
import org.florisboard.lib.snygg.SnyggLevel
|
||||
|
||||
fun florisPreferenceModel() = JetPref.getOrCreatePreferenceModel(AppPrefs::class, ::AppPrefs)
|
||||
|
||||
@@ -118,14 +118,6 @@ class AppPrefs : PreferenceModel("florisboard-app-prefs") {
|
||||
key = "clipboard__clean_up_after",
|
||||
default = 20,
|
||||
)
|
||||
val autoCleanSensitive = boolean(
|
||||
key = "clipboard__auto_clean_sensitive",
|
||||
default = false,
|
||||
)
|
||||
val autoCleanSensitiveAfter = int(
|
||||
key = "clipboard__auto_clean_sensitive_after",
|
||||
default = 20,
|
||||
)
|
||||
val limitHistorySize = boolean(
|
||||
key = "clipboard__limit_history_size",
|
||||
default = true,
|
||||
|
||||
@@ -20,9 +20,8 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.displayCutoutPadding
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
@@ -32,13 +31,13 @@ import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.navigation.NavController
|
||||
@@ -74,7 +73,7 @@ val LocalNavController = staticCompositionLocalOf<NavController> {
|
||||
error("LocalNavController not initialized")
|
||||
}
|
||||
|
||||
class FlorisAppActivity : AppCompatActivity() {
|
||||
class FlorisAppActivity : ComponentActivity() {
|
||||
private val prefs by florisPreferenceModel()
|
||||
private val cacheManager by cacheManager()
|
||||
private var appTheme by mutableStateOf(AppTheme.AUTO)
|
||||
@@ -94,12 +93,10 @@ class FlorisAppActivity : AppCompatActivity() {
|
||||
appTheme = it
|
||||
}
|
||||
prefs.advanced.settingsLanguage.observe(this) {
|
||||
val appLocale: LocaleListCompat = if (it == "auto") {
|
||||
LocaleListCompat.getEmptyLocaleList()
|
||||
} else {
|
||||
LocaleListCompat.forLanguageTags(FlorisLocale.fromTag(it).languageTag())
|
||||
}
|
||||
AppCompatDelegate.setApplicationLocales(appLocale)
|
||||
val config = Configuration(resources.configuration)
|
||||
val locale = if (it == "auto") FlorisLocale.default() else FlorisLocale.fromTag(it)
|
||||
config.setLocale(locale.base)
|
||||
resourcesContext = createConfigurationContext(config)
|
||||
}
|
||||
if (AndroidVersion.ATMOST_API28_P) {
|
||||
prefs.advanced.showAppIcon.observe(this) {
|
||||
@@ -218,5 +215,9 @@ class FlorisAppActivity : AppCompatActivity() {
|
||||
}
|
||||
intentToBeHandled = null
|
||||
}
|
||||
|
||||
SideEffect {
|
||||
navController.setOnBackPressedDispatcher(this.onBackPressedDispatcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,10 @@
|
||||
package dev.patrickgold.florisboard.app.ext
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
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.Add
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
@@ -38,13 +33,8 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import dev.patrickgold.florisboard.R
|
||||
@@ -56,7 +46,6 @@ import dev.patrickgold.florisboard.lib.compose.FlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
|
||||
import dev.patrickgold.florisboard.lib.compose.FlorisTextButton
|
||||
import dev.patrickgold.florisboard.lib.compose.defaultFlorisOutlinedBox
|
||||
import dev.patrickgold.florisboard.lib.compose.florisScrollbar
|
||||
import dev.patrickgold.florisboard.lib.compose.stringRes
|
||||
import dev.patrickgold.florisboard.lib.ext.ExtensionManager
|
||||
import dev.patrickgold.florisboard.lib.observeAsNonNullState
|
||||
@@ -91,66 +80,49 @@ enum class ExtensionListScreenType(
|
||||
fun ExtensionListScreen(type: ExtensionListScreenType, showUpdate: Boolean) = FlorisScreen {
|
||||
title = stringRes(type.titleResId)
|
||||
previewFieldVisible = false
|
||||
scrollable = false
|
||||
|
||||
val context = LocalContext.current
|
||||
val navController = LocalNavController.current
|
||||
val extensionManager by context.extensionManager()
|
||||
val extensionIndex by type.getExtensionIndex(extensionManager).observeAsNonNullState()
|
||||
|
||||
var fabHeight by remember {
|
||||
mutableStateOf(0)
|
||||
}
|
||||
val fabHeightDp = with(LocalDensity.current) { fabHeight.toDp()+16.dp }
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
content {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.florisScrollbar(state = listState, isVertical = true),
|
||||
state = listState,
|
||||
contentPadding = PaddingValues(bottom = fabHeightDp),
|
||||
) {
|
||||
if (showUpdate) {
|
||||
item {
|
||||
UpdateBox(extensionIndex = extensionIndex)
|
||||
}
|
||||
}
|
||||
items(extensionIndex) { ext ->
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
title = ext.meta.title,
|
||||
subtitle = ext.meta.id,
|
||||
if (showUpdate) {
|
||||
UpdateBox(extensionIndex = extensionIndex)
|
||||
}
|
||||
for (ext in extensionIndex) {
|
||||
FlorisOutlinedBox(
|
||||
modifier = Modifier.defaultFlorisOutlinedBox(),
|
||||
title = ext.meta.title,
|
||||
subtitle = ext.meta.id,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
text = ext.meta.description ?: "",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
text = ext.meta.description ?: "",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.View(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Outlined.Info,
|
||||
text = stringRes(id = R.string.ext__list__view_details),//stringRes(R.string.action__add),
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Edit(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Default.Edit,
|
||||
text = stringRes(R.string.action__edit),
|
||||
enabled = extensionManager.canDelete(ext),
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 6.dp),
|
||||
) {
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.View(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Outlined.Info,
|
||||
text = stringRes(id = R.string.ext__list__view_details),//stringRes(R.string.action__add),
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
FlorisTextButton(
|
||||
onClick = {
|
||||
navController.navigate(Routes.Ext.Edit(ext.meta.id))
|
||||
},
|
||||
icon = Icons.Default.Edit,
|
||||
text = stringRes(R.string.action__edit),
|
||||
enabled = extensionManager.canDelete(ext),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,9 +142,6 @@ fun ExtensionListScreen(type: ExtensionListScreenType, showUpdate: Boolean) = Fl
|
||||
text = stringRes(id = R.string.ext__editor__title_create_any),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.onGloballyPositioned {
|
||||
fabHeight = it.size.height
|
||||
},
|
||||
shape = FloatingActionButtonDefaults.extendedFabShape,
|
||||
onClick = { type.launchExtensionCreate.invoke(navController) },
|
||||
)
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
|
||||
package dev.patrickgold.florisboard.app.settings.advanced
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Adb
|
||||
import androidx.compose.material.icons.filled.Archive
|
||||
@@ -31,7 +26,6 @@ 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.platform.LocalContext
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.app.AppTheme
|
||||
import dev.patrickgold.florisboard.app.LocalNavController
|
||||
@@ -40,6 +34,7 @@ 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
|
||||
@@ -49,7 +44,6 @@ import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
|
||||
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
|
||||
import dev.patrickgold.jetpref.datastore.ui.listPrefEntries
|
||||
import dev.patrickgold.jetpref.datastore.ui.vectorResource
|
||||
import org.florisboard.lib.android.AndroidVersion
|
||||
|
||||
@Composable
|
||||
fun AdvancedScreen() = FlorisScreen {
|
||||
@@ -57,10 +51,6 @@ fun AdvancedScreen() = FlorisScreen {
|
||||
previewFieldVisible = false
|
||||
|
||||
val navController = LocalNavController.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val languageSettingsLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
|
||||
|
||||
content {
|
||||
ListPreference(
|
||||
@@ -77,86 +67,70 @@ fun AdvancedScreen() = FlorisScreen {
|
||||
AndroidVersion.ATLEAST_API31_S
|
||||
},
|
||||
)
|
||||
if (AndroidVersion.ATLEAST_API33_T) {
|
||||
Preference(
|
||||
title = stringRes(R.string.pref__advanced__settings_language__label),
|
||||
icon = Icons.Default.Language,
|
||||
onClick = {
|
||||
languageSettingsLauncher.launch(
|
||||
Intent(
|
||||
Settings.ACTION_APP_LOCALE_SETTINGS,
|
||||
Uri.parse("package:${context.packageName}")
|
||||
ListPreference(
|
||||
prefs.advanced.settingsLanguage,
|
||||
icon = Icons.Default.Language,
|
||||
title = stringRes(R.string.pref__advanced__settings_language__label),
|
||||
entries = listPrefEntries {
|
||||
listOf(
|
||||
"auto",
|
||||
"ar",
|
||||
"bg",
|
||||
"bs",
|
||||
"ca",
|
||||
"ckb",
|
||||
"cs",
|
||||
"da",
|
||||
"de",
|
||||
"el",
|
||||
"en",
|
||||
"eo",
|
||||
"es",
|
||||
"fa",
|
||||
"fi",
|
||||
"fr",
|
||||
"hr",
|
||||
"hu",
|
||||
"in",
|
||||
"it",
|
||||
"iw",
|
||||
"ja",
|
||||
"ko-KR",
|
||||
"ku",
|
||||
"lv-LV",
|
||||
"mk",
|
||||
"nds-DE",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sr",
|
||||
"sv",
|
||||
"tr",
|
||||
"uk",
|
||||
"zgh",
|
||||
"zh-CN",
|
||||
).map { languageTag ->
|
||||
if (languageTag == "auto") {
|
||||
entry(
|
||||
key = "auto",
|
||||
label = stringRes(R.string.settings__system_default),
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
prefs.advanced.settingsLanguage,
|
||||
icon = Icons.Default.Language,
|
||||
title = stringRes(R.string.pref__advanced__settings_language__label),
|
||||
entries = listPrefEntries {
|
||||
listOf(
|
||||
"auto",
|
||||
"ar",
|
||||
"bg",
|
||||
"bs",
|
||||
"ca",
|
||||
"ckb",
|
||||
"cs",
|
||||
"da",
|
||||
"de",
|
||||
"el",
|
||||
"en",
|
||||
"eo",
|
||||
"es",
|
||||
"fa",
|
||||
"fi",
|
||||
"fr",
|
||||
"hr",
|
||||
"hu",
|
||||
"in",
|
||||
"it",
|
||||
"iw",
|
||||
"ja",
|
||||
"ko-KR",
|
||||
"ku",
|
||||
"lv-LV",
|
||||
"mk",
|
||||
"nds-DE",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sr",
|
||||
"sv",
|
||||
"tr",
|
||||
"uk",
|
||||
"zgh",
|
||||
"zh-CN",
|
||||
).map { languageTag ->
|
||||
if (languageTag == "auto") {
|
||||
entry(
|
||||
key = "auto",
|
||||
label = stringRes(R.string.settings__system_default),
|
||||
)
|
||||
} else {
|
||||
val displayLanguageNamesIn by prefs.localization.displayLanguageNamesIn.observeAsState()
|
||||
val locale = FlorisLocale.fromTag(languageTag)
|
||||
entry(locale.languageTag(), when (displayLanguageNamesIn) {
|
||||
DisplayLanguageNamesIn.SYSTEM_LOCALE -> locale.displayName()
|
||||
DisplayLanguageNamesIn.NATIVE_LOCALE -> locale.displayName(locale)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
val displayLanguageNamesIn by prefs.localization.displayLanguageNamesIn.observeAsState()
|
||||
val locale = FlorisLocale.fromTag(languageTag)
|
||||
entry(locale.languageTag(), when (displayLanguageNamesIn) {
|
||||
DisplayLanguageNamesIn.SYSTEM_LOCALE -> locale.displayName()
|
||||
DisplayLanguageNamesIn.NATIVE_LOCALE -> locale.displayName(locale)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
SwitchPreference(
|
||||
prefs.advanced.showAppIcon,
|
||||
icon = Icons.Default.Preview,
|
||||
|
||||
@@ -25,7 +25,6 @@ import dev.patrickgold.jetpref.datastore.ui.DialogSliderPreference
|
||||
import dev.patrickgold.jetpref.datastore.ui.ExperimentalJetPrefDatastoreUi
|
||||
import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
|
||||
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
|
||||
import org.florisboard.lib.android.AndroidVersion
|
||||
|
||||
@OptIn(ExperimentalJetPrefDatastoreUi::class)
|
||||
@Composable
|
||||
@@ -72,22 +71,6 @@ fun ClipboardScreen() = FlorisScreen {
|
||||
stepIncrement = 5,
|
||||
enabledIf = { prefs.clipboard.historyEnabled isEqualTo true && prefs.clipboard.cleanUpOld isEqualTo true },
|
||||
)
|
||||
SwitchPreference(
|
||||
prefs.clipboard.autoCleanSensitive,
|
||||
title = stringRes(R.string.pref__clipboard__auto_clean_sensitive__label),
|
||||
enabledIf = { prefs.clipboard.historyEnabled isEqualTo true },
|
||||
visibleIf = { AndroidVersion.ATLEAST_API33_T },
|
||||
)
|
||||
DialogSliderPreference(
|
||||
prefs.clipboard.autoCleanSensitiveAfter,
|
||||
title = stringRes(R.string.pref__clipboard__auto_clean_sensitive_after__label),
|
||||
valueLabel = { pluralsRes(R.plurals.unit__seconds__written, it, "v" to it) },
|
||||
min = 0,
|
||||
max = 300,
|
||||
stepIncrement = 10,
|
||||
enabledIf = { prefs.clipboard.historyEnabled isEqualTo true && prefs.clipboard.autoCleanSensitive isEqualTo true },
|
||||
visibleIf = { AndroidVersion.ATLEAST_API33_T },
|
||||
)
|
||||
SwitchPreference(
|
||||
prefs.clipboard.limitHistorySize,
|
||||
title = stringRes(R.string.pref__clipboard__limit_history_size__label),
|
||||
|
||||
@@ -254,20 +254,14 @@ class ClipboardManager(
|
||||
}
|
||||
|
||||
private fun enforceExpiryDate(clipHistory: ClipboardHistory) {
|
||||
val itemsToRemove = mutableSetOf<ClipboardItem>()
|
||||
if (prefs.clipboard.cleanUpOld.get()) {
|
||||
val nonPinnedItems = clipHistory.recent + clipHistory.other
|
||||
val expiryTime = System.currentTimeMillis() - (prefs.clipboard.cleanUpAfter.get() * 60 * 1000)
|
||||
itemsToRemove.addAll(nonPinnedItems.filter { it.creationTimestampMs < expiryTime })
|
||||
}
|
||||
if (prefs.clipboard.autoCleanSensitive.get()) {
|
||||
val sensitiveData = clipHistory.all.filter { it.isSensitive }
|
||||
val expiryTime = System.currentTimeMillis() - (prefs.clipboard.autoCleanSensitiveAfter.get() * 1000)
|
||||
itemsToRemove.addAll(sensitiveData.filter { it.creationTimestampMs < expiryTime })
|
||||
}
|
||||
if (itemsToRemove.isNotEmpty()) {
|
||||
ioScope.launch {
|
||||
clipHistoryDao?.delete(itemsToRemove.toList())
|
||||
val itemsToRemove = nonPinnedItems.filter { it.creationTimestampMs < expiryTime }
|
||||
if (itemsToRemove.isNotEmpty()) {
|
||||
ioScope.launch {
|
||||
clipHistoryDao?.delete(itemsToRemove)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.database.getStringOrNull
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.AutoMigration
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Database
|
||||
@@ -39,13 +38,11 @@ import androidx.room.Entity
|
||||
import androidx.room.Insert
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.Query
|
||||
import androidx.room.RenameColumn
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverter
|
||||
import androidx.room.TypeConverters
|
||||
import androidx.room.Update
|
||||
import androidx.room.migration.AutoMigrationSpec
|
||||
import dev.patrickgold.florisboard.R
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
@@ -91,10 +88,8 @@ data class ClipboardItem @OptIn(ExperimentalSerializationApi::class) constructor
|
||||
val isPinned: Boolean,
|
||||
val mimeTypes: Array<String>,
|
||||
@EncodeDefault
|
||||
@ColumnInfo(name = "is_sensitive", defaultValue = "0")
|
||||
val isSensitive: Boolean = false,
|
||||
@EncodeDefault
|
||||
@ColumnInfo(name= "is_remote_device", defaultValue = "0")
|
||||
val isRemoteDevice: Boolean = false,
|
||||
) {
|
||||
companion object {
|
||||
@@ -242,7 +237,6 @@ data class ClipboardItem @OptIn(ExperimentalSerializationApi::class) constructor
|
||||
if (uri != other.uri) return false
|
||||
if (creationTimestampMs != other.creationTimestampMs) return false
|
||||
if (!mimeTypes.contentEquals(other.mimeTypes)) return false
|
||||
if (isSensitive != other.isSensitive) return false
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -254,7 +248,6 @@ data class ClipboardItem @OptIn(ExperimentalSerializationApi::class) constructor
|
||||
result = 31 * result + (uri?.hashCode() ?: 0)
|
||||
result = 31 * result + creationTimestampMs.hashCode()
|
||||
result = 31 * result + mimeTypes.contentHashCode()
|
||||
result = 31 * result + isSensitive.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -339,30 +332,11 @@ interface ClipboardHistoryDao {
|
||||
fun deleteAllUnpinned()
|
||||
}
|
||||
|
||||
@Database(
|
||||
entities = [ClipboardItem::class],
|
||||
version = 4,
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 2, to = 4),
|
||||
AutoMigration(from = 3, to = 4, spec = ClipboardHistoryDatabase.MIGRATE_3_TO_4::class),
|
||||
],
|
||||
)
|
||||
@Database(entities = [ClipboardItem::class], version = 3)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class ClipboardHistoryDatabase : RoomDatabase() {
|
||||
abstract fun clipboardItemDao(): ClipboardHistoryDao
|
||||
|
||||
@RenameColumn(
|
||||
tableName = CLIPBOARD_HISTORY_TABLE,
|
||||
fromColumnName = "isSensitive",
|
||||
toColumnName = "is_sensitive",
|
||||
)
|
||||
@RenameColumn(
|
||||
tableName = CLIPBOARD_HISTORY_TABLE,
|
||||
fromColumnName = "isRemoteDevice",
|
||||
toColumnName = "is_remote_device",
|
||||
)
|
||||
class MIGRATE_3_TO_4 : AutoMigrationSpec
|
||||
|
||||
companion object {
|
||||
fun new(context: Context): ClipboardHistoryDatabase {
|
||||
return Room
|
||||
|
||||
@@ -36,10 +36,10 @@ import dev.patrickgold.florisboard.ime.smartbar.ExtendedActionsPlacement
|
||||
import dev.patrickgold.florisboard.ime.smartbar.SmartbarLayout
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboard
|
||||
import dev.patrickgold.florisboard.keyboardManager
|
||||
import org.florisboard.lib.android.isOrientationLandscape
|
||||
import dev.patrickgold.florisboard.lib.observeAsTransformingState
|
||||
import dev.patrickgold.florisboard.lib.util.ViewUtils
|
||||
import dev.patrickgold.jetpref.datastore.model.observeAsState
|
||||
import org.florisboard.lib.android.isOrientationLandscape
|
||||
|
||||
private val LocalKeyboardRowBaseHeight = staticCompositionLocalOf { 65.dp }
|
||||
private val LocalSmartbarHeight = staticCompositionLocalOf { 40.dp }
|
||||
@@ -133,7 +133,7 @@ fun ProvideKeyboardRowBaseHeight(content: @Composable () -> Unit) {
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalKeyboardRowBaseHeight provides ViewUtils.px2dp(baseRowHeight).dp,
|
||||
LocalSmartbarHeight provides ViewUtils.px2dp(smartbarHeight).toInt().dp,
|
||||
LocalSmartbarHeight provides ViewUtils.px2dp(smartbarHeight).dp,
|
||||
) {
|
||||
content()
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ fun RowScope.OneHandedPanel(
|
||||
Column(
|
||||
modifier = modifier
|
||||
.weight(weight)
|
||||
.snyggBackground(context, oneHandedPanelStyle)
|
||||
.height(FlorisImeSizing.imeUiHeight()),
|
||||
.snyggBackground(context, oneHandedPanelStyle),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.SpaceEvenly,
|
||||
) {
|
||||
@@ -78,7 +77,7 @@ fun RowScope.OneHandedPanel(
|
||||
inputFeedbackController.keyPress()
|
||||
prefs.keyboard.oneHandedMode.set(panelSide)
|
||||
},
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
modifier = Modifier.height(FlorisImeSizing.keyboardUiHeight()).fillMaxWidth()
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (panelSide == OneHandedMode.START) {
|
||||
|
||||
@@ -48,13 +48,12 @@ import dev.patrickgold.florisboard.lib.toIntOffset
|
||||
@Composable
|
||||
fun rememberPopupUiController(
|
||||
key1: Any?,
|
||||
key2: Any?,
|
||||
boundsProvider: (key: Key) -> FlorisRect,
|
||||
isSuitableForBasicPopup: (key: Key) -> Boolean,
|
||||
isSuitableForExtendedPopup: (key: Key) -> Boolean,
|
||||
): PopupUiController {
|
||||
val context = LocalContext.current
|
||||
return remember(key1, key2) {
|
||||
return remember(key1) {
|
||||
PopupUiController(context, boundsProvider, isSuitableForBasicPopup, isSuitableForExtendedPopup)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ fun TextKeyboardLayout(
|
||||
modifier: Modifier = Modifier,
|
||||
evaluator: ComputingEvaluator,
|
||||
isPreview: Boolean = false,
|
||||
isSmartbarKeyboard: Boolean = false,
|
||||
): Unit = with(LocalDensity.current) {
|
||||
val prefs by florisPreferenceModel()
|
||||
val context = LocalContext.current
|
||||
@@ -124,7 +125,7 @@ fun TextKeyboardLayout(
|
||||
|
||||
val controller = remember { TextKeyboardLayoutController(context) }.also {
|
||||
it.keyboard = keyboard
|
||||
if (glideEnabled && !isPreview && keyboard.mode == KeyboardMode.CHARACTERS) {
|
||||
if (glideEnabled && !isSmartbarKeyboard && !isPreview && keyboard.mode == KeyboardMode.CHARACTERS) {
|
||||
val keys = keyboard.keys().asSequence().toList()
|
||||
glideTypingManager.setLayout(keys)
|
||||
}
|
||||
@@ -160,7 +161,13 @@ fun TextKeyboardLayout(
|
||||
BoxWithConstraints(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(FlorisImeSizing.keyboardUiHeight())
|
||||
.height(
|
||||
if (isSmartbarKeyboard) {
|
||||
FlorisImeSizing.smartbarHeight
|
||||
} else {
|
||||
FlorisImeSizing.keyboardUiHeight()
|
||||
}
|
||||
)
|
||||
.onGloballyPositioned { coords ->
|
||||
controller.size = coords.size.toSize()
|
||||
}
|
||||
@@ -189,7 +196,7 @@ fun TextKeyboardLayout(
|
||||
}
|
||||
.drawWithContent {
|
||||
drawContent()
|
||||
if (glideEnabled && glideShowTrail) {
|
||||
if (glideEnabled && glideShowTrail && !isSmartbarKeyboard) {
|
||||
val targetDist = 3.0f
|
||||
val radius = 20.0f
|
||||
|
||||
@@ -220,43 +227,57 @@ fun TextKeyboardLayout(
|
||||
val keyboardRowBaseHeight = FlorisImeSizing.keyboardRowBaseHeight
|
||||
|
||||
val desiredKey = remember(
|
||||
keyboard, keyboardWidth, keyboardHeight, keyMarginH, keyMarginV,
|
||||
keyboardRowBaseHeight, evaluator
|
||||
keyboard, isSmartbarKeyboard, keyboardWidth, keyboardHeight, keyMarginH, keyMarginV,
|
||||
keyboardRowBaseHeight
|
||||
) {
|
||||
TextKey(data = TextKeyData.UNSPECIFIED).also { desiredKey ->
|
||||
desiredKey.touchBounds.apply {
|
||||
width = keyboardWidth / 10f
|
||||
height = when (keyboard.mode) {
|
||||
KeyboardMode.CHARACTERS,
|
||||
KeyboardMode.NUMERIC_ADVANCED,
|
||||
KeyboardMode.SYMBOLS,
|
||||
KeyboardMode.SYMBOLS2 -> {
|
||||
(keyboardHeight / keyboard.rowCount)
|
||||
.coerceAtMost(keyboardRowBaseHeight.toPx() * 1.12f)
|
||||
if (isSmartbarKeyboard) {
|
||||
width = keyboardWidth / 8f
|
||||
height = keyboardHeight
|
||||
} else {
|
||||
width = keyboardWidth / 10f
|
||||
height = when (keyboard.mode) {
|
||||
KeyboardMode.CHARACTERS,
|
||||
KeyboardMode.NUMERIC_ADVANCED,
|
||||
KeyboardMode.SYMBOLS,
|
||||
KeyboardMode.SYMBOLS2 -> {
|
||||
(keyboardHeight / keyboard.rowCount)
|
||||
.coerceAtMost(keyboardRowBaseHeight.toPx() * 1.12f)
|
||||
}
|
||||
else -> keyboardRowBaseHeight.toPx()
|
||||
}
|
||||
else -> keyboardRowBaseHeight.toPx()
|
||||
}
|
||||
}
|
||||
desiredKey.visibleBounds.applyFrom(desiredKey.touchBounds).deflateBy(keyMarginH, keyMarginV)
|
||||
keyboard.layout(keyboardWidth, keyboardHeight, desiredKey, true)
|
||||
keyboard.layout(keyboardWidth, keyboardHeight, desiredKey, !isSmartbarKeyboard)
|
||||
}
|
||||
}
|
||||
|
||||
val fontSizeMultiplier = prefs.keyboard.fontSizeMultiplier()
|
||||
val popupUiController = rememberPopupUiController(
|
||||
key1 = keyboard,
|
||||
key2 = desiredKey,
|
||||
boundsProvider = { key ->
|
||||
val keyPopupWidth: Float
|
||||
val keyPopupHeight: Float
|
||||
when {
|
||||
configuration.isOrientationLandscape() -> {
|
||||
keyPopupWidth = desiredKey.visibleBounds.width * 1.0f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 3.0f
|
||||
if (isSmartbarKeyboard) {
|
||||
keyPopupWidth = key.visibleBounds.width * 1.0f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 3.0f * 1.2f
|
||||
} else {
|
||||
keyPopupWidth = desiredKey.visibleBounds.width * 1.0f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 3.0f
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
keyPopupWidth = desiredKey.visibleBounds.width * 1.1f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 2.5f
|
||||
if (isSmartbarKeyboard) {
|
||||
keyPopupWidth = key.visibleBounds.width * 1.1f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 2.5f * 1.2f
|
||||
} else {
|
||||
keyPopupWidth = desiredKey.visibleBounds.width * 1.1f
|
||||
keyPopupHeight = desiredKey.visibleBounds.height * 2.5f
|
||||
}
|
||||
}
|
||||
}
|
||||
val keyPopupDiffX = (key.visibleBounds.width - keyPopupWidth) / 2.0f
|
||||
@@ -274,7 +295,7 @@ fun TextKeyboardLayout(
|
||||
val numeric = keyboard.mode == KeyboardMode.NUMERIC ||
|
||||
keyboard.mode == KeyboardMode.PHONE || keyboard.mode == KeyboardMode.PHONE2 ||
|
||||
keyboard.mode == KeyboardMode.NUMERIC_ADVANCED && keyType == KeyType.NUMERIC
|
||||
keyCode > KeyCode.SPACE && keyCode != KeyCode.CJK_SPACE && !numeric
|
||||
keyCode > KeyCode.SPACE && keyCode != KeyCode.MULTIPLE_CODE_POINTS && keyCode != KeyCode.CJK_SPACE && !numeric
|
||||
} else {
|
||||
true
|
||||
}
|
||||
@@ -282,7 +303,7 @@ fun TextKeyboardLayout(
|
||||
isSuitableForExtendedPopup = { key ->
|
||||
if (key is TextKey) {
|
||||
val keyCode = key.computedData.code
|
||||
keyCode > KeyCode.SPACE && keyCode != KeyCode.CJK_SPACE || ExceptionsForKeyCodes.contains(keyCode)
|
||||
keyCode > KeyCode.SPACE && keyCode != KeyCode.MULTIPLE_CODE_POINTS && keyCode != KeyCode.CJK_SPACE || ExceptionsForKeyCodes.contains(keyCode)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
@@ -295,7 +316,7 @@ fun TextKeyboardLayout(
|
||||
val debugShowTouchBoundaries by prefs.devtools.showKeyTouchBoundaries.observeAsState()
|
||||
for (textKey in keyboard.keys()) {
|
||||
TextKeyButton(
|
||||
textKey, evaluator, fontSizeMultiplier,
|
||||
textKey, evaluator, fontSizeMultiplier, isSmartbarKeyboard,
|
||||
debugShowTouchBoundaries,
|
||||
)
|
||||
}
|
||||
@@ -317,12 +338,13 @@ private fun TextKeyButton(
|
||||
key: TextKey,
|
||||
evaluator: ComputingEvaluator,
|
||||
fontSizeMultiplier: Float,
|
||||
isSmartbarKey: Boolean,
|
||||
debugShowTouchBoundaries: Boolean,
|
||||
) = with(LocalDensity.current) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val keyStyle = FlorisImeTheme.style.get(
|
||||
element = FlorisImeUi.Key,
|
||||
element = if (isSmartbarKey) FlorisImeUi.SmartbarActionKey else FlorisImeUi.Key,
|
||||
code = key.computedData.code,
|
||||
mode = evaluator.state.inputShiftState.value,
|
||||
isPressed = key.isPressed && key.isEnabled,
|
||||
|
||||
@@ -207,6 +207,11 @@ class ThemeManager(context: Context) {
|
||||
val bgDrawable = Icon.createWithResource(context, bgDrawableId).apply {
|
||||
setTint(bgColor.toArgb())
|
||||
}
|
||||
val singleIconChipStyle = ViewStyle.Builder().run {
|
||||
setBackground(bgDrawable)
|
||||
setPadding(0, 0, 0, 0)
|
||||
build()
|
||||
}
|
||||
val chipStyle = ViewStyle.Builder().run {
|
||||
setBackground(bgDrawable)
|
||||
setPadding(
|
||||
@@ -244,7 +249,7 @@ class ThemeManager(context: Context) {
|
||||
build()
|
||||
}
|
||||
val suggestionStyle = InlineSuggestionUi.newStyleBuilder().run {
|
||||
setSingleIconChipStyle(chipStyle)
|
||||
setSingleIconChipStyle(singleIconChipStyle)
|
||||
setChipStyle(chipStyle)
|
||||
setStartIconStyle(iconStyle)
|
||||
setEndIconStyle(iconStyle)
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.florisboard.lib.android.AndroidVersion
|
||||
object NetworkUtils {
|
||||
private val Ipv4Regex = """(?<Ipv4>(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))""".toRegex()
|
||||
private val Ipv6Regex = """(?<Ipv6>(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])))""".toRegex()
|
||||
private val HostRegex = """(?<Host>(?:[a-zA-Z0-9][a-zA-Z0-9\-]+[a-zA-Z0-9]\.)+[a-zA-Z]{2,}|$Ipv4Regex|$Ipv6Regex)""".toRegex()
|
||||
private val HostRegex = """(?<Host>(?:[a-zA-Z\-]+\.)+[a-zA-Z]{2,}|$Ipv4Regex|$Ipv6Regex)""".toRegex()
|
||||
private val TcpIpPortRegex = """(?<TcpIpPort>6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|(?<![0-9])[0-5]?[0-9]{1,4}(?![0-9]))""".toRegex()
|
||||
private val UrlRegex = """(?<Url>(?:(?:(?:https?:\/\/)?$HostRegex)|(?:https?:\/\/[a-zA-Z]+))(?::$TcpIpPortRegex)?(?:\/[\p{L}0-9.,;?'\\\/+&%$#=~_\-]*)?)""".toRegex()
|
||||
private val EmailRegex = """(?<Email>(?:[a-z0-9!#${'$'}%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#${'$'}%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@$HostRegex)""".toRegex()
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package dev.patrickgold.florisboard.lib.util
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.FrameLayout
|
||||
@@ -83,7 +84,7 @@ object ViewUtils {
|
||||
* @return A float value to represent px equivalent to dp depending on device density
|
||||
*/
|
||||
fun dp2px(dp: Float): Float {
|
||||
return dp * Resources.getSystem().displayMetrics.density
|
||||
return dp * (Resources.getSystem().displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +96,6 @@ object ViewUtils {
|
||||
* @return A float value to represent dp equivalent to px value
|
||||
*/
|
||||
fun px2dp(px: Float): Float {
|
||||
return (px / Resources.getSystem().displayMetrics.density)
|
||||
return px / (Resources.getSystem().displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
unqualifiedResLocale=en-US
|
||||
@@ -114,13 +114,11 @@
|
||||
<string name="pref__input_feedback__haptic_vibration_duration__label" comment="Preference title">Duración de la vibración</string>
|
||||
<string name="pref__input_feedback__haptic_vibration_strength__label" comment="Preference title">Intensidá de la vibración</string>
|
||||
<string name="settings__keyboard__title" comment="Title of Keyboard preferences screen">Tecláu</string>
|
||||
<string name="pref__keyboard__number_row__label" comment="Preference title">Filera de númberos</string>
|
||||
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Amuesa la filera de númberos enriba de la distribución de tecles</string>
|
||||
<string name="pref__keyboard__space_bar_mode__label" comment="Preference title">Etiqueta de la barra d\'espaciu</string>
|
||||
<string name="pref__keyboard__font_size_multiplier__label" comment="Preference title">Multiplicador del tamañu de la fonte</string>
|
||||
<string name="pref__keyboard__height_factor__label" comment="Preference title">Altor del tecláu</string>
|
||||
<string name="pref__keyboard__group_keypress__label" comment="Preference group title">Pulsación de tecles</string>
|
||||
<string name="pref__keyboard__popup_enabled__label" comment="Preference title">Visibilidá d\'indicadores emerxentes</string>
|
||||
<string name="pref__keyboard__popup_enabled__label" comment="Preference title">Visibilidá de los indicadores emerxentes</string>
|
||||
<string name="pref__keyboard__popup_enabled__summary" comment="Preference summary">Amuesa un indicador emerxente cuando primes una tecla</string>
|
||||
<string name="pref__keyboard__long_press_delay__label" comment="Preference title">Retrasu de la pulsación de tecles llonga</string>
|
||||
<!-- Smartbar strings -->
|
||||
@@ -264,7 +262,6 @@
|
||||
<string name="ext__validation__enter_valid_number">Introduz nun númberu válidu</string>
|
||||
<string name="ext__validation__enter_positive_number">Introduz un númberu positivu (>=0)</string>
|
||||
<string name="ext__update_box__search_for_updates">Buscar anovamientos</string>
|
||||
<string name="ext__addon_management_box__addon_manager_info">Pues remanar toles xeres rellacionaes cola importación, esportación, creación, personalización y desaniciu d\'estensiones pente\'l xestor de complementos centralizáu.</string>
|
||||
<string name="ext__addon_management_box__go_to_page">Dir a «{ext_home_title}»</string>
|
||||
<string name="ext__home__visit_store">Visitar la tienda de complementos</string>
|
||||
<!-- Action strings -->
|
||||
@@ -313,7 +310,6 @@
|
||||
<string name="enum__incognito_mode__dynamic_on_off" comment="Enum value label">Des/activación automática</string>
|
||||
<string name="enum__landscape_input_ui_mode__dynamically_show" comment="Enum value label">Apaición dinámica</string>
|
||||
<string name="enum__snygg_level__advanced" comment="Enum value label">Configuración avanzada</string>
|
||||
<string name="enum__space_bar_mode__nothing" comment="Enum value label">Ensin etiqueta</string>
|
||||
<string name="enum__space_bar_mode__current_language" comment="Enum value label">Llingua actual</string>
|
||||
<string name="enum__swipe_action__redo" comment="Enum value label">Refacer</string>
|
||||
<string name="enum__swipe_action__undo" comment="Enum value label">Desfacer</string>
|
||||
|
||||
@@ -578,8 +578,6 @@
|
||||
<string name="devtools__show_input_state_overlay__summary" comment="Summary of Show input cache overlay in Devtools">Blendet Eingabe-Overlay zur Fehlersuche ein</string>
|
||||
<string name="devtools__show_spelling_overlay__label" comment="Label of Show spelling overlay in Devtools">Zeige Rechtschreibprüfungs-Overlay</string>
|
||||
<string name="devtools__show_spelling_overlay__summary" comment="Summary of Show spelling overlay in Devtools">Blendet die aktuellen Ergebnisse der Rechtschreibprüfung fürs Debugging ein</string>
|
||||
<string name="devtools__show_inline_autofill_overlay__label">Zeige Autofill-Overlay</string>
|
||||
<string name="devtools__show_inline_autofill_overlay__summary">Blendet das aktuelle Autofill-Ergebnis für das Debugging ein</string>
|
||||
<string name="devtools__show_key_touch_boundaries__label" comment="Label of Show key touch boundaries in Devtools">Tastendruck-Umrandungen einschalten</string>
|
||||
<string name="devtools__show_key_touch_boundaries__summary" comment="Summary of Show key touch boundaries in Devtools">Umrandet die gedrückte Taste in Rot</string>
|
||||
<string name="devtools__show_drag_and_drop_helpers__label" comment="Label of Show drag and drop helpers in Devtools">Zeige Verschiebe-Hilfen</string>
|
||||
|
||||
@@ -26,11 +26,10 @@
|
||||
<string name="prefs__media__emoji_suggestion_enabled__summary" comment="Preference summary">Предлагать смайлики при наборе текста</string>
|
||||
<string name="prefs__media__emoji_suggestion_type" comment="Preference title">Тип триггера</string>
|
||||
<string name="prefs__media__emoji_suggestion_update_history" comment="Preference title">Обновить историю смайликов</string>
|
||||
<string name="prefs__media__emoji_suggestion_update_history__summary" comment="Preference summary">Принятие предложенных эмодзи добавляет их в историю эмодзи</string>
|
||||
<string name="prefs__media__emoji_suggestion_candidate_show_name" comment="Preference title">Показать название смайлика</string>
|
||||
<string name="prefs__media__emoji_suggestion_candidate_show_name__summary" comment="Preference summary">Предложения смайликов отображают их название рядом</string>
|
||||
<string name="prefs__media__emoji_suggestion_query_min_length" comment="Preference title">Минимальная длина запроса</string>
|
||||
<string name="prefs__media__emoji_suggestion_candidate_max_count" comment="Preference title">Максимальное количество предложений</string>
|
||||
<string name="prefs__media__emoji_suggestion_candidate_max_count" comment="Preference title">Максимальное количество кандидатов</string>
|
||||
<!-- Emoji strings -->
|
||||
<string name="emoji__category__smileys_emotion" comment="Emoji category name">Смайлы и эмоции</string>
|
||||
<string name="emoji__category__people_body" comment="Emoji category name">Люди и тело</string>
|
||||
@@ -42,7 +41,6 @@
|
||||
<string name="emoji__category__symbols" comment="Emoji category name">Символы</string>
|
||||
<string name="emoji__category__flags" comment="Emoji category name">Флаги</string>
|
||||
<string name="emoji__history__empty_message" comment="Message if the emoji history is empty">Недавно использованные эмодзи не найдены. Как только вы начнете использовать эмодзи, они автоматически будут появляться здесь.</string>
|
||||
<string name="emoji__history__phone_locked_message" comment="Message to show if phone is locked">Чтобы получить доступ к истории эмодзи, сначала разблокируйте ваше устройство.</string>
|
||||
<string name="emoji__history__usage_tip" comment="Feature discoverability for actions of emoji history">Совет: Долго нажимайте на эмодзи в истории эмодзи, чтобы закрепить или удалить их!</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">Удаление {emoji} из истории эмодзи</string>
|
||||
<string name="emoji__history__pinned">Закреплено</string>
|
||||
@@ -56,7 +54,6 @@
|
||||
<string name="quick_action__arrow_left__tooltip">Переместить курсор влево</string>
|
||||
<string name="quick_action__arrow_right" maxLength="12">Вправо</string>
|
||||
<string name="quick_action__arrow_right__tooltip">Переместить курсор вправо</string>
|
||||
<string name="quick_action__clipboard_clear_primary_clip" maxLength="12">Очистить</string>
|
||||
<string name="quick_action__clipboard_clear_primary_clip__tooltip">Выполнить очистку основного клипа буфера обмена</string>
|
||||
<string name="quick_action__clipboard_copy" maxLength="12">Копировать</string>
|
||||
<string name="quick_action__clipboard_copy__tooltip">Выполнить копирование из буфера обмена</string>
|
||||
@@ -583,7 +580,6 @@
|
||||
<string name="devtools__show_input_state_overlay__summary" comment="Summary of Show input cache overlay in Devtools">Показывать наложением текущее состояние ввода для отладки</string>
|
||||
<string name="devtools__show_spelling_overlay__label" comment="Label of Show spelling overlay in Devtools">Показывать орфографию наложением</string>
|
||||
<string name="devtools__show_spelling_overlay__summary" comment="Summary of Show spelling overlay in Devtools">Показывать наложением текущие результаты проверки орфографии для отладки</string>
|
||||
<string name="devtools__show_inline_autofill_overlay__label">Показать встроенное окно автозаполнения</string>
|
||||
<string name="devtools__show_inline_autofill_overlay__summary">Отображает текущие результаты автозаполнения строки для отладки</string>
|
||||
<string name="devtools__show_key_touch_boundaries__label" comment="Label of Show key touch boundaries in Devtools">Показывать границы нажатия клавиш</string>
|
||||
<string name="devtools__show_key_touch_boundaries__summary" comment="Summary of Show key touch boundaries in Devtools">Обводить границы нажатия клавиш красным контуром</string>
|
||||
@@ -763,14 +759,10 @@
|
||||
<string name="enum__display_language_names_in__system_locale__description" comment="Enum value description">Подписи в приложении и интерфейсе клавиатуры указаны на языке, используемом в системе по умолчанию</string>
|
||||
<string name="enum__display_language_names_in__native_locale" comment="Enum value label">В исходном виде</string>
|
||||
<string name="enum__display_language_names_in__native_locale__description" comment="Enum value description">Подписи в приложении и интерфейсе клавиатуры приводятся на родных языках</string>
|
||||
<string name="enum__emoji_history_update_strategy__auto_sort_prepend" comment="Enum value label">Автоматическая сортировка (добавление в начало)</string>
|
||||
<string name="enum__emoji_history_update_strategy__auto_sort_prepend__description" comment="Enum value description">Автоматическое изменение порядка расположения эмодзи в зависимости от их использования. Новые эмодзи добавляются в начало.</string>
|
||||
<string name="enum__emoji_history_update_strategy__auto_sort_append" comment="Enum value label">Автоматическая сортировка (добавление в конец)</string>
|
||||
<string name="enum__emoji_history_update_strategy__auto_sort_append__description" comment="Enum value description">Автоматическое изменение порядка расположения эмодзи в зависимости от их использования. Новые эмодзи добавляются в конец.</string>
|
||||
<string name="enum__emoji_history_update_strategy__manual_sort_prepend" comment="Enum value label">Ручная сортировка (добавление в начало)</string>
|
||||
<string name="enum__emoji_history_update_strategy__manual_sort_prepend__description" comment="Enum value description">Не происходит автоматической перестановки эмодзи в зависимости от их использования.
|
||||
Новые эмодзи добавляются в начало.</string>
|
||||
<string name="enum__emoji_history_update_strategy__manual_sort_append" comment="Enum value label">Ручная сортировка (добавление в конец)</string>
|
||||
<string name="enum__emoji_history_update_strategy__manual_sort_append__description" comment="Enum value description">Не происходит автоматической перестановки эмодзи в зависимости от их использования.
|
||||
Новые эмодзи добавляются в конец.</string>
|
||||
<string name="enum__emoji_skin_tone__default" comment="Enum value label">Цвет кожи {emoji} по умолчанию</string>
|
||||
@@ -784,9 +776,7 @@
|
||||
<string name="enum__emoji_hair_style__curly_hair" comment="Enum value label">{emoji} Вьющиеся волосы</string>
|
||||
<string name="enum__emoji_hair_style__white_hair" comment="Enum value label">{emoji} Светлые волосы</string>
|
||||
<string name="enum__emoji_hair_style__bald" comment="Enum value label">{emoji} Без волос</string>
|
||||
<string name="enum__emoji_suggestion_type__leading_colon">Начальное двоеточие</string>
|
||||
<string name="enum__emoji_suggestion_type__leading_colon__description" comment="Keep the :emoji_name while translating, this is a syntax guide">Предлагайте эмодзи, используя синтаксис :emoji_name</string>
|
||||
<string name="enum__emoji_suggestion_type__inline_text">Встроенный текст</string>
|
||||
<string name="enum__emoji_suggestion_type__inline_text__description">Предлагает эмодзи, просто набрав название эмодзи в виде слова</string>
|
||||
<string name="enum__extended_actions_placement__above_candidates" comment="Enum value label">Вышестоящие предложение</string>
|
||||
<string name="enum__extended_actions_placement__above_candidates__description" comment="Enum value description">Размещает строку расширенных действий между пользовательским интерфейсом приложения и строкой предложений</string>
|
||||
@@ -911,16 +901,4 @@
|
||||
<item quantity="many">{v} элементов</item>
|
||||
<item quantity="other">{v} элементов</item>
|
||||
</plurals>
|
||||
<plurals name="unit__characters__written">
|
||||
<item quantity="one">{v} символ</item>
|
||||
<item quantity="few">{v} символа</item>
|
||||
<item quantity="many">{v} символов</item>
|
||||
<item quantity="other">{v} символов</item>
|
||||
</plurals>
|
||||
<plurals name="unit__candidates__written">
|
||||
<item quantity="one">{v} предложение</item>
|
||||
<item quantity="few">{v} предложения</item>
|
||||
<item quantity="many">{v} предложений</item>
|
||||
<item quantity="other">{v} предложений</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -595,8 +595,6 @@
|
||||
<string name="pref__clipboard__enable_clipboard_history__summary">Retain clipboard items for quick access</string>
|
||||
<string name="pref__clipboard__clean_up_old__label">Clean up old items</string>
|
||||
<string name="pref__clipboard__clean_up_after__label">Clean up old items after</string>
|
||||
<string name="pref__clipboard__auto_clean_sensitive__label">Auto clean sensitive items</string>
|
||||
<string name="pref__clipboard__auto_clean_sensitive_after__label">Auto clean sensitive items after</string>
|
||||
<string name="pref__clipboard__limit_history_size__label">Limit history size</string>
|
||||
<string name="pref__clipboard__max_history_size__label">Max history size</string>
|
||||
<string name="pref__clipboard__clear_primary_clip_deletes_last_item__label">Clear primary clip affects history</string>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
|
||||
</style>
|
||||
|
||||
<style name="FlorisAppTheme" parent="Theme.AppCompat.NoActionBar">
|
||||
<style name="FlorisAppTheme" parent="android:style/Theme.Material.NoActionBar">
|
||||
<item name="android:colorPrimary">@color/colorPrimary</item>
|
||||
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="android:colorAccent">@color/colorAccent</item>
|
||||
@@ -31,7 +31,7 @@
|
||||
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
|
||||
</style>
|
||||
|
||||
<style name="FlorisAppTheme.Transparent" parent="Theme.AppCompat.NoActionBar">
|
||||
<style name="FlorisAppTheme.Transparent" parent="android:style/Theme.Material.NoActionBar">
|
||||
<item name="android:colorPrimary">@android:color/transparent</item>
|
||||
<item name="android:colorPrimaryDark">@android:color/transparent</item>
|
||||
<item name="android:colorAccent">@android:color/transparent</item>
|
||||
|
||||
@@ -13,5 +13,5 @@ projectCompileSdk=34
|
||||
projectBuildToolsVersion=34.0.0
|
||||
projectNdkVersion=26.1.10909125
|
||||
|
||||
projectVersionCode=97
|
||||
projectVersionName=0.4.0-rc02
|
||||
projectVersionCode=100
|
||||
projectVersionName=0.4.2
|
||||
|
||||
@@ -14,7 +14,6 @@ androidx-material-icons = "1.7.3"
|
||||
androidx-navigation = "2.8.1"
|
||||
androidx-profileinstaller = "1.4.0"
|
||||
androidx-room = "2.6.1"
|
||||
appcompat = "1.7.0"
|
||||
cache4k = "0.7.0"
|
||||
kotlin = "2.0.20"
|
||||
kotlinx-coroutines = "1.8.1"
|
||||
@@ -54,7 +53,6 @@ androidx-navigation-compose = { module = "androidx.navigation:navigation-compose
|
||||
androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "androidx-profileinstaller" }
|
||||
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" }
|
||||
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidx-room" }
|
||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||
cache4k = { module = "io.github.reactivecircus.cache4k:cache4k", version.ref = "cache4k" }
|
||||
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
|
||||
|
||||
Reference in New Issue
Block a user