Skip to content

Commit c343a7e

Browse files
authored
Merge pull request #60 from wiiznokes/markdown
add markdown support
2 parents 671002d + 8f9046d commit c343a7e

File tree

9 files changed

+146
-74
lines changed

9 files changed

+146
-74
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ dependencies {
183183
implementation(libs.about.libraries)
184184

185185
// Markdown to HTML
186-
//implementation(libs.markdown)
186+
implementation(libs.richtext.commonmark)
187+
implementation(libs.richtext.ui.material3)
187188

188189
// unit test
189190
testImplementation(libs.test.junit.ktx)

app/src/main/java/io/github/wiiznokes/gitnote/data/AppPreferences.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class AppPreferences(
116116
databaseCommit.update("")
117117
}
118118

119+
val isReadOnlyModeActive = booleanPreference("isReadOnlyModeActive", false)
120+
119121
}
120122

121123

app/src/main/java/io/github/wiiznokes/gitnote/ui/screen/app/EditScreen.kt

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import androidx.compose.foundation.layout.WindowInsets
66
import androidx.compose.foundation.layout.fillMaxSize
77
import androidx.compose.foundation.layout.fillMaxWidth
88
import androidx.compose.foundation.layout.padding
9-
import androidx.compose.foundation.layout.safeContent
109
import androidx.compose.foundation.layout.safeDrawing
1110
import androidx.compose.foundation.layout.width
1211
import androidx.compose.foundation.shape.RoundedCornerShape
1312
import androidx.compose.foundation.text.KeyboardActions
1413
import androidx.compose.material.icons.Icons
1514
import androidx.compose.material.icons.automirrored.filled.ArrowBack
1615
import androidx.compose.material.icons.filled.Done
16+
import androidx.compose.material.icons.filled.Lock
17+
import androidx.compose.material.icons.filled.LockOpen
1718
import androidx.compose.material.icons.filled.Save
1819
import androidx.compose.material3.Button
1920
import androidx.compose.material3.ButtonDefaults
@@ -44,6 +45,9 @@ import androidx.compose.ui.graphics.Color
4445
import androidx.compose.ui.res.stringResource
4546
import androidx.compose.ui.text.style.TextOverflow
4647
import androidx.compose.ui.unit.dp
48+
import androidx.lifecycle.viewModelScope
49+
import com.halilibo.richtext.commonmark.Markdown
50+
import com.halilibo.richtext.ui.material3.RichText
4751
import io.github.wiiznokes.gitnote.R
4852
import io.github.wiiznokes.gitnote.ui.component.CustomDropDown
4953
import io.github.wiiznokes.gitnote.ui.component.CustomDropDownModel
@@ -52,6 +56,7 @@ import io.github.wiiznokes.gitnote.ui.destination.EditParams
5256
import io.github.wiiznokes.gitnote.ui.model.EditType
5357
import io.github.wiiznokes.gitnote.ui.model.FileExtension
5458
import io.github.wiiznokes.gitnote.ui.viewmodel.newEditViewModel
59+
import kotlinx.coroutines.launch
5560

5661

5762
private const val TAG = "EditScreen"
@@ -83,11 +88,11 @@ fun EditScreen(
8388
}
8489
}
8590

91+
val isReadOnlyModeActive = vm.prefs.isReadOnlyModeActive.getAsState().value
92+
8693
Scaffold(
8794
contentWindowInsets = WindowInsets.safeDrawing,
88-
contentColor = MaterialTheme.colorScheme.background,
8995
topBar = {
90-
9196
val backgroundColor = MaterialTheme.colorScheme.surfaceColorAtElevation(15.dp)
9297

9398
TopAppBar(
@@ -97,7 +102,7 @@ fun EditScreen(
97102
navigationIcon = {
98103
IconButton(
99104
onClick = {
100-
vm.onFinish()
105+
vm.shouldSaveWhenQuitting = false
101106
onFinished()
102107
},
103108
) {
@@ -117,6 +122,7 @@ fun EditScreen(
117122
onValueChange = {
118123
vm.name.value = it
119124
},
125+
readOnly = isReadOnlyModeActive,
120126
singleLine = true,
121127
placeholder = {
122128
Text(text = stringResource(R.string.note_name))
@@ -137,36 +143,57 @@ fun EditScreen(
137143
)
138144
},
139145
actions = {
140-
ExtensionChooser(vm.fileExtension)
146+
ExtensionChooser(vm.fileExtension, isReadOnlyModeActive)
141147
Spacer(modifier = Modifier.width(10.dp))
142148
IconButton(
143149
colors = IconButtonDefaults.iconButtonColors(
144150
containerColor = MaterialTheme.colorScheme.primary,
145151
contentColor = MaterialTheme.colorScheme.onPrimary
146152
),
147153
onClick = {
148-
vm.onValidation(onSuccess = null)
149-
}
154+
vm.save()
155+
},
156+
enabled = !isReadOnlyModeActive
150157
) {
151158
SimpleIcon(
152159
imageVector = Icons.Default.Save,
153160
)
154161
}
162+
163+
Spacer(modifier = Modifier.width(10.dp))
164+
165+
IconButton(
166+
colors = IconButtonDefaults.iconButtonColors(
167+
containerColor = MaterialTheme.colorScheme.primary,
168+
contentColor = MaterialTheme.colorScheme.onPrimary
169+
),
170+
onClick = {
171+
vm.viewModelScope.launch {
172+
vm.prefs.isReadOnlyModeActive.update(!isReadOnlyModeActive)
173+
}
174+
},
175+
) {
176+
SimpleIcon(
177+
imageVector = if (isReadOnlyModeActive) {
178+
Icons.Default.Lock
179+
} else {
180+
Icons.Default.LockOpen
181+
},
182+
)
183+
}
155184
}
156185
)
157186
},
158187
floatingActionButton = {
159-
160188
// bug: https://issuetracker.google.com/issues/224005027
161189
//AnimatedVisibility(visible = currentNoteFolderRelativePath.isNotEmpty()) {
162-
if (vm.name.value.text.isNotEmpty()) {
190+
if (!isReadOnlyModeActive && vm.name.value.text.isNotEmpty()) {
163191
FloatingActionButton(
164192
modifier = Modifier,
165193
containerColor = MaterialTheme.colorScheme.primary,
166194
shape = RoundedCornerShape(20.dp),
167195
onClick = {
168-
vm.onFinish()
169-
vm.onValidation(onSuccess = onFinished)
196+
vm.save(onSuccess = onFinished)
170197
}
171198
) {
172199
SimpleIcon(
@@ -177,48 +204,60 @@ fun EditScreen(
177204
}
178205
}
179206
) { paddingValues ->
180-
TextField(
181-
modifier = Modifier
182-
.padding(paddingValues)
183-
.fillMaxSize()
184-
.focusRequester(textFocusRequester),
185-
value = vm.content.value,
186-
onValueChange = {
187-
vm.content.value = it
188-
},
189-
colors = TextFieldDefaults.colors(
190-
focusedContainerColor = MaterialTheme.colorScheme.background,
191-
unfocusedContainerColor = MaterialTheme.colorScheme.background,
192-
focusedTextColor = MaterialTheme.colorScheme.onBackground,
193-
unfocusedTextColor = MaterialTheme.colorScheme.onBackground,
194-
focusedIndicatorColor = Color.Transparent,
195-
unfocusedIndicatorColor = Color.Transparent,
196-
),
197-
keyboardActions = KeyboardActions(
198-
onDone = {
199-
vm.onFinish()
200-
vm.onValidation(onSuccess = onFinished)
201-
}
202-
)
203-
)
204207

208+
if (isReadOnlyModeActive && vm.fileExtension.value is FileExtension.Md) {
209+
RichText(
210+
modifier = Modifier
211+
.padding(paddingValues)
212+
.fillMaxSize()
213+
) {
214+
Markdown(vm.content.value.text)
215+
}
216+
217+
218+
} else {
219+
TextField(
220+
modifier = Modifier
221+
.padding(paddingValues)
222+
.fillMaxSize()
223+
.focusRequester(textFocusRequester),
224+
value = vm.content.value,
225+
onValueChange = {
226+
vm.content.value = it
227+
},
228+
colors = TextFieldDefaults.colors(
229+
focusedContainerColor = MaterialTheme.colorScheme.background,
230+
unfocusedContainerColor = MaterialTheme.colorScheme.background,
231+
focusedTextColor = MaterialTheme.colorScheme.onBackground,
232+
unfocusedTextColor = MaterialTheme.colorScheme.onBackground,
233+
focusedIndicatorColor = Color.Transparent,
234+
unfocusedIndicatorColor = Color.Transparent,
235+
),
236+
keyboardActions = KeyboardActions(
237+
onDone = {
238+
vm.save(onSuccess = onFinished)
239+
}
240+
),
241+
readOnly = isReadOnlyModeActive
242+
)
243+
}
205244
}
206245
}
207246

208247

209248
@Composable
210249
private fun ExtensionChooser(
211-
fileExtension: MutableState<FileExtension>
250+
fileExtension: MutableState<FileExtension>,
251+
isReadOnly: Boolean,
212252
) {
213253
Box {
214254
val expanded = remember { mutableStateOf(false) }
215255
Button(
216256
colors = ButtonDefaults.buttonColors(
217257
containerColor = MaterialTheme.colorScheme.secondary
218258
),
219-
onClick = {
220-
expanded.value = true
221-
}
259+
onClick = { expanded.value = true },
260+
enabled = !isReadOnly
222261
) {
223262
Text(
224263
text = '.' + fileExtension.value.text,

app/src/main/java/io/github/wiiznokes/gitnote/ui/screen/app/grid/GridScreen.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,14 @@ import androidx.compose.ui.unit.Velocity
6464
import androidx.compose.ui.unit.dp
6565
import androidx.lifecycle.compose.collectAsStateWithLifecycle
6666
import androidx.lifecycle.viewmodel.compose.viewModel
67+
import com.halilibo.richtext.commonmark.Markdown
68+
import com.halilibo.richtext.ui.material3.RichText
6769
import io.github.wiiznokes.gitnote.R
6870
import io.github.wiiznokes.gitnote.data.room.Note
6971
import io.github.wiiznokes.gitnote.ui.component.CustomDropDown
7072
import io.github.wiiznokes.gitnote.ui.component.CustomDropDownModel
7173
import io.github.wiiznokes.gitnote.ui.model.EditType
74+
import io.github.wiiznokes.gitnote.ui.model.FileExtension
7275
import io.github.wiiznokes.gitnote.ui.screen.app.DrawerScreen
7376
import io.github.wiiznokes.gitnote.ui.viewmodel.GridViewModel
7477

@@ -311,12 +314,18 @@ private fun GridView(
311314
color = MaterialTheme.colorScheme.tertiary
312315
)
313316

314-
Text(
315-
text = gridNote.note.content,
316-
modifier = Modifier,
317-
overflow = TextOverflow.Ellipsis,
318-
color = MaterialTheme.colorScheme.onSurface
319-
)
317+
if (gridNote.note.fileExtension() is FileExtension.Md) {
318+
RichText {
319+
Markdown(gridNote.note.content)
320+
}
321+
} else {
322+
Text(
323+
text = gridNote.note.content,
324+
modifier = Modifier,
325+
overflow = TextOverflow.Ellipsis,
326+
color = MaterialTheme.colorScheme.onSurface
327+
)
328+
}
320329
}
321330
}
322331
}

app/src/main/java/io/github/wiiznokes/gitnote/ui/screen/app/grid/TopGrid.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import androidx.compose.ui.text.input.TextFieldValue
4343
import androidx.compose.ui.unit.Dp
4444
import androidx.compose.ui.unit.IntOffset
4545
import androidx.compose.ui.unit.dp
46+
import androidx.lifecycle.viewModelScope
4647
import io.github.wiiznokes.gitnote.R
4748
import io.github.wiiznokes.gitnote.ui.component.CustomDropDown
4849
import io.github.wiiznokes.gitnote.ui.component.CustomDropDownModel
@@ -183,6 +184,7 @@ private fun SearchBar(
183184
)
184185
}
185186

187+
val readOnlyMode = vm.prefs.isReadOnlyModeActive.getAsState().value
186188

187189
CustomDropDown(
188190
expanded = expanded,
@@ -191,6 +193,16 @@ private fun SearchBar(
191193
text = stringResource(R.string.settings),
192194
onClick = onSettingsClick
193195
),
196+
CustomDropDownModel(
197+
text = if (readOnlyMode) stringResource(
198+
R.string.read_only_mode_deactive
199+
) else stringResource(R.string.read_only_mode_activate),
200+
onClick = {
201+
vm.viewModelScope.launch {
202+
vm.prefs.isReadOnlyModeActive.update(!readOnlyMode)
203+
}
204+
}
205+
),
194206
)
195207
)
196208
}

0 commit comments

Comments
 (0)