Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 266 additions & 0 deletions app/schemas/com.maltaisn.notes.model.NotesDatabase/6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "fdfbc7c74a5e022a07562da68dfbc516",
"entities": [
{
"tableName": "notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `metadata` TEXT NOT NULL, `added_date` INTEGER NOT NULL, `modified_date` INTEGER NOT NULL, `rank` BLOB NOT NULL, `status` INTEGER NOT NULL, `color` INTEGER NOT NULL DEFAULT 0, `pinned` INTEGER NOT NULL, `reminder_start` INTEGER, `reminder_recurrence` TEXT, `reminder_next` INTEGER, `reminder_count` INTEGER, `reminder_done` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "metadata",
"columnName": "metadata",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "addedDate",
"columnName": "added_date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastModifiedDate",
"columnName": "modified_date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "rank",
"columnName": "rank",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "pinned",
"columnName": "pinned",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "reminder.start",
"columnName": "reminder_start",
"affinity": "INTEGER"
},
{
"fieldPath": "reminder.recurrence",
"columnName": "reminder_recurrence",
"affinity": "TEXT"
},
{
"fieldPath": "reminder.next",
"columnName": "reminder_next",
"affinity": "INTEGER"
},
{
"fieldPath": "reminder.count",
"columnName": "reminder_count",
"affinity": "INTEGER"
},
{
"fieldPath": "reminder.done",
"columnName": "reminder_done",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "notes_fts",
"createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`title` TEXT NOT NULL, `content` TEXT NOT NULL, tokenize=unicode61, content=`notes`)",
"fields": [
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": []
},
"ftsVersion": "FTS4",
"ftsOptions": {
"tokenizer": "unicode61",
"tokenizerArgs": [],
"contentTable": "notes",
"languageIdColumnName": "",
"matchInfo": "FTS4",
"notIndexedColumns": [],
"prefixSizes": [],
"preferredOrder": "ASC"
},
"contentSyncTriggers": [
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_notes_fts_BEFORE_UPDATE BEFORE UPDATE ON `notes` BEGIN DELETE FROM `notes_fts` WHERE `docid`=OLD.`rowid`; END",
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_notes_fts_BEFORE_DELETE BEFORE DELETE ON `notes` BEGIN DELETE FROM `notes_fts` WHERE `docid`=OLD.`rowid`; END",
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_notes_fts_AFTER_UPDATE AFTER UPDATE ON `notes` BEGIN INSERT INTO `notes_fts`(`docid`, `title`, `content`) VALUES (NEW.`rowid`, NEW.`title`, NEW.`content`); END",
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_notes_fts_AFTER_INSERT AFTER INSERT ON `notes` BEGIN INSERT INTO `notes_fts`(`docid`, `title`, `content`) VALUES (NEW.`rowid`, NEW.`title`, NEW.`content`); END"
]
},
{
"tableName": "labels",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `hidden` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "hidden",
"columnName": "hidden",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_labels_name",
"unique": false,
"columnNames": [
"name"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_labels_name` ON `${TABLE_NAME}` (`name`)"
}
]
},
{
"tableName": "label_refs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`noteId` INTEGER NOT NULL, `labelId` INTEGER NOT NULL, PRIMARY KEY(`noteId`, `labelId`), FOREIGN KEY(`noteId`) REFERENCES `notes`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`labelId`) REFERENCES `labels`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "noteId",
"columnName": "noteId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "labelId",
"columnName": "labelId",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"noteId",
"labelId"
]
},
"indices": [
{
"name": "index_label_refs_noteId",
"unique": false,
"columnNames": [
"noteId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_label_refs_noteId` ON `${TABLE_NAME}` (`noteId`)"
},
{
"name": "index_label_refs_labelId",
"unique": false,
"columnNames": [
"labelId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_label_refs_labelId` ON `${TABLE_NAME}` (`labelId`)"
}
],
"foreignKeys": [
{
"table": "notes",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"noteId"
],
"referencedColumns": [
"id"
]
},
{
"table": "labels",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"labelId"
],
"referencedColumns": [
"id"
]
}
]
}
],
"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, 'fdfbc7c74a5e022a07562da68dfbc516')"
]
}
}
3 changes: 2 additions & 1 deletion app/src/debug/kotlin/com/maltaisn/notes/DebugUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ object DebugUtils {
val added = getRandomDate()
val modified = getRandomDate(added)
val pinned = if (status == NoteStatus.ACTIVE) PinnedStatus.UNPINNED else PinnedStatus.CANT_PIN
val color = (0..5).random()

return Note(0, type, title, content, metadata, added, modified,
FractionalIndex.INITIAL, status, pinned, null)
FractionalIndex.INITIAL, status, color, pinned, null)
}

private fun getRandomString(size: IntRange): String {
Expand Down
13 changes: 12 additions & 1 deletion app/src/main/kotlin/com/maltaisn/notes/ViewExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.graphics.Paint
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.core.content.getSystemService

/**
Expand All @@ -31,9 +32,19 @@ fun View.hideKeyboard() {
imm?.hideSoftInputFromWindow(this.windowToken, 0)
}

@ColorRes
fun getNoteColorResource(index: Int): Int = when (index) {
0 -> R.color.note_color_default
1 -> R.color.note_color_1
2 -> R.color.note_color_2
3 -> R.color.note_color_3
4 -> R.color.note_color_4
5 -> R.color.note_color_5
else -> R.color.note_color_default
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use a color array resource instead to avoid having to do this. See this. At this point if you used an enum you would cast it to an int.


/**
* Try to show the keyboard from [this] view.
* The keyboard is shown with a 200 ms delay by default, otherwise it often doesn't work.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this comment removed, but nothing else changed? The comment is still correct.

*/
fun View.showKeyboard(delay: Long = 200L) {
val context = this.context ?: return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class DefaultJsonManager @Inject constructor(
val note = noteWithLabels.note
notesMap[note.id] = NoteSurrogate(note.type, note.title, note.content,
note.metadata, note.addedDate, note.lastModifiedDate,
note.rank, note.status, note.pinned, note.reminder,
note.rank, note.status, note.color, note.pinned, note.reminder,
noteWithLabels.labels.map { it.id })
}

Expand Down Expand Up @@ -223,7 +223,7 @@ class DefaultJsonManager @Inject constructor(
}

val newNote = Note(id, ns.type, ns.title, ns.content, ns.metadata, ns.addedDate,
ns.lastModifiedDate, rank, ns.status, ns.pinned, ns.reminder)
ns.lastModifiedDate, rank, ns.status, ns.color, ns.pinned, ns.reminder)
val oldNote = existingNotes[noteId]

// Remap labels appropriately and discard unresolved label IDs.
Expand Down Expand Up @@ -314,6 +314,8 @@ private data class NoteSurrogate(
val rank: FractionalIndex? = null,
@SerialName("status")
val status: NoteStatus,
@SerialName("color")
val color: Int = 0,
@SerialName("pinned")
val pinned: PinnedStatus,
@SerialName("reminder")
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/kotlin/com/maltaisn/notes/model/NotesDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ abstract class NotesDatabase : RoomDatabase() {

@Suppress("MagicNumber")
companion object {
const val VERSION = 5
const val VERSION = 6

val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
Expand Down Expand Up @@ -133,13 +133,23 @@ abstract class NotesDatabase : RoomDatabase() {
}
}

val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(db: SupportSQLiteDatabase) {
db.apply {
// Add color column to notes table, default to 0.
execSQL("ALTER TABLE notes ADD COLUMN color INTEGER NOT NULL DEFAULT 0")
}
}
}

// All SQL used in migrations must be compatible with min SDK version, API 21,
// which uses SQLite 3.8.6! See https://stackoverflow.com/a/4377116/5288316
val ALL_MIGRATIONS = arrayOf(
MIGRATION_1_2,
MIGRATION_2_3,
MIGRATION_3_4,
MIGRATION_4_5,
MIGRATION_5_6,
)
}
}
Loading