Skip to content

Commit f2e1495

Browse files
committed
Merge branch 'fix/limit-note-size'
# Conflicts: # app/src/main/java/com/philkes/notallyx/data/dao/CommonDao.kt # app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt # app/src/main/java/com/philkes/notallyx/utils/DataSchemaMigrations.kt # app/translations.xlsx
2 parents 36a67bd + 2f4fb2f commit f2e1495

10 files changed

Lines changed: 47 additions & 50 deletions

File tree

app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import com.philkes.notallyx.data.model.LabelsInBaseNote
1919
import com.philkes.notallyx.data.model.ListItem
2020
import com.philkes.notallyx.data.model.Reminder
2121
import com.philkes.notallyx.data.model.Type
22+
import com.philkes.notallyx.presentation.getQuantityString
2223
import com.philkes.notallyx.presentation.showToast
2324
import com.philkes.notallyx.utils.charLimit
2425
import com.philkes.notallyx.utils.log
25-
import kotlin.text.compareTo
2626

2727
data class NoteIdReminder(val id: Long, val reminders: List<Reminder>)
2828

@@ -45,7 +45,13 @@ interface BaseNoteDao {
4545

4646
private fun BaseNote.truncated(): Pair<Boolean, BaseNote> {
4747
return if (body.length > MAX_BODY_CHAR_LENGTH) {
48-
return Pair(true, copy(body = body.take(MAX_BODY_CHAR_LENGTH)))
48+
return Pair(
49+
true,
50+
copy(
51+
body = body.take(MAX_BODY_CHAR_LENGTH),
52+
spans = spans.filter { it.isInsideBounds() },
53+
),
54+
)
4955
} else Pair(false, this)
5056
}
5157

@@ -79,17 +85,19 @@ interface BaseNoteDao {
7985
}
8086
note
8187
}
82-
context.log(
83-
TAG,
84-
"${truncatedNotes.size} Notes are too big to save, they were truncated to $truncatedCharacterSize characters",
85-
)
86-
context.showToast(
87-
context.getString(
88-
R.string.notes_too_big_truncating,
89-
truncatedNotes.size,
90-
truncatedCharacterSize,
88+
if (truncatedNotes.isNotEmpty()) {
89+
context.log(
90+
TAG,
91+
"${truncatedNotes.size} Notes are too big to save, they were truncated to $truncatedCharacterSize characters",
9192
)
92-
)
93+
context.showToast(
94+
context.getQuantityString(
95+
R.plurals.notes_too_big_truncating,
96+
truncatedNotes.size,
97+
truncatedCharacterSize,
98+
)
99+
)
100+
}
93101
return insert(notes)
94102
}
95103

app/src/main/java/com/philkes/notallyx/data/dao/CommonDao.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.philkes.notallyx.data.dao
22

3-
import android.content.ContextWrapper
43
import androidx.room.Dao
54
import androidx.room.Transaction
65
import com.philkes.notallyx.data.NotallyDatabase
@@ -45,11 +44,7 @@ abstract class CommonDao(private val database: NotallyDatabase) {
4544
}
4645

4746
@Transaction
48-
open suspend fun importBackup(
49-
context: ContextWrapper,
50-
baseNotes: List<BaseNote>,
51-
labels: List<Label>,
52-
) {
47+
open suspend fun importBackup(baseNotes: List<BaseNote>, labels: List<Label>) {
5348
val dao = database.getBaseNoteDao()
5449
// Insert notes, splitting oversized text notes instead of truncating
5550
baseNotes.forEach { note ->

app/src/main/java/com/philkes/notallyx/data/model/SpanRepresentation.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.philkes.notallyx.data.model
22

3+
import com.philkes.notallyx.data.dao.BaseNoteDao.Companion.MAX_BODY_CHAR_LENGTH
4+
35
data class SpanRepresentation(
46
var start: Int,
57
var end: Int,
@@ -18,4 +20,6 @@ data class SpanRepresentation(
1820
fun isEqualInSize(representation: SpanRepresentation): Boolean {
1921
return start == representation.start && end == representation.end
2022
}
23+
24+
fun isInsideBounds(): Boolean = start < MAX_BODY_CHAR_LENGTH && end <= MAX_BODY_CHAR_LENGTH
2125
}

app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ class MainActivity : LockedActivity<ActivityMainBinding>() {
141141
navigateToStartView()
142142
}
143143
}
144-
preferences.setDataSchemaId(1)
145144
if (preferences.dataSchemaId.value < LATEST_DATA_SCHEMA) {
146145
val migrationProgress = MutableLiveData<MigrationProgress>()
147146
migrationProgress.setupProgressDialog(this)

app/src/main/java/com/philkes/notallyx/presentation/viewmodel/BaseNoteModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) {
422422
{ "InputStream for '$uri' is null" },
423423
)
424424
val (baseNotes, labels) = stream.readAsBackup()
425-
commonDao.importBackup(app, baseNotes, labels)
425+
commonDao.importBackup(baseNotes, labels)
426426
baseNotes.size
427427
}
428428
val message = app.getQuantityString(R.plurals.imported_notes, importedNotes)

app/src/main/java/com/philkes/notallyx/utils/DataSchemaMigrations.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ suspend fun Application.runMigrations(onProgressTitle: (Int) -> Unit = {}): Bool
3535
}
3636
if (newDataSchemaId < 2) {
3737
onProgressTitle(com.philkes.notallyx.R.string.migration_splitting_notes)
38-
splitOversizedNotes(preferences)
38+
splitOversizedNotes()
3939
newDataSchemaId = 2
4040
didWork = true
4141
}
@@ -61,8 +61,11 @@ private fun Application.moveAttachments(preferences: NotallyXPreferences) {
6161
* end of each truncated note that points to the next note. The link text is included in the body
6262
* and must also fit within the size limit.
6363
*/
64-
private suspend fun Application.splitOversizedNotes(preferences: NotallyXPreferences) {
65-
log(TAG, "Running migration 2: Splitting notes exceeding the body size limit")
64+
private suspend fun Application.splitOversizedNotes() {
65+
log(
66+
TAG,
67+
"Running migration 2: Splitting notes exceeding the body size limit (limit: $MAX_BODY_CHAR_LENGTH characters)",
68+
)
6669

6770
// Obtain a direct DB instance matching current storage location
6871
val db = NotallyDatabase.getDatabase(this as ContextWrapper, false).value
@@ -78,6 +81,11 @@ private suspend fun Application.splitOversizedNotes(preferences: NotallyXPrefere
7881
dao.get(id)
7982
} catch (e: SQLiteBlobTooBigException) {
8083
// Repair the single offending row, then retry
84+
log(
85+
TAG,
86+
"Note (id: $id) threw SQLiteBlobTooBigException since body is too large to load. Repairing...",
87+
e,
88+
)
8189
repaired += 1
8290
truncateBodyAndFixSpans(dao, id)
8391
dao.get(id)
@@ -91,7 +99,7 @@ private suspend fun Application.splitOversizedNotes(preferences: NotallyXPrefere
9199
val created = splitOversizedExistingNoteForMigration(original, dao)
92100
log(
93101
TAG,
94-
"Note (id: ${original.id}, title: '${original.title}') split into ${created+1} notes",
102+
"Note (id: ${original.id}, title: '${original.title}') split into ${created+1} notes (was: $bodyLen characters).",
95103
)
96104
}
97105

app/src/main/java/com/philkes/notallyx/utils/MiscExtensions.kt

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,7 @@ fun CharSequence?.findWebUrls(): Collection<Pair<Int, Int>> {
4444
} ?: listOf()
4545
}
4646

47-
fun String.truncateToMb(mb: Double): String {
48-
val maxBytes = (mb * 1024 * 1024).toInt()
49-
val bytes = this.toByteArray(Charsets.UTF_8)
50-
51-
if (bytes.size <= maxBytes) return this
52-
53-
// Take only the allowed bytes
54-
val truncatedBytes = bytes.sliceArray(0 until maxBytes)
55-
56-
// Converting back to String handles partial UTF-8 characters
57-
// by using the default replacement behavior.
58-
return String(truncatedBytes, Charsets.UTF_8)
59-
}
60-
61-
/**
62-
* Calculates the character limit for a given MB size.
63-
* * @param mb The size limit in Megabytes (e.g., 1.5)
64-
*
65-
* @return A Pair where: first = Minimum characters guaranteed (worst-case: 4 bytes/char) second =
66-
* Maximum characters possible (best-case: 1 byte/char)
67-
*/
47+
/** Calculates the character limit for a given MB size (in worst case). */
6848
fun Double.charLimit(): Int {
6949
val totalBytes = (this * 1024 * 1024).toInt()
7050
val minChars = totalBytes / 4 // Every character is an Emoji/Complex

app/src/main/java/com/philkes/notallyx/utils/backup/ImportExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ private fun Cursor.toBaseNote(sourceDb: SQLiteDatabase): BaseNote {
299299
val folder = Folder.valueOfOrDefault(folderTmp)
300300

301301
val labels = Converters.jsonToLabels(labelsTmp)
302-
val spans = Converters.jsonToSpans(spansTmp)
302+
val spans = Converters.jsonToSpans(spansTmp).filter { it.isInsideBounds() }
303303
val items = Converters.jsonToItems(itemsTmp)
304304

305305
val imagesIndex = getColumnIndex("images")

app/src/main/res/values/strings.xml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@
5454
<string name="biometrics_setup_success">Biometric/PIN lock has been enabled</string>
5555
<string name="bold">Bold</string>
5656
<string name="calculating">Calculating…</string>
57-
<string name="migrating_data">Migrating data…</string>
58-
<string name="migration_moving_attachments">Moving attachments…</string>
59-
<string name="migration_splitting_notes">Splitting oversized notes…</string>
6057
<string name="cancel">Cancel</string>
6158
<plurals name="cant_add_files">
6259
<item quantity="one">Can’t add %1$d file</item>
@@ -233,6 +230,9 @@
233230
<string name="max_lines_to_display">Max lines to display in note</string>
234231
<string name="max_lines_to_display_title">Max lines to display in title</string>
235232
<string name="medium">Medium</string>
233+
<string name="migrating_data">Migrating data…</string>
234+
<string name="migration_moving_attachments">Moving attachments…</string>
235+
<string name="migration_splitting_notes">Splitting oversized notes…</string>
236236
<string name="minutes">Minutes</string>
237237
<string name="modified_date">Modified</string>
238238
<string name="monospace">Monospace</string>
@@ -253,7 +253,10 @@
253253
<string name="note_too_big_truncating">Note is too big to save, it was truncated to %1$s characters (was: %2$s)</string>
254254
<string name="notes">Notes</string>
255255
<string name="notes_sorted_by">Notes sorted by</string>
256-
<string name="notes_too_big_truncating">%1$s Note are too big to save, they were truncated to %2$s characters</string>
256+
<plurals name="notes_too_big_truncating">
257+
<item quantity="one">%1$s Note is too big to save, it was truncated to %2$s characters</item>
258+
<item quantity="other">%1$s Notes are too big to save, they were truncated to %2$s characters</item>
259+
</plurals>
257260
<string name="open_link">Open link</string>
258261
<string name="open_note">Open Note</string>
259262
<string name="others">Others</string>

app/translations.xlsx

1.83 KB
Binary file not shown.

0 commit comments

Comments
 (0)