@use-voltra/ios-client 2.2.0 → 2.3.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/Voltra.podspec +1 -0
- package/build/commonjs/events.js +23 -0
- package/build/commonjs/events.js.map +1 -1
- package/build/commonjs/index.js +59 -0
- package/build/commonjs/index.js.map +1 -1
- package/build/commonjs/live-activity/api.js +3 -1
- package/build/commonjs/live-activity/api.js.map +1 -1
- package/build/commonjs/live-activity/dynamic-api.js +173 -0
- package/build/commonjs/live-activity/dynamic-api.js.map +1 -0
- package/build/commonjs/native/NativeVoltra.js.map +1 -1
- package/build/commonjs/utils/enableDynamicLiveActivityHotReload.js +47 -0
- package/build/commonjs/utils/enableDynamicLiveActivityHotReload.js.map +1 -0
- package/build/commonjs/utils/enableWidgetHotReload.js +8 -11
- package/build/commonjs/utils/enableWidgetHotReload.js.map +1 -1
- package/build/commonjs/utils/useUpdateOnHMR.js +3 -7
- package/build/commonjs/utils/useUpdateOnHMR.js.map +1 -1
- package/build/commonjs/widgets/server-credentials.js +9 -0
- package/build/commonjs/widgets/server-credentials.js.map +1 -1
- package/build/commonjs/widgets/server-update.js +78 -0
- package/build/commonjs/widgets/server-update.js.map +1 -0
- package/build/module/events.js +23 -0
- package/build/module/events.js.map +1 -1
- package/build/module/index.js +3 -0
- package/build/module/index.js.map +1 -1
- package/build/module/live-activity/api.js +2 -2
- package/build/module/live-activity/api.js.map +1 -1
- package/build/module/live-activity/dynamic-api.js +167 -0
- package/build/module/live-activity/dynamic-api.js.map +1 -0
- package/build/module/native/NativeVoltra.js.map +1 -1
- package/build/module/utils/enableDynamicLiveActivityHotReload.js +43 -0
- package/build/module/utils/enableDynamicLiveActivityHotReload.js.map +1 -0
- package/build/module/utils/enableWidgetHotReload.js +9 -11
- package/build/module/utils/enableWidgetHotReload.js.map +1 -1
- package/build/module/utils/useUpdateOnHMR.js +3 -7
- package/build/module/utils/useUpdateOnHMR.js.map +1 -1
- package/build/module/widgets/server-credentials.js +9 -0
- package/build/module/widgets/server-credentials.js.map +1 -1
- package/build/module/widgets/server-update.js +72 -0
- package/build/module/widgets/server-update.js.map +1 -0
- package/build/typescript/commonjs/events.d.ts +7 -0
- package/build/typescript/commonjs/events.d.ts.map +1 -1
- package/build/typescript/commonjs/index.d.ts +3 -0
- package/build/typescript/commonjs/index.d.ts.map +1 -1
- package/build/typescript/commonjs/live-activity/api.d.ts +7 -0
- package/build/typescript/commonjs/live-activity/api.d.ts.map +1 -1
- package/build/typescript/commonjs/live-activity/dynamic-api.d.ts +54 -0
- package/build/typescript/commonjs/live-activity/dynamic-api.d.ts.map +1 -0
- package/build/typescript/commonjs/native/NativeVoltra.d.ts +20 -0
- package/build/typescript/commonjs/native/NativeVoltra.d.ts.map +1 -1
- package/build/typescript/commonjs/types.d.ts +1 -1
- package/build/typescript/commonjs/types.d.ts.map +1 -1
- package/build/typescript/commonjs/utils/enableDynamicLiveActivityHotReload.d.ts +15 -0
- package/build/typescript/commonjs/utils/enableDynamicLiveActivityHotReload.d.ts.map +1 -0
- package/build/typescript/commonjs/utils/enableWidgetHotReload.d.ts +5 -7
- package/build/typescript/commonjs/utils/enableWidgetHotReload.d.ts.map +1 -1
- package/build/typescript/commonjs/utils/useUpdateOnHMR.d.ts +0 -3
- package/build/typescript/commonjs/utils/useUpdateOnHMR.d.ts.map +1 -1
- package/build/typescript/commonjs/widgets/server-credentials.d.ts +8 -0
- package/build/typescript/commonjs/widgets/server-credentials.d.ts.map +1 -1
- package/build/typescript/commonjs/widgets/server-update.d.ts +64 -0
- package/build/typescript/commonjs/widgets/server-update.d.ts.map +1 -0
- package/build/typescript/module/events.d.ts +7 -0
- package/build/typescript/module/events.d.ts.map +1 -1
- package/build/typescript/module/index.d.ts +3 -0
- package/build/typescript/module/index.d.ts.map +1 -1
- package/build/typescript/module/live-activity/api.d.ts +7 -0
- package/build/typescript/module/live-activity/api.d.ts.map +1 -1
- package/build/typescript/module/live-activity/dynamic-api.d.ts +54 -0
- package/build/typescript/module/live-activity/dynamic-api.d.ts.map +1 -0
- package/build/typescript/module/native/NativeVoltra.d.ts +20 -0
- package/build/typescript/module/native/NativeVoltra.d.ts.map +1 -1
- package/build/typescript/module/types.d.ts +1 -1
- package/build/typescript/module/types.d.ts.map +1 -1
- package/build/typescript/module/utils/enableDynamicLiveActivityHotReload.d.ts +15 -0
- package/build/typescript/module/utils/enableDynamicLiveActivityHotReload.d.ts.map +1 -0
- package/build/typescript/module/utils/enableWidgetHotReload.d.ts +5 -7
- package/build/typescript/module/utils/enableWidgetHotReload.d.ts.map +1 -1
- package/build/typescript/module/utils/useUpdateOnHMR.d.ts +0 -3
- package/build/typescript/module/utils/useUpdateOnHMR.d.ts.map +1 -1
- package/build/typescript/module/widgets/server-credentials.d.ts +8 -0
- package/build/typescript/module/widgets/server-credentials.d.ts.map +1 -1
- package/build/typescript/module/widgets/server-update.d.ts +64 -0
- package/build/typescript/module/widgets/server-update.d.ts.map +1 -0
- package/expo-plugin/build/cjs/constants.js +20 -1
- package/expo-plugin/build/cjs/constants.js.map +1 -1
- package/expo-plugin/build/cjs/index.js +6 -0
- package/expo-plugin/build/cjs/index.js.map +1 -1
- package/expo-plugin/build/cjs/ios/index.js +1 -0
- package/expo-plugin/build/cjs/ios/index.js.map +1 -1
- package/expo-plugin/build/cjs/ios/infoPlist.js +28 -5
- package/expo-plugin/build/cjs/ios/infoPlist.js.map +1 -1
- package/expo-plugin/build/cjs/ios/serverUpdate.js +25 -0
- package/expo-plugin/build/cjs/ios/serverUpdate.js.map +1 -0
- package/expo-plugin/build/cjs/ios-widget/clientRendered.js +4 -4
- package/expo-plugin/build/cjs/ios-widget/clientRendered.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/clientRenderedPrerender.js +5 -5
- package/expo-plugin/build/cjs/ios-widget/clientRenderedPrerender.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/dynamic-live-activity/swift.js +130 -0
- package/expo-plugin/build/cjs/ios-widget/dynamic-live-activity/swift.js.map +1 -0
- package/expo-plugin/build/cjs/ios-widget/files/index.js +9 -2
- package/expo-plugin/build/cjs/ios-widget/files/index.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/files/infoPlist.js +6 -3
- package/expo-plugin/build/cjs/ios-widget/files/infoPlist.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/files/manifest.js +24 -0
- package/expo-plugin/build/cjs/ios-widget/files/manifest.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/files/swift-utils.js +7 -0
- package/expo-plugin/build/cjs/ios-widget/files/swift-utils.js.map +1 -0
- package/expo-plugin/build/cjs/ios-widget/files/swift.js +56 -26
- package/expo-plugin/build/cjs/ios-widget/files/swift.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/index.js +9 -3
- package/expo-plugin/build/cjs/ios-widget/index.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/widgetPlist.js +34 -22
- package/expo-plugin/build/cjs/ios-widget/widgetPlist.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/xcode/buildPhases.js +51 -11
- package/expo-plugin/build/cjs/ios-widget/xcode/buildPhases.js.map +1 -1
- package/expo-plugin/build/cjs/ios-widget/xcode/index.js +21 -5
- package/expo-plugin/build/cjs/ios-widget/xcode/index.js.map +1 -1
- package/expo-plugin/build/cjs/utils/urlScheme.js +36 -14
- package/expo-plugin/build/cjs/utils/urlScheme.js.map +1 -1
- package/expo-plugin/build/cjs/validation.js +54 -0
- package/expo-plugin/build/cjs/validation.js.map +1 -1
- package/expo-plugin/build/esm/constants.js +17 -0
- package/expo-plugin/build/esm/constants.js.map +1 -1
- package/expo-plugin/build/esm/index.js +6 -0
- package/expo-plugin/build/esm/index.js.map +1 -1
- package/expo-plugin/build/esm/ios/index.js +1 -0
- package/expo-plugin/build/esm/ios/index.js.map +1 -1
- package/expo-plugin/build/esm/ios/infoPlist.js +28 -5
- package/expo-plugin/build/esm/ios/infoPlist.js.map +1 -1
- package/expo-plugin/build/esm/ios/serverUpdate.js +21 -0
- package/expo-plugin/build/esm/ios/serverUpdate.js.map +1 -0
- package/expo-plugin/build/esm/ios-widget/clientRendered.js +5 -5
- package/expo-plugin/build/esm/ios-widget/clientRendered.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/clientRenderedPrerender.js +6 -6
- package/expo-plugin/build/esm/ios-widget/clientRenderedPrerender.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/dynamic-live-activity/swift.js +122 -0
- package/expo-plugin/build/esm/ios-widget/dynamic-live-activity/swift.js.map +1 -0
- package/expo-plugin/build/esm/ios-widget/files/index.js +10 -3
- package/expo-plugin/build/esm/ios-widget/files/index.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/files/infoPlist.js +6 -3
- package/expo-plugin/build/esm/ios-widget/files/infoPlist.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/files/manifest.js +23 -1
- package/expo-plugin/build/esm/ios-widget/files/manifest.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/files/swift-utils.js +4 -0
- package/expo-plugin/build/esm/ios-widget/files/swift-utils.js.map +1 -0
- package/expo-plugin/build/esm/ios-widget/files/swift.js +50 -20
- package/expo-plugin/build/esm/ios-widget/files/swift.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/index.js +9 -3
- package/expo-plugin/build/esm/ios-widget/index.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/widgetPlist.js +34 -22
- package/expo-plugin/build/esm/ios-widget/widgetPlist.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/xcode/buildPhases.js +51 -11
- package/expo-plugin/build/esm/ios-widget/xcode/buildPhases.js.map +1 -1
- package/expo-plugin/build/esm/ios-widget/xcode/index.js +21 -5
- package/expo-plugin/build/esm/ios-widget/xcode/index.js.map +1 -1
- package/expo-plugin/build/esm/utils/urlScheme.js +34 -14
- package/expo-plugin/build/esm/utils/urlScheme.js.map +1 -1
- package/expo-plugin/build/esm/validation.js +54 -1
- package/expo-plugin/build/esm/validation.js.map +1 -1
- package/expo-plugin/build/types/constants.d.ts +10 -1
- package/expo-plugin/build/types/constants.d.ts.map +1 -1
- package/expo-plugin/build/types/index.d.ts +1 -1
- package/expo-plugin/build/types/index.d.ts.map +1 -1
- package/expo-plugin/build/types/ios/index.d.ts +2 -0
- package/expo-plugin/build/types/ios/index.d.ts.map +1 -1
- package/expo-plugin/build/types/ios/infoPlist.d.ts +2 -0
- package/expo-plugin/build/types/ios/infoPlist.d.ts.map +1 -1
- package/expo-plugin/build/types/ios/serverUpdate.d.ts +11 -0
- package/expo-plugin/build/types/ios/serverUpdate.d.ts.map +1 -0
- package/expo-plugin/build/types/ios-widget/clientRendered.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/clientRenderedPrerender.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/dynamic-live-activity/swift.d.ts +7 -0
- package/expo-plugin/build/types/ios-widget/dynamic-live-activity/swift.d.ts.map +1 -0
- package/expo-plugin/build/types/ios-widget/files/index.d.ts +3 -1
- package/expo-plugin/build/types/ios-widget/files/index.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/files/infoPlist.d.ts +2 -1
- package/expo-plugin/build/types/ios-widget/files/infoPlist.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/files/manifest.d.ts +9 -2
- package/expo-plugin/build/types/ios-widget/files/manifest.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/files/swift-utils.d.ts +2 -0
- package/expo-plugin/build/types/ios-widget/files/swift-utils.d.ts.map +1 -0
- package/expo-plugin/build/types/ios-widget/files/swift.d.ts +6 -2
- package/expo-plugin/build/types/ios-widget/files/swift.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/index.d.ts +3 -1
- package/expo-plugin/build/types/ios-widget/index.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/widgetPlist.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/xcode/buildPhases.d.ts +3 -1
- package/expo-plugin/build/types/ios-widget/xcode/buildPhases.d.ts.map +1 -1
- package/expo-plugin/build/types/ios-widget/xcode/index.d.ts +2 -1
- package/expo-plugin/build/types/ios-widget/xcode/index.d.ts.map +1 -1
- package/expo-plugin/build/types/types.d.ts +23 -4
- package/expo-plugin/build/types/types.d.ts.map +1 -1
- package/expo-plugin/build/types/utils/urlScheme.d.ts +16 -0
- package/expo-plugin/build/types/utils/urlScheme.d.ts.map +1 -1
- package/expo-plugin/build/types/validation.d.ts +2 -1
- package/expo-plugin/build/types/validation.d.ts.map +1 -1
- package/expo-plugin/src/constants.ts +24 -1
- package/expo-plugin/src/index.ts +9 -0
- package/expo-plugin/src/ios/index.ts +3 -0
- package/expo-plugin/src/ios/infoPlist.ts +33 -5
- package/expo-plugin/src/ios/serverUpdate.ts +29 -0
- package/expo-plugin/src/ios-widget/clientRendered.ts +9 -5
- package/expo-plugin/src/ios-widget/clientRenderedPrerender.ts +11 -6
- package/expo-plugin/src/ios-widget/dynamic-live-activity/swift.ts +138 -0
- package/expo-plugin/src/ios-widget/files/index.ts +15 -4
- package/expo-plugin/src/ios-widget/files/infoPlist.ts +17 -3
- package/expo-plugin/src/ios-widget/files/manifest.ts +42 -2
- package/expo-plugin/src/ios-widget/files/swift-utils.ts +3 -0
- package/expo-plugin/src/ios-widget/files/swift.ts +69 -22
- package/expo-plugin/src/ios-widget/index.ts +13 -3
- package/expo-plugin/src/ios-widget/widgetPlist.ts +37 -23
- package/expo-plugin/src/ios-widget/xcode/__snapshots__/applyXcodeChanges.node.test.ts.snap +34 -28
- package/expo-plugin/src/ios-widget/xcode/buildPhases.ts +59 -12
- package/expo-plugin/src/ios-widget/xcode/index.ts +23 -6
- package/expo-plugin/src/types.ts +28 -4
- package/expo-plugin/src/utils/urlScheme.ts +47 -17
- package/expo-plugin/src/validation.ts +76 -1
- package/ios/Package.swift +32 -3
- package/ios/VoltraWidget.podspec +1 -0
- package/ios/app/NativeVoltra.mm +107 -7
- package/ios/app/VoltraLiveActivityManager.swift +30 -0
- package/ios/app/VoltraLiveActivityService.swift +77 -5
- package/ios/app/VoltraModule.swift +99 -1
- package/ios/app/VoltraModuleImpl.swift +100 -2
- package/ios/app/VoltraViewComponentView.mm +3 -3
- package/ios/app/VoltraWidgetService.swift +147 -12
- package/ios/app/dynamic-live-activity/VoltraDynamicLiveActivityService.swift +97 -0
- package/ios/app/dynamic-live-activity/VoltraLiveActivityChronology.swift +68 -0
- package/ios/shared/DynamicWidgetPropsStore.swift +73 -6
- package/ios/shared/DynamicWidgetServerUpdate/DynamicWidgetServerFetchResolver.swift +34 -0
- package/ios/shared/DynamicWidgetServerUpdate/DynamicWidgetServerProps.swift +55 -0
- package/ios/shared/DynamicWidgetServerUpdate/DynamicWidgetServerPropsStore.swift +146 -0
- package/ios/shared/DynamicWidgetServerUpdate/DynamicWidgetServerUpdateRunner.swift +193 -0
- package/ios/shared/ServerWidgetContentResolver.swift +60 -0
- package/ios/shared/ServerWidgetResponseStore.swift +25 -0
- package/ios/shared/ShortNames.swift +6 -0
- package/ios/shared/VoltraConfig.swift +41 -0
- package/ios/shared/VoltraConstants.swift +15 -0
- package/ios/shared/VoltraElement.swift +127 -43
- package/ios/shared/VoltraEventBus.swift +52 -7
- package/ios/shared/VoltraJSRenderer.swift +90 -22
- package/ios/shared/VoltraNode.swift +1 -109
- package/ios/shared/VoltraRefreshIntent.swift +1 -1
- package/ios/shared/VoltraWidgetKind.swift +41 -0
- package/ios/shared/VoltraWidgetServerFetcher.swift +52 -107
- package/ios/shared/WidgetServer/VoltraWidgetAppearance.swift +17 -0
- package/ios/shared/WidgetServer/VoltraWidgetServer.swift +138 -0
- package/ios/shared/WidgetServer/WidgetCanonicalConfiguration.swift +77 -0
- package/ios/shared/WidgetServer/WidgetScope.swift +55 -0
- package/ios/shared/WidgetServer/WidgetServerEtagStore.swift +55 -0
- package/ios/shared/WidgetServer/WidgetServerFetcher.swift +179 -0
- package/ios/shared/WidgetServer/WidgetServerRequestBuilder.swift +114 -0
- package/ios/shared/WidgetServer/WidgetServerSettingsCodec.swift +47 -0
- package/ios/shared/WidgetServer/WidgetServerSettingsResolver.swift +129 -0
- package/ios/shared/WidgetServer/WidgetServerSettingsStore.swift +170 -0
- package/ios/shared/WidgetServer/WidgetServerSettingsValidator.swift +73 -0
- package/ios/shared/WidgetServer/WidgetServerUpdateSettings.swift +123 -0
- package/ios/shared/WidgetServer/WidgetServerUpdateSettingsJson.swift +115 -0
- package/ios/shared/dynamic-live-activity/DynamicLiveActivityPropsCodec.swift +13 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityBundleSource.swift +156 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityObserver.swift +97 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityOperations.swift +105 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityPayloadValidator.swift +55 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityRegistry.swift +143 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityRenderFailureQueue.swift +158 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityRenderFailureReporter.swift +120 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityRenderer.swift +370 -0
- package/ios/shared/dynamic-live-activity/VoltraDynamicLiveActivityTypes.swift +87 -0
- package/ios/shared/dynamic-live-activity/VoltraLiveActivityOrder.swift +19 -0
- package/ios/target/VoltraClientWidgetRuntime.swift +44 -6
- package/ios/target/VoltraDynamicWidgetServerUpdateProvider.swift +204 -0
- package/ios/target/VoltraHomeWidget.swift +85 -90
- package/ios/ui/Extensions/VoltraNode+View.swift +113 -0
- package/ios/ui/Generated/Parameters/ChartParameters.swift +3 -0
- package/ios/ui/Helpers/VoltraDeepLinkResolver.swift +2 -2
- package/ios/ui/Views/VoltraChart.swift +108 -0
- package/package.json +4 -4
- package/src/events.ts +34 -0
- package/src/index.ts +22 -0
- package/src/live-activity/api.ts +2 -2
- package/src/live-activity/dynamic-api.ts +240 -0
- package/src/native/NativeVoltra.ts +21 -0
- package/src/types.ts +4 -0
- package/src/utils/enableDynamicLiveActivityHotReload.ts +50 -0
- package/src/utils/enableWidgetHotReload.ts +9 -16
- package/src/utils/useUpdateOnHMR.ts +3 -12
- package/src/widgets/server-credentials.ts +8 -0
- package/src/widgets/server-update.ts +84 -0
- /package/ios/shared/{VoltraKeychainHelper.swift → WidgetServer/VoltraKeychainHelper.swift} +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { resolveWidgetServerUpdate } from '@use-voltra/expo-plugin';
|
|
2
|
+
/**
|
|
3
|
+
* iOS payload widgets have always defaulted to 15 minutes and accepted anything down to 1, since
|
|
4
|
+
* WidgetKit stretches a timeline it cannot honour rather than refusing it. A widget with an
|
|
5
|
+
* `entry` follows ADR 0002 instead: default 15, floor 15 on both platforms.
|
|
6
|
+
*/
|
|
7
|
+
export function iosServerUpdateRules(widget) {
|
|
8
|
+
return {
|
|
9
|
+
hasEntry: widget.entry !== undefined,
|
|
10
|
+
defaultIntervalMinutes: 15,
|
|
11
|
+
minimumIntervalMinutes: 1,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** `serverUpdate` with defaults applied, as the plist and Swift generators consume it. */
|
|
15
|
+
export function resolveIOSWidgetServerUpdate(widget) {
|
|
16
|
+
if (widget.serverUpdate === undefined) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return resolveWidgetServerUpdate(widget.serverUpdate, iosServerUpdateRules(widget));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=serverUpdate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverUpdate.js","sourceRoot":"","sources":["../../../src/ios/serverUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAMnE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAsC;IACzE,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,KAAK,KAAK,SAAS;QACpC,sBAAsB,EAAE,EAAE;QAC1B,sBAAsB,EAAE,CAAC;KAC1B,CAAA;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,4BAA4B,CAC1C,MAAuD;IAEvD,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,yBAAyB,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAA;AACrF,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import {
|
|
3
|
+
import { createPrerenderWidgetModuleLoader } from '@use-voltra/expo-plugin';
|
|
4
4
|
// Emit the experimental notice at most once per prebuild process (detection runs from several
|
|
5
5
|
// plugin steps).
|
|
6
6
|
let hasWarnedExperimental = false;
|
|
7
7
|
/** Inspect every widget once and tag entry-backed widgets as Dynamic Widgets. */
|
|
8
8
|
export function detectClientRenderedWidgets(widgets, projectRoot) {
|
|
9
|
-
const
|
|
9
|
+
const loader = createPrerenderWidgetModuleLoader(projectRoot, 'ios');
|
|
10
|
+
const detected = widgets.map((widget) => detectSingleWidget(widget, projectRoot, loader));
|
|
10
11
|
if (!hasWarnedExperimental) {
|
|
11
12
|
const clientWidgetIds = detected.filter((widget) => widget.clientRendered).map((widget) => widget.id);
|
|
12
13
|
if (clientWidgetIds.length > 0) {
|
|
@@ -18,7 +19,7 @@ export function detectClientRenderedWidgets(widgets, projectRoot) {
|
|
|
18
19
|
}
|
|
19
20
|
return detected;
|
|
20
21
|
}
|
|
21
|
-
function detectSingleWidget(widget, projectRoot) {
|
|
22
|
+
function detectSingleWidget(widget, projectRoot, loader) {
|
|
22
23
|
if (widget.entry === undefined) {
|
|
23
24
|
return {
|
|
24
25
|
...widget,
|
|
@@ -29,8 +30,7 @@ function detectSingleWidget(widget, projectRoot) {
|
|
|
29
30
|
if (!sourcePath || !fs.existsSync(sourcePath)) {
|
|
30
31
|
throw new Error(`[voltra] Dynamic Widget "${widget.id}" entry not found at ${path.relative(projectRoot, sourcePath ?? widget.entry)}`);
|
|
31
32
|
}
|
|
32
|
-
const
|
|
33
|
-
const widgetFn = widgetModule?.default ?? widgetModule;
|
|
33
|
+
const widgetFn = loader.loadDefaultExport(sourcePath);
|
|
34
34
|
if (typeof widgetFn !== 'function') {
|
|
35
35
|
throw new Error(`[voltra] Dynamic Widget "${widget.id}" at ${path.relative(projectRoot, sourcePath)} must default-export a function or component.`);
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientRendered.js","sourceRoot":"","sources":["../../../src/ios-widget/clientRendered.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"clientRendered.js","sourceRoot":"","sources":["../../../src/ios-widget/clientRendered.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,iCAAiC,EAA2B,MAAM,yBAAyB,CAAA;AAuBpG,8FAA8F;AAC9F,iBAAiB;AACjB,IAAI,qBAAqB,GAAG,KAAK,CAAA;AAEjC,iFAAiF;AACjF,MAAM,UAAU,2BAA2B,CAAC,OAA0B,EAAE,WAAmB;IACzF,MAAM,MAAM,GAAG,iCAAiC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;IAEzF,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACrG,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,qBAAqB,GAAG,IAAI,CAAA;YAC5B,OAAO,CAAC,IAAI,CACV,8CAA8C,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBAC3E,8FAA8F;gBAC9F,qFAAqF,CACxF,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,kBAAkB,CACzB,MAAuB,EACvB,WAAmB,EACnB,MAA0B;IAE1B,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO;YACL,GAAG,MAAM;YACT,cAAc,EAAE,KAAK;SACtB,CAAA;IACH,CAAC;IAED,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IACpE,IAAI,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,4BAA4B,MAAM,CAAC,EAAE,wBAAwB,IAAI,CAAC,QAAQ,CACxE,WAAW,EACX,UAAU,IAAI,MAAM,CAAC,KAAK,CAC3B,EAAE,CACJ,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;IACrD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,4BAA4B,MAAM,CAAC,EAAE,QAAQ,IAAI,CAAC,QAAQ,CACxD,WAAW,EACX,UAAU,CACX,+CAA+C,CACjD,CAAA;IACH,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,cAAc,EAAE,IAAI;QACpB,gBAAgB,EAAE,UAAU;KAC7B,CAAA;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa,EAAE,WAAmB;IAChE,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;AACzC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createPrerenderWidgetModuleLoader, logger, resolveInstalledPackageVersion, } from '@use-voltra/expo-plugin';
|
|
2
2
|
/**
|
|
3
3
|
* Initial-state prerender for Dynamic Widgets.
|
|
4
4
|
*
|
|
@@ -26,7 +26,7 @@ const SINGLE_LOCALE_KEY = '__default';
|
|
|
26
26
|
* mirror `WidgetEnvironment` from packages/core/src/widget-environment.ts so the widget
|
|
27
27
|
* function sees the same shape it gets at runtime.
|
|
28
28
|
*/
|
|
29
|
-
function buildPlaceholderEnv() {
|
|
29
|
+
function buildPlaceholderEnv(voltraVersion) {
|
|
30
30
|
return {
|
|
31
31
|
date: Date.now(),
|
|
32
32
|
widgetFamily: 'systemMedium',
|
|
@@ -39,7 +39,7 @@ function buildPlaceholderEnv() {
|
|
|
39
39
|
isDev: false,
|
|
40
40
|
metroUrl: null,
|
|
41
41
|
appVersion: 'unknown',
|
|
42
|
-
voltraVersion
|
|
42
|
+
voltraVersion,
|
|
43
43
|
},
|
|
44
44
|
};
|
|
45
45
|
}
|
|
@@ -59,11 +59,11 @@ export async function prerenderClientRenderedWidgets(widgets, projectRoot) {
|
|
|
59
59
|
// @use-voltra/android in a future phase.
|
|
60
60
|
const iosModuleId = '@use-voltra/ios';
|
|
61
61
|
const { renderVoltraVariantToJson } = (await import(iosModuleId));
|
|
62
|
-
const placeholderEnv = buildPlaceholderEnv();
|
|
62
|
+
const placeholderEnv = buildPlaceholderEnv(resolveInstalledPackageVersion(projectRoot, '@use-voltra/ios-client'));
|
|
63
|
+
const loader = createPrerenderWidgetModuleLoader(projectRoot, 'ios');
|
|
63
64
|
for (const widget of clientWidgets) {
|
|
64
65
|
try {
|
|
65
|
-
const
|
|
66
|
-
const widgetFn = widgetModule?.default ?? widgetModule;
|
|
66
|
+
const widgetFn = loader.loadDefaultExport(widget.clientSourcePath);
|
|
67
67
|
if (typeof widgetFn !== 'function') {
|
|
68
68
|
throw new Error(`Expected the entry module at ${widget.clientSourcePath} to default-export a function or component.`);
|
|
69
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientRenderedPrerender.js","sourceRoot":"","sources":["../../../src/ios-widget/clientRenderedPrerender.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"clientRenderedPrerender.js","sourceRoot":"","sources":["../../../src/ios-widget/clientRenderedPrerender.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,MAAM,EACN,8BAA8B,GAE/B,MAAM,yBAAyB,CAAA;AAIhC;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,4FAA4F;AAC5F,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAErC;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,aAAqB;IAChD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;QAChB,YAAY,EAAE,cAAc;QAC5B,WAAW,EAAE,OAAO;QACpB,MAAM,EAAE,OAAO;QACf,mBAAmB,EAAE,WAAW;QAChC,8BAA8B,EAAE,IAAI;QACpC,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE;YACL,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,SAAS;YACrB,aAAa;SACd;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,OAA4B,EAC5B,WAAmB;IAEnB,MAAM,OAAO,GAA4B,IAAI,GAAG,EAAE,CAAA;IAElD,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAClC,CAAC,CAAC,EAA6D,EAAE,CAAC,CAAC,CAAC,cAAc,CACnF,CAAA;IACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,kFAAkF;IAClF,kFAAkF;IAClF,yCAAyC;IACzC,MAAM,WAAW,GAAG,iBAAiB,CAAA;IACrC,MAAM,EAAE,yBAAyB,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,CAE/D,CAAA;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,8BAA8B,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAA;IACjH,MAAM,MAAM,GAAG,iCAAiC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAEpE,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;YAClE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,gCAAgC,MAAM,CAAC,gBAAgB,6CAA6C,CACrG,CAAA;YACH,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC,CAAA;YAC5C,MAAM,IAAI,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAA;YAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACvC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,uCAAuC,MAAM,CAAC,EAAE,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC/G,CAAA;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,eAAe,aAAa,CAAC,MAAM,gCAAgC,CAAC,CAAA;IAChF,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import dedent from 'dedent';
|
|
2
|
+
import { getDynamicLiveActivityAttributesType } from '@use-voltra/expo-plugin';
|
|
3
|
+
import { escapeForSwiftStringLiteral } from '../files/swift-utils';
|
|
4
|
+
export function generateDynamicLiveActivityWidgetInstances(liveActivities) {
|
|
5
|
+
return sortedDefinitions(liveActivities)
|
|
6
|
+
.map((liveActivity) => `VoltraDynamicLiveActivity_${getDynamicLiveActivityAttributesType(liveActivity.id)}()`)
|
|
7
|
+
.join('\n ');
|
|
8
|
+
}
|
|
9
|
+
/** Generates the Dynamic Live Activity types shared by the app and extension targets. */
|
|
10
|
+
export function generateDynamicLiveActivityTypesSwift(liveActivities) {
|
|
11
|
+
const definitions = sortedDefinitions(liveActivities);
|
|
12
|
+
const typeDefinitions = definitions.map(generateDynamicLiveActivitySwift).map(normalizeIndent).join('\n\n');
|
|
13
|
+
const header = dedent `
|
|
14
|
+
//
|
|
15
|
+
// VoltraDynamicLiveActivityTypes.swift
|
|
16
|
+
//
|
|
17
|
+
// Auto-generated by Voltra config plugin. Do not edit.
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
import ActivityKit
|
|
21
|
+
import Foundation
|
|
22
|
+
|
|
23
|
+
import VoltraRuntime
|
|
24
|
+
|
|
25
|
+
@objc(VoltraGeneratedDynamicLiveActivityRegistration)
|
|
26
|
+
public final class VoltraGeneratedDynamicLiveActivityRegistration: NSObject {
|
|
27
|
+
@objc public static func registerDefinitions() {
|
|
28
|
+
${definitions
|
|
29
|
+
.map((liveActivity) => ` VoltraDynamicLiveActivityRegistry.shared.register(${getDynamicLiveActivityAttributesType(liveActivity.id)}.self)`)
|
|
30
|
+
.join('\n')}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
`;
|
|
35
|
+
return [header.trim(), typeDefinitions.trim()].filter(Boolean).join('\n\n');
|
|
36
|
+
}
|
|
37
|
+
/** Generates extension-only ActivityConfiguration declarations for Dynamic Live Activities. */
|
|
38
|
+
export function generateDynamicLiveActivitiesSwift(liveActivities) {
|
|
39
|
+
const configurations = sortedDefinitions(liveActivities)
|
|
40
|
+
.map((liveActivity) => {
|
|
41
|
+
const attributesType = getDynamicLiveActivityAttributesType(liveActivity.id);
|
|
42
|
+
const definitionId = escapeForSwiftStringLiteral(liveActivity.id);
|
|
43
|
+
return dedent `
|
|
44
|
+
public struct VoltraDynamicLiveActivity_${attributesType}: Widget {
|
|
45
|
+
public init() {}
|
|
46
|
+
|
|
47
|
+
public var body: some WidgetConfiguration {
|
|
48
|
+
if #available(iOS 18.0, *) {
|
|
49
|
+
return adaptiveConfig()
|
|
50
|
+
} else {
|
|
51
|
+
return defaultConfig()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@available(iOS 18.0, *)
|
|
56
|
+
private func adaptiveConfig() -> some WidgetConfiguration {
|
|
57
|
+
ActivityConfiguration(for: ${attributesType}.self) { context in
|
|
58
|
+
VoltraDynamicLiveActivityRenderer.lockScreen(definitionId: "${definitionId}", context: context)
|
|
59
|
+
} dynamicIsland: { context in
|
|
60
|
+
VoltraDynamicLiveActivityRenderer.dynamicIsland(definitionId: "${definitionId}", context: context)
|
|
61
|
+
}
|
|
62
|
+
.supplementalActivityFamilies([.small, .medium])
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private func defaultConfig() -> some WidgetConfiguration {
|
|
66
|
+
ActivityConfiguration(for: ${attributesType}.self) { context in
|
|
67
|
+
VoltraDynamicLiveActivityRenderer.lockScreen(definitionId: "${definitionId}", context: context)
|
|
68
|
+
} dynamicIsland: { context in
|
|
69
|
+
VoltraDynamicLiveActivityRenderer.dynamicIsland(definitionId: "${definitionId}", context: context)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
})
|
|
75
|
+
.map(normalizeIndent)
|
|
76
|
+
.join('\n\n');
|
|
77
|
+
const header = dedent `
|
|
78
|
+
//
|
|
79
|
+
// VoltraDynamicLiveActivities.swift
|
|
80
|
+
//
|
|
81
|
+
// Auto-generated by Voltra config plugin. Do not edit.
|
|
82
|
+
//
|
|
83
|
+
|
|
84
|
+
import ActivityKit
|
|
85
|
+
import SwiftUI
|
|
86
|
+
import WidgetKit
|
|
87
|
+
import VoltraRuntime
|
|
88
|
+
|
|
89
|
+
`;
|
|
90
|
+
return [header.trim(), configurations.trim()].filter(Boolean).join('\n\n');
|
|
91
|
+
}
|
|
92
|
+
function generateDynamicLiveActivitySwift(liveActivity) {
|
|
93
|
+
const attributesType = getDynamicLiveActivityAttributesType(liveActivity.id);
|
|
94
|
+
const definitionId = escapeForSwiftStringLiteral(liveActivity.id);
|
|
95
|
+
return dedent `
|
|
96
|
+
public struct ${attributesType}: ActivityAttributes {
|
|
97
|
+
public typealias ContentState = VoltraDynamicLiveActivityContentState
|
|
98
|
+
|
|
99
|
+
public let name: String
|
|
100
|
+
public let deepLinkUrl: String?
|
|
101
|
+
|
|
102
|
+
public init(name: String, deepLinkUrl: String?) {
|
|
103
|
+
self.name = name
|
|
104
|
+
self.deepLinkUrl = deepLinkUrl
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
extension ${attributesType}: VoltraDynamicLiveActivityDefinition {
|
|
109
|
+
public static let definitionId = "${definitionId}"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
function sortedDefinitions(liveActivities) {
|
|
115
|
+
return [...liveActivities].sort((left, right) => left.id.localeCompare(right.id));
|
|
116
|
+
}
|
|
117
|
+
function normalizeIndent(source) {
|
|
118
|
+
const lines = source.trim().split('\n');
|
|
119
|
+
const indent = Math.min(...lines.filter(Boolean).map((line) => line.match(/^\s*/)?.[0].length ?? 0));
|
|
120
|
+
return lines.map((line) => line.slice(indent)).join('\n');
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=swift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swift.js","sourceRoot":"","sources":["../../../../src/ios-widget/dynamic-live-activity/swift.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import * as path from 'path';
|
|
|
4
4
|
import { generateAssets } from './assets';
|
|
5
5
|
import { generateEntitlements } from './entitlements';
|
|
6
6
|
import { generateInfoPlist } from './infoPlist';
|
|
7
|
-
import { generateIOSDynamicWidgetsManifest } from './manifest';
|
|
7
|
+
import { generateIOSDynamicLiveActivitiesManifest, generateIOSDynamicWidgetsManifest } from './manifest';
|
|
8
8
|
import { generateSwiftFiles } from './swift';
|
|
9
9
|
/**
|
|
10
10
|
* Plugin step that generates all widget extension files.
|
|
@@ -19,7 +19,7 @@ import { generateSwiftFiles } from './swift';
|
|
|
19
19
|
* This should run before configureXcodeProject so the files exist when Xcode project is configured.
|
|
20
20
|
*/
|
|
21
21
|
export const generateWidgetExtensionFiles = (config, props) => {
|
|
22
|
-
const { targetName, widgets, groupIdentifier, keychainGroup, version, buildNumber } = props;
|
|
22
|
+
const { targetName, widgets, liveActivities, groupIdentifier, keychainGroup, version, buildNumber, voltraVersion } = props;
|
|
23
23
|
return withDangerousMod(config, [
|
|
24
24
|
'ios',
|
|
25
25
|
async (config) => {
|
|
@@ -33,7 +33,7 @@ export const generateWidgetExtensionFiles = (config, props) => {
|
|
|
33
33
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
34
34
|
}
|
|
35
35
|
// Generate Info.plist
|
|
36
|
-
generateInfoPlist(targetPath, targetName, version, buildNumber);
|
|
36
|
+
generateInfoPlist(targetPath, targetName, version, buildNumber, voltraVersion);
|
|
37
37
|
// Generate Assets.xcassets and copy user images
|
|
38
38
|
generateAssets({ targetPath });
|
|
39
39
|
// Generate Swift files (widget bundle, initial states)
|
|
@@ -41,12 +41,19 @@ export const generateWidgetExtensionFiles = (config, props) => {
|
|
|
41
41
|
targetPath,
|
|
42
42
|
projectRoot,
|
|
43
43
|
widgets,
|
|
44
|
+
liveActivities,
|
|
44
45
|
});
|
|
45
46
|
// Write the iOS-owned Dynamic Widgets manifest for Metro to consume later.
|
|
46
47
|
generateIOSDynamicWidgetsManifest({
|
|
47
48
|
projectRoot,
|
|
48
49
|
widgets,
|
|
49
50
|
});
|
|
51
|
+
// Dynamic Live Activities have their own Metro manifest so their IDs may overlap with
|
|
52
|
+
// Dynamic Widgets and stale declarations never leak into a later prebuild.
|
|
53
|
+
generateIOSDynamicLiveActivitiesManifest({
|
|
54
|
+
projectRoot,
|
|
55
|
+
liveActivities,
|
|
56
|
+
});
|
|
50
57
|
// Generate entitlements file (may be empty if no groupIdentifier or keychainGroup)
|
|
51
58
|
generateEntitlements({
|
|
52
59
|
targetPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAG5B,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAG5B,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,wCAAwC,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAA;AACxG,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAa5C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAoD,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IAC7G,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,GAChH,KAAK,CAAA;IAEP,OAAO,gBAAgB,CAAC,MAAM,EAAE;QAC9B,KAAK;QACL,KAAK,EAAE,MAAM,EAAE,EAAE;YACf,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;gBACjC,OAAO,MAAM,CAAA;YACf,CAAC;YAED,MAAM,EAAE,mBAAmB,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,UAAU,CAAA;YAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAA;YAE7D,iCAAiC;YACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC/C,CAAC;YAED,sBAAsB;YACtB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;YAE9E,gDAAgD;YAChD,cAAc,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;YAE9B,uDAAuD;YACvD,MAAM,kBAAkB,CAAC;gBACvB,UAAU;gBACV,WAAW;gBACX,OAAO;gBACP,cAAc;aACf,CAAC,CAAA;YAEF,2EAA2E;YAC3E,iCAAiC,CAAC;gBAChC,WAAW;gBACX,OAAO;aACR,CAAC,CAAA;YAEF,sFAAsF;YACtF,2EAA2E;YAC3E,wCAAwC,CAAC;gBACvC,WAAW;gBACX,cAAc;aACf,CAAC,CAAA;YAEF,mFAAmF;YACnF,oBAAoB,CAAC;gBACnB,UAAU;gBACV,UAAU;gBACV,eAAe;gBACf,aAAa;aACd,CAAC,CAAA;YAEF,OAAO,MAAM,CAAA;QACf,CAAC;KACF,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -7,7 +7,7 @@ import { logger } from '@use-voltra/expo-plugin';
|
|
|
7
7
|
* This includes version information and the required WidgetKit extension point.
|
|
8
8
|
* Version keys are written directly to the plist following the Expo pattern.
|
|
9
9
|
*/
|
|
10
|
-
function generateInfoPlistContent(targetName, version, buildNumber) {
|
|
10
|
+
function generateInfoPlistContent(targetName, version, buildNumber, voltraVersion) {
|
|
11
11
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
12
12
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
13
13
|
<plist version="1.0">
|
|
@@ -30,6 +30,8 @@ function generateInfoPlistContent(targetName, version, buildNumber) {
|
|
|
30
30
|
<string>${version}</string>
|
|
31
31
|
<key>CFBundleVersion</key>
|
|
32
32
|
<string>${buildNumber}</string>
|
|
33
|
+
<key>Voltra_Version</key>
|
|
34
|
+
<string>${voltraVersion}</string>
|
|
33
35
|
<key>NSExtension</key>
|
|
34
36
|
<dict>
|
|
35
37
|
<key>NSExtensionPointIdentifier</key>
|
|
@@ -46,10 +48,11 @@ function generateInfoPlistContent(targetName, version, buildNumber) {
|
|
|
46
48
|
* @param targetName - The widget extension target name (used for CFBundleDisplayName)
|
|
47
49
|
* @param version - The app version (CFBundleShortVersionString)
|
|
48
50
|
* @param buildNumber - The build number (CFBundleVersion)
|
|
51
|
+
* @param voltraVersion - The installed @use-voltra/ios-client package version
|
|
49
52
|
*/
|
|
50
|
-
export function generateInfoPlist(targetPath, targetName, version, buildNumber) {
|
|
53
|
+
export function generateInfoPlist(targetPath, targetName, version, buildNumber, voltraVersion) {
|
|
51
54
|
const infoPlistPath = path.join(targetPath, 'Info.plist');
|
|
52
|
-
fs.writeFileSync(infoPlistPath, generateInfoPlistContent(targetName, version, buildNumber));
|
|
55
|
+
fs.writeFileSync(infoPlistPath, generateInfoPlistContent(targetName, version, buildNumber, voltraVersion));
|
|
53
56
|
logger.info('Generated Info.plist');
|
|
54
57
|
}
|
|
55
58
|
//# sourceMappingURL=infoPlist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infoPlist.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/infoPlist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD;;;;;GAKG;AACH,SAAS,wBAAwB,
|
|
1
|
+
{"version":3,"file":"infoPlist.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/infoPlist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD;;;;;GAKG;AACH,SAAS,wBAAwB,CAC/B,UAAkB,EAClB,OAAe,EACf,WAAmB,EACnB,aAAqB;IAErB,OAAO;;;;;;;WAOE,UAAU;;;;;;;;;;;;WAYV,OAAO;;WAEP,WAAW;;WAEX,aAAa;;;;;;;;CAQvB,CAAA;AACD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,UAAkB,EAClB,OAAe,EACf,WAAmB,EACnB,aAAqB;IAErB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACzD,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAA;IAC1G,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;AACrC,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import { logger, validateWidgetEntry } from '@use-voltra/expo-plugin';
|
|
3
|
+
import { logger, validateWidgetEntry, } from '@use-voltra/expo-plugin';
|
|
4
4
|
const MANIFEST_PATH = path.join('.voltra', 'manifest.ios.json');
|
|
5
|
+
const LIVE_ACTIVITIES_MANIFEST_PATH = path.join('.voltra', 'manifest.ios.live-activities.json');
|
|
5
6
|
export function createIOSDynamicWidgetsManifest(projectRoot, widgets) {
|
|
6
7
|
const manifestWidgets = [];
|
|
7
8
|
for (const widget of widgets) {
|
|
@@ -19,6 +20,18 @@ export function createIOSDynamicWidgetsManifest(projectRoot, widgets) {
|
|
|
19
20
|
widgets: manifestWidgets,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
23
|
+
export function createIOSDynamicLiveActivitiesManifest(projectRoot, liveActivities) {
|
|
24
|
+
return {
|
|
25
|
+
version: 1,
|
|
26
|
+
platform: 'ios',
|
|
27
|
+
liveActivities: [...liveActivities]
|
|
28
|
+
.sort((left, right) => left.id.localeCompare(right.id))
|
|
29
|
+
.map((liveActivity) => ({
|
|
30
|
+
id: liveActivity.id,
|
|
31
|
+
entry: validateWidgetEntry(liveActivity.entry, liveActivity.id, projectRoot),
|
|
32
|
+
})),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
22
35
|
export function generateIOSDynamicWidgetsManifest(options) {
|
|
23
36
|
const { projectRoot, widgets } = options;
|
|
24
37
|
const manifestPath = path.join(projectRoot, MANIFEST_PATH);
|
|
@@ -27,4 +40,13 @@ export function generateIOSDynamicWidgetsManifest(options) {
|
|
|
27
40
|
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
28
41
|
logger.info(`Generated ${MANIFEST_PATH}`);
|
|
29
42
|
}
|
|
43
|
+
/** Writes the dedicated Dynamic Live Activity manifest on every prebuild, including when empty. */
|
|
44
|
+
export function generateIOSDynamicLiveActivitiesManifest(options) {
|
|
45
|
+
const { projectRoot, liveActivities } = options;
|
|
46
|
+
const manifestPath = path.join(projectRoot, LIVE_ACTIVITIES_MANIFEST_PATH);
|
|
47
|
+
const manifest = createIOSDynamicLiveActivitiesManifest(projectRoot, liveActivities ?? []);
|
|
48
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
49
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
50
|
+
logger.info(`Generated ${LIVE_ACTIVITIES_MANIFEST_PATH}`);
|
|
51
|
+
}
|
|
30
52
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swift-utils.js","sourceRoot":"","sources":["../../../../src/ios-widget/files/swift-utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACtG,CAAC"}
|
|
@@ -2,10 +2,12 @@ import dedent from 'dedent';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { isWidgetLocalizedMap, logger, prerenderWidgetState, widgetLabelEnglish, } from '@use-voltra/expo-plugin';
|
|
5
|
-
import { DEFAULT_WIDGET_FAMILIES, WIDGET_FAMILY_MAP } from '../../constants';
|
|
5
|
+
import { DEFAULT_WIDGET_FAMILIES, WIDGET_FAMILY_MAP, widgetKind } from '../../constants';
|
|
6
6
|
import { VOLTRA_WIDGET_STRINGS_BASENAME } from '../../utils/fileDiscovery';
|
|
7
7
|
import { detectClientRenderedWidgets } from '../clientRendered';
|
|
8
8
|
import { prerenderClientRenderedWidgets } from '../clientRenderedPrerender';
|
|
9
|
+
import { generateDynamicLiveActivitiesSwift, generateDynamicLiveActivityTypesSwift, generateDynamicLiveActivityWidgetInstances, } from '../dynamic-live-activity/swift';
|
|
10
|
+
import { escapeForSwiftStringLiteral } from './swift-utils';
|
|
9
11
|
// ============================================================================
|
|
10
12
|
// Main Function
|
|
11
13
|
// ============================================================================
|
|
@@ -17,7 +19,7 @@ import { prerenderClientRenderedWidgets } from '../clientRenderedPrerender';
|
|
|
17
19
|
* - VoltraWidgetBundle.swift (widget bundle definition)
|
|
18
20
|
*/
|
|
19
21
|
export async function generateSwiftFiles(options) {
|
|
20
|
-
const { targetPath, projectRoot, widgets } = options;
|
|
22
|
+
const { targetPath, projectRoot, widgets, liveActivities } = options;
|
|
21
23
|
// Dynamic import keeps the plugin CommonJS-compatible while resolving the current package entry.
|
|
22
24
|
const serverModuleId = '@use-voltra/ios/server';
|
|
23
25
|
const { renderWidgetToString } = (await import(serverModuleId));
|
|
@@ -34,7 +36,7 @@ export async function generateSwiftFiles(options) {
|
|
|
34
36
|
// stringify). Both produce entries in the same map shape so
|
|
35
37
|
// VoltraWidgetInitialStates.swift can read either via the same lookup at runtime.
|
|
36
38
|
const serverWidgets = detectedWidgets.filter((w) => !w.clientRendered);
|
|
37
|
-
const serverStates = await prerenderWidgetState(serverWidgets, projectRoot, renderWidgetToString);
|
|
39
|
+
const serverStates = await prerenderWidgetState(serverWidgets, projectRoot, renderWidgetToString, 'ios');
|
|
38
40
|
const clientStates = await prerenderClientRenderedWidgets(detectedWidgets, projectRoot);
|
|
39
41
|
const prerenderedStates = new Map([...serverStates, ...clientStates]);
|
|
40
42
|
syncVoltraWidgetGalleryStrings(targetPath, widgets);
|
|
@@ -44,10 +46,15 @@ export async function generateSwiftFiles(options) {
|
|
|
44
46
|
fs.writeFileSync(initialStatesPath, initialStatesContent);
|
|
45
47
|
logger.info(`Generated VoltraWidgetInitialStates.swift with ${prerenderedStates.size} widget(s) (localized initial states where configured)`);
|
|
46
48
|
// Generate the widget bundle Swift file
|
|
47
|
-
const widgetBundleContent = detectedWidgets.length > 0
|
|
49
|
+
const widgetBundleContent = detectedWidgets.length > 0 || (liveActivities?.length ?? 0) > 0
|
|
50
|
+
? generateWidgetBundleSwift(detectedWidgets, liveActivities ?? [])
|
|
51
|
+
: generateDefaultWidgetBundleSwift();
|
|
48
52
|
const widgetBundlePath = path.join(targetPath, 'VoltraWidgetBundle.swift');
|
|
49
53
|
fs.writeFileSync(widgetBundlePath, widgetBundleContent);
|
|
50
54
|
logger.info(`Generated VoltraWidgetBundle.swift with ${widgets?.length ?? 0} home screen widgets`);
|
|
55
|
+
fs.writeFileSync(path.join(targetPath, 'VoltraDynamicLiveActivityTypes.swift'), generateDynamicLiveActivityTypesSwift(liveActivities ?? []));
|
|
56
|
+
fs.writeFileSync(path.join(targetPath, 'VoltraDynamicLiveActivities.swift'), generateDynamicLiveActivitiesSwift(liveActivities ?? []));
|
|
57
|
+
logger.info(`Generated Dynamic Live Activity Swift scaffolding with ${liveActivities?.length ?? 0} definition(s)`);
|
|
51
58
|
}
|
|
52
59
|
const GENERATED_INITIAL_STATE_LOCALE_HELPER = dedent `
|
|
53
60
|
private enum VoltraGeneratedInitialStateLocale {
|
|
@@ -118,9 +125,6 @@ const GENERATED_INITIAL_STATE_LOCALE_HELPER = dedent `
|
|
|
118
125
|
// LocalizedStringResource is still appropriate for extensions (deferred resolution).
|
|
119
126
|
// https://developer.apple.com/documentation/foundation/localizedstringresource
|
|
120
127
|
// ============================================================================
|
|
121
|
-
function escapeForSwiftStringLiteral(s) {
|
|
122
|
-
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
|
|
123
|
-
}
|
|
124
128
|
function escapeDotStringsValue(s) {
|
|
125
129
|
return escapeForSwiftStringLiteral(s);
|
|
126
130
|
}
|
|
@@ -227,6 +231,12 @@ function iosWidgetGalleryLabelSwiftExpr(widgetId, field, label) {
|
|
|
227
231
|
* - Dynamic Widget → `VoltraClientWidgetProvider` + `VoltraClientWidgetContentView`
|
|
228
232
|
* (the content view internally renders via VoltraHomeWidgetView so the UI layer is
|
|
229
233
|
* identical to the fallback state path — see VoltraClientWidgetRuntime.swift)
|
|
234
|
+
* - Dynamic Widget with a `serverUpdate` → `VoltraDynamicWidgetServerUpdateProvider`, which wraps
|
|
235
|
+
* the one above and adds the fetch, the commit and the schedule
|
|
236
|
+
*
|
|
237
|
+
* `entry` picks the render engine and `serverUpdate` picks where the data comes from, so the two
|
|
238
|
+
* keys together select one of four providers. Runtime code never asks "is this server-driven?" —
|
|
239
|
+
* the answer is baked in here, once, at generate time.
|
|
230
240
|
*/
|
|
231
241
|
function widgetUsesAppIntent(widget) {
|
|
232
242
|
return widget.clientRendered && !!widget.appIntent && widget.appIntent.parameters.length > 0;
|
|
@@ -243,9 +253,12 @@ function generateWidgetStruct(widget) {
|
|
|
243
253
|
const structName = `VoltraWidget_${widget.id}`;
|
|
244
254
|
const displayNameExpr = iosWidgetGalleryLabelSwiftExpr(widget.id, 'displayName', widget.displayName);
|
|
245
255
|
const descriptionExpr = iosWidgetGalleryLabelSwiftExpr(widget.id, 'description', widget.description);
|
|
256
|
+
const clientProviderName = widget.serverUpdate
|
|
257
|
+
? 'VoltraDynamicWidgetServerUpdateProvider'
|
|
258
|
+
: 'VoltraClientWidgetProvider';
|
|
246
259
|
const providerAndContent = widget.clientRendered
|
|
247
260
|
? dedent `
|
|
248
|
-
provider:
|
|
261
|
+
provider: ${clientProviderName}(
|
|
249
262
|
widgetId: widgetId,
|
|
250
263
|
initialState: VoltraWidgetInitialStates.getInitialState(for: widgetId)
|
|
251
264
|
)
|
|
@@ -271,7 +284,7 @@ function generateWidgetStruct(widget) {
|
|
|
271
284
|
|
|
272
285
|
public var body: some WidgetConfiguration {
|
|
273
286
|
StaticConfiguration(
|
|
274
|
-
kind: "
|
|
287
|
+
kind: "${widgetKind(widget)}",
|
|
275
288
|
${providerAndContent}
|
|
276
289
|
.configurationDisplayName(${displayNameExpr})
|
|
277
290
|
.description(${descriptionExpr})
|
|
@@ -305,6 +318,18 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
305
318
|
const initBody = params.map((p) => ` self.${p.name} = ${p.name}`).join('\n');
|
|
306
319
|
const configuredDict = dictLiteral(params.map((p) => `"${p.name}": configuration.${p.name}`));
|
|
307
320
|
const defaultDict = dictLiteral(params.map((p) => `"${p.name}": ${swiftDefault(p)}`));
|
|
321
|
+
// A server-driven Dynamic Widget fetches on every timeline request and schedules the next one
|
|
322
|
+
// from its resolved interval; a plain one has nothing to ask again for, so its policy is .never.
|
|
323
|
+
const appIntentTimelineBody = widget.serverUpdate
|
|
324
|
+
? dedent `
|
|
325
|
+
return await VoltraDynamicWidgetServerUpdateProvider.timeline(
|
|
326
|
+
widgetId: widgetId,
|
|
327
|
+
family: context.family,
|
|
328
|
+
configuration: ${configuredDict}
|
|
329
|
+
)`
|
|
330
|
+
: dedent `
|
|
331
|
+
let entry = await VoltraClientWidgetProvider.loadEntry(widgetId: widgetId, configuration: ${configuredDict})
|
|
332
|
+
return Timeline(entries: [entry], policy: .never)`;
|
|
308
333
|
return dedent `
|
|
309
334
|
// MARK: - Client-rendered AppIntent widget: ${widget.id}
|
|
310
335
|
|
|
@@ -335,9 +360,8 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
335
360
|
await VoltraClientWidgetProvider.loadEntry(widgetId: widgetId, configuration: ${configuredDict})
|
|
336
361
|
}
|
|
337
362
|
|
|
338
|
-
func timeline(for configuration: ${intentName}, in
|
|
339
|
-
|
|
340
|
-
return Timeline(entries: [entry], policy: .never)
|
|
363
|
+
func timeline(for configuration: ${intentName}, in context: Context) async -> Timeline<VoltraClientWidgetEntry> {
|
|
364
|
+
${appIntentTimelineBody}
|
|
341
365
|
}
|
|
342
366
|
}
|
|
343
367
|
|
|
@@ -349,7 +373,7 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
349
373
|
|
|
350
374
|
public var body: some WidgetConfiguration {
|
|
351
375
|
AppIntentConfiguration(
|
|
352
|
-
kind: "
|
|
376
|
+
kind: "${widgetKind(widget)}",
|
|
353
377
|
intent: ${intentName}.self,
|
|
354
378
|
provider: ${providerName}()
|
|
355
379
|
) { entry in
|
|
@@ -369,7 +393,7 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
369
393
|
/**
|
|
370
394
|
* Generates the VoltraWidgetBundle.swift file content with configured widgets
|
|
371
395
|
*/
|
|
372
|
-
function generateWidgetBundleSwift(widgets) {
|
|
396
|
+
function generateWidgetBundleSwift(widgets, liveActivities = []) {
|
|
373
397
|
// Generate widget structs
|
|
374
398
|
const widgetStructs = widgets.map((w) => generateWidgetStruct(w)).join('\n\n');
|
|
375
399
|
// AppIntent widgets are iOS 17+, so their bundle entries are gated behind #available.
|
|
@@ -381,7 +405,11 @@ function generateWidgetBundleSwift(widgets) {
|
|
|
381
405
|
.map((w) => `VoltraWidget_${w.id}()`)
|
|
382
406
|
.join('\n ')}\n }`
|
|
383
407
|
: '';
|
|
384
|
-
const
|
|
408
|
+
const dynamicLiveActivityInstances = generateDynamicLiveActivityWidgetInstances(liveActivities);
|
|
409
|
+
const widgetInstances = [plainInstances, appIntentInstances, dynamicLiveActivityInstances]
|
|
410
|
+
.filter(Boolean)
|
|
411
|
+
.join('\n ');
|
|
412
|
+
const widgetSectionTitle = liveActivities.length > 0 ? 'Home Screen Widgets and Dynamic Live Activities' : 'Home Screen Widgets';
|
|
385
413
|
const needsFoundation = widgets.some(widgetUsesGalleryLocalization);
|
|
386
414
|
const foundationImport = needsFoundation ? 'import Foundation\n' : '';
|
|
387
415
|
const appIntentsImport = appIntentWidgets.length > 0 ? 'import AppIntents\n' : '';
|
|
@@ -395,7 +423,7 @@ function generateWidgetBundleSwift(widgets) {
|
|
|
395
423
|
|
|
396
424
|
${foundationImport}${appIntentsImport}import SwiftUI
|
|
397
425
|
import WidgetKit
|
|
398
|
-
import
|
|
426
|
+
import VoltraRuntime
|
|
399
427
|
|
|
400
428
|
@main
|
|
401
429
|
struct VoltraWidgetBundle: WidgetBundle {
|
|
@@ -403,7 +431,7 @@ function generateWidgetBundleSwift(widgets) {
|
|
|
403
431
|
// Live Activity (with Watch/CarPlay support)
|
|
404
432
|
VoltraWidget()
|
|
405
433
|
|
|
406
|
-
//
|
|
434
|
+
// ${widgetSectionTitle}
|
|
407
435
|
${widgetInstances}
|
|
408
436
|
}
|
|
409
437
|
}
|
|
@@ -414,8 +442,8 @@ function generateWidgetBundleSwift(widgets) {
|
|
|
414
442
|
`;
|
|
415
443
|
}
|
|
416
444
|
/**
|
|
417
|
-
* Generates the VoltraWidgetBundle.swift file content when no widgets
|
|
418
|
-
*
|
|
445
|
+
* Generates the VoltraWidgetBundle.swift file content when no Home Screen widgets or Dynamic
|
|
446
|
+
* Live Activities are configured. Keep this legacy output stable for existing projects.
|
|
419
447
|
*/
|
|
420
448
|
function generateDefaultWidgetBundleSwift() {
|
|
421
449
|
return dedent `
|
|
@@ -428,7 +456,7 @@ function generateDefaultWidgetBundleSwift() {
|
|
|
428
456
|
|
|
429
457
|
import SwiftUI
|
|
430
458
|
import WidgetKit
|
|
431
|
-
import
|
|
459
|
+
import VoltraRuntime // Import Voltra widgets
|
|
432
460
|
|
|
433
461
|
@main
|
|
434
462
|
struct VoltraWidgetBundle: WidgetBundle {
|
|
@@ -536,5 +564,7 @@ function getSwiftRawStringDelimiter(str) {
|
|
|
536
564
|
export const __test__ = {
|
|
537
565
|
generateInitialStatesSwift,
|
|
538
566
|
generateWidgetBundleSwift,
|
|
567
|
+
generateDynamicLiveActivityTypesSwift,
|
|
568
|
+
generateDynamicLiveActivitiesSwift,
|
|
539
569
|
};
|
|
540
570
|
//# sourceMappingURL=swift.js.map
|