From 22ed828ee61a44b0ae6a475a3ca853fd9fd6de9c Mon Sep 17 00:00:00 2001 From: acclorite Date: Fri, 15 Mar 2024 14:21:00 +0200 Subject: [PATCH] 0.9.2 - Massive scrolling performance improvement --- app/build.gradle.kts | 4 +- app/src/main/AndroidManifest.xml | 1 - .../java/ua/acclorite/book_story/Activity.kt | 264 ++++++++---------- .../data/mapper/book/BookMapperImpl.kt | 11 +- .../data/parser/epub/EpubFileParser.kt | 4 +- .../data/parser/epub/EpubTextParser.kt | 16 +- .../data/repository/BookRepositoryImpl.kt | 52 +++- .../domain/repository/BookRepository.kt | 10 +- .../domain/use_case/ChangeLanguage.kt | 20 +- ...FromDownloads.kt => GetFilesFromDevice.kt} | 4 +- .../book_story/domain/use_case/GetText.kt | 8 +- .../domain/use_case/UpdateBooksWithText.kt | 12 + .../components/AnimatedTopAppBar.kt | 85 +++--- .../presentation/components/CustomCheckbox.kt | 9 +- .../components/CustomIconButton.kt | 45 +++ .../components/CustomSelectionContainer.kt | 1 - .../presentation/components/GoBackButton.kt | 27 +- .../presentation/components/MoreDropDown.kt | 23 +- .../BottomNavigationBar.kt | 2 + .../BottomNavigationItem.kt | 10 +- .../custom_dialog/CustomDialogWithContent.kt | 20 +- .../CustomDialogWithLazyColumn.kt | 20 +- .../CustomNavigationRailItem.kt | 10 +- .../book_story/presentation/data/MainEvent.kt | 5 +- .../presentation/data/MainViewModel.kt | 37 +-- .../screens/book_info/BookInfoScreen.kt | 90 +++--- .../components/BookInfoInfoSection.kt | 6 +- .../components/BookInfoMoreDropDown.kt | 20 +- .../components/BookInfoStatisticSection.kt | 35 +-- .../BookInfoChangeCoverBottomSheet.kt | 13 +- .../BookInfoDetailsBottomSheet.kt | 36 ++- .../BookInfoDetailsBottomSheetItem.kt | 4 +- .../book_info/data/BookInfoViewModel.kt | 18 +- .../screens/browse/BrowseScreen.kt | 179 ++++++------ .../browse/components/BrowseFIleItem.kt | 130 ++++----- .../BrowseStoragePermissionDialog.kt | 25 +- .../adding_dialog/BrowseAddingDialogItem.kt | 2 +- .../screens/browse/data/BrowseEvent.kt | 24 +- .../screens/browse/data/BrowseState.kt | 4 +- .../screens/browse/data/BrowseViewModel.kt | 138 +++++---- .../screens/history/HistoryScreen.kt | 215 ++++++-------- .../screens/history/components/HistoryItem.kt | 15 +- .../screens/history/data/HistoryEvent.kt | 2 - .../screens/history/data/HistoryState.kt | 3 + .../screens/history/data/HistoryViewModel.kt | 36 +-- .../screens/library/LibraryScreen.kt | 108 ++++--- .../library/components/LibraryBookItem.kt | 25 +- .../library/components/LibraryTabRow.kt | 40 +-- .../screens/library/data/LibraryViewModel.kt | 60 ++-- .../screens/reader/ReaderScreen.kt | 24 +- .../reader/components/ReaderStartItem.kt | 4 +- .../components/app_bar/ReaderBottomBar.kt | 21 +- .../reader/components/app_bar/ReaderTopBar.kt | 39 +-- .../ReaderSettingsBottomSheet.kt | 9 +- .../screens/reader/data/ReaderEvent.kt | 3 +- .../screens/reader/data/ReaderState.kt | 5 +- .../screens/reader/data/ReaderViewModel.kt | 67 +++-- .../screens/settings/SettingsScreen.kt | 5 + .../components/ColorPickerWithTitle.kt | 2 +- .../nested/appearance/AppearanceSettings.kt | 2 + .../AppearanceSettingsThemeSwitcher.kt | 7 +- .../AppearanceSettingsThemeSwitcherItem.kt | 4 +- .../nested/general/GeneralSettings.kt | 13 +- .../settings/nested/reader/ReaderSettings.kt | 2 + .../main/res/drawable/app_icon_colored.png | Bin 29654 -> 10209 bytes .../main/res/drawable/app_icon_monochrome.png | Bin 5996 -> 4129 bytes .../res/drawable/browse_screen_outlined.png | Bin 18232 -> 10620 bytes app/src/main/res/drawable/empty_browse.png | Bin 15400 -> 10238 bytes app/src/main/res/drawable/empty_history.png | Bin 16973 -> 10438 bytes app/src/main/res/drawable/empty_library.png | Bin 15682 -> 9535 bytes app/src/main/res/drawable/epub.png | Bin 9986 -> 0 bytes app/src/main/res/drawable/error.png | Bin 4347 -> 1776 bytes app/src/main/res/drawable/file.png | Bin 4998 -> 0 bytes .../res/drawable/history_screen_filled.png | Bin 18922 -> 11342 bytes .../res/drawable/history_screen_outlined.png | Bin 15353 -> 9592 bytes .../res/drawable/library_screen_filled.png | Bin 5369 -> 3680 bytes .../res/drawable/library_screen_outlined.png | Bin 4874 -> 3486 bytes app/src/main/res/drawable/pdf.png | Bin 8757 -> 0 bytes app/src/main/res/drawable/txt.png | Bin 7025 -> 0 bytes .../app_icon.xml | 0 .../app_icon_round.xml | 0 app/src/main/res/values-uk/strings.xml | 31 +- app/src/main/res/values/strings.xml | 33 ++- 83 files changed, 1175 insertions(+), 1024 deletions(-) rename app/src/main/java/ua/acclorite/book_story/domain/use_case/{GetFilesFromDownloads.kt => GetFilesFromDevice.kt} (77%) create mode 100644 app/src/main/java/ua/acclorite/book_story/domain/use_case/UpdateBooksWithText.kt create mode 100644 app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt delete mode 100644 app/src/main/res/drawable/epub.png delete mode 100644 app/src/main/res/drawable/file.png delete mode 100644 app/src/main/res/drawable/pdf.png delete mode 100644 app/src/main/res/drawable/txt.png rename app/src/main/res/{mipmap-anydpi-v26 => mipmap-anydpi}/app_icon.xml (100%) rename app/src/main/res/{mipmap-anydpi-v26 => mipmap-anydpi}/app_icon_round.xml (100%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4b5e05db..52eefaa9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,7 +15,7 @@ android { minSdk = 26 targetSdk = 34 versionCode = 1 - versionName = "0.9.0" + versionName = "0.9.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -139,4 +139,6 @@ dependencies { implementation("androidx.appcompat:appcompat:latest.release") implementation("androidx.appcompat:appcompat-resources:latest.release") + + implementation("io.coil-kt:coil-compose:2.6.0") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d1dab8b..7c9c53e6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,7 +35,6 @@ 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 b8ccfa15..a44d066a 100644 --- a/app/src/main/java/ua/acclorite/book_story/Activity.kt +++ b/app/src/main/java/ua/acclorite/book_story/Activity.kt @@ -1,15 +1,13 @@ package ua.acclorite.book_story import android.annotation.SuppressLint -import android.content.res.Configuration import android.database.CursorWindow import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -28,7 +26,6 @@ import dagger.hilt.android.AndroidEntryPoint import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.presentation.components.bottom_navigation_bar.BottomNavigationBar import ua.acclorite.book_story.presentation.components.custom_navigation_rail.CustomNavigationRail -import ua.acclorite.book_story.presentation.data.MainEvent import ua.acclorite.book_story.presentation.data.MainViewModel import ua.acclorite.book_story.presentation.data.NavigationHost import ua.acclorite.book_story.presentation.data.Screen @@ -55,7 +52,7 @@ import java.lang.reflect.Field @SuppressLint("DiscouragedPrivateApi") @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @AndroidEntryPoint -class Activity : ComponentActivity() { +class Activity : AppCompatActivity() { private val mainViewModel: MainViewModel by viewModels() private val libraryViewModel: LibraryViewModel by viewModels() private val historyViewModel: HistoryViewModel by viewModels() @@ -75,10 +72,7 @@ class Activity : ComponentActivity() { } // Initializing all variables - mainViewModel.init( - activity = this, - libraryViewModel, - ) + mainViewModel.init(libraryViewModel) // Splash screen installSplashScreen().apply { @@ -93,7 +87,6 @@ class Activity : ComponentActivity() { setContent { val windowClass = calculateWindowSizeClass(activity = this) - val updating = mainViewModel.updating.collectAsState().value val theme = mainViewModel.theme.collectAsState().value ?: Theme.BLUE val darkTheme = @@ -104,157 +97,142 @@ class Activity : ComponentActivity() { theme = theme, isDark = darkTheme.isDark() ) { - if (!updating) { - NavigationHost(startScreen = Screen.LIBRARY) { - val currentScreen by this.getCurrentScreen().collectAsState() + NavigationHost(startScreen = Screen.LIBRARY) { + val currentScreen by this.getCurrentScreen().collectAsState() - AnimatedVisibility( - visible = currentScreen == Screen.LIBRARY || - currentScreen == Screen.HISTORY || - currentScreen == Screen.BROWSE, - enter = Transitions.BackSlidingTransitionIn, - exit = Transitions.SlidingTransitionOut + AnimatedVisibility( + visible = currentScreen == Screen.LIBRARY || + currentScreen == Screen.HISTORY || + currentScreen == Screen.BROWSE, + enter = Transitions.BackSlidingTransitionIn, + exit = Transitions.SlidingTransitionOut + ) { + Scaffold( + bottomBar = { + if (!tabletUI) { + BottomNavigationBar(navigator = this@NavigationHost) + } + }, + containerColor = MaterialTheme.colorScheme.surface ) { - Scaffold( - bottomBar = { - if (!tabletUI) { - BottomNavigationBar(navigator = this@NavigationHost) - } - }, - containerColor = MaterialTheme.colorScheme.surface + Box( + modifier = Modifier + .fillMaxSize() + .padding( + start = if (tabletUI) 80.dp else 0.dp, + bottom = it.calculateBottomPadding() + ) ) { - Box( - modifier = Modifier - .fillMaxSize() - .padding( - start = if (tabletUI) 80.dp else 0.dp, - bottom = it.calculateBottomPadding() - ) - ) { - composable(screen = Screen.LIBRARY) { - @Suppress("UNCHECKED_CAST") - LibraryScreen( - viewModel = libraryViewModel, - historyViewModel = historyViewModel, - browseViewModel = browseViewModel, - navigator = this@NavigationHost, - addedBooks = retrieveArgument("added_books") as? List - ?: emptyList() - ) - } - - composable(screen = Screen.HISTORY) { - HistoryScreen( - viewModel = historyViewModel, - libraryViewModel = libraryViewModel, - navigator = this@NavigationHost - ) - } - - composable(screen = Screen.BROWSE) { - BrowseScreen( - viewModel = browseViewModel, - libraryViewModel = libraryViewModel, - navigator = this@NavigationHost - ) - } + composable(screen = Screen.LIBRARY) { + @Suppress("UNCHECKED_CAST") + LibraryScreen( + viewModel = libraryViewModel, + historyViewModel = historyViewModel, + browseViewModel = browseViewModel, + navigator = this@NavigationHost, + addedBooks = retrieveArgument("added_books") as? List + ?: emptyList() + ) } - if (tabletUI) { - CustomNavigationRail(navigator = this@NavigationHost) + composable(screen = Screen.HISTORY) { + HistoryScreen( + viewModel = historyViewModel, + libraryViewModel = libraryViewModel, + navigator = this@NavigationHost + ) + } + + composable(screen = Screen.BROWSE) { + BrowseScreen( + viewModel = browseViewModel, + libraryViewModel = libraryViewModel, + navigator = this@NavigationHost + ) } } - } - // Book Info - composable( - screen = Screen.BOOK_INFO, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - BookInfoScreen( - libraryViewModel = libraryViewModel, - browseViewModel = browseViewModel, - historyViewModel = historyViewModel, - navigator = this@NavigationHost - ) - } - composable( - screen = Screen.READER, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - ReaderScreen( - mainViewModel = mainViewModel, - libraryViewModel = libraryViewModel, - historyViewModel = historyViewModel, - navigator = this@NavigationHost - ) + if (tabletUI) { + CustomNavigationRail(navigator = this@NavigationHost) + } } + } - // Settings - composable( - screen = Screen.SETTINGS, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - SettingsScreen( - navigator = this@NavigationHost - ) - } + // Book Info + composable( + screen = Screen.BOOK_INFO, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + BookInfoScreen( + libraryViewModel = libraryViewModel, + browseViewModel = browseViewModel, + historyViewModel = historyViewModel, + navigator = this@NavigationHost + ) + } + composable( + screen = Screen.READER, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + ReaderScreen( + mainViewModel = mainViewModel, + libraryViewModel = libraryViewModel, + historyViewModel = historyViewModel, + navigator = this@NavigationHost + ) + } - // Nested categories - composable( - screen = Screen.GENERAL_SETTINGS, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - GeneralSettings( - mainViewModel = mainViewModel, - navigator = this@NavigationHost - ) - } - composable( - screen = Screen.APPEARANCE_SETTINGS, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - AppearanceSettings( - mainViewModel = mainViewModel, - navigator = this@NavigationHost - ) - } - composable( - screen = Screen.READER_SETTINGS, - enterAnim = Transitions.SlidingTransitionIn, - exitAnim = Transitions.SlidingTransitionOut - ) { - ReaderSettings( - mainViewModel = mainViewModel, - navigator = this@NavigationHost - ) - } + // Settings + composable( + screen = Screen.SETTINGS, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + SettingsScreen( + navigator = this@NavigationHost + ) + } + + // Nested categories + composable( + screen = Screen.GENERAL_SETTINGS, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + GeneralSettings( + mainViewModel = mainViewModel, + navigator = this@NavigationHost + ) + } + composable( + screen = Screen.APPEARANCE_SETTINGS, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + AppearanceSettings( + mainViewModel = mainViewModel, + navigator = this@NavigationHost + ) + } + composable( + screen = Screen.READER_SETTINGS, + enterAnim = Transitions.SlidingTransitionIn, + exitAnim = Transitions.SlidingTransitionOut + ) { + ReaderSettings( + mainViewModel = mainViewModel, + navigator = this@NavigationHost + ) + } // Start screen (later) // composable(screen = Screen.START) { // StartScreen() // } - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background( - MaterialTheme.colorScheme.surface - ) - ) } } } } - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - mainViewModel.onEvent(MainEvent.OnLocaleUpdate(this)) - } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt index f314e27d..5d54ec6f 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt @@ -9,7 +9,6 @@ import androidx.compose.ui.graphics.asImageBitmap import ua.acclorite.book_story.R import ua.acclorite.book_story.data.local.dto.BookEntity import ua.acclorite.book_story.domain.model.Book -import ua.acclorite.book_story.domain.model.StringWithId import ua.acclorite.book_story.util.UIText import java.io.ByteArrayOutputStream import java.io.File @@ -22,12 +21,12 @@ class BookMapperImpl @Inject constructor() : BookMapper { val stream = ByteArrayOutputStream() book.coverImage?.asAndroidBitmap()?.compress( if (legacyAPI) Bitmap.CompressFormat.WEBP - else Bitmap.CompressFormat.WEBP_LOSSLESS, - if (legacyAPI) 30 else 100, + else Bitmap.CompressFormat.WEBP_LOSSY, + 0, stream ) - val text = book.text.joinToString("\n") { + val textAsString = book.text.joinToString("\n") { it.line.trim() } @@ -37,7 +36,7 @@ class BookMapperImpl @Inject constructor() : BookMapper { filePath = book.filePath, progress = book.progress, author = book.author.string, - text = text, + text = textAsString, description = book.description, image = stream.toByteArray(), category = book.category @@ -64,7 +63,7 @@ class BookMapperImpl @Inject constructor() : BookMapper { description = bookEntity.description, progress = bookEntity.progress, file = if (file.exists()) file else null, - text = bookEntity.text.split("\n").map { StringWithId(it) }, + text = emptyList(), filePath = bookEntity.filePath, lastOpened = null, category = bookEntity.category, diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubFileParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubFileParser.kt index 482745c7..1d2493ee 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubFileParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubFileParser.kt @@ -37,11 +37,13 @@ class EpubFileParser @Inject constructor() : FileParser { } if (description != null) { - if (description.isEmpty()) { + if (description.isBlank()) { description = null } } + + return Book( id = null, title = title, diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt index 35688701..dfbdb7af 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt @@ -32,15 +32,27 @@ class EpubTextParser @Inject constructor() : TextParser { for (spineReference in book.spine.spineReferences) { val resource = spineReference.resource val inputStream = resource.inputStream - val reader = - BufferedReader(InputStreamReader(inputStream, Charset.forName("UTF-8"))) + val reader = BufferedReader( + InputStreamReader( + inputStream, + Charset.forName("UTF-8") + ) + ) var line: String? + withContext(Dispatchers.IO) { + inputStream.close() + } + while (withContext(Dispatchers.IO) { reader.readLine() }.also { line = it } != null) { unformattedText.append(line).append("\n") } + + withContext(Dispatchers.IO) { + reader.close() + } } val stringWithIds = mutableListOf() diff --git a/app/src/main/java/ua/acclorite/book_story/data/repository/BookRepositoryImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/repository/BookRepositoryImpl.kt index 915605c7..faa10015 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/repository/BookRepositoryImpl.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/repository/BookRepositoryImpl.kt @@ -90,6 +90,11 @@ class BookRepositoryImpl @Inject constructor( return database.findBooksById(ids).map { bookMapper.toBook(it) } } + override suspend fun getBookTextById(bookId: Int): String { + val book = database.findBookById(bookId) + return book.text + } + override suspend fun findBook( id: Int ): BookEntity { @@ -101,11 +106,39 @@ class BookRepositoryImpl @Inject constructor( } override suspend fun updateBooks(books: List) { + // without text + database.updateBooks( + books.map { + val book = database.findBookById(it.id ?: return) + bookMapper.toBookEntity( + it.copy( + text = book.text + .split("\n") + .map { line -> StringWithId(line.trim()) } + ) + ) + } + ) + } + + override suspend fun updateBooksWithText(books: List) { database.updateBooks(books.map { bookMapper.toBookEntity(it) }) } override suspend fun deleteBooks(books: List) { - database.deleteBooks(books.map { bookMapper.toBookEntity(it) }) + // without text + database.deleteBooks( + books.map { + val book = database.findBookById(it.id ?: return) + bookMapper.toBookEntity( + it.copy( + text = book.text + .split("\n") + .map { line -> StringWithId(line.trim()) } + ) + ) + } + ) } override suspend fun retrieveDataFromDataStore( @@ -119,7 +152,7 @@ class BookRepositoryImpl @Inject constructor( dataStore.putData(key, value) } - override suspend fun getFilesFromDownloads(query: String): Flow>> { + override suspend fun getFilesFromDevice(query: String): Flow>> { fun getAllFilesInDirectory(directory: File): List { val filesList = mutableListOf() @@ -140,20 +173,15 @@ class BookRepositoryImpl @Inject constructor( } return flow { - emit(Resource.Loading(true)) - val existingBooks = database .searchBooks("") .map { bookMapper.toBook(it) } - .filter { it.file != null } - val allFiles = getAllFilesInDirectory( - Environment - .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - ) + val primaryDirectory = Environment.getExternalStorageDirectory() + val allFiles = getAllFilesInDirectory(primaryDirectory) if (allFiles.isEmpty()) { - emit(Resource.Loading(false)) + emit(Resource.Success(null)) return@flow } @@ -168,7 +196,8 @@ class BookRepositoryImpl @Inject constructor( ) } val isFileAlreadyAdded = existingBooks.all { - it.file != file + it.filePath.substringAfterLast("/") != + file.path.substringAfterLast("/") } val isQuery = if (query.isEmpty()) true else file.name.lowercase() .contains(query.trim().lowercase()) @@ -193,7 +222,6 @@ class BookRepositoryImpl @Inject constructor( }.toMutableList() } - emit(Resource.Loading(false)) emit( Resource.Success( data = filteredFiles diff --git a/app/src/main/java/ua/acclorite/book_story/domain/repository/BookRepository.kt b/app/src/main/java/ua/acclorite/book_story/domain/repository/BookRepository.kt index edf27f7d..30b09407 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/repository/BookRepository.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/repository/BookRepository.kt @@ -24,6 +24,10 @@ interface BookRepository { ids: List ): List + suspend fun getBookTextById( + bookId: Int + ): String + suspend fun findBook( id: Int ): BookEntity @@ -36,6 +40,10 @@ interface BookRepository { books: List ) + suspend fun updateBooksWithText( + books: List + ) + suspend fun deleteBooks( books: List ) @@ -50,7 +58,7 @@ interface BookRepository { value: T ) - suspend fun getFilesFromDownloads(query: String = ""): Flow>> + suspend fun getFilesFromDevice(query: String = ""): Flow>> suspend fun getBookTextFromFile(file: File): Flow>> diff --git a/app/src/main/java/ua/acclorite/book_story/domain/use_case/ChangeLanguage.kt b/app/src/main/java/ua/acclorite/book_story/domain/use_case/ChangeLanguage.kt index 99341fcc..f9c4ef1e 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/use_case/ChangeLanguage.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/use_case/ChangeLanguage.kt @@ -1,27 +1,17 @@ package ua.acclorite.book_story.domain.use_case import android.annotation.SuppressLint -import androidx.activity.ComponentActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.os.LocaleListCompat import ua.acclorite.book_story.domain.repository.BookRepository import ua.acclorite.book_story.util.DataStoreConstants -import java.util.Locale import javax.inject.Inject class ChangeLanguage @Inject constructor(private val repository: BookRepository) { @SuppressLint("AppBundleLocaleChanges") - suspend fun execute(language: String, activity: ComponentActivity) { - val config = activity.resources.configuration - val resources = activity.resources - val locale = Locale(language) - - Locale.setDefault(locale) - config.setLocale(locale) - - activity.createConfigurationContext(config) - resources.updateConfiguration( - config, - resources.displayMetrics - ) + suspend fun execute(language: String) { + val appLocale = LocaleListCompat.forLanguageTags(language) + AppCompatDelegate.setApplicationLocales(appLocale) repository.putDataToDataStore( DataStoreConstants.LANGUAGE, diff --git a/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDownloads.kt b/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDevice.kt similarity index 77% rename from app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDownloads.kt rename to app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDevice.kt index b2d15ef7..2afd126e 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDownloads.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetFilesFromDevice.kt @@ -6,11 +6,11 @@ import ua.acclorite.book_story.util.Resource import java.io.File import javax.inject.Inject -class GetFilesFromDownloads @Inject constructor( +class GetFilesFromDevice @Inject constructor( private val repository: BookRepository ) { suspend fun execute(query: String): Flow>> { - return repository.getFilesFromDownloads(query) + return repository.getFilesFromDevice(query) } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetText.kt b/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetText.kt index 7bfab049..3b84f33f 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetText.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/use_case/GetText.kt @@ -1,15 +1,11 @@ package ua.acclorite.book_story.domain.use_case -import kotlinx.coroutines.flow.Flow -import ua.acclorite.book_story.domain.model.StringWithId import ua.acclorite.book_story.domain.repository.BookRepository -import ua.acclorite.book_story.util.Resource -import java.io.File import javax.inject.Inject class GetText @Inject constructor(private val repository: BookRepository) { - suspend fun execute(file: File): Flow>> { - return repository.getBookTextFromFile(file) + suspend fun execute(id: Int): String { + return repository.getBookTextById(bookId = id) } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/use_case/UpdateBooksWithText.kt b/app/src/main/java/ua/acclorite/book_story/domain/use_case/UpdateBooksWithText.kt new file mode 100644 index 00000000..6aad3df0 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/domain/use_case/UpdateBooksWithText.kt @@ -0,0 +1,12 @@ +package ua.acclorite.book_story.domain.use_case + +import ua.acclorite.book_story.domain.model.Book +import ua.acclorite.book_story.domain.repository.BookRepository +import javax.inject.Inject + +class UpdateBooksWithText @Inject constructor(private val repository: BookRepository) { + + suspend fun execute(books: List) { + repository.updateBooksWithText(books) + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/AnimatedTopAppBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/AnimatedTopAppBar.kt index f68d490c..b1322265 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/AnimatedTopAppBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/AnimatedTopAppBar.kt @@ -1,8 +1,11 @@ package ua.acclorite.book_story.presentation.components +import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.RowScope @@ -22,8 +25,9 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import ua.acclorite.book_story.ui.DefaultTransition +import ua.acclorite.book_story.R import ua.acclorite.book_story.ui.elevation /** @@ -38,7 +42,7 @@ import ua.acclorite.book_story.ui.elevation @Composable fun AnimatedTopAppBar( containerColor: Color = MaterialTheme.colorScheme.surface, - scrolledContainerColor: Color? = MaterialTheme.elevation(), + scrolledContainerColor: Color = MaterialTheme.elevation(), scrollBehavior: TopAppBarScrollBehavior?, isTopBarScrolled: Boolean?, @@ -58,79 +62,90 @@ fun AnimatedTopAppBar( content3Title: @Composable () -> Unit = {}, content3Actions: @Composable RowScope.() -> Unit = {} ) { - //todo fix lags. Box(modifier = Modifier.fillMaxWidth()) { - if ((scrollBehavior != null || isTopBarScrolled != null) && scrolledContainerColor != null) { - - val fraction by remember { - derivedStateOf { - scrollBehavior?.state?.overlappedFraction ?: 0f - } - } - - val isScrolled = if (scrollBehavior != null) { - fraction > 0.01f - } else isTopBarScrolled ?: false - - val color = if (isScrolled) scrolledContainerColor else containerColor - val animatedColor by animateColorAsState( - targetValue = color, - animationSpec = spring(stiffness = Spring.StiffnessMediumLow), - label = "TopAppBar color animation" - ) - - val statusBarPadding = with(LocalDensity.current) { - WindowInsets.statusBars.getTop(LocalDensity.current).toDp() - } + val density = LocalDensity.current + val statusBarPadding = with(density) { + WindowInsets.statusBars.getTop(density).toDp() + } + if (containerColor != Color.Transparent) { Box( modifier = Modifier .fillMaxWidth() .height(64.dp + statusBarPadding) .background( - animatedColor + if (isTopBarScrolled == true) scrolledContainerColor + else containerColor ) ) } - DefaultTransition(visible = content1Visibility ?: true) { + val scrollableContainerColor by remember(isTopBarScrolled) { + derivedStateOf { + if (isTopBarScrolled == true) { + scrolledContainerColor + } else { + containerColor + } + } + } + + val animatedContainerColor by animateColorAsState( + targetValue = scrollableContainerColor, + animationSpec = spring(stiffness = Spring.StiffnessMediumLow), + label = stringResource(id = R.string.top_app_bar_anim_content_desc) + ) + + AnimatedVisibility( + visible = content1Visibility ?: true, + enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)), + exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow)) + ) { TopAppBar( navigationIcon = content1NavigationIcon, title = content1Title, actions = content1Actions, scrollBehavior = scrollBehavior, colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - scrolledContainerColor = Color.Transparent + containerColor = animatedContainerColor, + scrolledContainerColor = scrolledContainerColor ) ) } if (content2Visibility != null) { - DefaultTransition(visible = content2Visibility) { + AnimatedVisibility( + visible = content2Visibility, + enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)), + exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow)) + ) { TopAppBar( navigationIcon = content2NavigationIcon, title = content2Title, actions = content2Actions, scrollBehavior = scrollBehavior, colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - scrolledContainerColor = Color.Transparent + containerColor = animatedContainerColor, + scrolledContainerColor = scrolledContainerColor ) ) } } if (content3Visibility != null) { - DefaultTransition(visible = content3Visibility) { + AnimatedVisibility( + visible = content3Visibility, + enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)), + exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow)) + ) { TopAppBar( navigationIcon = content3NavigationIcon, title = content3Title, actions = content3Actions, scrollBehavior = scrollBehavior, colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - scrolledContainerColor = Color.Transparent + containerColor = animatedContainerColor, + scrolledContainerColor = scrolledContainerColor ) ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomCheckbox.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomCheckbox.kt index b63df96b..3c2cc67a 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomCheckbox.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomCheckbox.kt @@ -13,14 +13,17 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.R import ua.acclorite.book_story.ui.elevation /** * Custom Checkbox. Has a Circle shape. */ @Composable -fun CustomCheckbox(selected: Boolean) { +fun CustomCheckbox(selected: Boolean, size: Dp = 22.dp) { Icon( imageVector = Icons.Default.Check, tint = if (selected) MaterialTheme.elevation(elevation = 2.dp) else Color.Transparent, @@ -36,7 +39,7 @@ fun CustomCheckbox(selected: Boolean) { shape = CircleShape ) .padding(4.dp) - .size(22.dp), - contentDescription = "checkbox" + .size(size), + contentDescription = stringResource(id = R.string.checkbox_content_desc) ) } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt new file mode 100644 index 00000000..69604482 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt @@ -0,0 +1,45 @@ +package ua.acclorite.book_story.presentation.components + +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector + +/** + * Custom Icon Button. Can be disabled after click, so user can't press button fast 2 or 3 times. + */ +@Composable +fun CustomIconButton( + modifier: Modifier = Modifier, + icon: ImageVector, + contentDescription: String, + disableOnClick: Boolean, + enabled: Boolean = true, + color: Color = LocalContentColor.current, + onClick: () -> Unit +) { + var isClicked by remember { mutableStateOf(false) } + IconButton( + enabled = enabled && !isClicked, + onClick = { + if (disableOnClick) { + isClicked = true + } + onClick() + } + ) { + Icon( + imageVector = icon, + modifier = modifier, + contentDescription = contentDescription, + tint = color + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomSelectionContainer.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomSelectionContainer.kt index e67b4435..39577ccc 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomSelectionContainer.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomSelectionContainer.kt @@ -127,7 +127,6 @@ private class CustomSelectionToolbar( context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager override var status: TextToolbarStatus by mutableStateOf(TextToolbarStatus.Hidden) - private set override fun showMenu( rect: Rect, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/GoBackButton.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/GoBackButton.kt index 70afc399..c11e8360 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/GoBackButton.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/GoBackButton.kt @@ -2,14 +2,7 @@ package ua.acclorite.book_story.presentation.components import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.data.Navigator @@ -19,20 +12,12 @@ import ua.acclorite.book_story.presentation.data.Navigator */ @Composable fun GoBackButton(navigator: Navigator, customOnClick: () -> Unit = {}) { - var isClicked by remember { mutableStateOf(false) } - - IconButton( - enabled = !isClicked, - onClick = { - isClicked = true - navigator.navigateBack() - customOnClick() - } + CustomIconButton( + icon = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(id = R.string.go_back_content_desc), + disableOnClick = true ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(id = R.string.go_back_content_desc), - tint = MaterialTheme.colorScheme.onSurface - ) + navigator.navigateBack() + customOnClick() } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/MoreDropDown.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/MoreDropDown.kt index f71eb974..877ff562 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/MoreDropDown.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/MoreDropDown.kt @@ -2,13 +2,10 @@ package ua.acclorite.book_story.presentation.components import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -16,7 +13,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp @@ -31,19 +27,17 @@ import ua.acclorite.book_story.presentation.data.Screen fun MoreDropDown(navigator: Navigator) { var showDropDown by remember { mutableStateOf(false) } - val startPadding = 12.dp - val endPadding = 36.dp + val startPadding = remember { 12.dp } + val endPadding = remember { 36.dp } Box { - IconButton(onClick = { + CustomIconButton( + icon = Icons.Default.MoreVert, + contentDescription = stringResource(id = R.string.show_dropdown_content_desc), + disableOnClick = false, + enabled = !showDropDown + ) { showDropDown = true - }) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = "Show drop down", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) } DropdownMenu( @@ -51,7 +45,6 @@ fun MoreDropDown(navigator: Navigator) { onDismissRequest = { showDropDown = false }, offset = DpOffset(10.dp, 0.dp) ) { - DropdownMenuItem( text = { Text( 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 e2cb079d..f154b5d1 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 @@ -18,6 +18,8 @@ import ua.acclorite.book_story.ui.elevation /** * Bottom navigation bar, uses default [NavigationBar]. + * + * @param navigator Navigator. */ @Composable fun BottomNavigationBar( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationItem.kt index eda6f49f..4ab1c43c 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/bottom_navigation_bar/BottomNavigationItem.kt @@ -8,6 +8,7 @@ import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -23,6 +24,11 @@ fun RowScope.BottomNavigationBarItem( isSelected: Boolean, onClick: () -> Unit ) { + val icon = remember(isSelected) { + if (isSelected) item.selectedIcon + else item.unselectedIcon + } + NavigationBarItem( label = { Text( @@ -37,9 +43,7 @@ fun RowScope.BottomNavigationBarItem( onClick = { onClick() }, icon = { Icon( - painter = - if (isSelected) item.selectedIcon - else item.unselectedIcon, + painter = icon, contentDescription = item.title, modifier = Modifier.size(24.dp) ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithContent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithContent.kt index 0fc92a81..cba44a90 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithContent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithContent.kt @@ -20,6 +20,10 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -69,6 +73,7 @@ fun CustomDialogWithContent( withDivider: Boolean, customContent: @Composable (ColumnScope.() -> Unit) = {} ) { + var actionClicked by remember { mutableStateOf(false) } AlertDialog( onDismissRequest = { onDismiss() }, properties = properties @@ -151,7 +156,13 @@ fun CustomDialogWithContent( .align(Alignment.End) .padding(horizontal = 24.dp) ) { - TextButton(onClick = { onDismiss() }) { + TextButton( + onClick = { + actionClicked = true + onDismiss() + }, + enabled = !actionClicked + ) { Text( text = stringResource(id = R.string.cancel), style = MaterialTheme.typography.labelLarge, @@ -161,8 +172,11 @@ fun CustomDialogWithContent( if (actionText != null) { Spacer(modifier = Modifier.width(4.dp)) TextButton( - onClick = { onAction() }, - enabled = isActionEnabled == true + onClick = { + actionClicked = true + onAction() + }, + enabled = isActionEnabled == true && !actionClicked ) { Text( text = actionText, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithLazyColumn.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithLazyColumn.kt index 0e7ea033..cce7512f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithLazyColumn.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_dialog/CustomDialogWithLazyColumn.kt @@ -21,6 +21,10 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -71,6 +75,7 @@ fun CustomDialogWithLazyColumn( withDivider: Boolean, items: (LazyListScope.() -> Unit) = {} ) { + var actionClicked by remember { mutableStateOf(false) } AlertDialog( onDismissRequest = { onDismiss() }, properties = properties @@ -156,7 +161,13 @@ fun CustomDialogWithLazyColumn( .align(Alignment.End) .padding(horizontal = 24.dp) ) { - TextButton(onClick = { onDismiss() }) { + TextButton( + onClick = { + actionClicked = true + onDismiss() + }, + enabled = !actionClicked + ) { Text( text = stringResource(id = R.string.cancel), style = MaterialTheme.typography.labelLarge, @@ -166,8 +177,11 @@ fun CustomDialogWithLazyColumn( if (actionText != null) { Spacer(modifier = Modifier.width(4.dp)) TextButton( - onClick = { onAction() }, - enabled = isActionEnabled == true + onClick = { + actionClicked = true + onAction() + }, + enabled = isActionEnabled == true && !actionClicked ) { Text( text = actionText, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_navigation_rail/CustomNavigationRailItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_navigation_rail/CustomNavigationRailItem.kt index 80ed8e28..3339ec92 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_navigation_rail/CustomNavigationRailItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/custom_navigation_rail/CustomNavigationRailItem.kt @@ -7,6 +7,7 @@ import androidx.compose.material3.NavigationRailItem import androidx.compose.material3.NavigationRailItemDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -22,6 +23,11 @@ fun CustomNavigationRailItem( isSelected: Boolean, onClick: () -> Unit ) { + val icon = remember(isSelected) { + if (isSelected) item.selectedIcon + else item.unselectedIcon + } + NavigationRailItem( label = { Text( @@ -36,9 +42,7 @@ fun CustomNavigationRailItem( onClick = { onClick() }, icon = { Icon( - painter = - if (isSelected) item.selectedIcon - else item.unselectedIcon, + painter = icon, contentDescription = item.title, modifier = Modifier.size(24.dp) ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt index aa25f590..dfd3ba13 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt @@ -1,10 +1,7 @@ package ua.acclorite.book_story.presentation.data -import androidx.activity.ComponentActivity - sealed class MainEvent { - data class OnLocaleUpdate(val activity: ComponentActivity) : MainEvent() - data class OnChangeLanguage(val lang: String, val activity: ComponentActivity) : MainEvent() + data class OnChangeLanguage(val lang: String) : MainEvent() data class OnChangeTheme(val theme: String) : MainEvent() data class OnChangeDarkTheme(val darkTheme: String) : MainEvent() data class OnChangeFontFamily(val fontFamily: String) : MainEvent() diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt index 08020779..87831515 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt @@ -1,14 +1,12 @@ package ua.acclorite.book_story.presentation.data import android.os.Build -import androidx.activity.ComponentActivity import androidx.compose.ui.graphics.Color import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -44,12 +42,16 @@ class MainViewModel @Inject constructor( private val _isReady = MutableStateFlow(false) val isReady = _isReady.asStateFlow() - private val _updating = MutableStateFlow(false) - val updating = _updating.asStateFlow() - /* -- Language ----------------------------------------------------- */ private var _language: String = - stateHandle[Constants.LANGUAGE] ?: Locale.getDefault().language + stateHandle[Constants.LANGUAGE] + ?: if ( + Constants.LANGUAGES.any { Locale.getDefault().language.take(2) == it.first } + ) { + Locale.getDefault().language.take(2) + } else { + "en" + } set(value) { field = value stateHandle[Constants.LANGUAGE] = value @@ -172,23 +174,9 @@ class MainViewModel @Inject constructor( fun onEvent(event: MainEvent) { when (event) { is MainEvent.OnChangeLanguage -> { - viewModelScope.launch(Dispatchers.IO) { - _updating.update { true } - - changeLanguage.execute(event.lang, event.activity) + viewModelScope.launch(Dispatchers.Main) { + changeLanguage.execute(event.lang) _language = event.lang - delay(100) - - _updating.update { false } - } - } - - is MainEvent.OnLocaleUpdate -> { - viewModelScope.launch(Dispatchers.IO) { - _updating.update { true } - changeLanguage.execute(_language, event.activity) - delay(10) - _updating.update { false } } } @@ -266,7 +254,6 @@ class MainViewModel @Inject constructor( } fun init( - activity: ComponentActivity, libraryViewModel: LibraryViewModel, ) { val isViewModelsReady = combine( @@ -311,11 +298,11 @@ class MainViewModel @Inject constructor( } // Language - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(Dispatchers.Main) { getDatastore .execute(DataStoreConstants.LANGUAGE, _language) .first { - onEvent(MainEvent.OnChangeLanguage(it, activity)) + onEvent(MainEvent.OnChangeLanguage(it)) it.isNotBlank() } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/BookInfoScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/BookInfoScreen.kt index 9e417482..43c31bea 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/BookInfoScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/BookInfoScreen.kt @@ -26,7 +26,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Done import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.Refresh -import androidx.compose.material.pullrefresh.PullRefreshDefaults import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState @@ -34,7 +33,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButtonDefaults import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHostState @@ -58,6 +56,7 @@ import dagger.hilt.android.lifecycle.withCreationCallback import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomSnackbar import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.data.Argument @@ -114,8 +113,6 @@ fun BookInfoScreen( val snackbarState = remember { SnackbarHostState() } val refreshState = rememberPullRefreshState( refreshing = state.isRefreshing, - refreshThreshold = PullRefreshDefaults.RefreshThreshold + 32.dp, - refreshingOffset = PullRefreshDefaults.RefreshingOffset + 64.dp, onRefresh = { viewModel.onEvent( BookInfoEvent.OnUpdateBook( @@ -193,26 +190,21 @@ fun BookInfoScreen( } }, content1Actions = { - IconButton( - enabled = !state.isRefreshing, - onClick = { - viewModel.onEvent( - BookInfoEvent.OnUpdateBook( - refreshList = { - libraryViewModel.onEvent(LibraryEvent.OnLoadList) - historyViewModel.onEvent(HistoryEvent.OnLoadList) - }, - snackbarState, - context - ) - ) - } + CustomIconButton( + icon = Icons.Default.Refresh, + contentDescription = stringResource(id = R.string.refresh_book_content_desc), + disableOnClick = false, + enabled = !state.isRefreshing ) { - Icon( - imageVector = Icons.Default.Refresh, - contentDescription = stringResource(id = R.string.refresh_book_content_desc), - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant + viewModel.onEvent( + BookInfoEvent.OnUpdateBook( + refreshList = { + libraryViewModel.onEvent(LibraryEvent.OnLoadList) + historyViewModel.onEvent(HistoryEvent.OnLoadList) + }, + snackbarState, + context + ) ) } @@ -230,34 +222,30 @@ fun BookInfoScreen( enter = Transitions.DefaultTransitionIn, exit = fadeOut(tween(200)) ) { - IconButton( + CustomIconButton( + icon = Icons.Default.Done, + contentDescription = stringResource(id = R.string.apply_changes_content_desc), + disableOnClick = true, enabled = state.titleValue.isNotBlank() && - state.titleValue.trim() != state.book.title.trim(), - onClick = { - viewModel.onEvent(BookInfoEvent.OnUpdateTitle( - refreshList = { - libraryViewModel.onEvent( - LibraryEvent.OnLoadList - ) - } - )) - Toast.makeText( - context, - context.getString(R.string.title_changed), - Toast.LENGTH_LONG - ).show() - } + state.titleValue.trim() != + state.book.title.trim(), + color = if (state.titleValue.isNotBlank() + && state.titleValue != state.book.title + ) MaterialTheme.colorScheme.onSurface + else MaterialTheme.colorScheme.onSurfaceVariant ) { - Icon( - imageVector = Icons.Default.Done, - contentDescription = "Apply changes", - tint = - if (state.titleValue.isNotBlank() - && state.titleValue != state.book.title - ) - MaterialTheme.colorScheme.onSurface - else MaterialTheme.colorScheme.onSurfaceVariant - ) + viewModel.onEvent(BookInfoEvent.OnUpdateTitle( + refreshList = { + libraryViewModel.onEvent( + LibraryEvent.OnLoadList + ) + } + )) + Toast.makeText( + context, + context.getString(R.string.title_changed), + Toast.LENGTH_LONG + ).show() } } } @@ -354,7 +342,9 @@ fun BookInfoScreen( PullRefreshIndicator( state.isRefreshing, refreshState, - Modifier.align(Alignment.TopCenter), + Modifier + .align(Alignment.TopCenter) + .padding(top = paddingValues.calculateTopPadding()), backgroundColor = MaterialTheme.colorScheme.inverseSurface, contentColor = MaterialTheme.colorScheme.inverseOnSurface ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoInfoSection.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoInfoSection.kt index 06af60bf..6f81b150 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoInfoSection.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoInfoSection.kt @@ -36,10 +36,12 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel @@ -76,7 +78,7 @@ fun BookInfoInfoSection(viewModel: BookInfoViewModel, book: Book) { ) { Icon( imageVector = Icons.Default.Image, - contentDescription = "Cover Image not found", + contentDescription = stringResource(id = R.string.cover_image_not_found_content_desc), modifier = Modifier .align(Alignment.Center) .fillMaxWidth(0.7f) @@ -87,7 +89,7 @@ fun BookInfoInfoSection(viewModel: BookInfoViewModel, book: Book) { if (book.coverImage != null) { Image( bitmap = book.coverImage, - contentDescription = "Cover", + contentDescription = stringResource(id = R.string.cover_image_content_desc), modifier = Modifier .fillMaxSize() .clip(MaterialTheme.shapes.large), diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoMoreDropDown.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoMoreDropDown.kt index 61f1ef0a..6610347d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoMoreDropDown.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoMoreDropDown.kt @@ -1,26 +1,22 @@ package ua.acclorite.book_story.presentation.screens.book_info.components import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.DriveFileMove import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Info import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.components.CustomDropDownMenuItem +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel @@ -32,15 +28,13 @@ fun BookInfoMoreDropDown(viewModel: BookInfoViewModel, snackbarState: SnackbarHo val state by viewModel.state.collectAsState() Box { - IconButton(onClick = { + CustomIconButton( + icon = Icons.Default.MoreVert, + contentDescription = stringResource(id = R.string.show_dropdown_content_desc), + disableOnClick = false, + enabled = !state.showMoreDropDown + ) { viewModel.onEvent(BookInfoEvent.OnShowHideMoreDropDown) - }) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = "Show drop down", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) } DropdownMenu( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoStatisticSection.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoStatisticSection.kt index 4d0410ba..e22b9f4d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoStatisticSection.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/BookInfoStatisticSection.kt @@ -9,6 +9,7 @@ import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.res.stringResource @@ -24,18 +25,29 @@ import ua.acclorite.book_story.presentation.data.removeTrailingZero */ @Composable fun BookInfoStatisticSection(book: Book) { + val progress = remember(book) { + "${ + (book.progress * 100) + .toDouble() + .removeDigits(1) + .removeTrailingZero() + }%" + } + val description = if (book.progress < 1f) stringResource( + id = R.string.you_read_query, + progress + ) + " " + stringResource( + if (book.progress > 0.2f) R.string.read_keep + else R.string.read_more + ) else stringResource(id = R.string.read_done) + Column( Modifier .fillMaxWidth() .padding(horizontal = 24.dp) ) { Text( - text = "${ - (book.progress * 100) - .toDouble() - .removeDigits(1) - .removeTrailingZero() - }%", + text = progress, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyLarge ) @@ -53,16 +65,7 @@ fun BookInfoStatisticSection(book: Book) { Spacer(modifier = Modifier.height(6.dp)) Text( - text = if (book.progress < 1f) stringResource( - id = R.string.you_read_query, - (book.progress * 100) - .toDouble() - .removeDigits(1) - .removeTrailingZero() + "%" - ) + " " + stringResource( - if (book.progress > 0.2f) R.string.read_keep - else R.string.read_more - ) else stringResource(id = R.string.read_done), + text = description, color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.bodySmall, maxLines = 1, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/change_cover_bottom_sheet/BookInfoChangeCoverBottomSheet.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/change_cover_bottom_sheet/BookInfoChangeCoverBottomSheet.kt index 072a1d45..95b0d1ff 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/change_cover_bottom_sheet/BookInfoChangeCoverBottomSheet.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/change_cover_bottom_sheet/BookInfoChangeCoverBottomSheet.kt @@ -6,8 +6,10 @@ import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBars import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.HideImage import androidx.compose.material.icons.filled.ImageSearch @@ -44,7 +46,8 @@ fun BookInfoChangeCoverBottomSheet( ) { val state by viewModel.state.collectAsState() val context = LocalContext.current - val book = state.book + val navigationBarPadding = + WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() val photoPicker = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia(), @@ -89,7 +92,7 @@ fun BookInfoChangeCoverBottomSheet( ) } - if (book.coverImage != null) { + if (state.book.coverImage != null) { BookInfoChangeCoverBottomSheetItem( icon = Icons.Default.HideImage, text = stringResource(id = R.string.delete_cover), @@ -109,6 +112,10 @@ fun BookInfoChangeCoverBottomSheet( } } - Spacer(modifier = Modifier.height(48.dp)) + Spacer( + modifier = Modifier.height( + 8.dp + navigationBarPadding + ) + ) } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheet.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheet.kt index 7797eab8..d5a952df 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheet.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheet.kt @@ -3,8 +3,10 @@ package ua.acclorite.book_story.presentation.screens.book_info.components.detail import android.widget.Toast import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBars import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet @@ -12,6 +14,7 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -35,20 +38,32 @@ fun BookInfoDetailsBottomSheet( ) { val state by viewModel.state.collectAsState() val context = LocalContext.current + val navigationBarPadding = + WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() - val pattern = SimpleDateFormat("HH:mm dd MMM yyyy", Locale.getDefault()) - val lastOpened = pattern.format(Date(state.book.lastOpened ?: 0)) + val pattern = remember { + SimpleDateFormat("HH:mm dd MMM yyyy", Locale.getDefault()) + } + val lastOpened = remember { + pattern.format(Date(state.book.lastOpened ?: 0)) + } - val sizeBytes = state.book.file?.length() ?: 0 + val sizeBytes = remember { + state.book.file?.length() ?: 0 + } - val fileSizeKB = if (sizeBytes > 0) sizeBytes.toDouble() / 1024.0 else 0.0 - val fileSizeMB = if (sizeBytes > 0) fileSizeKB / 1024.0 else 0.0 + val fileSizeKB = remember { + if (sizeBytes > 0) sizeBytes.toDouble() / 1024.0 else 0.0 + } + val fileSizeMB = remember { + if (sizeBytes > 0) fileSizeKB / 1024.0 else 0.0 + } - val fileSize = + val fileSize = remember { if (fileSizeMB >= 1.0) "%.2f MB".format(fileSizeMB) else if (fileSizeMB > 0.0) "%.2f KB".format(fileSizeKB) else "" - + } ModalBottomSheet( modifier = Modifier.fillMaxWidth(), @@ -129,7 +144,10 @@ fun BookInfoDetailsBottomSheet( } } - - Spacer(modifier = Modifier.height(48.dp)) + Spacer( + modifier = Modifier.height( + 8.dp + navigationBarPadding + ) + ) } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheetItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheetItem.kt index 22cf689f..6bf9a574 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheetItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/components/details_bottom_sheet/BookInfoDetailsBottomSheetItem.kt @@ -34,9 +34,7 @@ fun BookInfoDetailsBottomSheetItem( modifier .fillMaxWidth() .combinedClickable( - onClick = { - - }, + onClick = {}, onLongClick = { onClick() } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/data/BookInfoViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/data/BookInfoViewModel.kt index 48511fe1..9d3b08a2 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/data/BookInfoViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/book_info/data/BookInfoViewModel.kt @@ -27,6 +27,7 @@ import ua.acclorite.book_story.domain.model.NullableBook import ua.acclorite.book_story.domain.use_case.DeleteBooks import ua.acclorite.book_story.domain.use_case.GetBookFromFile import ua.acclorite.book_story.domain.use_case.UpdateBooks +import ua.acclorite.book_story.domain.use_case.UpdateBooksWithText import ua.acclorite.book_story.presentation.data.Navigator import ua.acclorite.book_story.presentation.data.Screen @@ -35,6 +36,7 @@ import ua.acclorite.book_story.presentation.data.Screen class BookInfoViewModel @AssistedInject constructor( @Assisted book: Book, private val updateBooks: UpdateBooks, + private val updateBooksWithText: UpdateBooksWithText, private val deleteBooks: DeleteBooks, private val getBookFromFile: GetBookFromFile ) : ViewModel() { @@ -42,7 +44,7 @@ class BookInfoViewModel @AssistedInject constructor( private val _state = MutableStateFlow(BookInfoState(book)) val state = _state.asStateFlow() - var job: Job? = null + private var job: Job? = null fun onEvent(event: BookInfoEvent) { when (event) { @@ -286,7 +288,8 @@ class BookInfoViewModel @AssistedInject constructor( viewModelScope.launch(Dispatchers.IO) { _state.update { it.copy( - isRefreshing = true + isRefreshing = true, + editTitle = false ) } @@ -358,13 +361,20 @@ class BookInfoViewModel @AssistedInject constructor( _state.update { it.copy( book = it.book.copy( + author = updatedBook.author, + description = updatedBook.description + ) + ) + } + updateBooksWithText.execute( + listOf( + _state.value.book.copy( author = updatedBook.author, description = updatedBook.description, text = updatedBook.text ) ) - } - updateBooks.execute(listOf(_state.value.book)) + ) event.refreshList() onEvent( 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 36f6a1fa..e0e3c143 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 @@ -11,14 +11,10 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -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.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -29,8 +25,6 @@ import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text @@ -38,14 +32,14 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.snapshotFlow +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -55,11 +49,9 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.debounce import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.MoreDropDown import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.components.is_messages.IsError @@ -79,7 +71,7 @@ import ua.acclorite.book_story.ui.elevation ExperimentalMaterial3Api::class, ExperimentalPermissionsApi::class, ExperimentalFoundationApi::class, - ExperimentalMaterialApi::class, FlowPreview::class + ExperimentalMaterialApi::class ) @Composable fun BrowseScreen( @@ -98,34 +90,21 @@ fun BrowseScreen( } ) val focusRequester = remember { FocusRequester() } - val listState = rememberLazyGridState(state.scrollIndex, state.scrollOffset) + var showErrorMessage by remember { mutableStateOf(false) } - LaunchedEffect(listState) { - snapshotFlow { - listState.firstVisibleItemIndex - } - .debounce(10L) - .collectLatest { - viewModel.onEvent(BrowseEvent.OnUpdateScrollIndex(it)) - } - } - LaunchedEffect(listState) { - snapshotFlow { - listState.firstVisibleItemScrollOffset - } - .debounce(10L) - .collectLatest { - viewModel.onEvent( - BrowseEvent.OnUpdateScrollOffset(it) - ) - } - } LaunchedEffect(Unit) { - viewModel.onEvent(BrowseEvent.OnPermissionCheck(permissionState)) + viewModel.onEvent( + BrowseEvent.OnPermissionCheck( + permissionState, + hideErrorMessage = { showErrorMessage = false } + ) + ) } if (state.requestPermissionDialog) { - BrowseStoragePermissionDialog(viewModel, permissionState) + BrowseStoragePermissionDialog(viewModel, permissionState) { + showErrorMessage = it + } } if (state.showAddingDialog) { BrowseAddingDialog( @@ -146,7 +125,7 @@ fun BrowseScreen( scrolledContainerColor = MaterialTheme.elevation(), scrollBehavior = null, - isTopBarScrolled = state.scrollIndex > 0 || state.scrollOffset > 0 || state.hasSelectedItems, + isTopBarScrolled = state.hasSelectedItems || state.listState.canScrollBackward, content1Visibility = !state.hasSelectedItems && !state.showSearch, content1NavigationIcon = {}, @@ -160,26 +139,26 @@ fun BrowseScreen( ) }, content1Actions = { - IconButton(onClick = { viewModel.onEvent(BrowseEvent.OnSearchShowHide) }) { - Icon( - imageVector = Icons.Default.Search, - contentDescription = "Search files", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + CustomIconButton( + icon = Icons.Default.Search, + contentDescription = stringResource(id = R.string.search_content_desc), + disableOnClick = false, + enabled = !state.showSearch + ) { + viewModel.onEvent(BrowseEvent.OnSearchShowHide) } MoreDropDown(navigator = navigator) }, content2Visibility = state.hasSelectedItems, content2NavigationIcon = { - IconButton(onClick = { viewModel.onEvent(BrowseEvent.OnClearSelectedFiles) }) { - Icon( - imageVector = Icons.Default.Clear, - contentDescription = "Clear selected items", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurface - ) + CustomIconButton( + icon = Icons.Default.Clear, + contentDescription = + stringResource(id = R.string.clear_selected_items_content_desc), + disableOnClick = true + ) { + viewModel.onEvent(BrowseEvent.OnClearSelectedFiles) } }, content2Title = { @@ -195,25 +174,27 @@ fun BrowseScreen( ) }, content2Actions = { - IconButton(onClick = { viewModel.onEvent(BrowseEvent.OnAddingDialogRequest) }) { - Icon( - imageVector = Icons.Default.Check, - contentDescription = "Add files to library", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + CustomIconButton( + icon = Icons.Default.Check, + contentDescription = + stringResource(id = R.string.add_files_content_desc), + disableOnClick = false, + enabled = !state.showAddingDialog + ) { + viewModel.onEvent(BrowseEvent.OnAddingDialogRequest) } }, content3Visibility = state.showSearch && !state.hasSelectedItems, content3NavigationIcon = { - IconButton(onClick = { viewModel.onEvent(BrowseEvent.OnSearchShowHide) }) { - Icon( - imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = "Exit search mode", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurface - ) + CustomIconButton( + icon = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = stringResource( + id = R.string.exit_search_content_desc + ), + disableOnClick = true + ) { + viewModel.onEvent(BrowseEvent.OnSearchShowHide) } }, content3Title = { @@ -268,52 +249,54 @@ fun BrowseScreen( .fillMaxSize() .padding(top = padding.calculateTopPadding()) ) { - LazyVerticalGrid( - state = listState, - modifier = Modifier - .fillMaxSize(), - columns = GridCells.Adaptive(170.dp), - contentPadding = PaddingValues(12.dp) - ) { - items( - state.selectableFiles, - key = { it.first.path } - ) { selectableFile -> - BrowseFileItem( - file = selectableFile, - modifier = Modifier - .animateItemPlacement(), - onClick = { - viewModel.onEvent(BrowseEvent.OnSelectFile(selectableFile)) - } - ) + DefaultTransition(visible = !state.isLoading) { + LazyColumn( + state = state.listState, + modifier = Modifier + .fillMaxSize(), + contentPadding = PaddingValues(vertical = 8.dp) + ) { + items( + state.selectableFiles, + key = { it.first.path } + ) { selectableFile -> + BrowseFileItem( + file = selectableFile, + modifier = Modifier + .animateItemPlacement(), + hasSelectedFiles = state.selectableFiles.any { it.second }, + onClick = { + viewModel.onEvent(BrowseEvent.OnSelectFile(selectableFile)) + } + ) + } } } - if (state.isLoading && !state.isRefreshing && state.selectableFiles.isEmpty()) { - CircularProgressIndicator( - color = MaterialTheme.colorScheme.primary, - strokeCap = StrokeCap.Round, - modifier = Modifier - .align(Alignment.Center) - .size(36.dp) - ) - } - - DefaultTransition(visible = state.showErrorMessage, Modifier.align(Alignment.Center)) { + AnimatedVisibility( + visible = showErrorMessage, + modifier = Modifier.align(Alignment.Center), + enter = Transitions.DefaultTransitionIn, + exit = fadeOut(tween(0)) + ) { IsError( modifier = Modifier.align(Alignment.Center), errorMessage = stringResource(id = R.string.error_permission), icon = painterResource(id = R.drawable.error), actionTitle = stringResource(id = R.string.grant_permission) ) { - viewModel.onEvent(BrowseEvent.OnPermissionCheck(permissionState)) + viewModel.onEvent( + BrowseEvent.OnPermissionCheck( + permissionState, + hideErrorMessage = { showErrorMessage = false } + ) + ) } } AnimatedVisibility( visible = !state.isLoading && state.selectableFiles.isEmpty() - && !state.showErrorMessage && !state.requestPermissionDialog + && !showErrorMessage && !state.requestPermissionDialog && !state.isRefreshing, modifier = Modifier.align(Alignment.Center), enter = Transitions.DefaultTransitionIn, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseFIleItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseFIleItem.kt index af035842..d81c78a3 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseFIleItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseFIleItem.kt @@ -15,22 +15,25 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CheckCircle +import androidx.compose.material.icons.automirrored.filled.InsertDriveFile import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ua.acclorite.book_story.R +import ua.acclorite.book_story.presentation.components.CustomCheckbox import ua.acclorite.book_story.ui.DefaultTransition import java.io.File import java.text.SimpleDateFormat @@ -41,19 +44,24 @@ import java.util.Locale * Browse list element item. Can be selected. */ @Composable -fun BrowseFileItem(file: Pair, modifier: Modifier, onClick: () -> Unit) { - val fileExtension: String = file.first.name.substringAfterLast(".", "") +fun BrowseFileItem( + file: Pair, + hasSelectedFiles: Boolean, + modifier: Modifier, onClick: () -> Unit +) { + val pattern = remember { SimpleDateFormat("HH:mm dd MMM yyyy", Locale.getDefault()) } + val lastModified = remember { pattern.format(Date(file.first.lastModified())) } + val sizeBytes = remember { file.first.length() } - val pattern = SimpleDateFormat("HH:mm dd MMM", Locale.getDefault()) - - val lastModified = pattern.format(Date(file.first.lastModified())) - val icon = when (fileExtension) { - "txt" -> painterResource(id = R.drawable.txt) - "epub" -> painterResource(id = R.drawable.epub) - "pdf" -> painterResource(id = R.drawable.pdf) - else -> painterResource(id = R.drawable.file) + val fileSizeKB = remember { if (sizeBytes > 0) sizeBytes.toDouble() / 1024.0 else 0.0 } + val fileSizeMB = remember { if (sizeBytes > 0) fileSizeKB / 1024.0 else 0.0 } + val fileSize = remember { + if (fileSizeMB >= 1.0) "%.2f MB".format(fileSizeMB) + else if (fileSizeMB > 0.0) "%.2f KB".format(fileSizeKB) + else "0 KB" } - val outlineColor = if (file.second) MaterialTheme.colorScheme.primary + + val outlineColor = if (file.second) MaterialTheme.colorScheme.outline else MaterialTheme.colorScheme.outlineVariant val backgroundColor = if (file.second) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent @@ -61,90 +69,82 @@ fun BrowseFileItem(file: Pair, modifier: Modifier, onClick: () -> val animatedOutlineColor by animateColorAsState( targetValue = outlineColor, tween(300), - label = "Outline animation" + label = stringResource(id = R.string.outline_anim_content_desc) ) val animatedBackgroundColor by animateColorAsState( targetValue = backgroundColor, tween(300), - label = "Background animation" + label = stringResource(id = R.string.background_anim_content_desc) ) - Column( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, + Row( + verticalAlignment = Alignment.CenterVertically, modifier = modifier - .padding(6.dp) - .clip(MaterialTheme.shapes.medium) - .border( - width = 1.dp, - color = animatedOutlineColor, - shape = MaterialTheme.shapes.medium - ) - .padding(1.dp) + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 3.dp) + .clip(RoundedCornerShape(10.dp)) .background(animatedBackgroundColor) .clickable { onClick() } + .padding(horizontal = 8.dp, vertical = 7.dp) ) { - Icon( - painter = icon, - contentDescription = "File icon", - modifier = Modifier - .padding(vertical = 60.dp) - .size(70.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start, - modifier = Modifier - .background(MaterialTheme.colorScheme.surface) - .padding(horizontal = 10.dp, vertical = 12.dp) + modifier = Modifier.weight(0.88f) ) { - Box { - DefaultTransition(visible = !file.second) { - Icon( - painter = painterResource(R.drawable.file), - contentDescription = "File", - modifier = Modifier - .size(28.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant + Box( + modifier = Modifier + .border( + 1.dp, + animatedOutlineColor, + RoundedCornerShape(6.dp) ) - } - DefaultTransition(visible = file.second) { - Icon( - imageVector = Icons.Filled.CheckCircle, - contentDescription = "Checked", - modifier = Modifier - .size(28.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - Spacer(modifier = Modifier.width(8.dp)) - Column( - verticalArrangement = Arrangement.Center + .padding(14.dp), + contentAlignment = Alignment.Center ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.InsertDriveFile, + contentDescription = stringResource(id = R.string.file_icon_content_desc), + modifier = Modifier + .size(22.dp), + tint = MaterialTheme.colorScheme.primary + ) + } + Spacer(modifier = Modifier.width(12.dp)) + Column(verticalArrangement = Arrangement.Center) { Text( file.first.name, color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.labelMedium, - maxLines = 1, + style = MaterialTheme.typography.bodyLarge, + maxLines = 2, + lineHeight = 18.sp, overflow = TextOverflow.Ellipsis, modifier = Modifier.fillMaxWidth() ) - Spacer(modifier = Modifier.height(2.dp)) + Spacer(modifier = Modifier.height(4.dp)) Text( - lastModified, + "$fileSize, $lastModified", color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.bodySmall, - fontSize = 11.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.fillMaxWidth() ) } + } + Box( + modifier = Modifier + .weight(0.12f) + .padding(end = 6.dp), + contentAlignment = Alignment.CenterEnd + ) { + DefaultTransition( + visible = hasSelectedFiles + ) { + CustomCheckbox(selected = file.second, size = 18.dp) + } } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseStoragePermissionDialog.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseStoragePermissionDialog.kt index 887ac8cb..1db2f06e 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseStoragePermissionDialog.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/BrowseStoragePermissionDialog.kt @@ -19,7 +19,11 @@ import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel */ @OptIn(ExperimentalPermissionsApi::class) @Composable -fun BrowseStoragePermissionDialog(viewModel: BrowseViewModel, permissionState: PermissionState) { +fun BrowseStoragePermissionDialog( + viewModel: BrowseViewModel, + permissionState: PermissionState, + showErrorMessage: (Boolean) -> Unit +) { val activity = LocalContext.current as ComponentActivity CustomDialogWithContent( @@ -27,15 +31,28 @@ fun BrowseStoragePermissionDialog(viewModel: BrowseViewModel, permissionState: P description = stringResource(id = R.string.storage_permission_description), actionText = stringResource(id = R.string.grant), imageVectorIcon = Icons.Default.SdStorage, - onDismiss = { viewModel.onEvent(BrowseEvent.OnStoragePermissionDismiss(permissionState)) }, + onDismiss = { + viewModel.onEvent( + BrowseEvent.OnStoragePermissionDismiss( + permissionState, + showErrorMessage = { showErrorMessage(true) } + ) + ) + }, isActionEnabled = true, withDivider = false, onAction = { viewModel.onEvent( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - BrowseEvent.OnStoragePermissionRequest(activity) + BrowseEvent.OnStoragePermissionRequest( + activity, + hideErrorMessage = { showErrorMessage(false) } + ) } else { - BrowseEvent.OnLegacyStoragePermissionRequest(permissionState) + BrowseEvent.OnLegacyStoragePermissionRequest( + permissionState, + hideErrorMessage = { showErrorMessage(false) } + ) } ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialogItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialogItem.kt index 9bfd271c..307eb37f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialogItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/components/adding_dialog/BrowseAddingDialogItem.kt @@ -81,7 +81,7 @@ fun BrowseAddingDialogItem(result: NullableBook, onClick: (Boolean) -> Unit) { ) { Icon( imageVector = icon, - contentDescription = "Error", + contentDescription = stringResource(id = R.string.error_content_desc), modifier = Modifier.size(26.dp), tint = MaterialTheme.colorScheme.error ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseEvent.kt index 9992bd75..17e6b1bb 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseEvent.kt @@ -11,13 +11,24 @@ import ua.acclorite.book_story.presentation.data.Navigator import java.io.File sealed class BrowseEvent { - data class OnStoragePermissionRequest(val activity: ComponentActivity) : BrowseEvent() - data class OnLegacyStoragePermissionRequest(val permissionState: PermissionState) : - BrowseEvent() + data class OnStoragePermissionRequest( + val activity: ComponentActivity, val hideErrorMessage: () -> Unit + ) : BrowseEvent() + + data class OnLegacyStoragePermissionRequest( + val permissionState: PermissionState, val hideErrorMessage: () -> Unit + ) : BrowseEvent() + + data class OnStoragePermissionDismiss( + val permissionState: PermissionState, val showErrorMessage: () -> Unit + ) : BrowseEvent() - data class OnStoragePermissionDismiss(val permissionState: PermissionState) : BrowseEvent() data object OnRefreshList : BrowseEvent() - data class OnPermissionCheck(val permissionState: PermissionState) : BrowseEvent() + data class OnPermissionCheck( + val permissionState: PermissionState, + val hideErrorMessage: () -> Unit + ) : BrowseEvent() + data class OnSelectFile(val file: Pair) : BrowseEvent() data class OnSelectBook(val book: NullableBook) : BrowseEvent() data object OnSearchShowHide : BrowseEvent() @@ -29,8 +40,5 @@ sealed class BrowseEvent { data object OnGetBooksFromFiles : BrowseEvent() data class OnAddBooks(val navigator: Navigator, val resetScroll: () -> Unit) : BrowseEvent() data object OnLoadList : BrowseEvent() - data class OnUpdateScrollIndex(val index: Int) : BrowseEvent() - data class OnUpdateScrollOffset(val offset: Int) : BrowseEvent() - } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseState.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseState.kt index 12ad5af7..e6a412f4 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseState.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/browse/data/BrowseState.kt @@ -1,5 +1,6 @@ package ua.acclorite.book_story.presentation.screens.browse.data +import androidx.compose.foundation.lazy.LazyListState import androidx.compose.runtime.Immutable import ua.acclorite.book_story.domain.model.NullableBook import java.io.File @@ -7,10 +8,11 @@ import java.io.File @Immutable data class BrowseState( val selectableFiles: List> = emptyList(), + val listState: LazyListState = LazyListState(0, 0), + val isLoading: Boolean = true, val isRefreshing: Boolean = false, val requestPermissionDialog: Boolean = false, - val showErrorMessage: Boolean = false, val selectedItemsCount: Int = 0, val hasSelectedItems: Boolean = false, 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 bd4e0df8..f72c146c 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 @@ -5,6 +5,7 @@ import android.net.Uri import android.os.Build import android.os.Environment import android.provider.Settings +import androidx.compose.foundation.lazy.LazyListState import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.accompanist.permissions.ExperimentalPermissionsApi @@ -20,7 +21,7 @@ import kotlinx.coroutines.launch import ua.acclorite.book_story.domain.model.NullableBook import ua.acclorite.book_story.domain.use_case.FastGetBooks import ua.acclorite.book_story.domain.use_case.GetBooksFromFiles -import ua.acclorite.book_story.domain.use_case.GetFilesFromDownloads +import ua.acclorite.book_story.domain.use_case.GetFilesFromDevice import ua.acclorite.book_story.domain.use_case.InsertBooks import ua.acclorite.book_story.presentation.data.Argument import ua.acclorite.book_story.presentation.data.Screen @@ -31,7 +32,7 @@ import javax.inject.Inject @HiltViewModel class BrowseViewModel @Inject constructor( private val getBooksFromFiles: GetBooksFromFiles, - private val getFilesFromDownloads: GetFilesFromDownloads, + private val getFilesFromDevice: GetFilesFromDevice, private val insertBooks: InsertBooks, private val fastGetBooks: FastGetBooks ) : ViewModel() { @@ -65,10 +66,10 @@ class BrowseViewModel @Inject constructor( } _state.update { it.copy( - requestPermissionDialog = false, - showErrorMessage = false + requestPermissionDialog = false ) } + event.hideErrorMessage() onEvent(BrowseEvent.OnRefreshList) break } @@ -93,10 +94,10 @@ class BrowseViewModel @Inject constructor( } _state.update { it.copy( - requestPermissionDialog = false, - showErrorMessage = false + requestPermissionDialog = false ) } + event.hideErrorMessage() onEvent(BrowseEvent.OnRefreshList) break } @@ -112,8 +113,7 @@ class BrowseViewModel @Inject constructor( _state.update { it.copy( - requestPermissionDialog = false, - showErrorMessage = !isPermissionGranted + requestPermissionDialog = false ) } @@ -121,8 +121,9 @@ class BrowseViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { getFilesFromDownloads() } + } else { + event.showErrorMessage() } - } is BrowseEvent.OnRefreshList -> { @@ -131,7 +132,8 @@ class BrowseViewModel @Inject constructor( it.copy( isRefreshing = true, hasSelectedItems = false, - showSearch = false + showSearch = false, + listState = LazyListState(0, 0) ) } @@ -146,55 +148,72 @@ class BrowseViewModel @Inject constructor( } is BrowseEvent.OnPermissionCheck -> { - val legacyPermission = Build.VERSION.SDK_INT < Build.VERSION_CODES.R - val isPermissionGranted = - if (!legacyPermission) Environment.isExternalStorageManager() - else event.permissionState.status.isGranted + viewModelScope.launch(Dispatchers.IO) { + val legacyPermission = Build.VERSION.SDK_INT < Build.VERSION_CODES.R + val isPermissionGranted = + if (!legacyPermission) Environment.isExternalStorageManager() + else event.permissionState.status.isGranted - if (isPermissionGranted) { - return - } - _state.update { - it.copy( - requestPermissionDialog = true, - showErrorMessage = false - ) + if (isPermissionGranted) { + return@launch + } + + _state.update { + it.copy( + requestPermissionDialog = true + ) + } + event.hideErrorMessage() } } is BrowseEvent.OnSelectFile -> { - val indexOfFile = _state.value.selectableFiles.indexOf(event.file) - val editedList = _state.value.selectableFiles.toMutableList() - editedList[indexOfFile] = editedList[indexOfFile].copy( - second = !editedList[indexOfFile].second - ) + viewModelScope.launch(Dispatchers.IO) { + val indexOfFile = _state.value.selectableFiles.indexOf(event.file) - _state.update { - it.copy( - selectableFiles = editedList.toList(), - selectedItemsCount = editedList.filter { file -> file.second }.size, - hasSelectedItems = editedList.any { file -> file.second } + if (indexOfFile == -1) { + return@launch + } + + val editedList = _state.value.selectableFiles.toMutableList() + editedList[indexOfFile] = editedList[indexOfFile].copy( + second = !editedList[indexOfFile].second ) + + _state.update { + it.copy( + selectableFiles = editedList.toList(), + selectedItemsCount = editedList.filter { file -> file.second }.size, + hasSelectedItems = editedList.any { file -> file.second } + ) + } } } is BrowseEvent.OnSelectBook -> { - val indexOfFile = _state.value.selectedBooks.indexOf(event.book) - val editedList = _state.value.selectedBooks.toMutableList() - editedList[indexOfFile] = NullableBook.NotNull( - editedList[indexOfFile].book!!.copy( - second = !editedList[indexOfFile].book!!.second - ) - ) + viewModelScope.launch(Dispatchers.IO) { + val indexOfFile = _state.value.selectedBooks.indexOf(event.book) - if (!editedList.any { it.book?.second == true }) { - return - } + if (indexOfFile == -1) { + return@launch + } - _state.update { - it.copy( - selectedBooks = editedList + val editedList = _state.value.selectedBooks.toMutableList() + editedList[indexOfFile] = NullableBook.NotNull( + editedList[indexOfFile].book!!.copy( + second = !editedList[indexOfFile].book!!.second + ) ) + + if (!editedList.any { it.book?.second == true }) { + return@launch + } + + _state.update { + it.copy( + selectedBooks = editedList + ) + } } } @@ -331,35 +350,20 @@ class BrowseViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { _state.update { it.copy( - isLoading = true + isLoading = true, + listState = LazyListState(0, 0) ) } getFilesFromDownloads() } } - - is BrowseEvent.OnUpdateScrollIndex -> { - _state.update { - it.copy( - scrollIndex = event.index - ) - } - } - - is BrowseEvent.OnUpdateScrollOffset -> { - _state.update { - it.copy( - scrollOffset = event.offset - ) - } - } } } private suspend fun getFilesFromDownloads( query: String = if (_state.value.showSearch) _state.value.searchQuery else "" ) { - getFilesFromDownloads.execute(query).collect { result -> + getFilesFromDevice.execute(query).collect { result -> when (result) { is Resource.Success -> { _state.update { @@ -371,13 +375,7 @@ class BrowseViewModel @Inject constructor( } } - is Resource.Loading -> { - _state.update { - it.copy( - isLoading = result.isLoading - ) - } - } + is Resource.Loading -> Unit is Resource.Error -> Unit } 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 c8973853..4d269075 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 @@ -12,13 +12,10 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -28,24 +25,19 @@ import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource @@ -54,12 +46,10 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.debounce import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar import ua.acclorite.book_story.presentation.components.CategoryTitle +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomSnackbar import ua.acclorite.book_story.presentation.components.MoreDropDown import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty @@ -72,13 +62,14 @@ import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel +import ua.acclorite.book_story.ui.DefaultTransition import ua.acclorite.book_story.ui.Transitions import ua.acclorite.book_story.ui.elevation import java.util.UUID @OptIn( ExperimentalMaterial3Api::class, - ExperimentalMaterialApi::class, FlowPreview::class, ExperimentalFoundationApi::class + ExperimentalMaterialApi::class, ExperimentalFoundationApi::class ) @Composable fun HistoryScreen( @@ -89,7 +80,6 @@ fun HistoryScreen( val context = LocalContext.current val state by viewModel.state.collectAsState() val books = libraryViewModel.state.collectAsState().value.books.map { it.first } - val refreshState = rememberPullRefreshState( refreshing = state.isRefreshing, onRefresh = { @@ -98,28 +88,6 @@ fun HistoryScreen( ) val focusRequester = remember { FocusRequester() } val snackbarState = remember { SnackbarHostState() } - val listState = rememberLazyListState(state.scrollIndex, state.scrollOffset) - - LaunchedEffect(listState) { - snapshotFlow { - listState.firstVisibleItemIndex - } - .debounce(10L) - .collectLatest { - viewModel.onEvent(HistoryEvent.OnUpdateScrollIndex(it)) - } - } - LaunchedEffect(listState) { - snapshotFlow { - listState.firstVisibleItemScrollOffset - } - .debounce(10L) - .collectLatest { - viewModel.onEvent( - HistoryEvent.OnUpdateScrollOffset(it) - ) - } - } if (state.showDeleteWholeHistoryDialog) { HistoryDeleteWholeHistoryDialog(viewModel = viewModel, libraryViewModel = libraryViewModel) @@ -134,7 +102,7 @@ fun HistoryScreen( AnimatedTopAppBar( scrolledContainerColor = MaterialTheme.elevation(), scrollBehavior = null, - isTopBarScrolled = (state.scrollIndex > 0 || state.scrollOffset > 0) && !state.isLoading, + isTopBarScrolled = state.listState.canScrollBackward, content1Visibility = !state.showSearch, content1NavigationIcon = {}, @@ -148,43 +116,39 @@ fun HistoryScreen( ) }, content1Actions = { - IconButton( - enabled = !state.isRefreshing, - onClick = { viewModel.onEvent(HistoryEvent.OnSearchShowHide) } + CustomIconButton( + icon = Icons.Default.Search, + contentDescription = stringResource(id = R.string.search_content_desc), + disableOnClick = false, + enabled = !state.showSearch ) { - Icon( - imageVector = Icons.Default.Search, - contentDescription = "Search history", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + viewModel.onEvent(HistoryEvent.OnSearchShowHide) } - IconButton( + CustomIconButton( + icon = Icons.Outlined.DeleteSweep, + contentDescription = stringResource( + id = R.string.delete_whole_history_content_desc + ), + disableOnClick = false, enabled = !state.isLoading && !state.isRefreshing - && state.history.isNotEmpty(), - onClick = { - viewModel.onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog) - } + && state.history.isNotEmpty() ) { - Icon( - imageVector = Icons.Outlined.DeleteSweep, - contentDescription = "Delete whole history", - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + viewModel.onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog) } MoreDropDown(navigator = navigator) }, content2Visibility = state.showSearch, content2NavigationIcon = { - IconButton(onClick = { viewModel.onEvent(HistoryEvent.OnSearchShowHide) }) { - Icon( - imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = "Exit search mode", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurface - ) + CustomIconButton( + icon = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = stringResource( + id = R.string.exit_search_content_desc + ), + disableOnClick = true + ) { + viewModel.onEvent(HistoryEvent.OnSearchShowHide) } }, content2Title = { @@ -243,68 +207,72 @@ fun HistoryScreen( .fillMaxSize() .padding(top = paddingValues.calculateTopPadding()) ) { - LazyColumn( - Modifier - .fillMaxSize(), - state = listState, - contentPadding = PaddingValues(vertical = 12.dp) - ) { - if (!state.isLoading) { - state.history.forEachIndexed { index, groupedHistory -> - item(key = groupedHistory.title) { - if (index > 0) { + DefaultTransition(visible = !state.isLoading) { + LazyColumn( + Modifier + .fillMaxSize(), + state = state.listState, + contentPadding = PaddingValues(vertical = 12.dp) + ) { + if (!state.isLoading) { + state.history.forEachIndexed { index, groupedHistory -> + item(key = groupedHistory.title) { + if (index > 0) { + Spacer(modifier = Modifier.height(8.dp)) + } + + CategoryTitle( + modifier = Modifier.animateItemPlacement(), + title = when (groupedHistory.title) { + "today" -> stringResource(id = R.string.today) + "yesterday" -> stringResource(id = R.string.yesterday) + else -> groupedHistory.title + }, + padding = 16.dp + ) Spacer(modifier = Modifier.height(8.dp)) } - CategoryTitle( - modifier = Modifier.animateItemPlacement(), - title = when (groupedHistory.title) { - "today" -> stringResource(id = R.string.today) - "yesterday" -> stringResource(id = R.string.yesterday) - else -> groupedHistory.title - }, - padding = 16.dp - ) - Spacer(modifier = Modifier.height(8.dp)) - } + items( + groupedHistory.history, key = { it.id ?: UUID.randomUUID() } + ) { + val book = remember { + books.find { book -> book.id == it.bookId } + } ?: return@items - items( - groupedHistory.history, key = { it.id ?: UUID.randomUUID() } - ) { - val book = books.find { book -> book.id == it.bookId } ?: return@items - - HistoryItem( - modifier = Modifier.animateItemPlacement(), - history = it, - book = book, - onBodyClick = { - navigator.navigate( - Screen.BOOK_INFO, - false, - Argument("book", book) - ) - }, - onTitleClick = { - navigator.navigate( - Screen.READER, - false, - Argument("book", book) - ) - }, - isDeleteEnabled = !state.isRefreshing, - onDeleteClick = { - viewModel.onEvent( - HistoryEvent.OnDeleteHistoryElement( - historyToDelete = it, - snackbarState = snackbarState, - context = context, - refreshList = { - libraryViewModel.onEvent(LibraryEvent.OnLoadList) - } + HistoryItem( + modifier = Modifier.animateItemPlacement(), + history = it, + book = book, + onBodyClick = { + navigator.navigate( + Screen.BOOK_INFO, + false, + Argument("book", book) ) - ) - } - ) + }, + onTitleClick = { + navigator.navigate( + Screen.READER, + false, + Argument("book", book) + ) + }, + isDeleteEnabled = !state.isRefreshing, + onDeleteClick = { + viewModel.onEvent( + HistoryEvent.OnDeleteHistoryElement( + historyToDelete = it, + snackbarState = snackbarState, + context = context, + refreshList = { + libraryViewModel.onEvent(LibraryEvent.OnLoadList) + } + ) + ) + } + ) + } } } } @@ -322,15 +290,6 @@ fun HistoryScreen( icon = painterResource(id = R.drawable.empty_history) ) } - if (state.isLoading && !state.isRefreshing) { - CircularProgressIndicator( - color = MaterialTheme.colorScheme.primary, - strokeCap = StrokeCap.Round, - modifier = Modifier - .align(Alignment.Center) - .size(36.dp) - ) - } PullRefreshIndicator( state.isRefreshing, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/components/HistoryItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/components/HistoryItem.kt index b890e7a7..efc4efd0 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/components/HistoryItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/components/HistoryItem.kt @@ -23,6 +23,7 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -51,8 +52,10 @@ fun HistoryItem( isDeleteEnabled: Boolean, onDeleteClick: () -> Unit ) { - val date = Date(history.time) - val pattern = SimpleDateFormat("HH:mm", Locale.getDefault()) + val date = remember(history) { Date(history.time) } + val pattern = remember { + SimpleDateFormat("HH:mm", Locale.getDefault()) + } Row( verticalAlignment = Alignment.CenterVertically, @@ -65,7 +68,7 @@ fun HistoryItem( ) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.weight(0.9f) + modifier = Modifier.weight(0.89f) ) { Box( modifier = Modifier @@ -76,7 +79,9 @@ fun HistoryItem( ) { Icon( imageVector = Icons.Default.Image, - contentDescription = "Cover Image not found", + contentDescription = stringResource( + id = R.string.cover_image_not_found_content_desc + ), modifier = Modifier .align(Alignment.Center) .fillMaxWidth(0.7f) @@ -128,7 +133,7 @@ fun HistoryItem( ) } } - Box(modifier = Modifier.weight(0.1f), contentAlignment = Alignment.CenterEnd) { + Box(modifier = Modifier.weight(0.11f), contentAlignment = Alignment.CenterEnd) { IconButton( enabled = isDeleteEnabled, onClick = { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryEvent.kt index 668978bd..5318fe90 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryEvent.kt @@ -20,6 +20,4 @@ sealed class HistoryEvent { data class OnSearchQueryChange(val query: String) : HistoryEvent() data object OnSearchShowHide : HistoryEvent() data class OnRequestFocus(val focusRequester: FocusRequester) : HistoryEvent() - data class OnUpdateScrollIndex(val index: Int) : HistoryEvent() - data class OnUpdateScrollOffset(val offset: Int) : HistoryEvent() } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryState.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryState.kt index 0f0c6158..72ba639c 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryState.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryState.kt @@ -1,9 +1,12 @@ package ua.acclorite.book_story.presentation.screens.history.data +import androidx.compose.foundation.lazy.LazyListState import ua.acclorite.book_story.domain.model.GroupedHistory data class HistoryState( val history: List = emptyList(), + val listState: LazyListState = LazyListState(0, 0), + val isRefreshing: Boolean = false, val isLoading: Boolean = true, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryViewModel.kt index 055a05d4..8c50dc17 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/history/data/HistoryViewModel.kt @@ -1,5 +1,6 @@ package ua.acclorite.book_story.presentation.screens.history.data +import androidx.compose.foundation.lazy.LazyListState import androidx.compose.material3.SnackbarResult import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -58,7 +59,8 @@ class HistoryViewModel @Inject constructor( _state.update { it.copy( isRefreshing = true, - showSearch = false + showSearch = false, + listState = LazyListState(0, 0), ) } @@ -76,12 +78,11 @@ class HistoryViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { _state.update { it.copy( - isLoading = true + isLoading = true, + listState = LazyListState(0, 0), ) } getHistoryFromDatabase() - onEvent(HistoryEvent.OnUpdateScrollIndex(0)) - onEvent(HistoryEvent.OnUpdateScrollOffset(0)) } } @@ -89,7 +90,8 @@ class HistoryViewModel @Inject constructor( viewModelScope.launch { _state.update { it.copy( - showDeleteWholeHistoryDialog = false + showDeleteWholeHistoryDialog = false, + isLoading = true ) } @@ -109,7 +111,7 @@ class HistoryViewModel @Inject constructor( } is HistoryEvent.OnDeleteHistoryElement -> { - viewModelScope.launch { + viewModelScope.launch(Dispatchers.IO) { deleteHistory.execute( listOf(event.historyToDelete) ) @@ -186,22 +188,6 @@ class HistoryViewModel @Inject constructor( } } } - - is HistoryEvent.OnUpdateScrollIndex -> { - _state.update { - it.copy( - scrollIndex = event.index - ) - } - } - - is HistoryEvent.OnUpdateScrollOffset -> { - _state.update { - it.copy( - scrollOffset = event.offset - ) - } - } } } @@ -224,16 +210,12 @@ class HistoryViewModel @Inject constructor( getHistory.execute().collect { result -> when (result) { is Resource.Success -> { - _state.update { - it.copy( - history = emptyList() - ) - } val history = result.data?.sortedByDescending { it.time } ?: emptyList() if (history.isEmpty()) { _state.update { it.copy( + history = emptyList(), isLoading = false ) } 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 fa843c82..088ed1ea 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 @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -26,7 +25,6 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -38,8 +36,6 @@ import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text @@ -58,7 +54,6 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource @@ -74,6 +69,7 @@ import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.domain.model.Category import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.MoreDropDown import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.data.Argument @@ -87,6 +83,7 @@ import ua.acclorite.book_story.presentation.screens.library.components.dialog.Li import ua.acclorite.book_story.presentation.screens.library.components.dialog.LibraryMoveDialog import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel +import ua.acclorite.book_story.ui.DefaultTransition import ua.acclorite.book_story.ui.Transitions import ua.acclorite.book_story.ui.elevation import java.util.UUID @@ -178,26 +175,26 @@ fun LibraryScreen( } }, content1Actions = { - IconButton(onClick = { viewModel.onEvent(LibraryEvent.OnSearchShowHide) }) { - Icon( - imageVector = Icons.Default.Search, - contentDescription = "Search books", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + CustomIconButton( + icon = Icons.Default.Search, + contentDescription = stringResource(id = R.string.search_content_desc), + disableOnClick = false, + enabled = !state.showSearch + ) { + viewModel.onEvent(LibraryEvent.OnSearchShowHide) } MoreDropDown(navigator = navigator) }, content2Visibility = state.hasSelectedItems, content2NavigationIcon = { - IconButton(onClick = { viewModel.onEvent(LibraryEvent.OnClearSelectedBooks) }) { - Icon( - imageVector = Icons.Default.Clear, - contentDescription = "Clear selected items", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurface - ) + CustomIconButton( + icon = Icons.Default.Clear, + contentDescription = + stringResource(id = R.string.clear_selected_items_content_desc), + disableOnClick = true + ) { + viewModel.onEvent(LibraryEvent.OnClearSelectedBooks) } }, content2Title = { @@ -213,37 +210,38 @@ fun LibraryScreen( ) }, content2Actions = { - IconButton(onClick = { viewModel.onEvent(LibraryEvent.OnShowHideMoveDialog) }) { - Icon( - imageVector = Icons.AutoMirrored.Outlined.DriveFileMove, - contentDescription = "Move books to another category", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + CustomIconButton( + icon = Icons.AutoMirrored.Outlined.DriveFileMove, + contentDescription = stringResource( + id = R.string.move_books_content_desc + ), + disableOnClick = true + ) { + viewModel.onEvent(LibraryEvent.OnShowHideMoveDialog) } - IconButton(onClick = { viewModel.onEvent(LibraryEvent.OnShowHideDeleteDialog) }) { - Icon( - imageVector = Icons.Outlined.Delete, - contentDescription = "Delete books from database", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) + CustomIconButton( + icon = Icons.Outlined.Delete, + contentDescription = stringResource( + id = R.string.delete_books_content_desc + ), + disableOnClick = true + ) { + viewModel.onEvent(LibraryEvent.OnShowHideDeleteDialog) } }, content3Visibility = state.showSearch && !state.hasSelectedItems, content3NavigationIcon = { - IconButton(onClick = { + CustomIconButton( + icon = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = stringResource( + id = R.string.exit_search_content_desc + ), + disableOnClick = true + ) { viewModel.onEvent( LibraryEvent.OnSearchShowHide ) - }) { - Icon( - imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = "Exit search mode", - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurface - ) } }, content3Title = { @@ -307,7 +305,7 @@ fun LibraryScreen( HorizontalPager(state = pagerState, userScrollEnabled = !state.isRefreshing) { index -> var categoryIsLoading by remember { mutableStateOf(true) } val categorizedBooks = remember { mutableStateListOf>() } - val category = Category.entries[index] + val category = remember { Category.entries[index] } LaunchedEffect(state.books) { categorizedBooks.clear() @@ -321,13 +319,13 @@ fun LibraryScreen( } Box(modifier = Modifier.fillMaxSize()) { - LazyVerticalGrid( - columns = GridCells.Adaptive(120.dp), - modifier = Modifier - .fillMaxSize(), - contentPadding = PaddingValues(8.dp) - ) { - if (!state.isLoading) { + DefaultTransition(visible = !state.isLoading && !categoryIsLoading) { + LazyVerticalGrid( + columns = GridCells.Adaptive(120.dp), + modifier = Modifier + .fillMaxSize(), + contentPadding = PaddingValues(8.dp) + ) { items( categorizedBooks, key = { it.first.id ?: UUID.randomUUID() } @@ -363,16 +361,6 @@ fun LibraryScreen( } } - if (state.isLoading && !state.isRefreshing) { - CircularProgressIndicator( - color = MaterialTheme.colorScheme.primary, - strokeCap = StrokeCap.Round, - modifier = Modifier - .align(Alignment.Center) - .size(36.dp) - ) - } - AnimatedVisibility( visible = !state.isLoading && !state.isRefreshing && categorizedBooks.isEmpty() && !categoryIsLoading, @@ -404,7 +392,7 @@ fun LibraryScreen( val activity = LocalContext.current as ComponentActivity val scope = rememberCoroutineScope() - var shouldExit = false + var shouldExit = remember { false } BackHandler { if (state.hasSelectedItems) { viewModel.onEvent(LibraryEvent.OnClearSelectedBooks) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryBookItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryBookItem.kt index a097aafc..69db8aaf 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryBookItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryBookItem.kt @@ -25,14 +25,17 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.presentation.data.removeDigits import ua.acclorite.book_story.presentation.data.removeTrailingZero @@ -55,6 +58,15 @@ fun LibraryBookItem( val fontColor = if (book.second) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurface + val progress = remember(book.first) { + "${ + (book.first.progress * 100) + .toDouble() + .removeDigits(1) + .removeTrailingZero() + }%" + } + val animatedBackgroundColor by animateColorAsState( targetValue = backgroundColor, tween(300), @@ -93,7 +105,9 @@ fun LibraryBookItem( ) { Icon( imageVector = Icons.Default.Image, - contentDescription = "Cover Image not found", + contentDescription = stringResource( + id = R.string.cover_image_not_found_content_desc + ), modifier = Modifier .align(Alignment.Center) .fillMaxWidth(0.7f) @@ -104,7 +118,7 @@ fun LibraryBookItem( if (book.first.coverImage != null) { Image( bitmap = book.first.coverImage!!, - contentDescription = "Cover", + contentDescription = stringResource(id = R.string.cover_image_content_desc), modifier = Modifier .fillMaxSize() .clip(MaterialTheme.shapes.large), @@ -113,12 +127,7 @@ fun LibraryBookItem( } Text( - "${ - (book.first.progress * 100) - .toDouble() - .removeDigits(1) - .removeTrailingZero() - }%", + progress, textAlign = TextAlign.Center, color = MaterialTheme.colorScheme.onPrimary, modifier = Modifier diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryTabRow.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryTabRow.kt index 32cda42e..efbc3e97 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryTabRow.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/components/LibraryTabRow.kt @@ -18,11 +18,12 @@ import androidx.compose.material3.TabRowDefaults import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book @@ -37,24 +38,27 @@ import ua.acclorite.book_story.ui.elevation @OptIn(ExperimentalFoundationApi::class) @Composable fun LibraryTabRow(viewModel: LibraryViewModel, books: List, pagerState: PagerState) { - val tabItems = listOf( - Pair( - stringResource(id = R.string.reading_tab), - books.filter { it.category == Category.READING }.size - ), - Pair( - stringResource(id = R.string.already_read_tab), - books.filter { it.category == Category.ALREADY_READ }.size - ), - Pair( - stringResource(id = R.string.planning_tab), - books.filter { it.category == Category.PLANNING }.size - ), - Pair( - stringResource(id = R.string.dropped_tab), - books.filter { it.category == Category.DROPPED }.size + val context = LocalContext.current + val tabItems = remember(books) { + listOf( + Pair( + context.getString(R.string.reading_tab), + books.filter { it.category == Category.READING }.size + ), + Pair( + context.getString(R.string.already_read_tab), + books.filter { it.category == Category.ALREADY_READ }.size + ), + Pair( + context.getString(R.string.planning_tab), + books.filter { it.category == Category.PLANNING }.size + ), + Pair( + context.getString(R.string.dropped_tab), + books.filter { it.category == Category.DROPPED }.size + ) ) - ) + } if (LocalConfiguration.current.screenWidthDp > 450) { TabRow( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/data/LibraryViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/data/LibraryViewModel.kt index 4f0c27a4..65020b90 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/data/LibraryViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/library/data/LibraryViewModel.kt @@ -156,18 +156,25 @@ class LibraryViewModel @Inject constructor( } is LibraryEvent.OnSelectBook -> { - val indexOfBook = _state.value.books.indexOf(event.book) - val editedList = _state.value.books.toMutableList() - editedList[indexOfBook] = editedList[indexOfBook].copy( - second = event.select ?: !editedList[indexOfBook].second - ) + viewModelScope.launch(Dispatchers.IO) { + val indexOfBook = _state.value.books.indexOf(event.book) - _state.update { - it.copy( - books = editedList.toList(), - selectedItemsCount = editedList.filter { book -> book.second }.size, - hasSelectedItems = editedList.any { book -> book.second } + if (indexOfBook == -1) { + return@launch + } + + val editedList = _state.value.books.toMutableList() + editedList[indexOfBook] = editedList[indexOfBook].copy( + second = event.select ?: !editedList[indexOfBook].second ) + + _state.update { + it.copy( + books = editedList.toList(), + selectedItemsCount = editedList.filter { book -> book.second }.size, + hasSelectedItems = editedList.any { book -> book.second } + ) + } } } @@ -252,7 +259,8 @@ class LibraryViewModel @Inject constructor( viewModelScope.launch { _state.update { it.copy( - showDeleteDialog = false + showDeleteDialog = false, + isLoading = true ) } @@ -269,17 +277,20 @@ class LibraryViewModel @Inject constructor( } is LibraryEvent.OnUpdateBook -> { - val books = _state.value.books.toMutableList() + viewModelScope.launch(Dispatchers.IO) { + val books = _state.value.books.toMutableList() + val index = books.indexOfFirst { it.first.id == event.book.id } + + if (index == -1) { + return@launch + } - val index = books.indexOfFirst { it.first.id == event.book.id } - if (index != -1) { books[index] = Pair(event.book, books[index].second) - } - - _state.update { - it.copy( - books = books - ) + _state.update { + it.copy( + books = books + ) + } } } } @@ -300,14 +311,7 @@ class LibraryViewModel @Inject constructor( } } - is Resource.Loading -> { - _state.update { - it.copy( - isLoading = result.isLoading - ) - } - } - + is Resource.Loading -> Unit is Resource.Error -> Unit } } 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 5459a8f9..aed7ebdb 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 @@ -150,16 +150,19 @@ fun ReaderScreen( } ) } + LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex - }.debounce(50).collectLatest { + }.debounce(1000).collectLatest { if (!loading) { + val lastVisibleItemIndex = listState.layoutInfo.visibleItemsInfo.last().index + val progress = if (it > 0) { - if ((it + listState.layoutInfo.visibleItemsInfo.size) >= state.book.text.lastIndex) { + if (lastVisibleItemIndex >= (listState.layoutInfo.totalItemsCount - 1)) { 1f } else { - (it.toFloat() / (state.book.text.size - 1).toFloat()) + (it.toFloat() / (state.book.text.lastIndex).toFloat()) } } else { 0f @@ -264,10 +267,10 @@ fun ReaderScreen( LazyColumn( state = listState, modifier = Modifier + .fillMaxSize() .then( if (!loading && toolbarShowed) { Modifier - .fillMaxSize() .clickable( interactionSource = null, indication = null, @@ -279,7 +282,6 @@ fun ReaderScreen( ) } else { Modifier - .fillMaxSize() } ) ) { @@ -293,7 +295,11 @@ fun ReaderScreen( itemsIndexed( state.book.text, key = { _, key -> key.id } - ) { index, text -> + ) { index, line -> + val text = remember { "${if (paragraphIndentation) " " else ""}${line.line}" } + val color = remember { Color(fontColor.toULong()) } + val lineHeightSp = remember { (fontSize + lineHeight).sp } + Column( Modifier .background(Color(backgroundColor.toULong())) @@ -307,8 +313,8 @@ fun ReaderScreen( ) ) { Text( - text = "${if (paragraphIndentation) " " else ""}${text.line}", - color = Color(fontColor.toULong()), + text = text, + color = color, style = TextStyle( lineBreak = LineBreak.Paragraph @@ -316,7 +322,7 @@ fun ReaderScreen( fontFamily = fontFamily.font, fontStyle = fontStyle, fontSize = fontSize.sp, - lineHeight = (fontSize + lineHeight).sp + lineHeight = lineHeightSp ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderStartItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderStartItem.kt index d209e611..e99104be 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderStartItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderStartItem.kt @@ -64,7 +64,7 @@ fun ReaderStartItem(viewModel: ReaderViewModel) { ) { Icon( imageVector = Icons.Default.Image, - contentDescription = "Cover Image not found", + contentDescription = stringResource(id = R.string.cover_image_not_found_content_desc), modifier = Modifier .align(Alignment.Center) .fillMaxWidth(0.7f) @@ -75,7 +75,7 @@ fun ReaderStartItem(viewModel: ReaderViewModel) { if (state.book.coverImage != null) { Image( bitmap = state.book.coverImage!!, - contentDescription = "Cover", + contentDescription = stringResource(id = R.string.cover_image_content_desc), modifier = Modifier .fillMaxSize() .clip(MaterialTheme.shapes.medium), diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderBottomBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderBottomBar.kt index ea21c461..e20b452b 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderBottomBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderBottomBar.kt @@ -14,7 +14,9 @@ import androidx.compose.material3.SliderDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -39,7 +41,15 @@ fun ReaderBottomBar( systemBarsColor: Color ) { val state by viewModel.state.collectAsState() - val book = state.book + val progress by remember(state.book.progress) { + derivedStateOf { + (state.book.progress * 100) + .toDouble() + .removeDigits(4) + .removeTrailingZero() + .dropWhile { it == '-' } + "%" + } + } Column( Modifier @@ -57,17 +67,12 @@ fun ReaderBottomBar( verticalArrangement = Arrangement.Center ) { Text( - text = - (book.progress * 100) - .toDouble() - .removeDigits(4) - .removeTrailingZero() - .dropWhile { it == '-' } + "%", + text = progress, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.titleLarge ) Slider( - value = book.progress, + value = state.book.progress, onValueChange = { viewModel.onEvent( ReaderEvent.OnChangeProgress( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderTopBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderTopBar.kt index 678b341a..80b91f51 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderTopBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/app_bar/ReaderTopBar.kt @@ -3,20 +3,18 @@ package ua.acclorite.book_story.presentation.screens.reader.components.app_bar import androidx.activity.ComponentActivity import androidx.compose.foundation.basicMarquee import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -27,6 +25,7 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp import ua.acclorite.book_story.R +import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.data.Argument import ua.acclorite.book_story.presentation.data.Navigator @@ -44,7 +43,16 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColor: Color) { val context = LocalContext.current as ComponentActivity val state by viewModel.state.collectAsState() - val book = state.book + + val progress by remember(state.book.progress) { + derivedStateOf { + (state.book.progress * 100) + .toDouble() + .removeDigits(2) + .removeTrailingZero() + .dropWhile { it == '-' } + "%" + } + } TopAppBar( navigationIcon = { @@ -55,7 +63,7 @@ fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColo title = { Column(verticalArrangement = Arrangement.Center) { Text( - book.title, + state.book.title, fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 20.sp, @@ -63,7 +71,7 @@ fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColo maxLines = 1, modifier = Modifier .clickable( - interactionSource = remember { MutableInteractionSource() }, + interactionSource = null, indication = null, onClick = { navigator.navigateWithoutBackStack( @@ -71,7 +79,7 @@ fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColo true, Argument( "book", - book + state.book ) ) } @@ -83,11 +91,7 @@ fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColo Text( stringResource( id = R.string.read_query, - (book.progress * 100) - .toDouble() - .removeDigits(2) - .removeTrailingZero() - .dropWhile { it == '-' } + "%" + progress ), color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.bodyLarge @@ -95,13 +99,12 @@ fun ReaderTopBar(viewModel: ReaderViewModel, navigator: Navigator, containerColo } }, actions = { - IconButton(onClick = { + CustomIconButton( + icon = Icons.Default.Settings, + contentDescription = stringResource(id = R.string.open_reader_settings_content_desc), + disableOnClick = false + ) { viewModel.onEvent(ReaderEvent.OnShowHideSettingsBottomSheet) - }) { - Icon( - imageVector = Icons.Default.Settings, - contentDescription = stringResource(id = R.string.open_reader_settings_content_desc), - ) } }, colors = TopAppBarDefaults.topAppBarColors( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/settings_bottom_sheet/ReaderSettingsBottomSheet.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/settings_bottom_sheet/ReaderSettingsBottomSheet.kt index fe09675c..3abe97d1 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/settings_bottom_sheet/ReaderSettingsBottomSheet.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/settings_bottom_sheet/ReaderSettingsBottomSheet.kt @@ -74,15 +74,18 @@ fun ReaderSettingsBottomSheet(mainViewModel: MainViewModel, viewModel: ReaderVie val backgroundColor = mainViewModel.backgroundColor.collectAsState().value!! val fontColor = mainViewModel.fontColor.collectAsState().value!! - val scrimColor = - if (currentPage == 1) Color.Transparent else BottomSheetDefaults.ScrimColor + val scrimColor = if (currentPage == 1) Color.Transparent + else BottomSheetDefaults.ScrimColor + val animatedScrimColor by animateColorAsState( targetValue = scrimColor, animationSpec = tween(300), label = "Scrim animation" ) - val height = if (currentPage == 1) 0.5f else 0.7f + val height = remember(currentPage) { + if (currentPage == 1) 0.5f else 0.7f + } val animatedHeight by animateFloatAsState( targetValue = height, animationSpec = tween(300), diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderEvent.kt index 92bcc2e9..ec1f6afe 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderEvent.kt @@ -15,7 +15,8 @@ sealed class ReaderEvent { val scrollState: LazyListState, val navigator: Navigator, val refreshList: (Book) -> Unit, - val onLoaded: () -> Unit + val onLoaded: () -> Unit, + val onTextIsEmpty: () -> Unit ) : ReaderEvent() data class OnShowHideMenu(val show: Boolean? = null, val context: ComponentActivity) : diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderState.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderState.kt index 5bca3077..318d066b 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderState.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderState.kt @@ -13,9 +13,6 @@ data class ReaderState( val errorMessage: UIText? = null, val showMenu: Boolean = false, - val showSettingsBottomSheet: Boolean = false, val currentPage: Int = 0, - - - ) \ No newline at end of file +) \ No newline at end of file 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 c6d59ae0..042913e7 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 @@ -26,6 +26,8 @@ import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.domain.model.Category import ua.acclorite.book_story.domain.model.History +import ua.acclorite.book_story.domain.model.StringWithId +import ua.acclorite.book_story.domain.use_case.GetText import ua.acclorite.book_story.domain.use_case.InsertHistory import ua.acclorite.book_story.domain.use_case.UpdateBooks import ua.acclorite.book_story.presentation.data.Argument @@ -40,7 +42,8 @@ import kotlin.math.roundToInt class ReaderViewModel @AssistedInject constructor( @Assisted book: Book, private val updateBooks: UpdateBooks, - private val insertHistory: InsertHistory + private val insertHistory: InsertHistory, + private val getText: GetText ) : ViewModel() { private val _state = MutableStateFlow(ReaderState(book)) @@ -59,14 +62,27 @@ class ReaderViewModel @AssistedInject constructor( is ReaderEvent.OnLoadText -> { viewModelScope.launch(Dispatchers.IO) { + val text = getText.execute(_state.value.book.id!!) + + if (text.isBlank()) { + event.onTextIsEmpty() + } + val time = Date().time - val text = _state.value.book.text.joinToString(separator = " ") { it.line } - val letters = text.replace(" ", "").length - val words = text.split("\\s+".toRegex()).size + val letters = text + .replace("\n", "") + .length + val words = text + .replace("\n", " ") + .split("\\s+".toRegex()) + .size _state.update { it.copy( book = it.book.copy( + text = text + .split("\n") + .map { line -> StringWithId(line.trim()) }, lastOpened = time ), letters = letters, @@ -98,14 +114,20 @@ class ReaderViewModel @AssistedInject constructor( val scrollTo = (itemsCount * _state.value.book.progress).roundToInt() if (itemsCount >= _state.value.book.text.size) { if (scrollTo > 0) { - while (true) { + var loaded = false + for (i in 1..100) { try { event.scrollState.scrollToItem(scrollTo) + loaded = true break } catch (e: Exception) { - delay(50) + delay(100) } } + + if (!loaded) { + event.onTextIsEmpty() + } } delay(100) @@ -172,12 +194,12 @@ class ReaderViewModel @AssistedInject constructor( } updateBooks.execute( - listOf(_state.value.book) + listOf(_state.value.book.copy(progress = event.progress)) ) event.navigator.putArgument( - Argument("book", _state.value.book) + Argument("book", _state.value.book.copy(progress = event.progress)) ) - event.refreshList(_state.value.book) + event.refreshList(_state.value.book.copy(progress = event.progress)) } } @@ -290,21 +312,20 @@ class ReaderViewModel @AssistedInject constructor( ReaderState(book = book) } - if (book.text.isEmpty()) { - onEvent(ReaderEvent.OnTextIsEmpty(onLoaded = { onLoaded() })) - } else { - onEvent(ReaderEvent.OnShowHideMenu(false, context)) - onEvent( - ReaderEvent.OnLoadText( - scrollState, - navigator, - refreshList = { refreshList(it) }, - onLoaded = { - onLoaded() - } - ) + onEvent(ReaderEvent.OnShowHideMenu(false, context)) + onEvent( + ReaderEvent.OnLoadText( + scrollState, + navigator, + refreshList = { refreshList(it) }, + onLoaded = { + onLoaded() + }, + onTextIsEmpty = { + onEvent(ReaderEvent.OnTextIsEmpty(onLoaded = { onLoaded() })) + } ) - } + ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/SettingsScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/SettingsScreen.kt index c2f2e0bd..43f034fd 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/SettingsScreen.kt @@ -1,7 +1,9 @@ package ua.acclorite.book_story.presentation.screens.settings +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 @@ -21,6 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.data.Navigator @@ -97,6 +100,8 @@ fun SettingsScreen( navigator.navigate(Screen.READER_SETTINGS, false) } } + + item { Spacer(modifier = Modifier.height(48.dp)) } } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/ColorPickerWithTitle.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/ColorPickerWithTitle.kt index 2906f581..c48b675d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/ColorPickerWithTitle.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/components/ColorPickerWithTitle.kt @@ -119,7 +119,7 @@ private fun RevertibleSlider( ) { Icon( imageVector = Icons.Default.History, - contentDescription = "Revert to initial", + contentDescription = stringResource(id = R.string.revert_content_desc), modifier = Modifier .size(28.dp), tint = if (initialValue == value.first) MaterialTheme.colorScheme.onSurfaceVariant diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/AppearanceSettings.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/AppearanceSettings.kt index cff4c1bb..76f360f4 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/AppearanceSettings.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/AppearanceSettings.kt @@ -160,6 +160,8 @@ fun AppearanceSettings( } ) } + + item { Spacer(modifier = Modifier.height(48.dp)) } } } } \ No newline at end of file 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 0a73e1b6..9274a3d1 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 @@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -31,8 +32,10 @@ fun AppearanceSettingsThemeSwitcher( val theme = mainViewModel.theme.collectAsState().value!! val darkTheme = mainViewModel.darkTheme.collectAsState().value!! - val themes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Constants.THEMES - else Constants.THEMES.dropWhile { it.first == Theme.DYNAMIC } + val themes = remember { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Constants.THEMES + else Constants.THEMES.dropWhile { it.first == Theme.DYNAMIC } + } Column( Modifier diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcherItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcherItem.kt index e4bdd814..75df2813 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcherItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/appearance/components/theme_switcher/AppearanceSettingsThemeSwitcherItem.kt @@ -27,8 +27,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.R import ua.acclorite.book_story.ui.Theme import ua.acclorite.book_story.ui.colorScheme import ua.acclorite.book_story.util.UIText @@ -83,7 +85,7 @@ fun AppearanceSettingsThemeSwitcherItem( Spacer(modifier = Modifier.width(8.dp)) Icon( imageVector = Icons.Default.CheckCircle, - contentDescription = null, + contentDescription = stringResource(id = R.string.selected_content_desc), modifier = Modifier .size(26.dp), tint = diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/general/GeneralSettings.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/general/GeneralSettings.kt index 2d2d8160..24e1e168 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/general/GeneralSettings.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/general/GeneralSettings.kt @@ -1,8 +1,9 @@ package ua.acclorite.book_story.presentation.screens.settings.nested.general -import androidx.activity.ComponentActivity +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 @@ -18,8 +19,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.LocalContext 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.ChipItem import ua.acclorite.book_story.presentation.components.GoBackButton @@ -42,7 +43,6 @@ fun GeneralSettings( listState.canScrollForward } ) - val context = LocalContext.current as ComponentActivity val language = mainViewModel.language.collectAsState().value!! @@ -84,16 +84,17 @@ fun GeneralSettings( MaterialTheme.typography.labelLarge, it.first == language ) - } + }.sortedBy { it.title } ) { mainViewModel.onEvent( MainEvent.OnChangeLanguage( - it.id, - context + it.id ) ) } } + + item { Spacer(modifier = Modifier.height(48.dp)) } } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/ReaderSettings.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/ReaderSettings.kt index a1b10ba3..13c36694 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/ReaderSettings.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/ReaderSettings.kt @@ -212,6 +212,8 @@ fun ReaderSettings( ) } } + + item { Spacer(modifier = Modifier.height(48.dp)) } } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/app_icon_colored.png b/app/src/main/res/drawable/app_icon_colored.png index 3615361af6de979e8547b96fe7228e6f97e6d84c..1cc515bb8490ba961fd0d3a8a4b5731b45a9708b 100644 GIT binary patch literal 10209 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 URIV5Q{oD>*)HT+rKJOUwKNt=KZU6uP literal 29654 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 W!OwNF)$ke!{L|LZSFcpHjrd diff --git a/app/src/main/res/drawable/app_icon_monochrome.png b/app/src/main/res/drawable/app_icon_monochrome.png index 0bc46a280f339ed26136d5c3857f1eda9cb735ed..434255d9ef2cf3e62756f5ce5e96a6390ca60190 100644 GIT binary patch literal 4129 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 literal 5996 zcmeI0iC2@?w!jYo1w{s>iV}uetK3^5*fIpgfMRjDRH#Y@3V~26hyemZ2=kytsu0lH zf(l60D)SnYcTblObpG?lL*yC1 zn!#h$SSD`Y`q!we{RV3hI(e63yggl~Y^I--Y&L%4E|Iln@a6t2!L#e(Wmig6sf&u` zq(O>m@GGs9|7X+0rLnLn1Wr08O@RH;OU=^|KT@cEcoVNzJ=#0E_Xe@FCTaOF6)UF6 zsotM8gdsZYn~4f%I21bMx5#X(<*KYTs&EFGL53JeQ3W22xDTV3n|Cq_@HSQMjY-QR zX-Zd6cqWXxpDO6#{J}jz^$|ZB*j*ee>`~7)7H6aknzwg{a&IO3Duhxam<-XdXjy+( zO`Kk)LxPWD242J!B{)T(UP3&yq6;lP2kW~O*i@>|%!>-_u%GX$Isq9nQgF2PVGhX= z73uWhPHIc?5d|4$Kn`|a@*6&;D)3fDdKqn7P>Ghxlvp7I)<8i!9H+ZXSC698PRlx(=5vAAEQKY2haC$D&~ zy64tL9W+&v@1jH&x0$=9(1;2%*cbic&Wme^j$xRE&&ZhaOn5j6PeX!eYf)3=?p?p< zLX-;B@ZNN4(10vQ1l<_qWT!}aHh|gVt@W2L?%u53_UiSkgZd5hX4|u`(298qWtWqM zI@E&kZue#uWo&KRJZXv>lPN3T{1BoarpVw4&BSR)O!aGOjZ0uZp*sQj;7w;URDtp8IS(H?J_c*d< z+o;3^rnua_NuRM0;4}O%<;ic0l!*KJDFg)zNq?g()HFG@CANI@PFD<_=0`43tV1c{ zi&8vf%U+DzM2dpbj(2%AOf5TQdFg|| z+x&hFhBbNORxC%Xlupv|!A#bf=e?CT1_)N^QQa9DWR6=pWL4|!2qb*GByNOtp zk2wD<-X)zB;<5ME`ftkm5-0g3OlY8IS4Q{CkULQ{B?a2$hW;PVV)Avz$ZEXl*Q zZS8qg^WpXydPt<`qo;U7=ao8(;sDxdagfS9{Oht$KxjIufkKXM`We>?!Nb;B3?2t zAH?lhQ0$)j}h;sxG!BrH(NKHX6~n{S7ueNfBCTG&ew+3r<+Z|?AQ=$5W^|S zBO__1D_y*ocCs5eSWz&>o}G8*Ouo}XslUSd%jV}!Hlxw0mUh$6c-yl)nCf7KiG|^P z0=plQGu72|(9BeXx}@a<2Z|*VW0Wa`&mc-K z6V6yalq_)xLkI&@66uXx+=H4ihO+6PSc9fF?2oyG)4Yl^M|7<6Ht%rih0-fxCk9wJ z6aPj_i>`D{ffNIqyivO6gezLZwY{tgQJGUEI7~w_S^QA|i;U|%O-{=O7Yli--525} zs;krk!$gkJyAf&Lom|psv|sz^)#UW~`wcR#zH_fC@pSVX;=F>}$ero)D#;@n0JI$u zL>eIUC9kBz5i5~J*v02q^Y*QvIx62!(_CYb7H(|p|M(G|FQ(m@t4qU;AHWk=&V!D| zJ$-~f7G%I++bg_|TgZ6g%SM zLQcK%8V{qY-tq6zRY5omBguTNdxdgXy2jfaVS5V33_w2+dd)0~*I?S4T;p&0W$yj(4k~F-JI*9h6$j-g%b;=m}is9pc34xhPGK;y*bn@sr=1<;HJ~d8|FW9?+o- zB&g=^>^edlvve`@mZF5Qkicfxqxp4u3za-2;C>IaT7;Xag7u>}yyo7q-|v#2BU zIoJ(=)Y=$A9*?Tfan(V9O2LC7)E_f{Rdfqce{eN@tAOo6kg3?Cz5OHk7MW(%(v5k@ zSp*4(u222Nqc3{JI?Jp^Dp%dfNCLLe$n>Si14bQdOaUNyYW=LsoFWVYe&PJeH~|L_)ca7$|@;>wyP;&g3~fJ~}ec&Egj)+t%-^Q%^s z5?HIsmW77y=$K#i0D+xj|8dNO_^v7I%9o∋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 diff --git a/app/src/main/res/drawable/browse_screen_outlined.png b/app/src/main/res/drawable/browse_screen_outlined.png index 5f6fcb62192d92f7ec62fa25cb8a18c9869ed0a9..e0616ccee783fbf94bfb6b85bcc6abee90378fdb 100644 GIT binary patch literal 10620 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 literal 18232 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 JPDHLkV1k&TzeE54 diff --git a/app/src/main/res/drawable/empty_browse.png b/app/src/main/res/drawable/empty_browse.png index 1990e698e23e3a1b96fe338b70419a2d65713333..f1798e6c641d7df4676f6509587aec26bb812463 100644 GIT binary patch literal 10238 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 O5Z=u8Sec3EfBzpY57+tt diff --git a/app/src/main/res/drawable/empty_history.png b/app/src/main/res/drawable/empty_history.png index 897c6ea44e437c7361d8d3df361d2789db8a0b5a..0e5ab0e84dbf87a4424f07fb8b65d3c657d4d017 100644 GIT binary patch literal 10438 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 literal 16973 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 Wd9QYh#)F@JfbdrKxa$3c%l`xX6|EZp diff --git a/app/src/main/res/drawable/empty_library.png b/app/src/main/res/drawable/empty_library.png index 5242d51e4599c46d98438f37cd89b618d97359ef..dace3dc0186a951f798b7028b99ea69b938e9235 100644 GIT binary patch literal 9535 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 WThl!?vYr6=vD$ZdZ^0gqEB_133V-PU literal 15682 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 NYJ8OV$jIgI{|_hSSUdm# diff --git a/app/src/main/res/drawable/epub.png b/app/src/main/res/drawable/epub.png deleted file mode 100644 index 7a86421a25669d6e65b3c2258253e0d712cac8e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9986 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 Cl?0vu diff --git a/app/src/main/res/drawable/error.png b/app/src/main/res/drawable/error.png index 095830526a8deef51f1fa08bb25ebb45bd118ea8..abee5e8ae9f33f9632ccd71e6e6a2082e867a52f 100644 GIT binary patch literal 1776 zcmchY{Zms{8pqE$IfQe8;Jpc$5V71O;sR1&Ep=S0_5>0FRUxAe6A<;Ps9Q@*w3HWx zdUB-_Uex$jGnU#6+Ag}bi#npMI(wPbf!)qp-PWyBStixizNt-JUzk$0H~Lfmf!>*C zzRx+&^EuD+%$z%?-CgR^#hK#(0J@T5$9w>g>LP$NswjKZclV{PjXFlw2tN(Wm^=n?Q*3{p8^yr&K z)56zI<%{#^7U{aCXAd*k_c0Tsv{SOei*slPu!v3|xUE4Cy`$%?3Lyf+b!4)cKZC1@ z8%@P|Fj;Pob>u<;bu$9(bdxkSiptC)+Nt0cgH=&f3=_f!a3kKS^Dja9=uNPNO;)VI zW;G}Z5nPNBN|g^1HJF5AV4SZNY?9WXo;|=v3mFxy%oaSvzD)-M+Fx$Rr<3P*EPGL*m;7WND2$4PbN*pyK3!EANuplDLJ=Q>|3&l)hJ^RPWnI^>*k> zl`8~wocSb+9N>5HLt^mRXtpo3nIgO3dkr7UQY&TKdaZq3p)Ms$t}v?U`r*OV1(Y+%Na$9Mx zY2qYQ|4$o zh88LoxoI_xjG-#!e64ORj3q}G6;>%wZmOjh78O=2r9UR_fVt#9r#4k9@p4lG?K`!p zMmhfqe+-t9+Y`>#CZ}hs@rdk(q>lv4gjh;?P4exEKy}CuO1f>wO*}G6B|m4wKO>(!ChG)|1U$ zZXZKC*ixcAkyWc{_|88y=Tw3>=nqe5%a~Ez4@b6E2s>f0Zw+X`gx~C3Ut&s;8JEg(4?|RA1^+L@k zO;7PX+&=$7;qfm9JC2Vle<|(h&!4aQTgz!_jGenD?0ir-?aE+R|G3JR)1JNZe9eiL zVegpo^}X$%J}5kKWpL|>aZ75`X1(K5v}YG6C!dox#1-2_%|7lcApk$Yx5*G|IHvzwyW&f=z915O%~Dhyde=xUxcZ0wt;{ff_ngLnrC zvK6QV&!yeC>lEtW$&!#Y+(i@BYgZ(;G2;J}tu0gP%>g@$?KTu!6wP_=03U{Hg}htj zat_jyFq?u>uvba;C7|hIj;5$ZsZZ(K3UntY2Po548Hz=!xjIkjO}spUvu!{#B6wUt zd)lVvB=}Fj{nMlk6Z$$pd}CQ?boRgobnZU4+!DGod!V0pH@zdhK{MrK^e$PRDc#Zc zI{J!2{D9e4fRC8+)^ne!KcaiHw40{Lo0uG| z1DojJCFR@nP$AO?ER-AKajM!#FCWGZ;zd?$kD_Lr06DaoVY@quBIu%w*+j}$tEgg= zxC_LC^5sypiSe+EITV8^w2EqrVLpSnNfOS$7ET?=gv|&e9Yl7&IuA_sb$~AF1V#K& zc5x1HhHSukK>$K)o{B1b21m&*EMkjJMR{DQzFSX2VE1c^l6{ZhrT=oyw!M4zMxUM% LXQ|_Z0!jWA-P2XB literal 4347 zcmeI0|5Fop8poggutH)ZB!EgdN1N6d z!<*N>^5(Ork&_t6~3wb)V^kf%3TGOyDD~U-PL4obU;&6(~9l&Pwm`dZ*Z*G(YUQ|&J+(I zZ?-Ub8=F1Y2g0i5l!MNtW}>DnbgTjntPXN}m|Q6}XqbsIA(F#^^dNVD;ihSBx7$3ZPz)NV z!MK^IIxC%43~7G}gk>wJ`=a51A;`VUa5XeX+~x+kVo**QvSy+ZP|FAFUjt!!)a1~E zZQ~603C*>;%?63Wu!=G$XQE{5XlpT8v29N@6%!3T*ydxnTAHI#lPU}f%3z#{vZ9s` zGHmNXO%8jo?GuLc(Hx6w!!`qDz_q2Vqh-Y)!?pv_R9H0Z!M16Jv(X&5&E@&Di~$dJ zI2cY%b6tpvX<06K(7(fQ<1{CAn{%TT4a=zpybAX^B*rcG#kwJep0&a(dUg5qY!TF+1+>WmCiG+$ z+LQ-V=*dcGQxQy|XU(HcxzH-40(!~K}K+b@)F`yZXg9jo&URd}H&9Hh;r8m1Vg4?A3v7s`Q0r&?eYlX?-h++N(Oz zE(tvJJZ?yKxyJY6=U@oJQ6_hP7_MvM?+>w;1#r?tJ|_t7?fXb_W+BW(aS_XtPw4Qb zK<1T#+yZ{xl^uL8E3XoG9R;1 z;ptD)R`Sm2j_M-wiG47uo5SEYdHs z)6Xp%Y>H6^Vy_cxM1vOQ;VqqF>QZdNvY=9 zO*h*loVQImu#W2!HqD?XD%sa0T=mMoUz7xnVMx8FBP%R!vuF0%H>=(q{${AmB*!OJ@=ZJy_8XgH&~eYo|I1lT3`SQc`= zS>;+sL++mcd=lI~%+SDn*>=eF<(P`v5BMhS^OpsGSP2S%iI&XZctj{Xm4HpD`jzX; z@$UeiE_-jCo*9@5Xw;}ozL6EQG+wAWo9TM{PUH9bahD}{^VC+1(CP4+H_bP{b_|GFTK?%E%hK!%++`=ng8NeY$w{h@XUuo9@;?H|d5)_fYQe+#(qDNRk_R4sp34Z}jJ z;qPi;PDnOhrG_~zfsU=bN(+g|I%@d=H6#kGh9A&EzrbvKwHo@7l{)xpEmR>Zwey*3 zs6rO$;4?Llfh-c47BcX(oyc^Mfk&NozDW%kIszFEzDWa4^l;HlT5zIQRl_&wz=>Xe z4IiZjCwhsPG!Tj2940M9qF0|DjEI4VXbM#6LA@LzVkp=V7wVC)F`a-DN@yeT;TtV= z8(*e_QY~ROcwInzwTQOx5lIlPCTz6Vr6xAH1}Z&%l^fzZC9uT7M`$5DnXs4QLU~e_ z>H?d>>#`ABxdwVs^FUm$1auBwuZD0vVaMY_76~iu1RJ(#h%H(JaUTDG8+x%V95pTI zuq^uO% zhDvO6qNar<*me*#DZ2pMlD#fFu|2GT=3o1(Jy3~l{k8mk67~`fg?ZkQc1Xn&%~pmq z1Rs%M*v3ytSd9h(?f#WoxQu^jrFY~AK8g^w+U;6J;VhE7cBZ-%Vq>WCi9j-Z)CFg@ z@D>ep;_JKvw`s625NikyB|)Hs=3aN3?@DkKqy`ga-rGmR-A<^)=k^N1Ms-1NzyDJm z#hqrrIuZCPh2lyyaB2&G;Q-E|nC$!ooI_V=pko`~f-9-VS(b){e=} zx8Pj6OarCp;c0Ehghz4yO~GBUjlYgFu>;c<{yNUxF}S0U;Vixy6Ed8qD{wa=!x?)g zCS*8wFV#TRR{lE9;<#7)G2wjvs0I?Z@>w{ul%XMlIOQmlGB*fOCT$QAlp!DlQEVDTJzP-~ zf!9t52($x(OhIrsh+y9qL_uYUpdbjrgrOO3rPq4z|6BKO*IHR8RcF`U-~Os<*WM?? z&1JiStfnjgDB$cZy8)=^FBN2@(c@eEt2y+b#W>;~GN>iV1pkcs%cI!7F#w7!k{{)Q zq2ekusBvVg&k^@Sp-1BOMu$LLT%5^)$ncn;y-^`1hoZx-jN54fs7T>kHhIM7jlBym z4T|tycz0cbrsEh zzfLaORr>GDZMQkb*Y~v$Z)JbG?-s6GudcH@%`vlH`O@c*q~Ba@Ev{Nv4Bwqj?t0rX zoSo;incb01zFiWH{W#j_EphF?Y4oZaTo8x*5$@S}If8E&Qj)h4*SwRH_kZkYE|ET= z$5FU`XLAX?Z|hUc#+E#3XkYFc&HlUvjEpI6qcd3JIl(X3u>PALZ53gU4DYcmM)nYO z2ILJqtMq$1FN?+>&>{o`=51heEp`PwRDr3u{X_|oq(h$V%A$f4#VjyPZ}wAb0hnp# zuPZpKLd@?aQqE-CgRVf9|D|4+e4w!gU>m8*dtmNH_(j*cOMO6U~J>s*E2 z3xZmWhUMRy27LEFG3K2~^iE$A#tG?`gD0wgVN)m-=3iZ+-3i@dIwj{(Np{k@t`%x* zDE;7SFgrCdq%U<}%@d@~M5g$7 zb%ysfAzkBaVHajQWGDBcdRY|bbqlFo6q2YDvl_%-ZxQ~UESf_EBUo|8#}P&6=s2RF zlu5f(GO{7cxC+GcO9=Pe>}f}k1G`CLN4EF{3< z{8f9Td=0!Iw${jHk^e0M7v926ikK%3C`0X@02c72zt0h<;4XKVCq5T7%x_TZA?$Mc zZGpEDQS94G?ar>E-wiDT`S)4|DV({0s{(gC3(cQYfwU?Q2AJs%KSmbNew>()uW&+M zrS1N?d0}ZOvr+C-(OiuEXcz>{eSM!VNVi#3)NfPe3GTl#rNX^Ry=JRr4Cm2h`4x9c1kHu{2xH5%XM4HwerqmxUebu)yAUB`1 za4VYY(@tw;=(v?|6-onA>R1)#RRD8$(USr%uT;@3^#CTs{PY!p3oPqG7o^~(D9jrj zLjOQJy4>z#6K9()ZRGLyd6uUJ`K9FJl0#EW-@91MSTtAfp)2|1p;b6NdUh<;IbIrg ztb|043Ke)4kp&6`_&-H3{G(BS;Wt)P#@gD$8&60XZ9_&*ik^!3dY%&XE0FpmkMdM^ z-xMV5h<2^I(?=mhmc-Zd63B&r(3QIVM4H_PB}%qPsQx6T&|;BZ+cM-t)`>7g1lA+9-4UQ- zKN{cx6doT-eT>w5Mlg)7*KrZi^2M(mB*;P}3MMEg8YKM=zL-yya6AK!ft}%nqA;r- zsg-RO0H;&OQswjk)aB3s8^BDzl5QelIs!2bCqJ&%`c%qQxWD+NU@SGp3ptz0(D~+B zFa2YRVw;$6Q;dM~=}L1ytRdSUeQ4Ar`%gBe$Re&(IsmSI?>GNvfzjfEdz2&5f!X}V zJr|-2y!NcMiwl9KX!!6B;tE;{r{z$1Z^RI$)s`05+L)3L4v%s}Y4FnbD8yGEJZ6Ht zv5?FQ2$=uVK3kCZ*uv=rJ=@=x)v`_r9Kvp`Tw1)9J?}Xw?|x5@d`i^a=AOH)B6;D- zI48I)|K~g3THSSZ7JaWqHr;eWu+FRori+l?x!LJu2BO;C&iQjDukfBhwpPL1(Y|L` zfopW^q?Y@U?L<}R%x=A|CRK!Qkf^KV{*2kPh3(jfQfBb+_On&=NW|2`+CnZ*btzjg zhBI%Y@j6zN6axRwubAH5d<<`A3p+Z~oX(AgfZ zZC}~3PS2K@ccQ(zTup@|RmNmZ=jOVWEcuJ~Q;f*%gU^q5jhq}yz2(7Jx2z11hY zlws#)ExtK!LPpgN9K{1J?43UDy}W$9U%p%^xs-d(Tm>aK>XA})M&xt}J$370Ip9<) zOx)|-%wMw{cunFF3g>(;HA)WDzw8jI;N#^?ni_JI*OY^47cr@7k5$1Nc<=Ie3I{dv z*POaBBn$jVzwEk3u8a@O8~iCC7W)(Th+aRIOk1`gKw{5j!P%f=!K4kJA{ITtygeC| zDS;Z#5BMWY=V)%yRimA)$Ux`Se+eGWF!XZ%1<>8NlbH7sDVZ@^yNscapN|WNut0PJ zh2khc_VqQK?{DINUC}|Y7*qp(Q~f&f4xVM4FBQ5Cp!9_=9_bRjMWkaUM+MH930pYn zW9v&*+{Y8u7?I8>;b77%n>X{ARGQ^bCHB=x7%bAMP^LNntcr6bGP9Fvxk^5!C^lM- zw_$MxHdT@?1uAUH+0ltaNsx1h<6jJ2y6Q*NnFi>z(26{HZ)(<)&3Lj!m-n{zzbKlm zHXzIOW_KgqnkQw=w8KK;;Sl1Fs zmgG?lruuyHnDr5TbUC;UW?(7Vf+tvdu4zE zr#swnrjyW(pnEOOp2u9v=j|GV!|lbC+>I0+v>|^wrg&dL2{gY0czF(hmyQC&dJF}N z)fANfq9C*%9dw7yC{O%bqlK*F9z-&=+&gqZ!V7NI0=IYG={v(zr%V7hh zPX|5~Exa|A+zy}E;K4AXx_U`oFXxR=w)HjsH4j~rg_nWNEM)@kWO$=k4(Jqz?PIT# z|95)h4K7dF+JqdOjHA4KJcVbuPSGiQDC)74`9zTt7_~Ltm?iC%!L<4g7eH;OpqQ?X z()5`mlpPzL-e5nT*vRoCo)Qsvm^5Au*OJVb)Qdv(OZ*zL(St$Z_r6m$Si-0r*OXl> zfS9--5d`(C@gsYPBtvo+DrL-8qI>?XykBEa%rZ`u0g?2OD+5DAL)Np6Z1^(v5M||; zu8fw@)m2a>QmIEC!vow|GGHOn#sjYO`$2{wm_9HhPnDbk&QP+I%VOeTR1f`MrDUeE zlq>j#b$Bw?>6gKm(HiWv1XkO8K;Haxzbt>GQoqKQ97VMf$Gss>a7G#aMD^6s4!zmV z>Oh)VNQc4f8SB~d9q{GD9(-c}iw3J=4-%$c40EqYidHv{GoMWi$iU6P-{l#LEHBnG zpBicu=dAvl{Jn`f@JEFqY5J60;?*sR`koulX4Ie&8t50fnTs&2e|FXAco!5IRU=uft~MNUO&eRC&HV z7y5e^-hUrBX{+MmaWC!wVV}8DhSJu04S#=8@JDBwk%~8jer>|EcSd`pAG-dXFRZ#} zNS@J%^*?qaKIg`uV0~bi{_OsAC6srJI}1lAlRA6jWuh9!$%%?q(~$TQ9iWTdi0LQI zoiV5;MxQ+P_Oy25?M2@&;~W`x6`sdZas_V&e1BAe%ql%{D_$8E&zUHCdl*`i?8y%y z-CIR(v zi%CC_Ru*>8rXA7`{?5=#DEph#4Ku;X?=O(df*_+(g5(SE?deRImiD4!2C*2 diff --git a/app/src/main/res/drawable/history_screen_filled.png b/app/src/main/res/drawable/history_screen_filled.png index 4a734c66a5b87d712c4d55307140de69a149e244..a2636f1e5afc9bf42005de27e50436c37f6c209a 100644 GIT binary patch literal 11342 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 literal 18922 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 oXSknP()_=#Cj33q=DuXeq@-YDssI20 literal 15353 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 JU2?nke*lm$UIPFC diff --git a/app/src/main/res/drawable/library_screen_filled.png b/app/src/main/res/drawable/library_screen_filled.png index cda3caea227709d743dd4cf331b6c2a63c915b4d..9a2b898f4df5cc97fee3f043881b4d4215f34b96 100644 GIT binary patch literal 3680 zcmeHJSyYqP7CwIh1Oyeqfk{H8B3cAgCK)552$ewsgh2^N8OmT%rT`K0V`~)!ilPAp z3REFlW{`PE0KpannGq0zqS7ECOd$v)X;|ytm-}$wt_Ez6D^7nXWSyN1pf$}J z=FF^Z7L#E`-Ba&&(ma8be>&jTp3*>gGP^Rm785M;pt=U zamv>Ul3tBw(nF$l*F9|WdHkEd_1vxCe&RiOPfDxzsgF+*UltQ893x^{@R;vAXvw_} zcdMiG-mBd>Sa_sNCrrtff7K3vZP#q9PB}-9u_t(BXBX8Mi>Du7{~=XPA919=;ij6J zEq3=@6K|5t92%E1#w&iKsUh}w!Iw67|Lqu> zeGs!cfwMEBhmW93v!c|`Xg$=vIQG#!0#%nBtjx!t7SK00|V#r0$yty&WtSj9)@ z9QKS0U4Rj*_^4Z7cnVz>S{62Vf|jIEy>I;^09x-dxl|@+A6dxBESs1?nBC#w-n$+Sk}Z6*U}Uix*eS%KuvGWkw(7w7h(6@0@QNlfdm zsJ>!V#Lr<>x=$9oK$Hz%e$eppHsD@y)dDr{S|n?$F`+3%GPNoH4hX5jt=6kUwe4P` zChY+U{JjbVp{t!sgk_J_v{cxmaca_F1y$MHW8K$vb|8arykx%xb^ zR0qmE3+%}uJXDjv6wrst)(6c5rIYm~#wgerxUFnrej;z$f=-m~Ol<->dSDx{Md`-2 zdjDkVa}@X?GYsMvZp=3*!*`*OIwIkxxOXhDTV`sr$zn|tbcz#0?_1O5VJAqdp{DZ@ z-W&;ALKmIcZ|M*w4-DhTYdA<#o>Aw5rW^!k5Vd);(|CZn1I#aQ7fV5|6_9^{i`#7W z0^7uhR$R2V1`tQoHm~m_ZUHw>KI#utE(Qz~3c&!RDa+{H{L9n%mkE$VtY$7?p(i?U zpD%MW;L%xxqXSU4ZsKz~NKwGi0;n7FJ~QbmCVSv|DEiY1(>*sc zODyyZ(EB>$0Ne|rPVzl#cLG@j#ypL(EOKl`yk2H8=S1WaAYsbSY!H$13~w3*D;Q!42HNLH2_egtJ)Gd($)WD$!Us3j< z5DV6#Z{!&U*c;#kg1wRqTK9eWAtbbxUsqA%;GhPwS34*7Vby@n>#xX^WU;A>WIs;X zIY4C-%HG%|i>YN3%3d~6A~gZJ-0fqJZ5~hwE?1xlq*@^bLF?L4*0+DR8s z6a$`R@y(Us2x{N);Yf-R81Xpj%gZN%*c3z0>W<<>lv-T>mC>;b1R~?uFtKh2d~g@^ zIKInoHgUHcW-PE?>nPn=6Mm4Hl>W%m$q}%mJGy#(<=YVFN;68?{>-#@h}yOj3DtOH zqmj5o>hM~iVcCMuL32&)ZWCyldTu?@Lcv z|U#sEJ7%@aAJrLzni9hmP6BGZ2UlXDsL+J~aCIU`yuJnFq%W0t zAOkmFe)!c8Zo5;J{r}9olf`8ZR%{^~{X-HKTn|@pgzMVv^n$B6& z%bmQwA>Zk4(B&~w-U70GDjTz%(s)RH$Cea0Mcs~CgZ+L#gf?`aOp#e7trVW8))kk7 z6;;2A#z=_<)YYMHV#s)1V5S^Gt!nS{lJ*FyEQ(W8f)CRTJbF^3c+@F9wDeO$P>LGa z*qhovRN3u1jYlx&GSk?uCM4TnvlAIRjR2-Ec6SnP1!Vo(ETFHfrd?&ql)&qR2+qOK1aMS%z{w)^vL7 z`wLq`Bl<@VU!930DOR*=n5NnWj>TfD2MfN&D%y=MHtJ^*`X4>bh*jk!m5mz2>)m(e zJj3$49p#hxK1WJYSm~iPA^BG}SofSoUFRD6g*NX_OUo>Iy1f!RnygS4=ps~L=Lt>( htZMv+esHXbf^6usd7T~DDcGt;n=|%SC6?aT{sh)&(yjmi literal 5369 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 asNwg`yXy!}6U`d;d-r(lF5Sua;lBZ(US;F} diff --git a/app/src/main/res/drawable/library_screen_outlined.png b/app/src/main/res/drawable/library_screen_outlined.png index ee576f9fda3d94b964206b9d7d649c3e06ac98d8..6f92b5a0856ef4ce8fadde5568e7d7ec9f298b9d 100644 GIT binary patch literal 3486 zcmeHJ_g7QN9-ky61d#G@1?i|@1w@gD3sR&kpduWF2M9`t6ag_vF+jj%1yn>qupuCA zr92V{T`5x5f~=r`^cITJq=gzt$lYQ80QbB-=bim!=iECp_w)UHzu%e9%-nmUZBCnu z3d;%u07NY0?Dra?tn}tYj|Dp3ApI$=dMBW z_e`EWCJRYIein`a0HwRUd83}-ui3*eCN`&R&CLByLHj@D9|iuh0v=`j5$IeOc;@t3 zAg(=%8q~APLz8G**GjkyJ|=TRXz9WVPhf9bya@Jbf5VWi<)V7m#6XR{V&uJxk{!aI zWp;Up9Zns_FZb;*oBANwqWLdYd)bj~#Oy3jiv=zF5##ay-Z}N~rOtMR<2&~>dC$il z>U^<&?%8$ucWy;bdZipw3{7#fcO^LFN{64RCMq8l`u4EA~$XqrXQiq`OXB*RCUh0S{%NA08|8Fp#vlSr@OR#{5^g6zh#H>hxD?a%k`DH);*Na}lAl5N=7}+Jar# zGirUrih9eS`m%~2h044dv-}#noLuX<_C(Z)=YAadtlfu9+B14>o?Nh_Z!l}?pWjnN zN6^2OAm1=J-|9v2j<4#hoV$*BzT|cyg3(DTo~A^2wi6KPE81>rB<$Sj>qvp&)1v4x z-%|>8lzZL%das>64^rcWlEc+oo-FVK!pB&F%q(7iLl{?kpspqmrFO(6vQx<_2%+DV z&N7!ApiYLA$1E1r1$d#m-6}24Cw>_>e!(nsX2fRUhc>RobS4QXNjmwL4U8tQvn$1nq@2Z4U9qNo-8f8O zR*bB&BLPFlo>!A90n!9Y(}yF$4@i)W$qYA(Ve%Gnl14IAJun3Fg+HWll(tw!$wWlOzr@Oar3dNuCrmlAM3Y1lG@7D z9DfGB2oVNvJaEbMY4rkbc)}7#i5~3(Xr`!?WBi8wR8eq$H?0V2(FSL0i9Y(3Lt2mp z%E!TI95Pmb0&N&gHit9?p&!9ndBn;Y15|K?snJ><6zm+x*5jXafe@B(bF}sggp7fQ z0sq5!40w(ql#kZ7L+CINmPb@!EJ>8jG>624u|$Dc9C8zilmJ@l*sLMQLIYVnzFZYl z(17+6G(!G<@$@%rRvk3HMLpEx$G}9kaz;I)wet|lLLIrvldgt*P1;y2LWINbz_v`Y zT_)gi6oZ}e2zE1su<}Q?As6zsQEznlo|`MALc867s6qZV0f|*k+8X4C0-_S4bpgf~ zGZKkKWHvo<>Dmp*(q>q6OWr887m9WQb!nJw*bJjZfzlOD+B$UA1?R$f)**0*$N=A? z{G69C1D>`bk34|W%R{A~Z$O@Jx`IoiY{OybfCjx3UR*5>OdO+KQ$j{zE?u#7OarnH z=2F1H|LA76bJ&_!6hGb@Nsqp=?8m)aGt=!?u&9-&Tk=t+EI8y0$pmHo(?TWc1_o)Aa z#>^EX?=*8Hzw6Q=?sOj3`n*r&?CHqnK+eohlK~(F>NvCTd{>#pR$R8?!|_Q^V>$vCUW#A`EI{m zUDO^}pAkYXwaGIDlCF#UxmavB>i*iAzME?~Vwe)Vaq{1nvvU%V$##1|hC@xt*61JZ8kCEn&DYa?9kc6GZN$N_EE6X;mqjswFVMn8C!B9#*^4My z6n=P@bYE$FLAT5lR+(4C%8PQ+k~bazk$#J^AEdl{l*A%+(RlpNj$j>fhlK8u*`Bq|rtNjn8b7Wie{vp+uMb02x3*P@UD>`O lNBG8}6IH+af2LB#Krkkv9&bD1-QoZ&mS(3-3ycXjeg`~xYoh=F literal 4874 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 F`!CDOiZ%cM diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon.xml b/app/src/main/res/mipmap-anydpi/app_icon.xml similarity index 100% rename from app/src/main/res/mipmap-anydpi-v26/app_icon.xml rename to app/src/main/res/mipmap-anydpi/app_icon.xml diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml b/app/src/main/res/mipmap-anydpi/app_icon_round.xml similarity index 100% rename from app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml rename to app/src/main/res/mipmap-anydpi/app_icon_round.xml diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index b1f63a7f..a60cebae 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -21,7 +21,7 @@ - Нам потрібен дозвіл на сховище, щоб просканувати вашу теку Завантажень. + Нам потрібен дозвіл на сховище, щоб просканувати Ваш Девайс на наявність книг. Без цього дозволу ви не зможете додати книгу. @@ -50,14 +50,11 @@ - Нам потрібен дозвіл на сховище, щоб просканувати вашу теку Завантажень та отримати книги + Нам потрібен дозвіл на сховище, щоб просканувати Ваш Девайс на наявність книг Немає опису. - - Файл не знайдено. Будь ласка, перевірте чи файл цієї книги все ще існує. - Щось пішло не так. Будь ласка, перевірте чи файл цієї книги не пошкоджений. @@ -186,9 +183,9 @@ Натисніть ще раз, щоб вийти - Всі книги були успішно додані. - Всі книги були успішно переміщені. - Всі книги були успішно видалені. + Всі обрані книги були успішно додані. + Всі обрані книги були успішно переміщені. + Всі обрані книги були успішно видалені. Обкладинка була успішно змінена. Обкладинка була успішно видалена. Назва була успішно змінена. @@ -236,5 +233,23 @@ Назад Обкладинка Відкрити налаштування читача + Анімація фону + Анімація контуру + Анімація верхньої панелі + Файл + Галочка + Показати випадаючий список + Обкладенка не знайдена + Застосувати зміни + Помилка + Пошук + Очистити вибрані предмети + Додати файли + Вийти з пошуку + Видалити всю історію + Перемістити книгу в іншу категорію + Видалити обрані книги + Повернути + Вибрано \ 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 5d8568b1..84ccbde7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - 0.9.0 + 0.9.2 Book\'s Story @@ -22,7 +22,7 @@ - We need storage permission to scan your Downloads folder. + We need storage permission to scan Your Device for books. Without this permission, you will not be able to add a book. @@ -51,14 +51,11 @@ - We need storage permission to scan your Downloads directory and get books + We need storage permission to scan Your Device for books No description. - - File was not found. Please check whether this book\'s file still exists. - Something went wrong. Please check whether this book\'s file is not corrupted. @@ -186,9 +183,9 @@ Press back again to exit - All books were successfully added. - All books were successfully moved. - All books were successfully deleted. + All selected books were successfully added. + All selected books were successfully moved. + All selected books were successfully deleted. Cover Image was successfully changed. Cover Image was successfully deleted. Title was successfully changed. @@ -236,5 +233,23 @@ Go back Cover image Open reader settings + Background animation + Outline animation + Top app bar animation + File + Checkbox + Show dropdown + Cover image not found + Apply changes + Error + Search + Clear selected items + Add files + Exit search + Delete whole history + Move books to another category + Delete selected books + Revert + Selected \ No newline at end of file