Inflate inline suggestions only once

This commit is contained in:
Aleksandras Kostarevas 2023-08-26 20:39:55 +03:00
parent d72838e659
commit 8278de9484
4 changed files with 46 additions and 38 deletions

View File

@ -26,6 +26,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.MutableState
import androidx.compose.runtime.key import androidx.compose.runtime.key
import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -51,6 +52,7 @@ import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.futo.inputmethod.latin.common.Constants import org.futo.inputmethod.latin.common.Constants
import org.futo.inputmethod.latin.uix.Action import org.futo.inputmethod.latin.uix.Action
@ -64,6 +66,7 @@ import org.futo.inputmethod.latin.uix.createInlineSuggestionsRequest
import org.futo.inputmethod.latin.uix.deferGetSetting import org.futo.inputmethod.latin.uix.deferGetSetting
import org.futo.inputmethod.latin.uix.deferSetSetting import org.futo.inputmethod.latin.uix.deferSetSetting
import org.futo.inputmethod.latin.uix.differsFrom import org.futo.inputmethod.latin.uix.differsFrom
import org.futo.inputmethod.latin.uix.inflateInlineSuggestion
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
import org.futo.inputmethod.latin.uix.theme.ThemeOption import org.futo.inputmethod.latin.uix.theme.ThemeOption
import org.futo.inputmethod.latin.uix.theme.ThemeOptions import org.futo.inputmethod.latin.uix.theme.ThemeOptions
@ -123,7 +126,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
return currWindowAction != null return currWindowAction != null
} }
private var inlineSuggestions: List<InlineSuggestion> = listOf() private var inlineSuggestions: List<MutableState<View?>> = listOf()
private fun recreateKeyboard() { private fun recreateKeyboard() {
legacyInputView = latinIMELegacy.onCreateInputView() legacyInputView = latinIMELegacy.onCreateInputView()
@ -546,7 +549,9 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
override fun onInlineSuggestionsResponse(response: InlineSuggestionsResponse): Boolean { override fun onInlineSuggestionsResponse(response: InlineSuggestionsResponse): Boolean {
inlineSuggestions = response.inlineSuggestions inlineSuggestions = response.inlineSuggestions.map {
inflateInlineSuggestion(it)
}
setContent() setContent()
return true return true

View File

@ -1,6 +1,7 @@
package org.futo.inputmethod.latin.uix package org.futo.inputmethod.latin.uix
import android.os.Build import android.os.Build
import android.view.View
import android.view.inputmethod.InlineSuggestion import android.view.inputmethod.InlineSuggestion
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
@ -27,6 +28,7 @@ import androidx.compose.material3.TextButton
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.CenterVertically
@ -55,6 +57,7 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import kotlinx.coroutines.flow.Flow
import org.futo.inputmethod.latin.R import org.futo.inputmethod.latin.R
import org.futo.inputmethod.latin.SuggestedWords import org.futo.inputmethod.latin.SuggestedWords
import org.futo.inputmethod.latin.SuggestedWords.SuggestedWordInfo import org.futo.inputmethod.latin.SuggestedWords.SuggestedWordInfo
@ -353,7 +356,7 @@ fun ActionBar(
words: SuggestedWords?, words: SuggestedWords?,
suggestionStripListener: SuggestionStripView.Listener, suggestionStripListener: SuggestionStripView.Listener,
onActionActivated: (Action) -> Unit, onActionActivated: (Action) -> Unit,
inlineSuggestions: List<InlineSuggestion>, inlineSuggestions: List<MutableState<View?>>,
forceOpenActionsInitially: Boolean = false, forceOpenActionsInitially: Boolean = false,
) { ) {
val isActionsOpen = remember { mutableStateOf(forceOpenActionsInitially) } val isActionsOpen = remember { mutableStateOf(forceOpenActionsInitially) }

View File

@ -4,11 +4,10 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.util.Size import android.util.Size
import android.util.TypedValue import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InlineSuggestion import android.view.inputmethod.InlineSuggestion
import android.view.inputmethod.InlineSuggestionsRequest import android.view.inputmethod.InlineSuggestionsRequest
import android.widget.inline.InlineContentView
import android.widget.inline.InlinePresentationSpec import android.widget.inline.InlinePresentationSpec
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.autofill.inline.UiVersions import androidx.autofill.inline.UiVersions
@ -21,19 +20,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import kotlin.math.roundToInt import kotlin.math.roundToInt
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
fun createInlineSuggestionsRequest( fun createInlineSuggestionsRequest(
@ -41,11 +36,7 @@ fun createInlineSuggestionsRequest(
activeColorScheme: ColorScheme activeColorScheme: ColorScheme
): InlineSuggestionsRequest { ): InlineSuggestionsRequest {
val fromDp = { v: Float -> val fromDp = { v: Float ->
TypedValue.applyDimension( context.fromDp(v).roundToInt()
TypedValue.COMPLEX_UNIT_DIP,
v,
context.resources.displayMetrics
).roundToInt()
} }
val stylesBuilder = UiVersions.newStylesBuilder() val stylesBuilder = UiVersions.newStylesBuilder()
@ -113,30 +104,31 @@ fun createInlineSuggestionsRequest(
} }
} }
@RequiresApi(Build.VERSION_CODES.R)
fun Context.inflateInlineSuggestion(inlineSuggestion: InlineSuggestion): MutableState<View?> {
val mutableState: MutableState<View?> = mutableStateOf(null)
val size = Size(ViewGroup.LayoutParams.WRAP_CONTENT, fromDp(32f).roundToInt())
try {
inlineSuggestion.inflate(this, size, mainExecutor) { inflatedView ->
if (inflatedView != null) {
mutableState.value = inflatedView
}
}
} catch (e: Exception) {
println(e.toString())
}
return mutableState
}
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
@Composable @Composable
fun InlineSuggestionView(inlineSuggestion: InlineSuggestion) = with(LocalDensity.current) { fun InlineSuggestionView(inlineSuggestion: MutableState<View?>) {
val context = LocalContext.current if (inlineSuggestion.value != null) {
val size = Size(ViewGroup.LayoutParams.WRAP_CONTENT, 32.dp.toPx().toInt())
var inlineContentView by remember { mutableStateOf<InlineContentView?>(null) }
LaunchedEffect(Unit) {
try {
inlineSuggestion.inflate(context, size, context.mainExecutor) { inflatedView ->
if (inflatedView != null) {
inlineContentView = inflatedView
}
}
} catch (e: Exception) {
println(e.toString())
}
}
if (inlineContentView != null) {
AndroidView( AndroidView(
factory = { inlineContentView!! }, factory = { inlineSuggestion.value!! },
modifier = Modifier.padding(4.dp, 0.dp) modifier = Modifier.padding(4.dp, 0.dp)
) )
} }
@ -144,8 +136,10 @@ fun InlineSuggestionView(inlineSuggestion: InlineSuggestion) = with(LocalDensity
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
@Composable @Composable
fun RowScope.InlineSuggestions(suggestions: List<InlineSuggestion>) { fun RowScope.InlineSuggestions(suggestions: List<MutableState<View?>>) {
LazyRow(modifier = Modifier.weight(1.0f).padding(0.dp, 4.dp)) { LazyRow(modifier = Modifier
.weight(1.0f)
.padding(0.dp, 4.dp)) {
items(suggestions.size) { items(suggestions.size) {
InlineSuggestionView(suggestions[it]) InlineSuggestionView(suggestions[it])
} }

View File

@ -1,5 +1,7 @@
package org.futo.inputmethod.latin.uix package org.futo.inputmethod.latin.uix
import android.content.Context
import android.util.TypedValue
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
// Not exhaustive // Not exhaustive
@ -13,4 +15,8 @@ fun ColorScheme.differsFrom(other: ColorScheme): Boolean {
|| this.onSurface != other.onSurface || this.onSurface != other.onSurface
|| this.onBackground != other.onBackground || this.onBackground != other.onBackground
|| this.onPrimary != other.onPrimary || this.onPrimary != other.onPrimary
}
fun Context.fromDp(v: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, v, resources.displayMetrics)
} }