@@ -20,17 +20,26 @@ import { clamp } from './utils';
2020let LottieProperty : typeof com . airbnb . lottie . LottieProperty ;
2121let LottieKeyPath : typeof com . airbnb . lottie . model . KeyPath ;
2222let LottieValueCallback : typeof com . airbnb . lottie . value . LottieValueCallback ;
23+ let LottieCompositionFactory : typeof com . airbnb . lottie . LottieCompositionFactory ;
2324
2425const cache = new Map ( ) ;
25- function loadLottieJSON ( iconSrc ) {
26+ async function loadLottieJSON ( iconSrc ) {
2627 if ( ! cache . has ( iconSrc ) ) {
2728 const file = File . fromPath ( iconSrc ) ;
28- return file . readText ( ) . then ( ( r ) => {
29- cache . set ( iconSrc , r ) ;
30- return r ;
31- } ) ;
29+ const r = await file . readText ( ) ;
30+ cache . set ( iconSrc , r ) ;
31+ return r ;
3232 }
33- return Promise . resolve ( cache . get ( iconSrc ) ) ;
33+ return cache . get ( iconSrc ) ;
34+ }
35+ function loadLottieJSONSync ( iconSrc ) {
36+ if ( ! cache . has ( iconSrc ) ) {
37+ const file = File . fromPath ( iconSrc ) ;
38+ const r = file . readTextSync ( ) ;
39+ cache . set ( iconSrc , r ) ;
40+ return r ;
41+ }
42+ return cache . get ( iconSrc ) ;
3443}
3544
3645export const RenderMode = {
@@ -52,7 +61,8 @@ export class LottieView extends LottieViewBase {
5261 return new com . nativescript . lottie . LottieAnimationView ( this . _context ) ;
5362 }
5463
55- animatorListener ;
64+ animatorListener : android . animation . Animator . AnimatorListener ;
65+ loadedListener : com . airbnb . lottie . LottieOnCompositionLoadedListener ;
5666 _completionBlock ;
5767 //@ts -ignore
5868 get completionBlock ( ) {
@@ -95,58 +105,104 @@ export class LottieView extends LottieViewBase {
95105 if ( this . animatorListener ) {
96106 this . nativeViewProtected . addAnimatorListener ( this . animatorListener ) ;
97107 }
98- // if (this.src) {
99- // this[srcProperty.setNative](this.src);
100- // }
101-
102- // if (this.loop) {
103- // this.nativeView.loop(this.loop);
104- // }
108+ if ( ! this . loadedListener ) {
109+ this . loadedListener = new com . airbnb . lottie . LottieOnCompositionLoadedListener ( {
110+ onCompositionLoaded : ( composition ) => {
111+ this . notify ( { eventName : 'compositionLoaded' , composition } ) ;
112+ }
113+ } ) ;
114+ }
115+ this . nativeViewProtected . addLottieOnCompositionLoadedListener ( this . loadedListener ) ;
105116
106- // if (this.autoPlay) {
107- // this.playAnimation();
108- // }
109117 }
110118
111119 public disposeNativeView ( ) : void {
112120 if ( this . animatorListener ) {
113121 this . nativeViewProtected . removeAnimatorListener ( this . animatorListener ) ;
114122 }
123+ if ( this . loadedListener ) {
124+ this . nativeViewProtected . removeLottieOnCompositionLoadedListener ( this . loadedListener ) ;
125+ }
115126 super . disposeNativeView ( ) ;
116127 }
117128
118129 [ srcProperty . setNative ] ( src : string ) {
119- const view = this . nativeViewProtected ;
120- if ( ! src ) {
121- // lottie does not support "clearing the animation"
122- // view.setAnimation(null);
123- } else if ( src [ 0 ] === '{' ) {
124- view . setAnimationFromJson ( src , null ) ;
125- } else if ( src . startsWith ( Utils . RESOURCE_PREFIX ) ) {
126- const resName = src . replace ( Utils . RESOURCE_PREFIX , '' ) ;
127- view . setAnimation ( resName ) ;
128- } else {
129- if ( ! / .( j s o n | z i p | l o t t i e ) $ / . test ( src ) ) {
130- src += '.json' ;
130+ try {
131+ if ( LottieCompositionFactory ) {
132+ LottieCompositionFactory = com . airbnb . lottie . LottieCompositionFactory ;
131133 }
132- if ( src [ 0 ] === '~' ) {
133- this . nativeView . setAnimation ( 'app/' + src . substring ( 2 ) ) ;
134- } else if ( ! src . startsWith ( 'file:/' ) && src [ 0 ] !== '/' ) {
135- this . nativeView . setAnimation ( src ) ;
134+ const view = this . nativeViewProtected ;
135+ let result : com . airbnb . lottie . LottieResult < com . airbnb . lottie . LottieComposition > ;
136+ if ( ! src ) {
137+ // lottie does not support "clearing the animation"
138+ // view.setAnimation(null);
139+ } else if ( src [ 0 ] === '{' ) {
140+ if ( this . async ) {
141+ view . setAnimationFromJson ( src , null ) ;
142+ } else {
143+ result = LottieCompositionFactory . fromJsonStringSync ( this . _context , src ) ;
144+ }
145+ } else if ( src . startsWith ( Utils . RESOURCE_PREFIX ) ) {
146+ const resName = src . replace ( Utils . RESOURCE_PREFIX , '' ) ;
147+ if ( this . async ) {
148+ view . setAnimation ( resName ) ;
149+ } else {
150+ result = com . airbnb . lottie . LottieCompositionFactory . fromAssetSync ( this . _context , resName ) ;
151+ }
136152 } else {
137- loadLottieJSON ( src ) . then ( ( r ) => {
138- this . nativeView . setAnimationFromJson ( r , null ) ;
139- } ) ;
153+ if ( ! / .( j s o n | z i p | l o t t i e ) $ / . test ( src ) ) {
154+ src += '.json' ;
155+ }
156+ if ( src [ 0 ] === '~' ) {
157+ if ( this . async ) {
158+ view . setAnimation ( 'app/' + src . substring ( 2 ) ) ;
159+ } else {
160+ result = com . airbnb . lottie . LottieCompositionFactory . fromAssetSync (
161+ this . _context ,
162+ 'app/' + src . substring ( 2 )
163+ ) ;
164+ }
165+ } else if ( ! src . startsWith ( 'file:/' ) && src [ 0 ] !== '/' ) {
166+ if ( this . async ) {
167+ view . setAnimation ( 'app/' + src ) ;
168+ } else {
169+ result = com . airbnb . lottie . LottieCompositionFactory . fromAssetSync ( this . _context , src ) ;
170+ }
171+ } else {
172+ if ( this . async ) {
173+ loadLottieJSON ( src ) . then ( ( result ) => {
174+ if ( this . nativeViewProtected ) {
175+ this . nativeViewProtected . setAnimationFromJson ( result , null ) ;
176+ }
177+ } ) ;
178+ } else {
179+ result = LottieCompositionFactory . fromJsonStringSync ( this . _context , loadLottieJSONSync ( src ) ) ;
180+ }
181+ }
140182 }
141- }
142-
143- if ( this . autoPlay ) {
144- this . playAnimation ( ) ;
183+ if ( result ) {
184+ if ( result . getException ( ) ) {
185+ console . error ( result . getException ( ) ) ;
186+ // view.setComposition(null);
187+ } else {
188+ view . setComposition ( result . getValue ( ) ) ;
189+ //in sync loading we need to fire it ourselves
190+ // if we dont differ it from now it wont be received
191+ setTimeout ( ( ) => {
192+ this . notify ( { eventName : 'compositionLoaded' , composition : result . getValue ( ) } ) ;
193+ } , 0 ) ;
194+ }
195+ }
196+ if ( this . autoPlay ) {
197+ this . playAnimation ( ) ;
198+ }
199+ } catch ( error ) {
200+ console . error ( error ) ;
145201 }
146202 }
147203
148204 [ loopProperty . setNative ] ( loop : boolean ) {
149- this . nativeViewProtected . loop ( loop ) ;
205+ this . nativeViewProtected . setRepeatCount ( loop ? - 1 /* android.animation.ValueAnimator.INFINITE */ : 0 ) ;
150206 }
151207 [ renderModeProperty . setNative ] ( renderMode ) {
152208 this . nativeViewProtected . setRenderMode ( renderMode ) ;
@@ -205,11 +261,6 @@ export class LottieView extends LottieViewBase {
205261 // LottieProperty.COLOR,
206262 // new LottieValueCallback(java.lang.Integer.valueOf(value.android))
207263 // );
208- nativeView . addValueCallback (
209- new LottieKeyPath ( nativeKeyPath as any ) ,
210- LottieProperty . COLOR ,
211- new LottieValueCallback ( java . lang . Integer . valueOf ( value . android ) )
212- ) ;
213264 }
214265 }
215266
0 commit comments