@applicaster/quick-brick-player 12.0.0-rc.13 → 12.0.0-rc.130
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/package.json +7 -6
- package/src/CellPlayer/Assets/AssetsComponent.tsx +61 -50
- package/src/CellPlayer/ContextProvider.tsx +53 -4
- package/src/Player/AudioLayer/AudioDescription.tsx +3 -3
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +277 -58
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +260 -71
- package/src/Player/AudioLayer/Layout/DockedLayout.tsx +81 -27
- package/src/Player/AudioLayer/Layout/defaultLayoutsConts.ts +32 -1
- package/src/Player/AudioLayer/Layout/index.tsx +9 -7
- package/src/Player/AudioLayer/MagicBG/index.tsx +96 -27
- package/src/Player/AudioLayer/utils.ts +33 -0
- package/src/Player/Utils/Utils.ts +26 -16
- package/src/Player/Utils/index.tsx +0 -2
- package/src/Player/index.tsx +146 -167
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import DefaultLayout from "./DefaultLayout";
|
|
3
|
-
import DockedLayout from "./DockedLayout";
|
|
4
3
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
5
4
|
|
|
6
5
|
type Dimensions = {
|
|
@@ -24,27 +23,30 @@ type LayoutProps = {
|
|
|
24
23
|
isBuffering: boolean;
|
|
25
24
|
};
|
|
26
25
|
value: GetValue;
|
|
26
|
+
sleepTimerDate: number;
|
|
27
|
+
playbackSpeedName: string;
|
|
28
|
+
playbackSleepName: string;
|
|
27
29
|
configuration: { [key: string]: any };
|
|
28
30
|
onPlaybackButtonPress: () => void;
|
|
29
31
|
onRewindButtonPress: () => void;
|
|
30
32
|
onForwardButtonPress: () => void;
|
|
33
|
+
onSpeedButtonPress: () => void;
|
|
34
|
+
onSleepButtonPress: () => void;
|
|
31
35
|
onCloseVideoModal: () => void;
|
|
36
|
+
cancelSleepTimer: () => void;
|
|
32
37
|
onPlayerSeek: (targetTime: number) => void;
|
|
33
38
|
onSkipStart: () => void;
|
|
34
39
|
onSkipLive: () => void;
|
|
35
40
|
maximiseVideoModal: () => void;
|
|
36
41
|
dimensions: Dimensions;
|
|
42
|
+
defaultDimensions: Dimensions;
|
|
37
43
|
playNextData: PlayNextData;
|
|
44
|
+
title: string | number;
|
|
45
|
+
summary: string | number;
|
|
38
46
|
};
|
|
39
47
|
|
|
40
48
|
export default function Layout(
|
|
41
49
|
props: LayoutProps
|
|
42
50
|
): React.ReactElement<LayoutProps> {
|
|
43
|
-
const { layoutState } = props;
|
|
44
|
-
|
|
45
|
-
if (layoutState.docked) {
|
|
46
|
-
return <DockedLayout {...props} />;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
51
|
return <DefaultLayout {...props} />;
|
|
50
52
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
// Disabling for now as lint can't recognise typescript definition here
|
|
2
1
|
/* eslint-disable react/prop-types */
|
|
3
2
|
import * as React from "react";
|
|
4
|
-
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { Animated, StyleSheet, View } from "react-native";
|
|
5
4
|
import LinearGradient from "../LinearGradient";
|
|
6
5
|
import { getDominantColor, getPalettes } from "../../../utils/utils";
|
|
6
|
+
import { useEffect } from "react";
|
|
7
7
|
|
|
8
8
|
type MagicBGProps = {
|
|
9
9
|
children: React.ReactNode;
|
|
10
10
|
image: string;
|
|
11
|
+
fallbackUrl?: string;
|
|
11
12
|
defaultColor: string;
|
|
13
|
+
colors: string[];
|
|
12
14
|
};
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const defaultColors = {
|
|
15
17
|
overlay: "rgba(0, 0, 0, 0.35)",
|
|
16
18
|
defaultGradientStart: "rgba(0, 0, 0, 0.25)",
|
|
17
19
|
defaultGradientEnd: "rgba(0, 0, 0, 0)",
|
|
@@ -23,7 +25,7 @@ const styles = StyleSheet.create({
|
|
|
23
25
|
},
|
|
24
26
|
fullScreenOverlay: {
|
|
25
27
|
...StyleSheet.absoluteFillObject,
|
|
26
|
-
backgroundColor:
|
|
28
|
+
backgroundColor: defaultColors.overlay,
|
|
27
29
|
},
|
|
28
30
|
gradientOverlay: {
|
|
29
31
|
position: "absolute",
|
|
@@ -34,53 +36,120 @@ const styles = StyleSheet.create({
|
|
|
34
36
|
},
|
|
35
37
|
});
|
|
36
38
|
|
|
39
|
+
const fetchPaletteAndDominantColor = async (imageUrl: string) => {
|
|
40
|
+
const palette = await getPalettes(imageUrl);
|
|
41
|
+
|
|
42
|
+
const colors = palette.map(
|
|
43
|
+
(color: { r: number; g: number; b: number }) =>
|
|
44
|
+
`rgb(${color.r}, ${color.g}, ${color.b})`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const dominant = await getDominantColor(imageUrl);
|
|
48
|
+
const dominantColor = `rgb(${dominant.r}, ${dominant.g}, ${dominant.b})`;
|
|
49
|
+
|
|
50
|
+
return { gradientColors: colors.slice(0, 2), dominantColor };
|
|
51
|
+
};
|
|
52
|
+
|
|
37
53
|
export const MagicBG: React.FC<MagicBGProps> = ({
|
|
38
54
|
children,
|
|
39
55
|
image,
|
|
56
|
+
fallbackUrl = "",
|
|
57
|
+
colors = [],
|
|
40
58
|
defaultColor,
|
|
41
59
|
}) => {
|
|
42
60
|
const [dominantColor, setDominantColor] =
|
|
43
61
|
React.useState<string>(defaultColor);
|
|
44
62
|
|
|
45
63
|
const [gradientColors, setGradientColors] = React.useState<string[]>([
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
defaultColors.defaultGradientStart,
|
|
65
|
+
defaultColors.defaultGradientEnd,
|
|
48
66
|
]);
|
|
49
67
|
|
|
50
|
-
React.
|
|
51
|
-
|
|
52
|
-
if (image) {
|
|
53
|
-
try {
|
|
54
|
-
const palette = await getPalettes(image);
|
|
68
|
+
const [backgroundColorAnim] = React.useState(new Animated.Value(0)); // from 0 to 1
|
|
69
|
+
const [gradientOpacityAnim] = React.useState(new Animated.Value(0)); // from 0 to 1
|
|
55
70
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const animateColors = () => {
|
|
73
|
+
Animated.timing(backgroundColorAnim, {
|
|
74
|
+
toValue: 1,
|
|
75
|
+
duration: 500,
|
|
76
|
+
useNativeDriver: false,
|
|
77
|
+
}).start();
|
|
60
78
|
|
|
61
|
-
|
|
79
|
+
Animated.timing(gradientOpacityAnim, {
|
|
80
|
+
toValue: 1,
|
|
81
|
+
duration: 500,
|
|
82
|
+
useNativeDriver: false,
|
|
83
|
+
}).start();
|
|
84
|
+
};
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
const fetchColors = async () => {
|
|
87
|
+
if (colors && colors.length > 0) {
|
|
88
|
+
setGradientColors(colors.slice(0, 2));
|
|
89
|
+
setDominantColor(colors[0]);
|
|
90
|
+
animateColors();
|
|
91
|
+
} else if (image) {
|
|
92
|
+
try {
|
|
93
|
+
const { gradientColors, dominantColor } =
|
|
94
|
+
await fetchPaletteAndDominantColor(image);
|
|
95
|
+
|
|
96
|
+
setGradientColors(gradientColors);
|
|
97
|
+
setDominantColor(dominantColor);
|
|
98
|
+
animateColors();
|
|
65
99
|
} catch (error) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
try {
|
|
101
|
+
const { gradientColors, dominantColor } =
|
|
102
|
+
await fetchPaletteAndDominantColor(fallbackUrl);
|
|
103
|
+
|
|
104
|
+
setGradientColors(gradientColors);
|
|
105
|
+
setDominantColor(dominantColor);
|
|
106
|
+
animateColors();
|
|
107
|
+
} catch {
|
|
108
|
+
setGradientColors([
|
|
109
|
+
defaultColors.defaultGradientStart,
|
|
110
|
+
defaultColors.defaultGradientEnd,
|
|
111
|
+
]);
|
|
70
112
|
|
|
71
|
-
|
|
113
|
+
setDominantColor(defaultColor);
|
|
114
|
+
}
|
|
72
115
|
}
|
|
116
|
+
} else {
|
|
117
|
+
setGradientColors([
|
|
118
|
+
defaultColors.defaultGradientStart,
|
|
119
|
+
defaultColors.defaultGradientEnd,
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
setDominantColor(defaultColor);
|
|
73
123
|
}
|
|
74
124
|
};
|
|
75
125
|
|
|
76
126
|
fetchColors();
|
|
77
|
-
}, [
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
|
|
130
|
+
inputRange: [0, 1],
|
|
131
|
+
outputRange: ["black", dominantColor],
|
|
132
|
+
});
|
|
78
133
|
|
|
79
134
|
return (
|
|
80
|
-
<View
|
|
135
|
+
<Animated.View
|
|
136
|
+
style={[
|
|
137
|
+
styles.container,
|
|
138
|
+
{ backgroundColor: interpolatedBackgroundColor },
|
|
139
|
+
]}
|
|
140
|
+
>
|
|
81
141
|
<View style={styles.fullScreenOverlay} />
|
|
82
|
-
|
|
142
|
+
|
|
143
|
+
<Animated.View
|
|
144
|
+
style={[styles.gradientOverlay, { opacity: gradientOpacityAnim }]}
|
|
145
|
+
>
|
|
146
|
+
<LinearGradient
|
|
147
|
+
colors={gradientColors}
|
|
148
|
+
style={StyleSheet.absoluteFill}
|
|
149
|
+
/>
|
|
150
|
+
</Animated.View>
|
|
151
|
+
|
|
83
152
|
{children}
|
|
84
|
-
</View>
|
|
153
|
+
</Animated.View>
|
|
85
154
|
);
|
|
86
155
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
2
|
+
import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
3
|
+
|
|
4
|
+
export const NAMESPACE = "audio-player";
|
|
5
|
+
|
|
6
|
+
export async function loadItemsFromStorage(key: string) {
|
|
7
|
+
const storedItems = await localStorage.getItem(key, NAMESPACE);
|
|
8
|
+
|
|
9
|
+
return parseJsonIfNeeded(storedItems) || null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const hasDatePassed = (timestamp: number) => {
|
|
13
|
+
// Get the current date and time
|
|
14
|
+
const currentDate = new Date();
|
|
15
|
+
|
|
16
|
+
// Compare the current date's timestamp with the given timestamp
|
|
17
|
+
return currentDate.getTime() > timestamp;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const formatSpeed = (value: number) => {
|
|
21
|
+
let formattedValue = value.toString();
|
|
22
|
+
|
|
23
|
+
// If the value ends with ".0", remove it
|
|
24
|
+
if (formattedValue.endsWith(".0")) {
|
|
25
|
+
formattedValue = formattedValue.slice(0, -2);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Replace "." with "_"
|
|
29
|
+
formattedValue = formattedValue.replace(".", "_");
|
|
30
|
+
|
|
31
|
+
// Return the formatted string with "speed_" prefix
|
|
32
|
+
return `speed_${formattedValue}`;
|
|
33
|
+
};
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
default:
|
|
8
|
-
// boolean, number, string
|
|
9
|
-
return obj.toString();
|
|
10
|
-
}
|
|
1
|
+
import queryString from "query-string";
|
|
2
|
+
import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
|
|
3
|
+
|
|
4
|
+
export const getLiveUrl = (url: string) => {
|
|
5
|
+
// Use the replace method with a regular expression to replace all instances of subClass with livePage
|
|
6
|
+
return url.replace(new RegExp("subClass", "g"), "livePage");
|
|
11
7
|
};
|
|
12
8
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
9
|
+
export const addQueryParam = (
|
|
10
|
+
baseUrl: string,
|
|
11
|
+
paramName: string,
|
|
12
|
+
paramValue: string | number
|
|
13
|
+
) => {
|
|
14
|
+
const [urlWithoutQuery, query] = baseUrl.split("?");
|
|
15
|
+
|
|
16
|
+
const parsedQuery = queryString.parse(query);
|
|
17
|
+
|
|
18
|
+
parsedQuery[paramName] = paramValue.toString();
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
20
|
+
const updatedQueryString = queryString.stringify(parsedQuery);
|
|
21
|
+
|
|
22
|
+
return `${urlWithoutQuery}?${updatedQueryString}`;
|
|
23
|
+
};
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
export const isValidDate = (dateString: string | undefined): boolean => {
|
|
26
|
+
return (
|
|
27
|
+
typeof dateString === "string" &&
|
|
28
|
+
dateString.trim() !== "" &&
|
|
29
|
+
dayjs.utc(dateString).isValid()
|
|
30
|
+
);
|
|
21
31
|
};
|