From 86cd33ff5f810edd5d462651ecc5a02e389cdc4e Mon Sep 17 00:00:00 2001 From: William Brawner Date: Wed, 31 Jul 2024 20:17:14 -0600 Subject: [PATCH 1/6] Address lint issues --- app/build.gradle.kts | 3 + .../wbrawner/simplemarkdown/MainActivity.kt | 23 ++++---- .../simplemarkdown/MarkdownApplication.kt | 9 ++- .../simplemarkdown/MarkdownViewModel.kt | 48 +++++++++++----- .../wbrawner/simplemarkdown/ui/MainScreen.kt | 35 +++++++----- .../simplemarkdown/ui/MarkdownInfoScreen.kt | 2 +- .../ui/MarkdownNavigationDrawer.kt | 5 +- .../simplemarkdown/ui/MarkdownText.kt | 2 + .../simplemarkdown/ui/MarkdownTextField.kt | 4 +- .../simplemarkdown/ui/MarkdownTopAppBar.kt | 9 +-- .../simplemarkdown/ui/SettingsScreen.kt | 41 +++++++------- .../simplemarkdown/ui/SupportScreen.kt | 9 +-- .../simplemarkdown/utility/Extensions.kt | 12 +--- .../simplemarkdown/utility/PersistentTree.kt | 12 ++-- .../utility/PreferenceHelper.kt | 2 +- app/src/main/res/drawable-hdpi/splash_fg.png | Bin 7977 -> 0 bytes app/src/main/res/drawable-mdpi/splash_fg.png | Bin 4399 -> 0 bytes app/src/main/res/drawable-xhdpi/splash_fg.png | Bin 11542 -> 0 bytes .../main/res/drawable-xxhdpi/splash_fg.png | Bin 21457 -> 0 bytes .../main/res/drawable-xxxhdpi/splash_fg.png | Bin 27668 -> 0 bytes app/src/main/res/values-night/colors.xml | 5 -- app/src/main/res/values/colors.xml | 2 - app/src/main/res/values/dimens.xml | 3 - app/src/main/res/values/strings.xml | 52 +++++++----------- core/build.gradle.kts | 3 + free/build.gradle.kts | 3 + gradle/libs.versions.toml | 4 +- non-free/build.gradle.kts | 3 + 28 files changed, 157 insertions(+), 134 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/splash_fg.png delete mode 100644 app/src/main/res/drawable-mdpi/splash_fg.png delete mode 100644 app/src/main/res/drawable-xhdpi/splash_fg.png delete mode 100644 app/src/main/res/drawable-xxhdpi/splash_fg.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/splash_fg.png delete mode 100644 app/src/main/res/values-night/colors.xml delete mode 100644 app/src/main/res/values/dimens.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f6aac4a..f977812 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -97,6 +97,9 @@ android { commit.set(true) } } + lint { + warningsAsErrors = true + } } play { diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.kt index 873f940..406123b 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.kt @@ -4,6 +4,7 @@ import android.os.Build import android.os.Bundle import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.compose.animation.AnimatedContentTransitionScope @@ -27,6 +28,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource import androidx.core.app.ActivityCompat import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat @@ -135,21 +137,21 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes } composable(Route.HELP.path) { MarkdownInfoScreen( - title = Route.HELP.title, + title = stringResource(Route.HELP.title), file = "Cheatsheet.md", navController = navController ) } composable(Route.ABOUT.path) { MarkdownInfoScreen( - title = Route.ABOUT.title, + title = stringResource(Route.ABOUT.title), file = "Libraries.md", navController = navController ) } composable(Route.PRIVACY.path) { MarkdownInfoScreen( - title = Route.PRIVACY.title, + title = stringResource(Route.PRIVACY.title), file = "Privacy Policy.md", navController = navController ) @@ -162,13 +164,14 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes enum class Route( val path: String, - val title: String, + @StringRes + val title: Int, val icon: ImageVector ) { - EDITOR("/", "Editor", Icons.Default.Edit), - SETTINGS("/settings", "Settings", Icons.Default.Settings), - SUPPORT("/support", "Support SimpleMarkdown", Icons.Default.Favorite), - HELP("/help", "Help", Icons.AutoMirrored.Filled.Help), - ABOUT("/about", "About", Icons.Default.Info), - PRIVACY("/privacy", "Privacy", Icons.Default.PrivacyTip), + EDITOR("/", R.string.title_editor, Icons.Default.Edit), + SETTINGS("/settings", R.string.title_settings, Icons.Default.Settings), + SUPPORT("/support", R.string.support_title, Icons.Default.Favorite), + HELP("/help", R.string.title_help, Icons.AutoMirrored.Filled.Help), + ABOUT("/about", R.string.title_about, Icons.Default.Info), + PRIVACY("/privacy", R.string.action_privacy, Icons.Default.PrivacyTip), } \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt index 7aa1ef4..b4f3b9b 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt @@ -9,13 +9,16 @@ import com.wbrawner.simplemarkdown.utility.FileHelper import com.wbrawner.simplemarkdown.utility.PersistentTree import com.wbrawner.simplemarkdown.utility.PreferenceHelper import com.wbrawner.simplemarkdown.utility.ReviewHelper -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import timber.log.Timber import java.io.File class MarkdownApplication : Application() { + private val coroutineScope = CoroutineScope(Dispatchers.Default) + override fun onCreate() { if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder() @@ -27,9 +30,9 @@ class MarkdownApplication : Application() { .penaltyLog() .build()) Timber.plant(Timber.DebugTree()) - GlobalScope.launch { + coroutineScope.launch { try { - Timber.plant(PersistentTree.create(File(getExternalFilesDir(null), "logs"))) + Timber.plant(PersistentTree.create(coroutineScope, File(getExternalFilesDir(null), "logs"))) } catch (e: Exception) { Timber.e(e, "Unable to create PersistentTree") } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt index f95bf64..835bb0d 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt @@ -1,5 +1,6 @@ package com.wbrawner.simplemarkdown +import androidx.annotation.StringRes import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope @@ -22,7 +23,7 @@ data class EditorState( val fileName: String = "Untitled.md", val markdown: String = "", val path: URI? = null, - val toast: String? = null, + val toast: ParameterizedText? = null, val alert: AlertDialogModel? = null, val saveCallback: (() -> Unit)? = null, /** @@ -95,7 +96,7 @@ class MarkdownViewModel( markdown = content, initialMarkdown = content, reloadToggle = currentState.reloadToggle.inv(), - toast = "Successfully loaded $name" + toast = ParameterizedText(R.string.file_loaded) ) preferenceHelper[Preference.AUTOSAVE_URI] = actualLoadPath } ?: throw IllegalStateException("Opened file was null") @@ -103,8 +104,8 @@ class MarkdownViewModel( Timber.e(e, "Failed to open file at path: $actualLoadPath") _state.value = _state.value.copy( alert = AlertDialogModel( - text = "Failed to open file at path: $actualLoadPath", - confirmButton = AlertDialogModel.ButtonModel("OK", onClick = ::dismissAlert) + text = ParameterizedText(R.string.file_load_error), + confirmButton = AlertDialogModel.ButtonModel(ParameterizedText(R.string.ok), onClick = ::dismissAlert) ) ) } @@ -130,20 +131,19 @@ class MarkdownViewModel( fileName = name, path = actualSavePath, initialMarkdown = currentState.markdown, - toast = if (interactive) "Successfully saved $name" else null + toast = if (interactive) ParameterizedText(R.string.file_saved, arrayOf(name)) else null ) Timber.i("Saved file $name to uri $actualSavePath") Timber.i("Persisting autosave uri in shared prefs: $actualSavePath") preferenceHelper[Preference.AUTOSAVE_URI] = actualSavePath true } catch (e: Exception) { - val message = "Failed to save file to $actualSavePath" - Timber.e(e, message) + Timber.e(e, "Failed to save file to $actualSavePath") _state.value = _state.value.copy( alert = AlertDialogModel( - text = message, + text = ParameterizedText(R.string.file_save_error), confirmButton = AlertDialogModel.ButtonModel( - text = "OK", + text = ParameterizedText(R.string.ok), onClick = ::dismissAlert ) ) @@ -189,9 +189,9 @@ class MarkdownViewModel( Timber.i("Resetting view model to default state") if (!force && _state.value.dirty) { _state.value = _state.value.copy(alert = AlertDialogModel( - text = "Would you like to save your changes?", + text = ParameterizedText(R.string.prompt_save_changes), confirmButton = AlertDialogModel.ButtonModel( - text = "Yes", + text = ParameterizedText(R.string.yes), onClick = { _state.value = _state.value.copy( saveCallback = { @@ -201,7 +201,7 @@ class MarkdownViewModel( } ), dismissButton = AlertDialogModel.ButtonModel( - text = "No", + text = ParameterizedText(R.string.no), onClick = { reset(untitledFileName, true) } @@ -231,9 +231,29 @@ class MarkdownViewModel( } data class AlertDialogModel( - val text: String, + val text: ParameterizedText, val confirmButton: ButtonModel, val dismissButton: ButtonModel? = null ) { - data class ButtonModel(val text: String, val onClick: () -> Unit) + data class ButtonModel(val text: ParameterizedText, val onClick: () -> Unit) +} + +data class ParameterizedText(@StringRes val text: Int, val params: Array = arrayOf()) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ParameterizedText + + if (text != other.text) return false + if (!params.contentEquals(other.params)) return false + + return true + } + + override fun hashCode(): Int { + var result = text + result = 31 * result + params.contentHashCode() + return result + } } \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt index 12a47b6..a1cb013 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt @@ -52,15 +52,18 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity import androidx.navigation.NavController import com.wbrawner.simplemarkdown.AlertDialogModel import com.wbrawner.simplemarkdown.EditorState import com.wbrawner.simplemarkdown.MarkdownViewModel +import com.wbrawner.simplemarkdown.ParameterizedText import com.wbrawner.simplemarkdown.R import com.wbrawner.simplemarkdown.Route import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.isActive import kotlinx.coroutines.launch @@ -98,7 +101,7 @@ fun MainScreen( initialMarkdown = initialMarkdown, markdown = markdown, setMarkdown = viewModel::updateMarkdown, - message = toast, + message = toast?.stringRes(), dismissMessage = viewModel::dismissToast, alert = alert, dismissAlert = viewModel::dismissAlert, @@ -181,17 +184,17 @@ private fun MainScreen( onDismissRequest = dismissAlert, confirmButton = { TextButton(onClick = it.confirmButton.onClick) { - Text(it.confirmButton.text) + Text(stringResource(it.confirmButton.text.text)) } }, dismissButton = { it.dismissButton?.let { dismissButton -> TextButton(onClick = dismissButton.onClick) { - Text(dismissButton.text) + Text(dismissButton.text.stringRes()) } } }, - text = { Text(it.text) } + text = { Text(it.text.stringRes()) } ) } val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() @@ -215,28 +218,28 @@ private fun MainScreen( ), null ) }) { - Icon(imageVector = Icons.Default.Share, contentDescription = "Share") + Icon(imageVector = Icons.Default.Share, contentDescription = stringResource(R.string.action_share)) } Box { var menuExpanded by remember { mutableStateOf(false) } IconButton(onClick = { menuExpanded = true }) { - Icon(imageVector = Icons.Default.MoreVert, "Editor Actions") + Icon(imageVector = Icons.Default.MoreVert, stringResource(R.string.action_editor_actions)) } DropdownMenu(expanded = menuExpanded, onDismissRequest = { menuExpanded = false }) { - DropdownMenuItem(text = { Text("New") }, onClick = { + DropdownMenuItem(text = { Text(stringResource(R.string.action_new)) }, onClick = { menuExpanded = false reset() }) - DropdownMenuItem(text = { Text("Open") }, onClick = { + DropdownMenuItem(text = { Text(stringResource(R.string.action_open)) }, onClick = { menuExpanded = false openFileLauncher.launch(arrayOf("text/*")) }) - DropdownMenuItem(text = { Text("Save") }, onClick = { + DropdownMenuItem(text = { Text(stringResource(R.string.action_save)) }, onClick = { menuExpanded = false saveFile(null) }) - DropdownMenuItem(text = { Text("Save as…") }, + DropdownMenuItem(text = { Text(stringResource(R.string.action_save_as )) }, onClick = { menuExpanded = false saveFileLauncher.launch(fileName) @@ -244,7 +247,7 @@ private fun MainScreen( if (!enableWideLayout) { DropdownMenuItem(text = { Row(verticalAlignment = Alignment.CenterVertically) { - Text("Lock Swiping") + Text(stringResource(R.string.action_lock_swipe)) Checkbox( checked = lockSwiping, onCheckedChange = { lockSwiping = !lockSwiping }) @@ -332,10 +335,10 @@ private fun TabbedMarkdownEditor( val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState { 2 } TabRow(selectedTabIndex = pagerState.currentPage) { - Tab(text = { Text("Edit") }, + Tab(text = { Text(stringResource(R.string.action_edit)) }, selected = pagerState.currentPage == 0, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } }) - Tab(text = { Text("Preview") }, + Tab(text = { Text(stringResource(R.string.action_preview)) }, selected = pagerState.currentPage == 1, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } }) } @@ -374,5 +377,7 @@ private fun TabbedMarkdownEditor( @Composable fun

MarkdownViewModel.collectAsState(prop: KProperty1, initial: P): State

= - state.map { prop.get(it) } - .collectAsState(initial) \ No newline at end of file + remember(prop) { state.map { prop.get(it) }.distinctUntilChanged() }.collectAsState(initial) + +@Composable +fun ParameterizedText.stringRes() = stringResource(text, params) \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownInfoScreen.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownInfoScreen.kt index fc4afce..36e1086 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownInfoScreen.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownInfoScreen.kt @@ -31,7 +31,7 @@ fun MarkdownInfoScreen( val context = LocalContext.current val (markdown, setMarkdown) = remember { mutableStateOf("") } LaunchedEffect(file) { - setMarkdown(context.assets.readAssetToString(file) ?: "Failed to load $file") + setMarkdown(context.assets.readAssetToString(file)) } MarkdownText( modifier = Modifier diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownNavigationDrawer.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownNavigationDrawer.kt index 6585f2d..0551b0c 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownNavigationDrawer.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownNavigationDrawer.kt @@ -17,6 +17,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.wbrawner.simplemarkdown.R import com.wbrawner.simplemarkdown.Route @@ -44,7 +45,7 @@ fun MarkdownNavigationDrawer( tint = MaterialTheme.colorScheme.onSurface ) Text( - text = "Simple Markdown", + text = stringResource(R.string.app_name), style = MaterialTheme.typography.titleLarge ) } @@ -56,7 +57,7 @@ fun MarkdownNavigationDrawer( icon = { Icon(imageVector = route.icon, contentDescription = null) }, - label = { Text(route.title) }, + label = { Text(stringResource(route.title)) }, selected = false, onClick = { navigate(route) diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownText.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownText.kt index 82ee9f2..dbdbc61 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownText.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownText.kt @@ -1,5 +1,6 @@ package com.wbrawner.simplemarkdown.ui +import android.annotation.SuppressLint import android.view.ViewGroup import android.webkit.WebView import androidx.compose.foundation.isSystemInDarkTheme @@ -69,6 +70,7 @@ fun MarkdownText(modifier: Modifier = Modifier, markdown: String) { } } +@SuppressLint("SetJavaScriptEnabled") @OptIn(ExperimentalStdlibApi::class) @Composable fun HtmlText(html: String, modifier: Modifier = Modifier) { diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTextField.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTextField.kt index bb36db2..2efdad7 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTextField.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTextField.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextRange @@ -33,6 +34,7 @@ import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp +import com.wbrawner.simplemarkdown.R import com.wbrawner.simplemarkdown.model.Readability @OptIn(ExperimentalMaterial3Api::class) @@ -96,7 +98,7 @@ fun MarkdownTextField( visualTransformation = VisualTransformation.None, innerTextField = innerTextField, placeholder = { - Text("Markdown here…") + Text(stringResource(R.string.markdown_here)) }, singleLine = false, enabled = true, diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTopAppBar.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTopAppBar.kt index 7e8d6d7..126ef92 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTopAppBar.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MarkdownTopAppBar.kt @@ -11,14 +11,14 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarColors -import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults.topAppBarColors import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextOverflow +import com.wbrawner.simplemarkdown.R import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @@ -32,6 +32,7 @@ fun MarkdownTopAppBar( scrollBehavior: TopAppBarScrollBehavior? = null, ) { val coroutineScope = rememberCoroutineScope() + val context = LocalContext.current TopAppBar( title = { Text(text = title, maxLines = 1, overflow = TextOverflow.Ellipsis) @@ -40,10 +41,10 @@ fun MarkdownTopAppBar( navigationIcon = { val (icon, contentDescription, onClick) = remember { if (backAsUp) { - Triple(Icons.AutoMirrored.Filled.ArrowBack, "Go Back", goBack) + Triple(Icons.AutoMirrored.Filled.ArrowBack, context.getString(R.string.action_back), goBack) } else { Triple( - Icons.Default.Menu, "Main Menu" + Icons.Default.Menu, context.getString(R.string.action_menu) ) { coroutineScope.launch { if (drawerState?.isOpen == true) { diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/SettingsScreen.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/SettingsScreen.kt index e612a91..a501a2b 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/SettingsScreen.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/SettingsScreen.kt @@ -26,10 +26,13 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringArrayResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.wbrawner.simplemarkdown.BuildConfig +import com.wbrawner.simplemarkdown.R import com.wbrawner.simplemarkdown.ui.theme.SimpleMarkdownTheme import com.wbrawner.simplemarkdown.utility.Preference import com.wbrawner.simplemarkdown.utility.PreferenceHelper @@ -47,36 +50,36 @@ fun SettingsScreen(navController: NavController, preferenceHelper: PreferenceHel .verticalScroll(rememberScrollState()) ) { BooleanPreference( - title = "Autosave", - enabledDescription = "Files will be saved automatically", - disabledDescription = "Files will not be saved automatically", + title = stringResource(R.string.pref_title_autosave), + enabledDescription = stringResource(R.string.pref_autosave_on), + disabledDescription = stringResource(R.string.pref_autosave_off), preference = Preference.AUTOSAVE_ENABLED, preferenceHelper = preferenceHelper ) ListPreference( - title = "Dark mode", - options = listOf("auto", "dark", "light"), + title = stringResource(R.string.title_dark_mode), + options = stringArrayResource(R.array.pref_values_dark_mode), preference = Preference.DARK_MODE, preferenceHelper = preferenceHelper ) BooleanPreference( - title = "Send crash reports", - enabledDescription = "Error reports will be sent", - disabledDescription = "Error reports will not be sent", + title = stringResource(R.string.pref_title_error_reports), + enabledDescription = stringResource(R.string.pref_error_reports_on), + disabledDescription = stringResource(R.string.pref_error_reports_off), preference = Preference.ERROR_REPORTS_ENABLED, preferenceHelper = preferenceHelper ) BooleanPreference( - title = "Send analytics", - enabledDescription = "Analytics events will be sent", - disabledDescription = "Analytics events will not be sent", + title = stringResource(R.string.pref_title_analytics), + enabledDescription = stringResource(R.string.pref_analytics_on), + disabledDescription = stringResource(R.string.pref_analytics_off), preference = Preference.ANALYTICS_ENABLED, preferenceHelper = preferenceHelper ) BooleanPreference( - title = "Readability highlighting", - enabledDescription = "Readability highlighting is on", - disabledDescription = "Readability highlighting is off", + title = stringResource(R.string.pref_title_readability), + enabledDescription = stringResource(R.string.pref_readability_on), + disabledDescription = stringResource(R.string.pref_readability_off), preference = Preference.READABILITY_ENABLED, preferenceHelper = preferenceHelper ) @@ -90,9 +93,9 @@ fun SettingsScreen(navController: NavController, preferenceHelper: PreferenceHel horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) { Column(verticalArrangement = Arrangement.Center) { - Text(text = "Force a crash", style = MaterialTheme.typography.bodyLarge) + Text(text = stringResource(R.string.action_force_crash), style = MaterialTheme.typography.bodyLarge) Text( - text = "Purposefully crash the app for testing purposes", + text = stringResource(R.string.description_force_crash), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -155,7 +158,7 @@ fun BooleanPreference( @Composable fun ListPreference( title: String, - options: List, + options: Array, preference: Preference, preferenceHelper: PreferenceHelper ) { @@ -171,7 +174,7 @@ fun ListPreference( @Composable fun ListPreference( - title: String, options: List, selected: String, setSelected: (String) -> Unit + title: String, options: Array, selected: String, setSelected: (String) -> Unit ) { var dialogShowing by remember { mutableStateOf(false) } Column(modifier = Modifier @@ -248,7 +251,7 @@ fun ListPreference_Preview() { SimpleMarkdownTheme { Surface { ListPreference( - "Dark mode", listOf("Light", "Dark", "Auto"), selected, setSelected + "Dark mode", arrayOf("Light", "Dark", "Auto"), selected, setSelected ) } } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/SupportScreen.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/SupportScreen.kt index 484d9f5..0a40fcb 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/SupportScreen.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/SupportScreen.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity @@ -39,7 +40,7 @@ import com.wbrawner.simplemarkdown.utility.SupportLinks @Composable fun SupportScreen(navController: NavController) { Scaffold(topBar = { - MarkdownTopAppBar(title = "Support SimpleMarkdown", goBack = { navController.popBackStack() }) + MarkdownTopAppBar(title = stringResource(R.string.support_title), goBack = { navController.popBackStack() }) }) { paddingValues -> val context = LocalContext.current Column( @@ -56,7 +57,7 @@ fun SupportScreen(navController: NavController) { contentDescription = null, tint = MaterialTheme.colorScheme.primary ) - Text(context.getString(R.string.support_info), textAlign = TextAlign.Center) + Text(stringResource(R.string.support_info), textAlign = TextAlign.Center) Spacer(modifier = Modifier.height(8.dp)) Button( modifier = Modifier.fillMaxWidth(), @@ -71,7 +72,7 @@ fun SupportScreen(navController: NavController) { contentColor = Color.White ) ) { - Text(context.getString(R.string.action_view_github)) + Text(stringResource(R.string.action_view_github)) } Button( modifier = Modifier.fillMaxWidth(), @@ -98,7 +99,7 @@ fun SupportScreen(navController: NavController) { contentColor = Color.White ) ) { - Text(context.getString(R.string.action_rate)) + Text(stringResource(R.string.action_rate)) } SupportLinks() } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/utility/Extensions.kt b/app/src/main/java/com/wbrawner/simplemarkdown/utility/Extensions.kt index a3ea912..2b9ba0a 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/utility/Extensions.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/utility/Extensions.kt @@ -10,17 +10,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.Reader -fun View.showKeyboard() { - (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) - .toggleSoftInput(InputMethodManager.SHOW_FORCED, 0) - requestFocus() -} - -fun View.hideKeyboard() = - (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) - .hideSoftInputFromWindow(windowToken, 0) - -suspend fun AssetManager.readAssetToString(asset: String): String? { +suspend fun AssetManager.readAssetToString(asset: String): String { return withContext(Dispatchers.IO) { open(asset).reader().use(Reader::readText) } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/utility/PersistentTree.kt b/app/src/main/java/com/wbrawner/simplemarkdown/utility/PersistentTree.kt index 33fb08f..4b09b65 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/utility/PersistentTree.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/utility/PersistentTree.kt @@ -2,6 +2,7 @@ package com.wbrawner.simplemarkdown.utility import android.util.Log import com.wbrawner.simplemarkdown.utility.PersistentTree.Companion.create +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -18,7 +19,10 @@ import java.util.* * A [Timber.Tree] implementation that persists all logs to disk for retrieval later. Create * instances via [create] instead of calling the constructor directly. */ -class PersistentTree private constructor(private val logFile: File) : Timber.Tree() { +class PersistentTree private constructor( + private val coroutineScope: CoroutineScope, + private val logFile: File +) : Timber.Tree() { private val dateFormat = object : ThreadLocal() { override fun initialValue(): SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US) @@ -26,7 +30,7 @@ class PersistentTree private constructor(private val logFile: File) : Timber.Tre override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { val timestamp = dateFormat.get()!!.format(System.currentTimeMillis()) - GlobalScope.launch(Dispatchers.IO) { + coroutineScope.launch(Dispatchers.IO) { val priorityLetter = when (priority) { Log.ASSERT -> "A" Log.DEBUG -> "D" @@ -63,14 +67,14 @@ class PersistentTree private constructor(private val logFile: File) : Timber.Tre * created/written to */ @Throws(IllegalArgumentException::class, IOException::class) - suspend fun create(logDir: File): PersistentTree = withContext(Dispatchers.IO) { + suspend fun create(coroutineScope: CoroutineScope, logDir: File): PersistentTree = withContext(Dispatchers.IO) { if (!logDir.mkdirs() && !logDir.isDirectory) throw IllegalArgumentException("Unable to create log directory at ${logDir.absolutePath}") val timestamp = SimpleDateFormat("yyyyMMddHHmmss", Locale.US).format(Date()) val logFile = File(logDir, "persistent-log-$timestamp.log") if (!logFile.createNewFile()) throw IOException("Unable to create logFile at ${logFile.absolutePath}") - PersistentTree(logFile) + PersistentTree(coroutineScope, logFile) } } } \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/utility/PreferenceHelper.kt b/app/src/main/java/com/wbrawner/simplemarkdown/utility/PreferenceHelper.kt index bae6b30..747da2f 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/utility/PreferenceHelper.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/utility/PreferenceHelper.kt @@ -23,7 +23,7 @@ interface PreferenceHelper { fun observe(preference: Preference): StateFlow } -class AndroidPreferenceHelper(context: Context, val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)): PreferenceHelper { +class AndroidPreferenceHelper(context: Context, private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)): PreferenceHelper { private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private val states = mapOf( Preference.ANALYTICS_ENABLED to MutableStateFlow(get(Preference.ANALYTICS_ENABLED)), diff --git a/app/src/main/res/drawable-hdpi/splash_fg.png b/app/src/main/res/drawable-hdpi/splash_fg.png deleted file mode 100644 index 6ef4bcb486727aba9098352eb20d0fd5828c1489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7977 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 diff --git a/app/src/main/res/drawable-xxhdpi/splash_fg.png b/app/src/main/res/drawable-xxhdpi/splash_fg.png deleted file mode 100644 index a820e6d26d5e08f87356cb54fdb48753e999ba25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21457 zcmZsCbzIZm_x}b1Mvm?nAs`_Qqf0_mP*FNIkZutK28bY)f9=5ILqcg79Lv$JczrW877CR!)Iy8b5&tJ!Reb>(xhQ@59U_wKWe9A1V&N*wK zH9B9*{ZrVTha-iV86n+U5F9L)_*%}DTtxJmiE>=;a!FJ0SGX?Y+zpVXF37CwU4&oU z{asDyl9`>l2M!MP6^k0!q}MTK;K945J^?{=31namAu@L*u!a=b{}vo0@81+;(ka99 zdl3uyqbdIP37ulm)_lbYr{Qf5Ff?X~f~={)@Mf^4M|hG_s~H3ijp2YUX>r!?+@DPA zpR}q)8-QZqA<>}iH@DO5&A1(r!`nSGKd!|>bo~{;Yu%ai^u@$Cn_+j{qvG(cjY16Qr?@R%+G#x5g}Wp?bS@SiMlxYw9KQ^64NUkS=4J4oC%1j&DlN zn1&F}#j4ipKanf3w@+?BaEf55?reMMe=4Dc5F|P4&B_Bb2vnE#sVE1dH4R?crTt{-HXhc zzI1L~?}l0b?PXr=>h|AWxv*kl$G^=&XuX2DC$1QAi~Q5V5-(@{?};YrVQ2C+`ts?I z|Ea;P`(3*ju-%4WmGiJE>;G+sAUE9NW77EwAppA}{@abWzZUiF?GzzlOdfnn?iE}I z)nSClFm`=R_DTXh?@=4PZdF^154L}!8v}331DPW2X2Tlw_N-__!Ct|c|9v>%e;*c& zTF1L$6aVkxdC7~3X8+raZemmCzs)LTUA5zHqo?~Dfio{%E}uTPYW4o_j)hU*M4tdV zat}J#^;$S)d zGl<*e)7w_9QvX|7G|F4cz2}{#&+6>|*&Bgz!dvCPWvauc07b|93Br)W!T;Id6wJ`4 z4KRT4Se~w(YFG8g|97BG;6P$Li|jU{QHxH)4ga~!6idRE9Fxui2&kFIOBt}D%m1us z7=r6dW)G=PO$0sf0MA7$Niu<P>*J+M@V^7)S+ zKe!OkW}Mz>;3KAJFKQ$QXM;BI{T@r4E#7rD5wuo!93~h5JzkQT9Qjq?^%VC?AhaMS0Hs~&o;q(emVZ*1q z&2kuC>@qd)lS`YIVlN_0;f&&aokN$!#m9u2K?Vi})>E}x&ec;pfXlIT(T^QeTm@~* zoz@xQuiJZhdYTk&h@k{V*QI?wBr>)1)pwKJqBKwbO3;-iT=nLO4#nlfbT4h2zrFE0 zrEi$A_wCv8;0Jo7EoVI%Sa13IV2~_7`BhLQ{+@k?l=X9K3yTTbU=O#=`4n6hE>-y1 z;Iw&(>6WlteGsKE`Q$r2sio3>E)j>xU;g1RYjEgg?v&>!su=MHP1JhF%phVZE5yI# zpIM8?AaLBmu5w*A0RG4mjpIZ<=(xeOp&ONRjACcK=O^srQqxLAn$E zLLPhOq**@NKC1NJIQnb68I)dkIRjfInICU*Ghp}jkMn~evXGO&+W#G$&THbjTCM}} zad7;!=2Su6($Qifu6TTQxVU3)XIFls zXhbZEv;a7`a1?E|Yv|Y6I@#0YgTsVCHJX#Z*9X;eJ{+fk^>z2~B^)a|EY)I!^H%3* zhM2a+t5Oy9jnSimn53&h1Jbq)r0P57pB>D4Cl(*6utQ%dz z!)%e-PZK6DVp0yO{8l^UC4W_Ur#Lt`TzQa6&L3vsqR2}iG9IADZwu96** zrwQFp0{6V}4A|6eEqv@&iL%6(F$VPYlLpQQYTmb>RUN)`>?kiUceA&jziox% z5Zt))u+WLvovC0Qz7RFbyfvLFp32`v)E`x@WaBV^1W1sokllr z4mbE4b5-WLES5WMwRK7*gj2h%=s0pDzDQ5MfA8MCl*B$KOwG|L{bemHk<31LwD#&F zep=>V1FsbLY8V8g7OYN&3_u^5KocAH-_Ql;M$U9NlUEZXJ!Rm&^fl@ zw(x$=*}3Mx#>A^a9GoRzZ0lkfEWgzpmnj-gfja2-*L-xY;_i?Q4um<*JoVFXFl5{a zBAcivs}uW?P{5_7>E-41$n7V5Ehy(5&J+EiywC%eWVO3h<{oEH@@?|vOQs;b{GH3c zyExkzZ6tUy8%iF=W6TG}hx`=!mtFjGq40XOkCou^krcyXsy-*VU>2+I3|xs7-Ny+D z37Bqb{$X!n$0>duuc3x^l+`uMS#VLoPhax3C+*QGP1(XE;~Nr_rqp2B;X}QXuFHxq zo5#i&Ay3)BuWtybxRSay+#D`0Q0P~;`L%Bo~`X~6iC$1P}ktSFZtpWCp^iYa=A9xeAlX#N#{!7tO4kn zs>r=2Ft0S3yW;@Mx@zh(td&%M&cfTCHH){sM&UiXC)0+R8-5e5FzTg; zJYHpbFY7?cv=h^bW6G(q9vUNA((ja(?*BetGQ( zxG!g}V=&kXHB*(Xa*vqsyM$%8`S9RwbmrE6^Cbc66os`n-3C;D(L9ye5CgSEhcAk_ zjsvXxz(^<~xb6n%I^F{N1Z0!i)1w!5)@;@J3{llt$EEfA&wXdV`@H!%rA=yqu4Q4E4mx* zs1of*E_FYQ@~ZzzNkL@G0cm$NFoA*ZJxeApm=^$XCIeF{=STo!6bkoyE@WqCe+6#+ zMy*PU!YzqEcleM)*)KcJh_km>`%{KK4h;qR%xTxw)I9LA>#eMlYkEh;;I3hz!tsgN z+S1bUrD=Kpj@RUCXp}W)ea-H0%$eIy{OwFAyxQJ_uHkusyo-q-Z%wa1zd--Y3obWE zaSq>2L*5Mi?ecf;I4NTS3w)Np$Frm$Pe=PXva(%0EVm9kM~f6j^+%|vlgFT+*r}H| znRM<5My28{s1iYu-lvYCKVGD0`*fcBCUM9tF!f*9luvspNAmCDgk?Dvw?r82WN=Yv zRkDRb0d(HZ;bw} z)dxFL-wTWPwV+50lTI4yM|tSpPkJb}*ZKD)+bT>f)xndSk{1wWPFo9$pZVqRpNlJh zdbseD`dUQeUnOt!hi1F3+UcjRlk|VKr*bL$?Bq{k*fu0X&_HehH_HA{{H-pw{|PAa zmyX=tQ!XupZ6Cso7k-e@etQCam*W?5A_}x^U+vVF0oQu8FJ9|mMP)l0(r(7!`?-Vu z26hfS{Zd$5m&{Y)tdnu<8By98GNu?}8%gD*)V~8^gdO2QfdGC=KHz|mfkm19O(yNG zXE;n=dOk~sFx_PPCbs26E#N}Xebk3NuNWo~W>Jd>96yiYCCzNjc&qf4LkXwrAS{nt zo5PLZj%%{>Av8(RS3wc2W6>*Z4CMpC2L}gkt9I>9x!ygAX8X~^H2rjkF7C~dNBs|# z&+SFc^6fYuU#)Dcnz~)Uzw&NgF<8BwsYX+|ioHkjigHY7lpoF81DqTxrPqxd^HsXgMgRL*a6Nc4^JBC`e-{4U8^jK5DyQn`hB;8MDbnQMgmtDAzE&Cf zV^QAiB(O-ACJ5>fZjY&-8TW%Q?o7gr9)LFBPSsNgo{dE~x`t`PpC!z-?+IJ+_^~1 zO#h+wsM-zG>O5URgIZbvUe(3Gpl`y%Jp9RqP2(-`4?+c)X(Oqk-;L3X%KmC=ledU` zS#o`^*b5lDqDkk0oBGYTOpyD2zS{|_HlxnYLVGDs7J^FCClSX48CfM+IAHV$o1bHN zhZ!Jw+d4Jk&fPH-y#e+o?eszJ<2G7r;R4IzEhhllzrD9Uy7*+{*N@q#OHt&U1K&<= z)wXnhZg#_4w1(z^66kp{n^p)z^*_sfv@k)n}acgo>owT}?Ow-lCG}%_$zE*wjsPhnR_AOYVR02QX zG%oB)5*C*R6Y#aSeDfMQu05ik|&xOrd5LceCxJ+3^#e5d|@86d~o#mg}s_0>xcIiH4KqQ@%OQQ&g{!~-XIivr-&0;^uhG?zkt-R*MSNBcYcc zv9In$6umy=EUA8}r(L=Wu|EAPxVCUh{NabsSqe#rzatfm;OijtZ03&2%!(*Al5J!{ zV9pd&PQQW-L?m4zU0GjMujW1vG@!jh)=`=Qql`sM+qWnN)f+Te6~k=#o%P*36x7$0 zyP_v#41}K50wtay@~l+>vaT1~WwP6zY`(NtztVA&xyxj52k~vL0-__v6gKmcev4r5 zoA9~8&}78v&whetgKy)OtGv0>>BnEnY0j?#9-PNNZKjuXbzo=~sNq<2G`W6V!QL2z zUfH|oedqAHIrg*d!Ms)3okpgpdZy`38j#qtG|+`dZn-Gi`5S(_)k8s}9<6=fN!zHD z6F0rfRI40w$lMzg)u97IPE}*0tHhu$0Pehg-NfWUrp3At*;H&J*Xn*N6IetP)Ii%D z3w!G;7-gs#PE#H`7|J;={bk7XVQ%pt_Mr1`MT)iVmLb_`65%BgR94`Tds)M2e?)5V1jxJEz4W5m}y%eBww!w#&q!UB76owCO4A`aqFF1}L~* zFvbQ*r;uBeM{EGdxg8htpn z!SDrydCS^CiJ!PTe{K)U%w4#}ojW}-RYDF%fCcV|NF041Fr-48xK*#(mo8h0G zt1s7TqH?9=nRJ}UkX~%2PiM2`h>CLOSq%rY;~~?{fe8Wpe_dF<@+@{SXmpnsTF@6r zh>QP{_nE0X1#lCX-Y@Zo{Ue?w{WIIC(+!^>WTabaVI2f7tTpazD6F3&3~DgwNVew9 zy9ufzrxWW5@mJm{&1kcn!WR=q`5K}amMd~~G9S*m`>Itkv@XHUrxBO!XS@$lu}XDj z)x(OcNO%$5-c#~EGv8eo^th6>OF^cIxo(} zb1ynMOSTdh&fCb<_RQfW`i)`d?}|iT&|7wbr%ol4$J@=`%q@HfL%+G8t&AU#tAJg_ z{r#8s?wl^P8i0nGySz7tJgmw(_;f)Hfo`eBA~gzHl|1H}9&E1~@?b%9*< z;Rl8-*NIe7<InaEL0k*S*Y@vqU!% zow6xRz?FoD-sI9+V4w&{^^1$7=hg~uDt5d$8pX(yMT1sr8@UcVc4=3H#kDD@=V0-O zE+VVRN1rZco$3HrV+>&b(BSYlR3kao1$P;B+OjzuFn+m5e7miY;4IJdlE|i6G`33aU33tX|(+ z+aG75KRv!3?${No&5quE#Pig)<6nG+o_Bav z1QzkQ0ucedL#`U-5lG#|9z?Wi^yOPTtdtue-{T-2LeIepYSU_wYO}pMjlrdrl~=N5 zQF^95=K^ouys`clW2|g#ha7a0r#pQ7$kpo3!G~dNYiz5EVv@@@+_i2r^vPP2aVB?e zc&;jHq+Pir8uds}yW8eR{RY*W{|=IVxP^AhKzr^t@Vbk68I+ePlv)VHh!4-mC30z5MCq$1g2zL$5s%L?C{U-;9eFfT_f71g#U9fc=aC9^hvz~sqm&7hT z6WMu29Lmv(2y@MmKY3^MSqPZ}6`#_vl_E-(y>sO1V>yE)fVqr1U}64H*7sui>K{2J zu7hlA#xI?p>itVF1Pc*nu9SL{77RLExhk)jcW0SJG0gqYwrSlK;SsLi!q#}8zqAW` zni}W*GFiUNJ(r^8QhLhw*i`G-LfzeSut56M$WiF8u4(U`u34Sy3-Omg!I}3Tbdv$A zd!4vOM4VNAtXszm7D%D_Q@aZy#uh4-e`y>`%;^t!^Cw@B00_nZumthu#aRaQK~YFA zA!$^}bOt_fTIy1cNq>qS#`f95TL*ZC>UBWmgvETn+(waqX(yzYVQ<89n~t4>!!LKz zXVwcJq&{wRuX9xf_e-_v$4$l{*6vTb#Bb!cn~^PA@@ONRqN&H}5iv(9W$f{R>I z#Dmahnwv$m-j|-?7n^|Sn}y(!w@i5d@!-@lDCnR8u#>FeI-ikjjnD_WBFreIodPMQ zp`*Vrp^1(4!j~KVmHqfBTF$&4!J{Az5_HdvAr+b@#Qsl#16naZKI?hd2KW{=kr6Yp&T$|3wbL+Je z^oq=_+jz`Iw>OIxMPhv6F}lR;3)t$~GfCQRF$e1OzqEt3vVRArn9?sI2J0YWlf>NY zOU2(sz&B{Hy}djF?m5e8DF>20odVA5LFI~{HV)I49sPPWtDG)mGL^h03ZFlJ?wjXJ zVu_2-l>P?$)S}Ly9@w#1*9acwAYfnBd`;JP+m2$`q>dP@?Q<51(mTB{i~Fod!=h{e zs;YKUi^Q+)`0$o^4gzK@muIIHl4M zX{GN5RKEO3*RNPiIqyq`2lbQ8v)uYspBnzEF zr0gjcjS3`mj?DB~x{C$u&2o(dqHM5e8!q-w`6_-3UH*vh*8y)+tFtq!X2KZvm4VEZ zRW|bZ1x@iSr1^&8Vtz{JY!LJ9W9P-J;R8x4(QYk%HO%>Gg}V$e2vBGVp-##EOyBd; z#bk-L|F>D?H2K1zztF_cvt2)Kx}1A61vX-S&dxOT0Y9BJ_>%fe-R#-M|9FVChOpi6 zl9ZGjI^C=trSTs|d1s=EEQc>#VTn+PHp?5|4+~UVb}s@J!bjrt+kDz0-zEv@Fn1k@ zE;NQqN_FX4L7%>Np84g;N2bfD5k~tq;>1mnyIqu%uExK{5B=0J=*J1DN>hqo-n1;L zQ}2_vmGLAJ82d7A7cH;PZBgS^wNDAXk(VxAvbWEfA74-*n}Z;f-mBcdudm-5in~V4 zeyt@2j4{6x_B7W6)f!|^OYT}&F#H(f=frTG-@F#p^VTr%=jY!7P)I*#$w%I@rH*=( zU^@&LjwkrT#^|p>!H7~kFp&44 zQ+xk;-K~9yT=v}PMlPcIkg(j_{&Hek7gZEKcq<_uUns*>k{y!gOCAG%owe*{KQ7PU z)@`P2z)Qz7!PoCd8KKatmle1^vL(QPJ(M4@o1WbA(TSIjfj0+C;!aZbj?d$7D^WSmm$1>c@T{O6g43Ah92T0$gv#r zwZ8K$5lhCzSNd561v15dz8*&3(3+UyD%(^(exLID`?W<1UHme?a^7irK;)?g#Ni@p zcXeRBYvU!;fw7f1AUQ?ilD{{hqCZQM@IS4PH0OFt?aX?V?e5sxs!QZgT&`LyMhSMn zJ~&mUbrH>+RyjD=i>y$Bx&&AzXU}db<$<}qi z4%Lld7h39=!(PqJFQXC*XgIo?VP9HCX7t(ep|w@w&7VI<3$)?93<6MtrUgVTRSXUA zX}8tW8<0?lVZqJW;3(m#lst<2rx8y`n_zLhPAjQkq4ZU`LEgbh!<#<=<^(bqqZ(&U zS%uwQq;S(RTjnncuzE*p3{S14DikTvb4a*r`{TBiG2zB zokicQ04T=6-oAbK>znI=tlLa8>b8K&j&;9G-QRwMJ4`m$E(FAQ7~X{S$fFfBGbsL& zBq<@$(95;eUn|io^IF2zeHGB!d`7>A{Nba)bwlCH6h*~dj8ZHLZ}lQ6rrG_4; z)1jfE@^|$9m>X`L=rG-P3lUh?r*^C{u@)0zj7yJ4TNUhSttI#)PSXH1ToE8S`ZFti zmqYD10$%+3wTRcx&sh;X+}uy^(=q>57V%a@>oCsH(p6U~m`49B#?>x|&^tTI#G~U( zsf?pgMZUK_fu9-2eg813^C?;3`5nNX-PPSm+Su3wzqz`qcU4u3?D-hjLYE6EzOID{ z2L*TqUnE&+e5m3zClMaS^@bkBF=IC0X8mD)-zI?+rD;)VH{A)0C(CNkadieLl;F5w z?az_CRtn=KDeC5)|5A`tM4`ut(^+O#q|vAKyk2mb7?5_7^$l;wPQl%NGm0i6&@ zAw3i*k6_|HcNrt0YKC3`rdECGOm08#obvYT-N+SI@?n|dVb50fv8h7JS~=y42C}4> z-)z%$b6`}C$qFoAiO7l10IqV~WhjG9%DP76`Z9m_fw;JMV(M$DIHTH5VDTF@CRKRc zlBKNq(*uQ_9>OAn*zb35uD|r{i@Ba~$Av^OIuG?uYX&!boMX9lZvD^1FXGXh>+5$b z-GFYeDuL8^Sz3Cl|C^^ZP4~D+RE~~e+eh9+K(Fh`3TR|I5Wxq!$HZ8K9AfPTsTQ6* zd6M6_5ayLZ(+pX}=@d_sM+86-=p_JT@h>fpZGyYKkni?r=fX;K5HB|12t9Hx?jP2; zU5--|N}in0(+$i6OE?W^RuLd`k^iWr^0%X_;;d>fvI6Mh0rf$NhO!aI`^f-sc^GS{ z2&MWF!o&Vv*7VYAKn@;yZT)N|0?Dy^RH0~gcC&FYviVz(CV{3$R76Ks>V9p!p;7Ve z5&le|kXn-OHM4ioF1JLTVwmVC4;_HmjrkMoY|jBHdW^s2;o(8dRSj$arYS~18MC+| z+wPU?TkI(>_FB?uf?$RnS%A%J`YyDE+UmVz+h&TJh(L< ze0-eZ{_&*se0T?dGuL2RB&5!@YajcUrPMyg;JHB5_*wUY?`4*$Jui;+R_WR%Ho<~? zblO3<)!U8DQW+V{tt+AnjI0kg7)fwh;GN9?wA`cZ` zSsX6JU0DDQ0&5J2wAlSbqSce=Vh#h2PO+q zH>#|t2m#Xg4CA^ZY`!#3<1t2yLhT;S{3ka|q%PxEgw)+Tcb+Q&(JZp*eJXvt-sBSK zg8Yti)!&%0+yNl;zX&&v**@h}tAo*DP;DMLaOjn&yn^hM*je1IO|M3nbyrl&_(=X_k2VH|^dr|?+NDomLMrV# zBB2ud#+$UbUzWQ3F}w_XQ_L;6vQ2(n!n6+(fHYjo{!L_ z8n6`TPoU}oZPKn{#3Dzc!%G=)Rs5Jv{Eqe`0wpwJD&{I2U}&atM;fzhv}^DZHIXF0 z?(PC70rHLe91)M{iJD8&zj|+uCC!%#jIp?YsbehZFdiP4sXh_DJi-D6ry7GsEhdAr zK9MmOCvdRjjO*$hduA>uTqG0vFA*no546|R)XV{4q{6=m)-8C!cfUH|xLI;eSdsEz znWs!3S2qHbh#Uj*6B_{W8bi-M|L$Mj;sV+?(&pOCczac{uoKGX(H$w zCxH$Z*xu>d5Uu#J2^_}hsO3UmnAE3 zgfy?5>OJYv`&MQqh>0Jucd)f><>^iF|B2B)xya^VsS9{^G$Jl_woa2ilu3=7P9}1GYzz<5 z-l3r0bfX#+mlA<)@vX~TxiXRs47_)cvLPUbxvBtyL*J-G-%-3`hyc>+mjSLzX>3&U zyNwOw40VHt?T!u{uMhBXvXVPz{8QhD#6P5=l{+PItuZBB`ZqF>w>8c)q$o;p(C*a) zxO@hPTbmQA3y68ON%1-1*Oy-@^EQjKCut@YoXB5`)=zx+ib627w;&~UoWt^uK9J3~ zl}*PRxQk2eW6(W%-tvdsYlgr6c6iHM-o5+UTTs`%pWrst+}^snWJed;jc_@7zrr@h z&Ax&^(x!^-9_Q-6k7fpda1oPtG=>UTQHwX}x zZHv?;fnO<0T@^y6mKBpnci|qhhy}Y@8LNDSo_F6`s}&s8|CDTg>2j|O zbeKhV3P8^M0CLiXuD?^^Ev?*)k%W3|?3yD_YuAT!8rfJ6ImHQixKf;7%2zdtA|+H& zh|=zLdV2av0M(zpy_qw?BZ9NGvJ#IKetqv<39ZJtREUHDZvNGmUoQO~i};y-6$)K< z&6Qdz2|*SeGO;+lqGbiw&x2G3YUP=Pz%h zGRE?!HN9st%B8d{sNz0MYr43&r~+d;{oZ9+EIyEZ$7q63_QaBL?h((s z#vO8&jX!^`^!XrVPP7WAKlH$A00b!$Rf3mn4YKLIcmY6+rL4nfZgh?|wOfQ_?$P!q z_B&13<@|rsc_Z=u@3QArQ>10eJRV&FtCOosP4!a0D(B>{*#c{PsATdE(=sCrvW7Ccuuz?|g zvYZ-I9k6#Fb8}KI;;31sI#4=_-1DOdpkDH6GD>h{jJx?b${-(w>lz}3Qu6jQ(a<(4 zv;wNgmpxD3TcimcMI3bju?9N&?8;xmQ?yBWbMr*1CpC&y`WN>u z6Gpq&Hfd|VAp#de6#W040A{}>O5tO$}8d?<&%Uz^8L@omsHOHyBCQh`Fs zUg5ux!Z@QKb+zQL>R>5eH5P?#DNQWjTRG(^3#n#0LF!jx@lRfQh}*qv8+hKQupSU0`uFqzi`lE68U;M#(d*?G=WadL#xCJ=M4Sxg|RXJ ziBB&i8xzd42fkDbMF-Oz61pjpvO58W1^_x|Q_TBpQS_bv`x5)g_YVro=~@gzh-SdM z8GXs$i!Si8va+74%*9GhFjy^(3$9iyTjm0{^st3~jO&bDp6jarCGUxRynO^9QVUZZ z**}z@38YO2fQe^e^;sDIE>%B6r$g=^a>I34dF6exM754ME6KgK3=M7W(YqFhmiKNd zfpe$uM{j)FNmhu{M6#}PK)N+if@)>q#kn9=S`qxEoX@4%O~3ukL><2#y<+&;Hij5S zTX3!S*)Q`04_^{OW`6PDyns75W0$hR-_!89t3oC=H}3K&{jw%NH@_wIl^WNnW5G%9 z#&k;2;Z^GL_^|8D&aarWN=Z@Cju{GRAm`dA23aMtJuF{wu?_+f`7^6rBf(lJ=T8LM zNWBkgnlAlW2KH5#c14&7&oV216<~9F1r@#J*8zk-TPF>SY^)8CJ#towlHE^avM&0L zet@YX$u%!vzaYy}r%c*zoFxZQyn=oS@x~B8eP2py-h>>`B2|s18RW*shnHK!F9XDn zJ^Fu_b#v^|%b#}Kj@$}#BFl8j9q92P?0FAr3*Kv?4`HV}3Q(5w%D(cW>pf7VvhPZN zE1TA|N1dK559LEwFX{rms&zhpxk~Gwdi2)ZBUe#%c>qFSNbbrS5Ws|A$>CWkIP6nx z?n6ZU{s9kFk=p0GPeD9p6YY$GG`Oaz0>l>Y+yalhGa%D-lU}LliSm?0#3tZR$eGYX z=zmq33Q5%wU4R3<)g8g^j=G=&`x7{19NPGj$<}QM%C~&dX|_D5s82qN20jAj1jQ%? zssT5a*1tuWz1D!m-Ak0I6=s`t@bF4```~D}^(Zr7%UDD{7~ov#69Qj7grg8qejtwS zy&ZmS0v%Ns<31TRuV=2)U>{NRQV7d|vczA8HHlw6?#9{(ift}E=Uz=!(%4x5VN}*M z_d)@EFsU@5?Qmg9YdPr&zAj3 zYw@%k3`r_k&R(YvKW#7HtM>!^!##YeAgwt$ZL~_l0RupFn^3;Lft>H}{4(&J%e?JT z^x?CA=sgGy2V&Qa%mQe$0W~2!Q|#-TuB&vS)PIzhjsp7{n0Elkuz_+ubO1tF6fik; zd89`DfsMHzU;;FS{NbKeDIf1RqNJZ-Ib-d4mW%GzVe{o~ybntUT1U&I!?dd)YM5$L zS7q?>LdkPr_5AyA761)DV7(x_lbzzhM^ zio6yhw)R~}UqM3B^ko^nE77-SsQXKKRwt-?IJ26->748KI{kmJ$i(zLSHBP3MDO3- zsTUnUi^>^jQBfc;Coxc8SyT3B3zTg;-T|pxP7$nV413-VLxt$iDFxoY;Lqm$*d}iN zL0i(%8;1HF)@Rk{@v>U5WwA0YbRW7vj7$LU>FL?fhdGh?ZK6kpeDz`YBco2SqF4Sv zB>)Y%Ie`&MZvm$JT+_x;ATAz>cGK~V8sUxF8xRe&F5N#?*rk22K9Z*n>D+f({Sc<# z{}IK0`X;=5HADeupWm~#Zl(e7;4K33j+0MCG>dTp( zZRbJ6<4`jo{?m=vbUz;$@VEMy{zC=?) zI8&8{j&crvA&mQkgNdh?H!qHG%xW$V>1J*~Qe1a^xquGG$^q-&$}<;}jr{_w33(q~ zzGNYCcDijX`F;>JMwAK@tk}-R^(GFY;~e2R*;$HLCosV<{ zS``&HfN@_6W&vT(XaLf7SeM;vSJm?#OihaNTv|2bUm_)ug5&Agb?SlyKyL}r*SEYXMp?2GV!YV>zV$p`&g&NL*fw54% zeF9>Rp*-#;!lQ0J8ECjagj%?gY_9RPNa5UHd}8|S=VtU!A=M3@;hR=B=Ss{9t|(Uo zS^>a=60>w=5ZixE^-j|O=2LI~-C99R6h{CAOH_QhoF)QZTi!W)9MF>}6eSRg$~Kxw z0x5^~ZZrTWkPlzbDR0Vdp|d`tf)bn|WZ_y-v#IuV?o0wtTEG6h;7Aj_`KhYBe2siQ z=oT{r%FU+axSj+H&z-mOW==7bS^DtmzI^y|ktlu=`Y2;R9|{)?8Hyy^_}1FagQ<2( ze^JcF#zsNn!|LZNjzHw&AD#tPdW>f&hiUp~`kWj7=mL*gcSfFZkvO~;38n37zn=UW zl@u1B^Mhe~PZWBwN&;JKPnT9j&wYdIbFYvYC+-AL4(z2|V#^b_Mg|a81v+C#7TEf^ zEY2%@$vf0m>vpTYfB&AhTX1n&;>B?;AinT@LU^ouU!ZB7_nSOZSl39bdYx#mm^B$R zUay^?jyMTT*q4$6>*SmC(ZjoEb(AAV;ip;_yJk`0uXsAEMou0K-UE0kb!YvK_=Tt? zfz+sa-lXb_)T=_z&b$-Mg3&y121=Wb@KAx%r^UM`3mjk(2t7fev;{2kODx@^_ksHK zNPGDX$)pi88oL#C{!{@2^|>&N&jgygK)tT%wjWvE`bdj=;nz5$YX$O`t>gLtnmP@U9b6uHk*+TWB`=N^un(`?Em(PL|4FynX5wn;GJ z@j?Tcok+;j$ZROfmQUsqf_dwLt38S9<BiD-t>qve zfIg*E6I(&du$QSTO5ohd)(FN%Ii-pTxDJ7`I`}j~$@C89|01&yEjHqVRs$ z5h=w_bPv@tkzHBi+QlhmA=^Ck*_@9r2+FG;66=3&Q(nu}4A1XHolmy}Z3J_w_}Xn3 z>c+M_^v{fjbcJ@U>-~HJ%APC3B=jyztGf&u3Da@OzaIMcLSeGfzO}er+Emf>UX$LV zZE~Lw={3=WqvbOd`!SEz=uL6N1maA;WBj-|c)YV_ffy@$dZN&d;n{~LF( z^_>S3T6e?;Ulc*Yykt?^;o;+I`wJ1fXB_| z#Xr{7X^#2$R7llz?ig}IcMeiU+~~2_pt^EL`NJ>!7uv7o4My=2T_K|ju6^fADf@|r#m*@T4F2sCD$;F{#64vF&mH_nDpYEipK0eg zgAl0W@;vDB%V+M-LGD)%mkGHKMWb%=KW>eIQZ6gh_OGh0KFs;%Q@Ga^=_~bfK1Jb` zifyWQw3WbVJgxvK+fT@Bnx*8C}3N@4i>Ri29gg640JC~e2glq#;Mkook-A!iWXR=F3SLb%n{ zpg=eyr~0GqIqA&hRc3NsGGtY0z=S^V=1vqeVuIlG`aXUWGB#-Xus(Q&Zcw2=>t@+X z_0uFe|8~EhXr9*gh8%|JGXB75)tkTQpXp$ED7lB%0rr01)RYtZ!`Ign%p{>mNJlSU z|21*odHI4Hux3ne;G7{SWfQW_$RV%zc;~O}>Nn=!%D6E96^{(RV&E0c2MO6x#cxcOUkWl48LDpfhB&5hQBu1_HEIF*c2KnLU-46+}e&3}?GcETh9DP31 z{Nbmgw1yL5#gpfEL(V=EmYtXQtlV5l1Ua$sihtJR?KS?`@?Wz5$W}WgpHorWt^-Oj zhI1@>a16fa|0qhweJQPuV?x(0KcQmk<=(uxuh`~6r6q#*y!qf~-LtJnDbDwPh;*zt zD>RzE4^2Zuk?M?HvHhiD|098G{VnjZ)kDXCR+Pz~Q$&n3j;t;w?^V93`#YS>x^zRD zCSGsd*P`2!M>)Ny(0&&j2`im=;agkfFE#4`JaUnw^+KMWyxEtS+@*v&+#)3gyf-ue zJ*JNGnBc$%zJCdYKaGhYds=XbdNXe4h<25=!{e{j>=vb1_&f-Gd#=bYR{2L#drYL0 zK!~Dl`Bs19?0ATx89yutG(yrqsh+T(DpXxJA5f4EjySEqNVUAg4=6K7X zxtn7&{Pb(jUlWu5Dufj4X~X`1yXow00U+~7*)rzoKU^HD(4z2(?iC44l{~?=tDJuy z*jio-p!!-fiC?E2KEJY;dY%;ObgHo+cpF=*5Z<<~ShV&F=Kjt7>72R@D$U1*vGG%@ zg2Kb0#N1vQ-x0os1Ft)hxxCpjKYJH4rMDUc=3NVsVRXVNreWw+`wwEUu}+e^dSaEr zpFLRQwG6Uo#SN*gKV@)b4Dqq486P(T@C8Aj@Uhif1}9(78ZLl2*W}uD?a}hG@s5ER zB?9=)T>ikjWR}tL1#y?;`Xc%e;RFIGmp!7t^s3yu67yq2maMWlcJoi2VbZUU-7;#L zTN5dj@=TuXEZf@-J4JD_d~z6@s`7F*&mvB@(CFhoiQKL>l~i?R5pb$+5j2~)o_5}c z3pOd;;oSG}+HzG>sME8^Z=peXgB(ITw6X_qts@1u1L|#Z7tgzM97~O-Z5ved*viSd z+kYK=?l={{%=qb$B^#Zv(PRioOMl66mIC_3HXQD~zGdaAI$I|$e$c(c=c@X)NpR*v zaub^YD%0(I3TY^rm#n;$i;NY>A__Fe2lI5sVy0E?Tb{vRzVDovm@vvvvH1i}UW~;$ zOIV=`10NVa+cSzbht$JD$57PIaB`v>$!jvP?m?%>_f(M$lH009C3UENkl#<+@*%BY z?4@VheH7?245Hz8jO@RP4lREkDZT$$pjL?xMLefnc4Pi=NLlR4@ocG=P8kEg1Y{G& zJ;UWk7yh8vlYVx_<+L%}yCQZBx)qb^d$xT7GF*U(@Tgl?O0TP?aHO|rLRb`Z>rNEu z3Qq1s45yOJ`~z9ciX~*Z7SWCQfJh7}=lLRD@fZssHdI|sHCE&w1wNiox8_?NZzZI^ z=P*$(P*D>O@^J!~VGJRfKF{9IMbi~b?U_~lp+#)q_#0Y|t$d322L-GR)aVp*JrXYBxG^WPg4>||Yi3*e;@`Qq~@#E%@j zW%!62Z3S6|L}r#pD-bd}x~`=pYdY3@i;u2I=N@gD`ltO?O0S~E*2z@ni-y!kG@glG zmyszKwzDroIR0XI%=q6ra!9Lx*(L|#ub)3266K!**-MpD>E1$y%XwCkXDg?x8*lkH z1_!p8(_<+`)d9SL^pL4+Dn8CK-vWL2V*lnP`X4|vGa2!@?QJXQxw^zGa}!87#?6{$ zGObvBZB@Q%(Jy4JkalvLtrQ@Y;z`tV=X z{G+$4Q8BFpWwR02U5TAi4i!*X!a zeK2oz8rMLcZe7}vXVOL!FPk)u>hqEPwRUztCSR>ifxxWQM=7h67>O=iu=7U4Twe_y7BWl@ z?|FO$*mWoJxu4)J^Wxm^lkv-0+3RICN#hJ-6x-A=Yd=SD1gEh*V_ZrJdE60F*>RX{ zq-*TO4X?;&kv4(Gi$Y+>l;oa$qH-cj;+z8E^;iLGj@{SSha($ZoS6K1GhdoGNBwmu zFNd8yZYKUh# zBs83KfTy)gLjHnM{rEc}7{uZ)9NqG2#WH;HZeWqz>h)FPYjlz4W4q&T$L&8wy+L#p zkj{(*%RE&F^FN;mf3L%%1$HoSC8^@SyFg{L$UgQ$Cu5=Hyowh7Dvy)-)YUxQ&I-Mu zgG2$SMaW%y>f%Z}-q#z$hor*lP9pXF+~Nch7MsBn77mtSw7d7F136i_3IVjpq(}8t zrDmVnQY52brSF1-47>|vhDZt>9;-ait(9V(7m_z&j9$ob~xPC zTREWdpyta?YkSvx4reoem-p;=otM}FF)?*&sT;o||LD$Xdi|#ZIqmt;{IC;t@S$Ku z3fds_OT&@=KyB-{6X!+m*UE`{xgpo5CbLipckF;=uuB6q$xekS$McWKq_UckrUE=(6#P#{k%bo}yqt@fJ)a?Rg7To}ooeZ6{x_If- zXkB%6Y6$zLk!UV6S4S`=CUSq%(KNLjMWXaZotepW5yD5R$My zRKiymeV8iky`#vxll$T5?RP1{(s|Ur*EU8r_qf zd0_VIRthGlPWmr?iYd&Q310Gu?Vr)UGLrRT9rrxrO<{z(B^I^l6f^BVWIT;p5sc#tW z(6^?2x@Jz?Kge98HHIHeqAsky$;5ir$ZLqIY-{){b0qWrR6-H-BLk{xYUGGky_+Ft zFN6ylYBEMVm}KrF!jx}(x#n3Tqo%KHkHk*v=3pOnEd@-Se=Jz~wC(ipss}hwS36l! zB~!6<|CgtK(9sU2`IK0ap*+(4-_FG8I03mCESEAKQ7FJ%<^iyPxg$#oakP?`OBEyj z!oLRfKCc61$%K$%5HVOeEUKv&FYmG%a*CH$U(lio}%giCHHlLX#vza2EI z<1*70;Ws~g(?FLimLzg95lV->{cwE7+XFc)Wl7fn5R2;aa*3{+Qa!im>zn0GrzxnH z^%s7;!Ts|zYTqSx-3t3ENqBC^Vdg5+TYEc0?cC#c6>}9UMe_D(q9*)G5@k0g z8sOvy!JMBWmA=m?oJnt2@JWKEyy{MThKE+jF@v~v7%!S&RhCjXm4vnMH$(%E9dI3U znvAw&ZT~tgY<{RS@HxlU2giU`(7)lKkBU7pd2a9zmlM)6aZ4=JKdl)abYr?gz zX?zpBV^j6;;XXb%jE_Fe`OT5ph7BSHxE=nD0-J))y1xEI9=~k-b&C^C&@+M_u^?lY zZ6KuQMeMS(D7B)ns zjLRZ@0q8Crw&)s^xe>hwJ&U*lJp^}Xj={XB{eDd0J;c|Kl##g>cD!cbH!c$U6oPx|TKaYXYMH~s-n6OoiZSUE1U zmrT2>Z!s-M$g%4pKn{{a^-EabITF-D&Hl09w2DRXd-ft{T7^}<4Y(kGe9b*uC$JMq z`WZnnf-DZ)Jt@it(zjq-#H`4}AM(K{{(hZ;*jWgjUSUI3k#G^ex99c(Q(kDCWc_EP z0PL3WZ?d4g06a)N#j%0A@B$p^vX?I!=?h?k_Ck~^0H8+F++ziDr8tg>>LSbq4S~bt z9FTprk)!Ptz^}s!y4g_{r3Uzl9}S_GuG2}ZltCKdl(cEyVrBy){0kfk6J2iHt$vd* zB?{?1+gsg~1U>9-+4p?g<4p1{S8<1p6Q9orui&1;R!*W=B?3!>apQec_IW1@Nb@$7 zWCr3-t~r>l)!WB&^-&@9;i diff --git a/app/src/main/res/drawable-xxxhdpi/splash_fg.png b/app/src/main/res/drawable-xxxhdpi/splash_fg.png deleted file mode 100644 index abf977315b6b5be3543c4510b7e43b455e0b238b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27668 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 diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml deleted file mode 100644 index 0a4164e..0000000 --- a/app/src/main/res/values-night/colors.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - #000000 - #FFFFFF - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index afeaf77..8277eaa 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,8 +4,6 @@ #b71c1c #d32f2f #FFFFFF - #000000 #24292e - #FFFFFFFF #689f38 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index 59a0b0c..0000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,3 +0,0 @@ - - 16dp - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 603f757..3ab3f56 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,65 +2,52 @@ Simple Markdown Markdown - Settings - Help + Editor + Settings + Help + About Edit Preview - + OK Markdown here… Save + Editor Actions Share - Export - Unable to share file - no capable apps installed Share file to… - Unable to save file without permissions Successfully saved %1$s - Load - Select a file to open - No file browser apps found An error occurred while saving the file File successfully loaded - An error occurred while writing the file An error occurred while opening the file - Libraries + Back + Main Menu New - Done Open Yes No - Settings Enable autosave - Automatically save files when closing the app Lock Swiping - Select Privacy - crashlytics.enable Enable automated error reports Error reports will not be sent Error reports will be sent - readability.enable + Send analytics + Analytics events will not be sent + Analytics events will be sent + Force a crash + Purposefully crash the app for testing purposes Enable readability highlighting (experimental) Readability highlighting is off Readability highlighting is on Files will be automatically saved Files will not be automatically saved - pref.custom_css - Custom CSS - Paste or write your own CSS to be used for the preview pane - pre {overflow:scroll; padding:15px; background: #F1F1F1;} - body{background: - #000000;color: #F1F1F1;}a{color:#7b91ff;}pre{background:#111111;} - darkMode Dark Mode Light Dark - Auto + light dark auto - Save Changes Would you like to save your changes? - Discard Save as… SimpleMarkdown is a personal project of mine that I develop and maintain in my free time. I very much appreciate any and all forms of support, whether @@ -73,12 +60,11 @@ View SimpleMarkdown on GitHub Support SimpleMarkdown Rate SimpleMarkdown - Heart - - @string/pref_value_light - @string/pref_value_dark - @string/pref_value_auto - + + + + + @string/pref_key_dark_mode_light @string/pref_key_dark_mode_dark diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 46113d5..bdf55b5 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,6 +47,9 @@ android { kotlinOptions { jvmTarget = "1.8" } + lint { + warningsAsErrors = true + } } dependencies { diff --git a/free/build.gradle.kts b/free/build.gradle.kts index fa1de8c..82c9ede 100644 --- a/free/build.gradle.kts +++ b/free/build.gradle.kts @@ -33,6 +33,9 @@ android { kotlinOptions { jvmTarget = "1.8" } + lint { + warningsAsErrors = true + } } dependencies { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1fe08d6..74dd6ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] acra = "5.11.3" -activityKtx = "1.9.0" +activityKtx = "1.9.1" animationCore = "1.6.8" appcompat = "1.7.0" billing = "7.0.0" @@ -20,7 +20,7 @@ androidGradlePlugin = "8.5.1" hamcrestCore = "1.3" junit = "4.13.2" kotlin = "2.0.0" -lifecycleViewmodelKtx = "2.8.3" +lifecycleViewmodelKtx = "2.8.4" material = "1.12.0" material3WindowSizeClassAndroid = "1.2.1" materialIconsCore = "1.6.8" diff --git a/non-free/build.gradle.kts b/non-free/build.gradle.kts index 04c916e..0eca8ae 100644 --- a/non-free/build.gradle.kts +++ b/non-free/build.gradle.kts @@ -33,6 +33,9 @@ android { kotlinOptions { jvmTarget = "1.8" } + lint { + warningsAsErrors = true + } } dependencies { -- 2.45.2 From c6e14d7d0b1be085ae64f817e150ee66abcfe5ea Mon Sep 17 00:00:00 2001 From: William Brawner Date: Wed, 31 Jul 2024 20:52:38 -0600 Subject: [PATCH 2/6] Setup Android SDK for UI test workflow job --- .forgejo/workflows/pull_request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.forgejo/workflows/pull_request.yml b/.forgejo/workflows/pull_request.yml index 7299bee..c383d40 100644 --- a/.forgejo/workflows/pull_request.yml +++ b/.forgejo/workflows/pull_request.yml @@ -59,6 +59,8 @@ jobs: uses: https://git.wbrawner.com/gradle/gradle-build-action@v2 with: arguments: assemblePlayDebug assemblePlayDebugAndroidTest + - name: Setup Android SDK + uses: https://git.wbrawner.com/android-actions/setup-android@v3 - name: Grant execute permission for flank_auth.sh run: chmod +x flank_auth.sh - name: Add auth for flank -- 2.45.2 From 262b63cfa0fc248683ae4c8c70412c29cddd416a Mon Sep 17 00:00:00 2001 From: William Brawner Date: Wed, 31 Jul 2024 20:58:33 -0600 Subject: [PATCH 3/6] Setup Android SDK before attempting to build in UI test job --- .forgejo/workflows/pull_request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/pull_request.yml b/.forgejo/workflows/pull_request.yml index c383d40..87cb19f 100644 --- a/.forgejo/workflows/pull_request.yml +++ b/.forgejo/workflows/pull_request.yml @@ -55,12 +55,12 @@ jobs: with: distribution: 'zulu' java-version: '17' + - name: Setup Android SDK + uses: https://git.wbrawner.com/android-actions/setup-android@v3 - name: Build with Gradle uses: https://git.wbrawner.com/gradle/gradle-build-action@v2 with: arguments: assemblePlayDebug assemblePlayDebugAndroidTest - - name: Setup Android SDK - uses: https://git.wbrawner.com/android-actions/setup-android@v3 - name: Grant execute permission for flank_auth.sh run: chmod +x flank_auth.sh - name: Add auth for flank -- 2.45.2 From b0e8ebbf718d4c277c820bff879c9b285b82bc4a Mon Sep 17 00:00:00 2001 From: William Brawner Date: Thu, 1 Aug 2024 18:47:12 -0600 Subject: [PATCH 4/6] Fix failing UI tests --- .../wbrawner/simplemarkdown/MarkdownTests.kt | 44 +++++++++++++------ .../simplemarkdown/MarkdownViewModel.kt | 2 +- .../wbrawner/simplemarkdown/ui/MainScreen.kt | 2 +- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt b/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt index 261f968..6aba4f9 100644 --- a/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt +++ b/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt @@ -6,13 +6,10 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.webkit.WebView -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.input.key.KeyEvent -import androidx.compose.ui.input.key.NativeKeyEvent import androidx.compose.ui.semantics.SemanticsProperties import androidx.compose.ui.semantics.getOrNull -import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.SemanticsMatcher +import androidx.compose.ui.test.SemanticsNodeInteraction import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsNotDisplayed @@ -27,13 +24,8 @@ import androidx.compose.ui.test.junit4.createEmptyComposeRule import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performKeyInput -import androidx.compose.ui.test.performKeyPress -import androidx.compose.ui.test.performTextInput -import androidx.compose.ui.test.performTextInputSelection import androidx.compose.ui.test.performTextReplacement import androidx.compose.ui.test.printToLog -import androidx.compose.ui.text.TextRange import androidx.core.content.FileProvider import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider.getApplicationContext @@ -233,7 +225,7 @@ class MarkdownTests { private fun ComposeTestRule.checkTitleEquals(title: String) = onNode(hasAnySibling(hasContentDescription("Main Menu")).and(hasText(title))) - .assertIsDisplayed() + .waitUntilIsDisplayed() private fun ComposeTestRule.typeMarkdown(markdown: String) = onNode(hasSetTextAction()).performTextReplacement(markdown) @@ -258,12 +250,38 @@ class MarkdownTests { private fun ComposeTestRule.clickSaveMenuItem() = onNodeWithText("Save").performClick() private fun ComposeTestRule.verifyDialogIsShown(text: String) = - onNode(isDialog().and(hasAnyDescendant(hasText(text)))).assertIsDisplayed() + onNode(isDialog().and(hasAnyDescendant(hasText(text)))).waitUntilIsDisplayed() - private fun ComposeTestRule.verifyDialogIsNotShown() = onNode(isDialog()).assertIsNotDisplayed() + private fun ComposeTestRule.verifyDialogIsNotShown() = + onNode(isDialog()).waitUntilIsNotDisplayed() private fun ComposeTestRule.discardChanges() = onNodeWithText("No").performClick() private fun ComposeTestRule.verifyTextIsShown(text: String) = - onNodeWithText(text).assertIsDisplayed() + onNodeWithText(text).waitUntilIsDisplayed() + + private val ASSERTION_TIMEOUT = 5_000L + + private fun SemanticsNodeInteraction.waitUntil(assertion: SemanticsNodeInteraction.() -> Unit) { + val start = System.currentTimeMillis() + lateinit var assertionError: AssertionError + while (System.currentTimeMillis() - start < ASSERTION_TIMEOUT) { + try { + assertion() + return + } catch (e: AssertionError) { + assertionError = e + Thread.sleep(10) + } + } + throw assertionError + } + + private fun SemanticsNodeInteraction.waitUntilIsDisplayed() = waitUntil { + assertIsDisplayed() + } + + private fun SemanticsNodeInteraction.waitUntilIsNotDisplayed() = waitUntil { + assertIsNotDisplayed() + } } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt index 835bb0d..ee6fb09 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt @@ -96,7 +96,7 @@ class MarkdownViewModel( markdown = content, initialMarkdown = content, reloadToggle = currentState.reloadToggle.inv(), - toast = ParameterizedText(R.string.file_loaded) + toast = ParameterizedText(R.string.file_loaded, arrayOf(name)) ) preferenceHelper[Preference.AUTOSAVE_URI] = actualLoadPath } ?: throw IllegalStateException("Opened file was null") diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt index a1cb013..62a39d0 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/ui/MainScreen.kt @@ -380,4 +380,4 @@ fun

MarkdownViewModel.collectAsState(prop: KProperty1, initi remember(prop) { state.map { prop.get(it) }.distinctUntilChanged() }.collectAsState(initial) @Composable -fun ParameterizedText.stringRes() = stringResource(text, params) \ No newline at end of file +fun ParameterizedText.stringRes() = stringResource(text, *params) \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3ab3f56..b8fd010 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,7 +16,7 @@ Share file to… Successfully saved %1$s An error occurred while saving the file - File successfully loaded + Successfully loaded %1$s An error occurred while opening the file Back Main Menu -- 2.45.2 From 840ebc4fd13d4993a2004bf59b67596fde1c4733 Mon Sep 17 00:00:00 2001 From: William Brawner Date: Fri, 2 Aug 2024 16:11:51 -0600 Subject: [PATCH 5/6] Fix failing UI test --- .../kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt | 4 +++- .../java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt b/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt index 6aba4f9..a3876b7 100644 --- a/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt +++ b/app/src/androidTest/kotlin/com/wbrawner/simplemarkdown/MarkdownTests.kt @@ -235,7 +235,9 @@ class MarkdownTests { val markdownMatcher = SemanticsMatcher("Markdown = [$markdown]") { it.config.getOrNull(SemanticsProperties.EditableText)?.text == markdown } - onNode(hasSetTextAction()).assert(markdownMatcher) + onNode(hasSetTextAction()).waitUntil { + assert(markdownMatcher) + } } private fun ComposeTestRule.openPreview() = onNodeWithText("Preview").performClick() diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt index ee6fb09..c2d0955 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.kt @@ -209,7 +209,8 @@ class MarkdownViewModel( )) return } - _state.value = EditorState(fileName = untitledFileName) + _state.value = + EditorState(fileName = untitledFileName, reloadToggle = _state.value.reloadToggle.inv()) Timber.i("Removing autosave uri from shared prefs") preferenceHelper[Preference.AUTOSAVE_URI] = null } -- 2.45.2 From 79a5a3809ae1ccfc061768e0cf117f471d843d48 Mon Sep 17 00:00:00 2001 From: William Brawner Date: Fri, 2 Aug 2024 16:46:03 -0600 Subject: [PATCH 6/6] Fix failing unit tests --- .../com/wbrawner/simplemarkdown/MarkdownViewModelTest.kt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/src/test/java/com/wbrawner/simplemarkdown/MarkdownViewModelTest.kt b/app/src/test/java/com/wbrawner/simplemarkdown/MarkdownViewModelTest.kt index dc31c6b..44fe955 100644 --- a/app/src/test/java/com/wbrawner/simplemarkdown/MarkdownViewModelTest.kt +++ b/app/src/test/java/com/wbrawner/simplemarkdown/MarkdownViewModelTest.kt @@ -5,14 +5,11 @@ import androidx.lifecycle.viewmodel.CreationExtras import com.wbrawner.simplemarkdown.utility.Preference import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.TestResult import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.advanceUntilIdle -import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain import org.junit.Assert.assertEquals @@ -25,8 +22,6 @@ import org.junit.Test import timber.log.Timber import java.io.File import java.net.URI -import java.util.Deque -import java.util.concurrent.ConcurrentLinkedDeque class MarkdownViewModelTest { private lateinit var fileHelper: FakeFileHelper @@ -185,7 +180,7 @@ class MarkdownViewModelTest { requireNotNull(onClick) onClick.invoke() } - assertEquals(viewModel.state.value, EditorState()) + assertEquals(viewModel.state.value, EditorState(reloadToggle = 0.inv())) } @Test @@ -204,7 +199,7 @@ class MarkdownViewModelTest { viewModel.save(uri) assertNotNull(viewModel.state.value.saveCallback) requireNotNull(viewModel.state.value.saveCallback).invoke() - assertEquals(viewModel.state.value, EditorState()) + assertEquals(viewModel.state.value, EditorState(reloadToggle = 0.inv())) } @Test -- 2.45.2