Skip to content
Open
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
60 changes: 30 additions & 30 deletions TRANSLATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@ See [Android Translations Converter](https://github.com/Crustack/android-transla
<!-- translations:start -->
| Language | Coverage |
|----------|----------|
| 🇺🇸 English | 100% (337/337) |
| 🇪🇸 Catalan | 19% (65/337) |
| 🇨🇿 Czech | 92% (313/337) |
| 🇩🇰 Danish | 20% (69/337) |
| 🇩🇪 German | 99% (335/337) |
| 🇬🇷 Greek | 21% (72/337) |
| 🇪🇸 Spanish | 93% (314/337) |
| 🇫🇷 French | 97% (327/337) |
| 🇭🇺 Hungarian | 19% (65/337) |
| 🇮🇩 Indonesian | 22% (75/337) |
| 🇮🇹 Italian | 86% (291/337) |
| 🇯🇵 Japanese | 21% (73/337) |
| 🇲🇲 Burmese | 26% (90/337) |
| 🇳🇴 Norwegian Bokmål | 31% (106/337) |
| 🇳🇱 Dutch | 62% (212/337) |
| 🇳🇴 Norwegian Nynorsk | 31% (106/337) |
| 🇵🇱 Polish | 89% (300/337) |
| 🇧🇷 Portuguese (Brazil) | 92% (312/337) |
| 🇵🇹 Portuguese (Portugal) | 21% (71/337) |
| 🇷🇴 Romanian | 89% (301/337) |
| 🇷🇺 Russian | 90% (305/337) |
| 🇸🇰 Slovak | 19% (65/337) |
| 🇸🇮 Slovenian | 32% (109/337) |
| 🇸🇪 Swedish | 18% (63/337) |
| 🇵🇭 Tagalog | 19% (65/337) |
| 🇹🇷 Turkish | 21% (73/337) |
| 🇺🇦 Ukrainian | 98% (331/337) |
| 🇻🇳 Vietnamese | 31% (107/337) |
| 🇨🇳 Chinese (Simplified) | 97% (328/337) |
| 🇹🇼 Chinese (Traditional) | 87% (294/337) |
| 🇺🇸 English | 100% (339/339) |
| 🇪🇸 Catalan | 19% (65/339) |
| 🇨🇿 Czech | 92% (313/339) |
| 🇩🇰 Danish | 20% (69/339) |
| 🇩🇪 German | 98% (335/339) |
| 🇬🇷 Greek | 21% (72/339) |
| 🇪🇸 Spanish | 92% (314/339) |
| 🇫🇷 French | 96% (327/339) |
| 🇭🇺 Hungarian | 19% (65/339) |
| 🇮🇩 Indonesian | 22% (75/339) |
| 🇮🇹 Italian | 85% (291/339) |
| 🇯🇵 Japanese | 21% (73/339) |
| 🇲🇲 Burmese | 26% (90/339) |
| 🇳🇴 Norwegian Bokmål | 31% (106/339) |
| 🇳🇱 Dutch | 62% (212/339) |
| 🇳🇴 Norwegian Nynorsk | 31% (106/339) |
| 🇵🇱 Polish | 88% (300/339) |
| 🇧🇷 Portuguese (Brazil) | 92% (312/339) |
| 🇵🇹 Portuguese (Portugal) | 20% (71/339) |
| 🇷🇴 Romanian | 88% (301/339) |
| 🇷🇺 Russian | 89% (305/339) |
| 🇸🇰 Slovak | 19% (65/339) |
| 🇸🇮 Slovenian | 32% (109/339) |
| 🇸🇪 Swedish | 18% (63/339) |
| 🇵🇭 Tagalog | 19% (65/339) |
| 🇹🇷 Turkish | 21% (73/339) |
| 🇺🇦 Ukrainian | 97% (331/339) |
| 🇻🇳 Vietnamese | 31% (107/339) |
| 🇨🇳 Chinese (Simplified) | 96% (328/339) |
| 🇹🇼 Chinese (Traditional) | 86% (294/339) |
<!-- translations:end -->
179 changes: 179 additions & 0 deletions app/schemas/com.philkes.notallyx.data.NotallyDatabase/10.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
{
"formatVersion": 1,
"database": {
"version": 10,
"identityHash": "6cdd7edd0a8e7bc0b6ba1a706986c6a2",
"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, `sortIdx` INTEGER)",
"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
},
{
"fieldPath": "sortIdx",
"columnName": "sortIdx",
"affinity": "INTEGER",
"notNull": false
}
],
"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`)"
},
{
"name": "index_BaseNote_sortIdx",
"unique": false,
"columnNames": [
"sortIdx"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_BaseNote_sortIdx` ON `${TABLE_NAME}` (`sortIdx`)"
}
],
"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, '6cdd7edd0a8e7bc0b6ba1a706986c6a2')"
]
}
}
18 changes: 17 additions & 1 deletion app/src/main/java/com/philkes/notallyx/data/NotallyDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import java.io.File
import net.zetetic.database.sqlcipher.SupportOpenHelperFactory

@TypeConverters(Converters::class)
@Database(entities = [BaseNote::class, Label::class], version = 9)
@Database(entities = [BaseNote::class, Label::class], version = 10)
abstract class NotallyDatabase : RoomDatabase() {

abstract fun getLabelDao(): LabelDao
Expand Down Expand Up @@ -161,6 +161,7 @@ abstract class NotallyDatabase : RoomDatabase() {
Migration7,
Migration8,
Migration9,
Migration10,
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
System.loadLibrary("sqlcipher")
Expand Down Expand Up @@ -300,5 +301,20 @@ abstract class NotallyDatabase : RoomDatabase() {
)
}
}

object Migration10 : Migration(9, 10) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE `BaseNote` ADD COLUMN `sortIdx` INTEGER")
db.execSQL(
"CREATE INDEX IF NOT EXISTS `index_BaseNote_sortIdx` ON `BaseNote` (`sortIdx`)"
)
db.execSQL(
"DROP INDEX IF EXISTS `index_BaseNote_id_folder_pinned_timestamp_labels_sortIdx` "
)
db.execSQL(
"CREATE INDEX IF NOT EXISTS `index_BaseNote_id_folder_pinned_timestamp_labels` ON `BaseNote` (`id`, `folder`, `pinned`, `timestamp`, `labels`)"
)
}
}
}
}
35 changes: 26 additions & 9 deletions app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Transaction
import androidx.room.Update
import androidx.sqlite.db.SupportSQLiteQuery
import com.philkes.notallyx.R
Expand Down Expand Up @@ -57,6 +58,10 @@ interface BaseNoteDao {
}

suspend fun insertSafe(context: ContextWrapper, baseNote: BaseNote): Long {
if (baseNote.sortIdx == null) {
val maxSortIdx = getMaxSortIdx() ?: 0
baseNote.sortIdx = maxSortIdx + 1
}
val (truncated, note) = baseNote.truncated()
if (truncated) {
context.log(
Expand All @@ -75,17 +80,19 @@ interface BaseNoteDao {
}

suspend fun insertSafe(context: ContextWrapper, baseNotes: List<BaseNote>): List<Long> {
val maxSortIdx = getMaxSortIdx() ?: 0
val truncatedNotes = mutableListOf<BaseNote>()
var truncatedCharacterSize = 0
val notes =
baseNotes.map { baseNote ->
val (truncated, note) = baseNote.truncated()
if (truncated) {
truncatedCharacterSize += baseNote.body.length
truncatedNotes.add(note)
}
note
baseNotes.forEachIndexed { index, baseNote ->
if (baseNote.sortIdx == null) {
baseNote.sortIdx = (maxSortIdx + 1 + index)
}
val (truncated, note) = baseNote.truncated()
if (truncated) {
truncatedCharacterSize += baseNote.body.length
truncatedNotes.add(note)
}
}
if (truncatedNotes.isNotEmpty()) {
context.log(
TAG,
Expand All @@ -99,7 +106,7 @@ interface BaseNoteDao {
)
)
}
return insert(notes)
return insert(baseNotes)
}

@Insert suspend fun insert(baseNotes: List<BaseNote>): List<Long>
Expand Down Expand Up @@ -244,6 +251,16 @@ interface BaseNoteDao {
*
* In this case, an exception will be thrown. It is the caller's responsibility to handle it.
*/
@Query("UPDATE BaseNote SET sortIdx = :sortIdx WHERE id = :id")
fun updateSortIdx(id: Long, sortIdx: Int)

@Transaction
fun updateSortIndices(idToIdx: Map<Long, Int>) {
idToIdx.forEach { (id, idx) -> updateSortIdx(id, idx) }
}

@Query("SELECT MAX(sortIdx) FROM BaseNote") fun getMaxSortIdx(): Int?

suspend fun updateChecked(id: Long, position: Int, checked: Boolean) {
val items =
requireNotNull(get(id), { "updateChecked: Note with id '$id' does not exist" }).items
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/com/philkes/notallyx/data/model/BaseNote.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import androidx.room.PrimaryKey
/** Format: `#RRGGBB` or `#AARRGGBB` or [BaseNote.COLOR_DEFAULT] */
typealias ColorString = String

@Entity(indices = [Index(value = ["id", "folder", "pinned", "timestamp", "labels"])])
@Entity(
indices =
[
Index(value = ["id", "folder", "pinned", "timestamp", "labels"]),
Index(value = ["sortIdx"]),
]
)
data class BaseNote(
@PrimaryKey(autoGenerate = true) val id: Long,
val type: Type,
Expand All @@ -26,6 +32,7 @@ data class BaseNote(
val audios: List<Audio>,
val reminders: List<Reminder>,
val viewMode: NoteViewMode,
var sortIdx: Int? = null,
) : Item {

companion object {
Expand Down Expand Up @@ -55,6 +62,7 @@ data class BaseNote(
if (audios != other.audios) return false
if (reminders != other.reminders) return false
if (viewMode != other.viewMode) return false
if (sortIdx != other.sortIdx) return false

return true
}
Expand All @@ -76,6 +84,7 @@ data class BaseNote(
result = 31 * result + audios.hashCode()
result = 31 * result + reminders.hashCode()
result = 31 * result + viewMode.hashCode()
result = 31 * result + (sortIdx ?: 0)
return result
}
}
Expand Down
Loading