Drive Tokens, File Previews, and a Cleaner List/Grid Toggle
Ship notes on token-based Drive calls, practical metadata (size, modified, MIME), and the new toggle that stops fighting your brain.
“Build small, ship quiet, iterate fast.”
— Rev. Brian Scott O’keefe
What shipped
- Token-based Google Drive calls (REST, no GTLR) with cleaner refresh logic.
- Metadata rows in list view: file size (human-readable), last modified (relative + absolute), MIME type (trimmed).
- List/Grid toggle that preserves mode across sessions and stops jarring reflow.
- Preview pipeline tuned for snappier thumbnails and graceful fallbacks.
If you missed the first installment, start with Dev Log #1 for context on tokens and layout goals: /blog/lifeos-scribraria-dev-log-1
.
Token-based Drive calls (quick, durable, boring)
- Access/refresh split: Access tokens power requests; refresh tokens are keyed in the system keychain. Expiration is tracked; refresh happens just-in-time, not constantly.
- URLSession + typed requests: Each Drive endpoint sits behind a tiny request type with robust error mapping (auth, quota, network).
- Backoff & retry: Transient 5xx errors back off with jitter; auth failures short-circuit to a guided re-auth path.
- Privacy guardrails: Scopes are minimal; logs strip tokens; request IDs help me trace without leaking details.
Why it matters: stable tokens mean previews and lists feel instantaneous instead of “sometimes-fast-sometimes-broken.”
File metadata that’s actually useful
- Size: Shown as KB/MB/GB with one decimal (e.g., 12.4 MB).
- Modified: Relative (“2h ago”), with tooltips/secondary text for the full timestamp.
- MIME: Trimmed to a friendly label (e.g., “PDF” instead of
application/pdf
).
- Secondary line pattern:
Owner • Size • Modified
. Responsive rules collapse gracefully on smaller widths.
Planned options: Toggle MIME on/off per user, and a compact “developer mode” to surface raw MIME + Drive IDs for debugging.
A calmer List/Grid toggle
- State that sticks: Your choice persists between launches (UserDefaults for now).
- Zero-jitter switch: The container reserves space, so toggling doesn’t cause big jumps.
- Grid polish: Square thumbs with consistent gutters; long names wrap to two lines and then truncate.
Previews that don’t lie
- Progressive load: Low-res thumb first, then swap in high-res when ready.
- Fallback chain: If a preview fails, we show a deterministic icon (by MIME family) and keep the metadata intact.
- No spinner storm: One spinner per cell if needed; batch prefetch avoids flicker in fast scrolls.
Known issues (and what I did about them)
- Occasional 401 after sleep: Added a wake-resume check that validates tokens before resuming queued requests.
- Over-eager reloads on tab switch: Debounced; navigation now respects cache freshness windows.
- Grid thumbnails on slow networks: Introduced a tiny placeholder palette so the grid doesn’t look empty while loading.
Next sprint (what I’m building immediately)
- Per-view sort & filter memory: Size/Modified/Name, ascending/descending, remembered per folder.
- Inline quick actions: Tap-hold for copy link, rename, and “open in Drive” without losing place.
- Preview extensions: Text, Markdown, and PDF inline readers with smooth paging.
- Diagnostics panel (developer mode): Surface request timing, cache hits, and Drive file IDs.
How you can help (CTA)
Which metadata matters most—size, modified, or MIME?
Tell me in a comment or DM. I’ll tune the default layout and the order of the secondary line based on your answer.
Changelog
2025-09-20
- Implemented token refresh guard & exponential backoff
- Added size/modified/MIME to list cells
- Persisted list/grid toggle; stabilized transitions
- Preview fallback logic + progressive thumbnails
Version / Tooling
- Languages/SDKs: Swift 6, SwiftUI, URLSession (REST), Keychain access
- Tooling: Xcode 16
- APIs: Google Sign-In (token exchange), Google Drive REST v3
- Platforms: iOS + macOS targets
- Data: Local caching for previews and metadata snapshots
— Rev. Brian Scott O’keefe
randomblink
“I build in public so I remember in private.”
Tokens, Sync, Clean Start
Current goals
- ✅ Go REST-only with tokens (ditch legacy SDK/gRPC/GTLR; rely on clean URLSession calls).
- ✅ Harden sign-in/out across macOS/iOS with a single source of truth for auth state.
- 🔄 Design a calmer file view that shows exactly what you need (and nothing you don’t).
- 📓 Make the logs the memory: short, truthful dev notes; tight screenshots; reproducible steps.
- 🧪 Stabilize sync for Drive/Calendar basics, then layer on previews and offline cache.
Auth & tokens (the new backbone)
The old way was tangled. The new way is simple:
- Token-based REST: standard OAuth2 flow → store access + refresh tokens in the Keychain; refresh automatically before expiry; never block the UI waiting on auth.
- Single Auth service: one AuthState drives UI. If isSignedIn == false, show a safe, minimal sign-in sheet; otherwise continue seamlessly.
- Sign-out that really signs out: clear tokens, reset caches, invalidate any background tasks, bounce the app to a clean state.
- Resilience first: every network call wraps:
- Retry on transient errors (exponential backoff).
- 401 → refresh token once → retry; if it fails, drop to signed-out.
- All errors surface as human-readable toasts and machine-readable logs.
What I broke today:
A silent refresh loop when the network dropped mid-refresh. Fixed by gating concurrent refresh calls and memoizing the in-flight promise so only one refresh can run at a time.
Privacy posture: tokens never leave the device; logs redact headers; no crash reports include PII.
File view ideas (don’t fight the brain)
I’m designing for calm and orientation:
- List ↔ Grid toggle with your last choice remembered.
- At-a-glance metadata: file type, size, modified date, and Drive ID (copy-on-click).
- Thumbnails/previews where useful; text-only for dense modes.
- Recents / Favorites tabs right on top.
- Inline filters (type, tag, owner) with a compact query pill you can edit.
- Breadcrumbs you can actually use (each crumb is clickable and copyable).
- One universal action key: ⏎ opens, ⌘C copies link/ID, Space previews.
- “What changed?” ghost highlights after a sync so your eyes find fresh stuff fast.
- Gentle empty states with a single next action (import, connect, or create).
Sketch note: the content column aligns to a golden-ratio container; actions hide until hover/focus to reduce visual noise.
Known bugs (current reality, not vibes)
- Folder lists sometimes load but aren’t clickable after a slow network wake. Likely a stale SwiftUI state binding—reloading the data source fixes it; investigating a proper identity key.
- Actor isolation warnings in Swift 6 where async services touch UI state (DrivePathResolver + cache).
- Occasional duplicate types after regenerating models (invalid redeclarations). Root cause: old files not removed during refactor; adding a “regenerate and prune” step.
- Ambiguous initializers in a mock service leading to “extra arguments” compile errors—cleaning up convenience inits and adopting builders for test data.
- Token refresh race (now fixed) caused a brief signed-out flicker on resume.
I’m keeping these here until each is closed and regression-tested.
Next sprint (tight, testable, shippable)
1) Auth polish
- Add a single-flight refresh guard (done), plus unit tests for: token expiry edge, network drop, revoked refresh token.
- Implement background refresh scheduling with OS hints to avoid wake storms.
2) File view MVP
- Ship List/Grid with: name, icon, size, modified, ID (copy-on-click).
- Add Recents/Favorites tabs and persist view mode in UserDefaults.
- Wire preview (Space) for images/PDF/text.
3) Sync + cache
- Local metadata cache keyed by Drive ID; optimistic UI for move/rename.
- Debounced search with cancellable tasks to keep typing smooth.
4) Quality gates
- “No new warnings” rule on main.
- Trace logs for every network call with request ID; redaction enforced in one place.
- Screenshot + short clip of each feature before merge (so this log has pictures).
CTA: Tell me your top pain in organizing files; I’ll test it in the next build.
Drop a comment or reply with a 1–2 sentence description (bonus: a quick phone snapshot of your folder chaos). Real pain > hypothetical features.
Changelog (human-sized)
- Refactor: Removed legacy SDK hooks; REST-only networking via URLSession.
- Auth: Centralized AuthState; fixed refresh loop; clearer error surfaces.
- Design: Spec’d calmer file view; golden-ratio container; copyable IDs.
- Tooling: Added request-ID tracing; started “screenshots or it didn’t happen” rule.
- randomblink