react-native-firework-sdk 2.8.6 → 2.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.
- package/FireworkVideoUI.xcframework/Info.plist +5 -5
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +1 -1
- package/android/build.gradle +2 -1
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/components/base/FWLoading.kt +22 -0
- package/android/src/main/java/com/fireworksdk/bridge/components/storyblock/StoryBlockFragment.kt +240 -18
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +19 -9
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationDeserializer.kt +49 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationModel.kt +13 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationSerializer.kt +42 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoDeserializer.kt +21 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoModel.kt +6 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoSerializer.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationDeserializer.kt +33 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationModel.kt +10 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationSerializer.kt +25 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +7 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationSerializer.kt +13 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +3 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelSerializer.kt +2 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +3 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +7 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelSerializer.kt +4 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWErrorAction.kt +18 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWEventName.kt +3 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +50 -26
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +47 -8
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +0 -10
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +42 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +5 -3
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +24 -6
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +95 -0
- package/android/src/main/res/layout/fw_bridge_story_block.xml +6 -0
- package/android/src/main/res/layout/fw_loading.xml +14 -0
- package/ios/Components/VideoFeed.swift +1 -1
- package/ios/FireworkVideoUI/Podfile.lock +1 -1
- package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.h +20 -0
- package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.m +84 -0
- package/lib/commonjs/VideoShopping.js +1 -4
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +32 -42
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +29 -11
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/VideoFeedUtil.js +73 -0
- package/lib/commonjs/utils/VideoFeedUtil.js.map +1 -0
- package/lib/module/VideoShopping.js +1 -5
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +32 -40
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +28 -11
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/VideoFeedUtil.js +65 -0
- package/lib/module/utils/VideoFeedUtil.js.map +1 -0
- package/lib/typescript/VideoShopping.d.ts +0 -1
- package/lib/typescript/components/StoryBlock.d.ts +15 -4
- package/lib/typescript/components/VideoFeed.d.ts +12 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/models/ButtonInfo.d.ts +0 -1
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +3 -3
- package/lib/typescript/models/StoryBlockConfiguration.d.ts +0 -2
- package/lib/typescript/models/VideoPlayerButtonConfiguration.d.ts +0 -6
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +0 -2
- package/lib/typescript/utils/VideoFeedUtil.d.ts +10 -0
- package/package.json +1 -1
- package/src/VideoShopping.ts +1 -4
- package/src/components/StoryBlock.tsx +40 -44
- package/src/components/VideoFeed.tsx +32 -11
- package/src/index.ts +2 -0
- package/src/models/ButtonInfo.ts +0 -1
- package/src/models/ProductInfoViewConfiguration.ts +3 -3
- package/src/models/StoryBlockConfiguration.ts +0 -2
- package/src/models/VideoPlayerButtonConfiguration.ts +0 -6
- package/src/models/VideoPlayerConfiguration.ts +0 -2
- package/src/utils/VideoFeedUtil.ts +74 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWStatusBarUtil.kt +0 -28
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWStoryBlockUtil.kt +0 -30
|
@@ -9,7 +9,6 @@ import React, {
|
|
|
9
9
|
} from 'react';
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
-
BackHandler,
|
|
13
12
|
findNodeHandle,
|
|
14
13
|
NativeSyntheticEvent,
|
|
15
14
|
Platform,
|
|
@@ -43,6 +42,11 @@ export interface IStoryBlockMethods {
|
|
|
43
42
|
* Pause the story block.
|
|
44
43
|
*/
|
|
45
44
|
pause: () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Open the fullscreen story block.
|
|
47
|
+
* Only supported on Android.
|
|
48
|
+
*/
|
|
49
|
+
openFullscreen: () => void;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
/**
|
|
@@ -93,18 +97,25 @@ export interface IStoryBlockProps {
|
|
|
93
97
|
*/
|
|
94
98
|
cornerRadius?: number;
|
|
95
99
|
/**
|
|
96
|
-
* Ad configuration of the feed.
|
|
100
|
+
* Ad configuration of the feed.
|
|
97
101
|
*/
|
|
98
102
|
adConfiguration?: AdConfiguration;
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
* The configuration of the story block.
|
|
102
|
-
*/
|
|
104
|
+
/* The configuration of the story block. */
|
|
103
105
|
storyBlockConfiguration?: StoryBlockConfiguration;
|
|
104
106
|
/**
|
|
105
107
|
* The feed loading result callback. It means loading successfully when error equals to undefined.
|
|
106
108
|
*/
|
|
107
109
|
onStoryBlockLoadFinished?: (error?: FWError) => void;
|
|
110
|
+
/**
|
|
111
|
+
* The callback is triggered when there are no items in the story block.
|
|
112
|
+
* The callback is triggered in the following cases:
|
|
113
|
+
* 1. Loading successfully but the back end returns an empty list.
|
|
114
|
+
* 2. The load failed and list is empty.
|
|
115
|
+
* onStoryBlockLoadFinished will also be triggered when onStoryBlockEmpty is triggered.
|
|
116
|
+
* Only supported on Android.
|
|
117
|
+
*/
|
|
118
|
+
onStoryBlockEmpty?: (error?: FWError) => void;
|
|
108
119
|
/**
|
|
109
120
|
* Start Picture in Picture callback. Only supported on iOS.
|
|
110
121
|
*/
|
|
@@ -120,10 +131,10 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
120
131
|
IStoryBlockProps
|
|
121
132
|
> = (props: IStoryBlockProps, forwardedRef) => {
|
|
122
133
|
const nativeComponentRef = useRef(null);
|
|
123
|
-
const [isFullscreenState, setIsFullscreenState] = useState<boolean>(false);
|
|
124
134
|
const [sdkInitCalled, setSdkInitCalled] = useState<boolean>(
|
|
125
135
|
FWGlobalState.getInstance().sdkInitCalled
|
|
126
136
|
);
|
|
137
|
+
const loadedRef = useRef<boolean>(false);
|
|
127
138
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
128
139
|
|
|
129
140
|
const handleStoryBlockLoadFinished = (event: NativeSyntheticEvent<any>) => {
|
|
@@ -131,22 +142,37 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
131
142
|
`StoryBlock handleStoryBlockLoadFinished ${event.nativeEvent.name}`
|
|
132
143
|
);
|
|
133
144
|
|
|
134
|
-
const { onStoryBlockLoadFinished } = props;
|
|
145
|
+
const { onStoryBlockLoadFinished, onStoryBlockEmpty } = props;
|
|
135
146
|
const { name, reason } = event.nativeEvent;
|
|
136
147
|
|
|
137
148
|
if (onStoryBlockLoadFinished) {
|
|
138
149
|
if (name) {
|
|
150
|
+
let error: FWError = { name };
|
|
139
151
|
if (reason) {
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
152
|
+
error.reason = reason;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
onStoryBlockLoadFinished(error);
|
|
156
|
+
if (!loadedRef.current) {
|
|
157
|
+
onStoryBlockEmpty?.(error);
|
|
143
158
|
}
|
|
144
159
|
} else {
|
|
145
160
|
onStoryBlockLoadFinished();
|
|
161
|
+
loadedRef.current = true;
|
|
146
162
|
}
|
|
147
163
|
}
|
|
148
164
|
};
|
|
149
165
|
|
|
166
|
+
const handleStoryBlockEmpty = (event: NativeSyntheticEvent<any>) => {
|
|
167
|
+
FWLoggerUtil.log(`StoryBlock handleStoryBlockEmpty ${event.nativeEvent}`);
|
|
168
|
+
|
|
169
|
+
const { onStoryBlockEmpty } = props;
|
|
170
|
+
|
|
171
|
+
if (onStoryBlockEmpty) {
|
|
172
|
+
onStoryBlockEmpty();
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
150
176
|
const handleStoryBlockDidStartPictureInPicture = (
|
|
151
177
|
event: NativeSyntheticEvent<any>
|
|
152
178
|
) => {
|
|
@@ -197,16 +223,6 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
197
223
|
}
|
|
198
224
|
};
|
|
199
225
|
|
|
200
|
-
const handleStoryBlockFullScreenStateChanged = (
|
|
201
|
-
event: NativeSyntheticEvent<any>
|
|
202
|
-
) => {
|
|
203
|
-
FWLoggerUtil.log(
|
|
204
|
-
`StoryBlock handleStoryBlockFullScreenStateChanged ${event.nativeEvent.isFullScreen}`
|
|
205
|
-
);
|
|
206
|
-
const { isFullScreen } = event.nativeEvent;
|
|
207
|
-
setIsFullscreenState(isFullScreen);
|
|
208
|
-
};
|
|
209
|
-
|
|
210
226
|
const generateDynamicContentParametersString = (): string => {
|
|
211
227
|
const { dynamicContentParameters } = props;
|
|
212
228
|
|
|
@@ -412,6 +428,9 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
412
428
|
pause: () => {
|
|
413
429
|
sendCommand('pause');
|
|
414
430
|
},
|
|
431
|
+
openFullscreen: () => {
|
|
432
|
+
sendCommand('openFullscreen');
|
|
433
|
+
},
|
|
415
434
|
};
|
|
416
435
|
},
|
|
417
436
|
[]
|
|
@@ -495,27 +514,6 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
495
514
|
});
|
|
496
515
|
}, []);
|
|
497
516
|
|
|
498
|
-
useEffect(() => {
|
|
499
|
-
if (Platform.OS === 'android') {
|
|
500
|
-
const onBackPress = () => {
|
|
501
|
-
if (isFullscreenState) {
|
|
502
|
-
FireworkSDK.getInstance().navigator.popNativeContainer();
|
|
503
|
-
return true;
|
|
504
|
-
}
|
|
505
|
-
return false;
|
|
506
|
-
};
|
|
507
|
-
const subscription = BackHandler.addEventListener(
|
|
508
|
-
'hardwareBackPress',
|
|
509
|
-
onBackPress
|
|
510
|
-
);
|
|
511
|
-
return () => {
|
|
512
|
-
subscription.remove();
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return;
|
|
517
|
-
}, [isFullscreenState]);
|
|
518
|
-
|
|
519
517
|
if (!sdkInitCalled) {
|
|
520
518
|
return null;
|
|
521
519
|
}
|
|
@@ -530,15 +528,13 @@ const StoryBlock: ForwardRefRenderFunction<
|
|
|
530
528
|
storyBlockConfiguration={storyBlockConfiguration}
|
|
531
529
|
enablePictureInPicture={undefined}
|
|
532
530
|
onStoryBlockLoadFinished={handleStoryBlockLoadFinished}
|
|
531
|
+
onStoryBlockEmpty={handleStoryBlockEmpty}
|
|
533
532
|
onStoryBlockDidStartPictureInPicture={
|
|
534
533
|
handleStoryBlockDidStartPictureInPicture
|
|
535
534
|
}
|
|
536
535
|
onStoryBlockDidStopPictureInPicture={
|
|
537
536
|
handleStoryBlockDidStopPictureInPicture
|
|
538
537
|
}
|
|
539
|
-
onStoryBlockFullScreenStateChanged={
|
|
540
|
-
handleStoryBlockFullScreenStateChanged
|
|
541
|
-
}
|
|
542
538
|
/>
|
|
543
539
|
);
|
|
544
540
|
};
|
|
@@ -88,13 +88,22 @@ export interface IVideoFeedProps {
|
|
|
88
88
|
*/
|
|
89
89
|
videoPlayerConfiguration?: VideoPlayerConfiguration;
|
|
90
90
|
/**
|
|
91
|
-
* Ad configuration of the feed.
|
|
91
|
+
* Ad configuration of the feed.
|
|
92
92
|
*/
|
|
93
93
|
adConfiguration?: AdConfiguration;
|
|
94
94
|
/**
|
|
95
95
|
* The feed loading result callback. It means loading successfully when error equals to undefined.
|
|
96
96
|
*/
|
|
97
97
|
onVideoFeedLoadFinished?: (error?: FWError) => void;
|
|
98
|
+
/**
|
|
99
|
+
* The callback is triggered when there are no items in the story block.
|
|
100
|
+
* The callback is triggered in the following cases:
|
|
101
|
+
* 1. Loading successfully but the back end returns an empty list.
|
|
102
|
+
* 2. The load failed and list is empty.
|
|
103
|
+
* onVideoFeedLoadFinished will also be triggered when onVideoFeedEmpty is triggered.
|
|
104
|
+
* Only supported on Android.
|
|
105
|
+
*/
|
|
106
|
+
onVideoFeedEmpty?: (error?: FWError) => void;
|
|
98
107
|
/**
|
|
99
108
|
* Start Picture in Picture callback. Only supported on iOS.
|
|
100
109
|
*/
|
|
@@ -126,6 +135,8 @@ class VideoFeed extends React.Component<IVideoFeedProps, IVideoFeedState> {
|
|
|
126
135
|
|
|
127
136
|
private _subscriptions: EmitterSubscription[] = [];
|
|
128
137
|
|
|
138
|
+
private _loaded: boolean = false;
|
|
139
|
+
|
|
129
140
|
constructor(props: IVideoFeedProps) {
|
|
130
141
|
super(props);
|
|
131
142
|
this.state = {
|
|
@@ -155,23 +166,38 @@ class VideoFeed extends React.Component<IVideoFeedProps, IVideoFeedState> {
|
|
|
155
166
|
FWLoggerUtil.log(
|
|
156
167
|
`VideoFeed _onVideoFeedLoadFinished ${JSON.stringify(event.nativeEvent)}`
|
|
157
168
|
);
|
|
158
|
-
const { onVideoFeedLoadFinished } = this.props;
|
|
169
|
+
const { onVideoFeedLoadFinished, onVideoFeedEmpty } = this.props;
|
|
159
170
|
|
|
160
171
|
const { name, reason } = event.nativeEvent;
|
|
161
172
|
|
|
162
173
|
if (onVideoFeedLoadFinished) {
|
|
163
174
|
if (name) {
|
|
175
|
+
let error: FWError = { name };
|
|
164
176
|
if (reason) {
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
177
|
+
error.reason = reason;
|
|
178
|
+
}
|
|
179
|
+
onVideoFeedLoadFinished(error);
|
|
180
|
+
if (!this._loaded) {
|
|
181
|
+
onVideoFeedEmpty?.(error);
|
|
168
182
|
}
|
|
169
183
|
} else {
|
|
170
184
|
onVideoFeedLoadFinished();
|
|
185
|
+
this._loaded = true;
|
|
171
186
|
}
|
|
172
187
|
}
|
|
173
188
|
};
|
|
174
189
|
|
|
190
|
+
private _onVideoFeedEmpty = (event: NativeSyntheticEvent<any>) => {
|
|
191
|
+
FWLoggerUtil.log(
|
|
192
|
+
`VideoFeed _onVideoFeedLoadFinished ${JSON.stringify(event.nativeEvent)}`
|
|
193
|
+
);
|
|
194
|
+
const { onVideoFeedEmpty } = this.props;
|
|
195
|
+
|
|
196
|
+
if (onVideoFeedEmpty) {
|
|
197
|
+
onVideoFeedEmpty();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
175
201
|
private _onVideoFeedDidStartPictureInPicture = (
|
|
176
202
|
event: NativeSyntheticEvent<any>
|
|
177
203
|
) => {
|
|
@@ -296,12 +322,6 @@ class VideoFeed extends React.Component<IVideoFeedProps, IVideoFeedState> {
|
|
|
296
322
|
* @ignore
|
|
297
323
|
*/
|
|
298
324
|
render() {
|
|
299
|
-
FWLoggerUtil.log(
|
|
300
|
-
`VideoFeed render props ${JSON.stringify(
|
|
301
|
-
this.props
|
|
302
|
-
)} state ${JSON.stringify(this.state)}`
|
|
303
|
-
);
|
|
304
|
-
|
|
305
325
|
if (!this.state.sdkInitCalled) {
|
|
306
326
|
return null;
|
|
307
327
|
}
|
|
@@ -466,6 +486,7 @@ class VideoFeed extends React.Component<IVideoFeedProps, IVideoFeedState> {
|
|
|
466
486
|
videoPlayerConfiguration={videoPlayerConfiguration}
|
|
467
487
|
ref={this._nativeComponentRef}
|
|
468
488
|
onVideoFeedLoadFinished={this._onVideoFeedLoadFinished}
|
|
489
|
+
onVideoFeedEmpty={this._onVideoFeedEmpty}
|
|
469
490
|
onVideoFeedDidStartPictureInPicture={
|
|
470
491
|
this._onVideoFeedDidStartPictureInPicture
|
|
471
492
|
}
|
package/src/index.ts
CHANGED
|
@@ -101,6 +101,7 @@ import type {
|
|
|
101
101
|
VideoPlayerLogoOption,
|
|
102
102
|
} from './models/VideoPlayerLogoConfiguration';
|
|
103
103
|
import type { VideoPlayerStyle } from './models/VideoPlayerStyle';
|
|
104
|
+
import VideoFeedUtil from './utils/VideoFeedUtil';
|
|
104
105
|
import type {
|
|
105
106
|
CustomClickCartIconCallback,
|
|
106
107
|
CustomClickLinkButtonCallback,
|
|
@@ -189,6 +190,7 @@ export {
|
|
|
189
190
|
VideoFeedSource,
|
|
190
191
|
VideoFeedTitleConfiguration,
|
|
191
192
|
VideoFeedTitlePosition,
|
|
193
|
+
VideoFeedUtil,
|
|
192
194
|
VideoLaunchBehavior,
|
|
193
195
|
VideoPlaybackCallback,
|
|
194
196
|
VideoPlaybackDetails,
|
package/src/models/ButtonInfo.ts
CHANGED
|
@@ -140,7 +140,7 @@ export interface ProductCardConfiguration {
|
|
|
140
140
|
*/
|
|
141
141
|
ctaButtonStyle?: ProductCardCTAButtonStyle;
|
|
142
142
|
/**
|
|
143
|
-
*
|
|
143
|
+
* The price configuration of product card.
|
|
144
144
|
*/
|
|
145
145
|
priceConfiguration?: ProductCardPriceConfiguration;
|
|
146
146
|
/**
|
|
@@ -172,7 +172,7 @@ export interface ProductCardConfiguration {
|
|
|
172
172
|
|
|
173
173
|
export default interface ProductInfoViewConfiguration {
|
|
174
174
|
/**
|
|
175
|
-
* Configuration of shopping CTA button.
|
|
175
|
+
* Configuration of shopping CTA button.
|
|
176
176
|
*/
|
|
177
177
|
ctaButton?: ShoppingCTAButtonConfiguration;
|
|
178
178
|
/**
|
|
@@ -180,7 +180,7 @@ export default interface ProductInfoViewConfiguration {
|
|
|
180
180
|
*/
|
|
181
181
|
linkButton?: LinkButtonConfiguration;
|
|
182
182
|
/**
|
|
183
|
-
* Configuration of product card.
|
|
183
|
+
* Configuration of product card.
|
|
184
184
|
*/
|
|
185
185
|
productCard?: ProductCardConfiguration;
|
|
186
186
|
}
|
|
@@ -64,12 +64,10 @@ export interface StoryBlockConfiguration {
|
|
|
64
64
|
/**
|
|
65
65
|
* The host app could use this property to customize the button images of the video player.
|
|
66
66
|
* On iOS, the property only applies to full-screen story block but not to compact story block.
|
|
67
|
-
* Only supported on iOS.
|
|
68
67
|
*/
|
|
69
68
|
buttonConfiguration?: VideoPlayerButtonConfiguration;
|
|
70
69
|
/**
|
|
71
70
|
* Specifies if the title should be shown.
|
|
72
|
-
* Only supported on ios.
|
|
73
71
|
*/
|
|
74
72
|
showVideoDetailTitle?: boolean;
|
|
75
73
|
/**
|
|
@@ -4,37 +4,31 @@ export default interface VideoPlayerButtonConfiguration {
|
|
|
4
4
|
/**
|
|
5
5
|
* Specifies the video detail button info.
|
|
6
6
|
* Image will be drawn in a 40pt x 40pt frame.
|
|
7
|
-
* Only supported on iOS.
|
|
8
7
|
*/
|
|
9
8
|
videoDetailButton?: ButtonInfo;
|
|
10
9
|
/**
|
|
11
10
|
* Specifies the close button info.
|
|
12
11
|
* Image will be drawn in a 40pt x 40pt frame.
|
|
13
|
-
* Only supported on iOS.
|
|
14
12
|
*/
|
|
15
13
|
closeButton?: ButtonInfo;
|
|
16
14
|
/**
|
|
17
15
|
* Specifies the mute button info.
|
|
18
16
|
* Image will be drawn in a 40pt x 40pt frame.
|
|
19
|
-
* Only supported on iOS.
|
|
20
17
|
*/
|
|
21
18
|
muteButton?: ButtonInfo;
|
|
22
19
|
/**
|
|
23
20
|
* Specifies the unmute button info.
|
|
24
21
|
* Image will be drawn in a 40pt x 40pt frame.
|
|
25
|
-
* Only supported on iOS.
|
|
26
22
|
*/
|
|
27
23
|
unmuteButton?: ButtonInfo;
|
|
28
24
|
/**
|
|
29
25
|
* Specifies the play info.
|
|
30
26
|
* Image will be drawn at the center of the player view.
|
|
31
|
-
* Only supported on iOS.
|
|
32
27
|
*/
|
|
33
28
|
playButton?: ButtonInfo;
|
|
34
29
|
/**
|
|
35
30
|
* Specifies the pause info.
|
|
36
31
|
* Image will be drawn at the center of the player view.
|
|
37
|
-
* Only supported on iOS.
|
|
38
32
|
*/
|
|
39
33
|
pauseButton?: ButtonInfo;
|
|
40
34
|
}
|
|
@@ -62,12 +62,10 @@ export default interface VideoPlayerConfiguration {
|
|
|
62
62
|
ctaWidth?: VideoPlayerCTAWidth;
|
|
63
63
|
/**
|
|
64
64
|
* The host app could use this property to customize the button images of the video player.
|
|
65
|
-
* Only supported on iOS.
|
|
66
65
|
*/
|
|
67
66
|
buttonConfiguration?: VideoPlayerButtonConfiguration;
|
|
68
67
|
/**
|
|
69
68
|
* Indicates if the video player shows title.
|
|
70
|
-
* Only supported on iOS.
|
|
71
69
|
*/
|
|
72
70
|
showVideoDetailTitle?: boolean;
|
|
73
71
|
/**
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import type VideoFeedConfiguration from '../models/VideoFeedConfiguration';
|
|
3
|
+
|
|
4
|
+
class VideoFeedUtil {
|
|
5
|
+
static calculateGridFeedHeight({
|
|
6
|
+
videoFeedConfiguration = {},
|
|
7
|
+
rows,
|
|
8
|
+
columns,
|
|
9
|
+
width,
|
|
10
|
+
}: {
|
|
11
|
+
videoFeedConfiguration?: VideoFeedConfiguration;
|
|
12
|
+
rows: number;
|
|
13
|
+
columns: number;
|
|
14
|
+
width: number;
|
|
15
|
+
}): number {
|
|
16
|
+
if (Platform.OS === 'ios') {
|
|
17
|
+
const contentPadding = videoFeedConfiguration.contentPadding ?? {
|
|
18
|
+
top: 10,
|
|
19
|
+
right: 10,
|
|
20
|
+
bottom: 10,
|
|
21
|
+
left: 10,
|
|
22
|
+
};
|
|
23
|
+
const itemSpacing = videoFeedConfiguration.itemSpacing ?? 10;
|
|
24
|
+
const aspectRatio = videoFeedConfiguration.aspectRatio ?? 4 / 6;
|
|
25
|
+
const horizontalMargin =
|
|
26
|
+
(contentPadding.left ?? 10) + (contentPadding.right ?? 10);
|
|
27
|
+
const verticalMargin =
|
|
28
|
+
(contentPadding.top ?? 10) + (contentPadding.bottom ?? 10);
|
|
29
|
+
const totalHorizontalSpacing = (columns - 1) * itemSpacing;
|
|
30
|
+
const totalVerticalSpacing = (rows - 1) * itemSpacing;
|
|
31
|
+
|
|
32
|
+
const availableItemWidth =
|
|
33
|
+
width - (totalHorizontalSpacing + horizontalMargin);
|
|
34
|
+
const singleItemWidth = availableItemWidth / columns;
|
|
35
|
+
const singleItemHeight = singleItemWidth / aspectRatio;
|
|
36
|
+
const feedHeight =
|
|
37
|
+
singleItemHeight * rows + totalVerticalSpacing + verticalMargin;
|
|
38
|
+
|
|
39
|
+
return Math.ceil(feedHeight);
|
|
40
|
+
} else {
|
|
41
|
+
const itemSpacing = videoFeedConfiguration.itemSpacing ?? 8;
|
|
42
|
+
const contentPadding = {
|
|
43
|
+
top: itemSpacing / 2,
|
|
44
|
+
right: itemSpacing / 2,
|
|
45
|
+
bottom: itemSpacing / 2,
|
|
46
|
+
left: itemSpacing / 2,
|
|
47
|
+
};
|
|
48
|
+
const aspectRatio = 9 / 16;
|
|
49
|
+
const horizontalMargin =
|
|
50
|
+
(contentPadding.left ?? 4) + (contentPadding.right ?? 4);
|
|
51
|
+
const verticalMargin =
|
|
52
|
+
(contentPadding.top ?? 4) + (contentPadding.bottom ?? 4);
|
|
53
|
+
const totalHorizontalSpacing = (columns - 1) * itemSpacing;
|
|
54
|
+
const totalVerticalSpacing = (rows - 1) * itemSpacing;
|
|
55
|
+
|
|
56
|
+
const availableItemWidth =
|
|
57
|
+
width - totalHorizontalSpacing - horizontalMargin;
|
|
58
|
+
const singleItemWidth = availableItemWidth / columns;
|
|
59
|
+
let singleItemHeight = 0;
|
|
60
|
+
if (videoFeedConfiguration.titlePosition === 'stacked') {
|
|
61
|
+
singleItemHeight = singleItemWidth / aspectRatio + 30;
|
|
62
|
+
} else {
|
|
63
|
+
singleItemHeight = singleItemWidth / aspectRatio;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const feedHeight =
|
|
67
|
+
singleItemHeight * rows + totalVerticalSpacing + verticalMargin;
|
|
68
|
+
|
|
69
|
+
return Math.ceil(feedHeight);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default VideoFeedUtil;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
package com.fireworksdk.bridge.utils
|
|
2
|
-
|
|
3
|
-
import android.app.Activity
|
|
4
|
-
import android.view.WindowManager
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
object FWStatusBarUtil {
|
|
8
|
-
|
|
9
|
-
private var windowAttrs: WindowManager.LayoutParams? = null
|
|
10
|
-
|
|
11
|
-
private fun saveFlags(activity: Activity) {
|
|
12
|
-
val attr = WindowManager.LayoutParams()
|
|
13
|
-
attr.copyFrom(activity.window.attributes)
|
|
14
|
-
windowAttrs = attr
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
fun hideSystemNavigationUI(activity: Activity) {
|
|
18
|
-
saveFlags(activity)
|
|
19
|
-
@Suppress("DEPRECATION")
|
|
20
|
-
activity.window.addFlags(
|
|
21
|
-
WindowManager.LayoutParams.FLAG_FULLSCREEN
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
fun restoreSystemNavigationUI(activity: Activity) {
|
|
26
|
-
activity.window.attributes = windowAttrs
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
package com.fireworksdk.bridge.utils
|
|
2
|
-
|
|
3
|
-
import com.fireworksdk.bridge.components.storyblock.StoryBlockFragment
|
|
4
|
-
|
|
5
|
-
object FWStoryBlockUtil {
|
|
6
|
-
|
|
7
|
-
private val list = ArrayList<StoryBlockFragment>()
|
|
8
|
-
|
|
9
|
-
fun getCurrentFullScreenStoryBlockFragment(): StoryBlockFragment? {
|
|
10
|
-
while (list.size > 0) {
|
|
11
|
-
val fragment = list.last()
|
|
12
|
-
if (!fragment.isFullScreen()) {
|
|
13
|
-
list.removeLast()
|
|
14
|
-
} else {
|
|
15
|
-
return fragment
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
fun addFullScreenStoryBlockFragment(fragment: StoryBlockFragment?) {
|
|
22
|
-
fragment ?: return
|
|
23
|
-
list.add(fragment)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
fun removeFullScreenStoryBlockFragment(fragment: StoryBlockFragment?) {
|
|
27
|
-
fragment ?: return
|
|
28
|
-
list.remove(fragment)
|
|
29
|
-
}
|
|
30
|
-
}
|