@legendapp/spark 0.0.1-next.2 → 0.0.1-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -4
- package/ai-codex.ts +1 -0
- package/ai.ts +1 -0
- package/app-documents.ts +1 -0
- package/camera.ts +13 -0
- package/config-plugin.d.cts +2 -0
- package/contracts.ts +2 -0
- package/diagnostics.ts +1 -0
- package/expo-config.d.cts +1 -0
- package/metro.cjs +4 -1
- package/metro.d.cts +12 -0
- package/native.cjs +3 -1
- package/native.d.cts +6 -0
- package/package.json +93 -15
- package/patches/camera/react-native-nitro-image.patch +320 -0
- package/patches/camera/react-native-nitro-modules.patch +50 -0
- package/patches/camera/react-native-vision-camera.patch +2662 -0
- package/patches/camera/upstream.json +22 -0
- package/patches/dependencies.json +8 -0
- package/patches/react-native-enriched-markdown@1.0.2.patch +8684 -0
- package/postinstall.cjs +1 -0
- package/schema.json +276 -58
- package/settings-observable.ts +1 -0
- package/settings-window.ts +1 -0
- package/shortcuts-commands.ts +1 -0
- package/shortcuts-keyboard.ts +3 -0
- package/ui-classnames.ts +1 -0
- package/ui-glass.ts +1 -0
- package/ui-search.ts +1 -0
- package/ui-sidebar.ts +1 -0
- package/ui-split-view.ts +1 -0
- package/ui-swipe.ts +1 -0
- package/ui-symbol.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
- package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
- package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
- package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
- package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
- package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
- package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
- package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
- package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
- package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
- package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +145 -59
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +61 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +10 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +37 -8
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +86 -25
- package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +13 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +13 -10
- package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +52 -44
- package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +86 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +90 -32
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +86 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
- package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
- package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +5 -9
- package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +12 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
- package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
- package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
- package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
- package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
- package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +116 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +18 -3
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.cjs +106 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.d.cts +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +7 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
- package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
- package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
- package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3169 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +146 -70
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
- package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
- package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
- package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
- package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
- package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
- package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
- package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
- package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
- package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
- package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
- package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
- package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +51 -8
- package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
- package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
- package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
- package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
- package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
- package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
- package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
- package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
- package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
- package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1419 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.h +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.mm +422 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
- package/vendor/node_modules/@legendapp/spark-ui/package.json +17 -4
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +37 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +86 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
- package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
- package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
- package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
- package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
- package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/index.tsx +41 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
- package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
- package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
- package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
- package/windows-macos.ts +1 -0
- package/expo-metro.cjs +0 -1
- package/message-dialog.ts +0 -1
- package/universal.cjs +0 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
import type { DirectEventHandler, Int32 } from "react-native/Libraries/Types/CodegenTypes";
|
|
4
|
+
|
|
5
|
+
export type NativeSelectChangeEvent = {
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface NativeProps extends ViewProps {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
selectionRevision?: Int32;
|
|
12
|
+
itemsJson: string;
|
|
13
|
+
onValueChange?: DirectEventHandler<NativeSelectChangeEvent>;
|
|
14
|
+
value: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default codegenNativeComponent<NativeProps>("NativeSelect") as HostComponent<NativeProps>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
1
2
|
import type { SelectProps } from "./types";
|
|
2
|
-
export function selectionIndex(options: SelectProps["options"], value: string) {
|
|
3
|
-
if (!options.length || new Set(options.map(option => option.value)).size !== options.length) throw new
|
|
3
|
+
export function selectionIndex(options: SelectProps["options"], value: string): number {
|
|
4
|
+
if (!Array.isArray(options) || !options.length || Array.from(options).some(option => !option || typeof option !== "object" || typeof option.label !== "string" || !option.label.length || typeof option.value !== "string") || new Set(options.map(option => option.value)).size !== options.length) throw new SparkError("E_INVALID_ARGUMENT", "Select options must have nonempty labels and unique string values");
|
|
5
|
+
for (const option of options) for (const key of Object.keys(option)) if (key !== "label" && key !== "value") throw new SparkError("E_UNSUPPORTED_OPTION", `Unknown select option: ${key}`);
|
|
4
6
|
const index = options.findIndex(option => option.value === value);
|
|
5
|
-
if (index < 0) throw new
|
|
7
|
+
if (index < 0) throw new SparkError("E_INVALID_ARGUMENT", "Select value must match an option");
|
|
6
8
|
return index;
|
|
7
9
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CodegenTypes, ColorValue, HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
|
|
4
|
+
export interface NativeProps extends ViewProps {
|
|
5
|
+
name: string;
|
|
6
|
+
onSymbolError?: CodegenTypes.DirectEventHandler<Readonly<{ name: string; message: string }>>;
|
|
7
|
+
color?: ColorValue;
|
|
8
|
+
scale?: string;
|
|
9
|
+
size?: CodegenTypes.Double;
|
|
10
|
+
yOffset?: CodegenTypes.Double;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default codegenNativeComponent<NativeProps>("SFSymbol") as HostComponent<NativeProps>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { View, type ColorValue, type NativeSyntheticEvent } from "react-native";
|
|
2
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
3
|
+
import { useControl } from "../control";
|
|
4
|
+
import { finite, identifier, macosViewAvailability, type SpecializedViewProps } from "../specialized";
|
|
5
|
+
import NativeSFSymbol from "./SFSymbolNativeComponent";
|
|
6
|
+
export type SFSymbolScale = "small" | "medium" | "large";
|
|
7
|
+
export interface SFSymbolProps extends Omit<SpecializedViewProps, "children"> {
|
|
8
|
+
name: string;
|
|
9
|
+
color?: ColorValue;
|
|
10
|
+
scale?: SFSymbolScale;
|
|
11
|
+
size?: number;
|
|
12
|
+
yOffset?: number;
|
|
13
|
+
}
|
|
14
|
+
export function getSFSymbolAvailability() { return macosViewAvailability("SFSymbol"); }
|
|
15
|
+
export function SFSymbol({ name, color, scale = "medium", size = 24, yOffset = 0, ref, onError, style, ...props }: SFSymbolProps) {
|
|
16
|
+
identifier(name, "symbol name"); finite(size, "symbol size", 1); finite(yOffset, "symbol offset", -Infinity);
|
|
17
|
+
if (!["small", "medium", "large"].includes(scale)) throw new SparkError("E_INVALID_ARGUMENT", "Invalid symbol scale");
|
|
18
|
+
const control = useControl({ ref, onError }, getSFSymbolAvailability());
|
|
19
|
+
const frame = [{ height: size, width: size }, style];
|
|
20
|
+
function error(event: NativeSyntheticEvent<{ name: string; message: string }>) {
|
|
21
|
+
if (!control.active()) return;
|
|
22
|
+
if (typeof event?.nativeEvent?.name !== "string" || typeof event?.nativeEvent?.message !== "string") { control.error(new SparkError("E_INVALID_DATA", "Invalid symbol error")); return; }
|
|
23
|
+
if (event.nativeEvent.name === name) control.error(new SparkError("E_NOT_FOUND", event.nativeEvent.message));
|
|
24
|
+
}
|
|
25
|
+
if (control.failed) return <View {...props} ref={control.ref} style={frame} />;
|
|
26
|
+
return <NativeSFSymbol {...props} ref={control.ref} name={name} color={color} scale={scale} size={size} yOffset={yOffset} style={frame} onSymbolError={error} />;
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
import type { DirectEventHandler, Double } from "react-native/Libraries/Types/CodegenTypes";
|
|
4
|
+
|
|
5
|
+
export type SidebarItemRightClickEvent = Readonly<{
|
|
6
|
+
altKey: boolean;
|
|
7
|
+
button: Double;
|
|
8
|
+
ctrlKey: boolean;
|
|
9
|
+
metaKey: boolean;
|
|
10
|
+
pageX: Double;
|
|
11
|
+
pageY: Double;
|
|
12
|
+
shiftKey: boolean;
|
|
13
|
+
x: Double;
|
|
14
|
+
y: Double;
|
|
15
|
+
}>;
|
|
16
|
+
|
|
17
|
+
export interface NativeProps extends ViewProps {
|
|
18
|
+
autoHeight?: boolean;
|
|
19
|
+
itemId?: string;
|
|
20
|
+
onRightClick?: DirectEventHandler<SidebarItemRightClickEvent>;
|
|
21
|
+
rowHeight?: Double;
|
|
22
|
+
selectable?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default codegenNativeComponent<NativeProps>("SidebarItem") as HostComponent<NativeProps>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
import type { DirectEventHandler, Double, Int32 } from "react-native/Libraries/Types/CodegenTypes";
|
|
4
|
+
|
|
5
|
+
export type SidebarSelectionChangeEvent = Readonly<{
|
|
6
|
+
id: string;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
export type SidebarLayoutEvent = Readonly<{
|
|
10
|
+
height: Double;
|
|
11
|
+
width: Double;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export interface NativeProps extends ViewProps {
|
|
15
|
+
contentInsetTop?: Double;
|
|
16
|
+
defaultRowHeight?: Double;
|
|
17
|
+
itemsJson?: string;
|
|
18
|
+
onSidebarLayout?: DirectEventHandler<SidebarLayoutEvent>;
|
|
19
|
+
onSidebarSelectionChange?: DirectEventHandler<SidebarSelectionChangeEvent>;
|
|
20
|
+
selectedId?: string;
|
|
21
|
+
selectionRevision?: Int32;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default codegenNativeComponent<NativeProps>("Sidebar") as HostComponent<NativeProps>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Children, Fragment, createContext, isValidElement, useContext, useMemo, useState, type ReactElement, type ReactNode } from "react";
|
|
2
|
+
import { Text, View, type NativeSyntheticEvent } from "react-native";
|
|
3
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
4
|
+
import { useControl } from "../control";
|
|
5
|
+
import { callback, finite, identifier, macosViewAvailability, type SpecializedViewProps } from "../specialized";
|
|
6
|
+
import NativeSidebar from "./SidebarNativeComponent";
|
|
7
|
+
import NativeSidebarItem from "./SidebarItemNativeComponent";
|
|
8
|
+
export interface SidebarItemData { id: string; label: string; selectable?: boolean }
|
|
9
|
+
export type SidebarRowHeight = number | "auto";
|
|
10
|
+
export interface SidebarSelectionEvent { id: string | null }
|
|
11
|
+
export interface SidebarContentLayoutEvent { width: number; height: number }
|
|
12
|
+
export interface SidebarContextMenuEvent {
|
|
13
|
+
id: string;
|
|
14
|
+
/** Logical top-left coordinates within the row and the owning window's content. */
|
|
15
|
+
position: { x: number; y: number };
|
|
16
|
+
windowPosition: { x: number; y: number };
|
|
17
|
+
modifiers: { alt: boolean; control: boolean; meta: boolean; shift: boolean };
|
|
18
|
+
}
|
|
19
|
+
export interface SidebarBaseProps extends Omit<SpecializedViewProps, "children"> {
|
|
20
|
+
contentInsetTop?: number;
|
|
21
|
+
defaultRowHeight?: number;
|
|
22
|
+
selectedId: string | null;
|
|
23
|
+
onContentLayout?: (event: SidebarContentLayoutEvent) => void;
|
|
24
|
+
onSelectionChange: (event: SidebarSelectionEvent) => void;
|
|
25
|
+
}
|
|
26
|
+
export type SidebarProps = SidebarBaseProps & ({ items: readonly SidebarItemData[]; children?: never } | { items?: never; children: ReactNode });
|
|
27
|
+
export interface SidebarItemProps extends SpecializedViewProps {
|
|
28
|
+
id: string;
|
|
29
|
+
rowHeight?: SidebarRowHeight;
|
|
30
|
+
selectable?: boolean;
|
|
31
|
+
onContextMenu?: (event: SidebarContextMenuEvent) => void;
|
|
32
|
+
}
|
|
33
|
+
const SidebarContext = createContext(false);
|
|
34
|
+
export function getSidebarAvailability() {
|
|
35
|
+
const availability = macosViewAvailability("Sidebar");
|
|
36
|
+
return availability.available ? macosViewAvailability("SidebarItem") : availability;
|
|
37
|
+
}
|
|
38
|
+
function childRows(children: ReactNode): ReactElement<SidebarItemProps>[] {
|
|
39
|
+
const rows: ReactElement<SidebarItemProps>[] = [];
|
|
40
|
+
Children.forEach(children, child => {
|
|
41
|
+
if (child === null) return;
|
|
42
|
+
if (isValidElement<{ children?: ReactNode }>(child) && child.type === Fragment) { rows.push(...childRows(child.props.children)); return; }
|
|
43
|
+
if (!isValidElement<SidebarItemProps>(child) || child.type !== SidebarItem) throw new SparkError("E_INVALID_ARGUMENT", "Sidebar children must be SidebarItem elements or fragments");
|
|
44
|
+
rows.push(child);
|
|
45
|
+
});
|
|
46
|
+
return rows;
|
|
47
|
+
}
|
|
48
|
+
export function Sidebar({ items, children, selectedId, contentInsetTop = 0, defaultRowHeight = 28, onContentLayout, onSelectionChange, ref, onError, ...props }: SidebarProps) {
|
|
49
|
+
finite(contentInsetTop, "content inset"); finite(defaultRowHeight, "row height", 1);
|
|
50
|
+
callback(onContentLayout, "content layout");
|
|
51
|
+
if (typeof onSelectionChange !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Sidebar selection is controlled and requires onSelectionChange");
|
|
52
|
+
if (items !== undefined && (children !== undefined || !Array.isArray(items))) throw new SparkError("E_INVALID_ARGUMENT", "Use either items or SidebarItem children");
|
|
53
|
+
const { selectableIds, itemsJson } = useMemo(() => {
|
|
54
|
+
const rows = items === undefined ? childRows(children) : [];
|
|
55
|
+
const entries = items === undefined ? rows.map(row => ({ id: row.props.id, selectable: row.props.selectable })) : items;
|
|
56
|
+
const ids = new Set<string>(), selectableIds = new Set<string>();
|
|
57
|
+
for (const item of entries) {
|
|
58
|
+
if (!item || typeof item !== "object") throw new SparkError("E_INVALID_ARGUMENT", "Invalid sidebar item");
|
|
59
|
+
identifier(item.id, "sidebar ID");
|
|
60
|
+
if (ids.has(item.id)) throw new SparkError("E_INVALID_ARGUMENT", "Sidebar IDs must be unique"); ids.add(item.id);
|
|
61
|
+
if (item.selectable !== undefined && typeof item.selectable !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Expected selectable boolean");
|
|
62
|
+
if (items !== undefined) identifier((item as SidebarItemData).label, "sidebar label");
|
|
63
|
+
if (item.selectable !== false) selectableIds.add(item.id);
|
|
64
|
+
}
|
|
65
|
+
return { selectableIds, itemsJson: items === undefined ? "" : JSON.stringify(items.map(({ id, label, selectable = true }) => ({ id, title: label, selectable }))) };
|
|
66
|
+
}, [items, children]);
|
|
67
|
+
if (selectedId !== null && !selectableIds.has(selectedId)) throw new SparkError("E_INVALID_ARGUMENT", "Selected sidebar ID must identify a selectable row");
|
|
68
|
+
const control = useControl({ ref, onError }, getSidebarAvailability());
|
|
69
|
+
const [selectionRevision, revise] = useState(0);
|
|
70
|
+
function selection(event: NativeSyntheticEvent<{ id: string }>) {
|
|
71
|
+
if (!control.active()) return;
|
|
72
|
+
const id = event?.nativeEvent?.id;
|
|
73
|
+
if (typeof id !== "string" || (id !== "" && !selectableIds.has(id))) { control.error(new SparkError("E_INVALID_DATA", "Invalid sidebar selection")); return; }
|
|
74
|
+
revise(value => value + 1); onSelectionChange?.({ id: id || null });
|
|
75
|
+
}
|
|
76
|
+
function layout(event: NativeSyntheticEvent<{ width: number; height: number }>) {
|
|
77
|
+
if (!control.active()) return;
|
|
78
|
+
try { finite(event?.nativeEvent?.width, "content width"); finite(event?.nativeEvent?.height, "content height"); }
|
|
79
|
+
catch (cause) { control.error(new SparkError("E_INVALID_DATA", "Invalid sidebar layout", { cause })); return; }
|
|
80
|
+
onContentLayout?.({ width: event.nativeEvent.width, height: event.nativeEvent.height });
|
|
81
|
+
}
|
|
82
|
+
if (control.failed) return <View {...props} ref={control.ref}><SidebarContext.Provider value>{items?.map(item => <Text key={item.id}>{item.label}</Text>) ?? children}</SidebarContext.Provider></View>;
|
|
83
|
+
return <NativeSidebar {...props} ref={control.ref} itemsJson={itemsJson} selectedId={selectedId ?? ""} selectionRevision={selectionRevision} contentInsetTop={contentInsetTop} defaultRowHeight={defaultRowHeight} onSidebarLayout={layout} onSidebarSelectionChange={selection}>
|
|
84
|
+
<SidebarContext.Provider value>{children}</SidebarContext.Provider>
|
|
85
|
+
</NativeSidebar>;
|
|
86
|
+
}
|
|
87
|
+
export function SidebarItem({ id, children, rowHeight, selectable = true, onContextMenu, ref, onError, ...props }: SidebarItemProps) {
|
|
88
|
+
if (!useContext(SidebarContext)) throw new SparkError("E_INVALID_ARGUMENT", "SidebarItem requires a Sidebar parent");
|
|
89
|
+
identifier(id, "sidebar ID"); callback(onContextMenu, "context menu");
|
|
90
|
+
if (rowHeight !== undefined && rowHeight !== "auto") finite(rowHeight, "row height", 1);
|
|
91
|
+
if (typeof selectable !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Expected selectable boolean");
|
|
92
|
+
const control = useControl({ ref, onError }, getSidebarAvailability());
|
|
93
|
+
function contextMenu(event: NativeSyntheticEvent<{ x: number; y: number; pageX: number; pageY: number; altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean }>) {
|
|
94
|
+
if (!control.active()) return;
|
|
95
|
+
const data = event?.nativeEvent;
|
|
96
|
+
try {
|
|
97
|
+
for (const key of ["x", "y", "pageX", "pageY"] as const) finite(data?.[key], key, -Infinity);
|
|
98
|
+
for (const key of ["altKey", "ctrlKey", "metaKey", "shiftKey"] as const) if (typeof data[key] !== "boolean") throw new Error("Invalid modifiers");
|
|
99
|
+
} catch (cause) { control.error(new SparkError("E_INVALID_DATA", "Invalid sidebar context menu event", { cause })); return; }
|
|
100
|
+
onContextMenu?.({ id, position: { x: data.x, y: data.y }, windowPosition: { x: data.pageX, y: data.pageY }, modifiers: { alt: data.altKey, control: data.ctrlKey, meta: data.metaKey, shift: data.shiftKey } });
|
|
101
|
+
}
|
|
102
|
+
if (control.failed) return <View {...props} ref={control.ref}>{children}</View>;
|
|
103
|
+
return <NativeSidebarItem {...props} ref={control.ref} itemId={id} autoHeight={rowHeight === "auto"} rowHeight={typeof rowHeight === "number" ? rowHeight : 0} selectable={selectable} onRightClick={contextMenu}>{children}</NativeSidebarItem>;
|
|
104
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Platform, UIManager, type ViewProps } from "react-native";
|
|
2
|
+
import type { Ref } from "react";
|
|
3
|
+
import { SparkError, type Availability } from "@legendapp/spark-desktop-app/src/contracts";
|
|
4
|
+
import type { ControlRef } from "./types";
|
|
5
|
+
export interface SpecializedViewProps extends ViewProps { ref?: Ref<ControlRef>; onError?: (error: SparkError) => void }
|
|
6
|
+
export function macosViewAvailability(name: string, minimumVersion = 14): Availability {
|
|
7
|
+
if (Platform.OS !== "macos") return { available: false, reason: "unsupported-platform" };
|
|
8
|
+
if (Number.parseInt(String(Platform.Version), 10) < minimumVersion) return { available: false, reason: "host-restriction" };
|
|
9
|
+
return UIManager.hasViewManagerConfig(name) ? { available: true } : { available: false, reason: "missing-module" };
|
|
10
|
+
}
|
|
11
|
+
export function finite(value: unknown, name: string, minimum = 0, maximum = Infinity): asserts value is number {
|
|
12
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < minimum || value > maximum) throw new SparkError("E_INVALID_ARGUMENT", `Invalid ${name}`);
|
|
13
|
+
}
|
|
14
|
+
export function identifier(value: unknown, name = "ID"): asserts value is string {
|
|
15
|
+
if (typeof value !== "string" || !value.length || value.includes("\0")) throw new SparkError("E_INVALID_ARGUMENT", `Expected a nonempty ${name}`);
|
|
16
|
+
}
|
|
17
|
+
export function appearance(value: unknown) {
|
|
18
|
+
if (!["system", "light", "dark"].includes(value as string)) throw new SparkError("E_INVALID_ARGUMENT", "Invalid appearance");
|
|
19
|
+
}
|
|
20
|
+
export function callback(value: unknown, name: string) {
|
|
21
|
+
if (value !== undefined && typeof value !== "function") throw new SparkError("E_INVALID_ARGUMENT", `Expected ${name} callback`);
|
|
22
|
+
}
|
package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
import type { DirectEventHandler } from "react-native/Libraries/Types/CodegenTypes";
|
|
4
|
+
|
|
5
|
+
export interface NativeProps extends ViewProps {
|
|
6
|
+
leadingActionsJson: string;
|
|
7
|
+
trailingActionsJson: string;
|
|
8
|
+
onSwipeAction?: DirectEventHandler<Readonly<{ actionId: string }>>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default codegenNativeComponent<NativeProps>("SwipeActions") as HostComponent<NativeProps>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { View, type NativeSyntheticEvent } from "react-native";
|
|
2
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
3
|
+
import { useControl } from "../control";
|
|
4
|
+
import { identifier, macosViewAvailability, type SpecializedViewProps } from "../specialized";
|
|
5
|
+
import NativeSwipeActions from "./SwipeActionsNativeComponent";
|
|
6
|
+
/** `dismisses` slides the row away on commit; remove or remount the row to recover after failure/undo. */
|
|
7
|
+
export interface SwipeAction { id: string; title: string; symbol: string; color: string; dismisses?: boolean }
|
|
8
|
+
export interface SwipeActionsProps extends SpecializedViewProps {
|
|
9
|
+
/** Revealed by swiping right; the first action is outermost and runs on a full swipe. */
|
|
10
|
+
leadingActions?: readonly SwipeAction[];
|
|
11
|
+
/** Revealed by swiping left; the first action is outermost and runs on a full swipe. */
|
|
12
|
+
trailingActions?: readonly SwipeAction[];
|
|
13
|
+
onAction: (id: string) => void;
|
|
14
|
+
}
|
|
15
|
+
const hexColor = /^#(?:[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
16
|
+
function actionsJson(actions: readonly SwipeAction[], ids: Set<string>) {
|
|
17
|
+
if (!Array.isArray(actions)) throw new SparkError("E_INVALID_ARGUMENT", "Swipe actions must be arrays");
|
|
18
|
+
for (const action of actions) {
|
|
19
|
+
identifier(action?.id, "swipe action ID"); identifier(action.title, "swipe action title"); identifier(action.symbol, "swipe action symbol");
|
|
20
|
+
if (typeof action.color !== "string" || !hexColor.test(action.color)) throw new SparkError("E_INVALID_ARGUMENT", "Swipe action colors are #RRGGBB or #RRGGBBAA");
|
|
21
|
+
if (action.dismisses !== undefined && typeof action.dismisses !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Invalid swipe action dismisses");
|
|
22
|
+
if (ids.has(action.id)) throw new SparkError("E_INVALID_ARGUMENT", "Duplicate swipe action ID");
|
|
23
|
+
ids.add(action.id);
|
|
24
|
+
}
|
|
25
|
+
return JSON.stringify(actions.map(({ id, title, symbol, color, dismisses = false }) => ({ id, title, symbol, color, dismisses })));
|
|
26
|
+
}
|
|
27
|
+
export function getSwipeActionsAvailability() { return macosViewAvailability("SwipeActions"); }
|
|
28
|
+
/** Native trackpad swipe actions. In recycling lists, key this view by the logical row ID. */
|
|
29
|
+
export function SwipeActions({ leadingActions = [], trailingActions = [], onAction, ref, onError, ...props }: SwipeActionsProps) {
|
|
30
|
+
if (typeof onAction !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected swipe action callback");
|
|
31
|
+
const ids = new Set<string>(), leading = actionsJson(leadingActions, ids), trailing = actionsJson(trailingActions, ids);
|
|
32
|
+
const control = useControl({ ref, onError }, getSwipeActionsAvailability());
|
|
33
|
+
function action(event: NativeSyntheticEvent<{ actionId: string }>) {
|
|
34
|
+
if (!control.active()) return;
|
|
35
|
+
const id = event?.nativeEvent?.actionId;
|
|
36
|
+
if (typeof id !== "string" || !ids.has(id)) { control.error(new SparkError("E_INVALID_DATA", "Invalid swipe action")); return; }
|
|
37
|
+
onAction(id);
|
|
38
|
+
}
|
|
39
|
+
if (control.failed) return <View {...props} ref={control.ref} />;
|
|
40
|
+
return <NativeSwipeActions {...props} ref={control.ref} leadingActionsJson={leading} trailingActionsJson={trailing} onSwipeAction={action} />;
|
|
41
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import { codegenNativeComponent } from "react-native";
|
|
3
|
+
import codegenNativeCommands from "react-native/Libraries/Utilities/codegenNativeCommands";
|
|
4
|
+
import type { DirectEventHandler, Int32, WithDefault } from "react-native/Libraries/Types/CodegenTypes";
|
|
5
|
+
|
|
6
|
+
export type TextInputSearchChangeEvent = {
|
|
7
|
+
text: string;
|
|
8
|
+
eventCount: Int32;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export interface NativeProps extends ViewProps {
|
|
12
|
+
appearance?: string;
|
|
13
|
+
defaultText?: string;
|
|
14
|
+
controlled?: WithDefault<boolean, false>;
|
|
15
|
+
disabled?: WithDefault<boolean, false>;
|
|
16
|
+
eventCount?: Int32;
|
|
17
|
+
onChangeText?: DirectEventHandler<TextInputSearchChangeEvent>;
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
text?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type NativeComponentType = HostComponent<NativeProps>;
|
|
23
|
+
|
|
24
|
+
export interface NativeCommands {
|
|
25
|
+
focus: (viewRef: React.ElementRef<NativeComponentType>) => void;
|
|
26
|
+
blur: (viewRef: React.ElementRef<NativeComponentType>) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const Commands = codegenNativeCommands<NativeCommands>({
|
|
30
|
+
supportedCommands: ["focus", "blur"],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export default codegenNativeComponent<NativeProps>("TextInputSearch") as NativeComponentType;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createElement, useCallback, useImperativeHandle, useRef, type ElementRef, type Ref } from "react";
|
|
2
|
+
import { Text, View, type NativeSyntheticEvent } from "react-native";
|
|
3
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
4
|
+
import { useControl, useTextValue } from "../control";
|
|
5
|
+
import { macosViewAvailability, appearance } from "../specialized";
|
|
6
|
+
import type { ControlRef, ControlledTextInputProps, UncontrolledTextInputProps } from "../types";
|
|
7
|
+
import NativeSearch, { Commands } from "./TextInputSearchNativeComponent";
|
|
8
|
+
export type TextInputSearchProps = (Omit<ControlledTextInputProps, "ref"> | Omit<UncontrolledTextInputProps, "ref">) & {
|
|
9
|
+
appearance?: "dark" | "light" | "system";
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
ref?: Ref<TextInputSearchRef>;
|
|
12
|
+
};
|
|
13
|
+
export interface TextInputSearchRef extends ControlRef { focus(): void; blur(): void }
|
|
14
|
+
export function getSearchAvailability() { return macosViewAvailability("TextInputSearch"); }
|
|
15
|
+
export function TextInputSearch({ ref, appearance: theme = "system", placeholder = "", ...props }: TextInputSearchProps) {
|
|
16
|
+
appearance(theme);
|
|
17
|
+
if (typeof placeholder !== "string") throw new SparkError("E_INVALID_ARGUMENT", "Expected search placeholder");
|
|
18
|
+
const layout = useRef<ControlRef>(null), native = useRef<ElementRef<typeof NativeSearch>>(null);
|
|
19
|
+
const control = useControl({ ...props, ref: layout }, getSearchAvailability()), value = useTextValue(props);
|
|
20
|
+
const nativeRef = useCallback((view: ElementRef<typeof NativeSearch> | null) => { native.current = view; control.ref(view); }, [control.ref]);
|
|
21
|
+
useImperativeHandle(ref, () => ({
|
|
22
|
+
measureInWindow(callback) { if (!layout.current) throw new SparkError("E_CLOSED", "Search input is not mounted"); layout.current.measureInWindow(callback); },
|
|
23
|
+
focus() { if (!native.current) throw new SparkError("E_CLOSED", "Search input is not mounted or available"); Commands.focus(native.current); },
|
|
24
|
+
blur() { if (!native.current) throw new SparkError("E_CLOSED", "Search input is not mounted or available"); Commands.blur(native.current); },
|
|
25
|
+
}), []);
|
|
26
|
+
function changed(event: NativeSyntheticEvent<{ text: string; eventCount: number }>) {
|
|
27
|
+
if (!control.active()) return;
|
|
28
|
+
const data = event?.nativeEvent;
|
|
29
|
+
if (typeof data?.text !== "string" || !Number.isSafeInteger(data.eventCount) || data.eventCount < 1 || data.eventCount > 2147483647) { control.error(new SparkError("E_INVALID_DATA", "Invalid search input event")); return; }
|
|
30
|
+
if (value.acknowledge(data.eventCount)) props.onChangeText?.(data.text);
|
|
31
|
+
}
|
|
32
|
+
if (control.failed) return <View ref={control.ref} style={props.style} testID={props.testID} accessible accessibilityLabel={props.accessibilityLabel} accessibilityState={{ disabled: true }}><Text>{value.controlled ? value.text : value.defaultText}</Text></View>;
|
|
33
|
+
return createElement(NativeSearch, { ref: nativeRef, appearance: theme, placeholder, disabled: control.disabled, controlled: value.controlled, eventCount: value.eventCount, defaultText: value.defaultText, text: value.text, onChangeText: changed, style: props.style, testID: props.testID, accessibilityLabel: props.accessibilityLabel });
|
|
34
|
+
}
|
|
@@ -1,28 +1,39 @@
|
|
|
1
|
+
import type { Ref } from "react";
|
|
1
2
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
2
|
-
|
|
3
|
+
import type { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
4
|
+
/** A layout-only ref; backend objects and native control methods stay internal. */
|
|
5
|
+
export interface ControlRef { measureInWindow(callback: (x: number, y: number, width: number, height: number) => void): void }
|
|
6
|
+
export interface ControlProps {
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
testID?: string;
|
|
11
|
+
ref?: Ref<ControlRef>;
|
|
12
|
+
onError?: (error: SparkError) => void;
|
|
13
|
+
}
|
|
3
14
|
/** A native text button. Layout styles affect its frame, not OS-managed chrome. */
|
|
4
|
-
export
|
|
15
|
+
export interface ButtonProps extends ControlProps {
|
|
5
16
|
children: string;
|
|
6
17
|
onPress?: () => void;
|
|
7
|
-
disabled?: boolean;
|
|
8
18
|
variant?: "default" | "bordered" | "borderless";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
}
|
|
20
|
+
export interface ControlledTextInputProps extends ControlProps {
|
|
21
|
+
value: string;
|
|
22
|
+
defaultValue?: never;
|
|
23
|
+
onChangeText?: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface UncontrolledTextInputProps extends ControlProps {
|
|
26
|
+
value?: never;
|
|
27
|
+
/** Read only on mount. Remount to reset an uncontrolled input. */
|
|
15
28
|
defaultValue?: string;
|
|
16
29
|
onChangeText?: (text: string) => void;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
options: readonly { label: string; value: string }[];
|
|
30
|
+
}
|
|
31
|
+
export type TextInputProps = ControlledTextInputProps | UncontrolledTextInputProps;
|
|
32
|
+
export interface SelectOption { label: string; value: string }
|
|
33
|
+
export interface SelectProps extends ControlProps {
|
|
34
|
+
options: readonly SelectOption[];
|
|
23
35
|
value: string;
|
|
24
36
|
onValueChange: (value: string) => void;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
37
|
+
}
|
|
38
|
+
export interface SegmentedControlProps extends SelectProps {}
|
|
39
|
+
export type ControlKind = "button" | "text-input" | "select" | "segmented-control";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { withUniwind } from "uniwind";
|
|
2
|
-
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
|
|
2
|
+
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
|
|
3
3
|
|
|
4
4
|
// Optional, module-level bindings preserve each platform's native implementation.
|
|
5
5
|
// className maps to the existing layout style; explicit style wins on conflicts.
|
|
6
6
|
export const Button = withUniwind(NativeButton);
|
|
7
7
|
export const TextInput = withUniwind(NativeTextInput);
|
|
8
8
|
export const Select = withUniwind(NativeSelect);
|
|
9
|
+
|
|
10
|
+
export const SegmentedControl = withUniwind(NativeSegmentedControl);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement, type ComponentType } from "react";
|
|
2
2
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
3
3
|
import { useResolveClassNames } from "uniwind";
|
|
4
|
-
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
|
|
4
|
+
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
|
|
5
5
|
|
|
6
6
|
function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Component: ComponentType<Props>) {
|
|
7
7
|
return function UniwindControl({ className = "", style, ...props }: Props & { className?: string }) {
|
|
@@ -15,3 +15,5 @@ function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Compon
|
|
|
15
15
|
export const Button = withSparkClasses(NativeButton);
|
|
16
16
|
export const TextInput = withSparkClasses(NativeTextInput);
|
|
17
17
|
export const Select = withSparkClasses(NativeSelect);
|
|
18
|
+
|
|
19
|
+
export const SegmentedControl = withSparkClasses(NativeSegmentedControl);
|
|
@@ -16,18 +16,17 @@ namespace React = Microsoft::ReactNative;
|
|
|
16
16
|
namespace Composition = Microsoft::ReactNative::Composition;
|
|
17
17
|
namespace Xaml = Microsoft::UI::Xaml;
|
|
18
18
|
namespace Json = Windows::Data::Json;
|
|
19
|
-
REACT_MODULE(SparkUIAvailability, L"NativeSparkUI")
|
|
20
|
-
struct SparkUIAvailability {
|
|
21
|
-
REACT_SYNC_METHOD(isAvailable)
|
|
22
|
-
bool isAvailable() noexcept { return true; }
|
|
23
|
-
};
|
|
24
19
|
struct Props : implements<Props, React::IComponentProps> {
|
|
25
20
|
React::ViewProps view{nullptr};
|
|
26
|
-
std::string title, defaultText, itemsJson = "[]", value, variant = "default";
|
|
27
|
-
bool disabled = false;
|
|
21
|
+
std::string title, defaultText, text, itemsJson = "[]", value, variant = "default";
|
|
22
|
+
bool disabled = false, controlled = false;
|
|
23
|
+
int32_t eventCount = 0;
|
|
28
24
|
void SetProp(uint32_t, hstring const &name, React::IJSValueReader const &reader) noexcept {
|
|
29
25
|
if (name == L"title") React::ReadValue(reader, title);
|
|
30
26
|
else if (name == L"defaultText") React::ReadValue(reader, defaultText);
|
|
27
|
+
else if (name == L"text") React::ReadValue(reader, text);
|
|
28
|
+
else if (name == L"controlled") React::ReadValue(reader, controlled);
|
|
29
|
+
else if (name == L"eventCount") React::ReadValue(reader, eventCount);
|
|
31
30
|
else if (name == L"itemsJson") React::ReadValue(reader, itemsJson);
|
|
32
31
|
else if (name == L"value") React::ReadValue(reader, value);
|
|
33
32
|
else if (name == L"variant") React::ReadValue(reader, variant);
|
|
@@ -56,10 +55,13 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
56
55
|
std::string kind, failure, items;
|
|
57
56
|
std::vector<std::string> values;
|
|
58
57
|
bool initialized = false, updating = false;
|
|
58
|
+
int32_t eventCount = 0;
|
|
59
59
|
void Emit(hstring const &name, std::string const &key = "", std::string const &value = "") {
|
|
60
|
-
|
|
60
|
+
const auto count = eventCount;
|
|
61
|
+
if (emitter) emitter.DispatchEvent(name, [key, value, name, count](React::IJSValueWriter const &writer) {
|
|
61
62
|
writer.WriteObjectBegin();
|
|
62
63
|
if (!key.empty()) { writer.WritePropertyName(to_hstring(key)); writer.WriteString(to_hstring(value)); }
|
|
64
|
+
if (name == L"textChange") { writer.WritePropertyName(L"eventCount"); writer.WriteInt64(count); }
|
|
63
65
|
writer.WriteObjectEnd();
|
|
64
66
|
});
|
|
65
67
|
}
|
|
@@ -78,7 +80,7 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
78
80
|
} else if (kind == "TextInput") {
|
|
79
81
|
Xaml::Controls::TextBox input;
|
|
80
82
|
input.TextChanged([weak](auto const &sender, auto const &) {
|
|
81
|
-
if (auto self = weak.get(); self && !self->updating) self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text()));
|
|
83
|
+
if (auto self = weak.get(); self && !self->updating && self->control.IsEnabled()) { ++self->eventCount; self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text())); }
|
|
82
84
|
});
|
|
83
85
|
control = input;
|
|
84
86
|
} else {
|
|
@@ -113,14 +115,16 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
113
115
|
updating = true;
|
|
114
116
|
control.IsEnabled(!props.disabled);
|
|
115
117
|
Xaml::Automation::AutomationProperties::SetAutomationId(control, props.view.TestId());
|
|
116
|
-
Xaml::Automation::AutomationProperties::SetName(control, kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
|
|
118
|
+
Xaml::Automation::AutomationProperties::SetName(control, props.view.AccessibilityLabel().empty() && kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
|
|
117
119
|
if (kind == "Button") {
|
|
118
120
|
auto button = control.as<Xaml::Controls::Button>();
|
|
119
121
|
button.Content(box_value(to_hstring(props.title)));
|
|
120
122
|
// WinUI owns hover, pressed, keyboard, disabled, and accessibility states.
|
|
121
123
|
button.BorderThickness(props.variant == "borderless" ? Xaml::Thickness{0, 0, 0, 0} : Xaml::Thickness{1, 1, 1, 1});
|
|
122
124
|
} else if (kind == "TextInput") {
|
|
123
|
-
|
|
125
|
+
auto input = control.as<Xaml::Controls::TextBox>();
|
|
126
|
+
if (!initialized) input.Text(to_hstring(props.defaultText));
|
|
127
|
+
if (props.controlled && props.eventCount >= eventCount && input.Text() != to_hstring(props.text)) input.Text(to_hstring(props.text));
|
|
124
128
|
} else {
|
|
125
129
|
auto select = control.as<Xaml::Controls::ComboBox>();
|
|
126
130
|
if (items != props.itemsJson) {
|
|
@@ -153,6 +157,7 @@ inline void RegisterControls(React::IReactPackageBuilder const &package) {
|
|
|
153
157
|
if (previous) {
|
|
154
158
|
auto old = get_self<Props>(previous);
|
|
155
159
|
props->title = old->title; props->defaultText = old->defaultText; props->itemsJson = old->itemsJson;
|
|
160
|
+
props->text = old->text; props->controlled = old->controlled; props->eventCount = old->eventCount;
|
|
156
161
|
props->value = old->value; props->variant = old->variant; props->disabled = old->disabled;
|
|
157
162
|
}
|
|
158
163
|
props->view = view; return props.as<React::IComponentProps>();
|
|
@@ -22,7 +22,7 @@ static NSString *UnavailableReason(void) {
|
|
|
22
22
|
+ (instancetype)shared { static SparkUpdater *updater; static dispatch_once_t once; dispatch_once(&once, ^{ updater = [SparkUpdater new]; }); return updater; }
|
|
23
23
|
- (NSDictionary *)status {
|
|
24
24
|
NSString *reason = UnavailableReason();
|
|
25
|
-
NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates) } mutableCopy];
|
|
25
|
+
NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates), @"checkIntervalSeconds": reason ? NSNull.null : @(self.started ? self.controller.updater.updateCheckInterval : 3600) } mutableCopy];
|
|
26
26
|
if (reason) result[@"reason"] = reason;
|
|
27
27
|
if (!reason) result[@"feedURL"] = [NSBundle.mainBundle objectForInfoDictionaryKey:@"SUFeedURL"];
|
|
28
28
|
return result;
|
|
@@ -55,17 +55,30 @@ RCT_EXPORT_MODULE(NativeDesktopUpdates)
|
|
|
55
55
|
[NSRunLoop.mainRunLoop performBlock:^{
|
|
56
56
|
SparkUpdater *updater = [SparkUpdater shared];
|
|
57
57
|
if ([method isEqual:@"status"]) { resolve(SparkJSON([updater status])); return; }
|
|
58
|
-
if (![@[@"start", @"check", @"
|
|
58
|
+
if (![@[@"start", @"check", @"background", @"configure"] containsObject:method]) { SparkInvalid(reject, @"Unknown update operation"); return; }
|
|
59
|
+
NSDictionary *args = SparkArgs(json);
|
|
60
|
+
if ([method isEqual:@"configure"]) {
|
|
61
|
+
id enabled = args[@"automaticallyChecks"], interval = args[@"checkIntervalSeconds"];
|
|
62
|
+
if ((enabled && (![enabled isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)enabled) != CFBooleanGetTypeID())) ||
|
|
63
|
+
(interval && (![interval isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)interval) == CFBooleanGetTypeID() || !isfinite([interval doubleValue]) || [interval doubleValue] <= 0))) {
|
|
64
|
+
SparkInvalid(reject, @"Invalid updater configuration"); return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
NSString *reason = UnavailableReason();
|
|
60
|
-
if (reason) { reject(@"
|
|
68
|
+
if (reason) { reject(@"E_UNAVAILABLE", [@"Updates require a configured standalone release app; current state: " stringByAppendingString:reason], nil); return; }
|
|
61
69
|
NSError *error = nil;
|
|
62
|
-
if (![updater start:&error]) { reject(@"
|
|
70
|
+
if (![updater start:&error]) { reject(@"E_NATIVE", error.localizedDescription ?: @"Could not start updater", error); return; }
|
|
63
71
|
if ([method isEqual:@"check"]) {
|
|
64
|
-
if (!updater.controller.updater.canCheckForUpdates) { reject(@"
|
|
72
|
+
if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
|
|
65
73
|
[updater.controller checkForUpdates:nil]; resolve(@"null");
|
|
66
|
-
} else if ([method isEqual:@"
|
|
67
|
-
updater.controller.updater.
|
|
68
|
-
|
|
74
|
+
} else if ([method isEqual:@"background"]) {
|
|
75
|
+
if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
|
|
76
|
+
[updater.controller.updater checkForUpdatesInBackground]; resolve(@"null");
|
|
77
|
+
} else if ([method isEqual:@"configure"]) {
|
|
78
|
+
if (args[@"automaticallyChecks"]) updater.controller.updater.automaticallyChecksForUpdates = [args[@"automaticallyChecks"] boolValue];
|
|
79
|
+
if (args[@"checkIntervalSeconds"]) updater.controller.updater.updateCheckInterval = [args[@"checkIntervalSeconds"] doubleValue];
|
|
80
|
+
resolve(@"null");
|
|
81
|
+
} else resolve(@"null");
|
|
69
82
|
}];
|
|
70
83
|
}
|
|
71
84
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { return std::make_shared<facebook::react::NativeDesktopUpdatesSpecJSI>(params); }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-updates",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
41
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
42
42
|
},
|
|
43
43
|
"private": true
|
|
44
44
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TurboModule } from "react-native";
|
|
2
2
|
import { TurboModuleRegistry } from "react-native";
|
|
3
|
-
export interface Spec extends TurboModule {
|
|
4
|
-
|
|
3
|
+
export interface Spec extends TurboModule {
|
|
4
|
+
call(method: string, args: string): Promise<string>; }
|
|
5
|
+
export default TurboModuleRegistry.get<Spec>("NativeDesktopUpdates");
|