@applicaster/quick-brick-player 13.0.0-rc.13 → 13.0.0-rc.131

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 (49) hide show
  1. package/package.json +27 -14
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +107 -68
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +142 -295
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +45 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +291 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +9 -27
  8. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  9. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +77 -81
  10. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +222 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +87 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +20 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +1 -0
  14. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +99 -0
  15. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +112 -0
  16. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +36 -0
  17. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +212 -0
  18. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +215 -0
  19. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +128 -0
  20. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  21. package/src/Player/AudioLayer/Layout/const.ts +26 -0
  22. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  23. package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
  24. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  25. package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
  26. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  27. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  28. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  29. package/src/Player/AudioLayer/Layout/utils.ts +7 -0
  30. package/src/Player/AudioLayer/SleepTimerManager.ts +130 -0
  31. package/src/Player/AudioLayer/SpeedManager.ts +52 -0
  32. package/src/Player/AudioLayer/components/SleepTimerModalHeader/SleepTimerModalHeader.tsx +66 -0
  33. package/src/Player/AudioLayer/components/SleepTimerModalHeader/index.ts +1 -0
  34. package/src/Player/AudioLayer/useSleepTimerModal.ts +109 -0
  35. package/src/Player/AudioLayer/utils.ts +27 -0
  36. package/src/Player/Const/sleepTimerOptions.ts +41 -0
  37. package/src/Player/Const/speedOptions.ts +4 -0
  38. package/src/Player/Utils/Utils.ts +0 -5
  39. package/src/Player/Utils/index.tsx +123 -0
  40. package/src/Player/hooks/useIsCasting.tsx +57 -0
  41. package/src/Player/index.tsx +106 -49
  42. package/src/QuickBrickPlayer.tsx +3 -0
  43. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  44. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
  45. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
  46. package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
  47. package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
  48. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
  49. package/src/utils/utils.ts +0 -25
@@ -1,452 +0,0 @@
1
- import * as React from "react";
2
- import * as R from "ramda";
3
- import { View } from "react-native";
4
- import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
5
-
6
- import {
7
- ProgressBar,
8
- Controls,
9
- TransportInfo,
10
- CountDown,
11
- } from "@applicaster/quick-brick-mobile-transport-controls";
12
-
13
- import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
14
-
15
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
16
- import {
17
- forwardButton,
18
- playbackButton,
19
- rewindButton,
20
- skipToStartButton,
21
- skipToLiveButton,
22
- PADDING_HORIZONTAL,
23
- speedButton,
24
- sleepButton,
25
- } from "./defaultLayoutsConts";
26
- import { AudioDescription } from "../AudioDescription";
27
- import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
28
- import { useLanguageData } from "@applicaster/zapp-react-native-utils/reactHooks/player";
29
- import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
30
- import { useEffect, useMemo, useState } from "react";
31
- import {
32
- useModalAnimationContext,
33
- AnimationComponent,
34
- ComponentAnimationType,
35
- } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
36
- import DockedLayout from "./DockedLayout";
37
- import { isValidDate } from "../../Utils";
38
-
39
- type Dimensions = {
40
- width: number;
41
- height: number;
42
- };
43
-
44
- type LayoutProps = {
45
- entry: ZappEntry;
46
- layoutState: {
47
- inline: boolean;
48
- docked: boolean;
49
- isModal: boolean;
50
- };
51
- playerState: {
52
- currentTime: number;
53
- duration: number;
54
- seekableDuration: number;
55
- isLive: boolean;
56
- isPaused: boolean;
57
- isBuffering: boolean;
58
- };
59
- sleepTimerDate: number;
60
- value: GetValue;
61
- playbackSpeedName: string;
62
- playbackSleepName: string;
63
- configuration: { [key: string]: any };
64
- onPlaybackButtonPress: () => void;
65
- onRewindButtonPress: () => void;
66
- onForwardButtonPress: () => void;
67
- onSpeedButtonPress: () => void;
68
- onSleepButtonPress: () => void;
69
- cancelSleepTimer: () => void;
70
- onPlayerSeek: (targetTime: number) => void;
71
- onSkipLive: () => void;
72
- onSkipStart: () => void;
73
- onCloseVideoModal: () => void;
74
- maximiseVideoModal: () => void;
75
- dimensions: Dimensions;
76
- playNextData: PlayNextData;
77
- title: string | number;
78
- summary: string | number;
79
- defaultDimensions: Dimensions;
80
- };
81
-
82
- const Styles = {
83
- container: { flex: 1 },
84
- tabletContainer: (isPortraitMode: boolean) => ({
85
- flex: 1,
86
- alignItems: "center",
87
- justifyContent: isPortraitMode ? "center" : "flex-start",
88
- }),
89
- playerImageWrapper: {
90
- width: "100%",
91
- maxHeight: 750,
92
- marginTop: 80,
93
- },
94
- tabletLayout: {
95
- width: 463,
96
- marginBottom: 80,
97
- },
98
- controls: (isTablet: boolean, isLiveShowFullControls: boolean) => ({
99
- height: isTablet ? 64 : 50,
100
- marginHorizontal: 10,
101
- justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
102
- }),
103
- backgroundImageContainer: (dimensions: Dimensions, isTablet: boolean) => {
104
- const mobileValue = dimensions.width
105
- ? dimensions.width - PADDING_HORIZONTAL * 2
106
- : 330;
107
-
108
- return {
109
- width: isTablet ? 463 : mobileValue,
110
- height: isTablet ? 463 : mobileValue,
111
- };
112
- },
113
- backgroundImageContainerImageStyle: (
114
- isTablet: boolean,
115
- docked: boolean,
116
- startComponentsAnimation: boolean,
117
- isActiveGesture: boolean
118
- ) => ({
119
- borderRadius:
120
- (startComponentsAnimation && isActiveGesture) || docked
121
- ? 0
122
- : isTablet
123
- ? 24
124
- : 10,
125
- }),
126
-
127
- paddingHorizontal: {
128
- paddingHorizontal: PADDING_HORIZONTAL,
129
- },
130
-
131
- controlsMobile: {
132
- height: 50,
133
- marginHorizontal: 24,
134
- },
135
- controlsTablet: {
136
- height: 96,
137
- marginHorizontal: 24,
138
- },
139
- separator: {
140
- height: 20,
141
- },
142
- flexDirectionRow: {
143
- flexDirection: "row",
144
- },
145
- alignItemsCenter: {
146
- alignItems: "center",
147
- },
148
- };
149
-
150
- export default function DefaultLayout(props: LayoutProps) {
151
- const {
152
- entry,
153
- layoutState,
154
- playerState,
155
- value,
156
- onPlaybackButtonPress,
157
- onRewindButtonPress,
158
- onForwardButtonPress,
159
- onPlayerSeek,
160
- onSkipStart,
161
- onSkipLive,
162
- onSpeedButtonPress,
163
- onSleepButtonPress,
164
- playbackSpeedName,
165
- playbackSleepName,
166
- configuration,
167
- dimensions,
168
- cancelSleepTimer,
169
- sleepTimerDate,
170
- title,
171
- summary,
172
- defaultDimensions,
173
- } = props;
174
-
175
- const isTablet = useIsTablet();
176
- const { width, height } = dimensions;
177
- const isPortraitMode = width < height;
178
- const isLiveContent = playerState.isLive;
179
- const docked = layoutState.docked;
180
-
181
- const languageData = useLanguageData("audio-player");
182
-
183
- const showCounter = useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
184
-
185
- const controller = playerManager.getActivePlayer();
186
- const liveButton = Boolean(value("live_badge_enabled"));
187
- const sleepTitle = value("playback_sleep_countdown_label");
188
-
189
- const [timeLeft, setTimeLeft] = useState(
190
- sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
191
- );
192
-
193
- let showFullControls = !controller?.isAd();
194
-
195
- const startTime = entry.extensions?.live?.start_time;
196
- const endTime = entry.extensions?.live?.end_time;
197
-
198
- const hasValidStartTime = isValidDate(startTime);
199
- const hasValidEndTime = isValidDate(endTime);
200
-
201
- const isDateBasedLiveContent =
202
- isLiveContent && hasValidStartTime && hasValidEndTime;
203
-
204
- const needsToShowProgressBar =
205
- (isLiveContent &&
206
- (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
207
- !isLiveContent;
208
-
209
- const startTimestamp = hasValidStartTime
210
- ? dayjs.utc(startTime!).valueOf()
211
- : undefined;
212
-
213
- const endTimestamp = hasValidEndTime
214
- ? dayjs.utc(endTime!).valueOf()
215
- : undefined;
216
-
217
- if (isLiveContent) {
218
- const seekEnabled = Boolean(value("liveSeekingEnabled"));
219
-
220
- showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
221
- }
222
-
223
- const actionButtons = React.useMemo(
224
- () =>
225
- R.compose(
226
- R.take(2),
227
- R.map(R.trim),
228
- R.split(","),
229
- R.propOr("", "player_action_buttons")
230
- )(configuration),
231
- [configuration.player_action_buttons]
232
- );
233
-
234
- const controlButtons = React.useCallback((): Array<ControlsButton> => {
235
- const play = playbackButton({
236
- playerState,
237
- liveButton,
238
- isTablet,
239
- isLiveShowFullControls: showFullControls && isLiveContent,
240
- onPress: onPlaybackButtonPress,
241
- });
242
-
243
- if (!showFullControls) {
244
- return [play];
245
- }
246
-
247
- const rewind = rewindButton({
248
- isTablet,
249
- onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
250
- });
251
-
252
- const forward = forwardButton({
253
- isTablet,
254
- onPress: controller?.hasSeekableDuration?.()
255
- ? onForwardButtonPress
256
- : null,
257
- });
258
-
259
- const speed = speedButton({
260
- isTablet,
261
- onPress: onSpeedButtonPress,
262
- name: playbackSpeedName,
263
- });
264
-
265
- const sleep = sleepButton({
266
- isTablet,
267
- onPress: onSleepButtonPress,
268
- name: playbackSleepName,
269
- });
270
-
271
- if (isLiveContent) {
272
- const skipToStart = skipToStartButton({
273
- isTablet,
274
- onPress: onSkipStart,
275
- });
276
-
277
- const skipToLive = skipToLiveButton({
278
- isTablet,
279
- onPress: onSkipLive,
280
- });
281
-
282
- return [skipToStart, rewind, play, forward, skipToLive];
283
- }
284
-
285
- return [speed, rewind, play, forward, sleep];
286
- }, [
287
- playerState,
288
- liveButton,
289
- isTablet,
290
- onPlaybackButtonPress,
291
- onRewindButtonPress,
292
- onForwardButtonPress,
293
- onSpeedButtonPress,
294
- showFullControls,
295
- onSkipStart,
296
- onSkipLive,
297
- isLiveContent,
298
- playbackSpeedName,
299
- playbackSleepName,
300
- controller,
301
- ]);
302
-
303
- useEffect(() => {
304
- if (showCounter && sleepTimerDate !== 0) {
305
- setTimeLeft(sleepTimerDate - Date.now());
306
-
307
- const intervalId = setInterval(() => {
308
- setTimeLeft(() => {
309
- const newTimeLeft = sleepTimerDate - Date.now();
310
-
311
- if (newTimeLeft <= 0) {
312
- clearInterval(intervalId);
313
-
314
- cancelSleepTimer();
315
-
316
- return 0;
317
- } else {
318
- return newTimeLeft;
319
- }
320
- });
321
- }, 1000);
322
-
323
- return () => clearInterval(intervalId);
324
- } else {
325
- setTimeLeft(0);
326
- }
327
- }, [sleepTimerDate, showCounter, cancelSleepTimer]);
328
-
329
- const Separator = () => <View style={Styles.separator} />;
330
-
331
- const defaultImageDimensions = React.useMemo(
332
- () =>
333
- defaultDimensions &&
334
- Styles.backgroundImageContainer(defaultDimensions, isTablet),
335
- [defaultDimensions, isTablet]
336
- );
337
-
338
- const { isActiveGesture, startComponentsAnimation } =
339
- useModalAnimationContext();
340
-
341
- return (
342
- <View
343
- style={
344
- isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
345
- }
346
- >
347
- <AnimationComponent animationType={ComponentAnimationType.componentFade}>
348
- <TransportInfo
349
- content={entry}
350
- value={value}
351
- visible={true}
352
- languageData={languageData}
353
- layoutState={layoutState}
354
- actionButtons={actionButtons}
355
- />
356
- </AnimationComponent>
357
- <AnimationComponent
358
- animationType={ComponentAnimationType.moveUpComponent}
359
- style={isTablet ? Styles.playerImageWrapper : undefined}
360
- >
361
- <AnimationComponent
362
- animationType={ComponentAnimationType.moveComponentHorizontal}
363
- additionalData={{
364
- disableAnimatedComponent: !isTablet,
365
- moveValue: (dimensions.width - 463) / 2,
366
- extraAnimation: !isTablet
367
- ? {
368
- [ComponentAnimationType.audioPlayerPaddingHorizontal]: {
369
- style: Styles.paddingHorizontal,
370
- },
371
- }
372
- : null,
373
- }}
374
- style={isTablet ? Styles.alignItemsCenter : undefined}
375
- >
376
- <PlayerImageBackground
377
- entry={entry}
378
- style={Styles.backgroundImageContainer(dimensions, isTablet)}
379
- imageStyle={Styles.backgroundImageContainerImageStyle(
380
- isTablet,
381
- docked,
382
- startComponentsAnimation,
383
- isActiveGesture
384
- )}
385
- defaultImageDimensions={defaultImageDimensions}
386
- />
387
- </AnimationComponent>
388
-
389
- <DockedLayout {...props} />
390
- </AnimationComponent>
391
- <View
392
- style={[
393
- Styles.paddingHorizontal,
394
- isTablet ? Styles.tabletLayout : undefined,
395
- ]}
396
- >
397
- {!docked && (
398
- <AnimationComponent
399
- animationType={ComponentAnimationType.componentFade}
400
- >
401
- <AudioDescription
402
- title={title}
403
- summary={summary}
404
- value={value}
405
- layoutState={layoutState}
406
- />
407
- <Separator />
408
- {needsToShowProgressBar && (
409
- <View>
410
- <ProgressBar
411
- content={entry}
412
- value={value}
413
- visible={true}
414
- layoutState={layoutState}
415
- onPlayerSeek={onPlayerSeek}
416
- playerState={playerState}
417
- disableFullscreen={true}
418
- sliderStyle={2}
419
- startTimestamp={startTimestamp}
420
- endTimestamp={endTimestamp}
421
- isDateBasedLiveContent={isDateBasedLiveContent}
422
- onSkipLive={onSkipLive}
423
- />
424
-
425
- {showCounter && timeLeft >= 0 && (
426
- <CountDown
427
- timeLeft={timeLeft}
428
- value={value}
429
- title={sleepTitle}
430
- />
431
- )}
432
-
433
- <Separator />
434
- </View>
435
- )}
436
- <Controls
437
- value={value}
438
- visible={true}
439
- keepAlive={null}
440
- buttons={controlButtons}
441
- style={Styles.controls(
442
- isTablet,
443
- isLiveContent && showFullControls
444
- )}
445
- playerState={playerState}
446
- />
447
- </AnimationComponent>
448
- )}
449
- </View>
450
- </View>
451
- );
452
- }
@@ -1,3 +0,0 @@
1
- import LinearGradient from "react-native-linear-gradient";
2
-
3
- export default LinearGradient;
@@ -1,3 +0,0 @@
1
- const WebLinearGradient = require("react-native-web-linear-gradient").default;
2
-
3
- export default WebLinearGradient;
@@ -1 +0,0 @@
1
- export { default } from "./LinearGradientProxy";
@@ -1,155 +0,0 @@
1
- /* eslint-disable react/prop-types */
2
- import * as React from "react";
3
- import { Animated, StyleSheet, View } from "react-native";
4
- import LinearGradient from "../LinearGradient";
5
- import { getDominantColor, getPalettes } from "../../../utils/utils";
6
- import { useEffect } from "react";
7
-
8
- type MagicBGProps = {
9
- children: React.ReactNode;
10
- image: string;
11
- fallbackUrl?: string;
12
- defaultColor: string;
13
- colors: string[];
14
- };
15
-
16
- const defaultColors = {
17
- overlay: "rgba(0, 0, 0, 0.35)",
18
- defaultGradientStart: "rgba(0, 0, 0, 0.25)",
19
- defaultGradientEnd: "rgba(0, 0, 0, 0)",
20
- };
21
-
22
- const styles = StyleSheet.create({
23
- container: {
24
- flex: 1,
25
- },
26
- fullScreenOverlay: {
27
- ...StyleSheet.absoluteFillObject,
28
- backgroundColor: defaultColors.overlay,
29
- },
30
- gradientOverlay: {
31
- position: "absolute",
32
- bottom: 0,
33
- left: 0,
34
- right: 0,
35
- height: "100%",
36
- },
37
- });
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
-
53
- export const MagicBG: React.FC<MagicBGProps> = ({
54
- children,
55
- image,
56
- fallbackUrl = "",
57
- colors = [],
58
- defaultColor,
59
- }) => {
60
- const [dominantColor, setDominantColor] =
61
- React.useState<string>(defaultColor);
62
-
63
- const [gradientColors, setGradientColors] = React.useState<string[]>([
64
- defaultColors.defaultGradientStart,
65
- defaultColors.defaultGradientEnd,
66
- ]);
67
-
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
70
-
71
- useEffect(() => {
72
- const animateColors = () => {
73
- Animated.timing(backgroundColorAnim, {
74
- toValue: 1,
75
- duration: 500,
76
- useNativeDriver: false,
77
- }).start();
78
-
79
- Animated.timing(gradientOpacityAnim, {
80
- toValue: 1,
81
- duration: 500,
82
- useNativeDriver: false,
83
- }).start();
84
- };
85
-
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();
99
- } catch (error) {
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
- ]);
112
-
113
- setDominantColor(defaultColor);
114
- }
115
- }
116
- } else {
117
- setGradientColors([
118
- defaultColors.defaultGradientStart,
119
- defaultColors.defaultGradientEnd,
120
- ]);
121
-
122
- setDominantColor(defaultColor);
123
- }
124
- };
125
-
126
- fetchColors();
127
- }, []);
128
-
129
- const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
130
- inputRange: [0, 1],
131
- outputRange: ["black", dominantColor],
132
- });
133
-
134
- return (
135
- <Animated.View
136
- style={[
137
- styles.container,
138
- { backgroundColor: interpolatedBackgroundColor },
139
- ]}
140
- >
141
- <View style={styles.fullScreenOverlay} />
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
-
152
- {children}
153
- </Animated.View>
154
- );
155
- };
@@ -1,7 +0,0 @@
1
- import keyMirror from "keymirror";
2
-
3
- export default keyMirror({
4
- contain: null,
5
- cover: null,
6
- stretch: null,
7
- });
@@ -1,25 +0,0 @@
1
- import RNColorThief from "@applicaster/react-native-color-thief";
2
- import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
3
-
4
- const { log_error } = createLogger({
5
- subsystem: "UIComponent",
6
- category: "MagicBackground",
7
- });
8
-
9
- export const getDominantColor = async (imageUrl: string): Promise<any> => {
10
- try {
11
- return await RNColorThief.getColor(imageUrl, 1, false);
12
- } catch (error) {
13
- log_error("Failed to get the dominant color", { error });
14
- throw error;
15
- }
16
- };
17
-
18
- export const getPalettes = async (imageUrl: string): Promise<any> => {
19
- try {
20
- return await RNColorThief.getPalette(imageUrl, 3, 1, true);
21
- } catch (error) {
22
- log_error("Failed to get the palette", { error });
23
- throw error;
24
- }
25
- };