1
0
mirror of https://github.com/avinal/nikki.git synced 2026-07-04 14:00:08 +05:30
Files
nikki/composeApp/build.gradle.kts
T
avinal e165be9f6c Add task notifications, JSON backup, and comprehensive test suite
Notifications:
- TaskCheckWorker (WorkManager, 15-min periodic) scans cached memos for
  tasks due today or overdue, fires Android notifications
- TaskNotificationManager: notification channel, tap-to-open intent
- Notification deduplication via SharedPreferences (notified task IDs)
- Toggle in settings (on/off persisted in DataStore)
- POST_NOTIFICATIONS permission requested on API 33+

JSON Backup:
- BackupManager: export all memos to JSON, import from JSON
- Export: saves to device via Android SAF (CreateDocument)
- Import: reads JSON file, creates memos via API, refreshes cache
- Backup format: version, exportedAt, memoCount, array of BackupMemo
- Export/import buttons in settings with status feedback

Test Suite (67 tests, all passing):
- TaskParserTest (29): checkbox parsing, priorities, dates, labels, lists,
  stable IDs, toggle/replace, line indices, edge cases
- DtoMappersTest (16): ID extraction, timestamps, visibility, properties,
  attachments, reactions, comment count from relations
- DtoSerializationTest (7): JSON deserialization, unknown fields, relation
  object refs, attachment size strings
- BackupManagerTest (7): export/import round-trip, version, memo count,
  invalid JSON handling
- MemoVisibilityTest (5): fromApiString, toApiString, round-trip
- ApiResultTest (3): Success, Error, NetworkError sealed class

Co-Authored-By: Claude Opus 4.6 (1M context)

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
2026-05-21 13:44:01 +05:30

90 lines
2.5 KiB
Kotlin

import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.android.kmp.library)
alias(libs.plugins.compose.multiplatform)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.room)
}
kotlin {
@Suppress("DEPRECATION")
androidLibrary {
namespace = "com.avinal.memos.shared"
compileSdk = 36
minSdk = 26
withHostTest {}
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
listOf(
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}
sourceSets {
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.materialIconsExtended)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.datastore.preferences)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.datetime)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.coil.compose)
implementation(libs.coil.network.ktor)
implementation(libs.room.runtime)
implementation(libs.sqlite.bundled)
}
androidMain.dependencies {
implementation(libs.kotlinx.coroutines.android)
implementation(libs.ktor.client.okhttp)
implementation(libs.androidx.work.runtime)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
commonTest.dependencies {
implementation(kotlin("test"))
implementation(libs.kotlinx.coroutines.core)
}
}
}
room {
schemaDirectory("$projectDir/schemas")
}
dependencies {
add("kspAndroid", libs.room.compiler)
add("kspIosSimulatorArm64", libs.room.compiler)
add("kspIosArm64", libs.room.compiler)
}