Align iOS TipTap images with Android (width presets, ⋯ actions, WebP
compress, reliable preview). Persist contentJson so image width survives
detail/viewer; force shared WebView re-push and block late autosave so
new notes open empty. Long-press fullscreen image preview opens resource
actions on both iOS and Android.
Make create Back commit like Android so notes appear in the list and the
next New note opens empty. Harden memo-card press feedback, allow
programmatic WKWebView keyboard focus, and pin the format toolbar above
the scrolling editor body so it no longer jumps under the software keyboard.
Give the rich-text and Markdown editors a dedicated hyperlink entry
separate from note linking, with Ctrl/Cmd+K, URL normalization, and
remove-link support. Closes the discoverability gap in #192; link
preview cards remain out of scope.
Related Issue: #192
Bump marketing/build versions for the Swift client, reuse the existing
App Store share-extension App ID, and add ExportOptions/fastlane/archive
scripts so the native binary can be signed and submitted without EAS iOS.
Pre-store bumps set package and Expo marketing versions to 1.12.6 without a GitHub Release. Restore the formal baseline so release automation can cut v1.12.6. Keep Android versionCode at 86 so the release commit advances it safely.
Unify /blob path normalization for authenticated note images, log and surface load failures once per note, and show a skeleton instead of a broken-image flash while resources decode.
Root bun install does not install apps/ios/EditorSource deps, so
including its Vite config in root typecheck failed with missing
vite-plugin-singlefile. Mirror mobile: exclude the nested package
and expose typecheck:ios-editor for optional local checks.
Fixes#189
Rebase stale outbox revisions, leave edit onto the list without flashing
detail, treat TipTap JSON as structural truth for image order while
deriving markdown for sync, and force the detail viewer through
setMarkdown so flattened contentJson no longer kills headings/lists.
Replace the silent PhotosPicker/Transferable path with PHPicker, insert
into TipTap with local hydrate, and flush materialized create/edit body
so uploaded images survive list → detail reopen.
Focus at document end only once when opening a note for edit. SwiftUI
re-binds and setContent no longer call focusEnd on every keystroke, so
mid-document editing keeps the caret in place.
Keep one long-lived viewer and editor WKWebView so switching notes only
rebinds setContent instead of reloading the EditorBundle. Warm both
runtimes after sign-in, restore Evernote-style focus-at-end on edit,
block empty autosave from clobbering notes, and stop showing flattened
contentText when the rich viewer is still booting.
Add bottom-sheet resource actions (share, download, rename, delete)
with success and failure feedback. Viewer image tap opens fullscreen
preview; long-press and attachment taps open the menu. Download uses
the Files export picker so users always know whether the save worked.
Pre-hydrate protected image srcs before TipTap setContent so file://
WebView never loads /api paths under sandbox. Detect SVG correctly,
emit data URLs for SVG assets, treat numeric image width as percent,
and keep unit tests off real demo cache keys.
Authenticated and remote images in TipTap now load via a custom
edgeever-res scheme after native fetch, so the file:// editor can
display protected blobs. Bottom create control sits under the tab
separator at a smaller size, and list decode skips corrupt memo rows
instead of blanking the feed.
Replace the abandoned RN iOS path with a SwiftUI app (iOS 17+) that reuses
the shared TipTap editor bundle, GRDB local mirror/outbox, and Android-aligned
shell chrome for list, create, detail, and Me. Package the editor HTML in the
app resources so Markdown renders, present edit from the workspace root with a
UIKit FAB, and keep caret stable while typing.
Android edits could stay pending after pull-to-refresh because content always queued and refresh only pulled. Save online when reachable, force-flush the outbox on refresh and resume, and surface retry/error details so Web sees Android changes again.
Related Issue: #185
Unsynced notes used local temporary IDs while multi-select delete only
called the remote API, so empty notes could not be removed and failed
silently. Delete local-only notes offline, soft-delete remotes after
API success, remap multi-select IDs, and surface delete errors.
Refs #184
Read-only Cloudflare forks were getting silent green no-ops when already
aligned, or unclear merge skips after Sync fork. Align deploy-only forks
with reset, keep merge for customized trees, always write a job summary,
and document force_redeploy plus an optional Cloudflare Deploy Hook.
Detail preview now uses static HTML WebView instead of Dom TipTap. Stagger
TextInput and editor host mount/teardown for edit, Me, create, and back so
Fabric ShadowNode measure and Hermes GC no longer SIGSEGV on iPadOS 26.5.
Apple rejected 1.10.1 for SIGSEGV in RCTTextLayoutManager and malloc
corruption during WKWebView media TCC probes on iPad. Drop Reanimated
list layout transitions, deny DOM/WebView media capture by default, and
declare required iOS privacy strings with full-screen phone-on-iPad
presentation for the next review build.
Read RN blobs via FileReader instead of missing Blob.arrayBuffer, dismiss
the action sheet before SAF/share UI, surface cancel/errors, and confirm
successful folder exports.
Give Web, desktop, and mobile the same product-baseline conflict recovery:
copy the local draft, then adopt the cloud version and rehydrate, instead of
telling users to reload while durable local conflict state remains.
Equalize columns via container-query widths so typical tables wrap in place, and scroll only inside tableWrapper when many columns still overflow. Preview and edit share LocalTiptapEditor styles.
Use MEMO_CONTENT_STYLE (15px / 24 line-height) for the mobile editor and
preview WebView instead of a hardcoded 17px body, and size headings in rem
so notes feel consistent with desktop reading density.
Wide tables and flex attachment rows were expanding the editor shell past
the viewport, so text and cells clipped on the right. Cap the shell/content
to 100%, use content-relative table column widths instead of 100vw, and
scroll wide tables inside their wrappers.
Bind resource actions on the image control itself instead of relying on
ProseMirror handleClick after pointerdown preventDefault, which Android
WebView often suppresses. Also accept resource URLs without a /blob suffix.
Prebuild a full iconutil ICNS (including 1024) instead of converting a lone
512 PWA PNG, validate Dock-critical types at package verify time, and set the
Dock icon at runtime as a Launch Services cache fallback.
Surface revision, content, edit-session, and offline-stale conflict details in the editor, keep error metadata through the sync queue, and avoid hook-order crashes plus stale dev service workers after failed HMR.
Make deleting notes one click on desktop list cards instead of buried under the more menu, while keeping the existing menu path for keyboard and right-click.
getStoredMermaidRenderer assumed localStorage always exists whenever window
was defined, so full bun test runs could fail after other suites stubbed a
partial window. Safe-read the storage key and clean up shared window mocks
so Verify update stays green for forked deployments.
Stop getMemo background refresh from overwriting newer local autosaves or
queued updates, and skip redundant setContent when reopening a note so the
caret no longer jumps to the end after detail refetches.