mirror of
https://github.com/PhilKes/NotallyX.git
synced 2025-06-28 20:29:54 +00:00
Merge pull request #503 from PhilKes/feat/persist-note-viewmode
Persist viewMode for each note individually
This commit is contained in:
commit
54d835e40b
26 changed files with 339 additions and 69 deletions
164
app/schemas/com.philkes.notallyx.data.NotallyDatabase/9.json
Normal file
164
app/schemas/com.philkes.notallyx.data.NotallyDatabase/9.json
Normal file
|
@ -0,0 +1,164 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 9,
|
||||
"identityHash": "042b20b5b4cfc8415e6cf6348196e869",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "BaseNote",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` TEXT NOT NULL, `folder` TEXT NOT NULL, `color` TEXT NOT NULL, `title` TEXT NOT NULL, `pinned` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `modifiedTimestamp` INTEGER NOT NULL, `labels` TEXT NOT NULL, `body` TEXT NOT NULL, `spans` TEXT NOT NULL, `items` TEXT NOT NULL, `images` TEXT NOT NULL, `files` TEXT NOT NULL, `audios` TEXT NOT NULL, `reminders` TEXT NOT NULL, `viewMode` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "folder",
|
||||
"columnName": "folder",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "color",
|
||||
"columnName": "color",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pinned",
|
||||
"columnName": "pinned",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "timestamp",
|
||||
"columnName": "timestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "modifiedTimestamp",
|
||||
"columnName": "modifiedTimestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "labels",
|
||||
"columnName": "labels",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "body",
|
||||
"columnName": "body",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "spans",
|
||||
"columnName": "spans",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "items",
|
||||
"columnName": "items",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "images",
|
||||
"columnName": "images",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "files",
|
||||
"columnName": "files",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "audios",
|
||||
"columnName": "audios",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "reminders",
|
||||
"columnName": "reminders",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "viewMode",
|
||||
"columnName": "viewMode",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_BaseNote_id_folder_pinned_timestamp_labels",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"id",
|
||||
"folder",
|
||||
"pinned",
|
||||
"timestamp",
|
||||
"labels"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_BaseNote_id_folder_pinned_timestamp_labels` ON `${TABLE_NAME}` (`id`, `folder`, `pinned`, `timestamp`, `labels`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "Label",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`value` TEXT NOT NULL, PRIMARY KEY(`value`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '042b20b5b4cfc8415e6cf6348196e869')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.Color
|
||||
import com.philkes.notallyx.data.model.Converters
|
||||
import com.philkes.notallyx.data.model.Label
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.toColorString
|
||||
import com.philkes.notallyx.presentation.view.misc.NotNullLiveData
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.BiometricLock
|
||||
|
@ -32,7 +33,7 @@ import net.sqlcipher.database.SQLiteDatabase
|
|||
import net.sqlcipher.database.SupportFactory
|
||||
|
||||
@TypeConverters(Converters::class)
|
||||
@Database(entities = [BaseNote::class, Label::class], version = 8)
|
||||
@Database(entities = [BaseNote::class, Label::class], version = 9)
|
||||
abstract class NotallyDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun getLabelDao(): LabelDao
|
||||
|
@ -131,6 +132,7 @@ abstract class NotallyDatabase : RoomDatabase() {
|
|||
Migration6,
|
||||
Migration7,
|
||||
Migration8,
|
||||
Migration9,
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
SQLiteDatabase.loadLibs(context)
|
||||
|
@ -261,5 +263,14 @@ abstract class NotallyDatabase : RoomDatabase() {
|
|||
cursor.close()
|
||||
}
|
||||
}
|
||||
|
||||
object Migration9 : Migration(8, 9) {
|
||||
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL(
|
||||
"ALTER TABLE `BaseNote` ADD COLUMN `viewMode` TEXT DEFAULT '${NoteViewMode.EDIT.name}'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.utils.log
|
||||
import com.philkes.notallyx.utils.startsWithAnyOf
|
||||
|
@ -155,6 +156,7 @@ fun EvernoteNote.mapToBaseNote(): BaseNote {
|
|||
files = files,
|
||||
audios = audios,
|
||||
reminders = mutableListOf(),
|
||||
NoteViewMode.EDIT,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.utils.listFilesRecursive
|
||||
import com.philkes.notallyx.utils.log
|
||||
|
@ -162,6 +163,7 @@ class GoogleKeepImporter : ExternalImporter {
|
|||
files = files,
|
||||
audios = audios,
|
||||
reminders = mutableListOf(),
|
||||
NoteViewMode.EDIT,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.philkes.notallyx.data.imports.ImportProgress
|
|||
import com.philkes.notallyx.data.model.BaseNote
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.utils.MIME_TYPE_JSON
|
||||
import com.philkes.notallyx.utils.readFileContents
|
||||
|
@ -59,6 +60,7 @@ class PlainTextImporter : ExternalImporter {
|
|||
files = listOf(),
|
||||
audios = listOf(),
|
||||
reminders = listOf(),
|
||||
NoteViewMode.EDIT,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ data class BaseNote(
|
|||
val files: List<FileAttachment>,
|
||||
val audios: List<Audio>,
|
||||
val reminders: List<Reminder>,
|
||||
val viewMode: NoteViewMode,
|
||||
) : Item {
|
||||
|
||||
companion object {
|
||||
|
@ -53,6 +54,7 @@ data class BaseNote(
|
|||
if (files != other.files) return false
|
||||
if (audios != other.audios) return false
|
||||
if (reminders != other.reminders) return false
|
||||
if (viewMode != other.viewMode) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -73,6 +75,7 @@ data class BaseNote(
|
|||
result = 31 * result + files.hashCode()
|
||||
result = 31 * result + audios.hashCode()
|
||||
result = 31 * result + reminders.hashCode()
|
||||
result = 31 * result + viewMode.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ object Converters {
|
|||
JSONObject().apply {
|
||||
put("id", reminder.id) // Store date as long timestamp
|
||||
put("dateTime", reminder.dateTime.time) // Store date as long timestamp
|
||||
put("repetition", reminder.repetition?.let { repetitionToJson(it) })
|
||||
put("repetition", reminder.repetition?.let { repetitionToJsonObject(it) })
|
||||
}
|
||||
}
|
||||
return JSONArray(objects)
|
||||
|
@ -165,10 +165,14 @@ object Converters {
|
|||
|
||||
@TypeConverter
|
||||
fun repetitionToJson(repetition: Repetition): String {
|
||||
return repetitionToJsonObject(repetition).toString()
|
||||
}
|
||||
|
||||
fun repetitionToJsonObject(repetition: Repetition): JSONObject {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("value", repetition.value)
|
||||
jsonObject.put("unit", repetition.unit.name) // Store the TimeUnit as a string
|
||||
return jsonObject.toString()
|
||||
return jsonObject
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
|
@ -34,8 +34,7 @@ data class ListItem(
|
|||
if (other !is ListItem) {
|
||||
return false
|
||||
}
|
||||
return (this.id == other.id &&
|
||||
this.body == other.body &&
|
||||
return (this.body == other.body &&
|
||||
this.order == other.order &&
|
||||
this.checked == other.checked &&
|
||||
this.isChild == other.isChild)
|
||||
|
|
|
@ -80,7 +80,8 @@ fun BaseNote.toJson(): String {
|
|||
.put("color", color)
|
||||
.put("title", title)
|
||||
.put("pinned", pinned)
|
||||
.put("date-created", timestamp)
|
||||
.put("timestamp", timestamp)
|
||||
.put("modifiedTimestamp", modifiedTimestamp)
|
||||
.put("labels", JSONArray(labels))
|
||||
|
||||
when (type) {
|
||||
|
@ -94,6 +95,7 @@ fun BaseNote.toJson(): String {
|
|||
}
|
||||
}
|
||||
jsonObject.put("reminders", Converters.remindersToJSONArray(reminders))
|
||||
jsonObject.put("viewMode", viewMode.name)
|
||||
return jsonObject.toString(2)
|
||||
}
|
||||
|
||||
|
@ -117,6 +119,7 @@ fun String.toBaseNote(): BaseNote {
|
|||
val files = Converters.jsonToFiles(jsonObject.getArrayOrEmpty("files"))
|
||||
val audios = Converters.jsonToAudios(jsonObject.getArrayOrEmpty("audios"))
|
||||
val reminders = Converters.jsonToReminders(jsonObject.getArrayOrEmpty("reminders"))
|
||||
val viewMode = NoteViewMode.valueOfOrDefault(jsonObject.getStringOrDefault("viewMode", ""))
|
||||
return BaseNote(
|
||||
id,
|
||||
type,
|
||||
|
@ -134,6 +137,7 @@ fun String.toBaseNote(): BaseNote {
|
|||
files,
|
||||
audios,
|
||||
reminders,
|
||||
viewMode,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package com.philkes.notallyx.data.model
|
||||
|
||||
import com.philkes.notallyx.R
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.StaticTextProvider
|
||||
|
||||
enum class NoteViewMode(override val textResId: Int) : StaticTextProvider {
|
||||
READ_ONLY(R.string.read_only),
|
||||
EDIT(R.string.edit);
|
||||
|
||||
companion object {
|
||||
fun valueOfOrDefault(value: String) =
|
||||
try {
|
||||
NoteViewMode.valueOf(value)
|
||||
} catch (e: Exception) {
|
||||
EDIT
|
||||
}
|
||||
}
|
||||
}
|
|
@ -647,13 +647,6 @@ class SettingsFragment : Fragment() {
|
|||
model.savePreference(autoSaveAfterIdleTime, newValue)
|
||||
}
|
||||
|
||||
defaultNoteViewMode.observe(viewLifecycleOwner) { value ->
|
||||
DefaultNoteViewMode.setup(defaultNoteViewMode, value, requireContext()) { newValue
|
||||
->
|
||||
model.savePreference(defaultNoteViewMode, newValue)
|
||||
}
|
||||
}
|
||||
|
||||
ClearData.setOnClickListener {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage(R.string.clear_data_message)
|
||||
|
|
|
@ -17,6 +17,7 @@ import android.util.TypedValue
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.view.ViewGroup.VISIBLE
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
|
@ -40,6 +41,7 @@ import com.philkes.notallyx.data.NotallyDatabase
|
|||
import com.philkes.notallyx.data.model.Audio
|
||||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.data.model.isImageMimeType
|
||||
import com.philkes.notallyx.databinding.ActivityEditBinding
|
||||
|
@ -80,7 +82,6 @@ import com.philkes.notallyx.presentation.viewmodel.ExportMimeType
|
|||
import com.philkes.notallyx.presentation.viewmodel.NotallyModel
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.DateFormat
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.ListItemSort
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NotesSortBy
|
||||
import com.philkes.notallyx.presentation.widget.WidgetProvider
|
||||
import com.philkes.notallyx.utils.FileError
|
||||
|
@ -125,10 +126,9 @@ abstract class EditActivity(private val type: Type) :
|
|||
protected var colorInt: Int = -1
|
||||
protected var inputMethodManager: InputMethodManager? = null
|
||||
|
||||
protected var viewMode: NotNullLiveData<NoteViewMode>? = null
|
||||
protected lateinit var toggleViewMode: ImageButton
|
||||
protected val canEdit
|
||||
get() = viewMode?.value == NoteViewMode.EDIT
|
||||
get() = notallyModel.viewMode.value == NoteViewMode.EDIT
|
||||
|
||||
private val autoSaveHandler = Handler(Looper.getMainLooper())
|
||||
private val autoSaveRunnable = Runnable {
|
||||
|
@ -550,22 +550,7 @@ abstract class EditActivity(private val type: Type) :
|
|||
binding.BottomAppBarRight.apply {
|
||||
removeAllViews()
|
||||
|
||||
toggleViewMode =
|
||||
addIconButton(R.string.edit, R.drawable.visibility) {
|
||||
viewMode!!.value =
|
||||
when (viewMode!!.value) {
|
||||
NoteViewMode.EDIT -> NoteViewMode.READ_ONLY
|
||||
NoteViewMode.READ_ONLY -> NoteViewMode.EDIT
|
||||
}
|
||||
}
|
||||
if (viewMode == null) {
|
||||
viewMode =
|
||||
NotNullLiveData(
|
||||
if (notallyModel.isNewNote) NoteViewMode.EDIT
|
||||
else preferences.defaultNoteViewMode.value
|
||||
)
|
||||
}
|
||||
|
||||
addToggleViewMode()
|
||||
addIconButton(R.string.more, R.drawable.more_vert, marginStart = 0) {
|
||||
MoreNoteBottomSheet(
|
||||
this@EditActivity,
|
||||
|
@ -578,6 +563,17 @@ abstract class EditActivity(private val type: Type) :
|
|||
setBottomAppBarColor(colorInt)
|
||||
}
|
||||
|
||||
protected fun ViewGroup.addToggleViewMode() {
|
||||
toggleViewMode =
|
||||
addIconButton(R.string.edit, R.drawable.visibility) {
|
||||
notallyModel.viewMode.value =
|
||||
when (notallyModel.viewMode.value) {
|
||||
NoteViewMode.EDIT -> NoteViewMode.READ_ONLY
|
||||
NoteViewMode.READ_ONLY -> NoteViewMode.EDIT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected fun createFolderActions() =
|
||||
when (notallyModel.folder) {
|
||||
Folder.NOTES ->
|
||||
|
@ -658,14 +654,14 @@ abstract class EditActivity(private val type: Type) :
|
|||
binding.EnterTitle.initHistory(changeHistory) { text ->
|
||||
notallyModel.title = text.trim().toString()
|
||||
}
|
||||
viewMode!!.observe(this) { value ->
|
||||
notallyModel.viewMode.observe(this) { value ->
|
||||
toggleViewMode.setImageResource(
|
||||
when (value) {
|
||||
NoteViewMode.READ_ONLY -> R.drawable.edit
|
||||
NoteViewMode.EDIT -> R.drawable.visibility
|
||||
else -> R.drawable.visibility
|
||||
}
|
||||
)
|
||||
toggleCanEdit(value)
|
||||
value?.let { toggleCanEdit(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import androidx.recyclerview.widget.SortedList
|
||||
import com.philkes.notallyx.R
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.presentation.addIconButton
|
||||
import com.philkes.notallyx.presentation.hideKeyboardOnFocusedItem
|
||||
|
@ -26,7 +27,6 @@ import com.philkes.notallyx.presentation.view.note.listitem.sorting.SortedItemsL
|
|||
import com.philkes.notallyx.presentation.view.note.listitem.splitByChecked
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.toMutableList
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.autoSortByCheckedEnabled
|
||||
import com.philkes.notallyx.utils.findAllOccurrences
|
||||
import com.philkes.notallyx.utils.indices
|
||||
|
@ -104,14 +104,7 @@ class EditListActivity : EditActivity(Type.LIST), MoreListActions {
|
|||
super.initBottomMenu()
|
||||
binding.BottomAppBarRight.apply {
|
||||
removeAllViews()
|
||||
toggleViewMode =
|
||||
addIconButton(R.string.edit, R.drawable.visibility) {
|
||||
viewMode!!.value =
|
||||
when (viewMode!!.value) {
|
||||
NoteViewMode.EDIT -> NoteViewMode.READ_ONLY
|
||||
NoteViewMode.READ_ONLY -> NoteViewMode.EDIT
|
||||
}
|
||||
}
|
||||
addToggleViewMode()
|
||||
addIconButton(R.string.more, R.drawable.more_vert, marginStart = 0) {
|
||||
MoreListBottomSheet(
|
||||
this@EditListActivity,
|
||||
|
|
|
@ -26,6 +26,7 @@ import androidx.core.view.updateLayoutParams
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.philkes.notallyx.R
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.data.model.createNoteUrl
|
||||
import com.philkes.notallyx.data.model.getNoteIdFromUrl
|
||||
|
@ -48,7 +49,6 @@ import com.philkes.notallyx.presentation.showToast
|
|||
import com.philkes.notallyx.presentation.view.note.TextFormattingAdapter
|
||||
import com.philkes.notallyx.presentation.view.note.action.AddNoteActions
|
||||
import com.philkes.notallyx.presentation.view.note.action.AddNoteBottomSheet
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.utils.LinkMovementMethod
|
||||
import com.philkes.notallyx.utils.copyToClipBoard
|
||||
import com.philkes.notallyx.utils.findAllOccurrences
|
||||
|
|
|
@ -6,10 +6,10 @@ import androidx.core.widget.NestedScrollView
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.SortedList
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.HighlightText
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.ListManager
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.TextSize
|
||||
|
||||
class CheckedListItemAdapter(
|
||||
|
|
|
@ -7,10 +7,10 @@ import androidx.recyclerview.widget.DiffUtil
|
|||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.HighlightText
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.ListManager
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.TextSize
|
||||
|
||||
class ListItemAdapter(
|
||||
|
|
|
@ -7,11 +7,11 @@ import androidx.core.widget.NestedScrollView
|
|||
import androidx.recyclerview.widget.NestedScrollViewItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.databinding.RecyclerListItemBinding
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.ListItemDragCallback
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.ListManager
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.TextSize
|
||||
|
||||
data class ListItemHighlight(
|
||||
|
|
|
@ -21,6 +21,7 @@ import cn.leaqi.drawer.SwipeDrawer.STATE_OPEN
|
|||
import com.philkes.notallyx.data.imports.txt.extractListItems
|
||||
import com.philkes.notallyx.data.imports.txt.findListSyntaxRegex
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.databinding.RecyclerListItemBinding
|
||||
import com.philkes.notallyx.presentation.clone
|
||||
import com.philkes.notallyx.presentation.createListTextWatcherWithHistory
|
||||
|
@ -30,7 +31,6 @@ import com.philkes.notallyx.presentation.view.misc.EditTextAutoClearFocus
|
|||
import com.philkes.notallyx.presentation.view.note.listitem.ListManager
|
||||
import com.philkes.notallyx.presentation.view.note.listitem.firstBodyOrEmptyString
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.ListItemSort
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.NoteViewMode
|
||||
import com.philkes.notallyx.presentation.viewmodel.preference.TextSize
|
||||
import com.philkes.notallyx.utils.changehistory.EditTextState
|
||||
import com.philkes.notallyx.utils.copyToClipBoard
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Reminder
|
||||
import com.philkes.notallyx.data.model.SpanRepresentation
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
|
@ -86,10 +87,13 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) {
|
|||
var body: Editable = SpannableStringBuilder()
|
||||
|
||||
val items = ArrayList<ListItem>()
|
||||
|
||||
val images = NotNullLiveData<List<FileAttachment>>(emptyList())
|
||||
val files = NotNullLiveData<List<FileAttachment>>(emptyList())
|
||||
val audios = NotNullLiveData<List<Audio>>(emptyList())
|
||||
|
||||
val reminders = NotNullLiveData<List<Reminder>>(emptyList())
|
||||
val viewMode = NotNullLiveData(NoteViewMode.EDIT)
|
||||
|
||||
val addingFiles = MutableLiveData<Progress>()
|
||||
val eventBus = MutableLiveData<Event<List<FileError>>>()
|
||||
|
@ -248,6 +252,7 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) {
|
|||
files.value = baseNote.files
|
||||
audios.value = baseNote.audios
|
||||
reminders.value = baseNote.reminders
|
||||
viewMode.value = baseNote.viewMode
|
||||
} else {
|
||||
originalNote = createBaseNote()
|
||||
app.showToast(R.string.cant_find_note)
|
||||
|
@ -345,6 +350,7 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) {
|
|||
files.value,
|
||||
audios.value,
|
||||
reminders.value,
|
||||
viewMode.value,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -76,13 +76,6 @@ class NotallyXPreferences private constructor(private val context: Context) {
|
|||
10,
|
||||
R.string.max_lines_to_display_title,
|
||||
)
|
||||
val defaultNoteViewMode =
|
||||
createEnumPreference(
|
||||
preferences,
|
||||
"defaultNoteViewMode",
|
||||
NoteViewMode.EDIT,
|
||||
R.string.default_note_view_mode,
|
||||
)
|
||||
val labelsHidden = StringSetPreference("labelsHiddenInNavigation", preferences, setOf())
|
||||
val labelTagsHiddenInOverview =
|
||||
BooleanPreference(
|
||||
|
@ -237,7 +230,6 @@ class NotallyXPreferences private constructor(private val context: Context) {
|
|||
backupPassword,
|
||||
backupOnSave,
|
||||
autoSaveAfterIdleTime,
|
||||
defaultNoteViewMode,
|
||||
)
|
||||
.forEach { it.refresh() }
|
||||
}
|
||||
|
|
|
@ -366,11 +366,6 @@ enum class BiometricLock(override val textResId: Int) : StaticTextProvider {
|
|||
DISABLED(R.string.disabled),
|
||||
}
|
||||
|
||||
enum class NoteViewMode(override val textResId: Int) : StaticTextProvider {
|
||||
READ_ONLY(R.string.read_only),
|
||||
EDIT(R.string.edit),
|
||||
}
|
||||
|
||||
object Constants {
|
||||
const val PASSWORD_EMPTY = "None"
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.philkes.notallyx.data.model.Converters
|
|||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.Label
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.data.model.parseToColorString
|
||||
import com.philkes.notallyx.presentation.getQuantityString
|
||||
|
@ -280,6 +281,11 @@ private fun Cursor.toBaseNote(): BaseNote {
|
|||
Converters.jsonToReminders(getString(remindersIndex))
|
||||
} else emptyList()
|
||||
|
||||
val viewModeIndex = getColumnIndex("viewMode")
|
||||
val viewMode =
|
||||
if (viewModeIndex != -1) {
|
||||
NoteViewMode.valueOfOrDefault(getString(viewModeIndex))
|
||||
} else NoteViewMode.EDIT
|
||||
return BaseNote(
|
||||
0,
|
||||
type,
|
||||
|
@ -297,6 +303,7 @@ private fun Cursor.toBaseNote(): BaseNote {
|
|||
files,
|
||||
audios,
|
||||
reminders,
|
||||
viewMode,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.Label
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.SpanRepresentation
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
import com.philkes.notallyx.data.model.parseToColorString
|
||||
|
@ -113,6 +114,7 @@ private fun XmlPullParser.parseBaseNote(rootTag: String, folder: Folder): BaseNo
|
|||
emptyList(),
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
NoteViewMode.EDIT,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -53,10 +53,6 @@
|
|||
android:id="@+id/StartView"
|
||||
layout="@layout/preference" />
|
||||
|
||||
<include
|
||||
android:id="@+id/DefaultNoteViewMode"
|
||||
layout="@layout/preference" />
|
||||
|
||||
<include
|
||||
android:id="@+id/AutoSaveAfterIdle"
|
||||
layout="@layout/preference_seekbar" />
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.philkes.notallyx.data.model.BaseNote
|
|||
import com.philkes.notallyx.data.model.FileAttachment
|
||||
import com.philkes.notallyx.data.model.Folder
|
||||
import com.philkes.notallyx.data.model.ListItem
|
||||
import com.philkes.notallyx.data.model.NoteViewMode
|
||||
import com.philkes.notallyx.data.model.Reminder
|
||||
import com.philkes.notallyx.data.model.SpanRepresentation
|
||||
import com.philkes.notallyx.data.model.Type
|
||||
|
@ -252,6 +253,7 @@ class GoogleKeepImporterTest {
|
|||
files,
|
||||
audios,
|
||||
reminders,
|
||||
NoteViewMode.EDIT,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package com.philkes.notallyx.data.model
|
||||
|
||||
import com.philkes.notallyx.test.createListItem
|
||||
import java.util.Date
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.mockStatic
|
||||
|
||||
class ModelExtensionsTest {
|
||||
|
||||
|
@ -14,9 +18,10 @@ class ModelExtensionsTest {
|
|||
"color": "#E2F6D3",
|
||||
"title": "Test",
|
||||
"pinned": false,
|
||||
"date-created": 1742822848689,
|
||||
"timestamp": 1742822848689,
|
||||
"modifiedTimestamp": 1742823434623,
|
||||
"labels": [
|
||||
"Ggg"
|
||||
"TestLabel"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
|
@ -56,9 +61,12 @@ class ModelExtensionsTest {
|
|||
"dateTime": 1742822940000,
|
||||
"repetition": "{\"value\":1,\"unit\":\"DAYS\"}"
|
||||
}
|
||||
]
|
||||
],
|
||||
"viewMode": "READ_ONLY"
|
||||
}
|
||||
"""
|
||||
val colorMock = mockStatic(android.graphics.Color::class.java)
|
||||
colorMock.`when`<Int> { android.graphics.Color.parseColor(anyString()) }.thenReturn(1)
|
||||
|
||||
val baseNote = json.toBaseNote()
|
||||
|
||||
|
@ -77,6 +85,77 @@ class ModelExtensionsTest {
|
|||
baseNote.items,
|
||||
)
|
||||
assertEquals(1, baseNote.reminders.size)
|
||||
assertEquals(1742822848689, baseNote.timestamp)
|
||||
assertEquals(1742823434623, baseNote.modifiedTimestamp)
|
||||
assertEquals(NoteViewMode.READ_ONLY, baseNote.viewMode)
|
||||
assertEquals(listOf("TestLabel"), baseNote.labels)
|
||||
assertEquals(Repetition(1, RepetitionTimeUnit.DAYS), baseNote.reminders[0].repetition)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `BaseNote toJson()`() {
|
||||
val baseNote =
|
||||
BaseNote(
|
||||
id = 1,
|
||||
Type.LIST,
|
||||
Folder.DELETED,
|
||||
"#E2F6D3",
|
||||
"Title",
|
||||
true,
|
||||
12354632465L,
|
||||
945869546L,
|
||||
listOf("label"),
|
||||
"Body",
|
||||
listOf(SpanRepresentation(0, 10, bold = true)),
|
||||
mutableListOf(
|
||||
createListItem("Item1", true, false),
|
||||
createListItem("Item2", true, true),
|
||||
),
|
||||
listOf(FileAttachment("localImage", "originalImage", "image/jpeg")),
|
||||
listOf(FileAttachment("localFile", "originalFile", "text/plain")),
|
||||
listOf(Audio("audio", 10L, 12312334L)),
|
||||
listOf(Reminder(1, Date(1743253506957), Repetition(10, RepetitionTimeUnit.WEEKS))),
|
||||
NoteViewMode.READ_ONLY,
|
||||
)
|
||||
|
||||
val json = baseNote.toJson()
|
||||
|
||||
assertEquals(
|
||||
"""
|
||||
{
|
||||
"reminders": [{
|
||||
"dateTime": 1743253506957,
|
||||
"id": 1,
|
||||
"repetition": {
|
||||
"unit": "WEEKS",
|
||||
"value": 10
|
||||
}
|
||||
}],
|
||||
"pinned": true,
|
||||
"color": "#E2F6D3",
|
||||
"modifiedTimestamp": 945869546,
|
||||
"type": "LIST",
|
||||
"title": "Title",
|
||||
"viewMode": "READ_ONLY",
|
||||
"items": [
|
||||
{
|
||||
"checked": true,
|
||||
"body": "Item1",
|
||||
"isChild": false
|
||||
},
|
||||
{
|
||||
"checked": true,
|
||||
"body": "Item2",
|
||||
"isChild": true
|
||||
}
|
||||
],
|
||||
"timestamp": 12354632465,
|
||||
"labels": ["label"]
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
.trimStart(),
|
||||
json,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue