1
0
mirror of https://github.com/avinal/nikki.git synced 2026-07-03 21:40:09 +05:30

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>
This commit is contained in:
2026-05-21 13:44:01 +05:30
parent 3070651652
commit e165be9f6c
19 changed files with 1064 additions and 1 deletions
+1
View File
@@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:allowBackup="true"
@@ -1,10 +1,17 @@
package com.avinal.memos
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.CompositionLocalProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.avinal.memos.notifications.TaskNotificationManager
import com.avinal.memos.notifications.scheduleTaskChecker
import com.avinal.memos.util.LocalAppDependencies
class MainActivity : ComponentActivity() {
@@ -20,6 +27,11 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
deps.initialize()
com.avinal.memos.util.appContext = applicationContext
TaskNotificationManager.createChannel(this)
requestNotificationPermission()
scheduleTaskChecker(applicationContext)
enableEdgeToEdge()
setContent {
CompositionLocalProvider(LocalAppDependencies provides deps) {
@@ -27,4 +39,14 @@ class MainActivity : ComponentActivity() {
}
}
}
private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001)
}
}
}
}