Parser doctor:
- validateContent() with error/warning severity levels
- Errors: invalid date, invalid priority, reminder without due,
invalid reminder unit
- Warnings: time without date, past date, multiple metadata,
typo detection with correction suggestions
- 21 new tests in ParserDoctorTest
Tag inheritance:
- extractTasks() accepts memoTags parameter
- Tasks without #tags inherit memo-level tags
Offline queue:
- PendingSyncEntity + PendingSyncDao for queued edits
- MemoRepository queues failed API calls, drains on next sync
- Sync status banner: "synced N min ago" / "offline · N pending"
UI:
- Parser doctor banner in tasks tab with inline highlighting
- Error/warning dots on task rows
- Pivot headers with absolute positioning and measured widths
- Logo in settings about section (Canvas-drawn circle variant)
Other:
- MIT license
- Logo design spec (LOGO.md)
- Concentric circle logo: pink circle, black+teal 47° annular wedge
- .gitignore updated for dev artifacts
144 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
reliable alarm scheduling
Auto sync:
- Configurable interval: 1/2/5/10/15/30/60 min (default 5)
- MemoRepository.syncIntervalMinutes updated live from DataStore
- Setting shown under "memos" section in settings
Notifications by priority:
- p1: 🔴 alarm sound, long vibration, wakes screen, bypasses DND
- p2: 🟠 notification sound, medium vibration, heads-up
- p3: 🔵 notification sound, short vibration
- none: silent, no vibration
- BigTextStyle with priority tag, colored accent bar
- 4 separate Android notification channels
Background reliability:
- FOREGROUND_SERVICE, WAKE_LOCK, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- Battery optimization exemption requested on first launch
- DirectAlarmScheduler: schedules alarms directly from app process
using live Room data (bypasses WorkManager DB sync issue)
- onContentChanged fires direct scheduling on every memo create/update
- TaskReminderReceiver moved to androidApp module for reliable
cold-start instantiation
- WorkManager kept as 15-min backup for server-side changes
123 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Notification fixes:
- Removed scheduledIds skip — alarms always recomputed on each worker
run (AlarmManager deduplicates via FLAG_UPDATE_CURRENT)
- Tasks with dueTime but no dueDate now assume today
- Worker runs once immediately on app launch + periodic 15min
- Added debug logging to trace task/alarm computation
- "check reminders now" button in settings triggers immediate check
Custom reminder picker:
- Number input field (digits only) + unit selector (min/hr/day/week)
- Replaces the preset-only list with free-form input
- "save" validates > 0 before applying, "clear" removes reminder
ReminderScheduler extracted to commonMain (testable):
- 18 tests covering: completed/no-date skip, due time alarms,
default 8am/8pm, duration offsets (min/hr/day/week),
past alarm filtering, multiple tasks, label preservation
125 tests total, all passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Archived memos:
- "view archived memos" in explorer navigates to memo list with
archived filter active
- Fetches archived memos from API (state == ARCHIVED)
- MemoCard shows "restore" instead of "archive" in context menu
- Restore calls updateMemo(state=NORMAL), upserts to local cache
- Compose card hidden when viewing archived
- Filter banner shows "archived memos" with clear option
Comment deletion:
- Each comment shows "delete" link next to creator/date
- Calls deleteMemo on the comment (child memo) and removes locally
Accessibility:
- Task group collapse icons now have contentDescription
("Expand"/"Collapse")
Test suite: 107 tests (5 new entity mapper tests)
- MemoEntityMappersTest: round-trip field preservation, empty tags,
cachedAt, all visibility variants, timestamp fidelity
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Loading state:
- CircularProgressIndicator shown during first fetch instead of
"no memos yet". isInitialLoading flag in MemoListUiState cleared
after first emission from observeMemos().
Error display:
- Failed refresh/load errors shown as red text in memo list
- Previously errors were captured but never displayed to user
Archived memos:
- listArchivedMemos() API endpoint added (filter: state == ARCHIVED)
- "view archived memos" link in explorer page (placeholder for full UI)
102 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
1. Default visibility now used in compose card (reads from DataStore)
2. Week start day wired to explorer calendar (rotates day labels,
adjusts Zeller offset)
3. Task toggle deduplicated: both MemoListViewModel and
MemoDetailViewModel now use TaskParser.toggleTaskInContent
instead of manual string replacement
4. reactToMemo refetches single memo instead of all memos
5. AppDependencies stores Job reference, cancels before re-init
6. HTTP timeouts added: 30s request/socket, 15s connect
102 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Task detail sheet:
- "open in memo" and "close" aligned on same line (left/right)
- Due date+time, reminder, priority, tags as labeled rows with
bordered value boxes (accent when set, muted when not)
- No presets for date/time — tap opens DatePicker/TimePicker
- Reminder picker: duration options (15min to 1week)
- Tag editor: text field for #tag input
- Dialog stays open after selections, "close" to dismiss
Reminder as duration (!Nunit):
- !30min, !1hr, !2day, !1week parsed into ReminderDuration
- Notification worker: alarm at dueTime - duration offset
- Shown in task list metadata row
Live preview in compose card:
- Shows parsed metadata chips as you type
- Auto-checklist: Enter after task line inserts "- [ ] "
Settings additions:
- Default visibility (tap cycles: private → protected → public)
- Default reminder (tap cycles: none → 15min → 30min → 1hr → 1day)
- Week starts on (tap cycles through days, for calendar)
- All new settings persisted in DataStore
Parser rewritten:
- Removed @labels entirely (@ not a Memos concept)
- Natural dates without prefix: today, tomorrow, yesterday
- Word boundary checks: mp3 ≠ p3, todaying ≠ today
- ISO date colons don't match as time
- !reminder not parsed as due time
102 tests (64 parser, 16 mapper, 7 serialization, 7 backup,
5 visibility, 3 apiResult), all passing.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Time parsing:
- 12-hour format: 5pm, 2:30pm, 11am, 12am (midnight), 12pm (noon)
- 24-hour format: 14:30, 9:00, 17:00
- Time extracted alongside date: "@today 3pm p1 #work"
- Time cleaned from display text
- dueTime field added to Task domain model (LocalTime?)
Notification scheduling:
- Tasks with specific time: AlarmManager.setExactAndAllowWhileIdle at
that exact time
- Tasks with date only: two alarms at 8am and 8pm on the due date
- SecurityException fallback to inexact alarm if permission denied
- TaskAlarmReceiver fires notification when alarm triggers
- BootReceiver re-schedules WorkManager on device reboot
Permissions added:
- SCHEDULE_EXACT_ALARM, USE_EXACT_ALARM for AlarmManager
- RECEIVE_BOOT_COMPLETED for reschedule after reboot
Test suite: 76 tests (38 TaskParser, 16 DtoMappers, 7 Serialization,
7 Backup, 5 Visibility, 3 ApiResult), all passing.
9 new time parsing tests: 12h am/pm, 12h with minutes, 24h, midnight,
noon, no time returns null, time+date combo, time cleaned from text.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Refresh now does a full sync:
- Fetches ALL pages from the API (loops until nextPageToken is empty)
- Clears the entire local cache before inserting fresh data
- Deleted/archived memos on server are now properly removed locally
AMOLED theme dialog fix:
- surface raised from #000000 to #161616 (dialogs no longer invisible)
- surfaceContainer at #1E1E1E for popup/dialog backgrounds
- surfaceContainerHigh at #222222 for elevated surfaces
- outline brightened to #444444 for better border visibility
- All AlertDialog containerColor changed to surfaceContainer
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Media upload:
- Android file picker via ActivityResultContracts.GetContent
- Upload attachment API (base64 content to /api/v1/attachments)
- Uploaded attachments linked to memo via CreateMemoRequest.attachments
- Upload status shown in compose card ("uploading...", "N attachment(s) ready")
Markdown improvements:
- Clickable links: URLs and [text](url) open in browser via LinkAnnotation
- Table rendering: pipe-delimited markdown tables with header row
- Fixed underscore italic (_text_) and bold (__text__) variants
Comments:
- Comments section at bottom of MemoDetailScreen
- List existing comments via /api/v1/memos/{id}/comments
- Add new comments with text input + send button
- Comments rendered with full markdown
Share:
- "share" option in memo long-press context menu
- Android share intent with memo content as plain text
Also:
- Task toggle now works in memo feed (onTaskToggle callback wired)
- Tag clicks in explorer filter memos page
- Search from explorer filters memos page instead of navigating
- All three filter types (date/tag/search) shown as banner with "clear"
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Tasks screen:
- Group by: Due Date, List/Topic, Priority, Source Memo, Status
- Sort by: Due Date, Priority (within groups)
- Collapsible groups with count badges
- Accent-colored checkboxes with content-based task identification
- Task detail bottom sheet: edit due date, priority, open source memo
- Completed tasks in collapsed group at bottom
Settings screen:
- Metro-style large section headers (24sp Light)
- Accent color picker: grid of 20 WP8 color circles
- Theme toggle: dark / light / amoled
- Account info display, sign-out with confirmation
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
MainScreen: WP Panorama-style navigation with parallax-scrolling pivot
headers (explore/memos/tasks/settings). Headers drift at 50% of swipe
speed. Active title in accent color, inactive fades with distance.
MemoListScreen: cardless feed with inline compose bar (expandable text
field, + insert menu, visibility picker, accent "post" button).
Pull-to-refresh, date-based filtering from explorer calendar.
MemoDetailScreen: full content view with markdown rendering, attachment
display, reactions. Back link, retry on load failure.
MemoEditorScreen: Metro-style editor with 32sp Light title, accent
underline text field, dirty state tracking, discard confirmation dialog.
ExplorerPage: activity calendar (month heatmap with navigation arrows),
search bar, tag list with counts. Calendar dates link to memos page
with date filter instead of opening detail screen.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Color system:
- Dark (#1F1F1F bg), Light (white bg), AMOLED (pure black bg)
- All 20 WP8 accent colors (Lime through Taupe)
- User-selectable accent color persisted in DataStore
- Default: Cobalt (#0050EF)
Typography (WP scale):
- 54sp Light for page titles, 32sp Light for pivot headers
- 24sp Light for section headers, 17sp body, 15sp normal, 14sp small
- SemiBold for emphasis, Light for large display text
Flat surfaces only — no elevation, no tonal surfaces, no Material chrome.
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
- AppDependencies: manual DI container with lazy singletons
- TokenStore: DataStore-backed persistence for server URL, access token,
theme preference, and accent color selection
- DataStoreFactory: multiplatform DataStore creation
- LocalAppDependencies: CompositionLocal for DI access in composables
- App.kt: root composable with theme + Coil ImageLoader (Ktor engine)
- MainActivity: creates AppDependencies, provides via CompositionLocal
- Coil configured with authenticated Ktor HttpClient for private images
Co-Authored-By: Claude Opus 4.6 (1M context)
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>