mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Request mic permission during setup, add test text field
This commit is contained in:
parent
350b8e8fcf
commit
6c4c6b8965
12
build.gradle
12
build.gradle
@ -144,12 +144,12 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0'
|
||||
implementation 'androidx.activity:activity-compose:1.8.2'
|
||||
implementation platform('androidx.compose:compose-bom:2022.10.00')
|
||||
implementation platform('androidx.compose:compose-bom:2024.02.02')
|
||||
implementation 'androidx.compose.ui:ui'
|
||||
implementation 'androidx.compose.ui:ui-graphics'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
@ -157,7 +157,7 @@ dependencies {
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-compose:2.7.6'
|
||||
implementation 'androidx.navigation:navigation-compose:2.7.7'
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
|
@ -39,4 +39,5 @@
|
||||
|
||||
<string name="blacklist">Blacklist</string>
|
||||
<string name="blacklist_from_suggestions">Blacklist \"%1$s\" from being suggested?</string>
|
||||
<string name="try_typing">Try typing here…</string>
|
||||
</resources>
|
@ -292,7 +292,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
||||
key(legacyInputView) {
|
||||
AndroidView(factory = {
|
||||
legacyInputView!!
|
||||
}, update = { }, modifier = modifier)
|
||||
}, modifier = modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
||||
latinIMELegacy.setComposeInputView(it)
|
||||
}
|
||||
|
||||
latinIMELegacy.setInputView(legacyInputView)
|
||||
latinIMELegacy.setInputView(newView)
|
||||
}
|
||||
|
||||
override fun setInputView(view: View?) {
|
||||
|
@ -1,9 +1,11 @@
|
||||
package org.futo.inputmethod.latin.uix.settings
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Context.INPUT_METHOD_SERVICE
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
@ -27,9 +29,12 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.futo.inputmethod.latin.R
|
||||
import org.futo.inputmethod.latin.uix.THEME_KEY
|
||||
import org.futo.inputmethod.latin.uix.USE_SYSTEM_VOICE_INPUT
|
||||
import org.futo.inputmethod.latin.uix.deferGetSetting
|
||||
import org.futo.inputmethod.latin.uix.getSetting
|
||||
import org.futo.inputmethod.latin.uix.theme.StatusBarColorSetter
|
||||
import org.futo.inputmethod.latin.uix.theme.ThemeOption
|
||||
import org.futo.inputmethod.latin.uix.theme.ThemeOptions
|
||||
@ -68,10 +73,10 @@ class SettingsActivity : ComponentActivity() {
|
||||
|
||||
private val inputMethodEnabled = mutableStateOf(false)
|
||||
private val inputMethodSelected = mutableStateOf(false)
|
||||
private val micPermissionGrantedOrUsingSystem = mutableStateOf(false)
|
||||
|
||||
private var wasImeEverDisabled = false
|
||||
|
||||
|
||||
private var fileBeingSaved: File? = null
|
||||
fun updateFileBeingSaved(to: File) {
|
||||
fileBeingSaved = to
|
||||
@ -82,12 +87,16 @@ class SettingsActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
private fun updateSystemState() {
|
||||
fun updateSystemState() {
|
||||
val inputMethodEnabled = isInputMethodEnabled()
|
||||
val inputMethodSelected = isDefaultIMECurrent()
|
||||
this.inputMethodEnabled.value = inputMethodEnabled
|
||||
this.inputMethodSelected.value = inputMethodSelected
|
||||
|
||||
this.micPermissionGrantedOrUsingSystem.value = (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) || runBlocking {
|
||||
getSetting(USE_SYSTEM_VOICE_INPUT)
|
||||
}
|
||||
|
||||
if(!inputMethodEnabled) {
|
||||
wasImeEverDisabled = true
|
||||
} else if(wasImeEverDisabled) {
|
||||
@ -138,7 +147,7 @@ class SettingsActivity : ComponentActivity() {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
SetupOrMain(inputMethodEnabled.value, inputMethodSelected.value) {
|
||||
SetupOrMain(inputMethodEnabled.value, inputMethodSelected.value, micPermissionGrantedOrUsingSystem.value) {
|
||||
SettingsNavigator(navController = navController)
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,13 @@ import androidx.compose.runtime.Composable
|
||||
import org.futo.inputmethod.latin.utils.UncachedInputMethodManagerUtils
|
||||
|
||||
@Composable
|
||||
fun SetupOrMain(inputMethodEnabled: Boolean, inputMethodSelected: Boolean, main: @Composable () -> Unit) {
|
||||
fun SetupOrMain(inputMethodEnabled: Boolean, inputMethodSelected: Boolean, micPermissionGrantedOrUsingSystem: Boolean, main: @Composable () -> Unit) {
|
||||
if (!inputMethodEnabled) {
|
||||
SetupEnableIME()
|
||||
} else if (!inputMethodSelected) {
|
||||
SetupChangeDefaultIME()
|
||||
} else if (!micPermissionGrantedOrUsingSystem) {
|
||||
SetupEnableMic()
|
||||
} else {
|
||||
main()
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package org.futo.inputmethod.latin.uix.settings
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@ -17,6 +21,10 @@ import androidx.compose.material3.LinearProgressIndicator
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -25,6 +33,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.futo.inputmethod.latin.R
|
||||
import org.futo.inputmethod.latin.uix.USE_SYSTEM_VOICE_INPUT
|
||||
import org.futo.inputmethod.latin.uix.theme.Typography
|
||||
|
||||
@Composable
|
||||
@ -93,10 +102,10 @@ fun SetupEnableIME() {
|
||||
|
||||
SetupContainer {
|
||||
Column {
|
||||
Step(fraction = 1.0f/3.0f, text = "Setup - Step 1 of 2")
|
||||
Step(fraction = 1.0f/3.0f, text = "Setup - Step 1 of 3")
|
||||
|
||||
Text(
|
||||
"To use FUTO Keyboard, you must first enable FUTO Keyboard as an input method.",
|
||||
"Welcome to FUTO Keyboard pre-alpha! Please keep in mind things may be rough. This is not a finished product in any way.\n\nFirst, enable FUTO Keyboard as an input method.",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@ -123,14 +132,16 @@ fun SetupChangeDefaultIME() {
|
||||
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
||||
inputMethodManager.showInputMethodPicker()
|
||||
|
||||
(context as SettingsActivity).updateSystemState()
|
||||
}
|
||||
|
||||
SetupContainer {
|
||||
Column {
|
||||
Step(fraction = 2.0f/3.0f, text = "Setup - Step 2 of 2")
|
||||
Step(fraction = 2.0f/3.0f, text = "Setup - Step 2 of 3")
|
||||
|
||||
Text(
|
||||
"Next, select FUTO Keyboard as your active input method.",
|
||||
"Please select FUTO Keyboard as your active input method.",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@ -144,4 +155,70 @@ fun SetupChangeDefaultIME() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun SetupEnableMic(onClick: () -> Unit = { }) {
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
if(isGranted) { onClick() }
|
||||
}
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
var askedCount by remember { mutableStateOf(0) }
|
||||
val askMicAccess = {
|
||||
if (askedCount++ >= 2) {
|
||||
val packageName = context.packageName
|
||||
val myAppSettings = Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse(
|
||||
"package:$packageName"
|
||||
)
|
||||
)
|
||||
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
myAppSettings.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
context.startActivity(myAppSettings)
|
||||
} else {
|
||||
launcher.launch(Manifest.permission.RECORD_AUDIO)
|
||||
}
|
||||
onClick()
|
||||
}
|
||||
|
||||
val (useSystemVoiceInput, setUseSystemVoiceInput) = useDataStore(key = USE_SYSTEM_VOICE_INPUT.key, default = USE_SYSTEM_VOICE_INPUT.default)
|
||||
|
||||
SetupContainer {
|
||||
Column {
|
||||
Step(fraction = 0.9f, text = "Step 3 of 3")
|
||||
Text(
|
||||
"Choose whether you want to use built-in voice input, or the system voice input.",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = askMicAccess,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text("Use built-in (mic permission needed)")
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
setUseSystemVoiceInput(true)
|
||||
(context as SettingsActivity).updateSystemState()
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp, 4.dp)
|
||||
) {
|
||||
Text("Use system")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,26 @@
|
||||
package org.futo.inputmethod.latin.uix.settings.pages
|
||||
|
||||
import android.widget.EditText
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import org.futo.inputmethod.latin.BuildConfig
|
||||
@ -18,64 +28,90 @@ import org.futo.inputmethod.latin.R
|
||||
import org.futo.inputmethod.latin.uix.settings.NavigationItem
|
||||
import org.futo.inputmethod.latin.uix.settings.NavigationItemStyle
|
||||
import org.futo.inputmethod.latin.uix.settings.ScreenTitle
|
||||
import org.futo.inputmethod.latin.uix.settings.ScrollableList
|
||||
import org.futo.inputmethod.latin.uix.settings.openLanguageSettings
|
||||
import org.futo.inputmethod.latin.uix.theme.Typography
|
||||
import org.futo.inputmethod.updates.ConditionalUpdate
|
||||
|
||||
@Composable
|
||||
fun AndroidTextInput() {
|
||||
val context = LocalContext.current
|
||||
val bgColor = MaterialTheme.colorScheme.background
|
||||
val fgColor = MaterialTheme.colorScheme.onBackground
|
||||
|
||||
if(!LocalInspectionMode.current) {
|
||||
val editText = remember {
|
||||
EditText(context).apply {
|
||||
setHint(R.string.try_typing)
|
||||
setBackgroundColor(bgColor.toArgb())
|
||||
setTextColor(fgColor.toArgb())
|
||||
setHintTextColor(fgColor.copy(alpha = 0.7f).toArgb())
|
||||
}
|
||||
}
|
||||
AndroidView({ editText }, modifier = Modifier.fillMaxWidth().padding(8.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun HomeScreen(navController: NavHostController = rememberNavController()) {
|
||||
val context = LocalContext.current
|
||||
ScrollableList {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
ScreenTitle("FUTO Keyboard Settings")
|
||||
val scrollState = rememberScrollState()
|
||||
Column {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1.0f).fillMaxWidth()
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
ScreenTitle("FUTO Keyboard Settings")
|
||||
|
||||
ConditionalUpdate(navController)
|
||||
ConditionalUpdate(navController)
|
||||
|
||||
NavigationItem(
|
||||
title = "Languages",
|
||||
style = NavigationItemStyle.HomePrimary,
|
||||
navigate = { context.openLanguageSettings() },
|
||||
icon = painterResource(id = R.drawable.globe)
|
||||
)
|
||||
NavigationItem(
|
||||
title = "Languages",
|
||||
style = NavigationItemStyle.HomePrimary,
|
||||
navigate = { context.openLanguageSettings() },
|
||||
icon = painterResource(id = R.drawable.globe)
|
||||
)
|
||||
|
||||
NavigationItem(
|
||||
title = "Predictive Text",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("predictiveText") },
|
||||
icon = painterResource(id = R.drawable.shift)
|
||||
)
|
||||
NavigationItem(
|
||||
title = "Predictive Text",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("predictiveText") },
|
||||
icon = painterResource(id = R.drawable.shift)
|
||||
)
|
||||
|
||||
NavigationItem(
|
||||
title = "Typing Preferences",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("typing") },
|
||||
icon = painterResource(id = R.drawable.delete)
|
||||
)
|
||||
NavigationItem(
|
||||
title = "Typing Preferences",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("typing") },
|
||||
icon = painterResource(id = R.drawable.delete)
|
||||
)
|
||||
|
||||
NavigationItem(
|
||||
title = "Voice Input",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("voiceInput") },
|
||||
icon = painterResource(id = R.drawable.mic_fill)
|
||||
)
|
||||
NavigationItem(
|
||||
title = "Voice Input",
|
||||
style = NavigationItemStyle.HomeSecondary,
|
||||
navigate = { navController.navigate("voiceInput") },
|
||||
icon = painterResource(id = R.drawable.mic_fill)
|
||||
)
|
||||
|
||||
NavigationItem(
|
||||
title = "Theme",
|
||||
style = NavigationItemStyle.HomeTertiary,
|
||||
navigate = { navController.navigate("themes") },
|
||||
icon = painterResource(id = R.drawable.eye)
|
||||
)
|
||||
NavigationItem(
|
||||
title = "Theme",
|
||||
style = NavigationItemStyle.HomeTertiary,
|
||||
navigate = { navController.navigate("themes") },
|
||||
icon = painterResource(id = R.drawable.eye)
|
||||
)
|
||||
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
"v${BuildConfig.VERSION_NAME}",
|
||||
style = Typography.labelSmall,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
"v${BuildConfig.VERSION_NAME}",
|
||||
style = Typography.labelSmall,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
AndroidTextInput()
|
||||
}
|
||||
}
|
@ -41,12 +41,12 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0'
|
||||
implementation 'androidx.activity:activity-compose:1.8.2'
|
||||
implementation platform('androidx.compose:compose-bom:2022.10.00')
|
||||
implementation platform('androidx.compose:compose-bom:2024.02.02')
|
||||
implementation 'androidx.compose.ui:ui'
|
||||
implementation 'androidx.compose.ui:ui-graphics'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
@ -54,7 +54,7 @@ dependencies {
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-compose:2.7.6'
|
||||
implementation 'androidx.navigation:navigation-compose:2.7.7'
|
||||
implementation 'androidx.datastore:datastore-preferences:1.0.0'
|
||||
|
||||
implementation(name:'vad-release', ext:'aar')
|
||||
|
Loading…
Reference in New Issue
Block a user