Force LTR in some UI, update actions autoclose

This commit is contained in:
Aleksandras Kostarevas 2024-06-15 16:12:26 +03:00
parent b74e977b6a
commit 494e27f482
4 changed files with 185 additions and 128 deletions

View File

@ -61,6 +61,7 @@ import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
@ -403,6 +404,7 @@ fun LazyItemScope.ActionItem(idx: Int, action: Action, onSelect: (Action) -> Uni
context.setSetting( context.setSetting(
ExpandableActionItems, ActionRegistry.moveElement( ExpandableActionItems, ActionRegistry.moveElement(
context.getSetting(ExpandableActionItems, DefaultActionsString), context.getSetting(ExpandableActionItems, DefaultActionsString),
DefaultActions,
action, action,
1 1
) )
@ -414,6 +416,7 @@ fun LazyItemScope.ActionItem(idx: Int, action: Action, onSelect: (Action) -> Uni
context.setSetting( context.setSetting(
ExpandableActionItems, ActionRegistry.moveElement( ExpandableActionItems, ActionRegistry.moveElement(
context.getSetting(ExpandableActionItems, DefaultActionsString), context.getSetting(ExpandableActionItems, DefaultActionsString),
DefaultActions,
action, action,
-1 -1
) )
@ -486,7 +489,6 @@ fun ActionItemSmall(action: Action, onSelect: (Action) -> Unit) {
fun ActionItems(onSelect: (Action) -> Unit) { fun ActionItems(onSelect: (Action) -> Unit) {
val actions = useDataStoreValueBlocking(key = ExpandableActionItems, default = DefaultActionsString) val actions = useDataStoreValueBlocking(key = ExpandableActionItems, default = DefaultActionsString)
if(actions != null) {
val actionItems = ActionRegistry.stringToActions(actions, DefaultActions) val actionItems = ActionRegistry.stringToActions(actions, DefaultActions)
LazyRow { LazyRow {
@ -495,7 +497,6 @@ fun ActionItems(onSelect: (Action) -> Unit) {
} }
} }
} }
}
@Composable @Composable
@ -588,7 +589,8 @@ fun ActionBar(
inlineSuggestions: List<MutableState<View?>>, inlineSuggestions: List<MutableState<View?>>,
forceOpenActionsInitially: Boolean = false, forceOpenActionsInitially: Boolean = false,
importantNotice: ImportantNotice? = null, importantNotice: ImportantNotice? = null,
keyboardManagerForAction: KeyboardManagerForAction? = null keyboardManagerForAction: KeyboardManagerForAction? = null,
actionsForcedOpenByUser: MutableState<Boolean> = mutableStateOf(false)
) { ) {
val view = LocalView.current val view = LocalView.current
val context = LocalContext.current val context = LocalContext.current
@ -600,14 +602,16 @@ fun ActionBar(
} }
LaunchedEffect(words) { LaunchedEffect(words) {
if(words != null && !words.isEmpty) { if(words != null && !words.isEmpty && !actionsForcedOpenByUser.value) {
isActionsOpen.value = false isActionsOpen.value = false
actionsForcedOpenByUser.value = false
} }
} }
LaunchedEffect(inlineSuggestions) { LaunchedEffect(inlineSuggestions) {
if(inlineSuggestions.isNotEmpty()) { if(inlineSuggestions.isNotEmpty()) {
isActionsOpen.value = false isActionsOpen.value = false
actionsForcedOpenByUser.value = false
} }
} }
@ -618,6 +622,8 @@ fun ActionBar(
Row { Row {
ExpandActionsButton(isActionsOpen.value) { ExpandActionsButton(isActionsOpen.value) {
isActionsOpen.value = !isActionsOpen.value isActionsOpen.value = !isActionsOpen.value
actionsForcedOpenByUser.value = isActionsOpen.value
if(isActionsOpen.value && importantNotice != null) { if(isActionsOpen.value && importantNotice != null) {
importantNotice.onDismiss(context) importantNotice.onDismiss(context)
} }

View File

@ -44,8 +44,10 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -259,6 +261,8 @@ class UixManager(private val latinIME: LatinIME) {
private var numSuggestionsSinceNotice = 0 private var numSuggestionsSinceNotice = 0
private var currentNotice: MutableState<ImportantNotice?> = mutableStateOf(null) private var currentNotice: MutableState<ImportantNotice?> = mutableStateOf(null)
private val actionsForcedOpenByUser = mutableStateOf(false)
var currWindowActionWindow: ActionWindow? = null var currWindowActionWindow: ActionWindow? = null
val isMainKeyboardHidden get() = mainKeyboardHidden val isMainKeyboardHidden get() = mainKeyboardHidden
@ -295,7 +299,8 @@ class UixManager(private val latinIME: LatinIME) {
inlineSuggestions = inlineSuggestions, inlineSuggestions = inlineSuggestions,
onActionActivated = { onActionActivated(it) }, onActionActivated = { onActionActivated(it) },
importantNotice = currentNotice.value, importantNotice = currentNotice.value,
keyboardManagerForAction = keyboardManagerForAction keyboardManagerForAction = keyboardManagerForAction,
actionsForcedOpenByUser = actionsForcedOpenByUser
) )
} }
} }
@ -319,6 +324,7 @@ class UixManager(private val latinIME: LatinIME) {
setContent() setContent()
actionsForcedOpenByUser.value = false
keyboardManagerForAction.announce("${latinIME.resources.getString(action.name)} mode") keyboardManagerForAction.announce("${latinIME.resources.getString(action.name)} mode")
} }
@ -340,6 +346,7 @@ class UixManager(private val latinIME: LatinIME) {
setContent() setContent()
actionsForcedOpenByUser.value = false
keyboardManagerForAction.announce("$name closed") keyboardManagerForAction.announce("$name closed")
} }
@ -491,6 +498,7 @@ class UixManager(private val latinIME: LatinIME) {
composeView?.setContent { composeView?.setContent {
UixThemeWrapper(latinIME.colorScheme) { UixThemeWrapper(latinIME.colorScheme) {
CompositionLocalProvider(LocalManager provides keyboardManagerForAction) { CompositionLocalProvider(LocalManager provides keyboardManagerForAction) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr ) {
Column { Column {
Spacer(modifier = Modifier.weight(1.0f)) Spacer(modifier = Modifier.weight(1.0f))
Surface(modifier = Modifier.onSizeChanged { Surface(modifier = Modifier.onSizeChanged {
@ -517,6 +525,7 @@ class UixManager(private val latinIME: LatinIME) {
} }
} }
} }
}
suspend fun showUpdateNoticeIfNeeded() { suspend fun showUpdateNoticeIfNeeded() {
if(!BuildConfig.UPDATE_CHECKING) return if(!BuildConfig.UPDATE_CHECKING) return
@ -606,6 +615,7 @@ class UixManager(private val latinIME: LatinIME) {
fun onInputFinishing() { fun onInputFinishing() {
closeActionWindow() closeActionWindow()
actionsForcedOpenByUser.value = false
languageSwitcherDialog?.dismiss() languageSwitcherDialog?.dismiss()
} }

View File

@ -45,11 +45,13 @@ import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.core.longPreferencesKey
@ -75,6 +77,8 @@ import org.futo.inputmethod.latin.uix.settings.ScrollableList
import org.futo.inputmethod.latin.uix.settings.useDataStore import org.futo.inputmethod.latin.uix.settings.useDataStore
import org.futo.inputmethod.latin.uix.settings.useDataStoreValueBlocking import org.futo.inputmethod.latin.uix.settings.useDataStoreValueBlocking
import org.futo.inputmethod.latin.uix.theme.Typography import org.futo.inputmethod.latin.uix.theme.Typography
import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper
import org.futo.inputmethod.latin.uix.theme.presets.DynamicDarkTheme
import org.futo.inputmethod.updates.dismissedMigrateUpdateNotice import org.futo.inputmethod.updates.dismissedMigrateUpdateNotice
import org.futo.inputmethod.updates.openURI import org.futo.inputmethod.updates.openURI
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@ -151,6 +155,7 @@ fun IconText(icon: Painter, title: String, body: String) {
fun PaymentText(verbose: Boolean) { fun PaymentText(verbose: Boolean) {
val numDaysInstalled = useNumberOfDaysInstalled() val numDaysInstalled = useNumberOfDaysInstalled()
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
// Doesn't make sense to say "You've been using for ... days" if it's less than seven days // Doesn't make sense to say "You've been using for ... days" if it's less than seven days
if (numDaysInstalled.intValue >= 7) { if (numDaysInstalled.intValue >= 7) {
ParagraphText(stringResource(R.string.payment_text_1, numDaysInstalled.value)) ParagraphText(stringResource(R.string.payment_text_1, numDaysInstalled.value))
@ -182,6 +187,7 @@ fun PaymentText(verbose: Boolean) {
ParagraphText(stringResource(R.string.payment_text_2)) ParagraphText(stringResource(R.string.payment_text_2))
} }
} }
}
suspend fun pushNoticeReminderTime(context: Context, days: Float) { suspend fun pushNoticeReminderTime(context: Context, days: Float) {
// If the user types in a crazy high number, the long can't store such a large value and it won't suppress the reminder // If the user types in a crazy high number, the long can't store such a large value and it won't suppress the reminder
@ -427,7 +433,7 @@ fun PaymentSurface(isPrimary: Boolean, title: String, onClick: (() -> Unit)? = n
} }
@Composable @Composable
@Preview(showBackground = true, heightDp = 10000) @Preview(showBackground = true, heightDp = 2048)
fun PaymentScreen( fun PaymentScreen(
navController: NavHostController = rememberNavController(), navController: NavHostController = rememberNavController(),
onExit: () -> Unit = { } onExit: () -> Unit = { }
@ -515,6 +521,7 @@ fun PaymentScreen(
val lastValidRemindValue = remember { mutableFloatStateOf(5.0f) } val lastValidRemindValue = remember { mutableFloatStateOf(5.0f) }
val remindDays = remember { mutableStateOf("5") } val remindDays = remember { mutableStateOf("5") }
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
Button( Button(
onClick = { onClick = {
coroutineScope.launch { coroutineScope.launch {
@ -551,6 +558,7 @@ fun PaymentScreen(
} }
} }
} }
}
NavigationItem(title = "Help", subtitle = "Need help? Visit our website", style = NavigationItemStyle.Misc, navigate = { NavigationItem(title = "Help", subtitle = "Need help? Visit our website", style = NavigationItemStyle.Misc, navigate = {
context.openURI("https://keyboard.futo.org/") context.openURI("https://keyboard.futo.org/")
@ -558,6 +566,17 @@ fun PaymentScreen(
} }
} }
@Composable
@Preview(heightDp = 2048)
private fun PaymentScreenDark() {
val context = LocalContext.current
UixThemeWrapper(colorScheme = DynamicDarkTheme.obtainColors(context)) {
Surface(color = MaterialTheme.colorScheme.background) {
PaymentScreen()
}
}
}
@Composable @Composable
fun PaymentScreenSwitch( fun PaymentScreenSwitch(

View File

@ -4,6 +4,7 @@ import android.widget.Toast
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@ -24,6 +25,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -31,10 +33,12 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.Path
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.futo.inputmethod.latin.uix.KeyBordersSetting import org.futo.inputmethod.latin.uix.KeyBordersSetting
import org.futo.inputmethod.latin.uix.KeyHintsSetting import org.futo.inputmethod.latin.uix.KeyHintsSetting
@ -234,10 +238,19 @@ fun ThemePicker(onSelected: (ThemeOption) -> Unit) {
} }
} }
val originalDirection = LocalLayoutDirection.current
Column { Column {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
LazyVerticalGrid( LazyVerticalGrid(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
columns = GridCells.Adaptive(minSize = 172.dp) columns = GridCells.Adaptive(minSize = 172.dp),
horizontalArrangement = if (LocalLayoutDirection.current == LayoutDirection.Rtl) {
Arrangement.End
} else {
Arrangement.Start
}
) { ) {
items(availableThemeOptions.count()) { items(availableThemeOptions.count()) {
val themeOption = availableThemeOptions[it].second val themeOption = availableThemeOptions[it].second
@ -262,19 +275,24 @@ fun ThemePicker(onSelected: (ThemeOption) -> Unit) {
item(span = { GridItemSpan(maxCurrentLineSpan) }) { } item(span = { GridItemSpan(maxCurrentLineSpan) }) { }
item(span = { GridItemSpan(maxCurrentLineSpan) }) { item(span = { GridItemSpan(maxCurrentLineSpan) }) {
CompositionLocalProvider(LocalLayoutDirection provides originalDirection) {
SettingToggleDataStore( SettingToggleDataStore(
title = "Key borders", title = "Key borders",
setting = KeyBordersSetting setting = KeyBordersSetting
) )
} }
}
item(span = { GridItemSpan(maxCurrentLineSpan) }) { item(span = { GridItemSpan(maxCurrentLineSpan) }) {
CompositionLocalProvider(LocalLayoutDirection provides originalDirection) {
SettingToggleDataStore( SettingToggleDataStore(
title = "Show symbol hints", title = "Show symbol hints",
setting = KeyHintsSetting setting = KeyHintsSetting
) )
} }
}
item(span = { GridItemSpan(maxCurrentLineSpan) }) { item(span = { GridItemSpan(maxCurrentLineSpan) }) {
CompositionLocalProvider(LocalLayoutDirection provides originalDirection) {
SettingSlider( SettingSlider(
title = "Keyboard Height", title = "Keyboard Height",
setting = KeyboardHeightMultiplierSetting, setting = KeyboardHeightMultiplierSetting,
@ -283,7 +301,9 @@ fun ThemePicker(onSelected: (ThemeOption) -> Unit) {
steps = 16 steps = 16
) )
} }
}
item(span = { GridItemSpan(maxCurrentLineSpan) }) { item(span = { GridItemSpan(maxCurrentLineSpan) }) {
CompositionLocalProvider(LocalLayoutDirection provides originalDirection) {
SettingSlider( SettingSlider(
title = "Keyboard Offset", title = "Keyboard Offset",
setting = KeyboardBottomOffsetSetting, setting = KeyboardBottomOffsetSetting,
@ -297,6 +317,8 @@ fun ThemePicker(onSelected: (ThemeOption) -> Unit) {
} }
} }
} }
}
}
@Preview @Preview