chore(quality): resolve all detekt findings for v1.8.1 release
Changes:
- UpdateChangelogSheet.kt: Remove 3 unused imports (Intent, Uri, withStyle)
- NoteEditorScreen.kt: Extract DRAGGING_ELEVATION_DP and AUTO_SCROLL_DELAY_MS constants
- NoteEditorScreen.kt: Add @Suppress("LongParameterList") to DraggableChecklistItem
- NoteEditorViewModel.kt: Refactor loadNote() into loadExistingNote(), loadChecklistData(), initNewNote()
- NoteEditorViewModel.kt: Extract parseSortOption() utility for safe enum parsing
- NoteEditorViewModel.kt: Fix NestedBlockDepth and SwallowedException findings
- ChecklistPreviewHelper.kt: Suppress SwallowedException for intentional fallback
- NoteWidgetActions.kt: Suppress SwallowedException for intentional fallback
- NoteWidgetContent.kt: Suppress SwallowedException in ChecklistCompactView + ChecklistFullView
- SyncWorker.kt: Suppress LongMethod on doWork() (linear flow, debug logging)
- detekt.yml: Update maxIssues from 100 to 0, update version comment
All 12 detekt findings resolved. Build compiles clean, 0 lint errors.
This commit is contained in:
@@ -73,6 +73,7 @@ class SyncWorker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("LongMethod") // Linear sync flow with debug logging — splitting would hurt readability
|
||||||
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Logger.d(TAG, "═══════════════════════════════════════")
|
Logger.d(TAG, "═══════════════════════════════════════")
|
||||||
|
|||||||
@@ -66,8 +66,10 @@ import dev.dettmer.simplenotes.utils.showToast
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
private const val LAYOUT_DELAY_MS = 100L
|
private const val LAYOUT_DELAY_MS = 100L
|
||||||
|
private const val AUTO_SCROLL_DELAY_MS = 50L
|
||||||
private const val ITEM_CORNER_RADIUS_DP = 8
|
private const val ITEM_CORNER_RADIUS_DP = 8
|
||||||
private const val DRAGGING_ITEM_Z_INDEX = 10f
|
private const val DRAGGING_ITEM_Z_INDEX = 10f
|
||||||
|
private val DRAGGING_ELEVATION_DP = 8.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Composable for the Note Editor screen.
|
* Main Composable for the Note Editor screen.
|
||||||
@@ -327,6 +329,7 @@ private fun TextNoteContent(
|
|||||||
* 🆕 v1.8.1 IMPL_14: Extrahiertes Composable für ein einzelnes draggbares Checklist-Item.
|
* 🆕 v1.8.1 IMPL_14: Extrahiertes Composable für ein einzelnes draggbares Checklist-Item.
|
||||||
* Entkoppelt von der Separator-Logik — wiederverwendbar für unchecked und checked Items.
|
* Entkoppelt von der Separator-Logik — wiederverwendbar für unchecked und checked Items.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("LongParameterList") // Compose callbacks — cannot be reduced without wrapper class
|
||||||
@Composable
|
@Composable
|
||||||
private fun LazyItemScope.DraggableChecklistItem(
|
private fun LazyItemScope.DraggableChecklistItem(
|
||||||
item: ChecklistItemState,
|
item: ChecklistItemState,
|
||||||
@@ -342,7 +345,7 @@ private fun LazyItemScope.DraggableChecklistItem(
|
|||||||
) {
|
) {
|
||||||
val isDragging = dragDropState.draggingItemIndex == visualIndex
|
val isDragging = dragDropState.draggingItemIndex == visualIndex
|
||||||
val elevation by animateDpAsState(
|
val elevation by animateDpAsState(
|
||||||
targetValue = if (isDragging) 8.dp else 0.dp,
|
targetValue = if (isDragging) DRAGGING_ELEVATION_DP else 0.dp,
|
||||||
label = "elevation"
|
label = "elevation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -426,7 +429,7 @@ private fun ChecklistEditor(
|
|||||||
// 🆕 v1.8.1 (IMPL_05): Auto-Scroll wenn ein Item durch Zeilenumbruch wächst
|
// 🆕 v1.8.1 (IMPL_05): Auto-Scroll wenn ein Item durch Zeilenumbruch wächst
|
||||||
LaunchedEffect(scrollToItemIndex) {
|
LaunchedEffect(scrollToItemIndex) {
|
||||||
scrollToItemIndex?.let { index ->
|
scrollToItemIndex?.let { index ->
|
||||||
delay(50) // Warten bis Layout-Pass abgeschlossen
|
delay(AUTO_SCROLL_DELAY_MS) // Warten bis Layout-Pass abgeschlossen
|
||||||
val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
|
val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
|
||||||
if (index >= lastVisibleIndex - 1) {
|
if (index >= lastVisibleIndex - 1) {
|
||||||
listState.animateScrollToItem(
|
listState.animateScrollToItem(
|
||||||
|
|||||||
@@ -91,7 +91,13 @@ class NoteEditorViewModel(
|
|||||||
val noteTypeString = savedStateHandle.get<String>(ARG_NOTE_TYPE) ?: NoteType.TEXT.name
|
val noteTypeString = savedStateHandle.get<String>(ARG_NOTE_TYPE) ?: NoteType.TEXT.name
|
||||||
|
|
||||||
if (noteId != null) {
|
if (noteId != null) {
|
||||||
// Load existing note
|
loadExistingNote(noteId)
|
||||||
|
} else {
|
||||||
|
initNewNote(noteTypeString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadExistingNote(noteId: String) {
|
||||||
existingNote = storage.loadNote(noteId)
|
existingNote = storage.loadNote(noteId)
|
||||||
existingNote?.let { note ->
|
existingNote?.let { note ->
|
||||||
currentNoteType = note.noteType
|
currentNoteType = note.noteType
|
||||||
@@ -110,14 +116,15 @@ class NoteEditorViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (note.noteType == NoteType.CHECKLIST) {
|
if (note.noteType == NoteType.CHECKLIST) {
|
||||||
|
loadChecklistData(note)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadChecklistData(note: Note) {
|
||||||
// 🆕 v1.8.1 (IMPL_03): Gespeicherte Sortierung laden
|
// 🆕 v1.8.1 (IMPL_03): Gespeicherte Sortierung laden
|
||||||
note.checklistSortOption?.let { sortName ->
|
note.checklistSortOption?.let { sortName ->
|
||||||
try {
|
_lastChecklistSortOption.value = parseSortOption(sortName)
|
||||||
_lastChecklistSortOption.value = ChecklistSortOption.valueOf(sortName)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
Logger.w(TAG, "Unknown sort option '$sortName', using MANUAL")
|
|
||||||
_lastChecklistSortOption.value = ChecklistSortOption.MANUAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val items = note.checklistItems?.sortedBy { it.order }?.map {
|
val items = note.checklistItems?.sortedBy { it.order }?.map {
|
||||||
@@ -131,13 +138,12 @@ class NoteEditorViewModel(
|
|||||||
// 🆕 v1.8.0 (IMPL_017): Sortierung sicherstellen (falls alte Daten unsortiert sind)
|
// 🆕 v1.8.0 (IMPL_017): Sortierung sicherstellen (falls alte Daten unsortiert sind)
|
||||||
_checklistItems.value = sortChecklistItems(items)
|
_checklistItems.value = sortChecklistItems(items)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
private fun initNewNote(noteTypeString: String) {
|
||||||
// New note
|
|
||||||
currentNoteType = try {
|
currentNoteType = try {
|
||||||
NoteType.valueOf(noteTypeString)
|
NoteType.valueOf(noteTypeString)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) {
|
||||||
Logger.w(TAG, "Invalid note type '$noteTypeString', defaulting to TEXT: ${e.message}")
|
Logger.w(TAG, "Invalid note type '$noteTypeString', defaulting to TEXT")
|
||||||
NoteType.TEXT
|
NoteType.TEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +164,18 @@ class NoteEditorViewModel(
|
|||||||
_checklistItems.value = listOf(ChecklistItemState.createEmpty(0))
|
_checklistItems.value = listOf(ChecklistItemState.createEmpty(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely parse a ChecklistSortOption from its string name.
|
||||||
|
* Falls back to MANUAL if the name is unknown (e.g., from older app versions).
|
||||||
|
*/
|
||||||
|
private fun parseSortOption(sortName: String): ChecklistSortOption {
|
||||||
|
return try {
|
||||||
|
ChecklistSortOption.valueOf(sortName)
|
||||||
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) {
|
||||||
|
Logger.w(TAG, "Unknown sort option '$sortName', using MANUAL")
|
||||||
|
ChecklistSortOption.MANUAL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package dev.dettmer.simplenotes.ui.main
|
package dev.dettmer.simplenotes.ui.main
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,7 +30,6 @@ import androidx.compose.ui.text.buildAnnotatedString
|
|||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextDecoration
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
import androidx.compose.ui.text.withLink
|
import androidx.compose.ui.text.withLink
|
||||||
import androidx.compose.ui.text.withStyle
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import dev.dettmer.simplenotes.BuildConfig
|
import dev.dettmer.simplenotes.BuildConfig
|
||||||
import dev.dettmer.simplenotes.R
|
import dev.dettmer.simplenotes.R
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fun sortChecklistItemsForPreview(
|
|||||||
): List<ChecklistItem> {
|
): List<ChecklistItem> {
|
||||||
val sortOption = try {
|
val sortOption = try {
|
||||||
sortOptionName?.let { ChecklistSortOption.valueOf(it) }
|
sortOptionName?.let { ChecklistSortOption.valueOf(it) }
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) {
|
||||||
null
|
null
|
||||||
} ?: ChecklistSortOption.MANUAL
|
} ?: ChecklistSortOption.MANUAL
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class ToggleChecklistItemAction : ActionCallback {
|
|||||||
// Konsistent mit NoteEditorViewModel.updateChecklistItemChecked
|
// Konsistent mit NoteEditorViewModel.updateChecklistItemChecked
|
||||||
val sortOption = try {
|
val sortOption = try {
|
||||||
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
||||||
} catch (e: IllegalArgumentException) { null }
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) { null }
|
||||||
?: ChecklistSortOption.MANUAL
|
?: ChecklistSortOption.MANUAL
|
||||||
|
|
||||||
val sortedItems = if (sortOption == ChecklistSortOption.MANUAL ||
|
val sortedItems = if (sortOption == ChecklistSortOption.MANUAL ||
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ private fun ChecklistCompactView(
|
|||||||
val checkedCount = items.count { it.isChecked }
|
val checkedCount = items.count { it.isChecked }
|
||||||
val sortOption = try {
|
val sortOption = try {
|
||||||
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
||||||
} catch (e: IllegalArgumentException) { null }
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) { null }
|
||||||
?: ChecklistSortOption.MANUAL
|
?: ChecklistSortOption.MANUAL
|
||||||
|
|
||||||
val showSeparator = (sortOption == ChecklistSortOption.MANUAL ||
|
val showSeparator = (sortOption == ChecklistSortOption.MANUAL ||
|
||||||
@@ -534,7 +534,7 @@ private fun ChecklistFullView(
|
|||||||
val checkedCount = items.count { it.isChecked }
|
val checkedCount = items.count { it.isChecked }
|
||||||
val sortOption = try {
|
val sortOption = try {
|
||||||
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
note.checklistSortOption?.let { ChecklistSortOption.valueOf(it) }
|
||||||
} catch (e: IllegalArgumentException) { null }
|
} catch (@Suppress("SwallowedException") e: IllegalArgumentException) { null }
|
||||||
?: ChecklistSortOption.MANUAL
|
?: ChecklistSortOption.MANUAL
|
||||||
|
|
||||||
val showSeparator = (sortOption == ChecklistSortOption.MANUAL ||
|
val showSeparator = (sortOption == ChecklistSortOption.MANUAL ||
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# ⚡ v1.3.1: detekt Configuration
|
# ⚡ v1.8.1: detekt Configuration
|
||||||
# Pragmatic rules for simple-notes-sync
|
# Pragmatic rules for simple-notes-sync
|
||||||
|
|
||||||
build:
|
build:
|
||||||
maxIssues: 100 # Allow existing issues for v1.3.1 release, fix in v1.4.0
|
maxIssues: 0 # v1.8.1: All issues resolved
|
||||||
excludeCorrectable: false
|
excludeCorrectable: false
|
||||||
|
|
||||||
config:
|
config:
|
||||||
|
|||||||
Reference in New Issue
Block a user