voltra 1.0.1 → 1.1.1
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 +17 -13
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +84 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/voltra/VoltraModule.kt +296 -0
- package/android/src/main/java/voltra/VoltraNotificationManager.kt +157 -0
- package/android/src/main/java/voltra/VoltraRN.kt +206 -0
- package/android/src/main/java/voltra/events/VoltraEvent.kt +25 -0
- package/android/src/main/java/voltra/events/VoltraEventBus.kt +198 -0
- package/android/src/main/java/voltra/generated/ShortNames.kt +167 -0
- package/android/src/main/java/voltra/glance/GlanceFactory.kt +20 -0
- package/android/src/main/java/voltra/glance/RemoteViewsGenerator.kt +121 -0
- package/android/src/main/java/voltra/glance/StyleUtils.kt +126 -0
- package/android/src/main/java/voltra/glance/VoltraRenderContext.kt +15 -0
- package/android/src/main/java/voltra/glance/renderers/ButtonRenderers.kt +219 -0
- package/android/src/main/java/voltra/glance/renderers/ComplexRenderers.kt +189 -0
- package/android/src/main/java/voltra/glance/renderers/InputRenderers.kt +180 -0
- package/android/src/main/java/voltra/glance/renderers/LayoutRenderers.kt +259 -0
- package/android/src/main/java/voltra/glance/renderers/LazyListRenderers.kt +149 -0
- package/android/src/main/java/voltra/glance/renderers/ProgressRenderers.kt +109 -0
- package/android/src/main/java/voltra/glance/renderers/RenderCommon.kt +221 -0
- package/android/src/main/java/voltra/glance/renderers/TextAndImageRenderers.kt +114 -0
- package/android/src/main/java/voltra/images/VoltraImageManager.kt +123 -0
- package/android/src/main/java/voltra/models/VoltraPayload.kt +53 -0
- package/android/src/main/java/voltra/models/parameters/AndroidBoxParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidButtonParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidCheckBoxParameters.kt +24 -0
- package/android/src/main/java/voltra/models/parameters/AndroidCircleIconButtonParameters.kt +28 -0
- package/android/src/main/java/voltra/models/parameters/AndroidCircularProgressIndicatorParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidColumnParameters.kt +22 -0
- package/android/src/main/java/voltra/models/parameters/AndroidFilledButtonParameters.kt +30 -0
- package/android/src/main/java/voltra/models/parameters/AndroidImageParameters.kt +22 -0
- package/android/src/main/java/voltra/models/parameters/AndroidLazyColumnParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidLazyVerticalGridParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidLinearProgressIndicatorParameters.kt +22 -0
- package/android/src/main/java/voltra/models/parameters/AndroidOutlineButtonParameters.kt +28 -0
- package/android/src/main/java/voltra/models/parameters/AndroidRadioButtonParameters.kt +24 -0
- package/android/src/main/java/voltra/models/parameters/AndroidRowParameters.kt +22 -0
- package/android/src/main/java/voltra/models/parameters/AndroidScaffoldParameters.kt +22 -0
- package/android/src/main/java/voltra/models/parameters/AndroidSpacerParameters.kt +20 -0
- package/android/src/main/java/voltra/models/parameters/AndroidSquareIconButtonParameters.kt +28 -0
- package/android/src/main/java/voltra/models/parameters/AndroidSwitchParameters.kt +24 -0
- package/android/src/main/java/voltra/models/parameters/AndroidTextParameters.kt +26 -0
- package/android/src/main/java/voltra/models/parameters/AndroidTitleBarParameters.kt +24 -0
- package/android/src/main/java/voltra/parsing/VoltraDecompressor.kt +56 -0
- package/android/src/main/java/voltra/parsing/VoltraNodeDeserializer.kt +43 -0
- package/android/src/main/java/voltra/parsing/VoltraPayloadParser.kt +32 -0
- package/android/src/main/java/voltra/payload/ComponentTypeID.kt +63 -0
- package/android/src/main/java/voltra/styling/JSColorParser.kt +255 -0
- package/android/src/main/java/voltra/styling/JSStyleParser.kt +338 -0
- package/android/src/main/java/voltra/styling/StyleConverter.kt +255 -0
- package/android/src/main/java/voltra/styling/StyleModifiers.kt +312 -0
- package/android/src/main/java/voltra/styling/StyleStructures.kt +207 -0
- package/android/src/main/java/voltra/widget/VoltraGlanceWidget.kt +171 -0
- package/android/src/main/java/voltra/widget/VoltraWidgetManager.kt +314 -0
- package/android/src/main/java/voltra/widget/VoltraWidgetReceiver.kt +28 -0
- package/android/src/main/res/xml/voltra_file_paths.xml +4 -0
- package/build/VoltraModule.d.ts +60 -0
- package/build/VoltraModule.d.ts.map +1 -1
- package/build/VoltraModule.js.map +1 -1
- package/build/android/client.d.ts +8 -0
- package/build/android/client.d.ts.map +1 -0
- package/build/android/client.js +10 -0
- package/build/android/client.js.map +1 -0
- package/build/android/components/VoltraView.d.ts +29 -0
- package/build/android/components/VoltraView.d.ts.map +1 -0
- package/build/android/components/VoltraView.js +44 -0
- package/build/android/components/VoltraView.js.map +1 -0
- package/build/android/components/VoltraWidgetPreview.d.ts +22 -0
- package/build/android/components/VoltraWidgetPreview.d.ts.map +1 -0
- package/build/android/components/VoltraWidgetPreview.js +27 -0
- package/build/android/components/VoltraWidgetPreview.js.map +1 -0
- package/build/android/index.d.ts +15 -0
- package/build/android/index.d.ts.map +1 -0
- package/build/android/index.js +3 -0
- package/build/android/index.js.map +1 -0
- package/build/android/jsx/Box.d.ts +4 -0
- package/build/android/jsx/Box.d.ts.map +1 -0
- package/build/android/jsx/Box.js +3 -0
- package/build/android/jsx/Box.js.map +1 -0
- package/build/android/jsx/Button.d.ts +4 -0
- package/build/android/jsx/Button.d.ts.map +1 -0
- package/build/android/jsx/Button.js +3 -0
- package/build/android/jsx/Button.js.map +1 -0
- package/build/android/jsx/CheckBox.d.ts +4 -0
- package/build/android/jsx/CheckBox.d.ts.map +1 -0
- package/build/android/jsx/CheckBox.js +3 -0
- package/build/android/jsx/CheckBox.js.map +1 -0
- package/build/android/jsx/CircleIconButton.d.ts +4 -0
- package/build/android/jsx/CircleIconButton.d.ts.map +1 -0
- package/build/android/jsx/CircleIconButton.js +11 -0
- package/build/android/jsx/CircleIconButton.js.map +1 -0
- package/build/android/jsx/CircularProgressIndicator.d.ts +4 -0
- package/build/android/jsx/CircularProgressIndicator.d.ts.map +1 -0
- package/build/android/jsx/CircularProgressIndicator.js +3 -0
- package/build/android/jsx/CircularProgressIndicator.js.map +1 -0
- package/build/android/jsx/Column.d.ts +4 -0
- package/build/android/jsx/Column.d.ts.map +1 -0
- package/build/android/jsx/Column.js +3 -0
- package/build/android/jsx/Column.js.map +1 -0
- package/build/android/jsx/FilledButton.d.ts +4 -0
- package/build/android/jsx/FilledButton.d.ts.map +1 -0
- package/build/android/jsx/FilledButton.js +11 -0
- package/build/android/jsx/FilledButton.js.map +1 -0
- package/build/android/jsx/Image.d.ts +13 -0
- package/build/android/jsx/Image.d.ts.map +1 -0
- package/build/android/jsx/Image.js +11 -0
- package/build/android/jsx/Image.js.map +1 -0
- package/build/android/jsx/LazyColumn.d.ts +4 -0
- package/build/android/jsx/LazyColumn.d.ts.map +1 -0
- package/build/android/jsx/LazyColumn.js +3 -0
- package/build/android/jsx/LazyColumn.js.map +1 -0
- package/build/android/jsx/LazyVerticalGrid.d.ts +4 -0
- package/build/android/jsx/LazyVerticalGrid.d.ts.map +1 -0
- package/build/android/jsx/LazyVerticalGrid.js +3 -0
- package/build/android/jsx/LazyVerticalGrid.js.map +1 -0
- package/build/android/jsx/LinearProgressIndicator.d.ts +4 -0
- package/build/android/jsx/LinearProgressIndicator.d.ts.map +1 -0
- package/build/android/jsx/LinearProgressIndicator.js +3 -0
- package/build/android/jsx/LinearProgressIndicator.js.map +1 -0
- package/build/android/jsx/OutlineButton.d.ts +4 -0
- package/build/android/jsx/OutlineButton.d.ts.map +1 -0
- package/build/android/jsx/OutlineButton.js +11 -0
- package/build/android/jsx/OutlineButton.js.map +1 -0
- package/build/android/jsx/RadioButton.d.ts +4 -0
- package/build/android/jsx/RadioButton.d.ts.map +1 -0
- package/build/android/jsx/RadioButton.js +3 -0
- package/build/android/jsx/RadioButton.js.map +1 -0
- package/build/android/jsx/Row.d.ts +4 -0
- package/build/android/jsx/Row.d.ts.map +1 -0
- package/build/android/jsx/Row.js +3 -0
- package/build/android/jsx/Row.js.map +1 -0
- package/build/android/jsx/Scaffold.d.ts +4 -0
- package/build/android/jsx/Scaffold.d.ts.map +1 -0
- package/build/android/jsx/Scaffold.js +3 -0
- package/build/android/jsx/Scaffold.js.map +1 -0
- package/build/android/jsx/Spacer.d.ts +4 -0
- package/build/android/jsx/Spacer.d.ts.map +1 -0
- package/build/android/jsx/Spacer.js +3 -0
- package/build/android/jsx/Spacer.js.map +1 -0
- package/build/android/jsx/SquareIconButton.d.ts +4 -0
- package/build/android/jsx/SquareIconButton.d.ts.map +1 -0
- package/build/android/jsx/SquareIconButton.js +11 -0
- package/build/android/jsx/SquareIconButton.js.map +1 -0
- package/build/android/jsx/Switch.d.ts +4 -0
- package/build/android/jsx/Switch.d.ts.map +1 -0
- package/build/android/jsx/Switch.js +3 -0
- package/build/android/jsx/Switch.js.map +1 -0
- package/build/android/jsx/Text.d.ts +7 -0
- package/build/android/jsx/Text.d.ts.map +1 -0
- package/build/android/jsx/Text.js +3 -0
- package/build/android/jsx/Text.js.map +1 -0
- package/build/android/jsx/TitleBar.d.ts +4 -0
- package/build/android/jsx/TitleBar.d.ts.map +1 -0
- package/build/android/jsx/TitleBar.js +11 -0
- package/build/android/jsx/TitleBar.js.map +1 -0
- package/build/android/jsx/baseProps.d.ts +9 -0
- package/build/android/jsx/baseProps.d.ts.map +1 -0
- package/build/android/jsx/baseProps.js +2 -0
- package/build/android/jsx/baseProps.js.map +1 -0
- package/build/android/jsx/index.d.ts +2 -0
- package/build/android/jsx/index.d.ts.map +1 -0
- package/build/android/jsx/index.js +2 -0
- package/build/android/jsx/index.js.map +1 -0
- package/build/android/jsx/primitives.d.ts +21 -0
- package/build/android/jsx/primitives.d.ts.map +1 -0
- package/build/android/jsx/primitives.js +21 -0
- package/build/android/jsx/primitives.js.map +1 -0
- package/build/android/jsx/props/Box.d.ts +6 -0
- package/build/android/jsx/props/Box.d.ts.map +1 -0
- package/build/android/jsx/props/Box.js +2 -0
- package/build/android/jsx/props/Box.js.map +1 -0
- package/build/android/jsx/props/Button.d.ts +6 -0
- package/build/android/jsx/props/Button.d.ts.map +1 -0
- package/build/android/jsx/props/Button.js +2 -0
- package/build/android/jsx/props/Button.js.map +1 -0
- package/build/android/jsx/props/CheckBox.d.ts +17 -0
- package/build/android/jsx/props/CheckBox.d.ts.map +1 -0
- package/build/android/jsx/props/CheckBox.js +2 -0
- package/build/android/jsx/props/CheckBox.js.map +1 -0
- package/build/android/jsx/props/CircleIconButton.d.ts +15 -0
- package/build/android/jsx/props/CircleIconButton.d.ts.map +1 -0
- package/build/android/jsx/props/CircleIconButton.js +2 -0
- package/build/android/jsx/props/CircleIconButton.js.map +1 -0
- package/build/android/jsx/props/CircularProgressIndicator.d.ts +12 -0
- package/build/android/jsx/props/CircularProgressIndicator.d.ts.map +1 -0
- package/build/android/jsx/props/CircularProgressIndicator.js +2 -0
- package/build/android/jsx/props/CircularProgressIndicator.js.map +1 -0
- package/build/android/jsx/props/Column.d.ts +8 -0
- package/build/android/jsx/props/Column.d.ts.map +1 -0
- package/build/android/jsx/props/Column.js +2 -0
- package/build/android/jsx/props/Column.js.map +1 -0
- package/build/android/jsx/props/FilledButton.d.ts +17 -0
- package/build/android/jsx/props/FilledButton.d.ts.map +1 -0
- package/build/android/jsx/props/FilledButton.js +2 -0
- package/build/android/jsx/props/FilledButton.js.map +1 -0
- package/build/android/jsx/props/Image.d.ts +16 -0
- package/build/android/jsx/props/Image.d.ts.map +1 -0
- package/build/android/jsx/props/Image.js +5 -0
- package/build/android/jsx/props/Image.js.map +1 -0
- package/build/android/jsx/props/LazyColumn.d.ts +6 -0
- package/build/android/jsx/props/LazyColumn.d.ts.map +1 -0
- package/build/android/jsx/props/LazyColumn.js +2 -0
- package/build/android/jsx/props/LazyColumn.js.map +1 -0
- package/build/android/jsx/props/LazyVerticalGrid.d.ts +12 -0
- package/build/android/jsx/props/LazyVerticalGrid.d.ts.map +1 -0
- package/build/android/jsx/props/LazyVerticalGrid.js +2 -0
- package/build/android/jsx/props/LazyVerticalGrid.js.map +1 -0
- package/build/android/jsx/props/LinearProgressIndicator.d.ts +10 -0
- package/build/android/jsx/props/LinearProgressIndicator.d.ts.map +1 -0
- package/build/android/jsx/props/LinearProgressIndicator.js +2 -0
- package/build/android/jsx/props/LinearProgressIndicator.js.map +1 -0
- package/build/android/jsx/props/OutlineButton.d.ts +15 -0
- package/build/android/jsx/props/OutlineButton.d.ts.map +1 -0
- package/build/android/jsx/props/OutlineButton.js +2 -0
- package/build/android/jsx/props/OutlineButton.js.map +1 -0
- package/build/android/jsx/props/RadioButton.d.ts +19 -0
- package/build/android/jsx/props/RadioButton.d.ts.map +1 -0
- package/build/android/jsx/props/RadioButton.js +2 -0
- package/build/android/jsx/props/RadioButton.js.map +1 -0
- package/build/android/jsx/props/Row.d.ts +8 -0
- package/build/android/jsx/props/Row.d.ts.map +1 -0
- package/build/android/jsx/props/Row.js +2 -0
- package/build/android/jsx/props/Row.js.map +1 -0
- package/build/android/jsx/props/Scaffold.d.ts +8 -0
- package/build/android/jsx/props/Scaffold.d.ts.map +1 -0
- package/build/android/jsx/props/Scaffold.js +2 -0
- package/build/android/jsx/props/Scaffold.js.map +1 -0
- package/build/android/jsx/props/Spacer.d.ts +6 -0
- package/build/android/jsx/props/Spacer.d.ts.map +1 -0
- package/build/android/jsx/props/Spacer.js +2 -0
- package/build/android/jsx/props/Spacer.js.map +1 -0
- package/build/android/jsx/props/SquareIconButton.d.ts +15 -0
- package/build/android/jsx/props/SquareIconButton.d.ts.map +1 -0
- package/build/android/jsx/props/SquareIconButton.js +2 -0
- package/build/android/jsx/props/SquareIconButton.js.map +1 -0
- package/build/android/jsx/props/Switch.d.ts +21 -0
- package/build/android/jsx/props/Switch.d.ts.map +1 -0
- package/build/android/jsx/props/Switch.js +2 -0
- package/build/android/jsx/props/Switch.js.map +1 -0
- package/build/android/jsx/props/Text.d.ts +6 -0
- package/build/android/jsx/props/Text.d.ts.map +1 -0
- package/build/android/jsx/props/Text.js +2 -0
- package/build/android/jsx/props/Text.js.map +1 -0
- package/build/android/jsx/props/TitleBar.d.ts +15 -0
- package/build/android/jsx/props/TitleBar.d.ts.map +1 -0
- package/build/android/jsx/props/TitleBar.js +2 -0
- package/build/android/jsx/props/TitleBar.js.map +1 -0
- package/build/android/live-update/api.d.ts +126 -0
- package/build/android/live-update/api.d.ts.map +1 -0
- package/build/android/live-update/api.js +203 -0
- package/build/android/live-update/api.js.map +1 -0
- package/build/android/live-update/renderer.d.ts +11 -0
- package/build/android/live-update/renderer.d.ts.map +1 -0
- package/build/android/live-update/renderer.js +41 -0
- package/build/android/live-update/renderer.js.map +1 -0
- package/build/android/live-update/types.d.ts +100 -0
- package/build/android/live-update/types.d.ts.map +1 -0
- package/build/android/live-update/types.js +2 -0
- package/build/android/live-update/types.js.map +1 -0
- package/build/android/payload/component-ids.d.ts +20 -0
- package/build/android/payload/component-ids.d.ts.map +1 -0
- package/build/android/payload/component-ids.js +78 -0
- package/build/android/payload/component-ids.js.map +1 -0
- package/build/android/preload.d.ts +45 -0
- package/build/android/preload.d.ts.map +1 -0
- package/build/android/preload.js +72 -0
- package/build/android/preload.js.map +1 -0
- package/build/android/server.d.ts +3 -0
- package/build/android/server.d.ts.map +1 -0
- package/build/android/server.js +3 -0
- package/build/android/server.js.map +1 -0
- package/build/android/styles/types.d.ts +114 -0
- package/build/android/styles/types.d.ts.map +1 -0
- package/build/android/styles/types.js +6 -0
- package/build/android/styles/types.js.map +1 -0
- package/build/android/widgets/api.d.ts +119 -0
- package/build/android/widgets/api.d.ts.map +1 -0
- package/build/android/widgets/api.js +129 -0
- package/build/android/widgets/api.js.map +1 -0
- package/build/android/widgets/index.d.ts +3 -0
- package/build/android/widgets/index.d.ts.map +1 -0
- package/build/android/widgets/index.js +3 -0
- package/build/android/widgets/index.js.map +1 -0
- package/build/android/widgets/renderer.d.ts +22 -0
- package/build/android/widgets/renderer.d.ts.map +1 -0
- package/build/android/widgets/renderer.js +51 -0
- package/build/android/widgets/renderer.js.map +1 -0
- package/build/android/widgets/types.d.ts +42 -0
- package/build/android/widgets/types.d.ts.map +1 -0
- package/build/android/widgets/types.js +2 -0
- package/build/android/widgets/types.js.map +1 -0
- package/build/client.d.ts +1 -1
- package/build/client.d.ts.map +1 -1
- package/build/client.js +1 -1
- package/build/client.js.map +1 -1
- package/build/events.d.ts +16 -0
- package/build/events.d.ts.map +1 -1
- package/build/events.js +19 -2
- package/build/events.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/jsx/Link.d.ts +4 -0
- package/build/jsx/Link.d.ts.map +1 -0
- package/build/jsx/Link.js +3 -0
- package/build/jsx/Link.js.map +1 -0
- package/build/jsx/primitives.d.ts +1 -0
- package/build/jsx/primitives.d.ts.map +1 -1
- package/build/jsx/primitives.js +1 -0
- package/build/jsx/primitives.js.map +1 -1
- package/build/jsx/props/AndroidBox.d.ts +6 -0
- package/build/jsx/props/AndroidBox.d.ts.map +1 -0
- package/build/jsx/props/AndroidBox.js +5 -0
- package/build/jsx/props/AndroidBox.js.map +1 -0
- package/build/jsx/props/AndroidButton.d.ts +6 -0
- package/build/jsx/props/AndroidButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidButton.js +5 -0
- package/build/jsx/props/AndroidButton.js.map +1 -0
- package/build/jsx/props/AndroidCheckBox.d.ts +10 -0
- package/build/jsx/props/AndroidCheckBox.d.ts.map +1 -0
- package/build/jsx/props/AndroidCheckBox.js +5 -0
- package/build/jsx/props/AndroidCheckBox.js.map +1 -0
- package/build/jsx/props/AndroidCircleIconButton.d.ts +14 -0
- package/build/jsx/props/AndroidCircleIconButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidCircleIconButton.js +5 -0
- package/build/jsx/props/AndroidCircleIconButton.js.map +1 -0
- package/build/jsx/props/AndroidCircularProgressIndicator.d.ts +6 -0
- package/build/jsx/props/AndroidCircularProgressIndicator.d.ts.map +1 -0
- package/build/jsx/props/AndroidCircularProgressIndicator.js +5 -0
- package/build/jsx/props/AndroidCircularProgressIndicator.js.map +1 -0
- package/build/jsx/props/AndroidColumn.d.ts +8 -0
- package/build/jsx/props/AndroidColumn.d.ts.map +1 -0
- package/build/jsx/props/AndroidColumn.js +5 -0
- package/build/jsx/props/AndroidColumn.js.map +1 -0
- package/build/jsx/props/AndroidFilledButton.d.ts +16 -0
- package/build/jsx/props/AndroidFilledButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidFilledButton.js +5 -0
- package/build/jsx/props/AndroidFilledButton.js.map +1 -0
- package/build/jsx/props/AndroidImage.d.ts +8 -0
- package/build/jsx/props/AndroidImage.d.ts.map +1 -0
- package/build/jsx/props/AndroidImage.js +5 -0
- package/build/jsx/props/AndroidImage.js.map +1 -0
- package/build/jsx/props/AndroidLazyColumn.d.ts +6 -0
- package/build/jsx/props/AndroidLazyColumn.d.ts.map +1 -0
- package/build/jsx/props/AndroidLazyColumn.js +5 -0
- package/build/jsx/props/AndroidLazyColumn.js.map +1 -0
- package/build/jsx/props/AndroidLazyVerticalGrid.d.ts +3 -0
- package/build/jsx/props/AndroidLazyVerticalGrid.d.ts.map +1 -0
- package/build/jsx/props/AndroidLazyVerticalGrid.js +5 -0
- package/build/jsx/props/AndroidLazyVerticalGrid.js.map +1 -0
- package/build/jsx/props/AndroidLinearProgressIndicator.d.ts +8 -0
- package/build/jsx/props/AndroidLinearProgressIndicator.d.ts.map +1 -0
- package/build/jsx/props/AndroidLinearProgressIndicator.js +5 -0
- package/build/jsx/props/AndroidLinearProgressIndicator.js.map +1 -0
- package/build/jsx/props/AndroidOutlineButton.d.ts +14 -0
- package/build/jsx/props/AndroidOutlineButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidOutlineButton.js +5 -0
- package/build/jsx/props/AndroidOutlineButton.js.map +1 -0
- package/build/jsx/props/AndroidRadioButton.d.ts +10 -0
- package/build/jsx/props/AndroidRadioButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidRadioButton.js +5 -0
- package/build/jsx/props/AndroidRadioButton.js.map +1 -0
- package/build/jsx/props/AndroidRow.d.ts +8 -0
- package/build/jsx/props/AndroidRow.d.ts.map +1 -0
- package/build/jsx/props/AndroidRow.js +5 -0
- package/build/jsx/props/AndroidRow.js.map +1 -0
- package/build/jsx/props/AndroidScaffold.d.ts +8 -0
- package/build/jsx/props/AndroidScaffold.d.ts.map +1 -0
- package/build/jsx/props/AndroidScaffold.js +5 -0
- package/build/jsx/props/AndroidScaffold.js.map +1 -0
- package/build/jsx/props/AndroidSpacer.d.ts +3 -0
- package/build/jsx/props/AndroidSpacer.d.ts.map +1 -0
- package/build/jsx/props/AndroidSpacer.js +5 -0
- package/build/jsx/props/AndroidSpacer.js.map +1 -0
- package/build/jsx/props/AndroidSquareIconButton.d.ts +14 -0
- package/build/jsx/props/AndroidSquareIconButton.d.ts.map +1 -0
- package/build/jsx/props/AndroidSquareIconButton.js +5 -0
- package/build/jsx/props/AndroidSquareIconButton.js.map +1 -0
- package/build/jsx/props/AndroidSwitch.d.ts +10 -0
- package/build/jsx/props/AndroidSwitch.d.ts.map +1 -0
- package/build/jsx/props/AndroidSwitch.js +5 -0
- package/build/jsx/props/AndroidSwitch.js.map +1 -0
- package/build/jsx/props/AndroidText.d.ts +12 -0
- package/build/jsx/props/AndroidText.d.ts.map +1 -0
- package/build/jsx/props/AndroidText.js +5 -0
- package/build/jsx/props/AndroidText.js.map +1 -0
- package/build/jsx/props/AndroidTitleBar.d.ts +10 -0
- package/build/jsx/props/AndroidTitleBar.d.ts.map +1 -0
- package/build/jsx/props/AndroidTitleBar.js +5 -0
- package/build/jsx/props/AndroidTitleBar.js.map +1 -0
- package/build/jsx/props/FilledButton.d.ts +16 -0
- package/build/jsx/props/FilledButton.d.ts.map +1 -0
- package/build/jsx/props/FilledButton.js +5 -0
- package/build/jsx/props/FilledButton.js.map +1 -0
- package/build/jsx/props/LegacyAndroidCheckBox.d.ts +8 -0
- package/build/jsx/props/LegacyAndroidCheckBox.d.ts.map +1 -0
- package/build/jsx/props/LegacyAndroidCheckBox.js +5 -0
- package/build/jsx/props/LegacyAndroidCheckBox.js.map +1 -0
- package/build/jsx/props/LegacyAndroidRadioButton.d.ts +8 -0
- package/build/jsx/props/LegacyAndroidRadioButton.d.ts.map +1 -0
- package/build/jsx/props/LegacyAndroidRadioButton.js +5 -0
- package/build/jsx/props/LegacyAndroidRadioButton.js.map +1 -0
- package/build/jsx/props/LegacyAndroidSwitch.d.ts +8 -0
- package/build/jsx/props/LegacyAndroidSwitch.d.ts.map +1 -0
- package/build/jsx/props/LegacyAndroidSwitch.js +5 -0
- package/build/jsx/props/LegacyAndroidSwitch.js.map +1 -0
- package/build/jsx/props/LegacyFilledButton.d.ts +8 -0
- package/build/jsx/props/LegacyFilledButton.d.ts.map +1 -0
- package/build/jsx/props/LegacyFilledButton.js +5 -0
- package/build/jsx/props/LegacyFilledButton.js.map +1 -0
- package/build/jsx/props/LegacyImage.d.ts +8 -0
- package/build/jsx/props/LegacyImage.d.ts.map +1 -0
- package/build/jsx/props/LegacyImage.js +5 -0
- package/build/jsx/props/LegacyImage.js.map +1 -0
- package/build/jsx/props/Link.d.ts +6 -0
- package/build/jsx/props/Link.d.ts.map +1 -0
- package/build/jsx/props/Link.js +5 -0
- package/build/jsx/props/Link.js.map +1 -0
- package/build/jsx/props/Timer.d.ts +2 -0
- package/build/jsx/props/Timer.d.ts.map +1 -1
- package/build/jsx/props/Timer.js.map +1 -1
- package/build/live-activity/renderer.d.ts.map +1 -1
- package/build/live-activity/renderer.js +4 -0
- package/build/live-activity/renderer.js.map +1 -1
- package/build/live-activity/types.d.ts +13 -0
- package/build/live-activity/types.d.ts.map +1 -1
- package/build/live-activity/types.js.map +1 -1
- package/build/payload/component-ids.d.ts.map +1 -1
- package/build/payload/component-ids.js +2 -0
- package/build/payload/component-ids.js.map +1 -1
- package/build/payload/short-names.d.ts.map +1 -1
- package/build/payload/short-names.js +40 -0
- package/build/payload/short-names.js.map +1 -1
- package/build/renderer/flatten-styles.d.ts +5 -1
- package/build/renderer/flatten-styles.d.ts.map +1 -1
- package/build/renderer/flatten-styles.js +4 -1
- package/build/renderer/flatten-styles.js.map +1 -1
- package/build/renderer/index.d.ts +1 -1
- package/build/renderer/index.d.ts.map +1 -1
- package/build/renderer/index.js +1 -1
- package/build/renderer/index.js.map +1 -1
- package/build/renderer/renderer.d.ts +20 -1
- package/build/renderer/renderer.d.ts.map +1 -1
- package/build/renderer/renderer.js +42 -8
- package/build/renderer/renderer.js.map +1 -1
- package/build/styles/types.d.ts +1 -1
- package/build/styles/types.d.ts.map +1 -1
- package/build/styles/types.js.map +1 -1
- package/build/widgets/types.d.ts +17 -0
- package/build/widgets/types.d.ts.map +1 -1
- package/build/widgets/types.js.map +1 -1
- package/build/widgets/widget-api.d.ts +57 -1
- package/build/widgets/widget-api.d.ts.map +1 -1
- package/build/widgets/widget-api.js +71 -0
- package/build/widgets/widget-api.js.map +1 -1
- package/expo-module.config.json +4 -1
- package/ios/app/VoltraActivity.swift +5 -0
- package/ios/app/VoltraLiveActivityService.swift +103 -7
- package/ios/app/VoltraModule.swift +29 -462
- package/ios/app/VoltraModuleImpl.swift +487 -0
- package/ios/shared/ComponentTypeID.swift +4 -0
- package/ios/shared/ShortNames.swift +21 -1
- package/ios/shared/VoltraElement.swift +6 -2
- package/ios/shared/VoltraNode.swift +3 -0
- package/ios/shared/VoltraRegion.swift +3 -0
- package/ios/target/VoltraHomeWidget.swift +174 -56
- package/ios/target/VoltraWidget.swift +125 -30
- package/ios/ui/Generated/Parameters/AndroidCheckBoxParameters.swift +29 -0
- package/ios/ui/Generated/Parameters/AndroidRadioButtonParameters.swift +29 -0
- package/ios/ui/Generated/Parameters/AndroidSwitchParameters.swift +29 -0
- package/ios/ui/Generated/Parameters/FilledButtonParameters.swift +29 -0
- package/ios/ui/Generated/Parameters/LinkParameters.swift +15 -0
- package/ios/ui/Generated/Parameters/TimerParameters.swift +5 -0
- package/ios/ui/Helpers/VoltraDeepLinkResolver.swift +19 -5
- package/ios/ui/Style/StyleConverter.swift +4 -0
- package/ios/ui/Style/TextStyle.swift +7 -1
- package/ios/ui/Views/VoltraLink.swift +25 -0
- package/ios/ui/Views/VoltraText.swift +16 -0
- package/ios/ui/Views/VoltraTimer.swift +31 -16
- package/package.json +22 -3
- package/plugin/build/constants/index.d.ts +1 -1
- package/plugin/build/constants/index.js +2 -1
- package/plugin/build/constants/paths.d.ts +2 -0
- package/plugin/build/constants/paths.js +3 -1
- package/plugin/build/features/android/files/assets/images.d.ts +20 -0
- package/plugin/build/features/android/files/assets/images.js +165 -0
- package/plugin/build/features/android/files/assets/index.d.ts +21 -0
- package/plugin/build/features/android/files/assets/index.js +95 -0
- package/plugin/build/features/android/files/assets/preview.d.ts +6 -0
- package/plugin/build/features/android/files/assets/preview.js +73 -0
- package/plugin/build/features/android/files/index.d.ts +19 -0
- package/plugin/build/features/android/files/index.js +58 -0
- package/plugin/build/features/android/files/initialStates.d.ts +13 -0
- package/plugin/build/features/android/files/initialStates.js +48 -0
- package/plugin/build/features/android/files/kotlin/index.d.ts +10 -0
- package/plugin/build/features/android/files/kotlin/index.js +59 -0
- package/plugin/build/features/android/files/kotlin/widgetReceiver.d.ts +5 -0
- package/plugin/build/features/android/files/kotlin/widgetReceiver.js +27 -0
- package/plugin/build/features/android/files/xml/index.d.ts +11 -0
- package/plugin/build/features/android/files/xml/index.js +76 -0
- package/plugin/build/features/android/files/xml/placeholderLayout.d.ts +5 -0
- package/plugin/build/features/android/files/xml/placeholderLayout.js +27 -0
- package/plugin/build/features/android/files/xml/previewLayout.d.ts +11 -0
- package/plugin/build/features/android/files/xml/previewLayout.js +106 -0
- package/plugin/build/features/android/files/xml/stringResources.d.ts +5 -0
- package/plugin/build/features/android/files/xml/stringResources.js +22 -0
- package/plugin/build/features/android/files/xml/widgetInfo.d.ts +5 -0
- package/plugin/build/features/android/files/xml/widgetInfo.js +43 -0
- package/plugin/build/features/android/index.d.ts +11 -0
- package/plugin/build/features/android/index.js +29 -0
- package/plugin/build/features/android/manifest/index.d.ts +14 -0
- package/plugin/build/features/android/manifest/index.js +62 -0
- package/plugin/build/features/ios/eas/index.d.ts +1 -1
- package/plugin/build/features/ios/eas/index.js +9 -7
- package/plugin/build/features/ios/files/entitlements.d.ts +2 -2
- package/plugin/build/features/ios/files/entitlements.js +3 -1
- package/plugin/build/features/ios/files/index.d.ts +1 -1
- package/plugin/build/features/ios/files/index.js +1 -1
- package/plugin/build/features/ios/files/swift/index.js +5 -2
- package/plugin/build/features/ios/files/swift/widgetBundle.js +2 -2
- package/plugin/build/features/ios/fonts.d.ts +21 -0
- package/plugin/build/features/ios/fonts.js +173 -0
- package/plugin/build/features/ios/index.d.ts +12 -5
- package/plugin/build/features/ios/index.js +21 -11
- package/plugin/build/features/ios/plist/index.d.ts +1 -1
- package/plugin/build/features/ios/plist/index.js +5 -1
- package/plugin/build/features/ios/xcode/build/phases.js +1 -1
- package/plugin/build/index.d.ts +2 -2
- package/plugin/build/index.js +17 -11
- package/plugin/build/types/index.d.ts +1 -1
- package/plugin/build/types/plugin.d.ts +108 -3
- package/plugin/build/utils/prerender.d.ts +24 -0
- package/plugin/build/{features/ios/files/swift → utils}/prerender.js +5 -5
- package/plugin/build/validation/validateAndroidWidget.d.ts +6 -0
- package/plugin/build/validation/validateAndroidWidget.js +123 -0
- package/plugin/build/validation/validateProps.d.ts +1 -1
- package/plugin/build/validation/validateProps.js +30 -14
- package/scripts/release-canary.js +65 -0
- package/plugin/build/features/ios/files/swift/prerender.d.ts +0 -13
package/README.md
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
-
### Build Live Activities with JSX in React Native
|
|
3
|
+
### Build Live Activities and Widgets with JSX in React Native
|
|
4
4
|
|
|
5
5
|
[![mit licence][license-badge]][license] [![npm downloads][npm-downloads-badge]][npm-downloads] [![PRs Welcome][prs-welcome-badge]][prs-welcome]
|
|
6
6
|
|
|
7
|
-
Voltra turns React Native JSX into SwiftUI so you can ship custom Live Activities, Dynamic Island layouts without touching
|
|
7
|
+
Voltra turns React Native JSX into SwiftUI and Jetpack Compose Glance so you can ship custom Live Activities, Dynamic Island layouts, and Android Widgets without touching native code. Author everything in React, keep hot reload, and let the config plugin handle the native extension targets.
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- **Ship Native
|
|
11
|
+
- **Ship Native Surfaces**: Create iOS Live Activities, Dynamic Island variants, and Android Home Screen widgets directly from React components - no Swift, Kotlin, or Xcode/Android Studio UI work required.
|
|
12
12
|
|
|
13
|
-
- **Fast Development Workflow**: Hooks respect Fast Refresh and both JS and native layers enforce
|
|
13
|
+
- **Fast Development Workflow**: Hooks respect Fast Refresh and both JS and native layers enforce platform-specific payload budgets.
|
|
14
14
|
|
|
15
|
-
- **Production-Ready Push Notifications**:
|
|
15
|
+
- **Production-Ready Push Notifications**: Support for ActivityKit push tokens (iOS) and FCM (Android) to stream lifecycle updates and build server-driven refreshes.
|
|
16
16
|
|
|
17
|
-
- **Familiar Styling**: Use React Native style props and
|
|
17
|
+
- **Familiar Styling**: Use React Native style props and platform-native modifiers (SwiftUI/Glance) in one place.
|
|
18
18
|
|
|
19
19
|
- **Type-Safe & Developer-Friendly**: The Voltra schema, hooks, and examples ship with TypeScript definitions, tests, and docs so AI coding agents stay productive.
|
|
20
20
|
|
|
21
|
-
- **Works With Your Setup**: Compatible with Expo Dev Client and bare React Native projects. The config plugin automatically wires
|
|
21
|
+
- **Works With Your Setup**: Compatible with Expo Dev Client and bare React Native projects. The config plugin automatically wires native extension targets for you.
|
|
22
22
|
|
|
23
23
|
## Documentation
|
|
24
24
|
|
|
25
25
|
The documentation is available at [use-voltra.dev](https://use-voltra.dev). You can also use the following links to jump to specific topics:
|
|
26
26
|
|
|
27
|
-
- [Quick Start](https://use-voltra.dev/
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
27
|
+
- [Quick Start](https://use-voltra.dev/getting-started/quick-start)
|
|
28
|
+
- [Development](https://www.use-voltra.dev/development/developing-live-activities)
|
|
29
|
+
- [Components](https://www.use-voltra.dev/components/overview)
|
|
30
|
+
- [API Reference](https://use-voltra.dev/api/configuration)
|
|
30
31
|
|
|
31
32
|
## Getting started
|
|
32
33
|
|
|
@@ -49,9 +50,9 @@ Add the config plugin to your `app.json`:
|
|
|
49
50
|
}
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
Then run `npx expo prebuild --clean` to generate the
|
|
53
|
+
Then run `npx expo prebuild --clean` to generate the native extension targets.
|
|
53
54
|
|
|
54
|
-
See the [documentation](https://use-voltra.dev/
|
|
55
|
+
See the [documentation](https://use-voltra.dev/getting-started/quick-start) for detailed setup instructions.
|
|
55
56
|
|
|
56
57
|
## Quick example
|
|
57
58
|
|
|
@@ -82,7 +83,10 @@ export function OrderTracker({ orderId }: { orderId: string }) {
|
|
|
82
83
|
|
|
83
84
|
## Platform compatibility
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
Voltra is a cross-platform library that supports:
|
|
87
|
+
|
|
88
|
+
- **iOS**: Live Activities and Dynamic Island (SwiftUI).
|
|
89
|
+
- **Android**: Home Screen Widgets (Jetpack Compose Glance).
|
|
86
90
|
|
|
87
91
|
## Authors
|
|
88
92
|
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
// 1. ADD THIS BLOCK TO RESOLVE THE PLUGIN
|
|
3
|
+
repositories {
|
|
4
|
+
google()
|
|
5
|
+
mavenCentral()
|
|
6
|
+
}
|
|
7
|
+
dependencies {
|
|
8
|
+
// Ensure this version matches your project's Kotlin version (e.g., 2.0.0, 2.0.20)
|
|
9
|
+
classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.0.0"
|
|
10
|
+
classpath "org.jetbrains.kotlin:kotlin-serialization:2.0.21"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Existing helper
|
|
14
|
+
ext.safeExtGet = { prop, fallback ->
|
|
15
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
apply plugin: 'com.android.library'
|
|
20
|
+
apply plugin: 'org.jetbrains.kotlin.plugin.compose'
|
|
21
|
+
apply plugin: 'org.jetbrains.kotlin.plugin.serialization'
|
|
22
|
+
|
|
23
|
+
group = 'voltra'
|
|
24
|
+
version = '0.1.0'
|
|
25
|
+
|
|
26
|
+
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
27
|
+
apply from: expoModulesCorePlugin
|
|
28
|
+
applyKotlinExpoModulesCorePlugin()
|
|
29
|
+
useCoreDependencies()
|
|
30
|
+
useExpoPublishing()
|
|
31
|
+
|
|
32
|
+
// If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
|
|
33
|
+
// The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
|
|
34
|
+
// Most of the time, you may like to manage the Android SDK versions yourself.
|
|
35
|
+
def useManagedAndroidSdkVersions = false
|
|
36
|
+
if (useManagedAndroidSdkVersions) {
|
|
37
|
+
useDefaultAndroidSdkVersions()
|
|
38
|
+
} else {
|
|
39
|
+
buildscript {
|
|
40
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
41
|
+
ext.safeExtGet = { prop, fallback ->
|
|
42
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
project.android {
|
|
46
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 36)
|
|
47
|
+
defaultConfig {
|
|
48
|
+
minSdkVersion safeExtGet("minSdkVersion", 31)
|
|
49
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 36)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
android {
|
|
55
|
+
namespace "voltra"
|
|
56
|
+
defaultConfig {
|
|
57
|
+
versionCode 1
|
|
58
|
+
versionName "0.1.0"
|
|
59
|
+
}
|
|
60
|
+
lintOptions {
|
|
61
|
+
abortOnError false
|
|
62
|
+
}
|
|
63
|
+
buildFeatures {
|
|
64
|
+
compose true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
dependencies {
|
|
69
|
+
// Jetpack Glance - use 'api' instead of 'implementation' to make these available to consuming apps
|
|
70
|
+
api "androidx.glance:glance:1.2.0-rc01"
|
|
71
|
+
api "androidx.glance:glance-appwidget:1.2.0-rc01"
|
|
72
|
+
|
|
73
|
+
// Compose runtime (required for Glance)
|
|
74
|
+
api "androidx.compose.runtime:runtime:1.6.8"
|
|
75
|
+
|
|
76
|
+
// JSON parsing
|
|
77
|
+
implementation "com.google.code.gson:gson:2.10.1"
|
|
78
|
+
|
|
79
|
+
// Coroutines
|
|
80
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
|
|
81
|
+
|
|
82
|
+
// Kotlinx Serialization
|
|
83
|
+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
|
|
84
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
|
3
|
+
|
|
4
|
+
<application>
|
|
5
|
+
<provider
|
|
6
|
+
android:name="androidx.core.content.FileProvider"
|
|
7
|
+
android:authorities="${applicationId}.voltra.fileprovider"
|
|
8
|
+
android:exported="false"
|
|
9
|
+
android:grantUriPermissions="true">
|
|
10
|
+
<meta-data
|
|
11
|
+
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
12
|
+
android:resource="@xml/voltra_file_paths" />
|
|
13
|
+
</provider>
|
|
14
|
+
</application>
|
|
15
|
+
</manifest>
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
package voltra
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import androidx.compose.ui.unit.DpSize
|
|
5
|
+
import androidx.compose.ui.unit.dp
|
|
6
|
+
import androidx.glance.appwidget.GlanceAppWidgetManager
|
|
7
|
+
import expo.modules.kotlin.modules.Module
|
|
8
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
9
|
+
import kotlinx.coroutines.async
|
|
10
|
+
import kotlinx.coroutines.awaitAll
|
|
11
|
+
import kotlinx.coroutines.runBlocking
|
|
12
|
+
import voltra.events.VoltraEventBus
|
|
13
|
+
import voltra.images.VoltraImageManager
|
|
14
|
+
import voltra.widget.VoltraGlanceWidget
|
|
15
|
+
import voltra.widget.VoltraWidgetManager
|
|
16
|
+
|
|
17
|
+
class VoltraModule : Module() {
|
|
18
|
+
companion object {
|
|
19
|
+
private const val TAG = "VoltraModule"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private val notificationManager by lazy {
|
|
23
|
+
VoltraNotificationManager(appContext.reactContext!!)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private val widgetManager by lazy {
|
|
27
|
+
VoltraWidgetManager(appContext.reactContext!!)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private val imageManager by lazy {
|
|
31
|
+
VoltraImageManager(appContext.reactContext!!)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private val eventBus by lazy {
|
|
35
|
+
VoltraEventBus.getInstance(appContext.reactContext!!)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private var eventBusUnsubscribe: (() -> Unit)? = null
|
|
39
|
+
|
|
40
|
+
override fun definition() =
|
|
41
|
+
ModuleDefinition {
|
|
42
|
+
Name("VoltraModule")
|
|
43
|
+
|
|
44
|
+
OnStartObserving {
|
|
45
|
+
Log.d(TAG, "OnStartObserving: Starting event bus subscription")
|
|
46
|
+
|
|
47
|
+
// Replay any persisted events from SharedPreferences (cold start)
|
|
48
|
+
val persistedEvents = eventBus.popAll()
|
|
49
|
+
Log.d(TAG, "Replaying ${persistedEvents.size} persisted events")
|
|
50
|
+
|
|
51
|
+
persistedEvents.forEach { event ->
|
|
52
|
+
sendEvent(event.type, event.toMap())
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Subscribe to hot event delivery (broadcast receiver)
|
|
56
|
+
eventBusUnsubscribe =
|
|
57
|
+
eventBus.addListener { event ->
|
|
58
|
+
Log.d(TAG, "Received hot event: ${event.type}")
|
|
59
|
+
sendEvent(event.type, event.toMap())
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
OnStopObserving {
|
|
64
|
+
Log.d(TAG, "OnStopObserving: Unsubscribing from event bus")
|
|
65
|
+
eventBusUnsubscribe?.invoke()
|
|
66
|
+
eventBusUnsubscribe = null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Android Live Update APIs
|
|
70
|
+
|
|
71
|
+
AsyncFunction("startAndroidLiveUpdate") {
|
|
72
|
+
payload: String,
|
|
73
|
+
options: Map<String, Any?>,
|
|
74
|
+
->
|
|
75
|
+
|
|
76
|
+
Log.d(TAG, "startAndroidLiveUpdate called")
|
|
77
|
+
|
|
78
|
+
val updateName = options["updateName"] as? String
|
|
79
|
+
val channelId = options["channelId"] as? String ?: "voltra_live_updates"
|
|
80
|
+
|
|
81
|
+
Log.d(TAG, "updateName=$updateName, channelId=$channelId")
|
|
82
|
+
|
|
83
|
+
val result =
|
|
84
|
+
runBlocking {
|
|
85
|
+
notificationManager.startLiveUpdate(payload, updateName, channelId)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Log.d(TAG, "startAndroidLiveUpdate returning: $result")
|
|
89
|
+
result
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
AsyncFunction("updateAndroidLiveUpdate") {
|
|
93
|
+
notificationId: String,
|
|
94
|
+
payload: String,
|
|
95
|
+
->
|
|
96
|
+
|
|
97
|
+
Log.d(TAG, "updateAndroidLiveUpdate called with notificationId=$notificationId")
|
|
98
|
+
|
|
99
|
+
runBlocking {
|
|
100
|
+
notificationManager.updateLiveUpdate(notificationId, payload)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
Log.d(TAG, "updateAndroidLiveUpdate completed")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
AsyncFunction("stopAndroidLiveUpdate") { notificationId: String ->
|
|
107
|
+
Log.d(TAG, "stopAndroidLiveUpdate called with notificationId=$notificationId")
|
|
108
|
+
notificationManager.stopLiveUpdate(notificationId)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Function("isAndroidLiveUpdateActive") { updateName: String ->
|
|
112
|
+
notificationManager.isLiveUpdateActive(updateName)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
AsyncFunction("endAllAndroidLiveUpdates") {
|
|
116
|
+
notificationManager.endAllLiveUpdates()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Android Widget APIs
|
|
120
|
+
|
|
121
|
+
AsyncFunction("updateAndroidWidget") {
|
|
122
|
+
widgetId: String,
|
|
123
|
+
jsonString: String,
|
|
124
|
+
options: Map<String, Any?>,
|
|
125
|
+
->
|
|
126
|
+
|
|
127
|
+
Log.d(TAG, "updateAndroidWidget called with widgetId=$widgetId")
|
|
128
|
+
|
|
129
|
+
val deepLinkUrl = options["deepLinkUrl"] as? String
|
|
130
|
+
|
|
131
|
+
widgetManager.writeWidgetData(widgetId, jsonString, deepLinkUrl)
|
|
132
|
+
|
|
133
|
+
runBlocking {
|
|
134
|
+
widgetManager.updateWidget(widgetId)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Log.d(TAG, "updateAndroidWidget completed")
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
AsyncFunction("reloadAndroidWidgets") { widgetIds: ArrayList<String>? ->
|
|
141
|
+
Log.d(TAG, "reloadAndroidWidgets called with widgetIds=$widgetIds")
|
|
142
|
+
|
|
143
|
+
runBlocking {
|
|
144
|
+
widgetManager.reloadWidgets(widgetIds)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Log.d(TAG, "reloadAndroidWidgets completed")
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
AsyncFunction("clearAndroidWidget") { widgetId: String ->
|
|
151
|
+
Log.d(TAG, "clearAndroidWidget called with widgetId=$widgetId")
|
|
152
|
+
|
|
153
|
+
widgetManager.clearWidgetData(widgetId)
|
|
154
|
+
|
|
155
|
+
runBlocking {
|
|
156
|
+
widgetManager.updateWidget(widgetId)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Log.d(TAG, "clearAndroidWidget completed")
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
AsyncFunction("clearAllAndroidWidgets") {
|
|
163
|
+
Log.d(TAG, "clearAllAndroidWidgets called")
|
|
164
|
+
|
|
165
|
+
widgetManager.clearAllWidgetData()
|
|
166
|
+
|
|
167
|
+
runBlocking {
|
|
168
|
+
widgetManager.reloadAllWidgets()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
Log.d(TAG, "clearAllAndroidWidgets completed")
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
AsyncFunction("requestPinGlanceAppWidget") {
|
|
175
|
+
widgetId: String,
|
|
176
|
+
options: Map<String, Any?>?,
|
|
177
|
+
->
|
|
178
|
+
|
|
179
|
+
Log.d(TAG, "requestPinGlanceAppWidget called with widgetId=$widgetId")
|
|
180
|
+
|
|
181
|
+
val context = appContext.reactContext!!
|
|
182
|
+
|
|
183
|
+
// Construct the receiver class name following the convention
|
|
184
|
+
val receiverClassName = "${context.packageName}.widget.VoltraWidget_${widgetId}Receiver"
|
|
185
|
+
|
|
186
|
+
Log.d(TAG, "Looking for receiver: $receiverClassName")
|
|
187
|
+
|
|
188
|
+
// Get the receiver class using reflection
|
|
189
|
+
val receiverClass =
|
|
190
|
+
try {
|
|
191
|
+
Class.forName(receiverClassName) as Class<out androidx.glance.appwidget.GlanceAppWidgetReceiver>
|
|
192
|
+
} catch (e: ClassNotFoundException) {
|
|
193
|
+
Log.e(TAG, "Widget receiver class not found: $receiverClassName", e)
|
|
194
|
+
throw IllegalArgumentException("Widget receiver not found for id: $widgetId")
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Get GlanceAppWidgetManager and request pin
|
|
198
|
+
val glanceManager = GlanceAppWidgetManager(context)
|
|
199
|
+
|
|
200
|
+
// Parse preview size from options (optional)
|
|
201
|
+
// See: https://developer.android.com/develop/ui/compose/glance/pin-in-app
|
|
202
|
+
val previewSize =
|
|
203
|
+
if (options != null) {
|
|
204
|
+
val width = (options["previewWidth"] as? Number)?.toFloat()
|
|
205
|
+
val height = (options["previewHeight"] as? Number)?.toFloat()
|
|
206
|
+
if (width != null && height != null) {
|
|
207
|
+
DpSize(width.dp, height.dp)
|
|
208
|
+
} else {
|
|
209
|
+
null
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
null
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
val result =
|
|
216
|
+
runBlocking {
|
|
217
|
+
// requestPinGlanceAppWidget is a suspend function
|
|
218
|
+
// See: https://developer.android.com/develop/ui/compose/glance/pin-in-app
|
|
219
|
+
if (previewSize != null) {
|
|
220
|
+
// Create preview widget with preview dimensions
|
|
221
|
+
val previewWidget = VoltraGlanceWidget(widgetId)
|
|
222
|
+
glanceManager.requestPinGlanceAppWidget(
|
|
223
|
+
receiver = receiverClass,
|
|
224
|
+
preview = previewWidget,
|
|
225
|
+
previewState = previewSize,
|
|
226
|
+
)
|
|
227
|
+
} else {
|
|
228
|
+
// Basic pin request without preview
|
|
229
|
+
glanceManager.requestPinGlanceAppWidget(receiverClass)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
Log.d(TAG, "requestPinGlanceAppWidget completed with result=$result")
|
|
234
|
+
result
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
AsyncFunction("preloadImages") { images: List<Map<String, Any>> ->
|
|
238
|
+
Log.d(TAG, "preloadImages called with ${images.size} images")
|
|
239
|
+
|
|
240
|
+
runBlocking {
|
|
241
|
+
val results =
|
|
242
|
+
images
|
|
243
|
+
.map { img ->
|
|
244
|
+
async {
|
|
245
|
+
val url = img["url"] as String
|
|
246
|
+
val key = img["key"] as String
|
|
247
|
+
val method = (img["method"] as? String) ?: "GET"
|
|
248
|
+
|
|
249
|
+
@Suppress("UNCHECKED_CAST")
|
|
250
|
+
val headers = img["headers"] as? Map<String, String>
|
|
251
|
+
|
|
252
|
+
val resultKey = imageManager.preloadImage(url, key, method, headers)
|
|
253
|
+
if (resultKey != null) {
|
|
254
|
+
Pair(key, null)
|
|
255
|
+
} else {
|
|
256
|
+
Pair(key, "Failed to download image")
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}.awaitAll()
|
|
260
|
+
|
|
261
|
+
val succeeded = results.filter { it.second == null }.map { it.first }
|
|
262
|
+
val failed =
|
|
263
|
+
results.filter { it.second != null }.map {
|
|
264
|
+
mapOf("key" to it.first, "error" to it.second)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
mapOf(
|
|
268
|
+
"succeeded" to succeeded,
|
|
269
|
+
"failed" to failed,
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
AsyncFunction("clearPreloadedImages") { keys: List<String>? ->
|
|
275
|
+
Log.d(TAG, "clearPreloadedImages called with keys=$keys")
|
|
276
|
+
imageManager.clearPreloadedImages(keys)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
AsyncFunction("reloadLiveActivities") { activityNames: List<String>? ->
|
|
280
|
+
// On Android, we don't have "Live Activities" in the same sense as iOS,
|
|
281
|
+
// but we might want to refresh widgets or notifications.
|
|
282
|
+
// For now, this is a no-op to match iOS API if called.
|
|
283
|
+
Log.d(TAG, "reloadLiveActivities called (no-op on Android)")
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
View(VoltraRN::class) {
|
|
287
|
+
Prop("payload") { view, payload: String ->
|
|
288
|
+
view.setPayload(payload)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
Prop("viewId") { view, viewId: String ->
|
|
292
|
+
view.setViewId(viewId)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
package voltra
|
|
2
|
+
|
|
3
|
+
import android.app.NotificationChannel
|
|
4
|
+
import android.app.NotificationManager
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.os.Build
|
|
7
|
+
import android.util.Log
|
|
8
|
+
import androidx.core.app.NotificationCompat
|
|
9
|
+
import kotlinx.coroutines.Dispatchers
|
|
10
|
+
import kotlinx.coroutines.withContext
|
|
11
|
+
import voltra.glance.RemoteViewsGenerator
|
|
12
|
+
import voltra.parsing.VoltraPayloadParser
|
|
13
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
14
|
+
import java.util.concurrent.atomic.AtomicInteger
|
|
15
|
+
|
|
16
|
+
class VoltraNotificationManager(
|
|
17
|
+
private val context: Context,
|
|
18
|
+
) {
|
|
19
|
+
companion object {
|
|
20
|
+
private const val TAG = "VoltraNotificationMgr"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private val notificationManager =
|
|
24
|
+
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
25
|
+
private val activeNotifications = ConcurrentHashMap<String, Int>()
|
|
26
|
+
private val idCounter = AtomicInteger(10000)
|
|
27
|
+
|
|
28
|
+
suspend fun startLiveUpdate(
|
|
29
|
+
payload: String,
|
|
30
|
+
updateName: String?,
|
|
31
|
+
channelId: String,
|
|
32
|
+
): String =
|
|
33
|
+
withContext(Dispatchers.Default) {
|
|
34
|
+
Log.d(TAG, "startLiveUpdate called with updateName=$updateName, channelId=$channelId")
|
|
35
|
+
Log.d(TAG, "Payload (first 200 chars): ${payload.take(200)}")
|
|
36
|
+
|
|
37
|
+
val voltraPayload = VoltraPayloadParser.parse(payload)
|
|
38
|
+
val notificationId = updateName ?: "live-update-${idCounter.getAndIncrement()}"
|
|
39
|
+
val intId = notificationId.hashCode().and(0x7FFFFFFF) // Ensure positive
|
|
40
|
+
|
|
41
|
+
Log.d(TAG, "Parsed payload, notificationId=$notificationId, intId=$intId")
|
|
42
|
+
|
|
43
|
+
createNotificationChannel(channelId)
|
|
44
|
+
|
|
45
|
+
val collapsedView = RemoteViewsGenerator.generateCollapsed(context, voltraPayload)
|
|
46
|
+
val expandedView = RemoteViewsGenerator.generateExpanded(context, voltraPayload)
|
|
47
|
+
|
|
48
|
+
Log.d(TAG, "Generated views: collapsed=${collapsedView != null}, expanded=${expandedView != null}")
|
|
49
|
+
|
|
50
|
+
val notification =
|
|
51
|
+
NotificationCompat
|
|
52
|
+
.Builder(context, channelId)
|
|
53
|
+
.setSmallIcon(getSmallIcon(voltraPayload.smallIcon))
|
|
54
|
+
.setOngoing(true)
|
|
55
|
+
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
|
56
|
+
.apply {
|
|
57
|
+
collapsedView?.let { setCustomContentView(it) }
|
|
58
|
+
expandedView?.let { setCustomBigContentView(it) }
|
|
59
|
+
}.build()
|
|
60
|
+
|
|
61
|
+
notificationManager.notify(intId, notification)
|
|
62
|
+
activeNotifications[notificationId] = intId
|
|
63
|
+
|
|
64
|
+
Log.d(TAG, "Notification posted. Active notifications: ${activeNotifications.keys}")
|
|
65
|
+
|
|
66
|
+
notificationId
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
suspend fun updateLiveUpdate(
|
|
70
|
+
notificationId: String,
|
|
71
|
+
payload: String,
|
|
72
|
+
) = withContext(Dispatchers.Default) {
|
|
73
|
+
Log.d(TAG, "updateLiveUpdate called with notificationId=$notificationId")
|
|
74
|
+
Log.d(TAG, "Active notifications: ${activeNotifications.keys}")
|
|
75
|
+
|
|
76
|
+
val intId = activeNotifications[notificationId]
|
|
77
|
+
if (intId == null) {
|
|
78
|
+
Log.e(TAG, "Notification $notificationId not found in activeNotifications!")
|
|
79
|
+
return@withContext
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Log.d(TAG, "Found intId=$intId for notificationId=$notificationId")
|
|
83
|
+
|
|
84
|
+
val voltraPayload = VoltraPayloadParser.parse(payload)
|
|
85
|
+
val channelId = voltraPayload.channelId ?: "voltra_live_updates"
|
|
86
|
+
|
|
87
|
+
val collapsedView = RemoteViewsGenerator.generateCollapsed(context, voltraPayload)
|
|
88
|
+
val expandedView = RemoteViewsGenerator.generateExpanded(context, voltraPayload)
|
|
89
|
+
|
|
90
|
+
Log.d(TAG, "Update generated views: collapsed=${collapsedView != null}, expanded=${expandedView != null}")
|
|
91
|
+
|
|
92
|
+
val notification =
|
|
93
|
+
NotificationCompat
|
|
94
|
+
.Builder(context, channelId)
|
|
95
|
+
.setSmallIcon(getSmallIcon(voltraPayload.smallIcon))
|
|
96
|
+
.setOngoing(true)
|
|
97
|
+
.setOnlyAlertOnce(true) // Don't make sound/vibration on updates
|
|
98
|
+
.setWhen(System.currentTimeMillis()) // Force timestamp update
|
|
99
|
+
.setShowWhen(false) // But don't show the time
|
|
100
|
+
.apply {
|
|
101
|
+
collapsedView?.let { setCustomContentView(it) }
|
|
102
|
+
expandedView?.let { setCustomBigContentView(it) }
|
|
103
|
+
}.build()
|
|
104
|
+
|
|
105
|
+
// Force notification flags to allow updates
|
|
106
|
+
notification.flags = notification.flags or android.app.Notification.FLAG_ONGOING_EVENT
|
|
107
|
+
|
|
108
|
+
notificationManager.notify(intId, notification)
|
|
109
|
+
Log.d(TAG, "Notification updated successfully")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun stopLiveUpdate(notificationId: String) {
|
|
113
|
+
Log.d(TAG, "stopLiveUpdate called with notificationId=$notificationId")
|
|
114
|
+
activeNotifications.remove(notificationId)?.let { intId ->
|
|
115
|
+
notificationManager.cancel(intId)
|
|
116
|
+
Log.d(TAG, "Notification cancelled")
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
fun isLiveUpdateActive(updateName: String): Boolean = activeNotifications.containsKey(updateName)
|
|
121
|
+
|
|
122
|
+
fun endAllLiveUpdates() {
|
|
123
|
+
Log.d(TAG, "endAllLiveUpdates called")
|
|
124
|
+
activeNotifications.forEach { (_, intId) ->
|
|
125
|
+
notificationManager.cancel(intId)
|
|
126
|
+
}
|
|
127
|
+
activeNotifications.clear()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private fun createNotificationChannel(channelId: String) {
|
|
131
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
132
|
+
val channel =
|
|
133
|
+
NotificationChannel(
|
|
134
|
+
channelId,
|
|
135
|
+
"Voltra Live Updates",
|
|
136
|
+
NotificationManager.IMPORTANCE_DEFAULT,
|
|
137
|
+
).apply {
|
|
138
|
+
description = "Live update notifications from Voltra"
|
|
139
|
+
}
|
|
140
|
+
notificationManager.createNotificationChannel(channel)
|
|
141
|
+
Log.d(TAG, "Notification channel created: $channelId")
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private fun getSmallIcon(iconName: String?): Int {
|
|
146
|
+
if (iconName != null) {
|
|
147
|
+
val resId =
|
|
148
|
+
context.resources.getIdentifier(
|
|
149
|
+
iconName,
|
|
150
|
+
"drawable",
|
|
151
|
+
context.packageName,
|
|
152
|
+
)
|
|
153
|
+
if (resId != 0) return resId
|
|
154
|
+
}
|
|
155
|
+
return context.applicationInfo.icon
|
|
156
|
+
}
|
|
157
|
+
}
|