| Age | Commit message (Collapse) | Author |
|
DashboardActivity is now the app's single home-screen launcher entry
(MAIN/LAUNCHER intent-filter), replacing SettingsActivity in that role.
SettingsActivity keeps only APPWIDGET_CONFIGURE (still exported=true,
since the launcher/home-screen process starts it directly during widget
placement) and is now reached via a gear button in Dashboard's toolbar.
DashboardActivity itself is rewritten from a bare setContentView(webView)
to Compose Scaffold/TopAppBar wrapping the WebView via AndroidView, adding:
- a back arrow (shown only when the WebView has history) instead of relying
solely on the hardware back key
- a settings gear action launching SettingsActivity
- the page title tracked from the loaded page
Also fixes a race in the original version: server URL was loaded via a
lifecycleScope coroutine racing the WebView's own initialization order.
Now it's plain Compose state (LaunchedEffect + AndroidView's update
callback), so the WebView never loads before the URL is known.
No native tab bar: web/templates/index.html's tabs are HTMX partials
(hx-get targeting #tab-content), not separate pages, so loading "/" in
the WebView already gets full in-app navigation for free.
Verified on emulator-5556 (doot_test_api36): pm resolve-activity confirms
DashboardActivity is the launcher default; launched it, confirmed no
crash and topResumedActivity is Dashboard; configured a dummy server URL
via Settings and confirmed the toolbar renders (title, gear icon) and
the gear button correctly navigates to SettingsActivity (topResumedActivity
becomes SettingsActivity) with no crash.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
|
|
QuickAddActivity's autofocus used delay(150) then requestFocus() +
keyboard.show() -- a fixed delay racing against the window actually
gaining focus. This is a translucent, separate-taskAffinity popup
activity, so window focus transfer is variable/device-dependent; a
show() call made before the window is focused is silently dropped by
the IME service, no error, no retry -- the classic cause of "keyboard
doesn't appear until I tap out and back in" (reported 2026-08-06, "more
consistent here" than the same general Android quirk elsewhere). Fixed
to react to LocalWindowInfo.isWindowFocused instead of guessing a
timing window, plus windowSoftInputMode="adjustResize|stateVisible" as
an OS-level second line of defense.
Tried to verify live and hit a real limitation worth recording: this
box's AVDs run -no-window (headless), and in that mode mInputShown
never reports true via dumpsys input_method even for a manual,
deliberate tap on the field -- confirmed by testing a plain tap
directly, independent of any app code. The harness can't observe IME
visibility here, so this fix is verified by code-level reasoning
(LocalWindowInfo-driven focus is the standard, documented fix for this
exact bug class) and confirmed window-focus DOES transfers correctly
(mServedView moves to the bottom sheet's window), not by watching the
keyboard actually appear. Real confirmation has to happen on-device.
Also: SettingsActivity.saveAndFinish() only ever called
DootWidget().updateAll() indirectly, as a side effect of RefreshWorker
succeeding its network fetch -- so a slow or failing request could
delay or block the widget from reflecting a setting the user just
saved, even though every setting saved there (theme, text size,
background, checkboxes) is already fully local and needs no network
round trip to take effect. Now calls updateAll() directly and
immediately after writing prefs; RefreshWorker still runs afterward to
separately pull fresh server data.
Verified installable and crash-free on a real API 36 emulator.
Deployed as doot-widget.apk.
|
|
First cut per the 2026-08-06 feasibility check (verdict: easy, no
architecture blockers): a plain WebView pointed at the configured
server URL, cookie jar enabled for the existing session-cookie login
(internal/auth/middleware.go's RequireAuth) -- no separate auth bridge
needed, the widget's own bearer token is a completely different scheme
and doesn't need to touch this at all. External links (e.g. a calendar
event's source URL) escape to the user's real browser instead of
getting stuck in the WebView.
No deep-linking to specific tabs, no native-rendered chrome -- this is
the minimal first step to validate the wrapped experience is worth
building further, not the final shape.
|
|
Tapping a calendar event (or any event-type item) now opens the event's
URL (Google Calendar, Plan to Eat, etc.) directly instead of showing an
intermediate popup with an "Open in Calendar" button. Removes
EventDetailActivity and the recurrence-schedule lookup it was the only
consumer of: WidgetRepository.getRecurrence, the Go
/api/widget/recurrence endpoint, HandleWidgetRecurrence,
GoogleCalendarAPI.GetRecurrenceRule, and formatRecurrence, plus their
tests. RecurringEventID itself stays -- it's general calendar-sync
metadata used elsewhere in the timeline pipeline, not exclusive to the
removed popup.
|
|
TaskDetailActivity, QuickAddActivity, and EventDetailActivity shared the
app's default task affinity with SettingsActivity. FLAG_ACTIVITY_NEW_TASK
reuses an existing task with matching affinity rather than creating a
fresh one, so if SettingsActivity's task was still alive in recents,
these translucent popups rendered on top of it instead of the home
screen behind them, as the theme's transparency was designed to show.
|
|
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
|
|
|
|
Replaces browser deep-link with a transparent TaskDetailActivity that
shows a Material3 ModalBottomSheet (20-40% screen height). The launcher
shows through the transparent window behind the dark scrim. Sheet shows
source color dot, task title, and Mark Complete button for Todoist tasks.
Tapping outside or swiping down dismisses. No browser involved.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
import in tests
|
|
|
|
|