From e2548f82b238be41d0d05e1ca3eac3452aebc61f Mon Sep 17 00:00:00 2001 From: maltaisn Date: Mon, 6 Sep 2021 15:02:30 -0400 Subject: [PATCH] Version bump, detekt fixes --- app/build.gradle | 4 +- .../maltaisn/notes/screenshot/Screenshots.kt | 4 +- .../maltaisn/notes/model/BadDataException.kt | 2 +- .../notes/model/DefaultJsonManager.kt | 33 +++++--- .../com/maltaisn/notes/model/SortSettings.kt | 2 +- .../com/maltaisn/notes/model/ValueEnum.kt | 2 +- .../notes/ui/labels/LabelEditViewModel.kt | 4 +- .../notes/ui/labels/LabelViewModel.kt | 8 +- .../com/maltaisn/notes/ui/note/Highlighted.kt | 2 +- .../maltaisn/notes/ui/note/NoteItemFactory.kt | 84 ++++++++++--------- .../ui/notification/NotificationViewModel.kt | 4 +- .../notes/ui/reminder/ReminderViewModel.kt | 4 +- .../play/release-notes/en-US/production.txt | 5 +- .../play/release-notes/fr-CA/production.txt | 5 +- .../maltaisn/notes/ui/MockAlarmCallback.kt | 2 +- .../notes/utils/RelativeDateFormatterTest.kt | 2 +- build.gradle | 4 +- config/detekt/detekt.yml | 1 + gradle.properties | 4 +- 19 files changed, 98 insertions(+), 78 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4bd9b53e..07fe19c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,8 +27,8 @@ android { applicationId "com.maltaisn.notes.sync" minSdkVersion 21 targetSdkVersion 30 - versionCode 10400 - versionName "1.4.0" + versionCode 10401 + versionName "1.4.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" kapt { diff --git a/app/src/androidTest/kotlin/com/maltaisn/notes/screenshot/Screenshots.kt b/app/src/androidTest/kotlin/com/maltaisn/notes/screenshot/Screenshots.kt index b5776c9f..1bc17d57 100644 --- a/app/src/androidTest/kotlin/com/maltaisn/notes/screenshot/Screenshots.kt +++ b/app/src/androidTest/kotlin/com/maltaisn/notes/screenshot/Screenshots.kt @@ -122,7 +122,7 @@ class Screenshots { )) onView(allOf(isDescendantOfA(withId(R.id.fragment_note_layout)), withId(R.id.recycler_view))) - .perform(actionOnItemAtPosition(0, click())) + .perform(actionOnItemAtPosition>(0, click())) delay(250) onView(allOf(isDescendantOfA(withId(R.id.fragment_edit_layout)), withId(R.id.recycler_view))) .perform(actionOnItemAtPosition(3, click())) @@ -180,7 +180,7 @@ class Screenshots { )) onView(allOf(isDescendantOfA(withId(R.id.fragment_note_layout)), withId(R.id.recycler_view))) - .perform(actionOnItemAtPosition(1, longClick())) + .perform(actionOnItemAtPosition>(1, longClick())) delay(250) onView(toolbarItem(R.id.item_reminder)).perform(click()) diff --git a/app/src/main/kotlin/com/maltaisn/notes/model/BadDataException.kt b/app/src/main/kotlin/com/maltaisn/notes/model/BadDataException.kt index 5407b0f7..b044ddcb 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/model/BadDataException.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/model/BadDataException.kt @@ -22,4 +22,4 @@ package com.maltaisn.notes.model * This is used to catch forward compatibility fails. */ class BadDataException(message: String = "", cause: Throwable? = null) - : IllegalStateException(message, cause) \ No newline at end of file + : IllegalStateException(message, cause) diff --git a/app/src/main/kotlin/com/maltaisn/notes/model/DefaultJsonManager.kt b/app/src/main/kotlin/com/maltaisn/notes/model/DefaultJsonManager.kt index 2dbc7dc8..3bdb3a5f 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/model/DefaultJsonManager.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/model/DefaultJsonManager.kt @@ -88,7 +88,22 @@ class DefaultJsonManager @Inject constructor( return ImportResult.BAD_DATA } - // Add labels + // Import all data + val newLabelsMap = importLabels(notesData) + importNotes(notesData, newLabelsMap) + + // Update all reminders + reminderAlarmManager.updateAllAlarms() + + return if (notesData.version > VERSION) { + // data comes from future version of app + ImportResult.FUTURE_VERSION + } else { + ImportResult.SUCCESS + } + } + + private suspend fun importLabels(notesData: NotesData): Map { val existingLabels = labelsDao.getAll() val existingLabelsIdMap = existingLabels.associateBy { it.id } val existingLabelsNameMap = existingLabels.associateBy { it.name } @@ -120,8 +135,10 @@ class DefaultJsonManager @Inject constructor( newLabelsMap[id] = labelsDao.insert(Label(id, labelName)) } } + return newLabelsMap + } - // Add notes + private suspend fun importNotes(notesData: NotesData, newLabelsMap: Map) { val existingNotes = notesDao.getAll().asSequence().map { it.note }.associateBy { it.id } val labelRefs = mutableListOf() for ((id, ns) in notesData.notes) { @@ -150,16 +167,6 @@ class DefaultJsonManager @Inject constructor( } } labelsDao.insertRefs(labelRefs) - - // Update all reminders - reminderAlarmManager.updateAllAlarms() - - return if (notesData.version > VERSION) { - // data comes from future version of app - ImportResult.FUTURE_VERSION - } else { - ImportResult.SUCCESS - } } enum class ImportResult { @@ -180,7 +187,7 @@ class DefaultJsonManager @Inject constructor( * adding [labels] to store label references. */ @Serializable -private class NoteSurrogate( +private data class NoteSurrogate( @SerialName("type") val type: NoteType, @SerialName("title") diff --git a/app/src/main/kotlin/com/maltaisn/notes/model/SortSettings.kt b/app/src/main/kotlin/com/maltaisn/notes/model/SortSettings.kt index 10e07528..0e724751 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/model/SortSettings.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/model/SortSettings.kt @@ -27,4 +27,4 @@ enum class SortField(override val value: String) : ValueEnum { enum class SortDirection(override val value: String) : ValueEnum { ASCENDING("ascending"), DESCENDING("descending"), -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/maltaisn/notes/model/ValueEnum.kt b/app/src/main/kotlin/com/maltaisn/notes/model/ValueEnum.kt index 7602fe10..e11fa19f 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/model/ValueEnum.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/model/ValueEnum.kt @@ -22,4 +22,4 @@ package com.maltaisn.notes.model */ interface ValueEnum { val value: T -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelEditViewModel.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelEditViewModel.kt index bdde26d2..324a3614 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelEditViewModel.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelEditViewModel.kt @@ -129,7 +129,7 @@ class LabelEditViewModel @AssistedInject constructor( } companion object { - private val KEY_NAME = "name" - private val KEY_HIDDEN = "hidden" + private const val KEY_NAME = "name" + private const val KEY_HIDDEN = "hidden" } } diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelViewModel.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelViewModel.kt index d5cce05b..07223b63 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelViewModel.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/labels/LabelViewModel.kt @@ -223,10 +223,10 @@ class LabelViewModel @AssistedInject constructor( /** Set the selected state of all notes to [selected]. */ private fun setAllSelected(selected: Boolean) { - if (!selected && selectedLabels.isEmpty() || - selected && selectedLabels.size == listItems.size - ) { - // Already all unselected or all selected. + val allSelected = selected && selectedLabels.size == listItems.size + val allUnselected = !selected && selectedLabels.isEmpty() + if (allSelected || allUnselected) { + // No changes needed. return } diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/note/Highlighted.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/note/Highlighted.kt index 643f755d..aebf8358 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/note/Highlighted.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/note/Highlighted.kt @@ -22,4 +22,4 @@ package com.maltaisn.notes.ui.note data class Highlighted( val content: String, val highlights: List = emptyList() -) \ No newline at end of file +) diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/note/NoteItemFactory.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/note/NoteItemFactory.kt index 449c8493..4c3fd09f 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/note/NoteItemFactory.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/note/NoteItemFactory.kt @@ -18,6 +18,7 @@ package com.maltaisn.notes.ui.note import com.maltaisn.notes.model.PrefsManager import com.maltaisn.notes.model.entity.Label +import com.maltaisn.notes.model.entity.ListNoteItem import com.maltaisn.notes.model.entity.Note import com.maltaisn.notes.model.entity.NoteType import com.maltaisn.notes.ui.note.adapter.NoteItemList @@ -94,43 +95,8 @@ class NoteItemFactory @Inject constructor( items.sortBy { it.checked } } - val highlights = if (query == null) { - mutableListOf() - } else { - var maxHighlights = MAX_HIGHLIGHTS_IN_LIST - items.mapTo(mutableListOf()) { - val ranges = HighlightHelper.findHighlightsInString(it.content, query!!, - minOf(maxHighlights, MAX_HIGHLIGHTS_IN_LIST_ITEM)) - maxHighlights -= ranges.size - ranges - } - } - - val maxItemsCount = prefs.getMaximumPreviewLines(NoteType.LIST) - val itemsCount = minOf(maxItemsCount, if (prefs.moveCheckedToBottom) { - var count = items.indexOfFirst { it.checked } - if (count == -1) { - count = items.size - } - if (query != null) { - // Show checked items with highlights as well - val checkedHighlighed = items.foldIndexed(0) { i, c, item -> - if (highlights[i].isNotEmpty() && item.checked) { - c + 1 - } else { - c - } - } - count += checkedHighlighed - } - if (MINIMUM_LIST_NOTE_ITEMS in count until maxItemsCount) { - // Less than minimum unchecked items, add checked items. - count = minOf(items.size, MINIMUM_LIST_NOTE_ITEMS) - } - count - } else { - items.size - }) + val highlights = getListItemHighlights(items) + val itemsCount = getListItemCount(items, highlights) var onlyCheckedInOverflow = true if (query != null) { @@ -176,6 +142,48 @@ class NoteItemFactory @Inject constructor( itemsChecked, overflowCount, onlyCheckedInOverflow, showMarkAsDone) } + private fun getListItemCount(items: List, highlights: List>): Int { + val maxItemsCount = prefs.getMaximumPreviewLines(NoteType.LIST) + return minOf(maxItemsCount, if (prefs.moveCheckedToBottom) { + var count = items.indexOfFirst { it.checked } + if (count == -1) { + count = items.size + } + if (query != null) { + // Show checked items with highlights as well + val checkedHighlighed = items.foldIndexed(0) { i, c, item -> + if (highlights[i].isNotEmpty() && item.checked) { + c + 1 + } else { + c + } + } + count += checkedHighlighed + } + if (MINIMUM_LIST_NOTE_ITEMS in count until maxItemsCount) { + // Less than minimum unchecked items, add checked items. + count = minOf(items.size, MINIMUM_LIST_NOTE_ITEMS) + } + count + } else { + items.size + }) + } + + private fun getListItemHighlights(items: List): MutableList> { + return if (query == null) { + mutableListOf() + } else { + var maxHighlights = MAX_HIGHLIGHTS_IN_LIST + items.mapTo(mutableListOf()) { + val ranges = HighlightHelper.findHighlightsInString(it.content, query!!, + minOf(maxHighlights, MAX_HIGHLIGHTS_IN_LIST_ITEM)) + maxHighlights -= ranges.size + ranges + } + } + } + private fun createTitle(note: Note): Highlighted { var title = note.title.trim() if (appendIdToTitle) { @@ -219,4 +227,4 @@ class NoteItemFactory @Inject constructor( private const val START_ELLIPSIS_THRESHOLD_CONTENT_FIRST = 5 // for first line of preview private const val START_ELLIPSIS_DISTANCE_CONTENT = 20 } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/notification/NotificationViewModel.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/notification/NotificationViewModel.kt index cbb030c5..02425557 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/notification/NotificationViewModel.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/notification/NotificationViewModel.kt @@ -98,7 +98,7 @@ class NotificationViewModel @AssistedInject constructor( // Open time dialog next viewModelScope.launch { // TODO thats ugly - delay(250) + delay(INTER_DIALOG_DELAY) _showTimeDialogEvent.send(postponeTime) } } @@ -139,6 +139,8 @@ class NotificationViewModel @AssistedInject constructor( } companion object { + private const val INTER_DIALOG_DELAY = 250L + private const val KEY_NOTE_ID = "note_id" private const val KEY_POSTPONE_TIME = "postpone_time" } diff --git a/app/src/main/kotlin/com/maltaisn/notes/ui/reminder/ReminderViewModel.kt b/app/src/main/kotlin/com/maltaisn/notes/ui/reminder/ReminderViewModel.kt index 99d453cc..a35da63e 100644 --- a/app/src/main/kotlin/com/maltaisn/notes/ui/reminder/ReminderViewModel.kt +++ b/app/src/main/kotlin/com/maltaisn/notes/ui/reminder/ReminderViewModel.kt @@ -137,7 +137,7 @@ class ReminderViewModel @AssistedInject constructor( val currHour = calendar[Calendar.HOUR_OF_DAY] val todayReminderHour = DEFAULT_REMINDER_HOURS.find { it > currHour + REMINDER_HOUR_MIN_DISTANCE } calendar[Calendar.HOUR_OF_DAY] = todayReminderHour ?: - DEFAULT_REMINDER_HOURS.first { it > currHour + REMINDER_HOUR_MIN_DISTANCE - 24 } + DEFAULT_REMINDER_HOURS.first { it > currHour + REMINDER_HOUR_MIN_DISTANCE - HOURS_IN_DAY } calendar[Calendar.MINUTE] = 0 calendar[Calendar.SECOND] = 0 calendar[Calendar.MILLISECOND] = 0 @@ -336,6 +336,8 @@ class ReminderViewModel @AssistedInject constructor( private val DEFAULT_REMINDER_HOURS = listOf(8, 13, 18, 20) private const val REMINDER_HOUR_MIN_DISTANCE = 3 + private const val HOURS_IN_DAY = 24 + private const val KEY_DATE = "date" private const val KEY_RECURRENCE = "recurrence" private const val KEY_NOTE_IDS = "note_ids" diff --git a/app/src/main/play/release-notes/en-US/production.txt b/app/src/main/play/release-notes/en-US/production.txt index 1c16e82c..4bdc524c 100644 --- a/app/src/main/play/release-notes/en-US/production.txt +++ b/app/src/main/play/release-notes/en-US/production.txt @@ -1,4 +1,3 @@ -- Added ability to hide all notes with a particular label. -- Added clickable links to edit screen. -- New Spanish translation. +- Added sorting options. +- Show more highlights in search screen. - Many bug fixes. \ No newline at end of file diff --git a/app/src/main/play/release-notes/fr-CA/production.txt b/app/src/main/play/release-notes/fr-CA/production.txt index fbe58a0e..5799946c 100644 --- a/app/src/main/play/release-notes/fr-CA/production.txt +++ b/app/src/main/play/release-notes/fr-CA/production.txt @@ -1,4 +1,3 @@ -- Ajout d'une fonctionnalité pour cacher les notes ayant une étiquette en particulier. -- Ajout de liens cliquables lors de l'édition. -- Nouvelle traduction en espagnol. +- Ajout d'options de tri. +- Plus de résultats surlignés dans la recherche. - Plusieurs bugs corrigés. diff --git a/app/src/test/kotlin/com/maltaisn/notes/ui/MockAlarmCallback.kt b/app/src/test/kotlin/com/maltaisn/notes/ui/MockAlarmCallback.kt index f8069028..58e4cf4c 100644 --- a/app/src/test/kotlin/com/maltaisn/notes/ui/MockAlarmCallback.kt +++ b/app/src/test/kotlin/com/maltaisn/notes/ui/MockAlarmCallback.kt @@ -30,4 +30,4 @@ class MockAlarmCallback : ReminderAlarmCallback { alarms -= noteId } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/maltaisn/notes/utils/RelativeDateFormatterTest.kt b/app/src/test/kotlin/com/maltaisn/notes/utils/RelativeDateFormatterTest.kt index efa43ad9..88f31c32 100644 --- a/app/src/test/kotlin/com/maltaisn/notes/utils/RelativeDateFormatterTest.kt +++ b/app/src/test/kotlin/com/maltaisn/notes/utils/RelativeDateFormatterTest.kt @@ -120,4 +120,4 @@ class RelativeDateFormatterTest { )) } -} \ No newline at end of file +} diff --git a/build.gradle b/build.gradle index 798e3ab1..a9a76cfa 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,8 @@ buildscript { repositories { google() + mavenCentral() + gradlePluginPortal() } dependencies { classpath "com.android.tools.build:gradle:$androidGradlePluginVersion" @@ -16,7 +18,7 @@ buildscript { plugins { id "base" - id "io.gitlab.arturbosch.detekt" version "1.16.0" + id "io.gitlab.arturbosch.detekt" version "1.18.1" } diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 02eb1cf3..b93711fb 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -94,6 +94,7 @@ complexity: LargeClass: active: true threshold: 600 + excludes: ['**/test/**', '**/androidTest/**', '**/sharedTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] LongMethod: active: true threshold: 60 diff --git a/gradle.properties b/gradle.properties index a120f6a3..6da7e3a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ # App version # Must be updated manually in app/build.gradle! # (F-Droid only supports raw literals for auto update detection) -appVersion=1.4.0 -appVersionCode=10400 +appVersion=1.4.1 +appVersionCode=10401 # Kotlin kotlinVersion=1.5.30