Add Schist Cloud integration for desktop and WASM, add iOS/iPadOS port - #115
Merged
Merged
Conversation
… search The cloud view was a bolt-on: bare buttons, no grouping, search in a dialog, and thumbnails that never loaded. The shared chrome (palette, top strip, tray, sidebar rows, grid frame and scrollbar, cell, drag ghost, menu frame, GroupBy) now lives in gallery_chrome.rs, so the local and cloud galleries are the same room. The cloud sidebar lists the library, a folder tree and buckets with right-click menus; the grid groups the page by month or folder; the search box sits in the strip and queries the provider as you type; filters have a button and a chip. Both search boxes share ui::LineEdit. The browser build composes its gallery from the same parts. Thumbnails: the provider's socket snapshots sent thumbnail_url: null (fixed in schist-cloud 9b042b7 with signed thumbnail tickets); the client now records failed fetches and shows 'no preview' for them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cloud folders now hang under a ☁ Schist Cloud root inside FOLDERS and cloud buckets sit in BUCKETS with the same badge, instead of a separate section. With a cloud signed in, + Add folder… and + New bucket ask whether you mean this computer or Schist Cloud. Connecting (including a stored login at launch) no longer opens the cloud gallery over whatever was on screen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Filters… form (MIME types, tags, edited, content, rating, dates, bounds as free text) is gone from the strip, the sidebar and the browser gallery. Search stays in the strip and the map filter keeps its chip; smart-bucket rules still carry their own fields. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The local-or-cloud menus behind + Add folder… and + New bucket sit on the library's context, which the cloud room never rendered, so clicking either with a cloud item selected did nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
New and Edit for a Schist Cloud bucket now open the same New Bucket dialog as a local one — name, search, an area drawn on the map with the presets — and send the result to the provider as the bucket's rule. The free-text field form is gone from desktop; the browser keeps a name-and-search form since it has no map. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Right-clicking a cloud bucket now offers Edit bucket…, Select all (N), Save all as ZIP… (N), Process all… (N), Move all to folder…, Clear added photos / Clear bucket and Delete bucket. ZIP and batch walk the bucket through the provider's assets.query request and download each photo; Process all stages the originals in a scratch folder and the batch dialog saves to a chosen folder. Move and Clear use the provider's asset.move and bucket.clear. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
IAmJSD
force-pushed
the
feat/schist-cloud
branch
from
September 6, 2026 22:59
603dcae to
f006cef
Compare
Right-click menus for cloud rows now open in the local room and vice versa, and the cloud menu uses the same list rows as the local one. VIEW stays in both rooms; World Map plots the cloud page by each asset's new location field, with markers, strip and marker menu shared with local photos. PEOPLE lists local people in both rooms and the cloud's people beneath them, styled alike, with rename/merge/forget on right-click. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…TTPS agent Cloud folder rows and the Schist Cloud root offer Upload files here…, Upload folder here… and Download folder… (Download everything… at the root), which recreates the cloud's sub-folders on disk. A watched local folder's row gets Upload to Schist Cloud…, asking for the destination folder. Every thumbnail fetch and download used to build a fresh ureq agent, paying a TLS handshake and root-store load each time; one shared agent now pools connections. Thumbnails fetch eight at a time and stay decoded for a few pages, so paging back is instant. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The cloud world map drew only the 200 assets of the page on show, so a library sorted by name put almost nothing on the map. It now fetches every located photo in the scope (the provider's bounds filter doubles as a has-a-fix test) once per change, up to 5000, and loads thumbnails for the markers in view alongside the page's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dropping local photos on a cloud folder or bucket uploaded them one by one and said nothing until the end. Files now go up in gzip batches of up to 48 MiB or 250 files — several payloads for a big drop — through the provider's asset.prepare_batch/commit_batch, falling back to single uploads on a provider without them. The tray in either room shows a bar with the running count; sub-folders in the drop become cloud folders. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The drop upload read, compressed and sent each batch in turn, so the network idled while the disk was read and the disk idled while bytes went up. A packer now runs on its own thread, reading and gzipping up to two batches ahead of the one being uploaded, and learns from the first reply whether the provider takes batches so it stops keeping raw files once payloads are enough. The browser build keeps the sequential order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The socket handle now carries an online flag, set when the workspace session is ready and cleared when it drops, and the client can tell a connection failure from a refusal. The uploader waits for the connection to come back — with a short pause, up to about four hours — and repeats the step with the same mutation IDs, so a batch whose commit reply was lost is answered from the provider's record rather than done twice, and a large file continues from the chunks already stored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ewal A dropped watched folder swept the gallery's own .schist/versions sidecar folders into the cloud as empty folders; enumeration now skips hidden entries. The workspace session renews itself every quarter hour by reconnecting, so the uploader's first retry after an interruption is now immediate and the message no longer calls it a lost connection. Socket requests get 180 s before they are called timed out — a batch commit stores hundreds of files before it answers, and repeating a still-running commit would store them twice — and that timeout counts as transient. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each file is hashed while it is packed, and before a batch goes up the uploader asks the provider's assets.exists which digests the library already has. Those files stay home — the batch is packed again without them — and a bucket drop still adds the existing assets to the bucket. The summary says how many were already there. Batches no longer keep raw bytes for the single-file fallback; they read the files again instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The delete-folder dialog gains a checkbox; ticked, the provider removes every photo and sub-folder in the subtree. Cloud dialogs can now carry yes/no fields (cloud-check-*), drawn with the shared Checkbox. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
After dedupe left files out of a batch, the prepare still declared the original number, and the provider rejected the payload as a changed file count. The declared count now follows the packed entries. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The dedupe rewrite packed an oversize single file (48–100 MiB) into a one-file payload, which the provider refuses above its 64 MiB batch cap. Such files are a distinct item now: checked for a duplicate, then sent as one plain upload, never packed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
IAmJSD
added a commit
that referenced
this pull request
Sep 12, 2026
#115) * feat: add native Schist Cloud integration * fix: align cloud capabilities and downloads with provider spec * feat: enable Schist Cloud in the hosted WASM editor * refactor: share the document engine between editor and cloud worker * feat: give the cloud gallery the local gallery's chrome, grouping and search The cloud view was a bolt-on: bare buttons, no grouping, search in a dialog, and thumbnails that never loaded. The shared chrome (palette, top strip, tray, sidebar rows, grid frame and scrollbar, cell, drag ghost, menu frame, GroupBy) now lives in gallery_chrome.rs, so the local and cloud galleries are the same room. The cloud sidebar lists the library, a folder tree and buckets with right-click menus; the grid groups the page by month or folder; the search box sits in the strip and queries the provider as you type; filters have a button and a chip. Both search boxes share ui::LineEdit. The browser build composes its gallery from the same parts. Thumbnails: the provider's socket snapshots sent thumbnail_url: null (fixed in schist-cloud 9b042b7 with signed thumbnail tickets); the client now records failed fetches and shows 'no preview' for them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: list cloud folders and buckets with the local ones, connect quietly Cloud folders now hang under a ☁ Schist Cloud root inside FOLDERS and cloud buckets sit in BUCKETS with the same badge, instead of a separate section. With a cloud signed in, + Add folder… and + New bucket ask whether you mean this computer or Schist Cloud. Connecting (including a stored login at launch) no longer opens the cloud gallery over whatever was on screen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Show server-provided bucket counts before loading photos * Show server-provided folder counts before loading photos * Keep local and cloud gallery controls consistent * Remove the cloud filter dialog The Filters… form (MIME types, tags, edited, content, rating, dates, bounds as free text) is gone from the strip, the sidebar and the browser gallery. Search stays in the strip and the map filter keeps its chip; smart-bucket rules still carry their own fields. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Keep the Schist Cloud library count visible in every view * Show the add-folder and new-bucket choice menus in the cloud room too The local-or-cloud menus behind + Add folder… and + New bucket sit on the library's context, which the cloud room never rendered, so clicking either with a cloud item selected did nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Give cloud buckets the local bucket dialog New and Edit for a Schist Cloud bucket now open the same New Bucket dialog as a local one — name, search, an area drawn on the map with the presets — and send the result to the provider as the bucket's rule. The free-text field form is gone from desktop; the browser keeps a name-and-search form since it has no map. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Give cloud bucket rows the local bucket menu Right-clicking a cloud bucket now offers Edit bucket…, Select all (N), Save all as ZIP… (N), Process all… (N), Move all to folder…, Clear added photos / Clear bucket and Delete bucket. ZIP and batch walk the bucket through the provider's assets.query request and download each photo; Process all stages the originals in a scratch folder and the batch dialog saves to a chosen folder. Move and Clear use the provider's asset.move and bucket.clear. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Integrate cloud People and screening after upstream rebase * Resolve strict lint checks for cloud integration * Keep the sidebar whole in the cloud room: menus, map, people Right-click menus for cloud rows now open in the local room and vice versa, and the cloud menu uses the same list rows as the local one. VIEW stays in both rooms; World Map plots the cloud page by each asset's new location field, with markers, strip and marker menu shared with local photos. PEOPLE lists local people in both rooms and the cloud's people beneath them, styled alike, with rename/merge/forget on right-click. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Add the asset location field to test fixtures Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Upload and download whole folders from the sidebar menus; reuse one HTTPS agent Cloud folder rows and the Schist Cloud root offer Upload files here…, Upload folder here… and Download folder… (Download everything… at the root), which recreates the cloud's sub-folders on disk. A watched local folder's row gets Upload to Schist Cloud…, asking for the destination folder. Every thumbnail fetch and download used to build a fresh ureq agent, paying a TLS handshake and root-store load each time; one shared agent now pools connections. Thumbnails fetch eight at a time and stay decoded for a few pages, so paging back is instant. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Plot the whole cloud scope on the world map, not one page The cloud world map drew only the 200 assets of the page on show, so a library sorted by name put almost nothing on the map. It now fetches every located photo in the scope (the provider's bounds filter doubles as a has-a-fix test) once per change, up to 5000, and loads thumbnails for the markers in view alongside the page's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Upload drops as compressed batches with a progress bar Dropping local photos on a cloud folder or bucket uploaded them one by one and said nothing until the end. Files now go up in gzip batches of up to 48 MiB or 250 files — several payloads for a big drop — through the provider's asset.prepare_batch/commit_batch, falling back to single uploads on a provider without them. The tray in either room shows a bar with the running count; sub-folders in the drop become cloud folders. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Skip invalid upload files without abandoning the remaining batch * Upload large cloud files in resumable chunks * Warn before uploading selections that exceed cloud storage * Find faces automatically without People opt-in dialogs * Show spinners while cloud photo snapshots are loading * Pack upload batches ahead of the network on their own thread The drop upload read, compressed and sent each batch in turn, so the network idled while the disk was read and the disk idled while bytes went up. A packer now runs on its own thread, reading and gzipping up to two batches ahead of the one being uploaded, and learns from the first reply whether the provider takes batches so it stops keeping raw files once payloads are enough. The browser build keeps the sequential order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Wait out an outage and resume uploads when the connection returns The socket handle now carries an online flag, set when the workspace session is ready and cleared when it drops, and the client can tell a connection failure from a refusal. The uploader waits for the connection to come back — with a short pause, up to about four hours — and repeats the step with the same mutation IDs, so a batch whose commit reply was lost is answered from the provider's record rather than done twice, and a large file continues from the chunks already stored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Leave hidden folders out of drops; resume at once after a session renewal A dropped watched folder swept the gallery's own .schist/versions sidecar folders into the cloud as empty folders; enumeration now skips hidden entries. The workspace session renews itself every quarter hour by reconnecting, so the uploader's first retry after an interruption is now immediate and the message no longer calls it a lost connection. Socket requests get 180 s before they are called timed out — a batch commit stores hundreds of files before it answers, and repeating a still-running commit would store them twice — and that timeout counts as transient. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Skip files the cloud already holds when uploading a drop Each file is hashed while it is packed, and before a batch goes up the uploader asks the provider's assets.exists which digests the library already has. Those files stay home — the batch is packed again without them — and a bucket drop still adds the existing assets to the bucket. The summary says how many were already there. Batches no longer keep raw bytes for the single-file fallback; they read the files again instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Cover the dedupe count in the upload summary test Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Offer to delete a cloud folder's contents along with it The delete-folder dialog gains a checkbox; ticked, the provider removes every photo and sub-folder in the subtree. Cloud dialogs can now carry yes/no fields (cloud-check-*), drawn with the shared Checkbox. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Tell prepare_batch the packed count, not the drop's After dedupe left files out of a batch, the prepare still declared the original number, and the provider rejected the payload as a changed file count. The declared count now follows the packed entries. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Send files too big for a batch on their own again The dedupe rewrite packed an oversize single file (48–100 MiB) into a one-file payload, which the provider refuses above its 64 MiB batch cap. Such files are a distinct item now: checked for a duplicate, then sent as one plain upload, never packed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * Run on iOS and iPadOS Schist builds for aarch64-apple-ios and the Simulator targets through the gpui fork's iOS backend (pinned at 135fff5). tools/ios-build.sh builds, bundles (packaging/ios/Info.plist) and launches it on a Simulator; tools/ios-test.sh runs a crate's tests there; docs/ios.md describes the port. A `sandboxed` cfg (crates/app/build.rs; wasm32 and iOS) compiles out what a sandboxed app cannot host: both plug-in hosts, the AI sidebar and its MCP bridge, the self-updater, drag-out and Quit. iOS keeps the gallery, the GPU compositor (its parity tests pass on the Simulator's Metal GPU), the crash reporter and the cloud. Touch chrome, one switch (ui::touch) and two metric tables: 44pt targets throughout; a scrollable toolbar; menu bar titles that open native menus (popovers on iPad, sheets with nested submenus on iPhone), in a bar that scrolls sideways on a phone and is not drawn on iPadOS, which has a system menu bar; options-bar sliders as buttons opening popover sliders; on a phone the panel column swapped in for the canvas and the gallery sidebar as a swipeable drawer; the gallery strip folded into a "..." menu on a phone; a grip that resizes the history panel; a pinch on the gallery grid in place of the thumbnail-size slider; rows, links and tiles acting on a tap's release so a swipe never fires them; dialogs fitting the window and scrolling; container paths never shown; Apple Symbols and Zapf Dingbats as text fallbacks for the chrome's symbols. The software keyboard comes up for every field: the fields keep their own buffers, so an input handler is registered while one is active and the keyboard's text replayed as keystrokes. Native on iOS: HEIC through ImageIO; "Import from Photos..." through PHPickerViewController; "Save to Photos" (File menu, options bar) into the camera roll; a file handed over by another app asked about, gallery or editor. library.json keeps in-container paths as $SANDBOX, since iOS moves the container on every install. Preferences stays in View on iOS, and the gallery's menus are pruned like the editor's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Schist Cloud to the desktop app and hosted WASM editor: live folders and buckets, scoped searches and filters, uploads/downloads, and collaborative image editing. Workspace operations and Yjs-compatible binary updates share one authenticated MessagePack WebSocket. The existing generation API retains its separate per-job stream.
Desktop sign-in prompts for a provider domain with
schist.appprefilled, registers the native callback on Linux/macOS/Windows, and stores credentials in the OS credential store. Browser sign-in is restricted tohttps://try.schist.appconnecting toschist.app. A popup returns a state-bound, verifier-bound authorization code without replacing the editor page; the client checks its origin, popup identity and state. Browser credentials remain in tab memory.The new
schist-documentlibrary and standalone MessagePack worker share the image model and built-in codec registry between the editor and provider. PSD registration is shared with the desktop app, and the model retains WASM-compatible undo timing.Documents bind to asset IDs and preserve their folder association. Collaborative property/tile updates support reconnect synchronization, local undo and native crash recovery. Capability discovery controls supported models, export choices, negotiated frame limits and merged-document limits. Revision-conflicted downloads fetch fresh tickets, retaining HTTP metadata and revisions. Terminal document errors preserve local edits and require explicit reopening before sync resumes.
Local files/folders upload through signed HTTPS tickets; remote folder drops add bucket references. WASM file/folder pickers retain relative paths, and downloads use the browser download flow. Native filesystem dragging and recovery across page reloads remain desktop features. Backend downloads now serve through the provider, including S3-backed files, without requiring storage bucket CORS.
Coordinated backend changes are pushed to schist-cloud. Both the Markdown protocol and TypeScript reference include the browser extension. No TypeScript implementation or tests are added to this Schist PR.
Validation:
make check-cloud-wasmadds a repeatable browser test target.Live WorkOS sign-in and account persistence have not been exercised against a real provider account. Browser adapter tests use a mock WebSocket peer in Chromium; they do not replace a deployed-provider smoke test. Browser edits survive socket reconnects in the current tab, but there is no filesystem crash recovery across page reloads.