From 4e7f2b4a68df7ebc9c5bae5998e2fe4eaf53b23e Mon Sep 17 00:00:00 2001 From: aro Date: Sun, 27 Nov 2022 21:27:36 +0100 Subject: [PATCH] feat: snackbars + made it prettier --- .../wrench/components/WatcherDisplay.kt | 7 +-- .../wrench/components/WrenchScaffold.kt | 6 ++- .../wrench/components/bottom/BottomBar.kt | 4 +- .../components/bottom/WatcherStatusButton.kt | 49 ++++++++++++++++-- .../wrench/components/center/FilePicker.kt | 7 ++- .../wrench/compose/SnackBarDataHolder.kt | 6 ++- .../xyz/atnrch/wrench/watcher/Watcher.kt | 51 ++++++++++++++++--- 7 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/xyz/atnrch/wrench/components/WatcherDisplay.kt b/src/main/kotlin/xyz/atnrch/wrench/components/WatcherDisplay.kt index 4574617..6632173 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/components/WatcherDisplay.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/components/WatcherDisplay.kt @@ -11,17 +11,14 @@ import androidx.compose.ui.Modifier import xyz.atnrch.wrench.components.center.input.InputEntries import xyz.atnrch.wrench.components.center.output.OutputEntries import xyz.atnrch.wrench.watcher.WatcherManager -import java.io.File @Composable -fun WatcherDisplay( - watcherManager: WatcherManager -) { +fun WatcherDisplay(watcherManager: WatcherManager) { var currentClick by remember { mutableStateOf(-1) } Row { if (watcherManager.getEntries().isEmpty()) { - watcherManager.addFile(File("/home/aro/IdeaProjects/Wrench/dummy")) + //watcherManager.addFile(File("/home/aro/IdeaProjects/Wrench/dummy")) Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth().fillMaxHeight() diff --git a/src/main/kotlin/xyz/atnrch/wrench/components/WrenchScaffold.kt b/src/main/kotlin/xyz/atnrch/wrench/components/WrenchScaffold.kt index ec7b148..947f0ac 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/components/WrenchScaffold.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/components/WrenchScaffold.kt @@ -6,6 +6,7 @@ import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.* import xyz.atnrch.wrench.components.center.AddButton import xyz.atnrch.wrench.components.top.TopBar +import xyz.atnrch.wrench.compose.SnackBarDataHolder import xyz.atnrch.wrench.watcher.Watcher import xyz.atnrch.wrench.watcher.WatcherEntry import xyz.atnrch.wrench.watcher.WatcherManager @@ -14,8 +15,9 @@ import xyz.atnrch.wrench.watcher.WatcherManager fun WrenchScaffold() { val scaffoldState: ScaffoldState = rememberScaffoldState() val entries: MutableMap = remember { mutableStateMapOf() } + val snackBarDataHolder = SnackBarDataHolder(scaffoldState, rememberCoroutineScope()) val watcherManager = remember { WatcherManager(entries) } - val watcher = remember { Watcher(watcherManager) } + val watcher = remember { Watcher(watcherManager, snackBarDataHolder) } var watcherState by remember { mutableStateOf(false) } Scaffold( @@ -23,7 +25,7 @@ fun WrenchScaffold() { topBar = { TopBar() }, floatingActionButton = { AddButton(watcherManager) }, isFloatingActionButtonDocked = true, - bottomBar = { BottomAppBar(watcher, watcherState) { watcherState = it } } + bottomBar = { BottomAppBar(watcher, watcherState, snackBarDataHolder) { watcherState = it } } ) { WatcherDisplay(watcherManager) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/atnrch/wrench/components/bottom/BottomBar.kt b/src/main/kotlin/xyz/atnrch/wrench/components/bottom/BottomBar.kt index dd72f4e..32a95b4 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/components/bottom/BottomBar.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/components/bottom/BottomBar.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.unit.dp +import xyz.atnrch.wrench.compose.SnackBarDataHolder import xyz.atnrch.wrench.ui.UIColors import xyz.atnrch.wrench.watcher.Watcher @@ -13,6 +14,7 @@ import xyz.atnrch.wrench.watcher.Watcher fun BottomAppBar( watcher: Watcher, state: Boolean, + snackBarDataHolder: SnackBarDataHolder, onStateChange: (state: Boolean) -> Unit ) { androidx.compose.material.BottomAppBar( @@ -21,5 +23,5 @@ fun BottomAppBar( ), backgroundColor = UIColors.PRIMARY, modifier = Modifier.shadow(20.dp, MaterialTheme.shapes.small, true) - ) { BottomRow(watcher, state, onStateChange) } + ) { BottomRow(watcher, state, onStateChange, snackBarDataHolder) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/atnrch/wrench/components/bottom/WatcherStatusButton.kt b/src/main/kotlin/xyz/atnrch/wrench/components/bottom/WatcherStatusButton.kt index aaca62a..c869ce9 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/components/bottom/WatcherStatusButton.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/components/bottom/WatcherStatusButton.kt @@ -1,5 +1,7 @@ package xyz.atnrch.wrench.components +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -7,15 +9,16 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults import androidx.compose.material.Icon +import androidx.compose.material.Text import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.Update import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import xyz.atnrch.wrench.compose.SnackBarDataHolder import xyz.atnrch.wrench.ui.UIColors import xyz.atnrch.wrench.watcher.Watcher @@ -23,21 +26,36 @@ import xyz.atnrch.wrench.watcher.Watcher fun BottomRow( watcher: Watcher, state: Boolean, - onStateChange: (state: Boolean) -> Unit + onStateChange: (state: Boolean) -> Unit, + snackBarDataHolder: SnackBarDataHolder ) { val buttonColors = remember { arrayOf(UIColors.WATCHER_START_BG) } Spacer(Modifier.width(5.dp)) - Button( + /*Button( { if (state) { buttonColors[0] = UIColors.WATCHER_START_BG run { watcher.stop() } onStateChange(false) + snackBarDataHolder.coroutineScope.launch { + snackBarDataHolder.scaffoldState.snackbarHostState.currentSnackbarData?.dismiss() + snackBarDataHolder.scaffoldState.snackbarHostState.showSnackbar( + message = "Stopped Watcher.", + duration = SnackbarDuration.Short, + ) + } } else { buttonColors[0] = UIColors.WATCHER_STOP_BG run { watcher.start() } onStateChange(true) + snackBarDataHolder.coroutineScope.launch { + snackBarDataHolder.scaffoldState.snackbarHostState.currentSnackbarData?.dismiss() + snackBarDataHolder.scaffoldState.snackbarHostState.showSnackbar( + message = "Started Watcher.", + duration = SnackbarDuration.Short + ) + } } }, colors = ButtonDefaults.buttonColors(buttonColors[0], Color.White), @@ -60,5 +78,28 @@ fun BottomRow( modifier = Modifier.size(28.dp) ) } + }*/ + Button( + onClick = { watcher.move() }, + colors = ButtonDefaults.buttonColors(UIColors.PRIMARY, Color.White), + contentPadding = PaddingValues( + start = 18.dp, + top = 6.dp, + end = 18.dp, + bottom = 6.dp + ), + shape = RoundedCornerShape(100), + border = BorderStroke(2.dp, UIColors.WATCHER_START_FG), + modifier = Modifier.shadow(24.dp, RoundedCornerShape(100), false) + ) { + Icon( + Icons.Filled.Update, + tint = UIColors.WATCHER_START_FG, + contentDescription = "Start", + modifier = Modifier.size(22.dp) + ) + Spacer(Modifier.size(ButtonDefaults.IconSpacing)) + Text("Move files") } + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/atnrch/wrench/components/center/FilePicker.kt b/src/main/kotlin/xyz/atnrch/wrench/components/center/FilePicker.kt index dc0486a..91d773f 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/components/center/FilePicker.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/components/center/FilePicker.kt @@ -1,6 +1,5 @@ package xyz.atnrch.wrench.components.center -import androidx.compose.ui.awt.ComposeWindow import java.io.File import javax.swing.JFileChooser @@ -14,7 +13,7 @@ fun showFilePicker( approveButtonText = "Confirm" approveButtonToolTipText = "Select source file" } - filePicker.showOpenDialog(ComposeWindow()) + filePicker.showOpenDialog(null) if (filePicker.selectedFile != null) onResult.invoke(filePicker.selectedFile) else onNoResult.invoke() } @@ -26,8 +25,8 @@ fun showDirectoryPicker( fileSelectionMode = JFileChooser.DIRECTORIES_ONLY dialogTitle = "Select a directory" approveButtonText = "Confirm" - approveButtonToolTipText = "Select source file" + approveButtonToolTipText = "Select output directory" } - filePicker.showOpenDialog(ComposeWindow()) + filePicker.showOpenDialog(null) if (filePicker.selectedFile != null) onResult.invoke(filePicker.selectedFile) else onNoResult.invoke() } \ No newline at end of file diff --git a/src/main/kotlin/xyz/atnrch/wrench/compose/SnackBarDataHolder.kt b/src/main/kotlin/xyz/atnrch/wrench/compose/SnackBarDataHolder.kt index e5aae3d..2adb626 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/compose/SnackBarDataHolder.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/compose/SnackBarDataHolder.kt @@ -1,4 +1,6 @@ package xyz.atnrch.wrench.compose -class SnackBarDataHolder { -} \ No newline at end of file +import androidx.compose.material.ScaffoldState +import kotlinx.coroutines.CoroutineScope + +data class SnackBarDataHolder(val scaffoldState: ScaffoldState, val coroutineScope: CoroutineScope) \ No newline at end of file diff --git a/src/main/kotlin/xyz/atnrch/wrench/watcher/Watcher.kt b/src/main/kotlin/xyz/atnrch/wrench/watcher/Watcher.kt index 455e4e2..5027f6b 100644 --- a/src/main/kotlin/xyz/atnrch/wrench/watcher/Watcher.kt +++ b/src/main/kotlin/xyz/atnrch/wrench/watcher/Watcher.kt @@ -1,11 +1,21 @@ package xyz.atnrch.wrench.watcher -import kotlinx.coroutines.* +import androidx.compose.material.SnackbarDuration +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import kotlinx.coroutines.swing.Swing +import xyz.atnrch.wrench.compose.SnackBarDataHolder import xyz.atnrch.wrench.logger.Logger -import java.util.concurrent.TimeUnit +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardCopyOption -class Watcher(private val watcherManager: WatcherManager) { +class Watcher( + private val watcherManager: WatcherManager, + private val snackBarDataHolder: SnackBarDataHolder +) { companion object { var WATCHING = false } @@ -19,13 +29,38 @@ class Watcher(private val watcherManager: WatcherManager) { WATCHING = true Logger.info("Started Watcher.") while (WATCHING) { - delay(TimeUnit.SECONDS.toMillis(5)) - for (entry: WatcherEntry in watcherManager.getEntries().values) { - entry.map.forEach { - //Files.copy(entry.file.toPath(), it.toAbsolutePath()) - } + move() + } + } + } + + fun move() { + snackBarDataHolder.coroutineScope.launch { + var filesTotal = 0 + var foldersTotal = 0 + for (entry: WatcherEntry in watcherManager.getEntries().values) { + filesTotal += 1 + entry.map.forEach { + val movePath = "${it.toAbsolutePath()}/${entry.file.name}" + println(movePath) + Files.copy(entry.file.toPath(), Path.of(movePath), StandardCopyOption.REPLACE_EXISTING) + foldersTotal += 1 } } + snackBarDataHolder.scaffoldState.snackbarHostState.currentSnackbarData?.dismiss() + println(foldersTotal) + if (foldersTotal < 1) { + println(foldersTotal) + snackBarDataHolder.scaffoldState.snackbarHostState.showSnackbar( + message = "No files to move, skipped.", + duration = SnackbarDuration.Short + ) + } else { + snackBarDataHolder.scaffoldState.snackbarHostState.showSnackbar( + message = "Successfully moved $filesTotal ${if (filesTotal > 1) "files" else "file"} to $foldersTotal different ${if (foldersTotal > 1) "folders" else "folder"}", + duration = SnackbarDuration.Short + ) + } } }