@applicaster/zapp-react-native-ui-components 16.0.0-alpha.6861239588 → 16.0.0-alpha.6918106967

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 (83) hide show
  1. package/Components/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
  2. package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
  3. package/Components/AudioPlayer/tv/index.tsx +5 -1
  4. package/Components/Cell/Cell.tsx +3 -6
  5. package/Components/Cell/TvOSCellComponent.tsx +0 -1
  6. package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
  7. package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
  8. package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
  9. package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
  10. package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
  11. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +1 -0
  12. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
  13. package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
  14. package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
  15. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
  16. package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
  17. package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
  18. package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +54 -0
  19. package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +21 -0
  20. package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
  21. package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +58 -0
  22. package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +0 -18
  23. package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +32 -27
  24. package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +25 -73
  25. package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +0 -18
  26. package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +166 -84
  27. package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +89 -0
  28. package/Components/ModalComponent/AudioPlayer/Components/index.ts +3 -1
  29. package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +230 -0
  30. package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +332 -0
  31. package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
  32. package/Components/ModalComponent/BottomSheetModalContent.tsx +385 -60
  33. package/Components/ModalComponent/Button/index.tsx +5 -3
  34. package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
  35. package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
  36. package/Components/ModalComponent/Header/index.tsx +20 -7
  37. package/Components/ModalComponent/Header/utils.ts +1 -1
  38. package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
  39. package/Components/ModalComponent/SortableList.tsx +142 -0
  40. package/Components/ModalComponent/SortableList.web.tsx +34 -0
  41. package/Components/ModalComponent/TextInputContent.tsx +100 -0
  42. package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
  43. package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +238 -0
  44. package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
  45. package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +120 -0
  46. package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
  47. package/Components/ModalComponent/index.tsx +11 -0
  48. package/Components/ModalComponent/presets/__tests__/getCell.test.ts +66 -0
  49. package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
  50. package/Components/ModalComponent/presets/index.ts +27 -0
  51. package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
  52. package/Components/ModalComponent/presets/standardCell.tsx +41 -0
  53. package/Components/ModalComponent/presets/types.ts +35 -0
  54. package/Components/ModalComponent/showTextInput.ts +43 -0
  55. package/Components/ModalComponent/utils.ts +82 -21
  56. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
  57. package/Components/OfflineHandler/__tests__/index.test.tsx +78 -18
  58. package/Components/OfflineHandler/hooks.ts +111 -0
  59. package/Components/OfflineHandler/index.tsx +51 -73
  60. package/Components/OfflineHandler/utils/index.ts +1 -13
  61. package/Components/PlayerContainer/PlayerContainer.tsx +11 -7
  62. package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
  63. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
  64. package/Components/PreloaderWrapper/index.tsx +1 -1
  65. package/Components/River/ComponentsMap/ComponentsMap.tsx +79 -51
  66. package/Components/River/River.tsx +4 -0
  67. package/Components/River/__tests__/resultCallback.test.tsx +47 -0
  68. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
  69. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
  70. package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
  71. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
  72. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
  73. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +20 -3
  74. package/Components/TopCutoffOverlay/index.tsx +2 -2
  75. package/Components/VideoLive/LiveImageManager.ts +1 -1
  76. package/Hooks/useEntryActionsExpander.ts +63 -0
  77. package/package.json +6 -5
  78. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
  79. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
  80. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
  81. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -66
  82. package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
  83. /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
@@ -20,6 +20,12 @@ import {
20
20
  Text,
21
21
  View,
22
22
  } from "react-native";
23
+ import {
24
+ MenuItem,
25
+ SelectionBehavior,
26
+ } from "@applicaster/zapp-react-native-utils/modalState/types";
27
+ import { useModalBlocksStyle } from "../../ModalBlocksStyleContext";
28
+ import { mergeItemConfiguration } from "../utils/mergeStyles";
23
29
 
24
30
  const styles = StyleSheet.create({
25
31
  row: {
@@ -34,25 +40,6 @@ const styles = StyleSheet.create({
34
40
  flexDirection: "row",
35
41
  alignItems: "center",
36
42
  },
37
- demoScreen: {
38
- flex: 1,
39
- backgroundColor: "#1C1C1E",
40
- paddingTop: 64,
41
- paddingHorizontal: 0,
42
- gap: 16,
43
- },
44
- demoHeading: {
45
- color: "#FFFFFF",
46
- fontSize: 20,
47
- fontWeight: "600",
48
- marginBottom: 8,
49
- paddingHorizontal: 16,
50
- },
51
- demoLabel: {
52
- color: "#999999",
53
- fontSize: 13,
54
- paddingHorizontal: 16,
55
- },
56
43
  });
57
44
 
58
45
  // ---------------------------------------------------------------------------
@@ -69,6 +56,10 @@ export type BackgroundConfiguration = {
69
56
  defaultColor: string;
70
57
  focusedColor: string;
71
58
  cornerRadius: number;
59
+ paddingTop?: number;
60
+ paddingRight?: number;
61
+ paddingBottom?: number;
62
+ paddingLeft?: number;
72
63
  };
73
64
 
74
65
  export type ImageConfiguration = {
@@ -95,6 +86,20 @@ export type NowPlayingAssetConfiguration = {
95
86
  asset?: string;
96
87
  };
97
88
 
89
+ export type CheckboxAssetsConfiguration = {
90
+ /** Unchecked multiSelect control (item.checkbox_asset). */
91
+ asset?: string;
92
+ /** Checked multiSelect control (item.checked_checkbox_asset). */
93
+ checkedAsset?: string;
94
+ };
95
+
96
+ export type ActionButtonAssetsConfiguration = {
97
+ /** Leading remove control on Edit Order rows. */
98
+ removeAsset?: string;
99
+ /** Trailing drag handle on Edit Order / queue rows. */
100
+ dragAsset?: string;
101
+ };
102
+
98
103
  export type ItemConfiguration = {
99
104
  background: BackgroundConfiguration;
100
105
  image: ImageConfiguration;
@@ -102,53 +107,10 @@ export type ItemConfiguration = {
102
107
  nowPlayingLabel: LabelConfiguration;
103
108
  textLabel1: LabelConfiguration;
104
109
  textLabel2: LabelConfiguration;
110
+ checkboxAssets?: CheckboxAssetsConfiguration;
111
+ actionButtonAssets?: ActionButtonAssetsConfiguration;
105
112
  };
106
113
 
107
- export interface Action {
108
- type: string;
109
- payload?: any;
110
- options?: any;
111
- }
112
-
113
- export interface Header {
114
- title: string;
115
- subtitle?: string;
116
- icon?: string;
117
- }
118
-
119
- export interface Content {
120
- title: string;
121
- stickyTitle?: boolean;
122
- items: MenuItem[];
123
- itemsUrl?: string;
124
- action?: Action;
125
- }
126
-
127
- export interface Menu {
128
- header?: Header;
129
- content: Content;
130
- closeButton?: boolean;
131
- }
132
-
133
- export interface PresentSubMenuAction extends Action {
134
- menu: Menu;
135
- }
136
-
137
- export interface SecondaryAction {
138
- action: Action | PresentSubMenuAction;
139
- icon?: string;
140
- }
141
-
142
- export interface MenuItem {
143
- trailingButton?: ItemButtonAction;
144
- title: string;
145
- summary?: string;
146
- icon?: string;
147
- isSelected?: boolean;
148
- action?: Action | PresentSubMenuAction;
149
- secondaryAction?: SecondaryAction;
150
- }
151
-
152
114
  export const DEFAULT_TEXT_LABEL_1_CONFIGURATION: LabelConfiguration = {
153
115
  fontColor: "#FFFFFF",
154
116
  focusedFontColor: "#FFFFFF",
@@ -211,6 +173,7 @@ export type AudioPlayerTrackItemProps = {
211
173
  onPress?: () => void;
212
174
  onLeadingButtonPress?: () => void;
213
175
  onTrailingButtonPress?: () => void;
176
+ renderHandle?: (element: React.ReactElement) => React.ReactElement;
214
177
  };
215
178
 
216
179
  // ---------------------------------------------------------------------------
@@ -326,14 +289,17 @@ function resolveContainerSpec(image: ImageConfiguration): ContainerSpec {
326
289
  : CONTAINER_SPEC_DEFAULT;
327
290
  }
328
291
 
329
- export function mapMenuItemToNowPlayingData(item: MenuItem): ItemData {
292
+ export function mapMenuItemToNowPlayingData(
293
+ item: MenuItem,
294
+ isPaused?: boolean
295
+ ): ItemData {
330
296
  return {
331
297
  imageUri: item.icon,
332
298
  textLabel1: item.title,
333
299
  textLabel2: item.summary ?? "",
334
300
  nowPlayingLabel: "Now Playing",
335
301
  trailingButton: "playPause",
336
- isSelected: item.isSelected,
302
+ isSelected: isPaused !== undefined ? !isPaused : item.isSelected,
337
303
  };
338
304
  }
339
305
 
@@ -348,12 +314,23 @@ export function mapMenuItemToQueuedData(item: MenuItem): ItemData {
348
314
  };
349
315
  }
350
316
 
351
- export function mapMenuItemToPlaylistData(item: MenuItem): ItemData {
317
+ export function mapMenuItemToPlaylistData(
318
+ item: MenuItem,
319
+ behavior?: SelectionBehavior
320
+ ): ItemData {
321
+ const showSelectionWidget =
322
+ behavior?.selectMode !== "none" && item.trailingButton !== "none";
323
+
324
+ const summary =
325
+ typeof item.summary === "string" ? item.summary.trim() : item.summary;
326
+
352
327
  return {
353
328
  imageUri: item.icon,
354
329
  textLabel1: item.title,
355
- textLabel2: item.summary ?? "",
356
- trailingButton: item.trailingButton || ("multiSelect" as ItemButtonAction),
330
+ textLabel2: summary || "",
331
+ trailingButton: showSelectionWidget
332
+ ? item.trailingButton || ("multiSelect" as ItemButtonAction)
333
+ : undefined,
357
334
  isSelected: item.isSelected,
358
335
  };
359
336
  }
@@ -386,10 +363,10 @@ function ItemContainer({
386
363
  style={({ pressed }) => ({
387
364
  backgroundColor: pressed ? background.focusedColor : bg,
388
365
  borderRadius: background.cornerRadius,
389
- paddingTop: container.paddingTop,
390
- paddingRight: container.paddingRight,
391
- paddingBottom: container.paddingBottom,
392
- paddingLeft: container.paddingLeft,
366
+ paddingTop: background.paddingTop ?? container.paddingTop,
367
+ paddingRight: background.paddingRight ?? container.paddingRight,
368
+ paddingBottom: background.paddingBottom ?? container.paddingBottom,
369
+ paddingLeft: background.paddingLeft ?? container.paddingLeft,
393
370
  })}
394
371
  >
395
372
  {children}
@@ -496,6 +473,8 @@ type ItemButtonProps = {
496
473
  focused?: boolean;
497
474
  onPress?: () => void;
498
475
  isSelected?: boolean;
476
+ checkboxAssets?: CheckboxAssetsConfiguration;
477
+ actionButtonAssets?: ActionButtonAssetsConfiguration;
499
478
  };
500
479
 
501
480
  function ItemButton({
@@ -503,9 +482,15 @@ function ItemButton({
503
482
  focused = false,
504
483
  onPress,
505
484
  isSelected = false,
485
+ checkboxAssets,
486
+ actionButtonAssets,
506
487
  }: ItemButtonProps) {
507
488
  const layout = BUTTON_LAYOUT_SPEC[action];
508
489
 
490
+ if (!layout) {
491
+ return null;
492
+ }
493
+
509
494
  const renderIcon = () => {
510
495
  switch (action) {
511
496
  case "playPause": {
@@ -573,6 +558,19 @@ function ItemButton({
573
558
  }
574
559
 
575
560
  case "drag": {
561
+ if (actionButtonAssets?.dragAsset) {
562
+ return (
563
+ <Image
564
+ source={{ uri: actionButtonAssets.dragAsset }}
565
+ style={{
566
+ width: layout.assetWidth,
567
+ height: layout.assetHeight,
568
+ }}
569
+ resizeMode="contain"
570
+ />
571
+ );
572
+ }
573
+
576
574
  return (
577
575
  <View
578
576
  style={{
@@ -607,6 +605,19 @@ function ItemButton({
607
605
  }
608
606
 
609
607
  case "remove": {
608
+ if (actionButtonAssets?.removeAsset) {
609
+ return (
610
+ <Image
611
+ source={{ uri: actionButtonAssets.removeAsset }}
612
+ style={{
613
+ width: layout.assetWidth,
614
+ height: layout.assetHeight,
615
+ }}
616
+ resizeMode="contain"
617
+ />
618
+ );
619
+ }
620
+
610
621
  return (
611
622
  <View
612
623
  style={{
@@ -632,6 +643,23 @@ function ItemButton({
632
643
  }
633
644
 
634
645
  case "multiSelect": {
646
+ const studioAsset = isSelected
647
+ ? checkboxAssets?.checkedAsset
648
+ : checkboxAssets?.asset;
649
+
650
+ if (studioAsset) {
651
+ return (
652
+ <Image
653
+ source={{ uri: studioAsset }}
654
+ style={{
655
+ width: layout.assetWidth,
656
+ height: layout.assetHeight,
657
+ }}
658
+ resizeMode="contain"
659
+ />
660
+ );
661
+ }
662
+
635
663
  if (!isSelected) {
636
664
  return (
637
665
  <View
@@ -680,7 +708,10 @@ function ItemButton({
680
708
 
681
709
  return (
682
710
  <Pressable
683
- onPress={onPress}
711
+ onPress={(e: any) => {
712
+ e?.stopPropagation?.();
713
+ onPress?.();
714
+ }}
684
715
  style={({ pressed }) => [
685
716
  {
686
717
  paddingTop: layout.paddingTop,
@@ -704,6 +735,9 @@ type ItemButtonsProps = {
704
735
  onLeadingButtonPress?: () => void;
705
736
  onTrailingButtonPress?: () => void;
706
737
  isSelected?: boolean;
738
+ renderHandle?: (element: React.ReactElement) => React.ReactElement;
739
+ checkboxAssets?: CheckboxAssetsConfiguration;
740
+ actionButtonAssets?: ActionButtonAssetsConfiguration;
707
741
  };
708
742
 
709
743
  function ItemButtons({
@@ -714,6 +748,9 @@ function ItemButtons({
714
748
  onLeadingButtonPress,
715
749
  onTrailingButtonPress,
716
750
  isSelected = false,
751
+ renderHandle,
752
+ checkboxAssets,
753
+ actionButtonAssets,
717
754
  }: ItemButtonsProps) {
718
755
  if (!leadingButton && !trailingButton) {
719
756
  return null;
@@ -728,17 +765,45 @@ function ItemButtons({
728
765
  focused={focusedLeadingButton}
729
766
  onPress={onLeadingButtonPress}
730
767
  isSelected={isSelected}
768
+ checkboxAssets={checkboxAssets}
769
+ actionButtonAssets={actionButtonAssets}
731
770
  />
732
771
  <View style={{ width: BUTTONS_CONTAINER_HORIZONTAL_GUTTER }} />
733
772
  </>
734
773
  ) : null}
735
774
  {trailingButton ? (
736
- <ItemButton
737
- action={trailingButton}
738
- focused={focusedTrailingButton}
739
- onPress={onTrailingButtonPress}
740
- isSelected={isSelected}
741
- />
775
+ trailingButton === "drag" ? (
776
+ renderHandle ? (
777
+ renderHandle(
778
+ <ItemButton
779
+ action={trailingButton}
780
+ focused={focusedTrailingButton}
781
+ onPress={onTrailingButtonPress}
782
+ isSelected={isSelected}
783
+ checkboxAssets={checkboxAssets}
784
+ actionButtonAssets={actionButtonAssets}
785
+ />
786
+ )
787
+ ) : (
788
+ <ItemButton
789
+ action={trailingButton}
790
+ focused={focusedTrailingButton}
791
+ onPress={onTrailingButtonPress}
792
+ isSelected={isSelected}
793
+ checkboxAssets={checkboxAssets}
794
+ actionButtonAssets={actionButtonAssets}
795
+ />
796
+ )
797
+ ) : (
798
+ <ItemButton
799
+ action={trailingButton}
800
+ focused={focusedTrailingButton}
801
+ onPress={onTrailingButtonPress}
802
+ isSelected={isSelected}
803
+ checkboxAssets={checkboxAssets}
804
+ actionButtonAssets={actionButtonAssets}
805
+ />
806
+ )
742
807
  ) : null}
743
808
  </View>
744
809
  );
@@ -757,18 +822,32 @@ export function AudioPlayerTrackItem({
757
822
  onPress,
758
823
  onLeadingButtonPress,
759
824
  onTrailingButtonPress,
825
+ renderHandle,
760
826
  }: AudioPlayerTrackItemProps) {
827
+ const modalBlocksStyle = useModalBlocksStyle();
828
+ const showNowPlaying = !!data.nowPlayingLabel;
829
+
830
+ const itemBlock =
831
+ showNowPlaying && modalBlocksStyle?.nowPlayingItem
832
+ ? modalBlocksStyle.nowPlayingItem
833
+ : modalBlocksStyle?.item;
834
+
835
+ const effectiveConfig = React.useMemo(() => {
836
+ return mergeItemConfiguration(configuration, itemBlock);
837
+ }, [configuration, itemBlock]);
838
+
761
839
  const {
762
840
  background,
763
841
  image,
764
- nowPlayingAsset,
765
- nowPlayingLabel,
766
842
  textLabel1,
767
843
  textLabel2,
768
- } = configuration;
844
+ nowPlayingLabel,
845
+ nowPlayingAsset,
846
+ checkboxAssets,
847
+ actionButtonAssets,
848
+ } = effectiveConfig;
769
849
 
770
850
  const container = resolveContainerSpec(image);
771
- const showNowPlaying = !!data.nowPlayingLabel;
772
851
 
773
852
  return (
774
853
  <ItemContainer
@@ -807,6 +886,9 @@ export function AudioPlayerTrackItem({
807
886
  onLeadingButtonPress={onLeadingButtonPress}
808
887
  onTrailingButtonPress={onTrailingButtonPress}
809
888
  isSelected={data.isSelected}
889
+ renderHandle={renderHandle}
890
+ checkboxAssets={checkboxAssets}
891
+ actionButtonAssets={actionButtonAssets}
810
892
  />
811
893
  </View>
812
894
  </ItemContainer>
@@ -0,0 +1,89 @@
1
+ import React from "react";
2
+ import { StyleSheet, View } from "react-native";
3
+ import {
4
+ AudioPlayerTrackItem,
5
+ VARIANT_NOW_PLAYING,
6
+ mapMenuItemToNowPlayingData,
7
+ } from "./Item";
8
+ import { AudioPlayerHeader, VARIANT_SECTION_HEADER } from "./Header";
9
+ import type { MenuItem } from "@applicaster/zapp-react-native-utils/modalState/types";
10
+ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
11
+ import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
12
+
13
+ const styles = StyleSheet.create({
14
+ divider: {
15
+ height: StyleSheet.hairlineWidth,
16
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
17
+ marginHorizontal: 20,
18
+ marginVertical: 8,
19
+ },
20
+ });
21
+
22
+ type NowPlayingHeaderSectionProps = {
23
+ onClear?: () => void;
24
+ };
25
+
26
+ export function NowPlayingHeaderSection({
27
+ onClear,
28
+ }: NowPlayingHeaderSectionProps) {
29
+ const player = usePlayer();
30
+ const playerState = usePlayerState("queue-now-playing-section");
31
+
32
+ const renderNowPlayingTrack = () => {
33
+ if (!player?.entry) {
34
+ return null;
35
+ }
36
+
37
+ const mediaGroup = player.entry.media_group;
38
+
39
+ const imageGroup = Array.isArray(mediaGroup)
40
+ ? mediaGroup.find((g: any) => g.type === "image")
41
+ : null;
42
+
43
+ const firstImage = Array.isArray(imageGroup?.media_item)
44
+ ? imageGroup.media_item[0]?.src
45
+ : imageGroup?.media_item?.src;
46
+
47
+ const nowPlayingItem: MenuItem = {
48
+ id: String(player.entry.id ?? "now_playing"),
49
+ title: (player.entry.title as string) || String(player.entry.id),
50
+ summary: (player.entry.summary as string) ?? "",
51
+ icon: firstImage,
52
+ };
53
+
54
+ const data = mapMenuItemToNowPlayingData(
55
+ nowPlayingItem,
56
+ playerState?.isPaused
57
+ );
58
+
59
+ const handlePlayPause = () => {
60
+ if (playerState?.isPaused) {
61
+ player?.play();
62
+ } else {
63
+ player?.pause();
64
+ }
65
+ };
66
+
67
+ return (
68
+ <View>
69
+ <AudioPlayerTrackItem
70
+ configuration={VARIANT_NOW_PLAYING}
71
+ data={data}
72
+ onTrailingButtonPress={handlePlayPause}
73
+ />
74
+ <View style={styles.divider} />
75
+ </View>
76
+ );
77
+ };
78
+
79
+ return (
80
+ <View>
81
+ {renderNowPlayingTrack()}
82
+ <AudioPlayerHeader
83
+ configuration={VARIANT_SECTION_HEADER}
84
+ data={{ title: "Next Up" }}
85
+ onClear={onClear}
86
+ />
87
+ </View>
88
+ );
89
+ }
@@ -1,9 +1,11 @@
1
1
  export { AudioPlayerAction } from "./Action";
2
2
 
3
- export { AudioPlayerButton } from "./Button";
3
+ export { AudioPlayerButton, VARIANT_WITH_ICON } from "./Button";
4
4
 
5
5
  export { AudioPlayerHeader } from "./Header";
6
6
 
7
7
  export { AudioPlayerTrackItem } from "./Item";
8
8
 
9
+ export { NowPlayingHeaderSection } from "./NowPlayingHeaderSection";
10
+
9
11
  export { AudioPlayerInput } from "./Input";