diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1b9d4d6c..046c097d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,7 +16,7 @@ android { minSdk = 26 targetSdk = 34 versionCode = 1 - versionName = "0.9.9" + versionName = "1.0.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 832045a8..653ee843 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -47,6 +47,7 @@ diff --git a/app/src/main/java/ua/acclorite/book_story/Activity.kt b/app/src/main/java/ua/acclorite/book_story/Activity.kt index f96ec417..84fc182d 100644 --- a/app/src/main/java/ua/acclorite/book_story/Activity.kt +++ b/app/src/main/java/ua/acclorite/book_story/Activity.kt @@ -30,6 +30,7 @@ import ua.acclorite.book_story.presentation.screens.about.nested.credits.Credits import ua.acclorite.book_story.presentation.screens.about.nested.license_info.LicenseInfoScreenRoot import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoViewModel import ua.acclorite.book_story.presentation.screens.about.nested.licenses.LicensesScreenRoot +import ua.acclorite.book_story.presentation.screens.about.nested.licenses.data.LicensesViewModel import ua.acclorite.book_story.presentation.screens.book_info.BookInfoScreenRoot import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel import ua.acclorite.book_story.presentation.screens.browse.BrowseScreenRoot @@ -70,6 +71,7 @@ class Activity : AppCompatActivity() { private val helpViewModel: HelpViewModel by viewModels() private val aboutViewModel: AboutViewModel by viewModels() private val licenseInfoViewModel: LicenseInfoViewModel by viewModels() + private val licensesViewModel: LicensesViewModel by viewModels() private val settingsViewModel: SettingsViewModel by viewModels() private val startViewModel: StartViewModel by viewModels() diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyGridHeader.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyGridHeader.kt new file mode 100644 index 00000000..fea50b3f --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyGridHeader.kt @@ -0,0 +1,12 @@ +package ua.acclorite.book_story.presentation.components + +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyGridItemScope +import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.runtime.Composable + +fun LazyGridScope.header( + content: @Composable LazyGridItemScope.() -> Unit +) { + item(span = { GridItemSpan(this.maxLineSpan) }, content = content) +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyListItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyListItem.kt new file mode 100644 index 00000000..d9db96f7 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/LazyListItem.kt @@ -0,0 +1,43 @@ +package ua.acclorite.book_story.presentation.components + +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.grid.LazyGridItemScope +import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.runtime.Composable + +fun LazyListScope.customItems( + items: List, + key: (T) -> Any?, + content: @Composable LazyItemScope.(T) -> Unit +) { + items.forEach { + item(key = key(it)) { + content(it) + } + } +} + +fun LazyListScope.customItemsIndexed( + items: List, + key: (T) -> Any?, + content: @Composable LazyItemScope.(Int, T) -> Unit +) { + items.forEachIndexed { index, item -> + item(key = key(item)) { + content(index, item) + } + } +} + +fun LazyGridScope.customItems( + items: List, + key: (T) -> Any?, + content: @Composable LazyGridItemScope.(T) -> Unit +) { + items.forEach { + item(key = key(it)) { + content(it) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationBar.kt index ce4ebfed..a7c44d8c 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationBar.kt @@ -16,7 +16,6 @@ import ua.acclorite.book_story.presentation.data.Screen /** * Bottom navigation bar, uses default [NavigationBar]. - * */ @Composable fun BottomNavigationBar() { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/credits/components/CreditItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/credits/components/CreditItem.kt index 179ae583..03d97029 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/credits/components/CreditItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/credits/components/CreditItem.kt @@ -21,6 +21,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import ua.acclorite.book_story.domain.model.Credit +/** + * Credit Item. + */ @OptIn(ExperimentalLayoutApi::class) @Composable fun CreditItem( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/license_info/LicenseInfoScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/license_info/LicenseInfoScreen.kt index 9f542e07..c156d828 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/license_info/LicenseInfoScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/license_info/LicenseInfoScreen.kt @@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Language @@ -52,6 +51,7 @@ import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.data.Navigator import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoEvent @@ -154,10 +154,14 @@ private fun LicenseInfoScreen( .fillMaxSize() .padding(top = paddingValues.calculateTopPadding()), state = scrollState.second, - contentPadding = PaddingValues(vertical = 12.dp, horizontal = 16.dp), + contentPadding = PaddingValues(horizontal = 16.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { - items(licenses, key = { it.name }) { license -> + item { + Spacer(modifier = Modifier.height(12.dp)) + } + + customItems(licenses, key = { it.name }) { license -> val showed = remember { mutableStateOf(licenses.size == 1) } @@ -206,6 +210,10 @@ private fun LicenseInfoScreen( } } } + + item { + Spacer(modifier = Modifier.height(12.dp)) + } } } } else { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/LicensesScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/LicensesScreen.kt index 47090254..2e644eae 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/LicensesScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/LicensesScreen.kt @@ -3,14 +3,14 @@ package ua.acclorite.book_story.presentation.screens.about.nested.licenses import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LargeTopAppBar import androidx.compose.material3.MaterialTheme @@ -31,6 +31,7 @@ import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.data.Argument import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.data.Navigator @@ -96,10 +97,13 @@ private fun LicensesScreen( Modifier .fillMaxSize() .padding(top = paddingValues.calculateTopPadding()), - state = scrollState.second, - contentPadding = PaddingValues(vertical = 12.dp) + state = scrollState.second ) { - items(state.value.licenses, key = { it.uniqueId }) { + item { + Spacer(modifier = Modifier.height(12.dp)) + } + + customItems(state.value.licenses, key = { it.uniqueId }) { LicenseItem(library = it) { navigator.navigate( Screen.LICENSES_INFO, @@ -108,6 +112,10 @@ private fun LicensesScreen( ) } } + + item { + Spacer(modifier = Modifier.height(12.dp)) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/components/LicenseItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/components/LicenseItem.kt index 4fa5fd40..30761762 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/components/LicenseItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/nested/licenses/components/LicenseItem.kt @@ -25,6 +25,9 @@ import androidx.compose.ui.unit.dp import com.mikepenz.aboutlibraries.entity.Library import com.mikepenz.aboutlibraries.ui.compose.m3.util.author +/** + * License Item. + */ @OptIn(ExperimentalLayoutApi::class) @Composable fun LicenseItem( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/dialog/BookInfoMoveDialog.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/dialog/BookInfoMoveDialog.kt index 444da7b2..87fecad5 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/dialog/BookInfoMoveDialog.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/dialog/BookInfoMoveDialog.kt @@ -1,7 +1,6 @@ package ua.acclorite.book_story.presentation.screens.book_info.components.dialog import android.widget.Toast -import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.DriveFileMove import androidx.compose.runtime.Composable @@ -12,6 +11,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Category +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.custom_dialog.CustomDialogWithLazyColumn import ua.acclorite.book_story.presentation.components.custom_dialog.SelectableDialogItem import ua.acclorite.book_story.presentation.data.LocalNavigator @@ -71,7 +71,7 @@ fun BookInfoMoveDialog( }, withDivider = false, items = { - items(categories) { + customItems(categories, key = { it.name }) { val category = when (it) { Category.READING -> stringResource(id = R.string.reading_tab) Category.ALREADY_READ -> stringResource(id = R.string.already_read_tab) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/BrowseScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/BrowseScreen.kt index 48ac5cf0..8f9ea355 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/BrowseScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/BrowseScreen.kt @@ -6,11 +6,11 @@ import androidx.activity.compose.BackHandler import androidx.compose.animation.core.tween import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -51,6 +51,7 @@ import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomSearchTextField import ua.acclorite.book_story.presentation.components.MoreDropDown +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.components.is_messages.IsError import ua.acclorite.book_story.presentation.data.LocalNavigator @@ -233,10 +234,13 @@ private fun BrowseScreen( LazyColumn( state = state.value.listState, modifier = Modifier - .fillMaxSize(), - contentPadding = PaddingValues(vertical = 8.dp) + .fillMaxSize() ) { - items( + item { + Spacer(modifier = Modifier.height(8.dp)) + } + + customItems( state.value.selectableFiles, key = { it.first.path } ) { selectableFile -> @@ -259,6 +263,10 @@ private fun BrowseScreen( } ) } + + item { + Spacer(modifier = Modifier.height(8.dp)) + } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialog.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialog.kt index 17e36aef..8b53d5ea 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialog.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialog.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AddChart import androidx.compose.material3.CircularProgressIndicator @@ -20,6 +19,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.NullableBook +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.custom_dialog.CustomDialogWithLazyColumn import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent @@ -90,7 +90,7 @@ fun BrowseAddingDialog( } } } else { - items(state.value.selectedBooks) { book -> + customItems(state.value.selectedBooks, key = { it.first.fileName }) { book -> BrowseAddingDialogItem( result = book ) { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseViewModel.kt index c390f511..54a75e92 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseViewModel.kt @@ -78,7 +78,7 @@ class BrowseViewModel @Inject constructor( } if (legacyStoragePermission) { - if (event.storagePermissionState.status.shouldShowRationale) { + if (!event.storagePermissionState.status.shouldShowRationale) { event.storagePermissionState.launchPermissionRequest() } else { val uri = Uri.parse("package:${event.activity.packageName}") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/HelpScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/HelpScreen.kt index 972436d2..ed00366f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/HelpScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/HelpScreen.kt @@ -41,6 +41,8 @@ import ua.acclorite.book_story.presentation.data.MainEvent import ua.acclorite.book_story.presentation.data.MainViewModel import ua.acclorite.book_story.presentation.data.Navigator 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 import ua.acclorite.book_story.presentation.screens.help.components.items.HelpAddBooksItem import ua.acclorite.book_story.presentation.screens.help.components.items.HelpClickMeNoteItem import ua.acclorite.book_story.presentation.screens.help.components.items.HelpCustomizeApp @@ -61,6 +63,7 @@ import ua.acclorite.book_story.presentation.screens.start.data.StartViewModel fun HelpScreenRoot() { val navigator = LocalNavigator.current val helpViewModel: HelpViewModel = hiltViewModel() + val browseViewModel: BrowseViewModel = hiltViewModel() val mainViewModel: MainViewModel = hiltViewModel() val startViewModel: StartViewModel = hiltViewModel() @@ -75,6 +78,7 @@ fun HelpScreenRoot() { navigator = navigator, onEvent = helpViewModel::onEvent, onMainEvent = mainViewModel::onEvent, + onBrowseEvent = browseViewModel::onEvent, onStartEvent = startViewModel::onEvent ) } @@ -88,6 +92,7 @@ private fun HelpScreen( navigator: Navigator, onEvent: (HelpEvent) -> Unit, onMainEvent: (MainEvent) -> Unit, + onBrowseEvent: (BrowseEvent) -> Unit, onStartEvent: (StartEvent) -> Unit ) { val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() @@ -117,6 +122,7 @@ private fun HelpScreen( ) { onStartEvent(StartEvent.OnResetStartScreen) onMainEvent(MainEvent.OnChangeShowStartScreen(true)) + onBrowseEvent(BrowseEvent.OnLoadList) navigator.navigateWithoutBackStack(Screen.START, false) navigator.clearBackStack() } @@ -142,6 +148,7 @@ private fun HelpScreen( shape = RoundedCornerShape(100), onClick = { navigator.clearArgument("from_start") + onMainEvent(MainEvent.OnChangeShowStartScreen(false)) navigator.navigateWithoutBackStack(Screen.BROWSE, false) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpAddBooksItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpAddBooksItem.kt index 048bdd6f..2cbe4bb3 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpAddBooksItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpAddBooksItem.kt @@ -51,11 +51,15 @@ fun LazyItemScope.HelpAddBooksItem( onTagClick = { tag -> when (tag) { "browse" -> { - navigator.navigate(Screen.BROWSE, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.BROWSE, true) + } } "library" -> { - navigator.navigate(Screen.LIBRARY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.LIBRARY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeApp.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeApp.kt index 65aa744a..6c84103e 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeApp.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeApp.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpCustomizeApp( onTagClick = { tag -> when (tag) { "settings" -> { - navigator.navigate(Screen.SETTINGS, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.SETTINGS, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeReader.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeReader.kt index 7bb3e08f..009411bc 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeReader.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpCustomizeReader.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpCustomizeReader( onTagClick = { tag -> when (tag) { "settings" -> { - navigator.navigate(Screen.SETTINGS, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.SETTINGS, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpEditBook.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpEditBook.kt index f00258be..f9116e8a 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpEditBook.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpEditBook.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpEditBook( onTagClick = { tag -> when (tag) { "library" -> { - navigator.navigate(Screen.LIBRARY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.LIBRARY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpManageHistory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpManageHistory.kt index f3636012..297e57f5 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpManageHistory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpManageHistory.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpManageHistory( onTagClick = { tag -> when (tag) { "history" -> { - navigator.navigate(Screen.HISTORY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.HISTORY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpMoveOrDeleteBooks.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpMoveOrDeleteBooks.kt index f08c26d6..30119a3a 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpMoveOrDeleteBooks.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpMoveOrDeleteBooks.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpMoveOrDeleteBooks( onTagClick = { tag -> when (tag) { "library" -> { - navigator.navigate(Screen.LIBRARY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.LIBRARY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpReadBook.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpReadBook.kt index 82bdb63c..89932576 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpReadBook.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpReadBook.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpReadBook( onTagClick = { tag -> when (tag) { "library" -> { - navigator.navigate(Screen.LIBRARY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.LIBRARY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpUpdateBook.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpUpdateBook.kt index fe3927c8..ea6ea104 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpUpdateBook.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/help/components/items/HelpUpdateBook.kt @@ -46,7 +46,9 @@ fun LazyItemScope.HelpUpdateBook( onTagClick = { tag -> when (tag) { "library" -> { - navigator.navigate(Screen.LIBRARY, true) + if (!state.value.fromStart) { + navigator.navigate(Screen.LIBRARY, true) + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/HistoryScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/HistoryScreen.kt index fd7f73cc..d6602fa9 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/HistoryScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/HistoryScreen.kt @@ -4,13 +4,11 @@ import androidx.activity.compose.BackHandler import androidx.compose.animation.core.tween import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -47,6 +45,7 @@ import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomSearchTextField import ua.acclorite.book_story.presentation.components.CustomSnackbar import ua.acclorite.book_story.presentation.components.MoreDropDown +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.data.Argument import ua.acclorite.book_story.presentation.data.LocalNavigator @@ -199,8 +198,11 @@ private fun HistoryScreen( Modifier .fillMaxSize(), state = state.value.listState, - contentPadding = PaddingValues(vertical = 12.dp) ) { + item { + Spacer(modifier = Modifier.height(12.dp)) + } + state.value.history.forEachIndexed { index, groupedHistory -> item(key = groupedHistory.title) { if (index > 0) { @@ -220,7 +222,7 @@ private fun HistoryScreen( Spacer(modifier = Modifier.height(8.dp)) } - items( + customItems( groupedHistory.history, key = { it.id } ) { HistoryItem( @@ -260,6 +262,10 @@ private fun HistoryScreen( ) } } + + item { + Spacer(modifier = Modifier.height(12.dp)) + } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/LibraryScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/LibraryScreen.kt index 1d1a62aa..003b01a7 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/LibraryScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/LibraryScreen.kt @@ -13,11 +13,11 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState @@ -69,6 +69,8 @@ import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomSearchTextField import ua.acclorite.book_story.presentation.components.MoreDropDown +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.Argument import ua.acclorite.book_story.presentation.data.LocalNavigator @@ -318,12 +320,13 @@ private fun LibraryScreen( columns = GridCells.Adaptive(120.dp), modifier = Modifier.fillMaxSize(), state = listState, - contentPadding = PaddingValues(8.dp) + contentPadding = PaddingValues(horizontal = 8.dp) ) { - items( - books, - key = { it.first.id } - ) { + header { + Spacer(modifier = Modifier.height(8.dp)) + } + + customItems(books, key = { it.first.id }) { LibraryBookItem( book = it, modifier = Modifier.animateItem( @@ -356,6 +359,10 @@ private fun LibraryScreen( } ) } + + header { + Spacer(modifier = Modifier.height(8.dp)) + } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/dialog/LibraryMoveDialog.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/dialog/LibraryMoveDialog.kt index da38b685..3423c143 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/dialog/LibraryMoveDialog.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/dialog/LibraryMoveDialog.kt @@ -1,7 +1,6 @@ package ua.acclorite.book_story.presentation.screens.library.components.dialog import android.widget.Toast -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.pager.PagerState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.DriveFileMove @@ -11,6 +10,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Category +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.custom_dialog.CustomDialogWithLazyColumn import ua.acclorite.book_story.presentation.components.custom_dialog.SelectableDialogItem import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent @@ -56,7 +56,7 @@ fun LibraryMoveDialog( }, withDivider = false, items = { - items(state.value.categories) { + customItems(state.value.categories, key = { it.name }) { val category = when (it) { Category.READING -> stringResource(id = R.string.reading_tab) Category.ALREADY_READ -> stringResource(id = R.string.already_read_tab) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt index 3e4921b7..7c3b602d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.text.selection.DisableSelection import androidx.compose.material3.LinearProgressIndicator @@ -59,6 +58,7 @@ import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.util.Constants import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility import ua.acclorite.book_story.presentation.components.CustomSelectionContainer +import ua.acclorite.book_story.presentation.components.customItemsIndexed import ua.acclorite.book_story.presentation.components.is_messages.IsError import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.data.MainEvent @@ -346,8 +346,8 @@ private fun ReaderScreen( } } - itemsIndexed( - state.value.book.text, key = { _, key -> key.id } + customItemsIndexed( + state.value.book.text, key = { key -> key.id } ) { index, line -> val text = remember(mainState.value.paragraphIndentation) { "${if (mainState.value.paragraphIndentation!!) " " else ""}${line.line}" diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt index bba9718a..bb351f3d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt @@ -420,21 +420,15 @@ class ReaderViewModel @Inject constructor( return@launch } - if (_state.value.book.id != bookId) { - val book = getBooksById.execute(listOf(bookId)) + val book = getBooksById.execute(listOf(bookId)) - if (book.isEmpty()) { - navigator.navigateBack() - return@launch - } + if (book.isEmpty()) { + navigator.navigateBack() + return@launch + } - _state.update { - ReaderState(book = book.first()) - } - } else { - _state.update { - ReaderState(book = it.book) - } + _state.update { + ReaderState(book = book.first()) } viewModelScope.launch { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/SegmentedButtonWithTitle.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/SegmentedButtonWithTitle.kt index 718c92d1..7fa647e2 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/SegmentedButtonWithTitle.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/SegmentedButtonWithTitle.kt @@ -18,6 +18,9 @@ import androidx.compose.ui.unit.dp import ua.acclorite.book_story.domain.model.ButtonItem import ua.acclorite.book_story.presentation.components.CategoryTitle +/** + * Segmented Button with Title. Contains [buttons]. + */ @Composable fun SegmentedButtonWithTitle( modifier: Modifier = Modifier, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/data/SettingsViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/data/SettingsViewModel.kt index 8ca40fd3..58e802dd 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/data/SettingsViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/data/SettingsViewModel.kt @@ -42,7 +42,7 @@ class SettingsViewModel @Inject constructor( return } - if (event.notificationsPermissionState.status.shouldShowRationale) { + if (!event.notificationsPermissionState.status.shouldShowRationale) { event.notificationsPermissionState.launchPermissionRequest() } else { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcher.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcher.kt index 86475bd3..2d8650ef 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcher.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcher.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.remember @@ -20,6 +19,7 @@ import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.util.Constants import ua.acclorite.book_story.presentation.components.CategoryTitle +import ua.acclorite.book_story.presentation.components.customItemsIndexed import ua.acclorite.book_story.presentation.data.MainEvent import ua.acclorite.book_story.presentation.data.MainState import ua.acclorite.book_story.presentation.ui.Theme @@ -54,7 +54,7 @@ fun AppearanceSettingsThemeSwitcher( Modifier .fillMaxWidth(), ) { - itemsIndexed(themes) { index, themeEntry -> + customItemsIndexed(themes, key = { it.first.name }) { index, themeEntry -> if (index == 0) { Spacer(modifier = Modifier.width(18.dp)) } else { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/components/StartLanguageScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/components/StartLanguageScreen.kt index 2c918275..9e375bf6 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/components/StartLanguageScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/components/StartLanguageScreen.kt @@ -3,7 +3,6 @@ package ua.acclorite.book_story.presentation.screens.start.components import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.items import androidx.compose.material3.MaterialTheme import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -11,6 +10,7 @@ import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.ButtonItem import ua.acclorite.book_story.presentation.components.CategoryTitle +import ua.acclorite.book_story.presentation.components.customItems import ua.acclorite.book_story.presentation.components.custom_dialog.SelectableDialogItem import ua.acclorite.book_story.presentation.data.MainEvent @@ -30,7 +30,7 @@ fun LazyListScope.startLanguageScreen( Spacer(modifier = Modifier.height(12.dp)) } - items(languages) { + customItems(languages, key = { it.id }) { SelectableDialogItem( selected = it.selected, title = it.title, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/data/StartViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/data/StartViewModel.kt index ae907eee..6cbbbe0f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/data/StartViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/start/data/StartViewModel.kt @@ -132,7 +132,7 @@ class StartViewModel @Inject constructor( } if (legacyStoragePermission) { - if (event.legacyStoragePermissionState.status.shouldShowRationale) { + if (!event.legacyStoragePermissionState.status.shouldShowRationale) { event.legacyStoragePermissionState.launchPermissionRequest() } else { val uri = Uri.parse("package:${event.activity.packageName}") @@ -198,7 +198,7 @@ class StartViewModel @Inject constructor( return } - if (event.notificationsPermissionState.status.shouldShowRationale) { + if (!event.notificationsPermissionState.status.shouldShowRationale) { event.notificationsPermissionState.launchPermissionRequest() } else { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 1b7bf4d8..928c02d3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -101,7 +101,7 @@ Щось пішло не так. - Будь ласка, перевірте ваше підключення до інтернету та спробуйте ще раз. + Спробуйте пізніше. @@ -292,8 +292,8 @@ Підтримати мою роботу Ліцензії з відкритим кодом Заслуги - Слава Україні! 🇺🇦 - Героям Слава! 🐉 + Слава Україні! + Героям Слава! 🇺🇦🐉 Дизайн diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38be0b01..3b856ab2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - 0.9.9 + 1.0.0 Book\'s Story @@ -121,7 +121,7 @@ Something went wrong. - Please check your internet connection and try again. + Try again later. @@ -311,8 +311,8 @@ Support my work Open source licenses Credits - Slava Ukraini! 🇺🇦 - Heroyam Slava! 🐉 + Slava Ukraini! + Heroyam Slava! 🇺🇦🐉 Design