diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt index f6dbefe2a..b2dc19821 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt @@ -1,20 +1,32 @@ // SPDX-License-Identifier: GPL-3.0-only package helium314.keyboard.settings.screens +import android.app.Activity import android.content.Context +import android.content.Intent +import android.graphics.BitmapFactory +import android.net.Uri import android.os.Build +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.material3.AlertDialog import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import helium314.keyboard.keyboard.KeyboardSwitcher import helium314.keyboard.keyboard.KeyboardTheme import helium314.keyboard.latin.R +import helium314.keyboard.latin.common.FileUtils import helium314.keyboard.latin.settings.ColorsNightSettingsFragment import helium314.keyboard.latin.settings.ColorsSettingsFragment import helium314.keyboard.latin.settings.Settings @@ -22,6 +34,7 @@ import helium314.keyboard.latin.settings.SettingsValues import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.getStringResourceOrName +import helium314.keyboard.latin.utils.infoDialog import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.switchTo import helium314.keyboard.settings.AllPrefs @@ -36,6 +49,9 @@ import helium314.keyboard.settings.SliderPreference import helium314.keyboard.settings.SwitchPreference import helium314.keyboard.settings.Theme import helium314.keyboard.settings.dialogs.CustomizeIconsDialog +import helium314.keyboard.settings.keyboardNeedsReload +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch @Composable fun AppearanceScreen( @@ -177,11 +193,69 @@ fun createAppearancePrefs(context: Context) = listOf( SwitchPreference(def, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) }, PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE, R.string.customize_background_image) { def -> - var showDialog by remember { mutableStateOf(false) } + var showDayNightDialog by remember { mutableStateOf(false) } + var showSelectionDialog by remember { mutableStateOf(false) } + var showErrorDialog by remember { mutableStateOf(false) } + var isNight by remember { mutableStateOf(false) } + val ctx = LocalContext.current + val dayNightPref = Settings.readDayNightPref(ctx.prefs(), ctx.resources) + val scope = rememberCoroutineScope() + val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult + val uri = result.data?.data ?: return@rememberLauncherForActivityResult + showSelectionDialog = false + showDayNightDialog = false + scope.launch(Dispatchers.IO) { + if (!setBackgroundImage(ctx, uri, isNight, false)) + showErrorDialog = true + } + } + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + .addCategory(Intent.CATEGORY_OPENABLE) + .setType("image/*") Preference( name = def.title, - onClick = { showDialog = true } - ) // todo: create and show the dialog + onClick = { + if (dayNightPref) { + showDayNightDialog = true + } else if (!Settings.getCustomBackgroundFile(ctx, false, false).exists()) { + launcher.launch(intent) + } else { + showSelectionDialog = true + } + } + ) + if (showDayNightDialog) { + // dialog to set isNight and then show other dialog if image exists + AlertDialog( + onDismissRequest = { showDayNightDialog = false }, + confirmButton = { + TextButton(onClick = { + showDayNightDialog = false + isNight = false + if (Settings.getCustomBackgroundFile(ctx, isNight, false).exists()) + showSelectionDialog = true + else launcher.launch(intent) + }) { Text(stringResource(R.string.day_or_night_day)) } + }, + dismissButton = { + TextButton(onClick = { + showDayNightDialog = false + isNight = true + if (Settings.getCustomBackgroundFile(ctx, isNight, false).exists()) + showSelectionDialog = true + else launcher.launch(intent) + }) { Text(stringResource(R.string.day_or_night_night)) } + }, + title = { Text(stringResource(R.string.day_or_night_image)) }, + ) + } + if (showSelectionDialog) { + // todo: delete file or start launcher + } + if (showErrorDialog) { + // todo: infoDialog(requireContext(), R.string.file_read_error) + } }, PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE_LANDSCAPE, R.string.customize_background_image_landscape, R.string.summary_customize_background_image_landscape) { def -> var showDialog by remember { mutableStateOf(false) } @@ -242,6 +316,20 @@ fun createAppearancePrefs(context: Context) = listOf( }, ) +private fun setBackgroundImage(ctx: Context, uri: Uri, isNight: Boolean, isLandscape: Boolean): Boolean { + val imageFile = Settings.getCustomBackgroundFile(ctx, isNight, false) + FileUtils.copyContentUriToNewFile(uri, ctx, imageFile) + keyboardNeedsReload = true + try { + BitmapFactory.decodeFile(imageFile.absolutePath) + } catch (_: Exception) { + imageFile.delete() + return false + } + Settings.clearCachedBackgroundImages() + return true +} + @Preview @Composable private fun Preview() {