@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1535029240 → 16.0.0-alpha.1701179921
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/Components/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -2
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +87 -97
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +87 -126
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +140 -83
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +252 -123
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +113 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +3 -3
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +356 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +521 -0
- package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +505 -66
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +52 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/hooks.ts +0 -12
- package/Components/PlayerContainer/PlayerContainer.tsx +19 -8
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
- package/Components/River/ComponentsMap/ComponentsMap.tsx +85 -59
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +138 -75
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +5 -0
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/Transitioner/Transitioner.tsx +2 -3
- package/Components/Transitioner/__tests__/transitioner.test.js +83 -2
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +0 -332
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { StyleSheet, Text, 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 { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
11
|
+
import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/const";
|
|
12
|
+
import type { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
|
|
13
|
+
|
|
14
|
+
const DEFAULT_EMPTY_MESSAGE = "Queued items will be added here";
|
|
15
|
+
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
divider: {
|
|
18
|
+
height: StyleSheet.hairlineWidth,
|
|
19
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
20
|
+
marginHorizontal: 20,
|
|
21
|
+
marginVertical: 8,
|
|
22
|
+
},
|
|
23
|
+
emptyMessage: {
|
|
24
|
+
paddingTop: 32,
|
|
25
|
+
paddingBottom: 32,
|
|
26
|
+
paddingHorizontal: 40,
|
|
27
|
+
textAlign: "center",
|
|
28
|
+
color: "#999999",
|
|
29
|
+
fontSize: 13,
|
|
30
|
+
lineHeight: 16,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const isPrimaryOrCastingPlayer = (player?: Player | null): boolean => {
|
|
35
|
+
if (!player) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
player.playerRole === PlayerRole.Primary ||
|
|
41
|
+
player.playerRole === PlayerRole.Chromecast
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getTargetPlayer = (): Player | null => {
|
|
46
|
+
if (playerManager.isCasting()) {
|
|
47
|
+
return playerManager.getCastingReceiver() || null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const active = playerManager.getActivePlayer();
|
|
51
|
+
|
|
52
|
+
return isPrimaryOrCastingPlayer(active) ? active : null;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type NowPlayingHeaderSectionProps = {
|
|
56
|
+
onClear?: () => void;
|
|
57
|
+
nextUpTitle?: string;
|
|
58
|
+
nowPlayingTitle?: string;
|
|
59
|
+
isEmpty?: boolean;
|
|
60
|
+
emptyMessage?: string;
|
|
61
|
+
clearLabel?: string;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export function NowPlayingHeaderSection({
|
|
65
|
+
onClear,
|
|
66
|
+
nextUpTitle = "Next Up",
|
|
67
|
+
nowPlayingTitle = "Now Playing",
|
|
68
|
+
isEmpty = false,
|
|
69
|
+
emptyMessage = DEFAULT_EMPTY_MESSAGE,
|
|
70
|
+
clearLabel,
|
|
71
|
+
}: NowPlayingHeaderSectionProps) {
|
|
72
|
+
const [activePlayer, setActivePlayer] = useState<Player | null>(
|
|
73
|
+
getTargetPlayer
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const [currentEntry, setCurrentEntry] = useState<ZappEntry | null>(
|
|
77
|
+
() => getTargetPlayer()?.entry || null
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const [isPaused, setIsPaused] = useState<boolean>(() =>
|
|
81
|
+
Boolean(getTargetPlayer()?.isPaused())
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const handleActivePlayerUpdate = () => {
|
|
86
|
+
const player = getTargetPlayer();
|
|
87
|
+
|
|
88
|
+
if (player) {
|
|
89
|
+
setActivePlayer(player);
|
|
90
|
+
|
|
91
|
+
if (player.entry) {
|
|
92
|
+
setCurrentEntry(player.entry);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setIsPaused(Boolean(player.isPaused()));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
handleActivePlayerUpdate();
|
|
100
|
+
|
|
101
|
+
const removeLifecycle = playerManager.addLifecycleListener({
|
|
102
|
+
onRegistered: (registeredPlayer) => {
|
|
103
|
+
if (isPrimaryOrCastingPlayer(registeredPlayer)) {
|
|
104
|
+
handleActivePlayerUpdate();
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
onCastingChanged: handleActivePlayerUpdate,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return () => {
|
|
111
|
+
removeLifecycle?.();
|
|
112
|
+
};
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!activePlayer) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const syncPlayerState = () => {
|
|
121
|
+
if (activePlayer.entry) {
|
|
122
|
+
setCurrentEntry(activePlayer.entry);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setIsPaused(Boolean(activePlayer.isPaused()));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
syncPlayerState();
|
|
129
|
+
|
|
130
|
+
const removeListener = activePlayer.addListener({
|
|
131
|
+
id: "queue-now-playing-header",
|
|
132
|
+
listener: {
|
|
133
|
+
onPlayerPause: () => setIsPaused(true),
|
|
134
|
+
onPlayerResume: () => setIsPaused(false),
|
|
135
|
+
onVideoLoad: syncPlayerState,
|
|
136
|
+
onLoad: syncPlayerState,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return () => {
|
|
141
|
+
removeListener?.();
|
|
142
|
+
};
|
|
143
|
+
}, [activePlayer]);
|
|
144
|
+
|
|
145
|
+
const handlePlayPause = () => {
|
|
146
|
+
if (!activePlayer) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (isPaused) {
|
|
151
|
+
activePlayer.play();
|
|
152
|
+
setIsPaused(false);
|
|
153
|
+
} else {
|
|
154
|
+
activePlayer.pause();
|
|
155
|
+
setIsPaused(true);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const renderNowPlayingTrack = () => {
|
|
160
|
+
if (!currentEntry) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const imageGroup = Array.isArray(currentEntry.media_group)
|
|
165
|
+
? currentEntry.media_group.find((g: any) => g.type === "image")
|
|
166
|
+
: null;
|
|
167
|
+
|
|
168
|
+
const firstImage = Array.isArray(imageGroup?.media_item)
|
|
169
|
+
? imageGroup.media_item[0]?.src
|
|
170
|
+
: imageGroup?.media_item?.src;
|
|
171
|
+
|
|
172
|
+
const nowPlayingItem: MenuItem = {
|
|
173
|
+
id: String(currentEntry.id ?? "now_playing"),
|
|
174
|
+
title: (currentEntry.title as string) || String(currentEntry.id),
|
|
175
|
+
summary: (currentEntry.summary as string) ?? "",
|
|
176
|
+
icon: firstImage,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const data = mapMenuItemToNowPlayingData(
|
|
180
|
+
nowPlayingItem,
|
|
181
|
+
isPaused,
|
|
182
|
+
nowPlayingTitle
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<AudioPlayerTrackItem
|
|
187
|
+
configuration={VARIANT_NOW_PLAYING}
|
|
188
|
+
data={data}
|
|
189
|
+
onTrailingButtonPress={handlePlayPause}
|
|
190
|
+
/>
|
|
191
|
+
);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<View>
|
|
196
|
+
{renderNowPlayingTrack()}
|
|
197
|
+
<AudioPlayerHeader
|
|
198
|
+
configuration={VARIANT_SECTION_HEADER}
|
|
199
|
+
data={{ title: nextUpTitle, clearLabel }}
|
|
200
|
+
onClear={onClear}
|
|
201
|
+
/>
|
|
202
|
+
{isEmpty ? <Text style={styles.emptyMessage}>{emptyMessage}</Text> : null}
|
|
203
|
+
</View>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Pressable } from "react-native";
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react-native";
|
|
4
|
+
import {
|
|
5
|
+
AudioPlayerTrackItem,
|
|
6
|
+
VARIANT_PLAYLIST_ITEM,
|
|
7
|
+
mapMenuItemToNowPlayingData,
|
|
8
|
+
} from "../Item";
|
|
9
|
+
|
|
10
|
+
const playlistItemData = {
|
|
11
|
+
textLabel1: "Queue",
|
|
12
|
+
textLabel2: "",
|
|
13
|
+
trailingButton: "multiSelect" as const,
|
|
14
|
+
isSelected: false,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("AudioPlayerTrackItem multiSelect checkbox", () => {
|
|
18
|
+
it("invokes onPress when the checkbox is pressed even if onTrailingButtonPress is omitted", () => {
|
|
19
|
+
const onPress = jest.fn();
|
|
20
|
+
|
|
21
|
+
render(
|
|
22
|
+
<AudioPlayerTrackItem
|
|
23
|
+
configuration={VARIANT_PLAYLIST_ITEM}
|
|
24
|
+
data={playlistItemData}
|
|
25
|
+
onPress={onPress}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const pressables = screen.UNSAFE_getAllByType(Pressable);
|
|
30
|
+
fireEvent.press(pressables[pressables.length - 1]);
|
|
31
|
+
|
|
32
|
+
expect(onPress).toHaveBeenCalledTimes(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("invokes onTrailingButtonPress instead of onPress when a dedicated trailing handler is provided", () => {
|
|
36
|
+
const onPress = jest.fn();
|
|
37
|
+
const onTrailingButtonPress = jest.fn();
|
|
38
|
+
|
|
39
|
+
render(
|
|
40
|
+
<AudioPlayerTrackItem
|
|
41
|
+
configuration={VARIANT_PLAYLIST_ITEM}
|
|
42
|
+
data={playlistItemData}
|
|
43
|
+
onPress={onPress}
|
|
44
|
+
onTrailingButtonPress={onTrailingButtonPress}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const pressables = screen.UNSAFE_getAllByType(Pressable);
|
|
49
|
+
fireEvent.press(pressables[pressables.length - 1]);
|
|
50
|
+
|
|
51
|
+
expect(onTrailingButtonPress).toHaveBeenCalledTimes(1);
|
|
52
|
+
expect(onPress).not.toHaveBeenCalled();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("invokes onPress when the row is pressed", () => {
|
|
56
|
+
const onPress = jest.fn();
|
|
57
|
+
|
|
58
|
+
render(
|
|
59
|
+
<AudioPlayerTrackItem
|
|
60
|
+
configuration={VARIANT_PLAYLIST_ITEM}
|
|
61
|
+
data={playlistItemData}
|
|
62
|
+
onPress={onPress}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
fireEvent.press(screen.UNSAFE_getAllByType(Pressable)[0]);
|
|
67
|
+
|
|
68
|
+
expect(onPress).toHaveBeenCalledTimes(1);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("renders only textLabel1 Text element when textLabel2 is missing or empty", () => {
|
|
72
|
+
const { UNSAFE_getAllByType, queryByText } = render(
|
|
73
|
+
<AudioPlayerTrackItem
|
|
74
|
+
configuration={VARIANT_PLAYLIST_ITEM}
|
|
75
|
+
data={{
|
|
76
|
+
textLabel1: "Only Title",
|
|
77
|
+
textLabel2: "",
|
|
78
|
+
}}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const { Text } = require("react-native");
|
|
83
|
+
const textNodes = UNSAFE_getAllByType(Text);
|
|
84
|
+
expect(textNodes).toHaveLength(1);
|
|
85
|
+
expect(queryByText("Only Title")).toBeTruthy();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("mapMenuItemToNowPlayingData", () => {
|
|
90
|
+
const item = {
|
|
91
|
+
id: "item_1",
|
|
92
|
+
title: "Track Title",
|
|
93
|
+
summary: "Artist Name",
|
|
94
|
+
icon: "https://example.com/cover.png",
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
it("uses default 'Now Playing' label when omitted", () => {
|
|
98
|
+
const data = mapMenuItemToNowPlayingData(item as any);
|
|
99
|
+
expect(data.nowPlayingLabel).toBe("Now Playing");
|
|
100
|
+
expect(data.textLabel1).toBe("Track Title");
|
|
101
|
+
expect(data.textLabel2).toBe("Artist Name");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("uses custom nowPlayingLabel when provided", () => {
|
|
105
|
+
const data = mapMenuItemToNowPlayingData(
|
|
106
|
+
item as any,
|
|
107
|
+
false,
|
|
108
|
+
"En cours de lecture"
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(data.nowPlayingLabel).toBe("En cours de lecture");
|
|
112
|
+
});
|
|
113
|
+
});
|
package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react-native";
|
|
3
|
+
import { NowPlayingHeaderSection } from "../NowPlayingHeaderSection";
|
|
4
|
+
|
|
5
|
+
jest.mock(
|
|
6
|
+
"@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer",
|
|
7
|
+
() => ({
|
|
8
|
+
usePlayer: () => null,
|
|
9
|
+
})
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
jest.mock(
|
|
13
|
+
"@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState",
|
|
14
|
+
() => ({
|
|
15
|
+
usePlayerState: () => ({ isPaused: true }),
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const EMPTY_COPY = "Queued items will be added here";
|
|
20
|
+
|
|
21
|
+
describe("NowPlayingHeaderSection empty queue", () => {
|
|
22
|
+
it("renders the empty message under Next Up when the list is empty", () => {
|
|
23
|
+
render(<NowPlayingHeaderSection isEmpty emptyMessage={EMPTY_COPY} />);
|
|
24
|
+
|
|
25
|
+
expect(screen.getByText("Next Up")).toBeTruthy();
|
|
26
|
+
expect(screen.getByText(EMPTY_COPY)).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("does not render the empty message when the list has items", () => {
|
|
30
|
+
render(
|
|
31
|
+
<NowPlayingHeaderSection isEmpty={false} emptyMessage={EMPTY_COPY} />
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(screen.queryByText(EMPTY_COPY)).toBeNull();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
export { AudioPlayerButton } from "./Button";
|
|
1
|
+
export { AudioPlayerButton, VARIANT_WITH_ICON } from "./Button";
|
|
4
2
|
|
|
5
3
|
export { AudioPlayerHeader } from "./Header";
|
|
6
4
|
|
|
7
5
|
export { AudioPlayerTrackItem } from "./Item";
|
|
8
6
|
|
|
7
|
+
export { NowPlayingHeaderSection } from "./NowPlayingHeaderSection";
|
|
8
|
+
|
|
9
9
|
export { AudioPlayerInput } from "./Input";
|