🚀 Add "Press back twice to exit" option
Added "Press back twice to exit the app" option. When true, to exit the app you need to press back twice (which may prevent unwanted exit).
This commit is contained in:
parent
fe77f7bf0c
commit
39f2f3e87e
9 changed files with 99 additions and 10 deletions
|
|
@ -14,6 +14,7 @@ object DataStoreConstants {
|
|||
val THEME_CONTRAST = stringPreferencesKey("theme_contrast")
|
||||
val SHOW_START_SCREEN = booleanPreferencesKey("guide")
|
||||
val CHECK_FOR_UPDATES = booleanPreferencesKey("check_for_updates")
|
||||
val DOUBLE_PRESS_EXIT = booleanPreferencesKey("double_press_exit")
|
||||
|
||||
// Reader settings
|
||||
val DOUBLE_CLICK_TRANSLATION = booleanPreferencesKey("double_click_translation")
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ sealed class MainEvent {
|
|||
data class OnChangeBrowseSortOrderDescending(val bool: Boolean) : MainEvent()
|
||||
data class OnChangeBrowseIncludedFilterItem(val item: String) : MainEvent()
|
||||
data class OnChangeTextAlignment(val alignment: String) : MainEvent()
|
||||
data class OnChangeDoublePressExit(val bool: Boolean) : MainEvent()
|
||||
}
|
||||
|
|
@ -36,22 +36,29 @@ import java.util.Locale
|
|||
@Keep
|
||||
@Parcelize
|
||||
data class MainState(
|
||||
// General Settings
|
||||
val language: String? = null,
|
||||
val theme: Theme? = null,
|
||||
val darkTheme: DarkTheme? = null,
|
||||
val pureDark: PureDark? = null,
|
||||
val themeContrast: ThemeContrast? = null,
|
||||
val showStartScreen: Boolean? = null,
|
||||
val checkForUpdates: Boolean? = null,
|
||||
val doublePressExit: Boolean? = null,
|
||||
|
||||
// Reader Settings
|
||||
val fontFamily: String? = null,
|
||||
val isItalic: Boolean? = null,
|
||||
val fontSize: Int? = null,
|
||||
val lineHeight: Int? = null,
|
||||
val paragraphHeight: Int? = null,
|
||||
val paragraphIndentation: Boolean? = null,
|
||||
val showStartScreen: Boolean? = null,
|
||||
val checkForUpdates: Boolean? = null,
|
||||
val sidePadding: Int? = null,
|
||||
val doubleClickTranslation: Boolean? = null,
|
||||
val fastColorPresetChange: Boolean? = null,
|
||||
val textAlignment: ReaderTextAlignment? = null,
|
||||
|
||||
// Browse Settings
|
||||
val browseFilesStructure: BrowseFilesStructure? = null,
|
||||
val browseLayout: BrowseLayout? = null,
|
||||
val browseAutoGridSize: Boolean? = null,
|
||||
|
|
@ -60,7 +67,6 @@ data class MainState(
|
|||
val browseSortOrder: BrowseSortOrder? = null,
|
||||
val browseSortOrderDescending: Boolean? = null,
|
||||
val browseIncludedFilterItems: List<String>? = null,
|
||||
val textAlignment: ReaderTextAlignment? = null,
|
||||
) : Parcelable {
|
||||
companion object {
|
||||
/**
|
||||
|
|
@ -157,6 +163,9 @@ data class MainState(
|
|||
val textAlignment = data[TEXT_ALIGNMENT.name] as? String
|
||||
?: ReaderTextAlignment.START.name
|
||||
|
||||
val doublePressExit = data[DOUBLE_PRESS_EXIT.name] as? Boolean
|
||||
?: false
|
||||
|
||||
return MainState(
|
||||
language = language,
|
||||
theme = theme.toTheme(),
|
||||
|
|
@ -182,7 +191,8 @@ data class MainState(
|
|||
browseSortOrder = browseSortOrder.toBrowseSortOrder(),
|
||||
browseSortOrderDescending = browseSortOrderDescending,
|
||||
browseIncludedFilterItems = browseIncludedFilterItems,
|
||||
textAlignment = textAlignment.toTextAlignment()
|
||||
textAlignment = textAlignment.toTextAlignment(),
|
||||
doublePressExit = doublePressExit
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,6 +345,20 @@ class MainViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
is MainEvent.OnChangeDoublePressExit -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
setDatastore.execute(
|
||||
DataStoreConstants.DOUBLE_PRESS_EXIT,
|
||||
event.bool
|
||||
)
|
||||
updateStateWithSavedHandle {
|
||||
it.copy(
|
||||
doublePressExit = event.bool
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -54,6 +55,8 @@ import ua.acclorite.book_story.presentation.components.customItems
|
|||
import ua.acclorite.book_story.presentation.components.header
|
||||
import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||
|
|
@ -73,10 +76,12 @@ import ua.acclorite.book_story.presentation.ui.Transitions
|
|||
fun LibraryScreenRoot() {
|
||||
val navigator = LocalNavigator.current
|
||||
val viewModel: LibraryViewModel = hiltViewModel()
|
||||
val mainViewModel: MainViewModel = hiltViewModel()
|
||||
val browseViewModel: BrowseViewModel = hiltViewModel()
|
||||
val historyViewModel: HistoryViewModel = hiltViewModel()
|
||||
|
||||
val state = viewModel.state.collectAsState()
|
||||
val mainState = mainViewModel.state.collectAsState()
|
||||
|
||||
val pagerState = rememberPagerState(
|
||||
initialPage = state.value.currentPage,
|
||||
|
|
@ -100,6 +105,7 @@ fun LibraryScreenRoot() {
|
|||
|
||||
LibraryScreen(
|
||||
state = state,
|
||||
mainState = mainState,
|
||||
onNavigate = { navigator.it() },
|
||||
pagerState = pagerState,
|
||||
refreshState = refreshState,
|
||||
|
|
@ -113,6 +119,7 @@ fun LibraryScreenRoot() {
|
|||
@Composable
|
||||
private fun LibraryScreen(
|
||||
state: State<LibraryState>,
|
||||
mainState: State<MainState>,
|
||||
onNavigate: OnNavigate,
|
||||
pagerState: PagerState,
|
||||
refreshState: PullRefreshState,
|
||||
|
|
@ -264,7 +271,7 @@ private fun LibraryScreen(
|
|||
|
||||
val activity = LocalContext.current as ComponentActivity
|
||||
val scope = rememberCoroutineScope()
|
||||
var shouldExit = remember { false }
|
||||
var shouldExit = rememberSaveable { false }
|
||||
BackHandler {
|
||||
if (state.value.hasSelectedItems) {
|
||||
onEvent(LibraryEvent.OnClearSelectedBooks)
|
||||
|
|
@ -281,7 +288,7 @@ private fun LibraryScreen(
|
|||
return@BackHandler
|
||||
}
|
||||
|
||||
if (shouldExit) {
|
||||
if (shouldExit || !mainState.value.doublePressExit!!) {
|
||||
activity.finish()
|
||||
return@BackHandler
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import ua.acclorite.book_story.presentation.data.MainState
|
|||
import ua.acclorite.book_story.presentation.screens.settings.data.SettingsEvent
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.general.components.settings.AppLanguageSetting
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.general.components.settings.CheckForUpdatesSetting
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.general.components.settings.DoublePressExitSetting
|
||||
|
||||
/**
|
||||
* General Settings Category.
|
||||
|
|
@ -56,6 +57,13 @@ fun LazyListScope.GeneralSettingsCategory(
|
|||
)
|
||||
}
|
||||
|
||||
item {
|
||||
DoublePressExitSetting(
|
||||
state = state,
|
||||
onMainEvent = onMainEvent
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package ua.acclorite.book_story.presentation.screens.settings.nested.general.components.settings
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SwitchWithTitle
|
||||
|
||||
/**
|
||||
* Double Press Exit setting.
|
||||
* If true, to close the app you need to press back twice.
|
||||
*/
|
||||
@SuppressLint("InlinedApi")
|
||||
@Composable
|
||||
fun LazyItemScope.DoublePressExitSetting(
|
||||
state: State<MainState>,
|
||||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.doublePressExit!!,
|
||||
modifier = Modifier.animateItem(),
|
||||
title = stringResource(id = R.string.double_press_exit_option),
|
||||
description = stringResource(id = R.string.double_press_exit_option_desc)
|
||||
) {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeDoublePressExit(!state.value.doublePressExit!!)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -211,11 +211,18 @@
|
|||
<string name="sort_browse_settings">Сотрування</string>
|
||||
|
||||
<!-- Settings options -->
|
||||
<!-- General -->
|
||||
<string name="language_option">Мова застосунка</string>
|
||||
<string name="dark_theme_option">Темна тема</string>
|
||||
<string name="pure_dark_option">Суцільна темрява (ОЛЕД)</string>
|
||||
<string name="theme_contrast_option">Контрастність теми</string>
|
||||
<string name="app_theme_option">Тема застосунка</string>
|
||||
<string name="check_for_updates_option">Перевіряти на оновлення</string>
|
||||
<string name="check_for_updates_option_desc">Перевіряти на новішу версію застосунку при запуску</string>
|
||||
<string name="double_press_exit_option">Подвійне натискання для виходу</string>
|
||||
<string name="double_press_exit_option_desc">Натисніть назад двічі, щоб вийти з застосунку</string>
|
||||
|
||||
<!-- Reader -->
|
||||
<string name="font_family_option">Сімейство шрифтів</string>
|
||||
<string name="font_style_option">Стиль шрифта</string>
|
||||
<string name="font_size_option">Розмір шрифта</string>
|
||||
|
|
@ -225,14 +232,14 @@
|
|||
<string name="color_preset_option">Пресет кольорів</string>
|
||||
<string name="background_color_option">Колір фона</string>
|
||||
<string name="font_color_option">Колір шрифта</string>
|
||||
<string name="check_for_updates_option">Перевіряти на оновлення</string>
|
||||
<string name="check_for_updates_option_desc">Перевіряти на новішу версію застосунку при запуску</string>
|
||||
<string name="side_padding_option">Бокові відступи</string>
|
||||
<string name="double_click_translation_option">Переклад подвійним кліком</string>
|
||||
<string name="double_click_translation_option_desc">Двічі клацніть на абзац, щоб перекласти його</string>
|
||||
<string name="fast_color_preset_change_option">Швидка зміна пресета кольорів</string>
|
||||
<string name="fast_color_preset_change_option_desc">Проведіть вліво або вправо, щоб змінити пресет кольорів</string>
|
||||
<string name="text_alignment_option">Розташування текста</string>
|
||||
|
||||
<!-- Browse -->
|
||||
<string name="browse_files_structure_option">Структура файлів</string>
|
||||
<string name="browse_layout_option">Режим відображення</string>
|
||||
<string name="browse_grid_size_option">Кількість комірок</string>
|
||||
|
|
|
|||
|
|
@ -230,11 +230,18 @@
|
|||
<string name="sort_browse_settings">Sort</string>
|
||||
|
||||
<!-- Settings options -->
|
||||
<!-- General -->
|
||||
<string name="language_option">App language</string>
|
||||
<string name="dark_theme_option">Dark theme</string>
|
||||
<string name="pure_dark_option">Pure dark (OLED)</string>
|
||||
<string name="theme_contrast_option">Theme contrast</string>
|
||||
<string name="app_theme_option">App theme</string>
|
||||
<string name="check_for_updates_option">Check for updates</string>
|
||||
<string name="check_for_updates_option_desc">Check for newer app version on startup</string>
|
||||
<string name="double_press_exit_option">Double back press to exit</string>
|
||||
<string name="double_press_exit_option_desc">Press back twice to exit the app</string>
|
||||
|
||||
<!-- Reader -->
|
||||
<string name="font_family_option">Font family</string>
|
||||
<string name="font_style_option">Font style</string>
|
||||
<string name="font_size_option">Font size</string>
|
||||
|
|
@ -244,14 +251,14 @@
|
|||
<string name="color_preset_option">Color preset</string>
|
||||
<string name="background_color_option">Background color</string>
|
||||
<string name="font_color_option">Font color</string>
|
||||
<string name="check_for_updates_option">Check for updates</string>
|
||||
<string name="check_for_updates_option_desc">Check for newer app version on startup</string>
|
||||
<string name="side_padding_option">Side padding</string>
|
||||
<string name="double_click_translation_option">Double click translation</string>
|
||||
<string name="double_click_translation_option_desc">Double click on paragraph to translate it</string>
|
||||
<string name="fast_color_preset_change_option">Fast color preset change</string>
|
||||
<string name="fast_color_preset_change_option_desc">Swipe left or right to change color preset</string>
|
||||
<string name="text_alignment_option">Text alignment</string>
|
||||
|
||||
<!-- Browse -->
|
||||
<string name="browse_files_structure_option">Files structure</string>
|
||||
<string name="browse_layout_option">Display mode</string>
|
||||
<string name="browse_grid_size_option">Grid size</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue