fix(apple-ui): share-ext prepare phases + clipboard + expiry pill - #8
Conversation
…0% freeze" User reported that uploading a 125 MB video froze the share sheet for 10-15s showing "Uploading… 0%" before the progress actually moved. It wasn't frozen — SHA-256 hash of the whole file plus multipart presign was running silently. Now the UI narrates every phase: - `.hashing(bytesHashed, totalBytes)` — SHA256Streamer gained a chunked overload that calls back every 1 MB. Label: "Preparing file…" with a determinate bar from 0 → 100% as the hash advances. - `.presigning` — emitted right after hash. Label: "Creating link…" with an indeterminate shimmer bar (presign + multipart init round-trip). - `.uploading(progress, …)` — existing, unchanged. - `.finalizing` — emitted after last R2 PUT, before POST /complete on the multipart path. Label: "Finalizing…" with indeterminate shimmer. UploadService picked up a new `UploadPreparePhase` enum + optional `prepareObserver` closure on `enqueue`. The protocol is unchanged — the legacy `enqueue(…)` is now a shim that passes `nil`. Bundle path untouched (it already had real-time aggregate progress). ShareViewModel's SwiftData poll (150ms) used to clobber the observer's pretty label back to `.preparing`; it now respects a transient phase already set by the observer and only overrides on terminal states.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 54 minutes and 17 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughO PR introduz rastreamento granular de fases de preparação de upload (hashing, presigning, finalizing) com callbacks de observação, permitindo que a interface de usuário exiba progresso determinado durante hash e progresso indeterminado durante presigning/finalizing através de novos tipos e lógica de renderização aprimorada. Changes
Sequence Diagram(s)sequenceDiagram
participant VC as ShareViewController
participant US as UploadService
participant Hasher as SHA256Streamer
participant VM as ShareViewModel
participant Root as ShareRootView
VC->>US: enqueue(..., prepareObserver:)
US->>VM: prepareObserver(.hashing(0, total))
VM->>Root: applyPreparePhase(.hashing)
Root->>Root: render progress UI
US->>Hasher: hash(fileAt:, progress:)
Hasher->>Hasher: read chunks (1MB)
Hasher->>US: progress(bytesHashed)
US->>VM: prepareObserver(.hashing(N, total))
VM->>Root: applyPreparePhase(.hashing)
Root->>Root: update percent + bar
US->>VM: prepareObserver(.presigning)
VM->>Root: applyPreparePhase(.presigning)
Root->>Root: render shimmer bar
US->>US: await presign responses
US->>VM: prepareObserver(.finalizing)
VM->>Root: applyPreparePhase(.finalizing)
Root->>Root: render finalizing state
US->>US: complete upload
VM->>Root: phase = .success
Root->>Root: render success
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutos Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Two issues on the success sheet: 1. Link wasn't being copied to clipboard reliably. `copyIfNeeded` only flipped the visual `copied` flag — it assumed the orchestrator had already written to the pasteboard, which sometimes didn't stick if another app clobbered it between /complete and the sheet render. Now `copyIfNeeded` (single) and `BundleSuccessStage.onAppear` defensively rewrite `UIPasteboard.general.setItems` with the shortURL. Idempotent on top of the orchestrator write. 2. "X hour before it expires" pill was left-aligned with loose padding and bleeding across the sheet. Tightened: Capsule fill, autofit width, center alignment, ring 16pt instead of 24pt, subtler opacity.
Três fixes de UX na Share Extension num build:
1. "0% freeze" em uploads grandes
Upload de 125 MB travava a tela por 10-15s antes do progresso mexer — era SHA256 + multipart presign rodando silencioso. Agora cada fase é narrada:
SHA256Streamerganhou overload chunked (1 MB) com callback.UploadServicenovoUploadPreparePhase+prepareObserver. Assinatura legacy preservada.ShareViewModelnão atropela fase transient do observer durante poll SwiftData.2. Link não copiava pro clipboard
copyIfNeededsó flipava o flag visual, sem gravar no pasteboard. Se outro app clobberasse o pasteboard entre /complete e o render do sheet, o user ficava sem link copiado.Agora
copyIfNeeded(single) eBundleSuccessStage.onAppeardefensivamente reescrevemUIPasteboard.general.setItemscom o shortURL — idempotente sobre o write do orchestrator.3. Pill "1 hour before it expires" desalinhado
Left-aligned com padding solto e bleeding. Agora é Capsule autofit centrado, ring 16pt, opacity suave.
Test plan
🤖 Generated with Claude Code