Skip to content

Commit b4a373f

Browse files
leandroBorgesFerreiraLeandro Ferreira
andauthored
Adding folder to mobile (#522)
* Adding folder to mobile * Navigating to folders * ktlint * Update NotesMenuScreen.native.kt --------- Co-authored-by: Leandro Ferreira <[email protected]>
1 parent 943a4e5 commit b4a373f

10 files changed

Lines changed: 137 additions & 25 deletions

File tree

application/core/common_ui/src/commonMain/kotlin/io/writeopia/commonui/buttons/CommonButton.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.writeopia.commonui.buttons
22

33
import androidx.compose.foundation.background
44
import androidx.compose.foundation.clickable
5+
import androidx.compose.foundation.layout.Arrangement
56
import androidx.compose.foundation.layout.Row
67
import androidx.compose.foundation.layout.Spacer
78
import androidx.compose.foundation.layout.fillMaxWidth
@@ -15,6 +16,7 @@ import androidx.compose.runtime.Composable
1516
import androidx.compose.runtime.collectAsState
1617
import androidx.compose.runtime.getValue
1718
import androidx.compose.ui.Alignment
19+
import androidx.compose.ui.Alignment.Companion
1820
import androidx.compose.ui.Modifier
1921
import androidx.compose.ui.draw.clip
2022
import androidx.compose.ui.graphics.Color
@@ -58,6 +60,8 @@ fun CommonButton(
5860
defaultColor: Color = WriteopiaTheme.colorScheme.defaultButton,
5961
selectedColor: Color = WriteopiaTheme.colorScheme.highlight,
6062
isEnabledState: StateFlow<Boolean> = MutableStateFlow(true),
63+
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
64+
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
6165
clickListener: () -> Unit,
6266
) {
6367
val isEditable by isEnabledState.collectAsState()
@@ -66,7 +70,8 @@ fun CommonButton(
6670
val shape = MaterialTheme.shapes.medium
6771

6872
Row(
69-
verticalAlignment = Alignment.CenterVertically,
73+
verticalAlignment = verticalAlignment,
74+
horizontalArrangement = horizontalArrangement,
7075
modifier = modifier
7176
.background(lockButtonColor, shape)
7277
.clip(shape)

application/features/note_menu/src/androidMain/kotlin/io/writeopia/notemenu/ui/screen/menu/ChooseNoteScreen.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
88
import androidx.compose.runtime.collectAsState
99
import androidx.compose.runtime.getValue
1010
import androidx.compose.ui.Modifier
11+
import io.writeopia.common.utils.NotesNavigation
1112
import io.writeopia.notemenu.viewmodel.ChooseNoteViewModel
1213

1314
@OptIn(ExperimentalSharedTransitionApi::class)
@@ -19,6 +20,7 @@ internal fun ChooseNoteScreen(
1920
navigateToNote: (String, String) -> Unit,
2021
newNote: () -> Unit,
2122
navigateToAccount: () -> Unit,
23+
navigateToNotes: (NotesNavigation) -> Unit,
2224
modifier: Modifier = Modifier,
2325
) {
2426
val hasSelectedNotes by chooseNoteViewModel.hasSelectedNotes.collectAsState()
@@ -40,9 +42,10 @@ internal fun ChooseNoteScreen(
4042
chooseNoteViewModel,
4143
sharedTransitionScope = sharedTransitionScope,
4244
animatedVisibilityScope = animatedVisibilityScope,
43-
navigateToNote,
44-
newNote,
45-
navigateToAccount,
46-
modifier
45+
navigateToNote = navigateToNote,
46+
newNote = newNote,
47+
navigateToAccount = navigateToAccount,
48+
navigateToNotes = navigateToNotes,
49+
modifier = modifier,
4750
)
4851
}

application/features/note_menu/src/androidMain/kotlin/io/writeopia/notemenu/ui/screen/menu/NotesMenuScreen.android.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ actual fun NotesMenuScreen(
3838
navigateToNote = onNoteClick,
3939
newNote = onNewNoteClick,
4040
navigateToAccount = onAccountClick,
41+
navigateToNotes = navigateToFolders,
4142
modifier = modifier,
4243
)
4344
}

application/features/note_menu/src/commonMain/kotlin/io/writeopia/notemenu/ui/screen/DesktopNotesMenu.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import io.writeopia.notemenu.ui.screen.configuration.molecules.NotesSelectionMen
3838
import io.writeopia.commonui.workplace.WorkspaceConfigurationDialog
3939
import io.writeopia.controller.OllamaConfigController
4040
import io.writeopia.commonui.dialogs.confirmation.DeleteConfirmationDialog
41-
import io.writeopia.notemenu.ui.screen.documents.NotesCards
41+
import io.writeopia.notemenu.ui.screen.documents.NotesCardsScreen
4242
import io.writeopia.notemenu.ui.screen.file.fileChooserLoad
4343
import io.writeopia.notemenu.viewmodel.ChooseNoteViewModel
4444
import io.writeopia.notemenu.viewmodel.ConfigState
@@ -86,8 +86,9 @@ fun DesktopNotesMenu(
8686
verticalAlignment = Alignment.CenterVertically,
8787
modifier = Modifier.padding(start = 40.dp)
8888
) {
89-
NotesCards(
89+
NotesCardsScreen(
9090
documents = chooseNoteViewModel.documentsState.collectAsState().value,
91+
showAddMenuState = chooseNoteViewModel.showAddMenuState,
9192
loadNote = { id, title ->
9293
val handled = chooseNoteViewModel.handleMenuItemTap(id)
9394
if (!handled) {
@@ -101,16 +102,16 @@ fun DesktopNotesMenu(
101102
navigateToNotes(NotesNavigation.Folder(id))
102103
}
103104
},
104-
moveRequest = { item, parentId ->
105-
chooseNoteViewModel.moveToFolder(item, parentId)
106-
},
105+
moveRequest = chooseNoteViewModel::moveToFolder,
107106
modifier = Modifier.weight(1F).fillMaxHeight()
108107
.padding(end = 10.dp, top = 20.dp),
109108
changeIcon = chooseNoteViewModel::changeIcons,
110109
onSelection = chooseNoteViewModel::toggleSelection,
111110
sharedTransitionScope = sharedTransitionScope,
112111
animatedVisibilityScope = animatedVisibilityScope,
113-
newNote = onNewNoteClick
112+
newNote = onNewNoteClick,
113+
newFolder = chooseNoteViewModel::newFolder,
114+
hideShowMenu = chooseNoteViewModel::hideAddMenu,
114115
)
115116

116117
Spacer(modifier = Modifier.width(20.dp))
@@ -159,7 +160,7 @@ fun DesktopNotesMenu(
159160
.padding(horizontal = 40.dp - borderPadding, vertical = 40.dp)
160161
.testTag("addNote"),
161162
onClick = {
162-
chooseNoteViewModel.requestInitFlow(onNewNoteClick)
163+
chooseNoteViewModel.requestInitFlow(chooseNoteViewModel::showAddMenu)
163164
},
164165
content = {
165166
Icon(

application/features/note_menu/src/commonMain/kotlin/io/writeopia/notemenu/ui/screen/documents/NoteItems.kt renamed to application/features/note_menu/src/commonMain/kotlin/io/writeopia/notemenu/ui/screen/documents/NotesCardsScreen.kt

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
2828
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
2929
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
3030
import androidx.compose.foundation.lazy.staggeredgrid.itemsIndexed
31+
import androidx.compose.material3.Card
3132
import androidx.compose.material3.CircularProgressIndicator
3233
import androidx.compose.material3.DropdownMenu
3334
import androidx.compose.material3.Icon
3435
import androidx.compose.material3.MaterialTheme
3536
import androidx.compose.material3.Text
3637
import androidx.compose.runtime.Composable
3738
import androidx.compose.runtime.LaunchedEffect
39+
import androidx.compose.runtime.collectAsState
3840
import androidx.compose.runtime.getValue
3941
import androidx.compose.runtime.mutableStateOf
4042
import androidx.compose.runtime.remember
@@ -53,10 +55,12 @@ import androidx.compose.ui.text.style.TextOverflow
5355
import androidx.compose.ui.unit.Dp
5456
import androidx.compose.ui.unit.dp
5557
import androidx.compose.ui.unit.sp
58+
import androidx.compose.ui.window.Dialog
5659
import io.writeopia.common.utils.icons.IconChange
5760
import io.writeopia.common.utils.icons.WrIcons
5861
import io.writeopia.common.utils.icons.WrIcons.folder
5962
import io.writeopia.commonui.IconsPicker
63+
import io.writeopia.commonui.buttons.CommonButton
6064
import io.writeopia.commonui.dtos.MenuItemUi
6165
import io.writeopia.core.configuration.models.NotesArrangement
6266
import io.writeopia.notemenu.ui.dto.NotesUi
@@ -79,15 +83,17 @@ import io.writeopia.ui.drawer.preview.ImagePreviewDrawer
7983
import io.writeopia.ui.drawer.preview.TextPreviewDrawer
8084
import io.writeopia.ui.drawer.preview.UnOrderedListItemPreviewDrawer
8185
import io.writeopia.ui.model.DrawInfo
86+
import kotlinx.coroutines.flow.StateFlow
8287
import org.jetbrains.compose.ui.tooling.preview.Preview
8388

8489
const val DOCUMENT_ITEM_TEST_TAG = "DocumentItem_"
8590
const val ADD_NOTE_TEST_TAG = "addNote"
8691

8792
@OptIn(ExperimentalSharedTransitionApi::class)
8893
@Composable
89-
fun NotesCards(
94+
fun NotesCardsScreen(
9095
documents: ResultData<NotesUi>,
96+
showAddMenuState: StateFlow<Boolean>,
9197
sharedTransitionScope: SharedTransitionScope,
9298
animatedVisibilityScope: AnimatedVisibilityScope,
9399
minimalNoteWidth: Dp = minimalNoteCardWidth(),
@@ -98,6 +104,8 @@ fun NotesCards(
98104
changeIcon: (String, String, Int, IconChange) -> Unit,
99105
onSelection: (String) -> Unit,
100106
newNote: () -> Unit,
107+
newFolder: () -> Unit,
108+
hideShowMenu: () -> Unit,
101109
modifier: Modifier = Modifier,
102110
) {
103111
when (documents) {
@@ -191,6 +199,58 @@ fun NotesCards(
191199
}
192200
}
193201
}
202+
203+
val showAddMenu by showAddMenuState.collectAsState()
204+
205+
if (showAddMenu) {
206+
Dialog(onDismissRequest = hideShowMenu) {
207+
Card(modifier = Modifier.width(320.dp), shape = MaterialTheme.shapes.large) {
208+
Column(
209+
modifier = Modifier.padding(
210+
start = 20.dp,
211+
end = 20.dp,
212+
bottom = 20.dp,
213+
top = 20.dp
214+
),
215+
horizontalAlignment = Alignment.CenterHorizontally
216+
) {
217+
val modifier = Modifier.height(50.dp).width(280.dp)
218+
219+
Text(
220+
"Add",
221+
style = MaterialTheme.typography.titleLarge,
222+
modifier = Modifier.fillMaxWidth()
223+
)
224+
225+
Spacer(modifier = Modifier.height(20.dp))
226+
227+
CommonButton(
228+
modifier = modifier,
229+
text = "Document",
230+
verticalAlignment = Alignment.CenterVertically,
231+
horizontalArrangement = Arrangement.Center,
232+
clickListener = {
233+
hideShowMenu()
234+
newNote()
235+
}
236+
)
237+
238+
Spacer(modifier = Modifier.height(10.dp))
239+
240+
CommonButton(
241+
modifier = modifier,
242+
text = "Folder",
243+
verticalAlignment = Alignment.CenterVertically,
244+
horizontalArrangement = Arrangement.Center,
245+
clickListener = {
246+
hideShowMenu()
247+
newFolder()
248+
}
249+
)
250+
}
251+
}
252+
}
253+
}
194254
}
195255

196256
@OptIn(ExperimentalSharedTransitionApi::class)

application/features/note_menu/src/commonMain/kotlin/io/writeopia/notemenu/ui/screen/menu/MobileChooseNoteScreen.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
3333
import androidx.compose.ui.semantics.semantics
3434
import androidx.compose.ui.semantics.testTag
3535
import androidx.compose.ui.unit.dp
36+
import io.writeopia.common.utils.NotesNavigation
3637
import io.writeopia.common.utils.icons.WrIcons
3738
import io.writeopia.notemenu.ui.screen.configuration.molecules.MobileConfigurationsMenu
3839
import io.writeopia.notemenu.ui.screen.configuration.molecules.NotesSelectionMenu
3940
import io.writeopia.commonui.dialogs.confirmation.DeleteConfirmationDialog
4041
import io.writeopia.notemenu.ui.screen.documents.ADD_NOTE_TEST_TAG
41-
import io.writeopia.notemenu.ui.screen.documents.NotesCards
42+
import io.writeopia.notemenu.ui.screen.documents.NotesCardsScreen
4243
import io.writeopia.notemenu.viewmodel.ChooseNoteViewModel
4344
import io.writeopia.notemenu.viewmodel.UserState
4445
import io.writeopia.notemenu.viewmodel.toNumberDesktop
@@ -55,6 +56,7 @@ internal fun MobileChooseNoteScreen(
5556
navigateToNote: (String, String) -> Unit,
5657
newNote: () -> Unit,
5758
navigateToAccount: () -> Unit,
59+
navigateToNotes: (NotesNavigation) -> Unit,
5860
modifier: Modifier = Modifier,
5961
) {
6062
LaunchedEffect(key1 = "refresh", block = {
@@ -76,7 +78,7 @@ internal fun MobileChooseNoteScreen(
7678
)
7779
},
7880
floatingActionButton = {
79-
FloatingActionButton(newNoteClick = newNote)
81+
FloatingActionButton(onClick = chooseNoteViewModel::showAddMenu)
8082
}
8183
) { paddingValues ->
8284
DraggableScreen {
@@ -87,7 +89,8 @@ internal fun MobileChooseNoteScreen(
8789
loadNote = navigateToNote,
8890
selectionListener = chooseNoteViewModel::onDocumentSelected,
8991
paddingValues = paddingValues,
90-
newNote = newNote
92+
newNote = newNote,
93+
navigateToNotes = navigateToNotes,
9194
)
9295
}
9396
}
@@ -220,13 +223,15 @@ private fun getUserName(userNameState: UserState<String>): String =
220223
}
221224

222225
@Composable
223-
private fun FloatingActionButton(newNoteClick: () -> Unit) {
226+
private fun FloatingActionButton(
227+
onClick: () -> Unit
228+
) {
224229
FloatingActionButton(
225230
modifier = Modifier.semantics {
226231
testTag = ADD_NOTE_TEST_TAG
227232
},
228233
containerColor = MaterialTheme.colorScheme.primary,
229-
onClick = newNoteClick,
234+
onClick = onClick,
230235
content = {
231236
Icon(
232237
imageVector = WrIcons.add,
@@ -246,19 +251,28 @@ private fun Content(
246251
loadNote: (String, String) -> Unit,
247252
selectionListener: (String, Boolean) -> Unit,
248253
newNote: () -> Unit,
254+
navigateToNotes: (NotesNavigation) -> Unit,
249255
paddingValues: PaddingValues,
250256
) {
251-
NotesCards(
257+
NotesCardsScreen(
252258
documents = chooseNoteViewModel.documentsState.collectAsState().value,
259+
showAddMenuState = chooseNoteViewModel.showAddMenuState,
253260
animatedVisibilityScope = animatedVisibilityScope,
254261
sharedTransitionScope = sharedTransitionScope,
255262
loadNote = loadNote,
256263
selectionListener = selectionListener,
257-
folderClick = {},
264+
hideShowMenu = chooseNoteViewModel::hideAddMenu,
265+
folderClick = { id ->
266+
val handled = chooseNoteViewModel.handleMenuItemTap(id)
267+
if (!handled) {
268+
navigateToNotes(NotesNavigation.Folder(id))
269+
}
270+
},
258271
changeIcon = { _, _, _, _ -> },
259-
moveRequest = { _, _ -> },
272+
moveRequest = chooseNoteViewModel::moveToFolder,
260273
onSelection = {},
261274
newNote = newNote,
275+
newFolder = chooseNoteViewModel::newFolder,
262276
modifier = Modifier
263277
.padding(paddingValues)
264278
.fillMaxSize()

application/features/note_menu/src/commonMain/kotlin/io/writeopia/notemenu/viewmodel/ChooseNoteKmpViewModel.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ internal class ChooseNoteKmpViewModel(
204204
}.stateIn(viewModelScope, SharingStarted.Lazily, ResultData.Idle())
205205
}
206206

207+
private val _showAddMenuState = MutableStateFlow(false)
208+
override val showAddMenuState: StateFlow<Boolean> = _showAddMenuState
209+
207210
init {
208211
folderController.initCoroutine(viewModelScope)
209212

@@ -250,15 +253,14 @@ internal class ChooseNoteKmpViewModel(
250253
}
251254
}
252255

253-
override fun handleMenuItemTap(id: String): Boolean {
254-
return if (selectionState.value) {
256+
override fun handleMenuItemTap(id: String): Boolean =
257+
if (selectionState.value) {
255258
toggleSelection(id)
256259

257260
true
258261
} else {
259262
false
260263
}
261-
}
262264

263265
override fun showEditMenu() {
264266
_editState.value = true
@@ -463,6 +465,12 @@ internal class ChooseNoteKmpViewModel(
463465
}
464466
}
465467

468+
override fun newFolder() {
469+
viewModelScope.launch(Dispatchers.Default) {
470+
folderController.addFolder()
471+
}
472+
}
473+
466474
private suspend fun importJsonNotes(externalFiles: List<ExternalFile>, now: Instant) {
467475
externalFiles.filter { file -> file.extension == "json" }
468476
.map { file -> file.fullPath }
@@ -486,6 +494,14 @@ internal class ChooseNoteKmpViewModel(
486494
.collect(notesUseCase::saveDocumentDb)
487495
}
488496

497+
override fun showAddMenu() {
498+
_showAddMenuState.value = true
499+
}
500+
501+
override fun hideAddMenu() {
502+
_showAddMenuState.value = false
503+
}
504+
489505
private suspend fun importMarkdownNotes(externalFiles: List<ExternalFile>, now: Instant) {
490506
externalFiles.filter { file -> file.extension == "md" }
491507
.map { file -> file.fullPath }

0 commit comments

Comments
 (0)