🚀 Pin paths in Browse
* Added replacement for directories structure * Always show all files and paths to them * Pin favorite paths Resolves: #91
This commit is contained in:
parent
32cea59c7a
commit
e49f010353
16 changed files with 204 additions and 79 deletions
|
|
@ -0,0 +1,10 @@
|
|||
package ua.acclorite.book_story.domain.browse
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
data class GroupedFiles(
|
||||
val header: String,
|
||||
val pinned: Boolean,
|
||||
val files: List<SelectableFile>
|
||||
)
|
||||
|
|
@ -14,6 +14,7 @@ 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 ua.acclorite.book_story.ui.main.MainEvent
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalPermissionsApi::class)
|
||||
@Composable
|
||||
|
|
@ -31,6 +32,7 @@ fun BrowseContent(
|
|||
gridSize: Int,
|
||||
autoGridSize: Boolean,
|
||||
includedFilterItems: List<String>,
|
||||
pinnedPaths: List<String>,
|
||||
canScrollBackList: Boolean,
|
||||
canScrollBackGrid: Boolean,
|
||||
hasSelectedItems: Boolean,
|
||||
|
|
@ -59,6 +61,7 @@ fun BrowseContent(
|
|||
dismissAddDialog: (BrowseEvent.OnDismissAddDialog) -> Unit,
|
||||
actionAddDialog: (BrowseEvent.OnActionAddDialog) -> Unit,
|
||||
selectAddDialog: (BrowseEvent.OnSelectAddDialog) -> Unit,
|
||||
changePinnedPaths: (MainEvent.OnChangeBrowsePinnedPaths) -> Unit,
|
||||
navigateToLibrary: () -> Unit,
|
||||
navigateToHelp: () -> Unit,
|
||||
) {
|
||||
|
|
@ -89,6 +92,7 @@ fun BrowseContent(
|
|||
gridSize = gridSize,
|
||||
autoGridSize = autoGridSize,
|
||||
includedFilterItems = includedFilterItems,
|
||||
pinnedPaths = pinnedPaths,
|
||||
canScrollBackList = canScrollBackList,
|
||||
canScrollBackGrid = canScrollBackGrid,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
|
|
@ -112,6 +116,7 @@ fun BrowseContent(
|
|||
selectFile = selectFile,
|
||||
showFilterBottomSheet = showFilterBottomSheet,
|
||||
showAddDialog = showAddDialog,
|
||||
changePinnedPaths = changePinnedPaths,
|
||||
navigateToHelp = navigateToHelp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package ua.acclorite.book_story.presentation.browse
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
|
@ -10,7 +11,7 @@ import androidx.compose.foundation.lazy.grid.items
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.domain.browse.BrowseLayout
|
||||
import ua.acclorite.book_story.domain.browse.GroupedFiles
|
||||
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||
import ua.acclorite.book_story.presentation.core.components.common.LazyVerticalGridWithScrollbar
|
||||
import ua.acclorite.book_story.presentation.core.components.common.header
|
||||
|
|
@ -19,43 +20,34 @@ import ua.acclorite.book_story.presentation.core.constants.providePrimaryScrollb
|
|||
|
||||
@Composable
|
||||
fun BrowseGridLayout(
|
||||
groupedFiles: List<GroupedFiles>,
|
||||
gridSize: Int,
|
||||
autoGridSize: Boolean,
|
||||
gridState: LazyGridState,
|
||||
files: List<SelectableFile>,
|
||||
hasSelectedItems: Boolean,
|
||||
onLongItemClick: (SelectableFile) -> Unit,
|
||||
onItemClick: (SelectableFile) -> Unit,
|
||||
headerContent: @Composable (header: String, pinned: Boolean) -> Unit,
|
||||
itemContent: @Composable (file: SelectableFile, files: List<SelectableFile>) -> Unit
|
||||
) {
|
||||
LazyVerticalGridWithScrollbar(
|
||||
columns = if (autoGridSize) GridCells.Adaptive(170.dp)
|
||||
else GridCells.Fixed(gridSize.coerceAtLeast(1)),
|
||||
state = gridState,
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(horizontal = 8.dp),
|
||||
scrollbarSettings = Constants.providePrimaryScrollbar(false)
|
||||
) {
|
||||
header {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
groupedFiles.forEach { group ->
|
||||
stickyHeader {
|
||||
headerContent(group.header, group.pinned)
|
||||
}
|
||||
|
||||
items(
|
||||
files,
|
||||
key = { it.path }
|
||||
) { selectableFile ->
|
||||
BrowseItem(
|
||||
file = selectableFile,
|
||||
modifier = Modifier.animateItem(),
|
||||
layout = BrowseLayout.GRID,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
onLongClick = {
|
||||
onLongItemClick(selectableFile)
|
||||
},
|
||||
onClick = {
|
||||
onItemClick(selectableFile)
|
||||
items(
|
||||
group.files,
|
||||
key = { it.path }
|
||||
) { selectableFile ->
|
||||
Box(Modifier.animateItem()) {
|
||||
itemContent(selectableFile, group.files)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import ua.acclorite.book_story.domain.browse.SelectableFile
|
|||
|
||||
@Composable
|
||||
fun BrowseItem(
|
||||
modifier: Modifier = Modifier,
|
||||
layout: BrowseLayout,
|
||||
file: SelectableFile,
|
||||
hasSelectedItems: Boolean,
|
||||
modifier: Modifier,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -3,41 +3,56 @@ package ua.acclorite.book_story.presentation.browse
|
|||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import ua.acclorite.book_story.domain.browse.BrowseLayout
|
||||
import ua.acclorite.book_story.domain.browse.GroupedFiles
|
||||
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||
import java.io.File
|
||||
|
||||
@Composable
|
||||
fun BrowseLayout(
|
||||
files: List<SelectableFile>,
|
||||
hasSelectedItems: Boolean,
|
||||
pinnedPaths: List<String>,
|
||||
layout: BrowseLayout,
|
||||
gridSize: Int,
|
||||
autoGridSize: Boolean,
|
||||
listState: LazyListState,
|
||||
gridState: LazyGridState,
|
||||
onLongItemClick: (SelectableFile) -> Unit,
|
||||
onItemClick: (SelectableFile) -> Unit
|
||||
headerContent: @Composable (header: String, pinned: Boolean) -> Unit,
|
||||
itemContent: @Composable (file: SelectableFile, files: List<SelectableFile>) -> Unit
|
||||
) {
|
||||
val groupedFiles = remember(files, pinnedPaths) {
|
||||
files.groupBy { file ->
|
||||
file.path.substringBeforeLast(File.separator)
|
||||
}.map { (header, files) ->
|
||||
GroupedFiles(
|
||||
header = header,
|
||||
pinned = pinnedPaths.any { it.lowercase().trim() == header.lowercase().trim() },
|
||||
files = files
|
||||
)
|
||||
}.sortedByDescending { group ->
|
||||
group.pinned
|
||||
}
|
||||
}
|
||||
|
||||
when (layout) {
|
||||
BrowseLayout.LIST -> {
|
||||
BrowseListLayout(
|
||||
files = files,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
groupedFiles = groupedFiles,
|
||||
listState = listState,
|
||||
onLongItemClick = onLongItemClick,
|
||||
onItemClick = onItemClick
|
||||
headerContent = headerContent,
|
||||
itemContent = itemContent
|
||||
)
|
||||
}
|
||||
|
||||
BrowseLayout.GRID -> {
|
||||
BrowseGridLayout(
|
||||
groupedFiles = groupedFiles,
|
||||
gridSize = gridSize,
|
||||
autoGridSize = autoGridSize,
|
||||
files = files,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
gridState = gridState,
|
||||
onLongItemClick = onLongItemClick,
|
||||
onItemClick = onItemClick
|
||||
headerContent = headerContent,
|
||||
itemContent = itemContent
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package ua.acclorite.book_story.presentation.browse
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.PushPin
|
||||
import androidx.compose.material.icons.outlined.PushPin
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
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.presentation.core.util.noRippleClickable
|
||||
|
||||
@Composable
|
||||
fun BrowseLayoutHeader(
|
||||
header: String,
|
||||
pinned: Boolean,
|
||||
pin: () -> Unit
|
||||
) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.padding(horizontal = 8.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = header,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.noRippleClickable {
|
||||
pin()
|
||||
},
|
||||
imageVector = if (pinned) Icons.Default.PushPin
|
||||
else Icons.Outlined.PushPin,
|
||||
contentDescription = stringResource(R.string.pin_content_desc),
|
||||
tint = if (pinned) MaterialTheme.colorScheme.primary
|
||||
else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ fun BrowseListItem(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp, vertical = 3.dp)
|
||||
.padding(vertical = 3.dp)
|
||||
.clip(RoundedCornerShape(10.dp))
|
||||
.background(
|
||||
if (file.selected) MaterialTheme.colorScheme.secondaryContainer
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package ua.acclorite.book_story.presentation.browse
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
|
|
@ -8,7 +10,7 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.domain.browse.BrowseLayout
|
||||
import ua.acclorite.book_story.domain.browse.GroupedFiles
|
||||
import ua.acclorite.book_story.domain.browse.SelectableFile
|
||||
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||
|
|
@ -16,37 +18,30 @@ import ua.acclorite.book_story.presentation.core.constants.providePrimaryScrollb
|
|||
|
||||
@Composable
|
||||
fun BrowseListLayout(
|
||||
files: List<SelectableFile>,
|
||||
hasSelectedItems: Boolean,
|
||||
groupedFiles: List<GroupedFiles>,
|
||||
listState: LazyListState,
|
||||
onLongItemClick: (SelectableFile) -> Unit,
|
||||
onItemClick: (SelectableFile) -> Unit,
|
||||
headerContent: @Composable (header: String, pinned: Boolean) -> Unit,
|
||||
itemContent: @Composable (file: SelectableFile, files: List<SelectableFile>) -> Unit
|
||||
) {
|
||||
LazyColumnWithScrollbar(
|
||||
state = listState,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(horizontal = 8.dp),
|
||||
scrollbarSettings = Constants.providePrimaryScrollbar(false)
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
groupedFiles.forEach { group ->
|
||||
stickyHeader {
|
||||
headerContent(group.header, group.pinned)
|
||||
}
|
||||
|
||||
items(
|
||||
files,
|
||||
key = { it.path }
|
||||
) { selectableFile ->
|
||||
BrowseItem(
|
||||
file = selectableFile,
|
||||
layout = BrowseLayout.LIST,
|
||||
modifier = Modifier.animateItem(),
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
onLongClick = {
|
||||
onLongItemClick(selectableFile)
|
||||
},
|
||||
onClick = {
|
||||
onItemClick(selectableFile)
|
||||
items(
|
||||
group.files,
|
||||
key = { it.path }
|
||||
) { selectableFile ->
|
||||
Box(Modifier.animateItem()) {
|
||||
itemContent(selectableFile, group.files)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ import androidx.compose.ui.Modifier
|
|||
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.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.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.theme.DefaultTransition
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalPermissionsApi::class)
|
||||
|
|
@ -35,6 +33,7 @@ fun BrowseScaffold(
|
|||
gridSize: Int,
|
||||
autoGridSize: Boolean,
|
||||
includedFilterItems: List<String>,
|
||||
pinnedPaths: List<String>,
|
||||
canScrollBackList: Boolean,
|
||||
canScrollBackGrid: Boolean,
|
||||
hasSelectedItems: Boolean,
|
||||
|
|
@ -57,10 +56,9 @@ fun BrowseScaffold(
|
|||
permissionCheck: (BrowseEvent.OnPermissionCheck) -> Unit,
|
||||
showFilterBottomSheet: (BrowseEvent.OnShowFilterBottomSheet) -> Unit,
|
||||
showAddDialog: (BrowseEvent.OnShowAddDialog) -> Unit,
|
||||
changePinnedPaths: (MainEvent.OnChangeBrowsePinnedPaths) -> Unit,
|
||||
navigateToHelp: () -> Unit,
|
||||
) {
|
||||
val context = LocalActivity.current
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -97,24 +95,46 @@ fun BrowseScaffold(
|
|||
DefaultTransition(visible = !isLoading) {
|
||||
BrowseLayout(
|
||||
files = files,
|
||||
pinnedPaths = pinnedPaths,
|
||||
layout = layout,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
gridSize = gridSize,
|
||||
autoGridSize = autoGridSize,
|
||||
listState = listState,
|
||||
gridState = gridState,
|
||||
onLongItemClick = { file ->
|
||||
context.getString(
|
||||
R.string.file_path_query,
|
||||
file.path
|
||||
).showToast(context = context)
|
||||
headerContent = { header, pinned ->
|
||||
BrowseLayoutHeader(
|
||||
header = header,
|
||||
pinned = pinned,
|
||||
pin = {
|
||||
changePinnedPaths(
|
||||
MainEvent.OnChangeBrowsePinnedPaths(
|
||||
value = header
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
onItemClick = { file ->
|
||||
selectFile(
|
||||
BrowseEvent.OnSelectFile(
|
||||
includedFileFormats = includedFilterItems,
|
||||
file = file
|
||||
)
|
||||
itemContent = { file, groupFiles ->
|
||||
BrowseItem(
|
||||
file = file,
|
||||
layout = layout,
|
||||
hasSelectedItems = hasSelectedItems,
|
||||
onLongClick = {
|
||||
selectFiles(
|
||||
BrowseEvent.OnSelectFiles(
|
||||
includedFileFormats = includedFilterItems,
|
||||
files = groupFiles
|
||||
)
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
selectFile(
|
||||
BrowseEvent.OnSelectFile(
|
||||
includedFileFormats = includedFilterItems,
|
||||
file = file
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -65,4 +65,5 @@ object DataStoreConstants {
|
|||
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")
|
||||
val BROWSE_PINNED_PATHS = stringSetPreferencesKey("browse_pinned_paths")
|
||||
}
|
||||
|
|
@ -153,6 +153,7 @@ object BrowseScreen : Screen, Parcelable {
|
|||
gridSize = mainState.value.browseGridSize,
|
||||
autoGridSize = mainState.value.browseAutoGridSize,
|
||||
includedFilterItems = mainState.value.browseIncludedFilterItems,
|
||||
pinnedPaths = mainState.value.browsePinnedPaths,
|
||||
canScrollBackList = listState.canScrollBackward,
|
||||
canScrollBackGrid = gridState.canScrollBackward,
|
||||
hasSelectedItems = state.value.hasSelectedItems,
|
||||
|
|
@ -181,6 +182,7 @@ object BrowseScreen : Screen, Parcelable {
|
|||
dismissAddDialog = screenModel::onEvent,
|
||||
selectAddDialog = screenModel::onEvent,
|
||||
actionAddDialog = screenModel::onEvent,
|
||||
changePinnedPaths = mainModel::onEvent,
|
||||
navigateToLibrary = {
|
||||
navigator.push(LibraryScreen, saveInBackStack = false)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -57,4 +57,5 @@ sealed class MainEvent {
|
|||
data class OnChangeProgressBarPadding(val value: Int) : MainEvent()
|
||||
data class OnChangeProgressBarAlignment(val value: String) : MainEvent()
|
||||
data class OnChangeProgressBarFontSize(val value: Int) : MainEvent()
|
||||
data class OnChangeBrowsePinnedPaths(val value: String) : MainEvent()
|
||||
}
|
||||
|
|
@ -229,7 +229,7 @@ class MainModel @Inject constructor(
|
|||
)
|
||||
|
||||
is MainEvent.OnChangeBrowseIncludedFilterItem -> handleBrowseIncludedFilterItemUpdate(
|
||||
event
|
||||
event = event
|
||||
)
|
||||
|
||||
is MainEvent.OnChangeTextAlignment -> handleDatastoreUpdate(
|
||||
|
|
@ -479,6 +479,10 @@ class MainModel @Inject constructor(
|
|||
it.copy(progressBarFontSize = this)
|
||||
}
|
||||
)
|
||||
|
||||
is MainEvent.OnChangeBrowsePinnedPaths -> handleBrowsePinnedPathsUpdate(
|
||||
event = event
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -546,6 +550,22 @@ class MainModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun handleBrowsePinnedPathsUpdate(
|
||||
event: MainEvent.OnChangeBrowsePinnedPaths
|
||||
) {
|
||||
val set = _state.value.browsePinnedPaths.toMutableSet()
|
||||
if (!set.add(event.value)) {
|
||||
set.remove(event.value)
|
||||
}
|
||||
handleDatastoreUpdate(
|
||||
key = DataStoreConstants.BROWSE_PINNED_PATHS,
|
||||
value = set,
|
||||
updateState = {
|
||||
it.copy(browsePinnedPaths = toList())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles and updates Datastore.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ data class MainState(
|
|||
val browseSortOrder: BrowseSortOrder = provideDefaultValue { BrowseSortOrder.LAST_MODIFIED },
|
||||
val browseSortOrderDescending: Boolean = provideDefaultValue { true },
|
||||
val browseIncludedFilterItems: List<String> = provideDefaultValue { emptyList() },
|
||||
val browsePinnedPaths: List<String> = provideDefaultValue { emptyList() },
|
||||
) : Parcelable {
|
||||
companion object {
|
||||
private fun <D> provideDefaultValue(calculation: () -> D): D {
|
||||
|
|
@ -345,6 +346,10 @@ data class MainState(
|
|||
progressBarFontSize = provideValue(
|
||||
PROGRESS_BAR_FONT_SIZE
|
||||
) { progressBarFontSize },
|
||||
|
||||
browsePinnedPaths = provideValue(
|
||||
BROWSE_PINNED_PATHS, convert = { toList() }
|
||||
) { browsePinnedPaths },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,4 +463,6 @@
|
|||
<string name="checkpoint_forward_content_desc">Чекпоінт вперед</string>
|
||||
<string name="chapters_content_desc">Розділи</string>
|
||||
<string name="more_content_desc">Більше</string>
|
||||
<string name="pin_content_desc">Закріпити</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -623,5 +623,6 @@
|
|||
<string name="checkpoint_forward_content_desc">Checkpoint forward</string>
|
||||
<string name="chapters_content_desc">Chapters</string>
|
||||
<string name="more_content_desc">More</string>
|
||||
<string name="pin_content_desc">Pin</string>
|
||||
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue