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.
Files changed (88) hide show
  1. package/FireworkVideoUI.xcframework/Info.plist +5 -5
  2. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  3. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
  4. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  5. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
  6. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +1 -1
  7. package/android/build.gradle +2 -1
  8. package/android/gradle.properties +1 -1
  9. package/android/src/main/java/com/fireworksdk/bridge/components/base/FWLoading.kt +22 -0
  10. package/android/src/main/java/com/fireworksdk/bridge/components/storyblock/StoryBlockFragment.kt +240 -18
  11. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +19 -9
  12. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationDeserializer.kt +49 -0
  13. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationModel.kt +13 -0
  14. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationSerializer.kt +42 -0
  15. package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoDeserializer.kt +21 -0
  16. package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoModel.kt +6 -0
  17. package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoSerializer.kt +17 -0
  18. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationDeserializer.kt +33 -0
  19. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationModel.kt +10 -0
  20. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationSerializer.kt +25 -0
  21. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +7 -0
  22. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +17 -0
  23. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationSerializer.kt +13 -0
  24. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
  25. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +3 -0
  26. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelSerializer.kt +2 -0
  27. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +3 -1
  28. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +7 -1
  29. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelSerializer.kt +4 -0
  30. package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWErrorAction.kt +18 -0
  31. package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWEventName.kt +3 -0
  32. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +50 -26
  33. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +47 -8
  34. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +1 -0
  35. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +0 -10
  36. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +42 -0
  37. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +5 -3
  38. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +24 -6
  39. package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +95 -0
  40. package/android/src/main/res/layout/fw_bridge_story_block.xml +6 -0
  41. package/android/src/main/res/layout/fw_loading.xml +14 -0
  42. package/ios/Components/VideoFeed.swift +1 -1
  43. package/ios/FireworkVideoUI/Podfile.lock +1 -1
  44. package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.h +20 -0
  45. package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.m +84 -0
  46. package/lib/commonjs/VideoShopping.js +1 -4
  47. package/lib/commonjs/VideoShopping.js.map +1 -1
  48. package/lib/commonjs/components/StoryBlock.js +32 -42
  49. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  50. package/lib/commonjs/components/VideoFeed.js +29 -11
  51. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  52. package/lib/commonjs/index.js +8 -0
  53. package/lib/commonjs/index.js.map +1 -1
  54. package/lib/commonjs/utils/VideoFeedUtil.js +73 -0
  55. package/lib/commonjs/utils/VideoFeedUtil.js.map +1 -0
  56. package/lib/module/VideoShopping.js +1 -5
  57. package/lib/module/VideoShopping.js.map +1 -1
  58. package/lib/module/components/StoryBlock.js +32 -40
  59. package/lib/module/components/StoryBlock.js.map +1 -1
  60. package/lib/module/components/VideoFeed.js +28 -11
  61. package/lib/module/components/VideoFeed.js.map +1 -1
  62. package/lib/module/index.js +2 -1
  63. package/lib/module/index.js.map +1 -1
  64. package/lib/module/utils/VideoFeedUtil.js +65 -0
  65. package/lib/module/utils/VideoFeedUtil.js.map +1 -0
  66. package/lib/typescript/VideoShopping.d.ts +0 -1
  67. package/lib/typescript/components/StoryBlock.d.ts +15 -4
  68. package/lib/typescript/components/VideoFeed.d.ts +12 -1
  69. package/lib/typescript/index.d.ts +2 -1
  70. package/lib/typescript/models/ButtonInfo.d.ts +0 -1
  71. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +3 -3
  72. package/lib/typescript/models/StoryBlockConfiguration.d.ts +0 -2
  73. package/lib/typescript/models/VideoPlayerButtonConfiguration.d.ts +0 -6
  74. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +0 -2
  75. package/lib/typescript/utils/VideoFeedUtil.d.ts +10 -0
  76. package/package.json +1 -1
  77. package/src/VideoShopping.ts +1 -4
  78. package/src/components/StoryBlock.tsx +40 -44
  79. package/src/components/VideoFeed.tsx +32 -11
  80. package/src/index.ts +2 -0
  81. package/src/models/ButtonInfo.ts +0 -1
  82. package/src/models/ProductInfoViewConfiguration.ts +3 -3
  83. package/src/models/StoryBlockConfiguration.ts +0 -2
  84. package/src/models/VideoPlayerButtonConfiguration.ts +0 -6
  85. package/src/models/VideoPlayerConfiguration.ts +0 -2
  86. package/src/utils/VideoFeedUtil.ts +74 -0
  87. package/android/src/main/java/com/fireworksdk/bridge/utils/FWStatusBarUtil.kt +0 -28
  88. 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. Only supported on iOS.
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
- onStoryBlockLoadFinished({ name, reason });
141
- } else {
142
- onStoryBlockLoadFinished({ name });
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. Only supported on iOS.
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
- onVideoFeedLoadFinished({ name, reason });
166
- } else {
167
- onVideoFeedLoadFinished({ name });
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,
@@ -2,7 +2,6 @@ export default interface ButtonInfo {
2
2
  /**
3
3
  * The name of image in the asset catalogs.
4
4
  * For example, you need to add the image in the Images.xcassets(or Assets.xcassets etc.)
5
- * Only supported on iOS.
6
5
  */
7
6
  imageName?: string;
8
7
  /**
@@ -140,7 +140,7 @@ export interface ProductCardConfiguration {
140
140
  */
141
141
  ctaButtonStyle?: ProductCardCTAButtonStyle;
142
142
  /**
143
- * Price is hidden or not.
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. Only supported on iOS.
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. Only supported on iOS.
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
- }