Commit Graph
29 Commits
Author SHA1 Message Date
Ayushya AmitabhandClaude Sonnet 5.5 e83358054c CI: signed iOS build and TestFlight upload on Release tags
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:14:07 -04:00
Ayushya Amitabh 1f19bb77f9 Fix bottom avatar popup account ordering on Android 2026-10-07 23:14:07 -04:00
Ayushya Amitabh 51636813af Refine iOS navigation, media controls, and background sync 2026-10-07 23:14:07 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 2e5fc4723a Avatar menu: same side inset as the Files list rows
The card was inset 16px from each screen edge; the list rows are 12px, so it
read as narrower. Now NooSpace.sm, with a test on the account row's width.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 e67e08d571 iOS: device sync (Swift port of the Android engine) behind the sync_service channel
PROPFIND walk / diff / GET / PUT mirror with conflicts, per-account state,
BGTaskScheduler background runs, and conflict notifications with Keep local /
Use server. Reviewed by Codex against the Kotlin original; its data-loss
findings are fixed and each has a regression test (fake-server end-to-end
tests, 68 Swift tests total): truncated/unusable PROPFIND answers are never a
manifest, unreadable state aborts the run, server paths can't leave the mirror,
case/Unicode collisions are skipped, atomic downloads, a locally edited file
deleted on the server is kept, '/' scope matching, serialised removal,
tracked/cancellable background runs, per-account conflicts, and sign-out vs
background-off credentials (cancel gains a 'forget' flag).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 e176152d56 Viewer: round icon buttons with backgrounds; plain text follows Edit -> Save too
Edit/Preview and Save are now compact (36px) icon-only NooButtons - primary when
alone, Edit/Preview secondary beside a primary Save, a spinner circle while
saving. Plain text opens read-only like Markdown and gets the same toggle.
NooButton gains an opt-in iconOnly mode.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 ca75eb9c30 Media viewer: Edit/Preview and Save move to the top bar
A TextPreviewController (owned by the viewer, bound by MediaTextPreview)
mirrors the editing/dirty/saving state out so the top bar draws the buttons;
Save shows a spinner while saving. Located and tested via a Codex consult
(its end-to-end widget test, with the provider fixed and the saving state
adapted); the controller design replaces its builder-wrapping patch.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 b7ca714bbf Share sheet: ask to unlock on every gated action, like the app
The sheet remembered one unlock for its whole lifetime, so later account picks
and hidden toggles skipped Face ID. Each switch / each turning-on of hidden
folders now prompts again; one action needing both is a single prompt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 1542d53a0c iOS: authenticate each request by its own header only (no cookies/credential cache)
Two accounts can share one server; the Share Extension's folder listing and
the upload sessions now ignore cookies and stored credentials so one account's
session can never answer for another. Logs each PROPFIND (user, path, status).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 c2f6e6166d Share sheet: Hidden and Storage toggles, plus diagnostics for the missing accounts
Two menu chips start at the account's app settings (hidden filter, storage
scope - now published per account), hidden-on asks for the app's unlock, and
external storage is detected via nc:mount-type incl. everything under a
mount. Adds logging for which accounts get published and why one is skipped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 c9a3036e07 Security locks work independently; other-account avatars flush right in the avatar menu
Login lock, lock account switching and lock hidden files no longer depend on
each other: passGate prompts on its own flag, the two sub-locks can be set
with login lock off, and disabling login lock leaves them alone. Turning any
lock on or off asks for device auth (on also checks the device can). The iOS
Share Extension's unlock rules follow. The avatar dropdown's additional
accounts lose the 44px spacer so their avatars sit at the right edge.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 a33b5c422f Share Extension: remove the legacy single-account keychain item on clear
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 85eb0a3cef Share Extension: account picker first, hidden folders follow the app's filter + unlock
The app now publishes every uploadable account, the active one, the three
lock settings and each account's own hidden-files filter (ShareAccountSync).
The sheet lists accounts first when there are several, asks for unlock to use
a non-active account (login lock + account-switching lock), and shows hidden
folders per the account's app setting behind the hidden-files unlock.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 673fb99d01 Frosted bottom bar: adjustable blur and opacity with Less/Default/More presets
Settings > Appearance shows a preset control plus Blur and Opacity sliders
(new NooSlider) while frosted glass is on; values persist and feed
NooBottomBar.frostedBlur/frostedOpacity. Default matches the old fixed look.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 8ef3d3471c iOS transfers: 'Uploading...' then 'Uploaded' notification, and count share uploads
The Share Extension's session had no delegate, so a fast upload finished
unseen and the invalidated session was discarded before the app could hear of
it - no summary notification. Results are now handled by a shared delegate in
whichever process is alive, started/finished notifications replace each
other in place, and the app refreshes the folder the extension uploaded to.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 8628f72c9d iOS Share Extension: pick the destination inside the share sheet
SwiftUI folder picker in the extension (WebDAV PROPFIND), account shared via
a Keychain group, upload on a background session that outlives the extension
and is finished by the app. The inbox + notification hand-off remains as the
fallback (no account / 'choose later'). Shared code moves to ios/Shared.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 89c3680f32 iOS: Share Extension (share to Noo) via an App Group inbox
ShareExtension target copies shared files into group.dev.ayushya.noo and
leaves a manifest; the app consumes it on launch/activation through the
existing share_intent channel into the destination picker. Extension is
embedded before Flutter's script phases; versions follow FLUTTER_BUILD_*.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 870ca8ea17 iOS: show transfer notifications as banners while the app is open
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 6a1d0eb23e iOS: native upload and download services (background URLSession)
Swift implementation of the upload_service/download_service channels:
background PUT/GET against the account's WebDAV root, one summary local
notification per batch, Downloads visible in the Files app. Pure helpers
covered by RunnerTests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 7434b90130 iOS: degrade gracefully where the Android-only native services are missing
Share/pick/sync calls and streams no longer throw MissingPluginException at
startup; upload/download/sync-now show 'X isn't available on this platform
yet'. Offline/sync mirror dir no longer uses the Android-only external dir.
Info.plist: Face ID and photo library usage strings.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 68827a9c80 Dynamic color: keep card surfaces lighter than the page
In light mode surfaceContainerLow is slightly darker than the OS surface bg
maps to, so the selection bar and other cards blended into the page. Use
surfaceContainerLowest (light) / surfaceContainer (dark) for NooColors.surface.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 fea7c3302e iOS: replace default Flutter app icons with the Noo icon
Generated from assets/icon/app_icon.png, opaque RGB at every size in the set.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 ef3315d0b2 Filter sheets: 'Type' label above the type control; shorten 'All + ...' to 'All'
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 1ebfb6d2a3 Filters: three-way hidden files and external storage
Hidden: hide / only hidden / all + hidden. External: cloud only / only
external / all + external; with 'all' Files shows the external items in a
collapsible section. Old show-hidden bool prefs are still read as fallback.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 e4023cc39f Bottom bar: add frosted glass option (Settings > Appearance)
Translucent fill over a backdrop blur, both platforms and both bar styles.
Frosted bars draw over an extended body, so the shell's extendBody and the
tab clearance now key off NooBottomBar.drawsBehindBody.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 b9d62acf85 Files: don't context.watch from the item tap handler
watch outside build asserts in debug builds, so taps on rows silently did
nothing in debug (release strips the assert, which hid it on Android).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 7cdae1eedb Floating bottom bar: use Android row (icon-only idle tabs) on iOS too
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya AmitabhandClaude Sonnet 5.5 b7a33ea441 iOS: raise deployment target to 15.0 (required by current Flutter)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 23:13:49 -04:00
Ayushya Amitabh 848d6a8905 Remove desktop platform support from documentation 2026-10-06 23:25:07 -04:00