diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt
index edd91d6c..d00d5aac 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt
@@ -1,40 +1,111 @@
package de.mm20.launcher2.ui.launcher.widgets.notes
+import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.text.BasicTextField
-import androidx.compose.material3.LocalContentColor
-import androidx.compose.material3.MaterialTheme
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.Add
+import androidx.compose.material.icons.rounded.Delete
+import androidx.compose.material.icons.rounded.MoreVert
+import androidx.compose.material.icons.rounded.SaveAlt
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.markdown.MarkdownEditor
import de.mm20.launcher2.widgets.NotesWidget
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
@Composable
fun NotesWidget(widget: NotesWidget) {
- val viewModel: NotesWidgetVM = viewModel(key = "notes-widget-${widget.id}", factory = NotesWidgetVM.Factory)
+ val context = LocalContext.current
+ val viewModel: NotesWidgetVM =
+ viewModel(key = "notes-widget-${widget.id}", factory = NotesWidgetVM.Factory)
LaunchedEffect(widget) {
viewModel.updateWidget(widget)
}
- val text by viewModel.noteText
-
- MarkdownEditor(
- value = text,
- onValueChange = { viewModel.setText(it) },
- modifier = Modifier.fillMaxWidth().padding(16.dp),
- placeholder = {
- Text(stringResource(R.string.notes_widget_placeholder))
+ val exportLauncher = rememberLauncherForActivityResult(
+ contract = ActivityResultContracts.CreateDocument("text/markdown"),
+ onResult = {
+ if (it != null) viewModel.exportNote(context, it)
}
)
+
+ val text by viewModel.noteText
+ Column {
+ MarkdownEditor(
+ value = text,
+ onValueChange = { viewModel.setText(it) },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ placeholder = {
+ Text(stringResource(R.string.notes_widget_placeholder))
+ }
+ )
+
+ AnimatedVisibility(text.isNotBlank()) {
+ var showMenu by remember { mutableStateOf(false) }
+ Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterEnd) {
+ Box {
+ IconButton(onClick = { showMenu = true }) {
+ Icon(Icons.Rounded.MoreVert, null)
+ }
+ DropdownMenu(expanded = showMenu, onDismissRequest = { showMenu = false }) {
+ DropdownMenuItem(
+ text = { Text("New note") },
+ leadingIcon = {
+ Icon(Icons.Rounded.Add, null)
+ },
+ onClick = { /*TODO*/ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.notes_widget_action_save)) },
+ leadingIcon = {
+ Icon(Icons.Rounded.SaveAlt, null)
+ },
+ onClick = {
+ val fileName = context.getString(
+ R.string.notes_widget_export_filename,
+ ZonedDateTime.now().format(
+ DateTimeFormatter.ISO_INSTANT
+ )
+ )
+ exportLauncher.launch("$fileName.md")
+ showMenu = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text("Dismiss") },
+ leadingIcon = {
+ Icon(Icons.Rounded.Delete, null)
+ },
+ onClick = { /*TODO*/ },
+ )
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidgetVM.kt
index b2c56cb0..e982c8a0 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidgetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidgetVM.kt
@@ -1,5 +1,7 @@
package de.mm20.launcher2.ui.launcher.widgets.notes
+import android.content.Context
+import android.net.Uri
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
@@ -8,14 +10,11 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import de.mm20.launcher2.services.widgets.WidgetsService
import de.mm20.launcher2.widgets.NotesWidget
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
-import org.intellij.markdown.ast.ASTNode
-import org.intellij.markdown.ast.getTextInNode
-import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
-import org.intellij.markdown.parser.MarkdownParser
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
@@ -43,6 +42,17 @@ class NotesWidgetVM(
}
}
+ fun exportNote(context: Context, uri: Uri) {
+ viewModelScope.launch(Dispatchers.IO) {
+ val text = noteText.value
+ Log.d("MM20", text)
+ val outputStream = context.contentResolver.openOutputStream(uri)
+ outputStream?.use {
+ it.write(text.toByteArray())
+ }
+ }
+ }
+
companion object: KoinComponent {
val Factory = viewModelFactory {
initializer {
diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml
index e8ada5c1..f95e5588 100644
--- a/core/i18n/src/main/res/values/strings.xml
+++ b/core/i18n/src/main/res/values/strings.xml
@@ -225,6 +225,13 @@
More
Write a noteā¦
+ New note
+
+ Save
+
+ Note_%1$s
+ Dismiss
+ Note dismissed.
By %1$s