pj d4c3a304b5 Sign in on a phone with no console work, in the browser's own session
Mobile OAuth reused the desktop client all along; what stopped it was the
browser. Sending the user out to Safari or Chrome backgrounds the app, iOS
suspends it, and the redirect carrying the code arrives at a socket nobody
is accepting on. The consent page now opens in front of the app instead, in
SFSafariViewController or a Chrome Custom Tab, so the loopback listener
stays live and the existing `installed` client is enough. Verified against
Google's real consent screen on a simulator and an emulator.

A per-platform client is still supported and is now an upgrade rather than a
prerequisite. On iOS it buys ASWebAuthenticationSession, which shares
Safari's session so nobody is asked to sign in to Google twice. Android
needs nothing: Custom Tabs share Chrome's cookies, measured rather than
assumed. iOS session sharing could not be confirmed on the simulator and
wants a real device.

Never an app-owned WebView: Google blocks it, and rightly, since a webview
the app controls can read the password typed into it.

Cancelling is no longer reported as a failure. AuthEvent carries a
`cancelled` flag, set by comparing against the constant every back-out path
returns, and Google's `access_denied` on desktop counts too.

Five frontend bugs found by driving the real UI, not by reading it: the
details card slid under the tab bar leaving its buttons unhittable; the
ghost click after a touch pressed a button in the card that tap had just
opened, opening the editor by itself; the swipe that pages the day was dead
over every read-only block; 84px of macOS traffic-light lane was reserved on
platforms with no traffic lights; and the desktop header ignored the top
safe area on an iPad. A first launch now says what to do next rather than
showing an empty grid, and accounts are named as Google accounts throughout.
2026-08-12 18:32:45 +05:30

Margin Calendar

A calendar for Google Calendar on macOS, Linux, Android and iOS. The grid owns the window, the day fits without scrolling, and on a desktop the whole thing is drivable from the keyboard.

It is a sibling to margin and shares its stack and its visual language.

Setup and the Google OAuth client it needs are in docs/setup.md, and the extra clients a phone build needs are in docs/mobile.md. The product decisions are in docs/design.md, how it is built is in docs/architecture.md, and the conventions it follows are in docs/conventions.md.

S
Description
No description provided
Readme MIT
2.1 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 54.8%
Rust 32.5%
CSS 10.2%
Kotlin 1.2%
Just 0.6%
Other 0.6%