@octane-xplat/lottie 0.0.1 → 0.9.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.
Files changed (58) hide show
  1. package/README.md +36 -2
  2. package/dist/native/cx.mobile.js +11 -0
  3. package/dist/native/escape-props.js +39 -0
  4. package/dist/native/index.js +182 -0
  5. package/dist/native/layout-child.js +38 -0
  6. package/dist/native/octane-client-build.json +8 -0
  7. package/dist/native/vendor/ui-lottie/index.android.js +286 -0
  8. package/dist/native/vendor/ui-lottie/index.ios.js +214 -0
  9. package/dist/native/vendor/ui-lottie/src/lottie/index.common.js +50 -0
  10. package/dist/native/vendor/ui-lottie/src/lottie/utils.js +6 -0
  11. package/dist/web/escape-props.web.js +17 -0
  12. package/dist/web/index.js +332 -0
  13. package/dist/web/layout-child.web.js +47 -0
  14. package/dist/web/octane-client-build.json +8 -0
  15. package/package.json +81 -10
  16. package/platforms/android/include.gradle +7 -0
  17. package/platforms/android/java/com/nativescript/lottie/LottieAnimationView.java +92 -0
  18. package/platforms/android/lottie.aar +0 -0
  19. package/platforms/android/native-api-usage.json +16 -0
  20. package/platforms/ios/Podfile +5 -0
  21. package/src/Lottie.tsrx +161 -0
  22. package/src/Lottie.web.tsrx +135 -0
  23. package/src/cx.mobile.ts +8 -0
  24. package/src/escape-props.ts +65 -0
  25. package/src/escape-props.web.ts +25 -0
  26. package/src/index.ts +2 -0
  27. package/src/index.web.ts +2 -0
  28. package/src/layout-child.ts +57 -0
  29. package/src/layout-child.web.ts +108 -0
  30. package/src/native-elements.d.ts +8 -0
  31. package/src/props.ts +128 -0
  32. package/src/references.d.ts +3 -0
  33. package/src/vendor/ui-lottie/LICENSE.md +21 -0
  34. package/src/vendor/ui-lottie/src/lottie/index.android.ts +447 -0
  35. package/src/vendor/ui-lottie/src/lottie/index.common.ts +84 -0
  36. package/src/vendor/ui-lottie/src/lottie/index.d.ts +133 -0
  37. package/src/vendor/ui-lottie/src/lottie/index.ios.ts +345 -0
  38. package/src/vendor/ui-lottie/src/lottie/typings/android.d.ts +4149 -0
  39. package/src/vendor/ui-lottie/src/lottie/typings/android.nativescript.d.ts +12 -0
  40. package/src/vendor/ui-lottie/src/lottie/typings/dotlottie.ios.d.ts +14 -0
  41. package/src/vendor/ui-lottie/src/lottie/typings/ios.d.ts +384 -0
  42. package/src/vendor/ui-lottie/src/lottie/utils.ts +9 -0
  43. package/types/generated/.tsrx-typegen-manifest.json +18 -0
  44. package/types/generated/Lottie.d.ts +7 -0
  45. package/types/generated/Lottie.web.d.ts +7 -0
  46. package/types/generated/cx.mobile.d.ts +6 -0
  47. package/types/generated/escape-props.d.ts +15 -0
  48. package/types/generated/escape-props.web.d.ts +5 -0
  49. package/types/generated/index.d.ts +2 -0
  50. package/types/generated/index.web.d.ts +2 -0
  51. package/types/generated/layout-child.d.ts +6 -0
  52. package/types/generated/layout-child.web.d.ts +15 -0
  53. package/types/generated/props.d.ts +106 -0
  54. package/types/generated/vendor/ui-lottie/src/lottie/index.common.d.ts +30 -0
  55. package/types/generated/vendor/ui-lottie/src/lottie/index.ios.d.ts +35 -0
  56. package/types/generated/vendor/ui-lottie/src/lottie/utils.d.ts +1 -0
  57. package/index.d.ts +0 -1
  58. package/index.js +0 -2
package/README.md CHANGED
@@ -1,3 +1,37 @@
1
- # @octane-xplat/lottie
1
+ # `@octane-xplat/lottie`
2
2
 
3
- Version 0.0.1 is a reservation stub so the automated release can publish this package name. It has no supported API. Use a later release for the implementation.
3
+ Lottie animations for Octane xplat apps: `lottie-web`'s svg renderer on
4
+ web and a vendored fork of `@nativescript-community/ui-lottie` on native
5
+ (`src/vendor/ui-lottie` submodule — the leaf _is_ the plugin via
6
+ `nativescript.platforms`, so no separate plugin install).
7
+
8
+ ```sh
9
+ pnpm add @octane-xplat/lottie
10
+ ```
11
+
12
+ ```tsx
13
+ import { Lottie } from '@octane-xplat/lottie'
14
+
15
+ ;<Lottie
16
+ src="https://example.com/anim.json" // native also takes ~/, res://, .lottie/.zip, or raw JSON
17
+ autoPlay // default true
18
+ loop // default false — a finite play is the shared contract
19
+ fit="contain" // 'contain' | 'cover' | 'fill'
20
+ onLoaded={(e) => console.log(e.duration)}
21
+ onEnded={() => console.log('done')}
22
+ bind={(h) => (handle = h)} // play/pause/stop/seekTo(0..1)/setSpeed + .native
23
+ />
24
+ ```
25
+
26
+ `data` (an inline animation object) wins over `src` when both are given.
27
+ Controlled `playing`/`progress`/`speed` props are optional — unset, the
28
+ animation is uncontrolled and the `bind` handle still drives it. Progress
29
+ is always normalized 0..1 and durations are milliseconds on every target
30
+ (the iOS plugin natively reports seconds; the leaf normalizes).
31
+
32
+ Per-target limits — including the expression/CSP boundary on web — are
33
+ recorded in [known limits](../../docs/known-limits.md). Exercised by
34
+ [`LottieDemo`](../demos/src/LottieDemo.tsrx).
35
+
36
+ This is a git submodule checkout: after cloning run
37
+ `git submodule update --init` before building the workspace.
@@ -0,0 +1,11 @@
1
+ //#region src/cx.mobile.ts
2
+ /** NS `className` splits on ' ' only, and the universal driver applies the
3
+ * prop via `String(value)` — an array would arrive comma-joined and match
4
+ * no class at all. Native leaves normalize through cx() before handing
5
+ * className to an intrinsic. (The DOM renderer already flattens arrays,
6
+ * so web leaves don't need this.) */
7
+ function cx(...parts) {
8
+ return parts.flat(Infinity).filter(Boolean).join(" ");
9
+ }
10
+ //#endregion
11
+ export { cx };
@@ -0,0 +1,39 @@
1
+ import { isAndroid, isIOS } from "@nativescript/core";
2
+ //#region src/escape-props.ts
3
+ /** Apply only the active device's escape bag after the primitive's own props. */
4
+ function applyEscapeProps(view, props) {
5
+ if (!view) return;
6
+ const bag = isIOS ? props.ios : isAndroid ? props.android : void 0;
7
+ if (bag) Object.assign(view, bag);
8
+ }
9
+ var NATIVE_ACCESSIBILITY_ROLES = {
10
+ button: "button",
11
+ link: "link",
12
+ search: "search",
13
+ image: "image",
14
+ heading: "header",
15
+ adjustable: "adjustable",
16
+ summary: "summary",
17
+ text: "text",
18
+ none: "none",
19
+ progressbar: "progressBar",
20
+ checkbox: "checkbox",
21
+ switch: "switch",
22
+ radio: "radioButton",
23
+ spinbutton: "spinButton",
24
+ tab: "button"
25
+ };
26
+ /** Translate the shared/ARIA spelling to NativeScript's narrower role enum. */
27
+ function nativeAccessibilityRole(role) {
28
+ return role ? NATIVE_ACCESSIBILITY_ROLES[role] : void 0;
29
+ }
30
+ /** NativeScript's AccessibilityState is a single enum value, unlike the
31
+ * web's independent ARIA booleans. Priority follows the strongest state. */
32
+ function nativeAccessibilityState(state) {
33
+ if (state?.disabled) return "disabled";
34
+ if (state?.selected) return "selected";
35
+ if (state?.checked === true) return "checked";
36
+ if (state?.checked === false) return "unchecked";
37
+ }
38
+ //#endregion
39
+ export { applyEscapeProps, nativeAccessibilityRole, nativeAccessibilityState };
@@ -0,0 +1,182 @@
1
+ import { cx } from "./cx.mobile.js";
2
+ import { applyEscapeProps, nativeAccessibilityRole, nativeAccessibilityState } from "./escape-props.js";
3
+ import { layoutChildProps } from "./layout-child.js";
4
+ import { defineUniversalComponent, hookSlots, registerElement, universalPlan, universalProps, universalValue, useCallback, useEffect, useRef } from "@nativescript-community/octane";
5
+ import { isAndroid } from "@nativescript/core";
6
+ import { LottieView } from "./vendor/ui-lottie";
7
+ //#region src/Lottie.tsrx
8
+ var _hs$ = /* @__PURE__ */ hookSlots(9);
9
+ var _h$0 = /* @__PURE__ */ Symbol(_hs$);
10
+ var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
11
+ var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
12
+ var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
13
+ var _h$4 = /* @__PURE__ */ Symbol(_hs$ + 4);
14
+ var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
15
+ var _h$6 = /* @__PURE__ */ Symbol(_hs$ + 6);
16
+ var _h$7 = /* @__PURE__ */ Symbol(_hs$ + 7);
17
+ var _h$8 = /* @__PURE__ */ Symbol(_hs$ + 8);
18
+ var __octaneUniversalPlan0 = universalPlan("nativescript", {
19
+ "kind": "host",
20
+ "type": "xplatlottie",
21
+ "propsSlot": 0
22
+ });
23
+ registerElement("xplatlottie", LottieView);
24
+ var clamp01 = (n) => Math.min(1, Math.max(0, n));
25
+ var STRETCH = {
26
+ contain: "aspectFit",
27
+ cover: "aspectFill",
28
+ fill: "fill"
29
+ };
30
+ function durationMs(v) {
31
+ const d = v.duration ?? 0;
32
+ return isAndroid ? d : Math.max(0, d) * 1e3;
33
+ }
34
+ function currentProgress(v) {
35
+ const nv = v.nativeViewProtected;
36
+ return isAndroid ? nv?.getProgress?.() ?? 0 : nv?.currentProgress ?? 0;
37
+ }
38
+ function stopView(v) {
39
+ if (isAndroid) v.cancelAnimation();
40
+ else v.nativeViewProtected?.stop();
41
+ v.progress = 0;
42
+ }
43
+ var Lottie = defineUniversalComponent("nativescript", function Lottie(props) {
44
+ const host = useRef(null, _h$0);
45
+ const appliedSrc = useRef(void 0, _h$1);
46
+ const loadedRef = useRef(false, _h$2);
47
+ const bindHost = useCallback((v) => {
48
+ host.current = v;
49
+ }, [], _h$3);
50
+ const wantPlay = () => props.playing ?? props.autoPlay ?? true;
51
+ const onReady = () => {
52
+ const v = host.current;
53
+ if (!v || loadedRef.current) return;
54
+ loadedRef.current = true;
55
+ if (props.speed !== void 0) v.speed = props.speed;
56
+ if (props.progress !== void 0) v.progress = clamp01(props.progress);
57
+ props.onLoaded?.({ duration: durationMs(v) });
58
+ if (wantPlay() && !v.isAnimating()) v.playAnimation();
59
+ };
60
+ useEffect(() => {
61
+ const v = host.current;
62
+ if (!v) return;
63
+ applyEscapeProps(v, props);
64
+ v.stretch = STRETCH[props.fit ?? "contain"];
65
+ v.async = true;
66
+ v.on(LottieView.compositionLoadedEvent, () => onReady());
67
+ v.on(LottieView.loadFailedEvent, (e) => {
68
+ loadedRef.current = false;
69
+ props.onError?.({ message: e?.error ? String(e.error) : "load failed" });
70
+ });
71
+ v.completionBlock = (finished) => {
72
+ if (finished) props.onEnded?.();
73
+ };
74
+ props.bind?.(handle(v));
75
+ }, [], _h$4);
76
+ useEffect(() => {
77
+ const v = host.current;
78
+ if (!v) return;
79
+ const src = props.data ? JSON.stringify(props.data) : props.src;
80
+ if (src === appliedSrc.current) return;
81
+ appliedSrc.current = src;
82
+ loadedRef.current = false;
83
+ v.src = src ?? "";
84
+ }, [props.src, props.data], _h$5);
85
+ useEffect(() => {
86
+ const v = host.current;
87
+ if (!v || props.playing === void 0) return;
88
+ if (props.playing) {
89
+ if (loadedRef.current) v.resumeAnimation();
90
+ } else v.pauseAnimation();
91
+ }, [props.playing], _h$6);
92
+ useEffect(() => {
93
+ const v = host.current;
94
+ if (!v || props.progress === void 0 || !loadedRef.current) return;
95
+ v.progress = clamp01(props.progress);
96
+ }, [props.progress], _h$7);
97
+ useEffect(() => {
98
+ const v = host.current;
99
+ if (!v || props.speed === void 0 || !loadedRef.current) return;
100
+ v.speed = props.speed;
101
+ }, [props.speed], _h$8);
102
+ const handle = (v) => ({
103
+ play: () => v.resumeAnimation(),
104
+ pause: () => v.pauseAnimation(),
105
+ stop: () => stopView(v),
106
+ seekTo: (p) => {
107
+ v.progress = clamp01(p);
108
+ },
109
+ setSpeed: (n) => {
110
+ v.speed = n;
111
+ },
112
+ progress: () => currentProgress(v),
113
+ duration: () => durationMs(v),
114
+ isPlaying: () => v.isAnimating(),
115
+ native: v
116
+ });
117
+ return universalValue(__octaneUniversalPlan0, [universalProps([
118
+ [
119
+ "set",
120
+ "ref",
121
+ bindHost
122
+ ],
123
+ [
124
+ "set",
125
+ "id",
126
+ props.id
127
+ ],
128
+ [
129
+ "set",
130
+ "className",
131
+ cx(props.className)
132
+ ],
133
+ [
134
+ "set",
135
+ "style",
136
+ props.style
137
+ ],
138
+ ["spread", layoutChildProps(props)],
139
+ [
140
+ "set",
141
+ "loop",
142
+ props.loop ?? false
143
+ ],
144
+ [
145
+ "set",
146
+ "accessible",
147
+ props.accessible
148
+ ],
149
+ [
150
+ "set",
151
+ "accessibilityLabel",
152
+ props.accessibilityLabel
153
+ ],
154
+ [
155
+ "set",
156
+ "accessibilityRole",
157
+ nativeAccessibilityRole(props.accessibilityRole)
158
+ ],
159
+ [
160
+ "set",
161
+ "accessibilityHint",
162
+ props.accessibilityHint
163
+ ],
164
+ [
165
+ "set",
166
+ "accessibilityValue",
167
+ props.accessibilityValue
168
+ ],
169
+ [
170
+ "set",
171
+ "accessibilityState",
172
+ nativeAccessibilityState(props.accessibilityState)
173
+ ],
174
+ [
175
+ "set",
176
+ "accessibilityLiveRegion",
177
+ props.accessibilityLiveRegion
178
+ ]
179
+ ])]);
180
+ }, { "module": "@nativescript-community/octane" });
181
+ //#endregion
182
+ export { Lottie };
@@ -0,0 +1,38 @@
1
+ //#region src/layout-child.ts
2
+ var FLEX_JUSTIFY = {
3
+ start: "flex-start",
4
+ end: "flex-end"
5
+ };
6
+ var FLEX_ALIGN = {
7
+ start: "flex-start",
8
+ end: "flex-end"
9
+ };
10
+ /** NativeScript reads these attributes from each child view during parent
11
+ * layout. Values are forwarded with NativeScript's own property names.
12
+ * The flex-container props (justifyContent/alignItems/flexWrap/gap) land on
13
+ * the host flexboxlayout itself — its own attributes, not child metadata. */
14
+ function layoutChildProps(props) {
15
+ const result = {};
16
+ for (const key of [
17
+ "row",
18
+ "col",
19
+ "rowSpan",
20
+ "colSpan",
21
+ "dock",
22
+ "left",
23
+ "top",
24
+ "flexGrow",
25
+ "flexShrink",
26
+ "alignSelf",
27
+ "order"
28
+ ]) if (props[key] !== void 0) result[key] = props[key];
29
+ if (props.justifyContent !== void 0) result.justifyContent = FLEX_JUSTIFY[props.justifyContent] ?? props.justifyContent;
30
+ if (props.alignItems !== void 0) result.alignItems = FLEX_ALIGN[props.alignItems] ?? props.alignItems;
31
+ if (props.flexWrap !== void 0) result.flexWrap = props.flexWrap === true ? "wrap" : props.flexWrap === false ? "nowrap" : props.flexWrap;
32
+ if (props.gap !== void 0) result.gap = props.gap;
33
+ if (props.rowGap !== void 0) result.rowGap = props.rowGap;
34
+ if (props.columnGap !== void 0) result.columnGap = props.columnGap;
35
+ return result;
36
+ }
37
+ //#endregion
38
+ export { layoutChildProps };
@@ -0,0 +1,8 @@
1
+ {
2
+ "version": 1,
3
+ "buildId": "30f71fe7-beba-4828-bcbe-70b0445dae09",
4
+ "mode": "production",
5
+ "capabilities": {
6
+ "independentHydration": false
7
+ }
8
+ }
@@ -0,0 +1,286 @@
1
+ import { LottieViewBase, autoPlayProperty, keyPathColorsProperty, loopProperty, progressProperty, renderModeProperty, srcProperty, stretchProperty } from "./src/lottie/index.common.js";
2
+ import { clamp } from "./src/lottie/utils.js";
3
+ import { Color, File, Http, Utils, knownFolders, path } from "@nativescript/core";
4
+ //#region src/vendor/ui-lottie/src/lottie/index.android.ts
5
+ /**********************************************************************************
6
+ * (c) 2017, Brad Martin.
7
+ * Licensed under the MIT license.
8
+ *
9
+ * Version 1.0.0 bradwaynemartin@gmail.com
10
+ **********************************************************************************/
11
+ var LottieProperty;
12
+ var LottieKeyPath;
13
+ var LottieValueCallback;
14
+ var LottieCompositionFactory;
15
+ var cache = /* @__PURE__ */ new Map();
16
+ async function loadLottieJSON(iconSrc) {
17
+ if (!cache.has(iconSrc)) {
18
+ const r = await File.fromPath(iconSrc).readText();
19
+ cache.set(iconSrc, r);
20
+ return r;
21
+ }
22
+ return cache.get(iconSrc);
23
+ }
24
+ function loadLottieJSONSync(iconSrc) {
25
+ if (!cache.has(iconSrc)) {
26
+ const r = File.fromPath(iconSrc).readTextSync();
27
+ cache.set(iconSrc, r);
28
+ return r;
29
+ }
30
+ return cache.get(iconSrc);
31
+ }
32
+ var RenderMode = {
33
+ get AUTOMATIC() {
34
+ return com.airbnb.lottie.RenderMode.AUTOMATIC;
35
+ },
36
+ get HARDWARE() {
37
+ return com.airbnb.lottie.RenderMode.HARDWARE;
38
+ },
39
+ get SOFTWARE() {
40
+ return com.airbnb.lottie.RenderMode.SOFTWARE;
41
+ }
42
+ };
43
+ var LottieView = class extends LottieViewBase {
44
+ constructor(..._args) {
45
+ super(..._args);
46
+ this._cancelled = false;
47
+ }
48
+ createNativeView() {
49
+ return new com.nativescript.lottie.LottieAnimationView(this._context);
50
+ }
51
+ get completionBlock() {
52
+ return this._completionBlock;
53
+ }
54
+ set completionBlock(block) {
55
+ this._completionBlock = block;
56
+ if (block) {
57
+ if (!this.animatorListener) {
58
+ const that = new WeakRef(this);
59
+ this.animatorListener = new android.animation.Animator.AnimatorListener({
60
+ onAnimationCancel: (_animator) => {
61
+ const owner = that?.get();
62
+ if (owner) owner._cancelled = true;
63
+ },
64
+ onAnimationEnd: (_animator) => {
65
+ const owner = that?.get();
66
+ if (owner?._completionBlock) owner._completionBlock(!owner._cancelled);
67
+ if (owner) owner._cancelled = false;
68
+ },
69
+ onAnimationRepeat: (_animator) => {},
70
+ onAnimationStart: (_animator) => {}
71
+ });
72
+ if (this.nativeViewProtected) this.nativeViewProtected.addAnimatorListener(this.animatorListener);
73
+ }
74
+ } else if (this.animatorListener) {
75
+ if (this.nativeViewProtected) this.nativeViewProtected.removeAnimatorListener(this.animatorListener);
76
+ this.animatorListener = null;
77
+ }
78
+ }
79
+ initNativeView() {
80
+ if (this.animatorListener) this.nativeViewProtected.addAnimatorListener(this.animatorListener);
81
+ if (!this.loadedListener) {
82
+ const that = new WeakRef(this);
83
+ this.loadedListener = new com.airbnb.lottie.LottieOnCompositionLoadedListener({ onCompositionLoaded: (composition) => {
84
+ const owner = that?.get();
85
+ if (owner) setTimeout(() => {
86
+ owner.notify({
87
+ eventName: LottieViewBase.compositionLoadedEvent,
88
+ composition
89
+ });
90
+ if (owner.autoPlay && !owner.isAnimating()) owner.playAnimation();
91
+ }, 0);
92
+ } });
93
+ }
94
+ this.nativeViewProtected.addLottieOnCompositionLoadedListener(this.loadedListener);
95
+ const that = new WeakRef(this);
96
+ this.nativeViewProtected.setFailureListener(new com.airbnb.lottie.LottieListener({ onResult: (result) => {
97
+ const owner = that?.get();
98
+ if (owner) owner.notify({
99
+ eventName: LottieViewBase.loadFailedEvent,
100
+ error: result
101
+ });
102
+ } }));
103
+ }
104
+ disposeNativeView() {
105
+ if (this.animatorListener) this.nativeViewProtected.removeAnimatorListener(this.animatorListener);
106
+ if (this.loadedListener) this.nativeViewProtected.removeLottieOnCompositionLoadedListener(this.loadedListener);
107
+ super.disposeNativeView();
108
+ }
109
+ setColor(value, keyPath) {
110
+ const nativeView = this.nativeViewProtected;
111
+ if (nativeView && value && keyPath && keyPath.length) {
112
+ if (keyPath[keyPath.length - 1].toLowerCase() === "color") {
113
+ keyPath = [...keyPath];
114
+ keyPath.pop();
115
+ if (keyPath.length === 0) return;
116
+ }
117
+ const nativeKeyPath = Array.create(java.lang.String, keyPath.length);
118
+ for (let index = 0; index < keyPath.length; index++) nativeKeyPath[index] = keyPath[index];
119
+ if (!LottieProperty) LottieProperty = com.airbnb.lottie.LottieProperty;
120
+ if (!LottieValueCallback) LottieValueCallback = com.airbnb.lottie.value.LottieValueCallback;
121
+ if (!LottieKeyPath) LottieKeyPath = com.airbnb.lottie.model.KeyPath;
122
+ const color = value instanceof Color ? value : new Color(value);
123
+ const colorFilter = new com.airbnb.lottie.SimpleColorFilter(color.android);
124
+ nativeView.addValueCallback(new LottieKeyPath(nativeKeyPath), LottieProperty.COLOR_FILTER, new LottieValueCallback(colorFilter));
125
+ }
126
+ }
127
+ setOpacity(value, keyPath) {
128
+ if (this.nativeViewProtected && value != null && keyPath && keyPath.length) {
129
+ if (keyPath[keyPath.length - 1].toLowerCase() === "opacity") {
130
+ keyPath = [...keyPath];
131
+ keyPath.pop();
132
+ if (keyPath.length === 0) return;
133
+ }
134
+ const nativeKeyPath = Array.create(java.lang.String, keyPath.length);
135
+ keyPath.forEach((key, index) => {
136
+ nativeKeyPath[index] = new java.lang.String(key);
137
+ });
138
+ value = clamp(value);
139
+ if (!LottieProperty) LottieProperty = com.airbnb.lottie.LottieProperty;
140
+ if (!LottieValueCallback) LottieValueCallback = com.airbnb.lottie.value.LottieValueCallback;
141
+ if (!LottieKeyPath) LottieKeyPath = com.airbnb.lottie.model.KeyPath;
142
+ this.nativeViewProtected.addValueCallback(new LottieKeyPath(nativeKeyPath), LottieProperty.OPACITY, new LottieValueCallback(new java.lang.Integer(value * 255)));
143
+ }
144
+ }
145
+ playAnimation() {
146
+ if (this.nativeViewProtected) {
147
+ this.nativeViewProtected.setMinAndMaxProgress(0, 1);
148
+ this.nativeViewProtected.playAnimation();
149
+ }
150
+ }
151
+ playAnimationFromProgressToProgress(startProgress, endProgress) {
152
+ if (this.nativeViewProtected) {
153
+ startProgress = startProgress ? clamp(startProgress) : 0;
154
+ endProgress = endProgress ? clamp(endProgress) : 1;
155
+ this.nativeViewProtected.setMinAndMaxProgress(startProgress, endProgress);
156
+ this.nativeViewProtected.playAnimation();
157
+ }
158
+ }
159
+ isAnimating() {
160
+ return this.nativeViewProtected ? this.nativeViewProtected.isAnimating() : false;
161
+ }
162
+ get speed() {
163
+ return this.nativeViewProtected ? this.nativeViewProtected.getSpeed() : void 0;
164
+ }
165
+ set speed(value) {
166
+ if (this.nativeViewProtected && value) this.nativeViewProtected.setSpeed(value);
167
+ }
168
+ get duration() {
169
+ return this.nativeViewProtected ? this.nativeViewProtected.getDuration() : void 0;
170
+ }
171
+ cancelAnimation() {
172
+ if (this.nativeViewProtected) this.nativeViewProtected.cancelAnimation();
173
+ }
174
+ pauseAnimation() {
175
+ if (this.nativeViewProtected) this.nativeViewProtected.pauseAnimation();
176
+ }
177
+ resumeAnimation() {
178
+ if (this.nativeViewProtected) this.nativeViewProtected.resumeAnimation();
179
+ }
180
+ [srcProperty.setNative](src) {
181
+ try {
182
+ if (!LottieCompositionFactory) LottieCompositionFactory = com.airbnb.lottie.LottieCompositionFactory;
183
+ const view = this.nativeViewProtected;
184
+ let result;
185
+ if (!src) {} else if (src[0] === "{") {
186
+ if (this.async) view.setAnimationFromJson(src, null);
187
+ else result = LottieCompositionFactory.fromJsonStringSync(src, null);
188
+ } else if (/^https?:/i.test(src)) {
189
+ const match = /\.(zip|lottie|json)(?=[?#]|$)/i.exec(src);
190
+ const dest = path.join(knownFolders.temp().path, `lottie-${Date.now()}${match ? match[0].toLowerCase() : ".json"}`);
191
+ Http.getFile(src, dest).then(() => {
192
+ this.src = dest;
193
+ }).catch((error) => {
194
+ console.error(error);
195
+ this.notify({
196
+ eventName: "loadFailed",
197
+ error
198
+ });
199
+ });
200
+ } else if (src.startsWith(Utils.RESOURCE_PREFIX)) {
201
+ const resName = src.replace(Utils.RESOURCE_PREFIX, "");
202
+ if (this.async) view.setAnimation(resName);
203
+ else result = com.airbnb.lottie.LottieCompositionFactory.fromAssetSync(this._context, resName);
204
+ } else {
205
+ if (!/.(json|zip|lottie)$/.test(src)) src += ".json";
206
+ if (src[0] === "~") {
207
+ if (this.async) view.setAnimation("app/" + src.substring(2));
208
+ else result = com.airbnb.lottie.LottieCompositionFactory.fromAssetSync(this._context, "app/" + src.substring(2));
209
+ } else if (!src.startsWith("file:/") && src[0] !== "/") {
210
+ if (this.async) view.setAnimation("app/" + src);
211
+ else result = com.airbnb.lottie.LottieCompositionFactory.fromAssetSync(this._context, src);
212
+ } else {
213
+ const filePath = src.startsWith("file:") ? src.substring(5) : src;
214
+ if (/\.(zip|lottie)$/i.test(filePath)) {
215
+ const stream = new java.util.zip.ZipInputStream(new java.io.FileInputStream(filePath));
216
+ if (this.async) {
217
+ const owner = new WeakRef(this);
218
+ com.airbnb.lottie.LottieCompositionFactory.fromZipStream(stream, null).addListener(new com.airbnb.lottie.LottieListener({ onResult: (composition) => {
219
+ const view = owner.get()?.nativeViewProtected;
220
+ if (view) view.setComposition(composition);
221
+ } })).addFailureListener(new com.airbnb.lottie.LottieListener({ onResult: (error) => console.error(error) }));
222
+ } else result = com.airbnb.lottie.LottieCompositionFactory.fromZipStreamSync(stream, null);
223
+ } else if (this.async) loadLottieJSON(src).then((result) => {
224
+ if (this.nativeViewProtected) this.nativeViewProtected.setAnimationFromJson(result, null);
225
+ });
226
+ else result = LottieCompositionFactory.fromJsonStringSync(loadLottieJSONSync(src), null);
227
+ }
228
+ }
229
+ if (result) {
230
+ if (result.getException()) {
231
+ console.error(result.getException());
232
+ this.notify({
233
+ eventName: LottieViewBase.loadFailedEvent,
234
+ error: result.getException()
235
+ });
236
+ } else view.setComposition(result.getValue());
237
+ }
238
+ if (this.autoPlay) this.playAnimation();
239
+ } catch (error) {
240
+ console.error(error);
241
+ this.notify({
242
+ eventName: LottieViewBase.loadFailedEvent,
243
+ error
244
+ });
245
+ }
246
+ }
247
+ [loopProperty.setNative](loop) {
248
+ this.nativeViewProtected.setRepeatCount(loop ? -1 : 0);
249
+ }
250
+ [progressProperty.setNative](value) {
251
+ this.nativeViewProtected.setProgress(value);
252
+ }
253
+ [renderModeProperty.setNative](renderMode) {
254
+ this.nativeViewProtected.setRenderMode(renderMode);
255
+ }
256
+ [keyPathColorsProperty.setNative](value) {
257
+ Object.keys(value).forEach((k) => this.setColor(value[k], k.split("|")));
258
+ }
259
+ [autoPlayProperty.setNative](autoPlay) {
260
+ if (autoPlay) {
261
+ if (!this.isAnimating()) this.playAnimation();
262
+ } else {
263
+ this.cancelAnimation();
264
+ if (this.progress) this.nativeViewProtected.setProgress(this.progress);
265
+ }
266
+ }
267
+ [stretchProperty.getDefault]() {
268
+ return "aspectFit";
269
+ }
270
+ [stretchProperty.setNative](value) {
271
+ switch (value) {
272
+ case "aspectFit":
273
+ this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER);
274
+ break;
275
+ case "aspectFill":
276
+ this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
277
+ break;
278
+ case "fill":
279
+ this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
280
+ break;
281
+ default: this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.MATRIX);
282
+ }
283
+ }
284
+ };
285
+ //#endregion
286
+ export { LottieView, RenderMode };