@marktiderman/genesis-native 0.2.0 → 0.4.0
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/README.md +470 -10
- package/dist/block-Onqx7NiK.d.ts +223 -0
- package/dist/blocks-C2RDpvaN.d.ts +1595 -0
- package/dist/chunk-65P7RU4V.js +49 -0
- package/dist/chunk-65P7RU4V.js.map +1 -0
- package/dist/chunk-6BT4PTGH.js +37 -0
- package/dist/chunk-6BT4PTGH.js.map +1 -0
- package/dist/chunk-75YP72G6.js +374 -0
- package/dist/chunk-75YP72G6.js.map +1 -0
- package/dist/chunk-NGYNYJPL.js +90 -0
- package/dist/chunk-NGYNYJPL.js.map +1 -0
- package/dist/chunk-ONAXQHNG.js +23 -0
- package/dist/chunk-ONAXQHNG.js.map +1 -0
- package/dist/chunk-VKTIHNAV.js +95 -0
- package/dist/chunk-VKTIHNAV.js.map +1 -0
- package/dist/{chunk-MMTPWUWI.js → chunk-VTJDIKFC.js} +9 -6
- package/dist/chunk-VTJDIKFC.js.map +1 -0
- package/dist/chunk-XE7LC7K6.js +29 -0
- package/dist/chunk-XE7LC7K6.js.map +1 -0
- package/dist/dev-warnings.d.ts +34 -0
- package/dist/dev-warnings.js +15 -0
- package/dist/dev-warnings.js.map +1 -0
- package/dist/devtools.d.ts +144 -0
- package/dist/devtools.js +390 -0
- package/dist/devtools.js.map +1 -0
- package/dist/index.d.ts +12 -368
- package/dist/index.js +88 -191
- package/dist/index.js.map +1 -1
- package/dist/observability.d.ts +170 -0
- package/dist/observability.js +123 -0
- package/dist/observability.js.map +1 -0
- package/dist/persist.d.ts +1 -1
- package/dist/persist.js +1 -1
- package/dist/push-payload.d.ts +43 -0
- package/dist/push-payload.js +3 -0
- package/dist/push-payload.js.map +1 -0
- package/dist/push.d.ts +187 -0
- package/dist/push.js +1069 -0
- package/dist/push.js.map +1 -0
- package/dist/{query-DhH3lLFa.d.ts → query-DUmVAfsF.d.ts} +11 -6
- package/dist/rich-push-plugin.d.ts +74 -0
- package/dist/rich-push-plugin.js +209 -0
- package/dist/rich-push-plugin.js.map +1 -0
- package/dist/updates.d.ts +8 -1
- package/dist/updates.js +44 -69
- package/dist/updates.js.map +1 -1
- package/ios/notification-service/NotificationService.swift +309 -0
- package/package.json +238 -5
- package/src/app.tsx +491 -0
- package/src/auth.tsx +176 -0
- package/src/blocks.tsx +144 -0
- package/src/boot.tsx +188 -0
- package/src/dev-warnings.ts +43 -0
- package/src/devtools/block.tsx +488 -0
- package/src/devtools/gestures.ts +107 -0
- package/src/devtools/index.ts +22 -0
- package/src/devtools/info.ts +45 -0
- package/src/devtools/slots.ts +21 -0
- package/src/errors.tsx +195 -0
- package/src/held-link.ts +90 -0
- package/src/hydration-gate.ts +88 -0
- package/src/index.ts +83 -0
- package/src/links.ts +140 -0
- package/src/nativewind.d.ts +41 -0
- package/src/observability/block.tsx +300 -0
- package/src/observability/events.ts +89 -0
- package/src/observability/index.ts +44 -0
- package/src/observability/scrub.ts +166 -0
- package/src/observability/sentry.ts +222 -0
- package/src/observability/sink.ts +147 -0
- package/src/persist.ts +83 -0
- package/src/plugin/rich-push.ts +312 -0
- package/src/push/backend.ts +137 -0
- package/src/push/block.tsx +604 -0
- package/src/push/index.ts +105 -0
- package/src/push/modules.ts +123 -0
- package/src/push/payload.ts +61 -0
- package/src/push/permission.ts +191 -0
- package/src/push/preferences.ts +136 -0
- package/src/push/quiet-hours.ts +71 -0
- package/src/push/registration.ts +225 -0
- package/src/push/routing.ts +57 -0
- package/src/push/screens.tsx +46 -0
- package/src/push/settings.tsx +378 -0
- package/src/query.ts +100 -0
- package/src/updates/block.tsx +442 -0
- package/src/updates/channels.ts +131 -0
- package/src/updates/checker.ts +190 -0
- package/src/updates/index.ts +87 -0
- package/src/updates/modules.ts +64 -0
- package/src/updates/policy.ts +314 -0
- package/src/updates/screens.tsx +159 -0
- package/src/updates/signature.ts +80 -0
- package/src/updates/store.ts +33 -0
- package/src/updates/version.ts +39 -0
- package/src/updates/whats-new.ts +122 -0
- package/dist/block-Dh5ny06W.d.ts +0 -535
- package/dist/chunk-MMTPWUWI.js.map +0 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync, copyFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { withDangerousMod, withXcodeProject } from 'expo/config-plugins';
|
|
5
|
+
|
|
6
|
+
// src/plugin/rich-push.ts
|
|
7
|
+
var COMMUNICATION_ENTITLEMENT = "com.apple.developer.usernotifications.communication";
|
|
8
|
+
var SEND_MESSAGE_INTENT = "INSendMessageIntent";
|
|
9
|
+
var DEFAULT_TARGET_NAME = "GenesisNotificationService";
|
|
10
|
+
var DEFAULT_BUNDLE_SUFFIX = "NotificationService";
|
|
11
|
+
var SWIFT_FILE = "NotificationService.swift";
|
|
12
|
+
function resolve(options) {
|
|
13
|
+
const targetName = options?.targetName ?? DEFAULT_TARGET_NAME;
|
|
14
|
+
const bundleIdSuffix = options?.bundleIdSuffix ?? DEFAULT_BUNDLE_SUFFIX;
|
|
15
|
+
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(targetName)) throw new Error(`rich-push-plugin: targetName "${targetName}" must be letters, digits and _`);
|
|
16
|
+
if (!/^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*$/.test(bundleIdSuffix)) throw new Error(`rich-push-plugin: bundleIdSuffix "${bundleIdSuffix}" isn't a bundle id part`);
|
|
17
|
+
const imageHosts = (options?.imageHosts ?? []).map((h) => h.trim().toLowerCase());
|
|
18
|
+
for (const h of imageHosts) if (!/^[a-z0-9-]+(\.[a-z0-9-]+)+$/.test(h)) throw new Error(`rich-push-plugin: imageHosts "${h}" isn't a host name`);
|
|
19
|
+
return { targetName, bundleIdSuffix, communication: options?.communication ?? true, deploymentTarget: options?.deploymentTarget, imageHosts };
|
|
20
|
+
}
|
|
21
|
+
function extensionBundleId(appBundleId, suffix = DEFAULT_BUNDLE_SUFFIX) {
|
|
22
|
+
return `${appBundleId}.${suffix}`;
|
|
23
|
+
}
|
|
24
|
+
function extensionEntitlements(communication) {
|
|
25
|
+
return communication ? { [COMMUNICATION_ENTITLEMENT]: true } : {};
|
|
26
|
+
}
|
|
27
|
+
function applyRichPushConfig(config, options) {
|
|
28
|
+
const o = resolve(options);
|
|
29
|
+
const bundleId = config.ios?.bundleIdentifier;
|
|
30
|
+
if (!bundleId) throw new Error("rich-push-plugin: ios.bundleIdentifier is required (the extension's id is built from it)");
|
|
31
|
+
const ios = { ...config.ios };
|
|
32
|
+
if (o.communication) {
|
|
33
|
+
ios.entitlements = { ...ios.entitlements, [COMMUNICATION_ENTITLEMENT]: true };
|
|
34
|
+
const types = Array.isArray(ios.infoPlist?.NSUserActivityTypes) ? ios.infoPlist.NSUserActivityTypes : [];
|
|
35
|
+
ios.infoPlist = { ...ios.infoPlist, NSUserActivityTypes: types.includes(SEND_MESSAGE_INTENT) ? types : [...types, SEND_MESSAGE_INTENT] };
|
|
36
|
+
}
|
|
37
|
+
const extra = { ...config.extra };
|
|
38
|
+
const eas = { ...extra.eas };
|
|
39
|
+
const build = { ...eas.build };
|
|
40
|
+
const experimental = { ...build.experimental };
|
|
41
|
+
const easIos = { ...experimental.ios };
|
|
42
|
+
const existing = Array.isArray(easIos.appExtensions) ? easIos.appExtensions : [];
|
|
43
|
+
const entry = { targetName: o.targetName, bundleIdentifier: extensionBundleId(bundleId, o.bundleIdSuffix), entitlements: extensionEntitlements(o.communication) };
|
|
44
|
+
easIos.appExtensions = [...existing.filter((e) => e?.targetName !== o.targetName), entry];
|
|
45
|
+
extra.eas = { ...eas, build: { ...build, experimental: { ...experimental, ios: easIos } } };
|
|
46
|
+
return { ...config, ios, extra };
|
|
47
|
+
}
|
|
48
|
+
function extensionInfoPlist(displayName, options = {}) {
|
|
49
|
+
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
50
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
51
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
52
|
+
<plist version="1.0">
|
|
53
|
+
<dict>
|
|
54
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
55
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
56
|
+
<key>CFBundleDisplayName</key>
|
|
57
|
+
<string>${esc(displayName)}</string>
|
|
58
|
+
<key>CFBundleExecutable</key>
|
|
59
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
60
|
+
<key>CFBundleIdentifier</key>
|
|
61
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
62
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
63
|
+
<string>6.0</string>
|
|
64
|
+
<key>CFBundleName</key>
|
|
65
|
+
<string>$(PRODUCT_NAME)</string>
|
|
66
|
+
<key>CFBundlePackageType</key>
|
|
67
|
+
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
|
68
|
+
<key>CFBundleShortVersionString</key>
|
|
69
|
+
<string>$(MARKETING_VERSION)</string>
|
|
70
|
+
<key>CFBundleVersion</key>
|
|
71
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
72
|
+
<key>NSExtension</key>
|
|
73
|
+
<dict>
|
|
74
|
+
<key>NSExtensionPointIdentifier</key>
|
|
75
|
+
<string>com.apple.usernotifications.service</string>
|
|
76
|
+
<key>NSExtensionPrincipalClass</key>
|
|
77
|
+
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>${options.communication ? `
|
|
78
|
+
<key>NSExtensionAttributes</key>
|
|
79
|
+
<dict>
|
|
80
|
+
<key>IntentsSupported</key>
|
|
81
|
+
<array>
|
|
82
|
+
<string>${SEND_MESSAGE_INTENT}</string>
|
|
83
|
+
</array>
|
|
84
|
+
</dict>` : ""}
|
|
85
|
+
</dict>${options.imageHosts?.length ? `
|
|
86
|
+
<key>GenesisRichPushImageHosts</key>
|
|
87
|
+
<array>
|
|
88
|
+
${options.imageHosts.map((h) => ` <string>${esc(h)}</string>`).join("\n")}
|
|
89
|
+
</array>` : ""}
|
|
90
|
+
</dict>
|
|
91
|
+
</plist>
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
function entitlementsPlist(entitlements) {
|
|
95
|
+
const body = Object.entries(entitlements).map(([k, v]) => ` <key>${k}</key>
|
|
96
|
+
<${v ? "true" : "false"}/>`).join("\n");
|
|
97
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
98
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
99
|
+
<plist version="1.0">
|
|
100
|
+
<dict>
|
|
101
|
+
${body}
|
|
102
|
+
</dict>
|
|
103
|
+
</plist>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
function packageRoot(from = path.dirname(fileURLToPath(import.meta.url))) {
|
|
107
|
+
let dir = from;
|
|
108
|
+
for (; ; ) {
|
|
109
|
+
const pkg = path.join(dir, "package.json");
|
|
110
|
+
if (existsSync(pkg) && JSON.parse(readFileSync(pkg, "utf8")).name === "@marktiderman/genesis-native") return dir;
|
|
111
|
+
const parent = path.dirname(dir);
|
|
112
|
+
if (parent === dir) throw new Error("rich-push-plugin: can't find @marktiderman/genesis-native's folder");
|
|
113
|
+
dir = parent;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function serviceSwiftPath(root = packageRoot()) {
|
|
117
|
+
return path.join(root, "ios", "notification-service", SWIFT_FILE);
|
|
118
|
+
}
|
|
119
|
+
function writeExtensionFiles(iosRoot, options) {
|
|
120
|
+
const dir = path.join(iosRoot, options.targetName);
|
|
121
|
+
mkdirSync(dir, { recursive: true });
|
|
122
|
+
copyFileSync(options.swiftSource ?? serviceSwiftPath(), path.join(dir, SWIFT_FILE));
|
|
123
|
+
writeFileSync(path.join(dir, "Info.plist"), extensionInfoPlist(options.displayName, { communication: options.communication, imageHosts: options.imageHosts ?? [] }));
|
|
124
|
+
writeFileSync(path.join(dir, `${options.targetName}.entitlements`), entitlementsPlist(extensionEntitlements(options.communication)));
|
|
125
|
+
}
|
|
126
|
+
var unquote = (v) => typeof v === "string" ? v.replace(/^"(.*)"$/, "$1") : v;
|
|
127
|
+
function appSetting(project, key) {
|
|
128
|
+
const app = project.getFirstTarget();
|
|
129
|
+
const listId = app?.firstTarget?.buildConfigurationList;
|
|
130
|
+
const lists = project.pbxXCConfigurationList();
|
|
131
|
+
const configs = project.pbxXCBuildConfigurationSection();
|
|
132
|
+
for (const ref of lists[listId]?.buildConfigurations ?? []) {
|
|
133
|
+
const value = configs[ref.value]?.buildSettings?.[key];
|
|
134
|
+
if (value !== void 0) return String(unquote(value));
|
|
135
|
+
}
|
|
136
|
+
return void 0;
|
|
137
|
+
}
|
|
138
|
+
function addNotificationServiceTarget(project, options) {
|
|
139
|
+
const { targetName } = options;
|
|
140
|
+
if (project.pbxTargetByName(targetName) || project.pbxTargetByName(`"${targetName}"`)) return { added: false };
|
|
141
|
+
const objects = project.hash.project.objects;
|
|
142
|
+
objects.PBXTargetDependency ??= {};
|
|
143
|
+
objects.PBXContainerItemProxy ??= {};
|
|
144
|
+
const deploymentTarget = options.deploymentTarget ?? appSetting(project, "IPHONEOS_DEPLOYMENT_TARGET") ?? "15.1";
|
|
145
|
+
const marketingVersion = options.marketingVersion ?? appSetting(project, "MARKETING_VERSION") ?? "1.0";
|
|
146
|
+
const buildNumber = options.buildNumber ?? appSetting(project, "CURRENT_PROJECT_VERSION") ?? "1";
|
|
147
|
+
const developmentTeam = options.developmentTeam ?? appSetting(project, "DEVELOPMENT_TEAM");
|
|
148
|
+
const group = project.addPbxGroup([SWIFT_FILE], targetName, targetName);
|
|
149
|
+
project.addFile("Info.plist", group.uuid, { lastKnownFileType: "text.plist.xml" });
|
|
150
|
+
project.addFile(`${targetName}.entitlements`, group.uuid, { lastKnownFileType: "text.plist.entitlements" });
|
|
151
|
+
const mainGroup = project.getFirstProject().firstProject.mainGroup;
|
|
152
|
+
project.addToPbxGroup(group.uuid, mainGroup);
|
|
153
|
+
const target = project.addTarget(targetName, "app_extension", targetName, options.bundleId);
|
|
154
|
+
project.addBuildPhase([SWIFT_FILE], "PBXSourcesBuildPhase", "Sources", target.uuid);
|
|
155
|
+
project.addBuildPhase([], "PBXFrameworksBuildPhase", "Frameworks", target.uuid);
|
|
156
|
+
project.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", target.uuid);
|
|
157
|
+
const configs = project.pbxXCBuildConfigurationSection();
|
|
158
|
+
const listId = target.pbxNativeTarget.buildConfigurationList;
|
|
159
|
+
for (const ref of project.pbxXCConfigurationList()[listId].buildConfigurations) {
|
|
160
|
+
const settings = configs[ref.value].buildSettings;
|
|
161
|
+
Object.assign(settings, {
|
|
162
|
+
INFOPLIST_FILE: `${targetName}/Info.plist`,
|
|
163
|
+
CODE_SIGN_ENTITLEMENTS: `${targetName}/${targetName}.entitlements`,
|
|
164
|
+
CODE_SIGN_STYLE: "Automatic",
|
|
165
|
+
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
166
|
+
TARGETED_DEVICE_FAMILY: '"1,2"',
|
|
167
|
+
SWIFT_VERSION: "5.0",
|
|
168
|
+
MARKETING_VERSION: marketingVersion,
|
|
169
|
+
CURRENT_PROJECT_VERSION: buildNumber,
|
|
170
|
+
GENERATE_INFOPLIST_FILE: "NO",
|
|
171
|
+
PRODUCT_BUNDLE_IDENTIFIER: `"${options.bundleId}"`,
|
|
172
|
+
SDKROOT: "iphoneos",
|
|
173
|
+
CLANG_ENABLE_MODULES: "YES",
|
|
174
|
+
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
175
|
+
...developmentTeam ? { DEVELOPMENT_TEAM: developmentTeam } : {}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
if (developmentTeam) project.addTargetAttribute("DevelopmentTeam", developmentTeam, target);
|
|
179
|
+
return { added: true };
|
|
180
|
+
}
|
|
181
|
+
var withRichPush = (config, options) => {
|
|
182
|
+
const o = resolve(options ?? void 0);
|
|
183
|
+
config = applyRichPushConfig(config, o);
|
|
184
|
+
const bundleId = extensionBundleId(config.ios.bundleIdentifier, o.bundleIdSuffix);
|
|
185
|
+
config = withDangerousMod(config, [
|
|
186
|
+
"ios",
|
|
187
|
+
(c) => {
|
|
188
|
+
writeExtensionFiles(c.modRequest.platformProjectRoot, { targetName: o.targetName, displayName: c.name, communication: o.communication, imageHosts: o.imageHosts });
|
|
189
|
+
return c;
|
|
190
|
+
}
|
|
191
|
+
]);
|
|
192
|
+
config = withXcodeProject(config, (c) => {
|
|
193
|
+
addNotificationServiceTarget(c.modResults, {
|
|
194
|
+
targetName: o.targetName,
|
|
195
|
+
bundleId,
|
|
196
|
+
...o.deploymentTarget ? { deploymentTarget: o.deploymentTarget } : {},
|
|
197
|
+
...c.ios?.appleTeamId ? { developmentTeam: c.ios.appleTeamId } : {},
|
|
198
|
+
...c.version ? { marketingVersion: c.version } : {},
|
|
199
|
+
...c.ios?.buildNumber ? { buildNumber: c.ios.buildNumber } : {}
|
|
200
|
+
});
|
|
201
|
+
return c;
|
|
202
|
+
});
|
|
203
|
+
return config;
|
|
204
|
+
};
|
|
205
|
+
var rich_push_default = withRichPush;
|
|
206
|
+
|
|
207
|
+
export { COMMUNICATION_ENTITLEMENT, DEFAULT_BUNDLE_SUFFIX, DEFAULT_TARGET_NAME, SEND_MESSAGE_INTENT, addNotificationServiceTarget, applyRichPushConfig, rich_push_default as default, entitlementsPlist, extensionBundleId, extensionEntitlements, extensionInfoPlist, packageRoot, serviceSwiftPath, writeExtensionFiles };
|
|
208
|
+
//# sourceMappingURL=rich-push-plugin.js.map
|
|
209
|
+
//# sourceMappingURL=rich-push-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin/rich-push.ts"],"names":[],"mappings":"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","file":"rich-push-plugin.js","sourcesContent":["/**\n * `@marktiderman/genesis-native/rich-push-plugin`: the Expo config plugin for\n * iOS rich push. It adds a Notification Service Extension target (the Swift in\n * `ios/notification-service/`) that downloads `data.image` / `data.senderAvatar`\n * and turns `messages` pushes into Communication Notifications (the sender's\n * photo, Focus treats them as messages), and it sets what they need:\n *\n * - the app: `com.apple.developer.usernotifications.communication` and\n * `NSUserActivityTypes: [INSendMessageIntent]`;\n * - the extension: its own bundle id (`<app>.NotificationService`), Info.plist\n * and entitlements, embedded in the app;\n * - EAS: `extra.eas.build.experimental.ios.appExtensions`, so EAS Build makes\n * the extension's provisioning profile with the app's.\n *\n * plugins: [..., \"@marktiderman/genesis-cli\", \"@marktiderman/genesis-native/rich-push-plugin\"]\n *\n * List it after any plugin that changes the bundle id (the Genesis plugin's\n * APP_VARIANT suffix): the extension's id is the app's plus a suffix, read\n * when this plugin runs. Running it twice changes nothing.\n */\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n// Expo's own copy (the app's `expo`), so the mods run on the same config-plugins as prebuild.\nimport { withDangerousMod, withXcodeProject, type ConfigPlugin } from \"expo/config-plugins\";\nimport type { ExpoConfig } from \"expo/config\";\n\nexport const COMMUNICATION_ENTITLEMENT = \"com.apple.developer.usernotifications.communication\";\nexport const SEND_MESSAGE_INTENT = \"INSendMessageIntent\";\nexport const DEFAULT_TARGET_NAME = \"GenesisNotificationService\";\nexport const DEFAULT_BUNDLE_SUFFIX = \"NotificationService\";\nconst SWIFT_FILE = \"NotificationService.swift\";\n\nexport interface RichPushPluginOptions {\n /** The extension's Xcode target and folder under ios/. Default `GenesisNotificationService`. */\n targetName?: string;\n /** Appended to the app's bundle id with a dot. Default `NotificationService`. */\n bundleIdSuffix?: string;\n /**\n * Communication Notifications (the sender's photo, Focus): the entitlement and\n * `NSUserActivityTypes`. Default true; false keeps image attachments only.\n */\n communication?: boolean;\n /** The extension's minimum iOS. Default: the app target's. */\n deploymentTarget?: string;\n /**\n * The hosts images may be downloaded from (`cdn.example.com`, or `example.com`\n * for it and its subdomains). Unset, any https host: a sender who puts a URL\n * a person chose (their avatar) in a push lets that host see each delivery.\n */\n imageHosts?: string[];\n}\n\ninterface Resolved {\n targetName: string;\n bundleIdSuffix: string;\n communication: boolean;\n deploymentTarget: string | undefined;\n imageHosts: string[];\n}\n\nfunction resolve(options: RichPushPluginOptions | undefined): Resolved {\n const targetName = options?.targetName ?? DEFAULT_TARGET_NAME;\n const bundleIdSuffix = options?.bundleIdSuffix ?? DEFAULT_BUNDLE_SUFFIX;\n if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(targetName)) throw new Error(`rich-push-plugin: targetName \"${targetName}\" must be letters, digits and _`);\n if (!/^[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$/.test(bundleIdSuffix)) throw new Error(`rich-push-plugin: bundleIdSuffix \"${bundleIdSuffix}\" isn't a bundle id part`);\n const imageHosts = (options?.imageHosts ?? []).map((h) => h.trim().toLowerCase());\n for (const h of imageHosts) if (!/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/.test(h)) throw new Error(`rich-push-plugin: imageHosts \"${h}\" isn't a host name`);\n return { targetName, bundleIdSuffix, communication: options?.communication ?? true, deploymentTarget: options?.deploymentTarget, imageHosts };\n}\n\n/** The extension's bundle id: the app's plus the suffix. */\nexport function extensionBundleId(appBundleId: string, suffix = DEFAULT_BUNDLE_SUFFIX): string {\n return `${appBundleId}.${suffix}`;\n}\n\n/** The extension's entitlements (also what EAS provisions it with). */\nexport function extensionEntitlements(communication: boolean): Record<string, unknown> {\n return communication ? { [COMMUNICATION_ENTITLEMENT]: true } : {};\n}\n\n/**\n * The config-time part, visible in `expo config`: the app's entitlement and\n * `NSUserActivityTypes`, and the extension for EAS. Fills gaps and appends;\n * never removes what the app set.\n */\nexport function applyRichPushConfig(config: ExpoConfig, options?: RichPushPluginOptions): ExpoConfig {\n const o = resolve(options);\n const bundleId = config.ios?.bundleIdentifier;\n if (!bundleId) throw new Error(\"rich-push-plugin: ios.bundleIdentifier is required (the extension's id is built from it)\");\n const ios = { ...config.ios };\n if (o.communication) {\n ios.entitlements = { ...ios.entitlements, [COMMUNICATION_ENTITLEMENT]: true };\n const types = Array.isArray(ios.infoPlist?.NSUserActivityTypes) ? (ios.infoPlist!.NSUserActivityTypes as unknown[]) : [];\n ios.infoPlist = { ...ios.infoPlist, NSUserActivityTypes: types.includes(SEND_MESSAGE_INTENT) ? types : [...types, SEND_MESSAGE_INTENT] };\n }\n const extra = { ...config.extra };\n const eas = { ...(extra.eas as Record<string, unknown> | undefined) };\n const build = { ...(eas.build as Record<string, unknown> | undefined) };\n const experimental = { ...(build.experimental as Record<string, unknown> | undefined) };\n const easIos = { ...(experimental.ios as Record<string, unknown> | undefined) };\n const existing = Array.isArray(easIos.appExtensions) ? (easIos.appExtensions as { targetName?: string }[]) : [];\n const entry = { targetName: o.targetName, bundleIdentifier: extensionBundleId(bundleId, o.bundleIdSuffix), entitlements: extensionEntitlements(o.communication) };\n easIos.appExtensions = [...existing.filter((e) => e?.targetName !== o.targetName), entry];\n extra.eas = { ...eas, build: { ...build, experimental: { ...experimental, ios: easIos } } };\n return { ...config, ios, extra };\n}\n\n/** The extension's Info.plist. Versions follow the app's (App Store Connect rejects a mismatch). */\nexport function extensionInfoPlist(displayName: string, options: { communication?: boolean; imageHosts?: string[] } = {}): string {\n const esc = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>CFBundleDevelopmentRegion</key>\n <string>$(DEVELOPMENT_LANGUAGE)</string>\n <key>CFBundleDisplayName</key>\n <string>${esc(displayName)}</string>\n <key>CFBundleExecutable</key>\n <string>$(EXECUTABLE_NAME)</string>\n <key>CFBundleIdentifier</key>\n <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n <key>CFBundleInfoDictionaryVersion</key>\n <string>6.0</string>\n <key>CFBundleName</key>\n <string>$(PRODUCT_NAME)</string>\n <key>CFBundlePackageType</key>\n <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n <key>CFBundleShortVersionString</key>\n <string>$(MARKETING_VERSION)</string>\n <key>CFBundleVersion</key>\n <string>$(CURRENT_PROJECT_VERSION)</string>\n <key>NSExtension</key>\n <dict>\n <key>NSExtensionPointIdentifier</key>\n <string>com.apple.usernotifications.service</string>\n <key>NSExtensionPrincipalClass</key>\n <string>$(PRODUCT_MODULE_NAME).NotificationService</string>${\n options.communication\n ? `\n <key>NSExtensionAttributes</key>\n <dict>\n <key>IntentsSupported</key>\n <array>\n <string>${SEND_MESSAGE_INTENT}</string>\n </array>\n </dict>`\n : \"\"\n }\n </dict>${\n options.imageHosts?.length\n ? `\n <key>GenesisRichPushImageHosts</key>\n <array>\n${options.imageHosts.map((h) => ` <string>${esc(h)}</string>`).join(\"\\n\")}\n </array>`\n : \"\"\n }\n</dict>\n</plist>\n`;\n}\n\nexport function entitlementsPlist(entitlements: Record<string, unknown>): string {\n const body = Object.entries(entitlements)\n .map(([k, v]) => ` <key>${k}</key>\\n <${v ? \"true\" : \"false\"}/>`)\n .join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n${body}\n</dict>\n</plist>\n`;\n}\n\n/** This package's root, found from this file (src/plugin in tests, dist when built). */\nexport function packageRoot(from = path.dirname(fileURLToPath(import.meta.url))): string {\n let dir = from;\n for (;;) {\n const pkg = path.join(dir, \"package.json\");\n if (existsSync(pkg) && (JSON.parse(readFileSync(pkg, \"utf8\")) as { name?: string }).name === \"@marktiderman/genesis-native\") return dir;\n const parent = path.dirname(dir);\n if (parent === dir) throw new Error(\"rich-push-plugin: can't find @marktiderman/genesis-native's folder\");\n dir = parent;\n }\n}\n\n/** The extension's Swift source, shipped in this package. */\nexport function serviceSwiftPath(root = packageRoot()): string {\n return path.join(root, \"ios\", \"notification-service\", SWIFT_FILE);\n}\n\n/** Writes the extension's folder under ios/: the Swift, its Info.plist and its entitlements. */\nexport function writeExtensionFiles(\n iosRoot: string,\n options: { targetName: string; displayName: string; communication: boolean; imageHosts?: string[]; swiftSource?: string },\n): void {\n const dir = path.join(iosRoot, options.targetName);\n mkdirSync(dir, { recursive: true });\n copyFileSync(options.swiftSource ?? serviceSwiftPath(), path.join(dir, SWIFT_FILE));\n writeFileSync(path.join(dir, \"Info.plist\"), extensionInfoPlist(options.displayName, { communication: options.communication, imageHosts: options.imageHosts ?? [] }));\n writeFileSync(path.join(dir, `${options.targetName}.entitlements`), entitlementsPlist(extensionEntitlements(options.communication)));\n}\n\n/** The parts of the `xcode` package's project this uses. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype XcodeProject = any;\n\nconst unquote = (v: unknown) => (typeof v === \"string\" ? v.replace(/^\"(.*)\"$/, \"$1\") : v);\n\n/** The app target's build setting (its first configuration that has it). */\nfunction appSetting(project: XcodeProject, key: string): string | undefined {\n const app = project.getFirstTarget();\n const listId = app?.firstTarget?.buildConfigurationList;\n const lists = project.pbxXCConfigurationList();\n const configs = project.pbxXCBuildConfigurationSection();\n for (const ref of lists[listId]?.buildConfigurations ?? []) {\n const value = configs[ref.value]?.buildSettings?.[key];\n if (value !== undefined) return String(unquote(value));\n }\n return undefined;\n}\n\n/**\n * Adds the extension target to the project (once): its group and files, the\n * sources, frameworks and resources phases, its build settings, a dependency\n * from the app and the app's phase that embeds it.\n */\nexport function addNotificationServiceTarget(\n project: XcodeProject,\n options: { targetName: string; bundleId: string; deploymentTarget?: string; developmentTeam?: string; marketingVersion?: string; buildNumber?: string },\n): { added: boolean } {\n const { targetName } = options;\n if (project.pbxTargetByName(targetName) || project.pbxTargetByName(`\"${targetName}\"`)) return { added: false };\n\n const objects = project.hash.project.objects;\n // The xcode package assumes these sections exist; Expo's template has none.\n objects.PBXTargetDependency ??= {};\n objects.PBXContainerItemProxy ??= {};\n\n const deploymentTarget = options.deploymentTarget ?? appSetting(project, \"IPHONEOS_DEPLOYMENT_TARGET\") ?? \"15.1\";\n const marketingVersion = options.marketingVersion ?? appSetting(project, \"MARKETING_VERSION\") ?? \"1.0\";\n const buildNumber = options.buildNumber ?? appSetting(project, \"CURRENT_PROJECT_VERSION\") ?? \"1\";\n const developmentTeam = options.developmentTeam ?? appSetting(project, \"DEVELOPMENT_TEAM\");\n\n // The Swift is compiled; the Info.plist and entitlements are build settings, so they are in the group only.\n const group = project.addPbxGroup([SWIFT_FILE], targetName, targetName);\n project.addFile(\"Info.plist\", group.uuid, { lastKnownFileType: \"text.plist.xml\" });\n project.addFile(`${targetName}.entitlements`, group.uuid, { lastKnownFileType: \"text.plist.entitlements\" });\n const mainGroup = project.getFirstProject().firstProject.mainGroup;\n project.addToPbxGroup(group.uuid, mainGroup);\n\n const target = project.addTarget(targetName, \"app_extension\", targetName, options.bundleId);\n project.addBuildPhase([SWIFT_FILE], \"PBXSourcesBuildPhase\", \"Sources\", target.uuid);\n project.addBuildPhase([], \"PBXFrameworksBuildPhase\", \"Frameworks\", target.uuid);\n project.addBuildPhase([], \"PBXResourcesBuildPhase\", \"Resources\", target.uuid);\n\n const configs = project.pbxXCBuildConfigurationSection();\n const listId = target.pbxNativeTarget.buildConfigurationList;\n for (const ref of project.pbxXCConfigurationList()[listId].buildConfigurations) {\n const settings = configs[ref.value].buildSettings;\n Object.assign(settings, {\n INFOPLIST_FILE: `${targetName}/Info.plist`,\n CODE_SIGN_ENTITLEMENTS: `${targetName}/${targetName}.entitlements`,\n CODE_SIGN_STYLE: \"Automatic\",\n IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,\n TARGETED_DEVICE_FAMILY: '\"1,2\"',\n SWIFT_VERSION: \"5.0\",\n MARKETING_VERSION: marketingVersion,\n CURRENT_PROJECT_VERSION: buildNumber,\n GENERATE_INFOPLIST_FILE: \"NO\",\n PRODUCT_BUNDLE_IDENTIFIER: `\"${options.bundleId}\"`,\n SDKROOT: \"iphoneos\",\n CLANG_ENABLE_MODULES: \"YES\",\n SWIFT_EMIT_LOC_STRINGS: \"YES\",\n ...(developmentTeam ? { DEVELOPMENT_TEAM: developmentTeam } : {}),\n });\n }\n if (developmentTeam) project.addTargetAttribute(\"DevelopmentTeam\", developmentTeam, target);\n return { added: true };\n}\n\nconst withRichPush: ConfigPlugin<RichPushPluginOptions | void> = (config, options) => {\n const o = resolve(options ?? undefined);\n config = applyRichPushConfig(config, o);\n const bundleId = extensionBundleId(config.ios!.bundleIdentifier!, o.bundleIdSuffix);\n\n config = withDangerousMod(config, [\n \"ios\",\n (c) => {\n writeExtensionFiles(c.modRequest.platformProjectRoot, { targetName: o.targetName, displayName: c.name, communication: o.communication, imageHosts: o.imageHosts });\n return c;\n },\n ]);\n config = withXcodeProject(config, (c) => {\n addNotificationServiceTarget(c.modResults, {\n targetName: o.targetName,\n bundleId,\n ...(o.deploymentTarget ? { deploymentTarget: o.deploymentTarget } : {}),\n ...(c.ios?.appleTeamId ? { developmentTeam: c.ios.appleTeamId } : {}),\n ...(c.version ? { marketingVersion: c.version } : {}),\n ...(c.ios?.buildNumber ? { buildNumber: c.ios.buildNumber } : {}),\n });\n return c;\n });\n return config;\n};\n\nexport default withRichPush;\n"]}
|
package/dist/updates.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { b5 as ApplicationLike, b6 as CLOCK_SKEW_MS, b7 as ChannelSwitchResult, b8 as ChannelSwitcher, b9 as ChannelSwitcherOptions, ba as EvaluatePolicyOptions, bb as ForceUpgradeProps, bc as ForceUpgradeScreen, bd as MaintenanceProps, be as MaintenanceScreen, bf as PolicyClientLike, bg as PolicyOrigin, bh as PolicyState, bi as PolicyStore, bj as PolicyStoreOptions, bk as ReleaseNote, bl as ReloadGuard, bm as SupabasePolicySourceOptions, bn as UPDATES_BLOCK_ID, bo as UpdateBanner, bp as UpdateBannerProps, bq as UpdateCheckState, br as UpdateCheckStatus, bs as UpdateChecker, bt as UpdateCheckerOptions, bu as UpdatePlatform, bv as UpdatePolicy, bw as UpdatePolicySource, bx as UpdateVerdict, by as UpdatesAppStateLike, U as UpdatesBlock, bz as UpdatesErrorSource, bA as UpdatesModuleLike, bB as UpdatesOnError, bC as UpdatesOptions, bD as UpdatesProvider, bE as UpdatesRoot, bF as UpdatesRootProps, bG as UpdatesSlots, bH as UpdatesStorageLike, V as VersionSignature, bI as VersionSignatureInput, bJ as WEEK_MS, bK as WhatsNewOptions, bL as WhatsNewProps, bM as WhatsNewSheet, bN as WhatsNewState, bO as WhatsNewStore, bP as createChannelSwitcher, bQ as createPolicyStore, bR as createReloadGuard, bS as createUpdateChecker, bT as createUpdates, bU as createWhatsNewStore, bV as evaluatePolicy, bW as notesSince, bX as sanitizePolicy, bY as staticPolicySource, bZ as supabasePolicySource, b_ as useBlockReload, b$ as useCanReload, c0 as useForceUpgrade, c1 as useMaintenance, c2 as useUpdateBanner, c3 as useUpdateCheck, c4 as useUpdatePolicy, c5 as useUpdateVerdict, c6 as useUpdates, c7 as useVersionSignature, c8 as useWhatsNew, c9 as versionSignature } from './blocks-C2RDpvaN.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
import '@marktiderman/genesis-core/slots';
|
|
4
|
+
import '@marktiderman/genesis-features/blocks';
|
|
5
|
+
import '@tanstack/react-query';
|
|
6
|
+
import '@marktiderman/genesis-design-system';
|
|
7
|
+
import '@marktiderman/genesis-core/provider';
|
|
8
|
+
import '@marktiderman/genesis-ui-native/layouts';
|
|
9
|
+
import '@marktiderman/genesis-ui-native/components';
|
|
10
|
+
import './query-DUmVAfsF.js';
|
|
4
11
|
|
|
5
12
|
/**
|
|
6
13
|
* Version numbers: the store version an app reports (`1.4.0`, `1.10`) and
|
package/dist/updates.js
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
|
+
import { createStore, delay } from './chunk-XE7LC7K6.js';
|
|
2
|
+
import { versionSignature } from './chunk-6BT4PTGH.js';
|
|
3
|
+
export { versionSignature } from './chunk-6BT4PTGH.js';
|
|
1
4
|
import { createContext, useContext, useEffect, useSyncExternalStore, useMemo, useState } from 'react';
|
|
2
5
|
import { View } from 'react-native';
|
|
3
6
|
import { renderSlot } from '@marktiderman/genesis-core/slots';
|
|
7
|
+
import { defineBlock } from '@marktiderman/genesis-features/blocks';
|
|
4
8
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
5
|
-
import { NativeEmptyState, NativeButton, NativeBanner, NativeSheet, NativeText } from '@marktiderman/genesis-ui-native/components';
|
|
9
|
+
import { NativeEmptyState, NativeButton, useLiquidGlass, NativeGlassSurface, NativeBanner, NativeSheet, NativeSheetScrollView, NativeText } from '@marktiderman/genesis-ui-native/components';
|
|
6
10
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
11
|
|
|
8
|
-
// src/updates/block.tsx
|
|
9
|
-
|
|
10
|
-
// src/updates/store.ts
|
|
11
|
-
function createStore(initial) {
|
|
12
|
-
let state = initial;
|
|
13
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
14
|
-
return {
|
|
15
|
-
getState: () => state,
|
|
16
|
-
setState(next) {
|
|
17
|
-
const merged = { ...state, ...next };
|
|
18
|
-
if (Object.keys(merged).every((key) => Object.is(merged[key], state[key]))) return;
|
|
19
|
-
state = merged;
|
|
20
|
-
for (const listener of [...listeners]) listener();
|
|
21
|
-
},
|
|
22
|
-
subscribe(listener) {
|
|
23
|
-
listeners.add(listener);
|
|
24
|
-
return () => {
|
|
25
|
-
listeners.delete(listener);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function delay(ms) {
|
|
31
|
-
return new Promise((resolve) => {
|
|
32
|
-
if (Number.isFinite(ms)) setTimeout(resolve, Math.max(0, ms));
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
12
|
// src/updates/modules.ts
|
|
37
13
|
function toError(value) {
|
|
38
14
|
return value instanceof Error ? value : new Error(typeof value === "string" ? value : "Unknown error");
|
|
@@ -444,39 +420,6 @@ function evaluatePolicy(state, options) {
|
|
|
444
420
|
return { kind: "ok" };
|
|
445
421
|
}
|
|
446
422
|
|
|
447
|
-
// src/updates/signature.ts
|
|
448
|
-
var UNKNOWN = "unknown";
|
|
449
|
-
function versionSignature({ application, updates, platform, requestedChannel = null }) {
|
|
450
|
-
const version = application?.nativeApplicationVersion ?? null;
|
|
451
|
-
const build = application?.nativeBuildVersion ?? null;
|
|
452
|
-
const on = Boolean(updates?.isEnabled);
|
|
453
|
-
const channel = on ? updates?.channel ?? null : null;
|
|
454
|
-
const updateId = on ? updates?.updateId ?? null : null;
|
|
455
|
-
const runtimeVersion = updates?.runtimeVersion ?? null;
|
|
456
|
-
const launch = !on ? "off" : updates?.isEmbeddedLaunch ? "embedded" : "update";
|
|
457
|
-
const emergency = on && updates?.isEmergencyLaunch === true;
|
|
458
|
-
const shownChannel = requestedChannel ?? channel;
|
|
459
|
-
const head = `${version ?? UNKNOWN} (${build ?? UNKNOWN})`;
|
|
460
|
-
const parts = [head];
|
|
461
|
-
if (launch === "off") {
|
|
462
|
-
parts.push("updates off");
|
|
463
|
-
} else {
|
|
464
|
-
parts.push(shownChannel ?? "no channel");
|
|
465
|
-
parts.push(launch === "embedded" ? "embedded" : updateId?.slice(0, 8) ?? UNKNOWN);
|
|
466
|
-
}
|
|
467
|
-
if (emergency) parts.push("emergency launch");
|
|
468
|
-
const short = parts.join(" \xB7 ");
|
|
469
|
-
const lines = [
|
|
470
|
-
`Version ${head}`,
|
|
471
|
-
`Platform ${platform}`,
|
|
472
|
-
`Channel ${channel ?? (on ? UNKNOWN : "none")}${requestedChannel && requestedChannel !== channel ? ` (switched to ${requestedChannel})` : ""}`,
|
|
473
|
-
`Runtime ${runtimeVersion ?? UNKNOWN}`,
|
|
474
|
-
`Update ${launch === "off" ? "updates off" : launch === "embedded" ? "embedded" : updateId ?? UNKNOWN}`
|
|
475
|
-
];
|
|
476
|
-
if (emergency) lines.push(`Emergency launch: ${updates?.emergencyLaunchReason ?? UNKNOWN}`);
|
|
477
|
-
return { version, build, platform, channel, requestedChannel, runtimeVersion, updateId, launch, emergency, short, text: lines.join("\n") };
|
|
478
|
-
}
|
|
479
|
-
|
|
480
423
|
// src/updates/whats-new.ts
|
|
481
424
|
function notesSince(notes, seen, version) {
|
|
482
425
|
return notes.filter((note) => {
|
|
@@ -574,14 +517,15 @@ function MaintenanceScreen({ message, retry, retrying }) {
|
|
|
574
517
|
) });
|
|
575
518
|
}
|
|
576
519
|
function UpdateBanner({ reload, dismiss, canReload, blocked, reloading }) {
|
|
577
|
-
|
|
520
|
+
const onGlass = useLiquidGlass() !== null;
|
|
521
|
+
return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["top"], pointerEvents: "box-none", style: { position: "absolute", top: 0, left: 0, right: 0 }, children: /* @__PURE__ */ jsx(View, { className: "mx-3 mt-2", children: /* @__PURE__ */ jsxs(NativeGlassSurface, { testID: "genesis-update-banner", fallbackClassName: "overflow-hidden rounded-lg border border-border bg-secondary", children: [
|
|
578
522
|
/* @__PURE__ */ jsx(
|
|
579
523
|
NativeBanner,
|
|
580
524
|
{
|
|
581
525
|
variant: "info",
|
|
582
526
|
title: "An update is ready",
|
|
583
527
|
description: blocked || !canReload ? "Finish what you're doing, then restart to use it." : "Restart to use the latest version.",
|
|
584
|
-
className: "border-b-0",
|
|
528
|
+
className: onGlass ? "border-b-0 border-transparent bg-transparent" : "border-b-0",
|
|
585
529
|
testID: "genesis-update-banner-message"
|
|
586
530
|
}
|
|
587
531
|
),
|
|
@@ -589,10 +533,10 @@ function UpdateBanner({ reload, dismiss, canReload, blocked, reloading }) {
|
|
|
589
533
|
/* @__PURE__ */ jsx(NativeButton, { variant: "ghost", size: "sm", onPress: dismiss, testID: "genesis-update-banner-later", children: "Later" }),
|
|
590
534
|
/* @__PURE__ */ jsx(NativeButton, { size: "sm", onPress: reload, disabled: !canReload, loading: reloading, testID: "genesis-update-banner-restart", children: "Restart" })
|
|
591
535
|
] })
|
|
592
|
-
] }) });
|
|
536
|
+
] }) }) });
|
|
593
537
|
}
|
|
594
538
|
function WhatsNewSheet({ notes, dismiss }) {
|
|
595
|
-
return /* @__PURE__ */ jsx(NativeSheet, { open: true, onOpenChange: (open) => open ? void 0 : dismiss(), testID: "genesis-whats-new", children: /* @__PURE__ */ jsxs(
|
|
539
|
+
return /* @__PURE__ */ jsx(NativeSheet, { open: true, onOpenChange: (open) => open ? void 0 : dismiss(), testID: "genesis-whats-new", children: /* @__PURE__ */ jsxs(NativeSheetScrollView, { contentContainerClassName: "gap-4 p-6", children: [
|
|
596
540
|
/* @__PURE__ */ jsx(NativeText, { preset: "h3", accessibilityRole: "header", children: "What's new" }),
|
|
597
541
|
notes.map((note) => /* @__PURE__ */ jsxs(View, { className: "gap-1", testID: `genesis-whats-new-${note.version}`, children: [
|
|
598
542
|
/* @__PURE__ */ jsx(NativeText, { preset: "label", children: note.title ?? `Version ${note.version}` }),
|
|
@@ -601,6 +545,7 @@ function WhatsNewSheet({ notes, dismiss }) {
|
|
|
601
545
|
/* @__PURE__ */ jsx(NativeButton, { onPress: dismiss, testID: "genesis-whats-new-done", children: "Got it" })
|
|
602
546
|
] }) });
|
|
603
547
|
}
|
|
548
|
+
var UPDATES_BLOCK_ID = "app-updates";
|
|
604
549
|
function createUpdates(options) {
|
|
605
550
|
const {
|
|
606
551
|
platform,
|
|
@@ -661,7 +606,34 @@ function createUpdates(options) {
|
|
|
661
606
|
});
|
|
662
607
|
return loaded;
|
|
663
608
|
};
|
|
609
|
+
const bootStep = { id: "genesis:updates", run: load, timeoutMs: policyTimeoutMs + 5e3 };
|
|
610
|
+
const { versionRow } = options;
|
|
611
|
+
const declaration = defineBlock({
|
|
612
|
+
id: UPDATES_BLOCK_ID,
|
|
613
|
+
platforms: ["native"],
|
|
614
|
+
contributes: {
|
|
615
|
+
settings: versionRow === false ? [] : [
|
|
616
|
+
{
|
|
617
|
+
id: "app-version",
|
|
618
|
+
section: versionRow?.section ?? "about",
|
|
619
|
+
title: versionRow?.title ?? "Version",
|
|
620
|
+
testID: "genesis-app-version",
|
|
621
|
+
// Bound to this block, so it needs no provider above the Settings screen.
|
|
622
|
+
useSubtitle: () => useVersionSignatureOf(block).short
|
|
623
|
+
}
|
|
624
|
+
],
|
|
625
|
+
migrations: [
|
|
626
|
+
{
|
|
627
|
+
package: "@marktiderman/genesis-supabase",
|
|
628
|
+
file: "migrations/0002_genesis_app_release_policy.sql",
|
|
629
|
+
test: "migrations/tests/0002_genesis_app_release_policy.test.sql"
|
|
630
|
+
}
|
|
631
|
+
],
|
|
632
|
+
privacy: { notes: ["Reads the installed version and update ids on the device to decide on a force upgrade; sends nothing about the person."] }
|
|
633
|
+
}
|
|
634
|
+
});
|
|
664
635
|
const block = {
|
|
636
|
+
...declaration,
|
|
665
637
|
options,
|
|
666
638
|
policy,
|
|
667
639
|
checker,
|
|
@@ -669,7 +641,8 @@ function createUpdates(options) {
|
|
|
669
641
|
whatsNew,
|
|
670
642
|
channels: switcher,
|
|
671
643
|
signature,
|
|
672
|
-
bootStep
|
|
644
|
+
bootStep,
|
|
645
|
+
bootSteps: [bootStep],
|
|
673
646
|
start() {
|
|
674
647
|
void load();
|
|
675
648
|
void checker.check();
|
|
@@ -765,7 +738,9 @@ function useWhatsNew() {
|
|
|
765
738
|
return { notes: state.notes, version: block.options.application?.nativeApplicationVersion ?? null, dismiss: () => block.whatsNew.dismiss() };
|
|
766
739
|
}
|
|
767
740
|
function useVersionSignature() {
|
|
768
|
-
|
|
741
|
+
return useVersionSignatureOf(useUpdates());
|
|
742
|
+
}
|
|
743
|
+
function useVersionSignatureOf(block) {
|
|
769
744
|
const [requested, setRequested] = useState(null);
|
|
770
745
|
useEffect(() => {
|
|
771
746
|
let alive = true;
|
|
@@ -808,6 +783,6 @@ function UpdatesParts({ slots, slotProps, children }) {
|
|
|
808
783
|
] });
|
|
809
784
|
}
|
|
810
785
|
|
|
811
|
-
export { CLOCK_SKEW_MS, ForceUpgradeScreen, MaintenanceScreen, UpdateBanner, UpdatesProvider, UpdatesRoot, WEEK_MS, WhatsNewSheet, compareVersions, createChannelSwitcher, createPolicyStore, createReloadGuard, createUpdateChecker, createUpdates, createWhatsNewStore, evaluatePolicy, isBelowMinimum, notesSince, parseVersion, sanitizePolicy, staticPolicySource, supabasePolicySource, useBlockReload, useCanReload, useForceUpgrade, useMaintenance, useUpdateBanner, useUpdateCheck, useUpdatePolicy, useUpdateVerdict, useUpdates, useVersionSignature, useWhatsNew
|
|
786
|
+
export { CLOCK_SKEW_MS, ForceUpgradeScreen, MaintenanceScreen, UPDATES_BLOCK_ID, UpdateBanner, UpdatesProvider, UpdatesRoot, WEEK_MS, WhatsNewSheet, compareVersions, createChannelSwitcher, createPolicyStore, createReloadGuard, createUpdateChecker, createUpdates, createWhatsNewStore, evaluatePolicy, isBelowMinimum, notesSince, parseVersion, sanitizePolicy, staticPolicySource, supabasePolicySource, useBlockReload, useCanReload, useForceUpgrade, useMaintenance, useUpdateBanner, useUpdateCheck, useUpdatePolicy, useUpdateVerdict, useUpdates, useVersionSignature, useWhatsNew };
|
|
812
787
|
//# sourceMappingURL=updates.js.map
|
|
813
788
|
//# sourceMappingURL=updates.js.map
|