Remove unused Capacitor plugin implementation and simplify shared image
handling to use only the temp file approach, which is already working
reliably for both iOS and Android.
Changes:
- Delete ios/App/App/ShareImagePlugin.swift (unused, never registered)
- Delete ios/App/App/ShareImageBridge.swift (only used by plugin)
- Remove ~80 lines of plugin fallback code from src/main.capacitor.ts
- Simplify error handling to single code path
- Add documentation comment explaining temp file approach and future
plugin implementation possibility
Benefits:
- ~154 lines of code removed
- Single, consistent code path for both platforms
- Easier to maintain and debug
- No functional changes - temp file approach already working
The temp file approach uses Capacitor's Filesystem plugin to read shared
image data written by native code (AppDelegate on iOS, MainActivity on
Android). This is simpler and more reliable than the plugin approach,
which required registration and bridge setup.
Future improvement: Consider implementing Capacitor plugins for direct
native-to-JS communication if lower latency becomes a priority, though
the current approach performs well in production.
Improve iOS share extension implementation to skip interstitial UI and
fix issues with subsequent image shares not updating the view.
iOS Share Extension Improvements:
- Replace SLComposeServiceViewController with custom UIViewController
to eliminate interstitial "Post" button UI
- Use minimal URL (timesafari://) instead of deep link for app launch
- Implement app lifecycle detection via Capacitor appStateChange listener
instead of relying solely on deep links
Deep Link and Navigation Fixes:
- Remove "shared-photo" from deep link schemas (no longer needed)
- Add empty path URL handling for share extension launches
- Implement processing lock to prevent duplicate image processing
- Add retry mechanism (300ms delay) to handle race conditions with
AppDelegate writing temp files
- Use router.replace() when already on /shared-photo route to force refresh
- Clear old images from temp DB before storing new ones
- Delete temp file immediately after reading to prevent stale data
SharedPhotoView Component:
- Add route watcher (@Watch) to reload image when fileName query
parameter changes
- Extract image loading logic into reusable loadSharedImage() method
- Improve error handling to clear image state on failures
This fixes the issue where sharing a second image while already on
SharedPhotoView would display the previous image instead of the new one.
Implement iOS Share Extension to enable native image sharing from Photos
and other apps directly into TimeSafari. Users can now share images from
the iOS share sheet, which will open in SharedPhotoView for use as gifts
or profile pictures.
iOS Native Implementation:
- Add TimeSafariShareExtension target with ShareViewController
- Configure App Groups for data sharing between extension and main app
- Implement ShareViewController to process shared images and convert to base64
- Store shared image data in App Group UserDefaults
- Add ShareImageBridge utility to read shared data from App Group
- Update AppDelegate to handle shared-photo deep link and bridge data to JS
JavaScript Integration:
- Add checkAndStoreNativeSharedImage() in main.capacitor.ts to read shared
images from native layer via temporary file bridge
- Convert base64 data to data URL format for compatibility with base64ToBlob
- Integrate with existing SharedPhotoView component
- Add "shared-photo" to deep link validation schema
Build System:
- Integrate Xcode 26 / CocoaPods compatibility workaround into build-ios.sh
- Add run_pod_install_with_workaround() for explicit pod install
- Add run_cap_sync_with_workaround() for Capacitor sync (which runs pod
install internally)
- Automatically detect project format version 70 and apply workaround
- Remove standalone pod-install-workaround.sh script
Code Cleanup:
- Remove verbose debug logs from ShareViewController, AppDelegate, and
main.capacitor.ts
- Retain essential logger calls for production debugging
Documentation:
- Add ios-share-extension-setup.md with manual Xcode setup instructions
- Add ios-share-extension-git-commit-guide.md for version control best practices
- Add ios-share-implementation-status.md tracking implementation progress
- Add native-share-target-implementation.md with overall architecture
- Add xcode-26-cocoapods-workaround.md documenting the compatibility issue
The implementation uses a temporary file bridge (AppDelegate writes to Documents
directory, JS reads via Capacitor Filesystem plugin) as a workaround for
Capacitor plugin auto-discovery issues. This can be improved in the future by
properly registering ShareImagePlugin in Capacitor's plugin registry.
Android build was failing due to missing drawable and mipmap directories
for splash screens and launcher icons. iOS was missing complete asset
catalog structure for app icons and splash screens.
- Create missing Android resource directories (drawable, mipmap-*)
- Add splash screen files to Android drawable directory
- Generate complete set of Android launcher icons
- Create iOS asset catalog structure with proper Contents.json files
- Generate 21 iOS assets (app icons + splash screens) using ImageMagick
- Add resource validation scripts for both platforms
- Enhance Android resource check to auto-create missing directories
NOTE: you need to test this from a fresh clone and after an npm install!
Android build now completes successfully. iOS assets ready for macOS/Xcode
builds. Both platforms have complete resource sets for development.
- Add @capawesome/capacitor-file-picker dependency
- Update DataExportSection UI text to reflect new file picker behavior
- Implement file picker in CapacitorPlatformService
- Add debug logging for path handling
- Fix logger to show messages in Capacitor environment
WIP: File path handling still needs refinement
Adds native deep linking capabilities:
- Configure timesafari:// URL scheme for iOS and Android
- Add @capacitor/app dependency and configuration
- Implement deep link handler with improved error logging
- Support parameterized routes like claim/:id
- Add debug logging for native platforms
- Handle app mounting state for deep links
Technical changes:
- Update AndroidManifest.xml with intent filters
- Add URL scheme to iOS Info.plist
- Add @capacitor/app to Podfile and Gradle
- Enhance main.capacitor.ts with robust deep link handling