Skip to content

Commit 0ec4d64

Browse files
committed
Set up custom file type saving
1 parent 73c7851 commit 0ec4d64

File tree

42 files changed

+564
-411
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+564
-411
lines changed

.idea/deploymentTargetSelector.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/kotlin/com/w2sv/filenavigator/ui/designsystem/Icons.kt

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,3 @@ fun FileTypeIcon(
2727
tint = tint
2828
)
2929
}
30-
31-
// @Composable
32-
// fun AutoMoveIcon(modifier: Modifier = Modifier, tint: Color = LocalContentColor.current) {
33-
// Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier) {
34-
// CompositionLocalProvider(LocalContentColor provides tint) {
35-
// Icon(
36-
// painter = painterResource(id = com.w2sv.core.navigator.R.drawable.ic_app_logo_24),
37-
// contentDescription = null
38-
// )
39-
// Text(
40-
// text = stringResource(id = R.string.auto),
41-
// fontSize = 12.sp,
42-
// lineHeight = 6.sp,
43-
// fontWeight = FontWeight.Medium
44-
// )
45-
// }
46-
// }
47-
// }
Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
package com.w2sv.filenavigator.ui.modelext
22

3+
import android.annotation.SuppressLint
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.ReadOnlyComposable
36
import androidx.compose.ui.graphics.Color
7+
import androidx.compose.ui.res.stringResource
8+
import com.w2sv.domain.model.CustomFileType
49
import com.w2sv.domain.model.FileType
10+
import com.w2sv.domain.model.PresetFileType
511

612
/**
7-
* Returns previously cached Color.
13+
* @return previously cached Color.
814
*/
915
val FileType.color: Color
10-
get() = fileTypeColors.getValue(this)
16+
get() = Color(colorInt) // TODO fileTypeColors.getValue(this)
1117

12-
private val fileTypeColors =
13-
FileType
14-
.values
15-
.associateWith { Color(it.colorInt) }
18+
//private val fileTypeColors =
19+
// PresetFileType
20+
// .values
21+
// .associateWith { Color(it.colorInt) }
22+
23+
@SuppressLint("ComposeUnstableReceiver")
24+
@Composable
25+
@ReadOnlyComposable
26+
fun FileType.stringResource(): String =
27+
when (this) {
28+
is PresetFileType -> stringResource(labelRes)
29+
is CustomFileType -> name
30+
}

app/src/main/kotlin/com/w2sv/filenavigator/ui/modelext/MoveEntryExtensions.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ fun MovedFile.launchViewMovedFileActivity(context: Context): SnackbarVisuals? {
2828
localOrNull?.let {
2929
setDataAndType(
3030
it.mediaUri.uri,
31-
this@launchViewMovedFileActivity.type.simpleStorageMediaType.mimeType
31+
this@launchViewMovedFileActivity.fileType.mediaType.mimeType
3232
)
3333
}
3434
externalOrNull?.let {
3535
setDataAndType(
3636
documentUri.uri,
37-
this@launchViewMovedFileActivity.type.simpleStorageMediaType.mimeType
37+
this@launchViewMovedFileActivity.fileType.mediaType.mimeType
3838
)
3939
setPackage(it.moveDestination.providerPackageName)
4040
}

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/home/components/movehistory/MoveHistory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ private fun FileNameWithTypeAndSourceIcon(moveEntry: MovedFile, modifier: Modifi
170170
Icon(
171171
painter = painterResource(id = moveEntry.fileAndSourceType.iconRes),
172172
contentDescription = null,
173-
tint = moveEntry.type.color
173+
tint = moveEntry.fileType.color
174174
)
175175
}
176176
}

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/navigatorsettings/NavigatorSettingsScreen.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import com.w2sv.filenavigator.ui.util.Easing
6767
import com.w2sv.filenavigator.ui.util.activityViewModel
6868
import com.w2sv.filenavigator.ui.util.lifecycleAwareStateValue
6969
import com.w2sv.filenavigator.ui.viewmodel.NavigatorViewModel
70+
import kotlinx.collections.immutable.toImmutableSet
7071
import kotlinx.collections.immutable.toPersistentList
7172
import kotlinx.coroutines.CoroutineScope
7273
import kotlinx.coroutines.flow.filter
@@ -108,7 +109,7 @@ fun NavigatorSettingsScreen(
108109
mutableStateOf(false)
109110
}
110111
var showFileTypeCreationDialog by rememberSaveable {
111-
mutableStateOf(true)
112+
mutableStateOf(false)
112113
}
113114

114115
Scaffold(
@@ -178,12 +179,15 @@ fun NavigatorSettingsScreen(
178179
}
179180
},
180181
onDismissRequest = remember { { showAddFileTypesBottomSheet = false } },
181-
onCreateFileTypeCardClick = remember { { showFileTypeCreationDialog = true } }
182+
onCreateFileTypeCardClick = remember { { showFileTypeCreationDialog = true } },
183+
selectFileType = navigatorVM.reversibleConfig.selectFileType
182184
)
183185
}
184186
if (showFileTypeCreationDialog) {
185187
FileTypeCreationDialog(
186-
onDismissRequest = { showFileTypeCreationDialog = false }
188+
fileTypes = navigatorConfig.fileTypes.toImmutableSet(),
189+
onDismissRequest = { showFileTypeCreationDialog = false },
190+
onCreateFileType = navigatorVM.reversibleConfig::createCustomFileType
187191
)
188192
}
189193
}

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/navigatorsettings/components/AddFileTypesBottomSheet.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,19 @@ import androidx.compose.ui.text.style.TextAlign
4545
import androidx.compose.ui.tooling.preview.Preview
4646
import androidx.compose.ui.unit.dp
4747
import androidx.compose.ui.unit.sp
48+
import com.w2sv.composed.CollectFromFlow
4849
import com.w2sv.composed.extensions.thenIf
4950
import com.w2sv.composed.extensions.toMutableStateMap
5051
import com.w2sv.domain.model.FileType
5152
import com.w2sv.filenavigator.R
5253
import com.w2sv.filenavigator.ui.designsystem.DialogButton
5354
import com.w2sv.filenavigator.ui.designsystem.FileTypeIcon
55+
import com.w2sv.filenavigator.ui.modelext.stringResource
5456
import com.w2sv.filenavigator.ui.theme.AppTheme
5557
import com.w2sv.kotlinutils.toggle
5658
import kotlinx.collections.immutable.ImmutableList
5759
import kotlinx.coroutines.CoroutineScope
60+
import kotlinx.coroutines.flow.Flow
5861
import kotlinx.coroutines.launch
5962

6063
@OptIn(ExperimentalLayoutApi::class)
@@ -64,6 +67,7 @@ fun AddFileTypesBottomSheet(
6467
addFileTypes: (List<FileType>) -> Unit,
6568
onDismissRequest: () -> Unit,
6669
onCreateFileTypeCardClick: () -> Unit,
70+
selectFileType: Flow<FileType>,
6771
modifier: Modifier = Modifier,
6872
sheetState: SheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
6973
scope: CoroutineScope = rememberCoroutineScope()
@@ -76,6 +80,10 @@ fun AddFileTypesBottomSheet(
7680
)
7781
}
7882

83+
CollectFromFlow(selectFileType) { fileType ->
84+
selectionMap[fileType] = true
85+
}
86+
7987
ModalBottomSheet(
8088
onDismissRequest = onDismissRequest,
8189
sheetState = sheetState,
@@ -163,7 +171,7 @@ private fun FileTypeCard(
163171
GridCard(isSelected = isSelected, onClick = onClick, modifier = modifier) {
164172
FileTypeIcon(fileType, modifier = Modifier.size(46.dp))
165173
Spacer(modifier = Modifier.height(6.dp))
166-
Text(text = stringResource(id = fileType.labelRes))
174+
Text(text = fileType.stringResource())
167175
}
168176
}
169177

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/navigatorsettings/components/ConfigurationColumn.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.net.Uri
55
import androidx.activity.compose.ManagedActivityResultLauncher
66
import androidx.activity.compose.rememberLauncherForActivityResult
77
import androidx.activity.result.contract.ActivityResultContracts
8-
import androidx.compose.animation.AnimatedVisibility
98
import androidx.compose.foundation.layout.Arrangement
109
import androidx.compose.foundation.layout.Column
1110
import androidx.compose.foundation.layout.Row

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/navigatorsettings/components/FileTypeCreationDialog.kt

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ import androidx.compose.ui.Modifier
4141
import androidx.compose.ui.input.pointer.pointerInput
4242
import androidx.compose.ui.tooling.preview.Preview
4343
import androidx.compose.ui.unit.dp
44+
import com.w2sv.domain.model.CustomFileType
45+
import com.w2sv.domain.model.FileType
4446
import com.w2sv.filenavigator.ui.designsystem.DialogButton
4547
import com.w2sv.filenavigator.ui.theme.AppColor
4648
import com.w2sv.filenavigator.ui.theme.AppTheme
4749
import com.w2sv.filenavigator.ui.util.ClearFocusOnFlowEmissionOrKeyboardHidden
4850
import com.w2sv.kotlinutils.coroutines.flow.emit
51+
import kotlinx.collections.immutable.ImmutableSet
4952
import kotlinx.coroutines.CoroutineScope
5053
import kotlinx.coroutines.flow.MutableSharedFlow
5154
import kotlinx.coroutines.flow.asSharedFlow
@@ -57,7 +60,7 @@ private enum class FileExtensionInvalidityReason(val errorMessage: String) {
5760
}
5861

5962
@Stable
60-
private class CustomFileType(private val scope: CoroutineScope) {
63+
private class EditedCustomFileType(private val scope: CoroutineScope, private val usedFileTypes: Collection<FileType>) {
6164
var name by mutableStateOf("")
6265
private set
6366

@@ -100,48 +103,70 @@ private class CustomFileType(private val scope: CoroutineScope) {
100103
fun clearFocus() {
101104
_clearFocus.emit(Unit, scope)
102105
}
106+
107+
fun toCustomFileType(): CustomFileType =
108+
CustomFileType(name, extensions, usedFileTypes.map { it.ordinal }.max() + 1) // TODO
103109
}
104110

105111
@Composable
106-
fun FileTypeCreationDialog(onDismissRequest: () -> Unit, modifier: Modifier = Modifier) {
112+
fun FileTypeCreationDialog(
113+
fileTypes: ImmutableSet<FileType>,
114+
onDismissRequest: () -> Unit,
115+
onCreateFileType: (CustomFileType) -> Unit,
116+
modifier: Modifier = Modifier
117+
) {
107118
val scope = rememberCoroutineScope()
108-
val customFileType = remember { CustomFileType(scope) } // TODO: rememberSavable
119+
val editedCustomFileType = remember(fileTypes) { EditedCustomFileType(scope, fileTypes) } // TODO: rememberSavable
109120

110-
StatelessFileTypeCreationDialog(customFileType, onDismissRequest, modifier)
121+
StatelessFileTypeCreationDialog(editedCustomFileType, onDismissRequest, onCreateFileType, modifier)
111122
}
112123

113124
@OptIn(ExperimentalLayoutApi::class)
114125
@Composable
115-
private fun StatelessFileTypeCreationDialog(customFileType: CustomFileType, onDismissRequest: () -> Unit, modifier: Modifier = Modifier) {
126+
private fun StatelessFileTypeCreationDialog(
127+
editedCustomFileType: EditedCustomFileType,
128+
onDismissRequest: () -> Unit,
129+
createFileType: (CustomFileType) -> Unit,
130+
modifier: Modifier = Modifier
131+
) {
116132
AlertDialog(
117-
modifier = modifier.pointerInput(Unit) { detectTapGestures { customFileType.clearFocus() } },
133+
modifier = modifier.pointerInput(Unit) { detectTapGestures { editedCustomFileType.clearFocus() } },
118134
title = { Text("Create a file type") },
119135
onDismissRequest = onDismissRequest,
120136
text = {
121-
ClearFocusOnFlowEmissionOrKeyboardHidden(customFileType.clearFocus)
137+
ClearFocusOnFlowEmissionOrKeyboardHidden(editedCustomFileType.clearFocus)
122138

123139
Column {
124140
Spacer(Modifier.height(24.dp))
125141
OutlinedTextField(
126-
value = customFileType.name,
127-
onValueChange = customFileType::updateName,
142+
value = editedCustomFileType.name,
143+
onValueChange = editedCustomFileType::updateName,
128144
placeholder = { Text("Enter name") },
129145
singleLine = true
130146
)
131147
FileExtensionTextField(
132-
customFileType = customFileType,
148+
editedCustomFileType = editedCustomFileType,
133149
modifier = Modifier
134150
.width(192.dp)
135151
.padding(vertical = 16.dp)
136152
)
137153
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
138-
customFileType.extensions.forEachIndexed { i, extension ->
139-
FileExtensionBadgeWithTooltip(extension = extension, deleteExtension = { customFileType.deleteExtension(i) })
154+
editedCustomFileType.extensions.forEachIndexed { i, extension ->
155+
FileExtensionBadgeWithTooltip(extension = extension, deleteExtension = { editedCustomFileType.deleteExtension(i) })
140156
}
141157
}
142158
}
143159
},
144-
confirmButton = { DialogButton("Create", onClick = {}, enabled = customFileType.canBeCreated) },
160+
confirmButton = {
161+
DialogButton(
162+
text = "Create",
163+
onClick = {
164+
createFileType(editedCustomFileType.toCustomFileType())
165+
onDismissRequest()
166+
},
167+
enabled = editedCustomFileType.canBeCreated
168+
)
169+
},
145170
)
146171
}
147172

@@ -199,24 +224,24 @@ private fun FileExtensionBadge(extension: String, modifier: Modifier = Modifier)
199224
}
200225

201226
@Composable
202-
private fun FileExtensionTextField(customFileType: CustomFileType, modifier: Modifier = Modifier) {
227+
private fun FileExtensionTextField(editedCustomFileType: EditedCustomFileType, modifier: Modifier = Modifier) {
203228
OutlinedTextField(
204-
value = customFileType.newFileExtension,
205-
onValueChange = customFileType::updateNewFileExtension,
229+
value = editedCustomFileType.newFileExtension,
230+
onValueChange = editedCustomFileType::updateNewFileExtension,
206231
textStyle = MaterialTheme.typography.bodyLarge,
207232
placeholder = { Text("Enter file extension", maxLines = 1) },
208233
singleLine = true,
209234
modifier = modifier,
210235
trailingIcon = when {
211-
customFileType.newFileExtensionCanBeAdded -> {
236+
editedCustomFileType.newFileExtensionCanBeAdded -> {
212237
{
213-
FilledTonalIconButton(onClick = customFileType::addNewFileExtension) {
238+
FilledTonalIconButton(onClick = editedCustomFileType::addNewFileExtension) {
214239
Icon(Icons.Default.Add, contentDescription = null, tint = AppColor.success)
215240
}
216241
}
217242
}
218243

219-
customFileType.newFileExtensionInvalidityReason != null -> {
244+
editedCustomFileType.newFileExtensionInvalidityReason != null -> {
220245
{
221246
Icon(Icons.Outlined.Warning, contentDescription = null, tint = MaterialTheme.colorScheme.error)
222247
}
@@ -226,8 +251,8 @@ private fun FileExtensionTextField(customFileType: CustomFileType, modifier: Mod
226251
null
227252
}
228253
},
229-
isError = customFileType.newFileExtensionInvalidityReason != null,
230-
supportingText = customFileType.newFileExtensionInvalidityReason?.let { invalidityReason ->
254+
isError = editedCustomFileType.newFileExtensionInvalidityReason != null,
255+
supportingText = editedCustomFileType.newFileExtensionInvalidityReason?.let { invalidityReason ->
231256
{
232257
Text(
233258
text = invalidityReason.errorMessage,
@@ -243,12 +268,13 @@ private fun FileExtensionTextField(customFileType: CustomFileType, modifier: Mod
243268
private fun StatelessFileTypeCreationDialogPrev() {
244269
AppTheme {
245270
StatelessFileTypeCreationDialog(
246-
customFileType = CustomFileType(rememberCoroutineScope())
271+
editedCustomFileType = EditedCustomFileType(rememberCoroutineScope(), emptyList())
247272
.apply {
248273
extensions.addAll(listOf("jpg", "png", "jpgasdf"))
249274
updateNewFileExtension("dot")
250275
},
251-
onDismissRequest = {}
276+
onDismissRequest = {},
277+
createFileType = {}
252278
)
253279
}
254280
}

app/src/main/kotlin/com/w2sv/filenavigator/ui/screen/navigatorsettings/components/filetypeselection/FileTypeAccordion.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import com.w2sv.domain.model.navigatorconfig.SourceConfig
3737
import com.w2sv.filenavigator.R
3838
import com.w2sv.filenavigator.ui.designsystem.FileTypeIcon
3939
import com.w2sv.filenavigator.ui.modelext.color
40+
import com.w2sv.filenavigator.ui.modelext.stringResource
4041
import com.w2sv.filenavigator.ui.screen.navigatorsettings.components.SubDirectoryIcon
4142
import com.w2sv.filenavigator.ui.screen.navigatorsettings.components.rememberSelectAutoMoveDestination
4243
import kotlinx.collections.immutable.ImmutableMap
@@ -115,7 +116,7 @@ private fun FileTypeRow(
115116
.size(34.dp)
116117
)
117118
Text(
118-
text = stringResource(id = fileType.labelRes),
119+
text = fileType.stringResource(),
119120
fontSize = 18.sp
120121
)
121122
Spacer(modifier = Modifier.weight(1f))

0 commit comments

Comments
 (0)