diff --git a/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/9.json b/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/9.json new file mode 100644 index 00000000..42943f72 --- /dev/null +++ b/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/9.json @@ -0,0 +1,170 @@ +{ + "formatVersion": 1, + "database": { + "version": 9, + "identityHash": "e7887e5269c44d6066b6c71418b013fa", + "entities": [ + { + "tableName": "BookEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `author` TEXT, `description` TEXT, `filePath` TEXT NOT NULL, `scrollIndex` INTEGER NOT NULL, `scrollOffset` INTEGER NOT NULL, `progress` REAL NOT NULL, `image` TEXT, `category` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "scrollIndex", + "columnName": "scrollIndex", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scrollOffset", + "columnName": "scrollOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "progress", + "columnName": "progress", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "HistoryEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `bookId` INTEGER NOT NULL, `time` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookId", + "columnName": "bookId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ColorPresetEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `backgroundColor` INTEGER NOT NULL, `fontColor` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL, `order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "backgroundColor", + "columnName": "backgroundColor", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fontColor", + "columnName": "fontColor", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSelected", + "columnName": "isSelected", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e7887e5269c44d6066b6c71418b013fa')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/di/RepositoryModule.kt b/app/src/main/java/ua/acclorite/book_story/data/di/RepositoryModule.kt index 5e1321f5..8cb4d9c6 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/di/RepositoryModule.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/di/RepositoryModule.kt @@ -21,14 +21,12 @@ import ua.acclorite.book_story.data.parser.TextParserImpl import ua.acclorite.book_story.data.repository.BookRepositoryImpl import ua.acclorite.book_story.data.repository.ColorPresetRepositoryImpl import ua.acclorite.book_story.data.repository.DataStoreRepositoryImpl -import ua.acclorite.book_story.data.repository.FavoriteDirectoryRepositoryImpl import ua.acclorite.book_story.data.repository.FileSystemRepositoryImpl import ua.acclorite.book_story.data.repository.HistoryRepositoryImpl import ua.acclorite.book_story.data.repository.RemoteRepositoryImpl import ua.acclorite.book_story.domain.repository.BookRepository import ua.acclorite.book_story.domain.repository.ColorPresetRepository import ua.acclorite.book_story.domain.repository.DataStoreRepository -import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository import ua.acclorite.book_story.domain.repository.FileSystemRepository import ua.acclorite.book_story.domain.repository.HistoryRepository import ua.acclorite.book_story.domain.repository.RemoteRepository @@ -79,12 +77,6 @@ abstract class RepositoryModule { remoteRepositoryImpl: RemoteRepositoryImpl ): RemoteRepository - @Binds - @Singleton - abstract fun bindFavoriteDirectoryRepository( - favoriteDirectoryRepositoryImpl: FavoriteDirectoryRepositoryImpl - ): FavoriteDirectoryRepository - @Binds @Singleton abstract fun bindBookMapper( diff --git a/app/src/main/java/ua/acclorite/book_story/data/local/dto/FavoriteDirectoryEntity.kt b/app/src/main/java/ua/acclorite/book_story/data/local/dto/FavoriteDirectoryEntity.kt deleted file mode 100644 index 37302626..00000000 --- a/app/src/main/java/ua/acclorite/book_story/data/local/dto/FavoriteDirectoryEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package ua.acclorite.book_story.data.local.dto - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity -data class FavoriteDirectoryEntity( - @PrimaryKey(autoGenerate = false) - val path: String -) \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDao.kt b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDao.kt index 378704c9..9c9e6601 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDao.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDao.kt @@ -9,7 +9,6 @@ import androidx.room.Update import androidx.room.Upsert import ua.acclorite.book_story.data.local.dto.BookEntity import ua.acclorite.book_story.data.local.dto.ColorPresetEntity -import ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity import ua.acclorite.book_story.data.local.dto.HistoryEntity /** @@ -88,16 +87,4 @@ interface BookDao { @Query("DELETE FROM colorpresetentity") suspend fun deleteColorPresets() /* - - - - - - - - - - - - - - - - - - - - - - */ - - - /* ------ FavoriteDirectoryEntity ----------- */ - @Upsert - suspend fun insertFavoriteDirectory(favoriteDirectoryEntity: FavoriteDirectoryEntity) - - @Query("SELECT EXISTS(SELECT 1 FROM favoritedirectoryentity WHERE path = :path LIMIT 1)") - suspend fun favoriteDirectoryExits(path: String): Boolean - - @Delete - suspend fun deleteFavoriteDirectory(favoriteDirectoryEntity: FavoriteDirectoryEntity) - /* - - - - - - - - - - - - - - - - - - - - - - */ } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt index 142a9699..aecd54e3 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt @@ -11,7 +11,6 @@ import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import ua.acclorite.book_story.data.local.dto.BookEntity import ua.acclorite.book_story.data.local.dto.ColorPresetEntity -import ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity import ua.acclorite.book_story.data.local.dto.HistoryEntity import java.io.File @@ -20,9 +19,8 @@ import java.io.File BookEntity::class, HistoryEntity::class, ColorPresetEntity::class, - FavoriteDirectoryEntity::class, ], - version = 8, + version = 9, autoMigrations = [ AutoMigration(1, 2), AutoMigration(2, 3), @@ -30,7 +28,8 @@ import java.io.File AutoMigration(4, 5), AutoMigration(5, 6), AutoMigration(6, 7), - AutoMigration(7, 8, spec = DatabaseHelper.MIGRATION_7_8::class) + AutoMigration(7, 8, spec = DatabaseHelper.MIGRATION_7_8::class), + AutoMigration(8, 9, spec = DatabaseHelper.MIGRATION_8_9::class), ], exportSchema = true ) @@ -105,4 +104,7 @@ object DatabaseHelper { } } } + + @DeleteTable("FavoriteDirectoryEntity") + class MIGRATION_8_9 : AutoMigrationSpec } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/repository/FavoriteDirectoryRepositoryImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/repository/FavoriteDirectoryRepositoryImpl.kt deleted file mode 100644 index b3b7bfc0..00000000 --- a/app/src/main/java/ua/acclorite/book_story/data/repository/FavoriteDirectoryRepositoryImpl.kt +++ /dev/null @@ -1,35 +0,0 @@ -package ua.acclorite.book_story.data.repository - -import ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity -import ua.acclorite.book_story.data.local.room.BookDao -import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository -import javax.inject.Inject -import javax.inject.Singleton - -/** - * Favorite Directory repository. - * Manages all [ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity] related work. - */ -@Singleton -class FavoriteDirectoryRepositoryImpl @Inject constructor( - private val database: BookDao, -) : FavoriteDirectoryRepository { - - /** - * Create or delete favorite directory if already exists. - * - * @param path Path to directory. - */ - override suspend fun updateFavoriteDirectory(path: String) { - if (database.favoriteDirectoryExits(path)) { - database.deleteFavoriteDirectory( - FavoriteDirectoryEntity(path) - ) - return - } - - database.insertFavoriteDirectory( - FavoriteDirectoryEntity(path) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/repository/FileSystemRepositoryImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/repository/FileSystemRepositoryImpl.kt index 89056128..afd1fcf5 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/repository/FileSystemRepositoryImpl.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/repository/FileSystemRepositoryImpl.kt @@ -1,10 +1,15 @@ package ua.acclorite.book_story.data.repository +import android.app.Application +import android.content.Context.STORAGE_SERVICE +import android.os.Build import android.os.Environment +import android.os.storage.StorageManager import android.util.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import ua.acclorite.book_story.R import ua.acclorite.book_story.data.local.room.BookDao -import ua.acclorite.book_story.data.mapper.book.BookMapper import ua.acclorite.book_story.data.parser.FileParser import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.domain.library.book.NullableBook @@ -27,8 +32,8 @@ private const val GET_FILES_FROM_DEVICE = "FILES FROM DEVICE, REPO" */ @Singleton class FileSystemRepositoryImpl @Inject constructor( + private val application: Application, private val database: BookDao, - private val bookMapper: BookMapper, private val fileParser: FileParser ) : FileSystemRepository { @@ -39,101 +44,100 @@ class FileSystemRepositoryImpl @Inject constructor( override suspend fun getFilesFromDevice(query: String): List { Log.i(GET_FILES_FROM_DEVICE, "Getting files from device by query: \"$query\".") - val existingBooks = database + val existingPaths = database .searchBooks("") - .map { bookMapper.toBook(it) } + .map { it.filePath.trim() } val supportedExtensions = Constants.provideExtensions() + /** + * Verify that a file is valid and can be shown correctly. + */ fun File.isValid(): Boolean { - if (!exists()) { - return false + if (!exists() || !canRead() || !isFile) return false + + // First: Ensuring supported extension + supportedExtensions.any { ext -> + name.endsWith(ext, ignoreCase = true) + }.let { if (!it) return false } + + // Second: Ensuring query to match + if (query.isNotBlank()) { + name.contains(query.trim(), ignoreCase = true) + .let { if (!it) return false } } - val isFileSupported = supportedExtensions.any { ext -> - name.endsWith( - ext, - ignoreCase = true - ) - } + // Third: Ensuring that a file is not added already + existingPaths.none { existingPath -> + existingPath.equals(path.trim(), ignoreCase = true) + }.let { if (!it) return false } - if (!isFileSupported) { - return false - } - - val isFileNotAdded = existingBooks.all { - it.filePath.lowercase().trim() != path.lowercase().trim() - } - - if (!isFileNotAdded) { - return false - } - - val isQuery = if (query.isEmpty()) true else name.trim().lowercase() - .contains(query.trim().lowercase()) - - return isQuery + return true } - suspend fun File.getAllFiles(): List { - val filesList = mutableListOf() + /** + * Get all verified files from directory (root). + */ + fun File.getFilesFromDirectory(): List { + return walk().mapNotNull { + if (!it.isValid()) return@mapNotNull null + SelectableFile( + name = it.name, + path = it.path, + size = it.length(), + lastModified = it.lastModified(), + selected = false + ) + }.toList() + } - val files = listFiles() - if (files != null) { - for (file in files) { - if (!file.exists()) { - continue + /** + * Get all storages (including SD). + */ + fun getAllStorageDirectories(): List { + val storageDirectories = mutableListOf() + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val storageManager = application.getSystemService(STORAGE_SERVICE) as StorageManager + + val storageVolumes = storageManager.storageVolumes.mapNotNull { it.directory } + for (volume in storageVolumes) { + if (volume.exists() && volume.canRead() && volume.isDirectory) { + storageDirectories.add(volume) } + } + } else { + val internalStorage = Environment.getExternalStorageDirectory() + if (internalStorage.exists() && internalStorage.canRead() && internalStorage.isDirectory) { + storageDirectories.add(internalStorage) + } - when { - file.isFile -> { - if (file.isValid()) { - filesList.add( - SelectableFile( - fileOrDirectory = file, - parentDirectory = this, - isDirectory = false, - isFavorite = false, - isSelected = false - ) - ) - } - } - - file.isDirectory -> { - val subDirectoryFiles = file.getAllFiles() - if (subDirectoryFiles.isNotEmpty()) { - filesList.add( - SelectableFile( - fileOrDirectory = file, - parentDirectory = this, - isDirectory = true, - isFavorite = database.favoriteDirectoryExits(file.path), - isSelected = false - ) - ) - filesList.addAll(subDirectoryFiles) - } + val storageVolumes = File("/storage") + if (storageVolumes.exists() && storageVolumes.canRead() && storageVolumes.isDirectory) { + storageVolumes.listFiles()?.forEach { volume -> + if ( + volume.exists() && + volume.canRead() && + volume.isDirectory && + volume != internalStorage + ) { + storageDirectories.add(volume) } } } } - return filesList + return storageDirectories } - val rootDirectory = Environment.getExternalStorageDirectory() - if ( - !rootDirectory.exists() || - !rootDirectory.isDirectory || - (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED && - Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED_READ_ONLY) - ) { - Log.e(GET_FILES_FROM_DEVICE, "Could not correctly get root directory.") - return emptyList() + val storageDirectories = getAllStorageDirectories() + val files = mutableListOf() + + for (volume in storageDirectories) { + files.addAll(withContext(Dispatchers.IO) { volume.getFilesFromDirectory() }) } Log.i(GET_FILES_FROM_DEVICE, "Successfully got all matching files.") - return rootDirectory.getAllFiles() + return files } /** diff --git a/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseFilesStructure.kt b/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseFilesStructure.kt deleted file mode 100644 index 1210b148..00000000 --- a/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseFilesStructure.kt +++ /dev/null @@ -1,12 +0,0 @@ -package ua.acclorite.book_story.domain.browse - -import androidx.compose.runtime.Immutable - -@Immutable -enum class BrowseFilesStructure { - ALL_FILES, DIRECTORIES -} - -fun String.toBrowseFilesStructure(): BrowseFilesStructure { - return BrowseFilesStructure.valueOf(this) -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseSortOrder.kt b/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseSortOrder.kt index 2553ae92..29a1da1e 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseSortOrder.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/browse/BrowseSortOrder.kt @@ -3,11 +3,14 @@ package ua.acclorite.book_story.domain.browse enum class BrowseSortOrder { NAME, FILE_FORMAT, - FILE_TYPE, LAST_MODIFIED, FILE_SIZE, } fun String.toBrowseSortOrder(): BrowseSortOrder { - return BrowseSortOrder.valueOf(this) + return try { + BrowseSortOrder.valueOf(this) + } catch (_: IllegalArgumentException) { + BrowseSortOrder.LAST_MODIFIED + } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/browse/FileWithTitle.kt b/app/src/main/java/ua/acclorite/book_story/domain/browse/FileWithTitle.kt deleted file mode 100644 index 7473e20c..00000000 --- a/app/src/main/java/ua/acclorite/book_story/domain/browse/FileWithTitle.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ua.acclorite.book_story.domain.browse - -import androidx.compose.runtime.Immutable -import ua.acclorite.book_story.domain.ui.UIText -import java.io.File - -@Immutable -data class FileWithTitle( - val title: UIText, - val file: File -) \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/browse/SelectableFile.kt b/app/src/main/java/ua/acclorite/book_story/domain/browse/SelectableFile.kt index 5218918a..e2fc1dc6 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/browse/SelectableFile.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/browse/SelectableFile.kt @@ -1,14 +1,12 @@ package ua.acclorite.book_story.domain.browse import androidx.compose.runtime.Immutable -import ua.acclorite.book_story.domain.util.Selected -import java.io.File @Immutable data class SelectableFile( - val fileOrDirectory: File, - val parentDirectory: File, - val isDirectory: Boolean, - val isFavorite: Boolean, - val isSelected: Selected + val name: String, + val path: String, + val size: Long, + val lastModified: Long, + val selected: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/repository/FavoriteDirectoryRepository.kt b/app/src/main/java/ua/acclorite/book_story/domain/repository/FavoriteDirectoryRepository.kt deleted file mode 100644 index 8cccd6f1..00000000 --- a/app/src/main/java/ua/acclorite/book_story/domain/repository/FavoriteDirectoryRepository.kt +++ /dev/null @@ -1,6 +0,0 @@ -package ua.acclorite.book_story.domain.repository - -interface FavoriteDirectoryRepository { - - suspend fun updateFavoriteDirectory(path: String) -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/use_case/favorite_directory/UpdateFavoriteDirectory.kt b/app/src/main/java/ua/acclorite/book_story/domain/use_case/favorite_directory/UpdateFavoriteDirectory.kt deleted file mode 100644 index 8b0bd324..00000000 --- a/app/src/main/java/ua/acclorite/book_story/domain/use_case/favorite_directory/UpdateFavoriteDirectory.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ua.acclorite.book_story.domain.use_case.favorite_directory - -import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository -import javax.inject.Inject - -class UpdateFavoriteDirectory @Inject constructor( - private val repository: FavoriteDirectoryRepository -) { - - suspend fun execute(path: String) { - return repository.updateFavoriteDirectory(path) - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseBackHandler.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseBackHandler.kt index b177a409..0261644e 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseBackHandler.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseBackHandler.kt @@ -8,10 +8,8 @@ import ua.acclorite.book_story.ui.browse.BrowseEvent fun BrowseBackHandler( hasSelectedItems: Boolean, showSearch: Boolean, - inNestedDirectory: Boolean, searchVisibility: (BrowseEvent.OnSearchVisibility) -> Unit, clearSelectedFiles: (BrowseEvent.OnClearSelectedFiles) -> Unit, - goBackDirectory: (BrowseEvent.OnGoBackDirectory) -> Unit, navigateToLibrary: () -> Unit ) { BackHandler { @@ -25,11 +23,6 @@ fun BrowseBackHandler( return@BackHandler } - if (inNestedDirectory) { - goBackDirectory(BrowseEvent.OnGoBackDirectory) - return@BackHandler - } - navigateToLibrary() } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseContent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseContent.kt index 3df57b39..cf042bdb 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseContent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseContent.kt @@ -8,14 +8,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.focus.FocusRequester import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionState -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseLayout import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.domain.library.book.SelectableNullableBook import ua.acclorite.book_story.domain.util.BottomSheet import ua.acclorite.book_story.domain.util.Dialog import ua.acclorite.book_story.ui.browse.BrowseEvent -import java.io.File @OptIn(ExperimentalMaterialApi::class, ExperimentalPermissionsApi::class) @Composable @@ -30,14 +28,11 @@ fun BrowseContent( listState: LazyListState, gridState: LazyGridState, layout: BrowseLayout, - filesStructure: BrowseFilesStructure, gridSize: Int, autoGridSize: Boolean, includedFilterItems: List, canScrollBackList: Boolean, canScrollBackGrid: Boolean, - selectedDirectory: File, - inNestedDirectory: Boolean, hasSelectedItems: Boolean, selectedItemsCount: Int, isRefreshing: Boolean, @@ -47,19 +42,15 @@ fun BrowseContent( filesEmpty: Boolean, showSearch: Boolean, searchQuery: String, - hasSearched: Boolean, focusRequester: FocusRequester, searchVisibility: (BrowseEvent.OnSearchVisibility) -> Unit, searchQueryChange: (BrowseEvent.OnSearchQueryChange) -> Unit, search: (BrowseEvent.OnSearch) -> Unit, requestFocus: (BrowseEvent.OnRequestFocus) -> Unit, clearSelectedFiles: (BrowseEvent.OnClearSelectedFiles) -> Unit, - goBackDirectory: (BrowseEvent.OnGoBackDirectory) -> Unit, selectFiles: (BrowseEvent.OnSelectFiles) -> Unit, selectFile: (BrowseEvent.OnSelectFile) -> Unit, permissionCheck: (BrowseEvent.OnPermissionCheck) -> Unit, - updateFavoriteDirectory: (BrowseEvent.OnUpdateFavoriteDirectory) -> Unit, - changeDirectory: (BrowseEvent.OnChangeDirectory) -> Unit, dismissBottomSheet: (BrowseEvent.OnDismissBottomSheet) -> Unit, showFilterBottomSheet: (BrowseEvent.OnShowFilterBottomSheet) -> Unit, actionPermissionDialog: (BrowseEvent.OnActionPermissionDialog) -> Unit, @@ -95,28 +86,23 @@ fun BrowseContent( listState = listState, gridState = gridState, layout = layout, - filesStructure = filesStructure, gridSize = gridSize, autoGridSize = autoGridSize, includedFilterItems = includedFilterItems, canScrollBackList = canScrollBackList, canScrollBackGrid = canScrollBackGrid, - selectedDirectory = selectedDirectory, - inNestedDirectory = inNestedDirectory, hasSelectedItems = hasSelectedItems, selectedItemsCount = selectedItemsCount, isRefreshing = isRefreshing, dialogHidden = dialogHidden, showSearch = showSearch, searchQuery = searchQuery, - hasSearched = hasSearched, focusRequester = focusRequester, searchVisibility = searchVisibility, searchQueryChange = searchQueryChange, search = search, requestFocus = requestFocus, clearSelectedFiles = clearSelectedFiles, - goBackDirectory = goBackDirectory, selectFiles = selectFiles, storagePermissionState = storagePermissionState, isLoading = isLoading, @@ -124,8 +110,6 @@ fun BrowseContent( filesEmpty = filesEmpty, permissionCheck = permissionCheck, selectFile = selectFile, - updateFavoriteDirectory = updateFavoriteDirectory, - changeDirectory = changeDirectory, showFilterBottomSheet = showFilterBottomSheet, showAddDialog = showAddDialog, navigateToHelp = navigateToHelp @@ -134,10 +118,8 @@ fun BrowseContent( BrowseBackHandler( hasSelectedItems = hasSelectedItems, showSearch = showSearch, - inNestedDirectory = inNestedDirectory, searchVisibility = searchVisibility, clearSelectedFiles = clearSelectedFiles, - goBackDirectory = goBackDirectory, navigateToLibrary = navigateToLibrary ) } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridDirectoryItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridDirectoryItem.kt deleted file mode 100644 index 12f85584..00000000 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridDirectoryItem.kt +++ /dev/null @@ -1,126 +0,0 @@ -package ua.acclorite.book_story.presentation.browse - -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.FavoriteBorder -import androidx.compose.material.icons.filled.Folder -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -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 androidx.compose.ui.unit.sp -import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.SelectableFile -import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox -import ua.acclorite.book_story.presentation.core.util.noRippleClickable -import ua.acclorite.book_story.ui.theme.DefaultTransition -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -@Composable -fun BrowseGridDirectoryItem( - file: SelectableFile, - hasSelectedFiles: Boolean, - onFavoriteClick: () -> Unit -) { - val lastModified = rememberSaveable { - SimpleDateFormat("dd MMM yyyy", Locale.getDefault()) - .format(Date(file.fileOrDirectory.lastModified())) - } - - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Box( - modifier = Modifier - .border( - 1.dp, - if (file.isSelected) MaterialTheme.colorScheme.outline - else MaterialTheme.colorScheme.outlineVariant, - RoundedCornerShape(10.dp) - ) - .fillMaxWidth() - .aspectRatio(1f), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.Folder, - contentDescription = stringResource(id = R.string.directory_icon_content_desc), - modifier = Modifier - .fillMaxWidth(0.3f) - .aspectRatio(1f), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - - DefaultTransition( - visible = hasSelectedFiles, - modifier = Modifier - .align(Alignment.TopStart) - .padding(12.dp) - ) { - CircularCheckbox( - selected = file.isSelected, - containerColor = MaterialTheme.colorScheme.surface, - size = 18.dp - ) - } - DefaultTransition( - visible = !hasSelectedFiles, - modifier = Modifier - .align(Alignment.TopStart) - .padding(12.dp) - ) { - Icon( - imageVector = if (file.isFavorite) Icons.Default.Favorite - else Icons.Default.FavoriteBorder, - contentDescription = stringResource( - id = R.string.favorite_directory_content_desc - ), - modifier = Modifier - .size(24.dp) - .noRippleClickable(enabled = !hasSelectedFiles) { - onFavoriteClick() - }, - tint = if (file.isFavorite) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurfaceVariant.copy(0.8f) - ) - } - } - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - file.fileOrDirectory.name, - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodyLarge, - maxLines = 2, - textAlign = TextAlign.Center, - lineHeight = 18.sp, - overflow = TextOverflow.Ellipsis - ) - Spacer(modifier = Modifier.height(2.dp)) - Text( - lastModified, - color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.bodySmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridFileItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridFileItem.kt index 14592459..bce4ae79 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridFileItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridFileItem.kt @@ -32,13 +32,13 @@ import java.util.Date import java.util.Locale @Composable -fun BrowseGridFileItem(file: SelectableFile, hasSelectedFiles: Boolean) { +fun BrowseGridFileItem(file: SelectableFile, hasSelectedItems: Boolean) { val lastModified = rememberSaveable { SimpleDateFormat("dd MMM yyyy", Locale.getDefault()) - .format(Date(file.fileOrDirectory.lastModified())) + .format(Date(file.lastModified)) } - val sizeBytes = rememberSaveable { file.fileOrDirectory.length() } + val sizeBytes = rememberSaveable { file.size } val fileSizeKB = rememberSaveable { if (sizeBytes > 0) sizeBytes.toDouble() / 1024.0 else 0.0 } @@ -56,7 +56,7 @@ fun BrowseGridFileItem(file: SelectableFile, hasSelectedFiles: Boolean) { modifier = Modifier .border( 1.dp, - if (file.isSelected) MaterialTheme.colorScheme.outline + if (file.selected) MaterialTheme.colorScheme.outline else MaterialTheme.colorScheme.outlineVariant, RoundedCornerShape(10.dp) ) @@ -74,11 +74,11 @@ fun BrowseGridFileItem(file: SelectableFile, hasSelectedFiles: Boolean) { ) DefaultTransition( - visible = hasSelectedFiles, + visible = hasSelectedItems, modifier = Modifier.align(Alignment.TopStart) ) { CircularCheckbox( - selected = file.isSelected, + selected = file.selected, containerColor = MaterialTheme.colorScheme.surface, size = 18.dp, modifier = Modifier.padding(12.dp) @@ -89,7 +89,7 @@ fun BrowseGridFileItem(file: SelectableFile, hasSelectedFiles: Boolean) { Spacer(modifier = Modifier.height(8.dp)) Text( - file.fileOrDirectory.name, + file.name, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyLarge, maxLines = 2, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridItem.kt index 763b7662..8ad4979e 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridItem.kt @@ -20,9 +20,8 @@ import ua.acclorite.book_story.domain.browse.SelectableFile fun BrowseGridItem( modifier: Modifier, file: SelectableFile, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, onClick: () -> Unit, - onFavoriteClick: () -> Unit, onLongClick: () -> Unit ) { Column( @@ -31,7 +30,7 @@ fun BrowseGridItem( .padding(3.dp) .clip(RoundedCornerShape(12.dp)) .background( - if (file.isSelected) MaterialTheme.colorScheme.secondaryContainer + if (file.selected) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent, RoundedCornerShape(12.dp) ) @@ -41,21 +40,9 @@ fun BrowseGridItem( ) .padding(5.dp) ) { - when { - !file.isDirectory -> { - BrowseGridFileItem( - file = file, - hasSelectedFiles = hasSelectedFiles - ) - } - - file.isDirectory -> { - BrowseGridDirectoryItem( - file = file, - hasSelectedFiles = hasSelectedFiles, - onFavoriteClick = onFavoriteClick - ) - } - } + BrowseGridFileItem( + file = file, + hasSelectedItems = hasSelectedItems + ) } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridLayout.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridLayout.kt index 428baad6..5fd39c67 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseGridLayout.kt @@ -23,9 +23,8 @@ fun BrowseGridLayout( autoGridSize: Boolean, gridState: LazyGridState, files: List, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, onLongItemClick: (SelectableFile) -> Unit, - onFavoriteItemClick: (SelectableFile) -> Unit, onItemClick: (SelectableFile) -> Unit, ) { LazyVerticalGridWithScrollbar( @@ -43,19 +42,16 @@ fun BrowseGridLayout( items( files, - key = { it.fileOrDirectory.path } + key = { it.path } ) { selectableFile -> BrowseItem( file = selectableFile, modifier = Modifier.animateItem(), layout = BrowseLayout.GRID, - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, onLongClick = { onLongItemClick(selectableFile) }, - onFavoriteClick = { - onFavoriteItemClick(selectableFile) - }, onClick = { onItemClick(selectableFile) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseItem.kt index f8fc6ece..b56a16f9 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseItem.kt @@ -9,10 +9,9 @@ import ua.acclorite.book_story.domain.browse.SelectableFile fun BrowseItem( layout: BrowseLayout, file: SelectableFile, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, modifier: Modifier, onClick: () -> Unit, - onFavoriteClick: () -> Unit, onLongClick: () -> Unit ) { when (layout) { @@ -20,9 +19,8 @@ fun BrowseItem( BrowseListItem( modifier = modifier, file = file, - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, onClick = onClick, - onFavoriteClick = onFavoriteClick, onLongClick = onLongClick ) } @@ -31,9 +29,8 @@ fun BrowseItem( BrowseGridItem( modifier = modifier, file = file, - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, onClick = onClick, - onFavoriteClick = onFavoriteClick, onLongClick = onLongClick ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseLayout.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseLayout.kt index ff063267..dd6e4741 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseLayout.kt @@ -9,24 +9,22 @@ import ua.acclorite.book_story.domain.browse.SelectableFile @Composable fun BrowseLayout( files: List, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, layout: BrowseLayout, gridSize: Int, autoGridSize: Boolean, listState: LazyListState, gridState: LazyGridState, onLongItemClick: (SelectableFile) -> Unit, - onFavoriteItemClick: (SelectableFile) -> Unit, onItemClick: (SelectableFile) -> Unit ) { when (layout) { BrowseLayout.LIST -> { BrowseListLayout( files = files, - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, listState = listState, onLongItemClick = onLongItemClick, - onFavoriteItemClick = onFavoriteItemClick, onItemClick = onItemClick ) } @@ -36,10 +34,9 @@ fun BrowseLayout( gridSize = gridSize, autoGridSize = autoGridSize, files = files, - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, gridState = gridState, onLongItemClick = onLongItemClick, - onFavoriteItemClick = onFavoriteItemClick, onItemClick = onItemClick ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListDirectoryItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListDirectoryItem.kt deleted file mode 100644 index 0e4b21de..00000000 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListDirectoryItem.kt +++ /dev/null @@ -1,73 +0,0 @@ -package ua.acclorite.book_story.presentation.browse - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -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.material.icons.Icons -import androidx.compose.material.icons.filled.Folder -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -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.domain.browse.SelectableFile -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -@Composable -fun RowScope.BrowseListDirectoryItem(file: SelectableFile) { - val lastModified = rememberSaveable { - SimpleDateFormat("dd MMM yyyy", Locale.getDefault()) - .format(Date(file.fileOrDirectory.lastModified())) - } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.weight(1f) - ) { - Icon( - imageVector = Icons.Default.Folder, - contentDescription = stringResource(id = R.string.directory_icon_content_desc), - modifier = Modifier - .padding(14.dp) - .size(22.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.width(12.dp)) - Column(verticalArrangement = Arrangement.Center) { - Text( - file.fileOrDirectory.name, - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodyLarge, - maxLines = 2, - lineHeight = 18.sp, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(2.dp)) - Text( - lastModified, - color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.bodySmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.fillMaxWidth() - ) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListFileItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListFileItem.kt index 395f081b..ab26add6 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListFileItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListFileItem.kt @@ -36,10 +36,10 @@ import java.util.Locale fun RowScope.BrowseListFileItem(file: SelectableFile) { val lastModified = rememberSaveable { SimpleDateFormat("HH:mm dd MMM yyyy", Locale.getDefault()) - .format(Date(file.fileOrDirectory.lastModified())) + .format(Date(file.lastModified)) } - val sizeBytes = rememberSaveable { file.fileOrDirectory.length() } + val sizeBytes = rememberSaveable { file.size } val fileSizeKB = rememberSaveable { if (sizeBytes > 0) sizeBytes.toDouble() / 1024.0 else 0.0 } @@ -60,7 +60,7 @@ fun RowScope.BrowseListFileItem(file: SelectableFile) { modifier = Modifier .border( 1.dp, - if (file.isSelected) MaterialTheme.colorScheme.outline + if (file.selected) MaterialTheme.colorScheme.outline else MaterialTheme.colorScheme.outlineVariant, RoundedCornerShape(6.dp) ) @@ -78,7 +78,7 @@ fun RowScope.BrowseListFileItem(file: SelectableFile) { Spacer(modifier = Modifier.width(12.dp)) Column(verticalArrangement = Arrangement.Center) { Text( - file.fileOrDirectory.name, + file.name, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyLarge, maxLines = 2, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListItem.kt index fb618ba1..07d03180 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListItem.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListItem.kt @@ -3,30 +3,21 @@ package ua.acclorite.book_story.presentation.browse import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.FavoriteBorder -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable 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.unit.dp -import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox -import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.ui.theme.FadeTransitionPreservingSpace @OptIn(ExperimentalFoundationApi::class) @@ -34,9 +25,8 @@ import ua.acclorite.book_story.ui.theme.FadeTransitionPreservingSpace fun BrowseListItem( modifier: Modifier, file: SelectableFile, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, onClick: () -> Unit, - onFavoriteClick: () -> Unit, onLongClick: () -> Unit ) { Row( @@ -46,7 +36,7 @@ fun BrowseListItem( .padding(horizontal = 8.dp, vertical = 3.dp) .clip(RoundedCornerShape(10.dp)) .background( - if (file.isSelected) MaterialTheme.colorScheme.secondaryContainer + if (file.selected) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent, RoundedCornerShape(10.dp) ) @@ -60,59 +50,19 @@ fun BrowseListItem( ) .padding(horizontal = 8.dp, vertical = 7.dp) ) { - when { - !file.isDirectory -> { - BrowseListFileItem(file = file) + BrowseListFileItem(file = file) - FadeTransitionPreservingSpace(visible = hasSelectedFiles) { - Row(verticalAlignment = Alignment.CenterVertically) { - Spacer(modifier = Modifier.width(16.dp)) + FadeTransitionPreservingSpace(visible = hasSelectedItems) { + Row(verticalAlignment = Alignment.CenterVertically) { + Spacer(modifier = Modifier.width(16.dp)) - CircularCheckbox( - selected = file.isSelected, - containerColor = MaterialTheme.colorScheme.surface, - size = 18.dp - ) + CircularCheckbox( + selected = file.selected, + containerColor = MaterialTheme.colorScheme.surface, + size = 18.dp + ) - Spacer(modifier = Modifier.width(8.dp)) - } - } - } - - file.isDirectory -> { - BrowseListDirectoryItem(file = file) - - Row(verticalAlignment = Alignment.CenterVertically) { - Spacer(modifier = Modifier.width(16.dp)) - - Box(contentAlignment = Alignment.Center) { - FadeTransitionPreservingSpace(hasSelectedFiles) { - CircularCheckbox( - selected = file.isSelected, - containerColor = MaterialTheme.colorScheme.surface, - size = 18.dp - ) - } - FadeTransitionPreservingSpace(!hasSelectedFiles) { - Icon( - imageVector = if (file.isFavorite) Icons.Default.Favorite - else Icons.Default.FavoriteBorder, - contentDescription = stringResource( - id = R.string.favorite_directory_content_desc - ), - modifier = Modifier - .size(24.dp) - .noRippleClickable(enabled = !hasSelectedFiles) { - onFavoriteClick() - }, - tint = if (file.isFavorite) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurfaceVariant.copy(0.8f) - ) - } - } - - Spacer(modifier = Modifier.width(8.dp)) - } + Spacer(modifier = Modifier.width(8.dp)) } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListLayout.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListLayout.kt index d34a8abf..2140af69 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseListLayout.kt @@ -17,10 +17,9 @@ import ua.acclorite.book_story.presentation.core.constants.providePrimaryScrollb @Composable fun BrowseListLayout( files: List, - hasSelectedFiles: Boolean, + hasSelectedItems: Boolean, listState: LazyListState, onLongItemClick: (SelectableFile) -> Unit, - onFavoriteItemClick: (SelectableFile) -> Unit, onItemClick: (SelectableFile) -> Unit, ) { LazyColumnWithScrollbar( @@ -34,19 +33,16 @@ fun BrowseListLayout( items( files, - key = { it.fileOrDirectory.path } + key = { it.path } ) { selectableFile -> BrowseItem( file = selectableFile, layout = BrowseLayout.LIST, modifier = Modifier.animateItem(), - hasSelectedFiles = hasSelectedFiles, + hasSelectedItems = hasSelectedItems, onLongClick = { onLongItemClick(selectableFile) }, - onFavoriteClick = { - onFavoriteItemClick(selectableFile) - }, onClick = { onItemClick(selectableFile) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseScaffold.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseScaffold.kt index 33a06d38..9ec8385d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseScaffold.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseScaffold.kt @@ -16,14 +16,12 @@ import androidx.compose.ui.focus.FocusRequester import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionState import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseLayout import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.presentation.core.util.LocalActivity import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.ui.browse.BrowseEvent import ua.acclorite.book_story.ui.theme.DefaultTransition -import java.io.File @OptIn(ExperimentalMaterialApi::class, ExperimentalPermissionsApi::class) @Composable @@ -34,14 +32,11 @@ fun BrowseScaffold( listState: LazyListState, gridState: LazyGridState, layout: BrowseLayout, - filesStructure: BrowseFilesStructure, gridSize: Int, autoGridSize: Boolean, includedFilterItems: List, canScrollBackList: Boolean, canScrollBackGrid: Boolean, - selectedDirectory: File, - inNestedDirectory: Boolean, hasSelectedItems: Boolean, selectedItemsCount: Int, isRefreshing: Boolean, @@ -51,19 +46,15 @@ fun BrowseScaffold( filesEmpty: Boolean, showSearch: Boolean, searchQuery: String, - hasSearched: Boolean, focusRequester: FocusRequester, searchVisibility: (BrowseEvent.OnSearchVisibility) -> Unit, searchQueryChange: (BrowseEvent.OnSearchQueryChange) -> Unit, search: (BrowseEvent.OnSearch) -> Unit, requestFocus: (BrowseEvent.OnRequestFocus) -> Unit, - goBackDirectory: (BrowseEvent.OnGoBackDirectory) -> Unit, clearSelectedFiles: (BrowseEvent.OnClearSelectedFiles) -> Unit, selectFiles: (BrowseEvent.OnSelectFiles) -> Unit, selectFile: (BrowseEvent.OnSelectFile) -> Unit, permissionCheck: (BrowseEvent.OnPermissionCheck) -> Unit, - updateFavoriteDirectory: (BrowseEvent.OnUpdateFavoriteDirectory) -> Unit, - changeDirectory: (BrowseEvent.OnChangeDirectory) -> Unit, showFilterBottomSheet: (BrowseEvent.OnShowFilterBottomSheet) -> Unit, showAddDialog: (BrowseEvent.OnShowAddDialog) -> Unit, navigateToHelp: () -> Unit, @@ -79,27 +70,20 @@ fun BrowseScaffold( BrowseTopBar( files = files, layout = layout, - filesStructure = filesStructure, includedFilterItems = includedFilterItems, canScrollBackList = canScrollBackList, canScrollBackGrid = canScrollBackGrid, - selectedDirectory = selectedDirectory, - inNestedDirectory = inNestedDirectory, hasSelectedItems = hasSelectedItems, selectedItemsCount = selectedItemsCount, showSearch = showSearch, searchQuery = searchQuery, - hasSearched = hasSearched, - isError = isError, focusRequester = focusRequester, searchVisibility = searchVisibility, searchQueryChange = searchQueryChange, search = search, requestFocus = requestFocus, - goBackDirectory = goBackDirectory, clearSelectedFiles = clearSelectedFiles, selectFiles = selectFiles, - changeDirectory = changeDirectory, showFilterBottomSheet = showFilterBottomSheet, showAddDialog = showAddDialog ) @@ -114,66 +98,24 @@ fun BrowseScaffold( BrowseLayout( files = files, layout = layout, - hasSelectedFiles = files.any { it.isSelected }, + hasSelectedItems = hasSelectedItems, gridSize = gridSize, autoGridSize = autoGridSize, listState = listState, gridState = gridState, onLongItemClick = { file -> - when (file.isDirectory) { - false -> { - context.getString( - R.string.file_path_query, - file.fileOrDirectory.path - ).showToast(context = context) - } - - true -> { - selectFile( - BrowseEvent.OnSelectFile( - includedFileFormats = includedFilterItems, - file = file - ) - ) - } - } - }, - onFavoriteItemClick = { file -> - updateFavoriteDirectory( - BrowseEvent.OnUpdateFavoriteDirectory( - file.fileOrDirectory.path - ) - ) + context.getString( + R.string.file_path_query, + file.path + ).showToast(context = context) }, onItemClick = { file -> - when (file.isDirectory) { - false -> { - selectFile( - BrowseEvent.OnSelectFile( - includedFileFormats = includedFilterItems, - file = file - ) - ) - } - - true -> { - if (!hasSelectedItems) { - changeDirectory( - BrowseEvent.OnChangeDirectory( - file.fileOrDirectory, - savePreviousDirectory = true - ) - ) - } else { - selectFile( - BrowseEvent.OnSelectFile( - includedFileFormats = includedFilterItems, - file = file - ) - ) - } - } - } + selectFile( + BrowseEvent.OnSelectFile( + includedFileFormats = includedFilterItems, + file = file + ) + ) } ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBar.kt index 2c0b9fe1..3451102e 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBar.kt @@ -13,9 +13,7 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -24,7 +22,6 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseLayout import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.presentation.core.components.common.IconButton @@ -33,40 +30,29 @@ import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBar import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBarData import ua.acclorite.book_story.presentation.navigator.NavigatorIconButton import ua.acclorite.book_story.ui.browse.BrowseEvent -import java.io.File @OptIn(ExperimentalMaterial3Api::class) @Composable fun BrowseTopBar( files: List, layout: BrowseLayout, - filesStructure: BrowseFilesStructure, includedFilterItems: List, canScrollBackList: Boolean, canScrollBackGrid: Boolean, - selectedDirectory: File, - inNestedDirectory: Boolean, hasSelectedItems: Boolean, selectedItemsCount: Int, showSearch: Boolean, searchQuery: String, - hasSearched: Boolean, - isError: Boolean, focusRequester: FocusRequester, searchVisibility: (BrowseEvent.OnSearchVisibility) -> Unit, searchQueryChange: (BrowseEvent.OnSearchQueryChange) -> Unit, search: (BrowseEvent.OnSearch) -> Unit, requestFocus: (BrowseEvent.OnRequestFocus) -> Unit, - goBackDirectory: (BrowseEvent.OnGoBackDirectory) -> Unit, clearSelectedFiles: (BrowseEvent.OnClearSelectedFiles) -> Unit, selectFiles: (BrowseEvent.OnSelectFiles) -> Unit, - changeDirectory: (BrowseEvent.OnChangeDirectory) -> Unit, showFilterBottomSheet: (BrowseEvent.OnShowFilterBottomSheet) -> Unit, showAddDialog: (BrowseEvent.OnShowAddDialog) -> Unit ) { - val selectedDirectoryName = remember { - mutableStateOf(selectedDirectory.name) - } val isScrolled = remember(layout, canScrollBackList, canScrollBackGrid) { derivedStateOf { when (layout) { @@ -82,20 +68,13 @@ fun BrowseTopBar( } else LocalContentColor.current ) - LaunchedEffect(inNestedDirectory, selectedDirectory) { - if (inNestedDirectory) { - selectedDirectoryName.value = selectedDirectory.name - } - } - TopAppBar( scrollBehavior = null, isTopBarScrolled = isScrolled.value || hasSelectedItems, shownTopBar = when { - hasSelectedItems -> 3 - showSearch -> 2 - inNestedDirectory -> 1 + hasSelectedItems -> 2 + showSearch -> 1 else -> 0 }, topBars = listOf( @@ -131,45 +110,6 @@ fun BrowseTopBar( TopAppBarData( contentID = 1, - contentNavigationIcon = { - IconButton( - icon = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = R.string.go_back_content_desc, - disableOnClick = false, - enabled = inNestedDirectory - ) { - goBackDirectory(BrowseEvent.OnGoBackDirectory) - } - }, - contentTitle = { - Text( - selectedDirectoryName.value, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, - contentActions = { - IconButton( - icon = Icons.Default.Search, - contentDescription = R.string.search_content_desc, - disableOnClick = true - ) { - searchVisibility(BrowseEvent.OnSearchVisibility(true)) - } - IconButton( - icon = Icons.Default.FilterList, - contentDescription = R.string.filter_content_desc, - disableOnClick = false, - color = animatedFilterIconColor.value - ) { - showFilterBottomSheet(BrowseEvent.OnShowFilterBottomSheet) - } - NavigatorIconButton() - } - ), - - TopAppBarData( - contentID = 2, contentNavigationIcon = { IconButton( icon = Icons.AutoMirrored.Default.ArrowBack, @@ -201,7 +141,7 @@ fun BrowseTopBar( ), TopAppBarData( - contentID = 3, + contentID = 2, contentNavigationIcon = { IconButton( icon = Icons.Default.Clear, @@ -243,16 +183,6 @@ fun BrowseTopBar( } } ) - ), - customContent = { - BrowseTopBarDirectoryPath( - selectedDirectory = selectedDirectory, - hasSelectedItems = hasSelectedItems, - hasSearched = hasSearched, - isError = isError, - filesStructure = filesStructure, - changeDirectory = changeDirectory - ) - } + ) ) } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBarDirectoryPath.kt b/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBarDirectoryPath.kt deleted file mode 100644 index 81004771..00000000 --- a/app/src/main/java/ua/acclorite/book_story/presentation/browse/BrowseTopBarDirectoryPath.kt +++ /dev/null @@ -1,160 +0,0 @@ -package ua.acclorite.book_story.presentation.browse - -import android.os.Environment -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.expandVertically -import androidx.compose.animation.shrinkVertically -import androidx.compose.foundation.layout.Spacer -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.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowRight -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure -import ua.acclorite.book_story.domain.browse.FileWithTitle -import ua.acclorite.book_story.domain.ui.UIText -import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility -import ua.acclorite.book_story.presentation.core.util.noRippleClickable -import ua.acclorite.book_story.ui.browse.BrowseEvent -import java.io.File - -@Composable -fun BrowseTopBarDirectoryPath( - selectedDirectory: File, - hasSelectedItems: Boolean, - hasSearched: Boolean, - isError: Boolean, - filesStructure: BrowseFilesStructure, - changeDirectory: (BrowseEvent.OnChangeDirectory) -> Unit -) { - val rootDirectory = Environment.getExternalStorageDirectory() - - val directories = remember(selectedDirectory) { - val directories = mutableListOf() - - if (selectedDirectory == rootDirectory) { - return@remember listOf( - FileWithTitle( - title = UIText.StringResource(R.string.internal_storage), - file = rootDirectory - ) - ) - } - - directories.add( - FileWithTitle( - title = UIText.StringValue(selectedDirectory.name), - file = selectedDirectory - ) - ) - var currentDirectory = selectedDirectory.parentFile ?: return@remember emptyList() - - while (true) { - if (currentDirectory == rootDirectory) { - break - } - - directories.add( - FileWithTitle( - title = UIText.StringValue(currentDirectory.name), - file = currentDirectory - ) - ) - currentDirectory = currentDirectory.parentFile ?: continue - } - - directories.add( - FileWithTitle( - title = UIText.StringResource(R.string.internal_storage), - file = rootDirectory - ) - ) - - directories.reversed() - } - val listState = rememberLazyListState(directories.lastIndex) - - LaunchedEffect(directories) { - try { - listState.animateScrollToItem(directories.lastIndex) - } catch (e: Exception) { - e.printStackTrace() - } - } - - AnimatedVisibility( - visible = !hasSelectedItems - && !hasSearched - && !isError - && filesStructure == BrowseFilesStructure.DIRECTORIES, - enter = expandVertically(), - exit = shrinkVertically() - ) { - LazyRow( - Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - state = listState, - verticalAlignment = Alignment.CenterVertically - ) { - itemsIndexed( - directories, - key = { index, _ -> index } - ) { index, directory -> - if (index == 0) { - Spacer(modifier = Modifier.width(16.dp)) - } - - Text( - text = directory.title.asString(), - color = animateColorAsState( - if (index == directories.lastIndex) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurface, - label = "" - ).value, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.noRippleClickable( - enabled = selectedDirectory != directory.file - ) { - changeDirectory( - BrowseEvent.OnChangeDirectory( - directory = directory.file, - savePreviousDirectory = false - ) - ) - } - ) - - if (index < directories.lastIndex) { - Spacer(modifier = Modifier.width(4.dp)) - - Icon( - imageVector = Icons.AutoMirrored.Default.ArrowRight, - contentDescription = stringResource(id = R.string.path_arrow_icon_content_desc), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant, - ) - - Spacer(modifier = Modifier.width(4.dp)) - } else { - Spacer(modifier = Modifier.width(16.dp)) - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt index 7d9b3a02..1fac18b9 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt @@ -59,11 +59,9 @@ object DataStoreConstants { val PROGRESS_BAR_FONT_SIZE = intPreferencesKey("progress_bar_font_size") // Browse settings - val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") val BROWSE_LAYOUT = stringPreferencesKey("browse_layout") val BROWSE_AUTO_GRID_SIZE = booleanPreferencesKey("browse_auto_grid_size") val BROWSE_GRID_SIZE = intPreferencesKey("browse_grid_size") - val BROWSE_PIN_FAVORITE_DIRECTORIES = booleanPreferencesKey("browse_pin_favorite_directories") val BROWSE_SORT_ORDER = stringPreferencesKey("browse_sort_order") val BROWSE_SORT_ORDER_DESCENDING = booleanPreferencesKey("browse_sort_order_descending") val BROWSE_INCLUDED_FILTER_ITEMS = stringSetPreferencesKey("browse_included_filter_items") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/BrowseGeneralSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/BrowseGeneralSubcategory.kt index c1307d68..82facba5 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/BrowseGeneralSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/BrowseGeneralSubcategory.kt @@ -10,8 +10,6 @@ import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.settings.browse.general.components.BrowseGridSizeOption import ua.acclorite.book_story.presentation.settings.browse.general.components.BrowseLayoutOption -import ua.acclorite.book_story.presentation.settings.browse.general.components.FilesStructureOption -import ua.acclorite.book_story.presentation.settings.browse.general.components.PinFavoriteDirectoriesOption import ua.acclorite.book_story.presentation.settings.components.SettingsSubcategory fun LazyListScope.BrowseGeneralSubcategory( @@ -26,14 +24,6 @@ fun LazyListScope.BrowseGeneralSubcategory( showTitle = showTitle, showDivider = showDivider ) { - item { - FilesStructureOption() - } - - item { - PinFavoriteDirectoriesOption() - } - item { BrowseLayoutOption() } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/FilesStructureOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/FilesStructureOption.kt deleted file mode 100644 index e1a08ed4..00000000 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/FilesStructureOption.kt +++ /dev/null @@ -1,40 +0,0 @@ -package ua.acclorite.book_story.presentation.settings.browse.general.components - -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure -import ua.acclorite.book_story.domain.ui.ButtonItem -import ua.acclorite.book_story.presentation.core.components.settings.SegmentedButtonWithTitle -import ua.acclorite.book_story.ui.main.MainEvent -import ua.acclorite.book_story.ui.main.MainModel - -@Composable -fun FilesStructureOption() { - val mainModel = hiltViewModel() - val state = mainModel.state.collectAsStateWithLifecycle() - - SegmentedButtonWithTitle( - title = stringResource(id = R.string.browse_files_structure_option), - buttons = BrowseFilesStructure.entries.map { - ButtonItem( - it.toString(), - when (it) { - BrowseFilesStructure.ALL_FILES -> stringResource(id = R.string.files_structure_all) - BrowseFilesStructure.DIRECTORIES -> stringResource(id = R.string.files_structure_directory) - }, - MaterialTheme.typography.labelLarge, - it == state.value.browseFilesStructure - ) - } - ) { - mainModel.onEvent( - MainEvent.OnChangeBrowseFilesStructure( - it.id - ) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/PinFavoriteDirectoriesOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/PinFavoriteDirectoriesOption.kt deleted file mode 100644 index c5be8553..00000000 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/general/components/PinFavoriteDirectoriesOption.kt +++ /dev/null @@ -1,32 +0,0 @@ -package ua.acclorite.book_story.presentation.settings.browse.general.components - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure -import ua.acclorite.book_story.presentation.core.components.settings.SwitchWithTitle -import ua.acclorite.book_story.ui.main.MainEvent -import ua.acclorite.book_story.ui.main.MainModel -import ua.acclorite.book_story.ui.theme.ExpandingTransition - -@Composable -fun PinFavoriteDirectoriesOption() { - val mainModel = hiltViewModel() - val state = mainModel.state.collectAsStateWithLifecycle() - - ExpandingTransition(visible = state.value.browseFilesStructure == BrowseFilesStructure.DIRECTORIES) { - SwitchWithTitle( - selected = state.value.browsePinFavoriteDirectories, - title = stringResource(id = R.string.browse_pin_favorite_directories_option), - description = stringResource(id = R.string.browse_pin_favorite_directories_option_desc) - ) { - mainModel.onEvent( - MainEvent.OnChangeBrowsePinFavoriteDirectories( - !state.value.browsePinFavoriteDirectories - ) - ) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/sort/components/BrowseSortOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/sort/components/BrowseSortOption.kt index d213d6b1..74b8b379 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/sort/components/BrowseSortOption.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/browse/sort/components/BrowseSortOption.kt @@ -87,7 +87,6 @@ private fun BrowseSortOptionItem( when (item) { BrowseSortOrder.NAME -> R.string.browse_sort_order_name BrowseSortOrder.FILE_FORMAT -> R.string.browse_sort_order_file_format - BrowseSortOrder.FILE_TYPE -> R.string.browse_sort_order_file_type BrowseSortOrder.LAST_MODIFIED -> R.string.browse_sort_order_last_modified BrowseSortOrder.FILE_SIZE -> R.string.browse_sort_order_file_size } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseEvent.kt b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseEvent.kt index 9db1b40d..8c975263 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseEvent.kt @@ -10,7 +10,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionState import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.domain.library.book.SelectableNullableBook -import java.io.File @Immutable sealed class BrowseEvent { @@ -35,13 +34,6 @@ sealed class BrowseEvent { data object OnClearSelectedFiles : BrowseEvent() - data class OnChangeDirectory( - val directory: File, - val savePreviousDirectory: Boolean - ) : BrowseEvent() - - data object OnGoBackDirectory : BrowseEvent() - data class OnSelectFiles( val includedFileFormats: List, val files: List @@ -52,10 +44,6 @@ sealed class BrowseEvent { val file: SelectableFile ) : BrowseEvent() - data class OnUpdateFavoriteDirectory( - val path: String - ) : BrowseEvent() - data object OnShowFilterBottomSheet : BrowseEvent() data object OnDismissBottomSheet : BrowseEvent() diff --git a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt index 23fc8260..d8cc91f9 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt @@ -24,13 +24,11 @@ import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import kotlinx.coroutines.yield import ua.acclorite.book_story.R -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseSortOrder import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.domain.library.book.NullableBook import ua.acclorite.book_story.domain.library.book.SelectableNullableBook import ua.acclorite.book_story.domain.use_case.book.InsertBook -import ua.acclorite.book_story.domain.use_case.favorite_directory.UpdateFavoriteDirectory import ua.acclorite.book_story.domain.use_case.file_system.GetBookFromFile import ua.acclorite.book_story.domain.use_case.file_system.GetFilesFromDevice import ua.acclorite.book_story.presentation.core.util.launchActivity @@ -43,7 +41,6 @@ import kotlin.collections.map @HiltViewModel class BrowseModel @Inject constructor( private val getFilesFromDevice: GetFilesFromDevice, - private val updateFavoriteDirectory: UpdateFavoriteDirectory, private val getBookFromFile: GetBookFromFile, private val insertBook: InsertBook ) : ViewModel() { @@ -69,7 +66,6 @@ class BrowseModel @Inject constructor( private var refreshJob: Job? = null private var changeSearchQueryJob: Job? = null - private var changeDirectoryJob: Job? = null private var storagePermissionJob: Job? = null private var getAddDialogBooksJob: Job? = null @@ -160,58 +156,27 @@ class BrowseModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { _state.update { it.copy( - files = it.files.map { it.copy(isSelected = false) }, + files = it.files.map { it.copy(selected = false) }, hasSelectedItems = false ) } } } - is BrowseEvent.OnChangeDirectory -> { - viewModelScope.launch { - changeDirectoryJob?.cancel() - changeSearchQueryJob?.cancel() - - changeDirectoryJob = launch(Dispatchers.IO) { - yield() - _state.update { - it.copy( - selectedDirectory = event.directory, - previousDirectory = if (event.savePreviousDirectory) it.selectedDirectory - else event.directory.parentFile, - inNestedDirectory = event.directory != Environment.getExternalStorageDirectory() - ) - } - BrowseScreen.resetScrollPositionCompositionChannel.trySend(Unit) - } - } - } - - is BrowseEvent.OnGoBackDirectory -> { - onEvent( - BrowseEvent.OnChangeDirectory( - _state.value.previousDirectory ?: Environment.getExternalStorageDirectory(), - savePreviousDirectory = false - ) - ) - } - is BrowseEvent.OnSelectFiles -> { viewModelScope.launch(Dispatchers.IO) { val editedList = _state.value.files.map { file -> if ( event.files.any { - file.fileOrDirectory.path.startsWith(it.fileOrDirectory.path) + file.path.startsWith(it.path) } && event.includedFileFormats.run { if (isEmpty()) return@run true any { - file.fileOrDirectory.path.endsWith( - it, ignoreCase = true - ) || file.isDirectory + file.path.endsWith(it, ignoreCase = true) } } ) { - file.copy(isSelected = true) + file.copy(selected = true) } else { file } @@ -221,13 +186,13 @@ class BrowseModel @Inject constructor( it.copy( files = editedList, selectedItemsCount = editedList.filter { file -> - file.isSelected && !file.isDirectory + file.selected }.size.run { if (this == 0) return@run it.selectedItemsCount this }, hasSelectedItems = editedList.any { file -> - file.isSelected && !file.isDirectory + file.selected } ) } @@ -237,37 +202,12 @@ class BrowseModel @Inject constructor( is BrowseEvent.OnSelectFile -> { viewModelScope.launch(Dispatchers.IO) { val editedList = _state.value.files.map { file -> - when (event.file.isDirectory) { - false -> { - if (event.file.fileOrDirectory.path == file.fileOrDirectory.path) { - file.copy( - isSelected = !file.isSelected - ) - } else { - file - } - } - - true -> { - if ( - file.fileOrDirectory.path.startsWith( - event.file.fileOrDirectory.path - ) && event.includedFileFormats.run { - if (isEmpty()) return@run true - any { - file.fileOrDirectory.path.endsWith( - it, ignoreCase = true - ) || file.isDirectory - } - } - ) { - file.copy( - isSelected = !event.file.isSelected - ) - } else { - file - } - } + if (event.file.path == file.path) { + file.copy( + selected = !file.selected + ) + } else { + file } } @@ -275,29 +215,19 @@ class BrowseModel @Inject constructor( it.copy( files = editedList, selectedItemsCount = editedList.filter { file -> - file.isSelected && !file.isDirectory + file.selected }.size.run { if (this == 0) return@run it.selectedItemsCount this }, hasSelectedItems = editedList.any { file -> - file.isSelected && !file.isDirectory + file.selected } ) } } } - is BrowseEvent.OnUpdateFavoriteDirectory -> { - viewModelScope.launch { - _state.update { - it.copy(isLoading = true) - } - updateFavoriteDirectory.execute(event.path) - getFilesFromDownloads() - } - } - is BrowseEvent.OnShowFilterBottomSheet -> { viewModelScope.launch { _state.update { @@ -463,7 +393,7 @@ class BrowseModel @Inject constructor( val books = mutableListOf() _state.value.files - .filter { it.isSelected && !it.isDirectory } + .filter { it.selected } .ifEmpty { _state.update { it.copy( @@ -473,7 +403,7 @@ class BrowseModel @Inject constructor( } return@launch } - .map { it.fileOrDirectory } + .map { File(it.path) } .forEach { yield() books.add(getBookFromFile.execute(it)) @@ -609,7 +539,6 @@ class BrowseModel @Inject constructor( it.copy( files = this, selectedItemsCount = 0, - hasSearched = query.isNotBlank(), hasSelectedItems = false, isLoading = false ) @@ -626,15 +555,11 @@ class BrowseModel @Inject constructor( fun filterList( files: List, - hasSearched: Boolean, - selectedDirectory: File, - pinFavoriteDirectories: Boolean, sortOrderDescending: Boolean, includedFilterItems: List, - filesStructure: BrowseFilesStructure, sortOrder: BrowseSortOrder ): List { - fun thenCompareBy( + fun compareByWithOrder( selector: (T) -> Comparable<*>? ): Comparator { return if (sortOrderDescending) { @@ -650,83 +575,36 @@ class BrowseModel @Inject constructor( } return filter { file -> - when (file.isDirectory) { - true -> { - return@filter this.filter { - if (file == it) { - return@filter false - } - - it.fileOrDirectory.path.startsWith(file.fileOrDirectory.path) - }.filterFiles().isNotEmpty() - } - - false -> { - return@filter includedFilterItems.any { - file.fileOrDirectory.path.endsWith( - it, ignoreCase = true - ) - } - } + includedFilterItems.any { + file.path.endsWith( + it, ignoreCase = true + ) } } } return files .filterFiles() - .filter { - if (hasSearched || filesStructure == BrowseFilesStructure.ALL_FILES) { - return@filter !it.isDirectory - } - - if ( - Environment.getExternalStorageDirectory() == selectedDirectory - && it.isFavorite - && pinFavoriteDirectories - ) { - return@filter true - } - - it.parentDirectory == selectedDirectory - } .sortedWith( - compareByDescending { - when (pinFavoriteDirectories) { - true -> it.isFavorite - false -> true - } - }.then( - compareByDescending { - when (sortOrder != BrowseSortOrder.FILE_TYPE) { - true -> it.isDirectory - false -> true + compareByWithOrder { + when (sortOrder) { + BrowseSortOrder.NAME -> { + it.name.trim() + } + + BrowseSortOrder.FILE_FORMAT -> { + it.path.substringAfterLast(".").lowercase().trimEnd() + } + + BrowseSortOrder.FILE_SIZE -> { + it.size + } + + else -> { + it.lastModified } } - ).then( - thenCompareBy { - when (sortOrder) { - BrowseSortOrder.NAME -> { - it.fileOrDirectory.name.lowercase().trim() - } - - BrowseSortOrder.FILE_TYPE -> { - it.isDirectory - } - - BrowseSortOrder.FILE_FORMAT -> { - it.fileOrDirectory.extension - } - - BrowseSortOrder.FILE_SIZE -> { - it.fileOrDirectory.length() - } - - BrowseSortOrder.LAST_MODIFIED -> { - it.fileOrDirectory.lastModified() - } - } - } - ) + } ) } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseScreen.kt b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseScreen.kt index 95b62242..4e10b06f 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseScreen.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseLayout import ua.acclorite.book_story.domain.navigator.Screen import ua.acclorite.book_story.presentation.browse.BrowseContent @@ -93,12 +92,8 @@ object BrowseScreen : Screen, Parcelable { derivedStateOf { screenModel.filterList( files = state.value.files, - hasSearched = state.value.hasSearched, - selectedDirectory = state.value.selectedDirectory, - pinFavoriteDirectories = mainState.value.browsePinFavoriteDirectories, sortOrderDescending = mainState.value.browseSortOrderDescending, includedFilterItems = mainState.value.browseIncludedFilterItems, - filesStructure = mainState.value.browseFilesStructure, sortOrder = mainState.value.browseSortOrder ) } @@ -155,15 +150,11 @@ object BrowseScreen : Screen, Parcelable { listState = listState, gridState = gridState, layout = mainState.value.browseLayout, - filesStructure = mainState.value.browseFilesStructure, gridSize = mainState.value.browseGridSize, autoGridSize = mainState.value.browseAutoGridSize, includedFilterItems = mainState.value.browseIncludedFilterItems, canScrollBackList = listState.canScrollBackward, canScrollBackGrid = gridState.canScrollBackward, - selectedDirectory = state.value.selectedDirectory, - inNestedDirectory = state.value.inNestedDirectory - && mainState.value.browseFilesStructure != BrowseFilesStructure.ALL_FILES, hasSelectedItems = state.value.hasSelectedItems, selectedItemsCount = state.value.selectedItemsCount, isRefreshing = state.value.isRefreshing, @@ -173,19 +164,15 @@ object BrowseScreen : Screen, Parcelable { filesEmpty = files.value.isEmpty(), showSearch = state.value.showSearch, searchQuery = state.value.searchQuery, - hasSearched = state.value.hasSearched, focusRequester = focusRequester, searchVisibility = screenModel::onEvent, searchQueryChange = screenModel::onEvent, search = screenModel::onEvent, requestFocus = screenModel::onEvent, clearSelectedFiles = screenModel::onEvent, - goBackDirectory = screenModel::onEvent, selectFiles = screenModel::onEvent, selectFile = screenModel::onEvent, permissionCheck = screenModel::onEvent, - changeDirectory = screenModel::onEvent, - updateFavoriteDirectory = screenModel::onEvent, showFilterBottomSheet = screenModel::onEvent, dismissBottomSheet = screenModel::onEvent, actionPermissionDialog = screenModel::onEvent, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseState.kt b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseState.kt index 3f5f4c89..36dd9753 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseState.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseState.kt @@ -1,21 +1,15 @@ package ua.acclorite.book_story.ui.browse -import android.os.Environment import androidx.compose.runtime.Immutable import ua.acclorite.book_story.domain.browse.SelectableFile import ua.acclorite.book_story.domain.library.book.SelectableNullableBook import ua.acclorite.book_story.domain.util.BottomSheet import ua.acclorite.book_story.domain.util.Dialog -import java.io.File @Immutable data class BrowseState( val files: List = emptyList(), - val selectedDirectory: File = Environment.getExternalStorageDirectory(), - val previousDirectory: File? = null, - val inNestedDirectory: Boolean = false, - val isLoading: Boolean = true, val isRefreshing: Boolean = false, val isError: Boolean = false, @@ -25,7 +19,6 @@ data class BrowseState( val showSearch: Boolean = false, val searchQuery: String = "", - val hasSearched: Boolean = false, val hasFocused: Boolean = false, val dialog: Dialog? = null, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt index 96cc43e1..50d24cbb 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt @@ -20,11 +20,9 @@ sealed class MainEvent { data class OnChangeSidePadding(val value: Int) : MainEvent() data class OnChangeDoubleClickTranslation(val value: Boolean) : MainEvent() data class OnChangeFastColorPresetChange(val value: Boolean) : MainEvent() - data class OnChangeBrowseFilesStructure(val value: String) : MainEvent() data class OnChangeBrowseLayout(val value: String) : MainEvent() data class OnChangeBrowseAutoGridSize(val value: Boolean) : MainEvent() data class OnChangeBrowseGridSize(val value: Int) : MainEvent() - data class OnChangeBrowsePinFavoriteDirectories(val value: Boolean) : MainEvent() data class OnChangeBrowseSortOrder(val value: String) : MainEvent() data class OnChangeBrowseSortOrderDescending(val value: Boolean) : MainEvent() data class OnChangeBrowseIncludedFilterItem(val value: String) : MainEvent() diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt index 1acc54f6..e2b6f787 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import kotlinx.coroutines.yield -import ua.acclorite.book_story.domain.browse.toBrowseFilesStructure import ua.acclorite.book_story.domain.browse.toBrowseLayout import ua.acclorite.book_story.domain.browse.toBrowseSortOrder import ua.acclorite.book_story.domain.reader.toColorEffects @@ -189,14 +188,6 @@ class MainModel @Inject constructor( } ) - is MainEvent.OnChangeBrowseFilesStructure -> handleDatastoreUpdate( - key = DataStoreConstants.BROWSE_FILES_STRUCTURE, - value = event.value, - updateState = { - it.copy(browseFilesStructure = toBrowseFilesStructure()) - } - ) - is MainEvent.OnChangeBrowseLayout -> handleDatastoreUpdate( key = DataStoreConstants.BROWSE_LAYOUT, value = event.value, @@ -221,14 +212,6 @@ class MainModel @Inject constructor( } ) - is MainEvent.OnChangeBrowsePinFavoriteDirectories -> handleDatastoreUpdate( - key = DataStoreConstants.BROWSE_PIN_FAVORITE_DIRECTORIES, - value = event.value, - updateState = { - it.copy(browsePinFavoriteDirectories = this) - } - ) - is MainEvent.OnChangeBrowseSortOrder -> handleDatastoreUpdate( key = DataStoreConstants.BROWSE_SORT_ORDER, value = event.value, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt index d62f3f1a..8c8b5e0d 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt @@ -7,10 +7,8 @@ import androidx.annotation.Keep import androidx.compose.runtime.Immutable import androidx.datastore.preferences.core.Preferences import kotlinx.parcelize.Parcelize -import ua.acclorite.book_story.domain.browse.BrowseFilesStructure import ua.acclorite.book_story.domain.browse.BrowseLayout import ua.acclorite.book_story.domain.browse.BrowseSortOrder -import ua.acclorite.book_story.domain.browse.toBrowseFilesStructure import ua.acclorite.book_story.domain.browse.toBrowseLayout import ua.acclorite.book_story.domain.browse.toBrowseSortOrder import ua.acclorite.book_story.domain.reader.ReaderColorEffects @@ -108,13 +106,9 @@ data class MainState( val progressBarFontSize: Int = provideDefaultValue { 8 }, // Browse Settings - val browseFilesStructure: BrowseFilesStructure = provideDefaultValue { - BrowseFilesStructure.DIRECTORIES - }, val browseLayout: BrowseLayout = provideDefaultValue { BrowseLayout.LIST }, val browseAutoGridSize: Boolean = provideDefaultValue { true }, val browseGridSize: Int = provideDefaultValue { 0 }, - val browsePinFavoriteDirectories: Boolean = provideDefaultValue { true }, val browseSortOrder: BrowseSortOrder = provideDefaultValue { BrowseSortOrder.LAST_MODIFIED }, val browseSortOrderDescending: Boolean = provideDefaultValue { true }, val browseIncludedFilterItems: List = provideDefaultValue { emptyList() }, @@ -208,10 +202,6 @@ data class MainState( FAST_COLOR_PRESET_CHANGE ) { fastColorPresetChange }, - browseFilesStructure = provideValue( - BROWSE_FILES_STRUCTURE, convert = { toBrowseFilesStructure() } - ) { browseFilesStructure }, - browseLayout = provideValue( BROWSE_LAYOUT, convert = { toBrowseLayout() } ) { browseLayout }, @@ -224,10 +214,6 @@ data class MainState( BROWSE_GRID_SIZE ) { browseGridSize }, - browsePinFavoriteDirectories = provideValue( - BROWSE_PIN_FAVORITE_DIRECTORIES - ) { browsePinFavoriteDirectories }, - browseSortOrder = provideValue( BROWSE_SORT_ORDER, convert = { toBrowseSortOrder() } ) { browseSortOrder }, diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 677fd1e1..4cb93f77 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -128,13 +128,9 @@ لم يتم العثور على تطبيق قاموس. لم يتم العثور على تطبيق للمشاركة. مائل - كل الملفات - المجلدات - تثبيت مجلداتك المفضلة في أعلى الشاشة أخضر أحمر أزرق - تثبيت المجلدات المفضلة معطل عطارد زحل @@ -151,7 +147,6 @@ اوتوماتيكي بالسطر أبجديا - نوع الملف نبتون المريخ المشتري @@ -197,7 +192,6 @@ توفير آخر تعديل مواءمة النص - هيكل الملفات اضغط مرة أخرى مزدوجة للخروج اضغط مرتين للخروج من التطبيق تباعد الحروف @@ -241,7 +235,6 @@ الافتراضي السطوع غانيميد - التخزين الداخلي اخر مرة تم فيها فتح الملف فصول كاليستو diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index ad1553fa..bbb8f320 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -61,7 +61,6 @@ Verze aplikace Knihovna Pomozte překládat - Složky Filtr Čtečka Aktualizace %1$s @@ -122,7 +121,6 @@ Překlad na dvojité kliknutí Nechat obrazovku zapnutou Formát souboru - Typ souboru Velikost souboru Začátek Konec @@ -137,7 +135,6 @@ Nahlásit chybu Zdroje Spolupracovníci - Interní úložiště Smaže to všechny vybrané knihy( %1$s) z databáze. Nesmaže to knihy ze zařízení. Nikdy Nastavení @@ -182,7 +179,6 @@ Barvy Velikost fontu Výška odstavce - Připnout oblíbené složky Modrá Book\'s Story v%1$s Změnit barvu pozadí na čistě černou @@ -196,12 +192,10 @@ Resetovat obálku Klepněte pro zkontrolování aktualizací Přejít na - Struktura souborů Zapnutý Spořič Střední Vysoký - Všechny soubory na řádku Zarovnat Do prostřed @@ -225,8 +219,6 @@ Vyžadováno, abychom mohli skenoval Vaše úložiště a hledat knihy Preference jazyka Preference témat - Složka - Oblíbená složka Historie čtení Řadit podle Obálka diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b4f1179b..7f524562 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -254,7 +254,6 @@ Dreizack GitHub Profil Ziehen - Interner Speicher Filter Filter Sortieren @@ -264,31 +263,22 @@ Sortieren Anzeigemodus Rastergröße - Alle Dateien - Verzeichnisse Liste Raster Auto Pro Reihe Alphabetisch Dateiformat - Dateityp - Ordner - Lieblingsordner Sortierung - Pfadpfeil Alle Dateien auswählen Keine App zum Teilen gefunden. Keine Wörterbuch-App gefunden. Websuche Teilen Allgemein - Lieblingsverzeichnisse anpinnen - Heften Sie Ihre Lieblingsverzeichnisse oben auf dem Bildschirm an Zuletzt geändert Dateigröße Textausrichtung - Dateistruktur Start Rechtfertigen Mitte diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 499630b8..28907083 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -260,11 +260,7 @@ Cuadrícula por fila Tamaño del archivo - Almacenamiento interno - Directorio - Directorio preferido Orden de clasificación - Flecha de trayectoria No se ha encontrado ninguna aplicación para compartir. No se ha encontrado ninguna aplicación de diccionario. Buscar en Internet @@ -275,12 +271,7 @@ Filtrar Clasificar Modo de visualización - Fijar directorios favoritos - Todos los archivos Lista - Fija tus directorios favoritos en la parte superior de la pantalla - Directorios - Tipo de archivo Auto Formato del archivo Alfabéticamente @@ -288,7 +279,6 @@ Seleccionar todos los archivos Filtrar Alineación del texto - Estructura de los ficheros Iniciar Justificar Centrar diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9e737865..b147b178 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -92,11 +92,8 @@ Balayez la barre supérieure à gauche ou à droite pour changer de couleur par défaut Alignement du texte Espacement des lettres - Structure des fichiers Mode d\'affichage Taille de la grille - Épingler les répertoires favoris - Épinglez vos répertoires préférés en haut de l\'écran Rouge Vert Bleu @@ -110,12 +107,10 @@ Élevé Italique Normal - Tous les fichiers Liste Grille Automatique par ligne - Type de fichier Dernière modification Taille de fichier Début @@ -149,7 +144,6 @@ Dernier fichier ouvert Taille du fichier Inconnu - Stockage interne Book\'s Story v%1$s Cliquez pour vérifier les mises à jour Signaler un bug @@ -206,8 +200,6 @@ Retourner Image de couverture Fichier - Répertoire - Flèche du chemin Case à cocher L\'image de couverture n\'a pas été trouvée Appliquer les changements @@ -275,7 +267,6 @@ Hauteur de la ligne Activé Désactivé - Répertoires Format de fichier Alphabétiquement Déplacer @@ -300,7 +291,6 @@ Ordre de tri Historique de lecture Aujourd\'hui - Répertoire favoris Créer un nouveau préréglage de couleur Filtre Noir absolu diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index b56284f9..de62aadf 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -138,11 +138,8 @@ धारणा विस्तारक केंद्र पर ध्यान केंद्रित करके अपनी पढ़ने की गति बढ़ाएँ धारणा विस्तारक लाइन पैडिंग - फ़ाइल संरचना प्रदर्शन मोड ग्रिड का आकार - पसंदीदा फ़ोल्डर पिन करें - पसंदीदा फ़ोल्डरों को स्क्रीन के शीर्ष पर पिन करें हरा नीला प्रीसेट को नाम दें… @@ -157,13 +154,10 @@ ऊँचा तिर्छा साधारण - सभी फाइलें - फ़ोल्डर्स सूची ग्रिड स्वचालित फाइल का प्रकार - फाइल का प्रकार आखिरी बार संशोधित प्रारंभ सममित करें @@ -244,7 +238,6 @@ इतिहास तत्व सफलतापूर्वक हटा दिया गया। फ़ाइल का नाम अज्ञात - आंतरिक स्टोरेज एक बग रिपोर्ट करो नए अपडेट का प्रबंधन यदि आपको डाउनलोड की गई पुस्तकें दिखाई नहीं देती हैं तो सूची को नीचे खींचकर ताज़ा करने का प्रयास करें। सुनिश्चित करें कि आपकी पुस्तकों में फ़ाइल स्वरूप समर्थित है। फिर पुस्तक को चुनने के लिए उस पर क्लिक करें या उसका स्थान दिखाने के लिए उसे दबाए रखें। अपनी इच्छित सभी पुस्तकों का चयन करने के बाद, ऊपरी दाएं कोने में चेकमार्क आइकन पर क्लिक करें, सभी पुस्तकों के लोड होने की प्रतीक्षा करें और \"जोड़ें\" पर क्लिक करें। अब आपको वे सभी पुस्तकें दिखनी चाहिए जिन्हें आपने इसमें जोड़ा है diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 15e903e4..0122d5d2 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -33,7 +33,6 @@ Aggiungi libri Impostazioni lettore File - Cartella preferita Criterio di ordinamento Profilo GitHub Dimensioni griglia @@ -79,7 +78,6 @@ Sì, vai ad Aiuto No Elimina preset di colori - Cartelle Abilitato Aiuto Errore @@ -129,7 +127,6 @@ Standard Alfabetico Ultima modifica - Tipo file Dimensioni file Saturno Mercurio @@ -157,7 +154,6 @@ Autore Lista Traduzione - Cartella Spostare libro? Impostazioni Aggiungere libri? @@ -180,14 +176,12 @@ Generale Filtro Normale - Tutti i file Elimina tutta la cronologia Ieri Random Orientamento dello schermo Disabilitato Libero - Struttura dei file Modalità di visualizzazione Velocità di lettura Nessuna app da condividere trovata. @@ -213,7 +207,6 @@ L\'ultima versione dell\'app è già installata. Libreria Benvenuti in Book\'s Story! - Freccia del percorso per riga La cronologia è stata eliminata correttamente. Premere di nuovo Indietro per uscire @@ -247,7 +240,6 @@ Impostazioni Elimina cronologia elemento Lettura - Blocca le directory preferite Come si legge un libro? Cancella gli elementi selezionati Ripristina @@ -330,10 +322,8 @@ Cliccando sul pulsante Elimina a destra dell\'elemento cronologia, questo verrà eliminato. La cronologia influisce sull\'ordine dei libri in Libreria, eliminando l\'elemento cronologia si riordinerà anche un libro. L\'ultimo libro aperto è sempre il primo in Libreria e Cronologia. Come si utilizzano i suggerimenti? L\'espansore di percezione può aiutarti a leggere più velocemente. Per prima cosa, abilitalo nelle impostazioni del Lettore(vedi: Come personalizzare il Lettore?). Una volta abilitato, appariranno due linee verticali su entrambi i lati del Lettore. Per ottimizzare ulteriormente la velocità di lettura, regola il margine per creare meno spazio attorno al centro. Per utilizzarlo, concentrati sul centro dello schermo mentre consenti alla tua visione periferica di cogliere il testo sui lati. Mentre leggi, mantieni la concentrazione sul centro senza guardare direttamente i lati dopo ogni riga. - Memoria interna L\'immagine di copertina è stata reimpostata correttamente. Idea - Aggiungi le tue directory preferite nella parte superiore dello schermo Cosa c\'è di nuovo Se non vedi i libri scaricati, prova ad aggiornare l\'elenco tirandolo verso il basso. Assicurati che i tuoi libri abbiano un formato di file supportato. Quindi fai clic sul libro per selezionarlo o tieni premuto per mostrarne la posizione. Dopo aver selezionato tutti i libri desiderati, fai clic sull\'icona del segno di spunta nell\'angolo in alto a destra, attendi che tutti i libri vengano caricati e fai clic su «Aggiungi». Ora dovresti vedere tutti i libri che hai aggiunto nella Contributori diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 7bdc1f17..df0a0e97 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -114,14 +114,11 @@ Pełny ekran Pozostaw włączony ekran Ukryj paski w szybkim przewijaniu - Struktura plików - Przypnij swoje ulubione katalogi na górze ekranu Wyłączony Średni Normalny Lista Format pliku - Typ pliku Ostatnio modyfikowany Rozmiar pliku Start @@ -132,7 +129,6 @@ Naciśnij ponownie, aby wyjść Przesuń w lewo lub w prawo, aby zmienić ustawienie koloru Treść książki jest pusta. Upewnij się, że zawartość książki nie jest pusta i zaktualizuj ją. - Katalogi Nie znaleziono aplikacji tłumacza. Znaleziono nową wersję Book\'s Story. Chcesz ją pobrać? Klikając przycisk « Pobierz », zostaniesz przeniesiony do przeglądarki i automatycznie pobierzesz najnowszą aktualizację. Siatka @@ -140,13 +136,11 @@ Zresetuj obraz okładki Przenieść książki? Nie można zresetować obrazu okładki. - Przypnij ulubione katalogi To spowoduje usunięcie wszystkie wybranych książek (%1$s) z bazy danych. Nie usunie wybranych książek z twojego urządzenia. na rząd Wyrównanie tekstu Porzucone Tryb wyświetlania - Wszystkie pliki Możesz wybrać książki, które chcesz dodać. Możesz później edytować tytuł i obraz okładki książki. Proces ładowania może potrwać do kilku minut. Potrzebujemy uprawnień do przechowywania, aby przeskanować Twoje urządzenie w poszukiwaniu książek. Bez tego pozwolenia nie będziesz mógł dodać książki. Nie znaleziono aplikacji przeglądarki. @@ -217,7 +211,6 @@ Plik ostatnio otwarty Rozmiar pliku Nieznany - Pamięć wewnętrzna Ikony Przenieś wybrane książki Przywróć @@ -241,8 +234,6 @@ Wróć Obraz okładki Ustawienia czytnika - Ulubiony katalog - Strzałka ścieżki Pole wyboru Dodaj pliki Usuń element historii @@ -298,7 +289,6 @@ Co nowego Licencje open source Ustawienia - Katalog Błąd Szukaj Wyczyść wybrane elementy diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c8461682..db142f66 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -73,7 +73,6 @@ Sistema Padrão Normal - Diretórios Dar permissão? Apagar histórico de leitura? Autor @@ -111,7 +110,6 @@ Ontem Checkbox Arquivo - Diretório Erro Pesquisar Permissões @@ -156,7 +154,6 @@ Cor da fonte Margens verticais Alinhamento do texto - Todos os arquivos Tamanho do arquivo Contribuidores Tema do aplicativo @@ -170,10 +167,8 @@ Altura do parágrafo Padrão de cores Margem do recorte - Estrutura dos arquivos Modo de exibição por linha - Tipo de arquivo Lido Tamanho da grade Dar permissão @@ -184,7 +179,6 @@ Código fechado Pesquisa web Margens laterais - Armazenamento interno Iluminação Formato de arquivo Modificação mais recente @@ -210,7 +204,6 @@ Está tudo feito! Imagem da capa Configurações do leitor - Diretório favorito Slava Ukraini! Fechar pesquisa Ícone do App diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 54b8d9a6..976c0d54 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -42,7 +42,6 @@ முடக்கப்பட்டது இயக்கப்பட்டது மண்டலம் - அனைத்து கோப்புகள் எரிச் தேர்ந்தெடுக்கப்பட்ட அனைத்து புத்தகங்களும் வெற்றிகரமாக நகர்த்தப்பட்டன. தேர்ந்தெடுக்கப்பட்ட அனைத்து புத்தகங்களும் வெற்றிகரமாக நீக்கப்பட்டன. @@ -65,7 +64,6 @@ திரும்பிச் செல்லுங்கள் கவர் படம் வாசகர் அமைப்புகள் - பாதை அம்பு தேர்வுப்பெட்டி உங்கள் நூலகம் வரலாற்று உறுப்பை நீக்கு @@ -94,7 +92,6 @@ திறந்த மூல உரிமங்கள் வரலாறு கோப்பு - அடைவு எல்லா கோப்புகளையும் தேர்ந்தெடுக்கவும் வெளியேறும் தேடல் தெரியவில்லை @@ -246,10 +243,7 @@ வண்ண முன்னமைவை மாற்ற மேல் பட்டியை இடது அல்லது வலதுபுறமாக ச்வைப் செய்யவும் கடிதம் இடைவெளி திரை நோக்குநிலை - கோப்புகள் அமைப்பு கட்டம் அளவு - பிடித்த கோப்பகங்கள் - உங்களுக்கு பிடித்த கோப்பகங்களை திரையின் மேற்புறத்தில் பொருத்துங்கள் சிவப்பு பச்சை நீலம் @@ -258,9 +252,7 @@ உயர்ந்த சாய்வு சாதாரண - கோப்பகங்கள் அகரவரிசை - கோப்பு வகை கடைசியாக மாற்றப்பட்டது கோப்பு அளவு தொடங்கு @@ -288,7 +280,6 @@ கோப்பு பாதை கோப்பு கடைசியாக திறக்கப்பட்டது கோப்பு அளவு - உள் சேமிப்பு அத்தியாயங்கள் இல்லை பாடங்கள் புத்தகத்தின் கதை v%1$s @@ -330,7 +321,6 @@ பயன்பாட்டின் அடிப்படை அமைப்பை நீங்கள் வெற்றிகரமாக முடித்துவிட்டீர்கள். உதவித் திரையைப் படிப்பதன் மூலம் பயன்பாட்டை எவ்வாறு பயன்படுத்துவது என்பதை அறிய விரும்புகிறீர்களா? நேற்று தொடர்ந்து படிக்கவும் - பிடித்த அடைவு வரிசைப்படுத்தும் முறை கவர் படம் கிடைக்கவில்லை மாற்றங்களைப் பயன்படுத்துங்கள் diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index dcfab654..707afb4f 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -129,11 +129,8 @@ Renk ön ayarını değiştirmek için üst çubuğu sola veya sağa kaydırın Metin hizalama Harf aralığı - Dosya yapısı Görüntüleme modu Izgara boyutu - Favori dizinleri sabitle - Favori dizinlerinizi ekranın üst kısmına sabitleyin Kırmızı Yeşil Mavi @@ -149,15 +146,12 @@ Yüksek İtalik Normal - Tüm dosyalar - Dizinler Liste Izgara Otomatik satır başına Alfabetik Dosya formatı - Dosya türü Son değiştirilme Dosya boyutu Başlangıç @@ -195,7 +189,6 @@ Son açılma tarihi Dosya boyutu Bilinmiyor - Dahili Depolama Uygulama sürümü Book Story v%1$s Güncellemeleri kontrol etmek için tıklayın @@ -268,10 +261,7 @@ Kapak resmi Okuyucu ayarları Dosya - Dizin - Favori dizin Sıralama düzeni - Yol oku Onay kutusu Kapak resmi bulunamadı Değişiklikleri uygula diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 90d8f530..fe6be938 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -209,12 +209,8 @@ Розмір шрифта - Структура файлів Режим відображення Кількість комірок - Закріпити улюблені директорії - Закріпіть ваші улюблені директорії зверху екрана - Червоний Зелений @@ -241,9 +237,6 @@ Нормальний - Всі файли - Директорії - Список Сітка @@ -255,7 +248,6 @@ За алфавітом Формат файла - Тип файла Остання зміна Розмір файла @@ -334,8 +326,6 @@ Невідомо - Внутрішнє Сховище - Немає розділів Розділи @@ -437,10 +427,7 @@ Обкладинка Налаштування читача Файл - Тека - Улюблена тека Порядок сортування - Стрілка шляху Галочка Обкладенка не знайдена Застосувати зміни diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0c04fbc8..203ea258 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -87,8 +87,6 @@ 改变背景颜色使完全黑暗 镂空填充 将填充应用于镂空区域 - 在屏幕顶端固定您的收藏目录 - 固定收藏目录 网格大小 系统 正常 @@ -155,7 +153,6 @@ 感知扩展器 专注于中心以提升你的阅读速度 感知扩展器行厚度 - 文件结构 绿色 常规 中等 @@ -187,10 +184,8 @@ 居中 水星 阋神星 - 目录 文件大小 最后修改 - 全部文件 常规 阅读器 常规 @@ -198,7 +193,6 @@ 继续坚持! 网格 自动 - 文件类型 成功添加所有已选择的书。 成功删除所有已选择的书。 成功删除了封面图片。 @@ -234,7 +228,6 @@ 荣耀属于乌克兰! 文件最后打开 未知 - 内部存储 帮助翻译 翻译 如果你没有看见已下载的书可以尝试下拉刷新列表。确保你的书拥有所支持的文件格式。点击书来选择它或者按住来显示它的位置。当你选择了所有想选择的书之后,点击右上角的对勾图标,等待所有的书加载好后点击“添加”。所有你已经添加的书都应该显示在 @@ -286,7 +279,6 @@ 欢迎来到“Book\'s Story”! Perception Expander可以帮助你加快阅读速度。 首先,在阅读器设置中启用它(请参阅:如何自定义阅读器?) 启用后,阅读器两侧会出现两条竖线。 要进一步优化阅读速度,可以调整边距以减少屏幕四周的空间。 要使用它,请将注意力集中在屏幕中央,同时让你的余光捕捉到两侧的文字。 阅读时,请将注意力集中在中心位置,不要在每一行之后直接看两侧 阅读模式 - 阅读器设置 今天 昨天 继续阅读 @@ -302,7 +294,6 @@ 用于检查应用更新 语言偏好 应用主题 - 词典偏好 排序规则 应用更改 搜索 @@ -320,7 +311,6 @@ 移动所选书籍 返回 阅读设置 - 路径箭头 删除颜色预设 检查点撤回 你的书库 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44f11d9f..95c8af7c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -266,13 +266,8 @@ Font size - Files structure Display mode Grid size - Pin favorite directories - - Pin your favorite directories to the top of the screen - Red @@ -299,10 +294,6 @@ Italic Normal - - All files - Directories - List Grid @@ -314,7 +305,6 @@ Alphabetically File format - File type Last modified File size @@ -392,9 +382,6 @@ File size Unknown - - Internal Storage - No chapters Chapters @@ -597,10 +584,7 @@ Cover image Reader settings File - Directory - Favorite directory Sort order - Path arrow Checkbox Cover image not found Apply changes