@legendapp/spark 0.0.1-next.3 → 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/camera.ts +13 -0
- package/package.json +21 -11
- 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/ui-swipe.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-audio/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +62 -11
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +3 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +6 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +41 -26
- package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +43 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +3 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +27 -22
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +19 -19
- package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +1 -8
- package/vendor/node_modules/@legendapp/spark-cli/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-codex/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-commands/package.json +5 -5
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -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 +5 -4
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +39 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-documents/package.json +7 -7
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +16 -11
- package/vendor/node_modules/@legendapp/spark-processes/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-settings/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +4 -4
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +263 -26
- 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/package.json +3 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +20 -11
- 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-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-context-menu",
|
|
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
45
45
|
},
|
|
46
46
|
"private": true
|
|
47
47
|
}
|
|
@@ -11,6 +11,7 @@ export type MenuItem =
|
|
|
11
11
|
| { type: "separator" }
|
|
12
12
|
| (MenuEntry & { type: "action"; shortcut?: string })
|
|
13
13
|
| (MenuEntry & { type: "checkbox"; checked: boolean; shortcut?: string })
|
|
14
|
+
| (MenuEntry & { type: "radio"; checked: boolean; shortcut?: string })
|
|
14
15
|
| (MenuEntry & { type: "submenu"; items: readonly MenuItem[] })
|
|
15
16
|
| (Omit<MenuEntry, "label"> & { type: "role"; role: MenuRole; label?: string; shortcut?: string })
|
|
16
17
|
| (MenuEntry & { type: "slider"; min: number; max: number; value: number; suffix?: string });
|
|
@@ -20,7 +21,7 @@ export type MenuItemTree<Leaf extends Exclude<MenuItem, { type: "submenu" }>> =
|
|
|
20
21
|
/** Internal transport shape; never reexported from feature entry points. */
|
|
21
22
|
export interface MenuWireItem {
|
|
22
23
|
id?: string; title?: string; target?: MenuTarget; placement?: MenuPlacement; _sparkOwner?: string; _sparkIdentity?: string; enabled?: boolean; hidden?: boolean; checked?: boolean; separator?: boolean;
|
|
23
|
-
shortcut?: Accelerator; items?: MenuWireItem[]; role?: MenuRole;
|
|
24
|
+
shortcut?: Accelerator; items?: MenuWireItem[]; role?: MenuRole; radio?: boolean;
|
|
24
25
|
systemImageName?: string; imagePath?: string; slider?: { min: number; max: number; value: number; suffix?: string };
|
|
25
26
|
}
|
|
26
27
|
export interface MenuSupport { types: readonly MenuItem["type"][]; shortcuts?: boolean; icons?: readonly MenuIcon["type"][]; targeting?: boolean }
|
|
@@ -43,7 +44,7 @@ export function menuItems(input: readonly MenuItem[], support: MenuSupport, plat
|
|
|
43
44
|
if (typeof item.id !== "string" || !item.id.length || item.id.length > 200 || item.id.includes("\0") || ids.has(item.id)) throw new SparkError("E_INVALID_ARGUMENT", "Menu item ids must be nonempty and unique");
|
|
44
45
|
ids.add(item.id);
|
|
45
46
|
const common = ["type", "id", "label", "disabled", "hidden", "icon", "target", "placement"];
|
|
46
|
-
keys(item, [...common, ...(item.type === "submenu" ? ["items"] : item.type === "slider" ? ["min", "max", "value", "suffix"] : item.type === "role" ? ["role", "shortcut"] : item.type === "checkbox" ? ["checked", "shortcut"] : ["shortcut"])]);
|
|
47
|
+
keys(item, [...common, ...(item.type === "submenu" ? ["items"] : item.type === "slider" ? ["min", "max", "value", "suffix"] : item.type === "role" ? ["role", "shortcut"] : item.type === "checkbox" || item.type === "radio" ? ["checked", "shortcut"] : ["shortcut"])]);
|
|
47
48
|
if ((item.type !== "role" || item.label !== undefined) && (typeof item.label !== "string" || !item.label.trim())) throw new SparkError("E_INVALID_ARGUMENT", "Menu items need a label");
|
|
48
49
|
if ([item.disabled, item.hidden].some(value => value !== undefined && typeof value !== "boolean")) throw new SparkError("E_INVALID_ARGUMENT", "Menu flags must be boolean");
|
|
49
50
|
const result: MenuWireItem = { id: item.id, title: item.label, enabled: !item.disabled };
|
|
@@ -57,9 +58,10 @@ export function menuItems(input: readonly MenuItem[], support: MenuSupport, plat
|
|
|
57
58
|
result.placement = item.placement.before !== undefined ? { before: menuTarget(item.placement.before) } : { after: menuTarget(item.placement.after!) };
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
if (item.type === "checkbox") {
|
|
61
|
-
if (typeof item.checked !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Checkbox menus require checked state");
|
|
61
|
+
if (item.type === "checkbox" || item.type === "radio") {
|
|
62
|
+
if (typeof item.checked !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Checkbox and radio menus require checked state");
|
|
62
63
|
result.checked = item.checked;
|
|
64
|
+
if (item.type === "radio") result.radio = true;
|
|
63
65
|
}
|
|
64
66
|
if (item.type === "submenu") result.items = visit(item.items, depth + 1);
|
|
65
67
|
if (item.type === "role") {
|
|
@@ -69,6 +69,7 @@ function developmentConfig(value, target) {
|
|
|
69
69
|
return result;
|
|
70
70
|
}
|
|
71
71
|
function expoConfig(root) {
|
|
72
|
+
require("./native-patches.cjs").prepareNativePatches(root);
|
|
72
73
|
if (process.env.SPARK_DEV_SESSION === "1") {
|
|
73
74
|
return developmentConfig(JSON.parse(fs.readFileSync(path.join(root, filename), "utf8")), process.env.SPARK_PLATFORM);
|
|
74
75
|
}
|
|
@@ -137,6 +138,7 @@ function merge(base, override) {
|
|
|
137
138
|
// Expo tools read this generated transport file. All framework consumers resolve
|
|
138
139
|
// the canonical source; the generated file is never edited by SDK commands.
|
|
139
140
|
function prepareConfig(root) {
|
|
141
|
+
require("./native-patches.cjs").prepareNativePatches(root);
|
|
140
142
|
if (isExpoProject(root)) return readConfig(root);
|
|
141
143
|
if (isUniversal(root)) {
|
|
142
144
|
const file = path.join(root, "app.config.js");
|
|
@@ -5,6 +5,7 @@ const path = require('node:path');
|
|
|
5
5
|
// Only an explicitly selected desktop command applies the Spark overlay.
|
|
6
6
|
function withSparkExpo(original, root) {
|
|
7
7
|
return context => {
|
|
8
|
+
require('./native-patches.cjs').prepareNativePatches(root);
|
|
8
9
|
const base = typeof original === 'function' ? original(context) : original;
|
|
9
10
|
const target = process.env.SPARK_PLATFORM;
|
|
10
11
|
const development = process.env.SPARK_DEV_SESSION === '1';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const { createHash } = require("node:crypto");
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { createRequire } = require("node:module");
|
|
5
|
+
|
|
6
|
+
const cameraPackages = ["react-native-nitro-image", "react-native-vision-camera"];
|
|
7
|
+
|
|
8
|
+
function prepareNativePatches(root) {
|
|
9
|
+
const manifestFile = path.join(root, "package.json");
|
|
10
|
+
if (!fs.existsSync(manifestFile)) return {};
|
|
11
|
+
const app = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
|
|
12
|
+
if (app.name !== "@legendapp/spark" && !app.dependencies?.["@legendapp/spark"] && !app.devDependencies?.["@legendapp/spark"]) return {};
|
|
13
|
+
const appRequire = createRequire(manifestFile);
|
|
14
|
+
let sparkFile;
|
|
15
|
+
try { sparkFile = appRequire.resolve("@legendapp/spark/package.json"); }
|
|
16
|
+
catch (error) { if (error.code === "MODULE_NOT_FOUND") return {}; throw error; }
|
|
17
|
+
const spark = JSON.parse(fs.readFileSync(sparkFile, "utf8"));
|
|
18
|
+
const directory = path.dirname(sparkFile);
|
|
19
|
+
const patchesRoot = spark.spark?.bundledModuleRoot
|
|
20
|
+
? path.join(directory, "patches") : path.resolve(__dirname, "../../patches");
|
|
21
|
+
const pins = {};
|
|
22
|
+
if (cameraPackages.some(name => spark.dependencies?.[name])) {
|
|
23
|
+
const cameraPins = JSON.parse(fs.readFileSync(path.join(patchesRoot, "camera/upstream.json"), "utf8"));
|
|
24
|
+
for (const name of ["react-native-nitro-modules", ...cameraPackages]) {
|
|
25
|
+
pins[name] = { ...cameraPins[name], patch: `camera/${name}.patch`,
|
|
26
|
+
requires: name === "react-native-vision-camera" ? ["react-native-nitro-modules", "react-native-nitro-image"] : ["react-native-nitro-modules"] };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const integrations = path.join(patchesRoot, "dependencies.json");
|
|
30
|
+
if (fs.existsSync(integrations)) Object.assign(pins, JSON.parse(fs.readFileSync(integrations, "utf8")));
|
|
31
|
+
const active = Object.keys(pins).filter(name => spark.dependencies?.[name]);
|
|
32
|
+
if (!active.length) return {};
|
|
33
|
+
const { parsePatch, applyPatch, reversePatch } = require("diff");
|
|
34
|
+
const queue = [appRequire, createRequire(sparkFile)];
|
|
35
|
+
const visited = new Set();
|
|
36
|
+
const packages = {};
|
|
37
|
+
for (const req of queue) {
|
|
38
|
+
for (const name of active) {
|
|
39
|
+
let file;
|
|
40
|
+
try { file = req.resolve(`${name}/package.json`); }
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error.code !== "MODULE_NOT_FOUND") throw error;
|
|
43
|
+
if (req === appRequire) continue;
|
|
44
|
+
throw new Error(`Spark needs ${name}@${pins[name].version}. Finish installing dependencies before native preparation.`);
|
|
45
|
+
}
|
|
46
|
+
if (!fs.existsSync(file)) throw new Error(`Spark needs ${name}@${pins[name].version}. Finish installing dependencies before native preparation.`);
|
|
47
|
+
const packageRoot = fs.realpathSync(path.dirname(file));
|
|
48
|
+
if (visited.has(packageRoot)) continue;
|
|
49
|
+
visited.add(packageRoot);
|
|
50
|
+
packages[name] = { root: packageRoot };
|
|
51
|
+
queue.push(createRequire(file));
|
|
52
|
+
const manifest = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
53
|
+
const pin = pins[name];
|
|
54
|
+
if (manifest.version !== pin.version) throw new Error(`Spark needs ${name}@${pin.version}; found ${manifest.version}. Use the SDK's pinned dependency version.`);
|
|
55
|
+
const bytes = fs.readFileSync(path.join(patchesRoot, pin.patch));
|
|
56
|
+
const writes = [];
|
|
57
|
+
for (const patch of parsePatch(bytes.toString("utf8"))) {
|
|
58
|
+
const relative = patch.newFileName.replace(/^b\//, "");
|
|
59
|
+
const target = path.resolve(packageRoot, relative);
|
|
60
|
+
if (!target.startsWith(packageRoot + path.sep) || patch.newFileName === "/dev/null") throw new Error(`Invalid native patch target: ${relative}`);
|
|
61
|
+
let current = fs.existsSync(target) ? fs.readFileSync(target, "utf8") : "";
|
|
62
|
+
if (patch.oldFileName === "/dev/null") {
|
|
63
|
+
const next = applyPatch("", patch);
|
|
64
|
+
if (current === next) continue;
|
|
65
|
+
if (current !== "") throw new Error(`Cannot apply Spark's ${name} patch to ${relative}. Reinstall dependencies before retrying.`);
|
|
66
|
+
writes.push([target, next]);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (relative === "package.json" && manifest.spark?.dependencyPatch) {
|
|
70
|
+
const original = JSON.parse(current);
|
|
71
|
+
delete original.spark.dependencyPatch;
|
|
72
|
+
delete original.spark.sdk;
|
|
73
|
+
delete original.spark.requires;
|
|
74
|
+
if (!Object.keys(original.spark).length) delete original.spark;
|
|
75
|
+
current = JSON.stringify(original, null, 2) + "\n";
|
|
76
|
+
}
|
|
77
|
+
if (applyPatch(current, reversePatch(patch)) !== false) continue;
|
|
78
|
+
const next = applyPatch(current, patch);
|
|
79
|
+
if (next === false) throw new Error(`Cannot apply Spark's ${name} patch to ${relative}. Reinstall dependencies before retrying.`);
|
|
80
|
+
writes.push([target, next]);
|
|
81
|
+
}
|
|
82
|
+
// Verify every file before writing; rename rather than mutate package-manager cache hardlinks.
|
|
83
|
+
for (const [target, next] of writes) {
|
|
84
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
85
|
+
const temporary = `${target}.spark-${process.pid}.tmp`;
|
|
86
|
+
fs.writeFileSync(temporary, next); fs.renameSync(temporary, target);
|
|
87
|
+
}
|
|
88
|
+
const patched = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
89
|
+
patched.spark ??= {};
|
|
90
|
+
if (name !== "react-native-nitro-modules") {
|
|
91
|
+
patched.spark.sdk = true;
|
|
92
|
+
patched.spark.requires = pin.requires ?? [];
|
|
93
|
+
}
|
|
94
|
+
patched.spark.dependencyPatch = { schema: 1, version: pin.version,
|
|
95
|
+
patchHash: createHash("sha256").update(bytes).digest("hex"), upstreamIntegrity: pin.integrity };
|
|
96
|
+
const serialized = JSON.stringify(patched, null, 2) + "\n";
|
|
97
|
+
if (fs.readFileSync(file, "utf8") !== serialized) {
|
|
98
|
+
const temporary = `${file}.spark-${process.pid}.tmp`;
|
|
99
|
+
fs.writeFileSync(temporary, serialized); fs.renameSync(temporary, file);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return packages;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = { prepareNativePatches };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function prepareNativePatches(root: string): Record<string, { root: string }>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-desktop-config",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "app.plugin.cjs",
|
|
6
6
|
"files": [
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"expo-desktop-config-plugins": "1.2.0",
|
|
14
|
-
"@legendapp/spark-desktop-host": "0.0.1-next.
|
|
15
|
-
"@legendapp/spark-window-options": "0.0.1-next.
|
|
14
|
+
"@legendapp/spark-desktop-host": "0.0.1-next.4",
|
|
15
|
+
"@legendapp/spark-window-options": "0.0.1-next.4",
|
|
16
16
|
"@expo/config-plugins": "54.0.5",
|
|
17
|
-
"@expo/config-types": "54.0.10"
|
|
17
|
+
"@expo/config-types": "54.0.10",
|
|
18
|
+
"diff": "8.0.2"
|
|
18
19
|
},
|
|
19
20
|
"private": true
|
|
20
21
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-desktop-host",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"AppDelegate.mm",
|
|
7
7
|
"windows"
|
|
8
8
|
],
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
10
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
11
11
|
},
|
|
12
12
|
"private": true
|
|
13
13
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-desktop-links",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"react-native": "src/index",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
45
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"expo-linking": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-desktop-shortcuts",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"react-native": "src/index",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
43
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
44
44
|
},
|
|
45
45
|
"private": true
|
|
46
46
|
}
|
package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm
CHANGED
|
@@ -1219,7 +1219,37 @@ RCT_EXPORT_MODULE(NativeWindowManager)
|
|
|
1219
1219
|
NSMutableDictionary *config = [item mutableCopy]; config[@"instanceId"] = objc_getAssociatedObject(window, NSSelectorFromString(@"sparkWindowInstanceId")) ?: @""; [configs addObject:config];
|
|
1220
1220
|
}
|
|
1221
1221
|
}
|
|
1222
|
+
NSArray<NSDictionary *> *previousConfigs = self.toolbarItemConfigs[toolbar.identifier];
|
|
1223
|
+
BOOL menuUpdate = previousConfigs != nil && previousConfigs.count == configs.count;
|
|
1224
|
+
for (NSUInteger index = 0; menuUpdate && index < configs.count; index++) {
|
|
1225
|
+
NSMutableDictionary *previous = [previousConfigs[index] mutableCopy];
|
|
1226
|
+
NSMutableDictionary *next = [configs[index] mutableCopy];
|
|
1227
|
+
if ([next[@"type"] isEqual:@"menuButton"]) {
|
|
1228
|
+
[previous removeObjectForKey:@"menuItems"];
|
|
1229
|
+
[next removeObjectForKey:@"menuItems"];
|
|
1230
|
+
}
|
|
1231
|
+
menuUpdate = [previous isEqualToDictionary:next];
|
|
1232
|
+
}
|
|
1222
1233
|
self.toolbarItemConfigs[toolbar.identifier] = configs;
|
|
1234
|
+
if (menuUpdate) {
|
|
1235
|
+
for (NSDictionary *config in configs) {
|
|
1236
|
+
if (![config[@"type"] isEqual:@"menuButton"]) continue;
|
|
1237
|
+
NSString *itemId = config[@"id"];
|
|
1238
|
+
if (![itemId isKindOfClass:NSString.class] || itemId.length == 0) { menuUpdate = NO; break; }
|
|
1239
|
+
NSString *itemIdentifier = [@"legend.toolbar." stringByAppendingString:itemId];
|
|
1240
|
+
NSToolbarItem *item = nil;
|
|
1241
|
+
for (NSToolbarItem *candidate in toolbar.items) {
|
|
1242
|
+
if ([candidate.itemIdentifier isEqual:itemIdentifier]) { item = candidate; break; }
|
|
1243
|
+
}
|
|
1244
|
+
id control = item.view ?: item;
|
|
1245
|
+
NSDictionary *metadata = control ? objc_getAssociatedObject(control, &LegendToolbarControlMetadataKey) : nil;
|
|
1246
|
+
if (!metadata) { menuUpdate = NO; break; }
|
|
1247
|
+
NSMutableDictionary *nextMetadata = [metadata mutableCopy];
|
|
1248
|
+
nextMetadata[@"menuItems"] = config[@"menuItems"] ?: @[];
|
|
1249
|
+
objc_setAssociatedObject(control, &LegendToolbarControlMetadataKey, nextMetadata, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
1250
|
+
}
|
|
1251
|
+
if (menuUpdate) return;
|
|
1252
|
+
}
|
|
1223
1253
|
|
|
1224
1254
|
while (toolbar.items.count > 0) {
|
|
1225
1255
|
[toolbar removeItemAtIndex:toolbar.items.count - 1];
|
|
@@ -2416,6 +2446,15 @@ willBeInsertedIntoToolbar:(BOOL)flag
|
|
|
2416
2446
|
resolve([self failureJson:@"Toolbar item does not support text"]);
|
|
2417
2447
|
return;
|
|
2418
2448
|
}
|
|
2449
|
+
NSMutableArray *configs = [self.toolbarItemConfigs[window.toolbar.identifier] mutableCopy];
|
|
2450
|
+
for (NSUInteger index = 0; index < configs.count; index++) {
|
|
2451
|
+
if (![[self toolbarItemIdentifierForConfig:configs[index]] isEqualToString:toolbarIdentifier]) continue;
|
|
2452
|
+
NSMutableDictionary *config = [configs[index] mutableCopy];
|
|
2453
|
+
config[[toolbarItem.view isKindOfClass:NSTextField.class] ? @"text" : @"label"] = text ?: @"";
|
|
2454
|
+
configs[index] = config;
|
|
2455
|
+
break;
|
|
2456
|
+
}
|
|
2457
|
+
self.toolbarItemConfigs[window.toolbar.identifier] = configs;
|
|
2419
2458
|
resolve([self successJson]);
|
|
2420
2459
|
});
|
|
2421
2460
|
#else
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-desktop-windows",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"react-native": "src/index",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
-
"@legendapp/spark-window-options": "0.0.1-next.
|
|
43
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4",
|
|
44
|
+
"@legendapp/spark-window-options": "0.0.1-next.4",
|
|
45
45
|
"@legendapp/state": "^3.0.0-beta.42"
|
|
46
46
|
},
|
|
47
47
|
"private": true
|
|
@@ -54,7 +54,9 @@ export async function getCursorPoint(): Promise<CursorPoint> { return windowCall
|
|
|
54
54
|
export async function setWindowOptions(id: string, options: WindowUpdateOptions): Promise<void> {
|
|
55
55
|
windowId(id); validateOptions(options, Platform.OS, false);
|
|
56
56
|
const snapshot = JSON.parse(JSON.stringify(options)) as WindowUpdateOptions;
|
|
57
|
-
|
|
57
|
+
if (!snapshot.macos || Object.keys(snapshot).some(key => key !== "macos")) {
|
|
58
|
+
await windowCommand("options", { id, options: snapshot });
|
|
59
|
+
}
|
|
58
60
|
if (snapshot.macos) await updateMacOSWindow(id, snapshot.macos);
|
|
59
61
|
}
|
|
60
62
|
/** Portable frame change. Animated moves are macOS-only: pass `macos.durationMs` and the call rejects on Windows rather than ignoring the request. */
|
|
@@ -38,7 +38,7 @@ export function macosOptions(options: MacOSWindowOptions | undefined): Record<st
|
|
|
38
38
|
if (options.toolbar.items) style.toolbarItems = options.toolbar.items.map(item => {
|
|
39
39
|
const { type, ...common } = item;
|
|
40
40
|
if (type === "segmented") { const value = item as Extract<typeof item, { type: "segmented" }>; return { ...common, type, selectedValue: value.value, segments: value.segments.map(({ symbol, ...segment }) => ({ ...segment, systemImageName: symbol })) }; }
|
|
41
|
-
if (type === "menu") { const value = item as Extract<typeof item, { type: "menu" }>; return { ...
|
|
41
|
+
if (type === "menu") { const { items, ...value } = item as Extract<typeof item, { type: "menu" }>; return { ...value, type: "menuButton", enabled: !value.disabled, systemImageName: value.symbol, menuItems: menuItems(items, { types: ["action", "checkbox", "separator", "slider"], icons: ["symbol"] }, "macos") }; }
|
|
42
42
|
return { ...common, type, ...("disabled" in item ? { enabled: !item.disabled } : {}), ...("symbol" in item ? { systemImageName: item.symbol } : {}) };
|
|
43
43
|
});
|
|
44
44
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-documents",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/index.tsx",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"src"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@legendapp/spark-file-dialog": "0.0.1-next.
|
|
12
|
-
"@legendapp/spark-file-system": "0.0.1-next.
|
|
13
|
-
"@legendapp/spark-native-menu": "0.0.1-next.
|
|
14
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
15
|
-
"@legendapp/spark-desktop-windows": "0.0.1-next.
|
|
16
|
-
"@legendapp/spark-desktop-links": "0.0.1-next.
|
|
11
|
+
"@legendapp/spark-file-dialog": "0.0.1-next.4",
|
|
12
|
+
"@legendapp/spark-file-system": "0.0.1-next.4",
|
|
13
|
+
"@legendapp/spark-native-menu": "0.0.1-next.4",
|
|
14
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4",
|
|
15
|
+
"@legendapp/spark-desktop-windows": "0.0.1-next.4",
|
|
16
|
+
"@legendapp/spark-desktop-links": "0.0.1-next.4"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"react": "19.1.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-drag-drop",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"react-native": "src/index.tsx",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
]
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
42
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
43
43
|
},
|
|
44
44
|
"private": true
|
|
45
45
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-file-dialog",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"main": "src/index",
|
|
5
5
|
"react-native": "src/index",
|
|
6
6
|
"codegenConfig": {
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
},
|
|
46
46
|
"private": true,
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
48
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-file-system",
|
|
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",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
46
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
47
47
|
},
|
|
48
48
|
"private": true
|
|
49
49
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-global-shortcuts",
|
|
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
45
45
|
},
|
|
46
46
|
"private": true
|
|
47
47
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-message-dialog",
|
|
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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
43
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
44
44
|
},
|
|
45
45
|
"private": true
|
|
46
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-native-menu",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"main": "src/index",
|
|
5
5
|
"react-native": "src/index",
|
|
6
6
|
"codegenConfig": {
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
},
|
|
42
42
|
"private": true,
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-notifications",
|
|
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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
43
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
44
44
|
},
|
|
45
45
|
"private": true
|
|
46
46
|
}
|
|
@@ -108,22 +108,27 @@ struct NotificationsState : std::enable_shared_from_this<NotificationsState> {
|
|
|
108
108
|
auto audio = xml.CreateElement(L"audio");
|
|
109
109
|
auto tone = std::wstring(L"ms-winsoundevent:Notification.");
|
|
110
110
|
if (sound == L"mail") tone += L"Mail"; else if (sound == L"message") tone += L"IM"; else if (sound == L"reminder") tone += L"Reminder";
|
|
111
|
-
else if (sound == L"call") { tone += L"Looping.Call"; audio.SetAttribute(L"duration", L"long"); }
|
|
111
|
+
else if (sound == L"call") { tone += L"Looping.Call"; audio.SetAttribute(L"loop", L"true"); xml.DocumentElement().SetAttribute(L"duration", L"long"); }
|
|
112
112
|
else tone += L"Default";
|
|
113
113
|
audio.SetAttribute(L"src", tone.c_str()); xml.DocumentElement().AppendChild(audio);
|
|
114
114
|
}
|
|
115
115
|
// Action buttons activate through the same CustomActivator as the toast body,
|
|
116
116
|
// carrying their own action id in the activation arguments.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
auto
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
auto entries = args.GetNamedArray(L"actions", Json::JsonArray());
|
|
118
|
+
if (entries.Size() > 0) {
|
|
119
|
+
auto actions = xml.CreateElement(L"actions");
|
|
120
|
+
xml.DocumentElement().AppendChild(actions);
|
|
121
|
+
for (auto const &entry : entries) {
|
|
122
|
+
auto action = entry.GetObject();
|
|
123
|
+
auto button = xml.CreateElement(L"action");
|
|
124
|
+
// JsonObject is a reference type; parse a copy so each action carries its
|
|
125
|
+
// own action id without mutating the body/dismiss payload.
|
|
126
|
+
auto arguments = Json::JsonObject::Parse(response.Stringify());
|
|
127
|
+
arguments.SetNamedValue(L"action", Json::JsonValue::CreateStringValue(action.GetNamedString(L"id")));
|
|
128
|
+
button.SetAttribute(L"content", action.GetNamedString(L"label").c_str());
|
|
129
|
+
button.SetAttribute(L"arguments", arguments.Stringify().c_str());
|
|
130
|
+
actions.AppendChild(button);
|
|
131
|
+
}
|
|
127
132
|
}
|
|
128
133
|
auto tag = Hash(id); RemovePending(tag); Forget(tag);
|
|
129
134
|
if (delay > 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-processes",
|
|
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
45
45
|
},
|
|
46
46
|
"private": true
|
|
47
47
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-secure-storage",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"react-native": "src/index",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
44
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"expo-secure-store": {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-settings",
|
|
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
|
"files": [
|
|
7
7
|
"src"
|
|
8
8
|
],
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@legendapp/spark-file-system": "0.0.1-next.
|
|
10
|
+
"@legendapp/spark-file-system": "0.0.1-next.4",
|
|
11
11
|
"@legendapp/state": "^3.0.0-beta.42",
|
|
12
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
12
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.4"
|
|
13
13
|
},
|
|
14
14
|
"private": true,
|
|
15
15
|
"spark": {
|