@draftbit/core 49.5.1-eca979.2 → 49.5.1
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/lib/commonjs/components/Button.js +1 -1
- package/lib/commonjs/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js +1 -1
- package/lib/commonjs/components/MediaPlayer/MediaPlayerCommon.js +1 -1
- package/lib/commonjs/components/MediaPlayer/VideoPlayer/VideoPlayer.js +1 -1
- package/lib/typescript/src/components/Button.js +4 -3
- package/lib/typescript/src/components/Button.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js +3 -25
- package/lib/typescript/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.d.ts +6 -0
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.js +43 -0
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js +11 -3
- package/lib/typescript/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js.map +1 -1
- package/lib/typescript/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/components/Button.js +4 -3
- package/src/components/Button.js.map +1 -1
- package/src/components/Button.tsx +14 -2
- package/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js +3 -25
- package/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js.map +1 -1
- package/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx +8 -31
- package/src/components/MediaPlayer/MediaPlayerCommon.js +43 -0
- package/src/components/MediaPlayer/MediaPlayerCommon.js.map +1 -1
- package/src/components/MediaPlayer/MediaPlayerCommon.ts +56 -0
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js +11 -3
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js.map +1 -1
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.tsx +18 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draftbit/core",
|
|
3
|
-
"version": "49.5.1
|
|
3
|
+
"version": "49.5.1",
|
|
4
4
|
"description": "Core (non-native) Components",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"types": "lib/typescript/src/index.d.ts",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@date-io/date-fns": "^1.3.13",
|
|
43
43
|
"@draftbit/react-theme-provider": "^2.1.1",
|
|
44
|
-
"@draftbit/types": "
|
|
44
|
+
"@draftbit/types": "49.2.6",
|
|
45
45
|
"@expo/vector-icons": "^13.0.0",
|
|
46
46
|
"@gorhom/bottom-sheet": "5.0.0-alpha.7",
|
|
47
47
|
"@material-ui/core": "^4.11.0",
|
|
@@ -74,7 +74,8 @@
|
|
|
74
74
|
"react-native-typography": "^1.4.1",
|
|
75
75
|
"react-native-web-swiper": "^2.2.3",
|
|
76
76
|
"react-native-youtube-iframe": "^2.2.2",
|
|
77
|
-
"react-youtube": "^10.1.0"
|
|
77
|
+
"react-youtube": "^10.1.0",
|
|
78
|
+
"uuid": "^9.0.1"
|
|
78
79
|
},
|
|
79
80
|
"peerDependencies": {
|
|
80
81
|
"react-native-avoid-softinput": "^4.0.1"
|
|
@@ -92,6 +93,7 @@
|
|
|
92
93
|
"@types/lodash.isnumber": "^3.0.6",
|
|
93
94
|
"@types/lodash.omit": "^4.5.6",
|
|
94
95
|
"@types/lodash.tonumber": "^4.0.6",
|
|
96
|
+
"@types/uuid": "^9.0.8",
|
|
95
97
|
"react-native-avoid-softinput": "^4.0.1"
|
|
96
98
|
},
|
|
97
99
|
"eslintIgnore": [
|
|
@@ -114,5 +116,5 @@
|
|
|
114
116
|
],
|
|
115
117
|
"testEnvironment": "node"
|
|
116
118
|
},
|
|
117
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "8029e0ffe47e93ff611df9464da088a6bf948458"
|
|
118
120
|
}
|
package/src/components/Button.js
CHANGED
|
@@ -7,7 +7,7 @@ const CONSTANTS = {
|
|
|
7
7
|
padding: 8,
|
|
8
8
|
icon: 24,
|
|
9
9
|
};
|
|
10
|
-
function Base({ Icon, icon, title, loading, disabled, style, activeOpacity = 0.8, disabledOpacity = 0.8, ...props }) {
|
|
10
|
+
function Base({ Icon, icon, iconPosition = "left", iconSize = CONSTANTS.icon, title, loading, disabled, style, activeOpacity = 0.8, disabledOpacity = 0.8, ...props }) {
|
|
11
11
|
const { color, fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, textTransform, textAlign, textDecorationLine, textDecorationColor, textDecorationStyle, ...buttonStyles } = StyleSheet.flatten(style || {});
|
|
12
12
|
const titleStyles = {
|
|
13
13
|
color,
|
|
@@ -38,8 +38,9 @@ function Base({ Icon, icon, title, loading, disabled, style, activeOpacity = 0.8
|
|
|
38
38
|
];
|
|
39
39
|
}, ...props },
|
|
40
40
|
loading ? (React.createElement(ActivityIndicator, { size: "small", color: color, style: styles.loading })) : null,
|
|
41
|
-
icon && !loading ? (React.createElement(Icon, { name: icon, color: color, style: styles.icon, size:
|
|
42
|
-
React.createElement(Text, { style: titleStyles }, title)
|
|
41
|
+
iconPosition === "left" && icon && !loading ? (React.createElement(Icon, { name: icon, color: color, style: styles.icon, size: iconSize })) : null,
|
|
42
|
+
React.createElement(Text, { style: titleStyles }, title),
|
|
43
|
+
iconPosition === "right" && icon && !loading ? (React.createElement(Icon, { name: icon, color: color, style: styles.icon, size: iconSize })) : null));
|
|
43
44
|
}
|
|
44
45
|
const Solid = ({ style, theme, ...props }) => {
|
|
45
46
|
return (React.createElement(Base, { style: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sourceRoot":"","sources":["Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,IAAI,EACJ,SAAS,EAET,QAAQ,EACR,UAAU,EAEV,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKvC,MAAM,SAAS,GAAG;IAChB,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,CAAC;IACf,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,EAAE;CACT,CAAC;
|
|
1
|
+
{"version":3,"file":"Button.js","sourceRoot":"","sources":["Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,IAAI,EACJ,SAAS,EAET,QAAQ,EACR,UAAU,EAEV,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKvC,MAAM,SAAS,GAAG;IAChB,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,CAAC;IACf,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,EAAE;CACT,CAAC;AAmCF,SAAS,IAAI,CAAC,EACZ,IAAI,EACJ,IAAI,EACJ,YAAY,GAAG,MAAM,EACrB,QAAQ,GAAG,SAAS,CAAC,IAAI,EACzB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,KAAK,EACL,aAAa,GAAG,GAAG,EACnB,eAAe,GAAG,GAAG,EACrB,GAAG,KAAK,EACE;IACV,MAAM,EACJ,KAAK,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,GAAG,YAAY,EAChB,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,IAAK,EAAgB,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAc;QAC7B,KAAK;QACL,UAAU;QACV,UAAU;QACV,QAAQ;QACR,UAAU;QACV,aAAa;QACb,aAAa;QACb,SAAS;QACT,kBAAkB;QAClB,mBAAmB;QACnB,mBAAmB;KACpB,CAAC;IAEF,IAAI,SAAS,KAAK,MAAM,EAAE;QACxB,YAAY,CAAC,cAAc,GAAG,YAAY,CAAC;KAC5C;IAED,IAAI,SAAS,KAAK,OAAO,EAAE;QACzB,YAAY,CAAC,cAAc,GAAG,UAAU,CAAC;KAC1C;IAED,OAAO,CACL,oBAAC,SAAS,IACR,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAC7B,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACrB,OAAO;gBACL,MAAM,CAAC,IAAI;gBACX;oBACE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;iBAClE;gBACD,YAAY;aACb,CAAC;QACJ,CAAC,KACG,KAAK;QAER,OAAO,CAAC,CAAC,CAAC,CACT,oBAAC,iBAAiB,IAAC,IAAI,EAAC,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,GAAI,CACxE,CAAC,CAAC,CAAC,IAAI;QACP,YAAY,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAC7C,oBAAC,IAAI,IACH,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAe,EACtB,KAAK,EAAE,MAAM,CAAC,IAAI,EAClB,IAAI,EAAE,QAAQ,GACd,CACH,CAAC,CAAC,CAAC,IAAI;QACR,oBAAC,IAAI,IAAC,KAAK,EAAE,WAAW,IAAG,KAAK,CAAQ;QACvC,YAAY,KAAK,OAAO,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAC9C,oBAAC,IAAI,IACH,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAe,EACtB,KAAK,EAAE,MAAM,CAAC,IAAI,EAClB,IAAI,EAAE,QAAQ,GACd,CACH,CAAC,CAAC,CAAC,IAAI,CACE,CACb,CAAC;AACJ,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,EAAS,EAAe,EAAE;IAC/D,OAAO,CACL,oBAAC,IAAI,IACH,KAAK,EAAE;YACL;gBACE,KAAK,EAAE,MAAM;gBACb,YAAY,EAAE,KAAK,CAAC,SAAS;gBAC7B,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;aACtC;YACD,KAAK;SACN,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,GAAQ,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,MAAM,GAAQ,SAAS,CAAC,KAAK,CAAC,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,EAAS,EAAe,EAAE;IACjE,OAAO,CACL,oBAAC,IAAI,IACH,KAAK,EAAE;YACL,MAAM,CAAC,OAAO;YACd;gBACE,YAAY,EAAE,KAAK,CAAC,SAAS;gBAC7B,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;gBACjC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;aAC5B;YACD,KAAK;SACN,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,aAAa,GAAQ,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,QAAQ,EAAE,UAAU;QACpB,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;QACxB,SAAS,EAAE,SAAS,CAAC,UAAU;QAC/B,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,KAAK;QACjB,GAAG,QAAQ,CAAC,MAAM,CAAC;YACjB,GAAG,EAAE;gBACH,MAAM,EAAE,SAAS;gBACjB,UAAU,EAAE,MAAM;aACnB;SACF,CAAC;KACH;IACD,OAAO,EAAE;QACP,eAAe,EAAE,aAAa;QAC9B,WAAW,EAAE,CAAC;KACf;IACD,IAAI,EAAE;QACJ,eAAe,EAAE,aAAa;QAC9B,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,SAAS;KACrB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,CAAC;KACf;IACD,IAAI,EAAE;QACJ,GAAG,QAAQ,CAAC,MAAM,CAAC;YACjB,GAAG,EAAE;gBACH,SAAS,EAAE,CAAC;gBACZ,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,QAAQ;aACpB;YACD,OAAO,EAAE;gBACP,YAAY,EAAE,CAAC;gBACf,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,QAAQ;aACpB;SACF,CAAC;KACH;CACF,CAAC,CAAC"}
|
|
@@ -33,6 +33,8 @@ type BaseProps = {
|
|
|
33
33
|
delayLongPress?: number;
|
|
34
34
|
hitSlop?: number;
|
|
35
35
|
icon?: string;
|
|
36
|
+
iconSize?: number;
|
|
37
|
+
iconPosition?: "left" | "right";
|
|
36
38
|
} & PressableProps &
|
|
37
39
|
IconSlot;
|
|
38
40
|
|
|
@@ -55,6 +57,8 @@ type Props = {
|
|
|
55
57
|
function Base({
|
|
56
58
|
Icon,
|
|
57
59
|
icon,
|
|
60
|
+
iconPosition = "left",
|
|
61
|
+
iconSize = CONSTANTS.icon,
|
|
58
62
|
title,
|
|
59
63
|
loading,
|
|
60
64
|
disabled,
|
|
@@ -117,15 +121,23 @@ function Base({
|
|
|
117
121
|
{loading ? (
|
|
118
122
|
<ActivityIndicator size="small" color={color} style={styles.loading} />
|
|
119
123
|
) : null}
|
|
120
|
-
{icon && !loading ? (
|
|
124
|
+
{iconPosition === "left" && icon && !loading ? (
|
|
121
125
|
<Icon
|
|
122
126
|
name={icon}
|
|
123
127
|
color={color as string}
|
|
124
128
|
style={styles.icon}
|
|
125
|
-
size={
|
|
129
|
+
size={iconSize}
|
|
126
130
|
/>
|
|
127
131
|
) : null}
|
|
128
132
|
<Text style={titleStyles}>{title}</Text>
|
|
133
|
+
{iconPosition === "right" && icon && !loading ? (
|
|
134
|
+
<Icon
|
|
135
|
+
name={icon}
|
|
136
|
+
color={color as string}
|
|
137
|
+
style={styles.icon}
|
|
138
|
+
size={iconSize}
|
|
139
|
+
/>
|
|
140
|
+
) : null}
|
|
129
141
|
</Pressable>
|
|
130
142
|
);
|
|
131
143
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Audio, InterruptionModeIOS, InterruptionModeAndroid, } from "expo-av";
|
|
3
|
-
import { mapToMediaPlayerStatus } from "../MediaPlayerCommon";
|
|
3
|
+
import { mapToMediaPlayerStatus, normalizeBase64Source, useSourceDeepCompareEffect, } from "../MediaPlayerCommon";
|
|
4
4
|
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
5
5
|
/**
|
|
6
6
|
* Audio Player component without an interface (UI).
|
|
@@ -56,7 +56,8 @@ const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lowe
|
|
|
56
56
|
bufferedDurationMillis: 0,
|
|
57
57
|
isError: false,
|
|
58
58
|
});
|
|
59
|
-
|
|
59
|
+
let finalSource = await normalizeBase64Source(source);
|
|
60
|
+
const { sound } = await Audio.Sound.createAsync(finalSource);
|
|
60
61
|
setCurrentSound(sound);
|
|
61
62
|
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
|
|
62
63
|
};
|
|
@@ -66,28 +67,5 @@ const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lowe
|
|
|
66
67
|
}, [source]);
|
|
67
68
|
return (React.createElement(MediaPlaybackWrapper, { ref: ref, isPlaying: isPlaying, media: currentSound, onTogglePlayback: onTogglePlayback }));
|
|
68
69
|
});
|
|
69
|
-
// The source provided into the AudioPlayer can be of type {uri: "some uri"}
|
|
70
|
-
// In the case that this object is created inline, each rerender provides a new source object because a new object is initialized everytime
|
|
71
|
-
// This creates an issue with being a useEffect dependency
|
|
72
|
-
//
|
|
73
|
-
// This creates variants of useEffect that checks deep equality of 'uri' to determine if dependency changed or not
|
|
74
|
-
// Follows: https://stackoverflow.com/a/54096391
|
|
75
|
-
function sourceDeepCompareEquals(a, b) {
|
|
76
|
-
if ((a === null || a === void 0 ? void 0 : a.uri) && (b === null || b === void 0 ? void 0 : b.uri)) {
|
|
77
|
-
return a.uri === b.uri;
|
|
78
|
-
}
|
|
79
|
-
return a === b;
|
|
80
|
-
}
|
|
81
|
-
function useSourceDeepCompareMemoize(value) {
|
|
82
|
-
const ref = React.useRef();
|
|
83
|
-
if (!sourceDeepCompareEquals(value, ref.current)) {
|
|
84
|
-
ref.current = value;
|
|
85
|
-
}
|
|
86
|
-
return ref.current;
|
|
87
|
-
}
|
|
88
|
-
function useSourceDeepCompareEffect(callback, dependencies) {
|
|
89
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
90
|
-
React.useEffect(callback, dependencies.map(useSourceDeepCompareMemoize));
|
|
91
|
-
}
|
|
92
70
|
export default HeadlessAudioPlayer;
|
|
93
71
|
//# sourceMappingURL=HeadlessAudioPlayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeadlessAudioPlayer.js","sourceRoot":"","sources":["HeadlessAudioPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,KAAK,EAEL,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,
|
|
1
|
+
{"version":3,"file":"HeadlessAudioPlayer.js","sourceRoot":"","sources":["HeadlessAudioPlayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,11 @@ import {
|
|
|
6
6
|
InterruptionModeAndroid,
|
|
7
7
|
} from "expo-av";
|
|
8
8
|
import { HeadlessAudioPlayerProps } from "./AudioPlayerCommon";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
mapToMediaPlayerStatus,
|
|
11
|
+
normalizeBase64Source,
|
|
12
|
+
useSourceDeepCompareEffect,
|
|
13
|
+
} from "../MediaPlayerCommon";
|
|
10
14
|
import type { MediaPlayerRef } from "../MediaPlayerCommon";
|
|
11
15
|
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
12
16
|
|
|
@@ -89,7 +93,9 @@ const HeadlessAudioPlayer = React.forwardRef<
|
|
|
89
93
|
isError: false,
|
|
90
94
|
});
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
let finalSource = await normalizeBase64Source(source);
|
|
97
|
+
|
|
98
|
+
const { sound } = await Audio.Sound.createAsync(finalSource);
|
|
93
99
|
setCurrentSound(sound);
|
|
94
100
|
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
|
|
95
101
|
};
|
|
@@ -111,33 +117,4 @@ const HeadlessAudioPlayer = React.forwardRef<
|
|
|
111
117
|
}
|
|
112
118
|
);
|
|
113
119
|
|
|
114
|
-
// The source provided into the AudioPlayer can be of type {uri: "some uri"}
|
|
115
|
-
// In the case that this object is created inline, each rerender provides a new source object because a new object is initialized everytime
|
|
116
|
-
// This creates an issue with being a useEffect dependency
|
|
117
|
-
//
|
|
118
|
-
// This creates variants of useEffect that checks deep equality of 'uri' to determine if dependency changed or not
|
|
119
|
-
// Follows: https://stackoverflow.com/a/54096391
|
|
120
|
-
function sourceDeepCompareEquals(a: any, b: any) {
|
|
121
|
-
if (a?.uri && b?.uri) {
|
|
122
|
-
return a.uri === b.uri;
|
|
123
|
-
}
|
|
124
|
-
return a === b;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function useSourceDeepCompareMemoize(value: any) {
|
|
128
|
-
const ref = React.useRef();
|
|
129
|
-
if (!sourceDeepCompareEquals(value, ref.current)) {
|
|
130
|
-
ref.current = value;
|
|
131
|
-
}
|
|
132
|
-
return ref.current;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function useSourceDeepCompareEffect(
|
|
136
|
-
callback: React.EffectCallback,
|
|
137
|
-
dependencies: React.DependencyList
|
|
138
|
-
) {
|
|
139
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
-
React.useEffect(callback, dependencies.map(useSourceDeepCompareMemoize));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
120
|
export default HeadlessAudioPlayer;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import * as FileSystem from "expo-file-system";
|
|
2
|
+
import { v4 as uuid } from "uuid";
|
|
3
|
+
import { Platform } from "react-native";
|
|
4
|
+
import React from "react";
|
|
1
5
|
export function mapToMediaPlayerStatus(status) {
|
|
2
6
|
if (status.isLoaded) {
|
|
3
7
|
return {
|
|
@@ -21,4 +25,43 @@ export function mapToMediaPlayerStatus(status) {
|
|
|
21
25
|
error: status.error,
|
|
22
26
|
};
|
|
23
27
|
}
|
|
28
|
+
// https://stackoverflow.com/a/7874175/8805150
|
|
29
|
+
const BASE_64_REGEX = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
|
|
30
|
+
/**
|
|
31
|
+
* Base64 strings are not playable on iOS and needs to be saved to a file before playing
|
|
32
|
+
*/
|
|
33
|
+
export async function normalizeBase64Source(source) {
|
|
34
|
+
const uri = source === null || source === void 0 ? void 0 : source.uri;
|
|
35
|
+
if (Platform.OS === "ios" && uri && uri.match(BASE_64_REGEX)) {
|
|
36
|
+
const fileName = `${FileSystem.cacheDirectory}${uuid()}`;
|
|
37
|
+
await FileSystem.writeAsStringAsync(fileName, uri, {
|
|
38
|
+
encoding: FileSystem.EncodingType.Base64,
|
|
39
|
+
});
|
|
40
|
+
return { uri: fileName };
|
|
41
|
+
}
|
|
42
|
+
return source;
|
|
43
|
+
}
|
|
44
|
+
// The source provided into the AudioPlayer can be of type {uri: "some uri"}
|
|
45
|
+
// In the case that this object is created inline, each rerender provides a new source object because a new object is initialized everytime
|
|
46
|
+
// This creates an issue with being a useEffect dependency
|
|
47
|
+
//
|
|
48
|
+
// This creates variants of useEffect that checks deep equality of 'uri' to determine if dependency changed or not
|
|
49
|
+
// Follows: https://stackoverflow.com/a/54096391
|
|
50
|
+
function sourceDeepCompareEquals(a, b) {
|
|
51
|
+
if ((a === null || a === void 0 ? void 0 : a.uri) && (b === null || b === void 0 ? void 0 : b.uri)) {
|
|
52
|
+
return a.uri === b.uri;
|
|
53
|
+
}
|
|
54
|
+
return a === b;
|
|
55
|
+
}
|
|
56
|
+
function useSourceDeepCompareMemoize(value) {
|
|
57
|
+
const ref = React.useRef();
|
|
58
|
+
if (!sourceDeepCompareEquals(value, ref.current)) {
|
|
59
|
+
ref.current = value;
|
|
60
|
+
}
|
|
61
|
+
return ref.current;
|
|
62
|
+
}
|
|
63
|
+
export function useSourceDeepCompareEffect(callback, dependencies) {
|
|
64
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
|
+
React.useEffect(callback, dependencies.map(useSourceDeepCompareMemoize));
|
|
66
|
+
}
|
|
24
67
|
//# sourceMappingURL=MediaPlayerCommon.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaPlayerCommon.js","sourceRoot":"","sources":["MediaPlayerCommon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MediaPlayerCommon.js","sourceRoot":"","sources":["MediaPlayerCommon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,MAAM,UAAU,sBAAsB,CACpC,MAAwB;IAExB,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,qBAAqB,EAAE,MAAM,CAAC,cAAc,IAAI,CAAC;YACjD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,CAAC;YAC1C,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,CAAC;YAC1D,OAAO,EAAE,KAAK;SACf,CAAC;KACH;IAED,OAAO;QACL,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,KAAK;QAChB,WAAW,EAAE,KAAK;QAClB,qBAAqB,EAAE,CAAC;QACxB,cAAc,EAAE,CAAC;QACjB,sBAAsB,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;AACJ,CAAC;AAED,8CAA8C;AAC9C,MAAM,aAAa,GACjB,kEAAkE,CAAC;AAErE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAwB;IAExB,MAAM,GAAG,GAAwB,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,GAAG,CAAC;IAErD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;QAC5D,MAAM,QAAQ,GAAG,GAAG,UAAU,CAAC,cAAc,GAAG,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,UAAU,CAAC,kBAAkB,CAAC,QAAQ,EAAE,GAAG,EAAE;YACjD,QAAQ,EAAE,UAAU,CAAC,YAAY,CAAC,MAAM;SACzC,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;KAC1B;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,2IAA2I;AAC3I,0DAA0D;AAC1D,EAAE;AACF,kHAAkH;AAClH,gDAAgD;AAChD,SAAS,uBAAuB,CAAC,CAAM,EAAE,CAAM;IAC7C,IAAI,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,GAAG,MAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,GAAG,CAAA,EAAE;QACpB,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;KACxB;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAU;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE;QAChD,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;KACrB;IACD,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,QAA8B,EAC9B,YAAkC;IAElC,uDAAuD;IACvD,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { AVPlaybackSource, AVPlaybackStatus } from "expo-av";
|
|
2
|
+
import * as FileSystem from "expo-file-system";
|
|
3
|
+
import { v4 as uuid } from "uuid";
|
|
4
|
+
import { Platform } from "react-native";
|
|
5
|
+
import React from "react";
|
|
2
6
|
|
|
3
7
|
export interface MediaPlayerStatus {
|
|
4
8
|
isPlaying: boolean;
|
|
@@ -50,3 +54,55 @@ export function mapToMediaPlayerStatus(
|
|
|
50
54
|
error: status.error,
|
|
51
55
|
};
|
|
52
56
|
}
|
|
57
|
+
|
|
58
|
+
// https://stackoverflow.com/a/7874175/8805150
|
|
59
|
+
const BASE_64_REGEX =
|
|
60
|
+
/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Base64 strings are not playable on iOS and needs to be saved to a file before playing
|
|
64
|
+
*/
|
|
65
|
+
export async function normalizeBase64Source(
|
|
66
|
+
source: AVPlaybackSource
|
|
67
|
+
): Promise<AVPlaybackSource> {
|
|
68
|
+
const uri: string | undefined = (source as any)?.uri;
|
|
69
|
+
|
|
70
|
+
if (Platform.OS === "ios" && uri && uri.match(BASE_64_REGEX)) {
|
|
71
|
+
const fileName = `${FileSystem.cacheDirectory}${uuid()}`;
|
|
72
|
+
await FileSystem.writeAsStringAsync(fileName, uri, {
|
|
73
|
+
encoding: FileSystem.EncodingType.Base64,
|
|
74
|
+
});
|
|
75
|
+
return { uri: fileName };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return source;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The source provided into the AudioPlayer can be of type {uri: "some uri"}
|
|
82
|
+
// In the case that this object is created inline, each rerender provides a new source object because a new object is initialized everytime
|
|
83
|
+
// This creates an issue with being a useEffect dependency
|
|
84
|
+
//
|
|
85
|
+
// This creates variants of useEffect that checks deep equality of 'uri' to determine if dependency changed or not
|
|
86
|
+
// Follows: https://stackoverflow.com/a/54096391
|
|
87
|
+
function sourceDeepCompareEquals(a: any, b: any) {
|
|
88
|
+
if (a?.uri && b?.uri) {
|
|
89
|
+
return a.uri === b.uri;
|
|
90
|
+
}
|
|
91
|
+
return a === b;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function useSourceDeepCompareMemoize(value: any) {
|
|
95
|
+
const ref = React.useRef();
|
|
96
|
+
if (!sourceDeepCompareEquals(value, ref.current)) {
|
|
97
|
+
ref.current = value;
|
|
98
|
+
}
|
|
99
|
+
return ref.current;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function useSourceDeepCompareEffect(
|
|
103
|
+
callback: React.EffectCallback,
|
|
104
|
+
dependencies: React.DependencyList
|
|
105
|
+
) {
|
|
106
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
107
|
+
React.useEffect(callback, dependencies.map(useSourceDeepCompareMemoize));
|
|
108
|
+
}
|
|
@@ -2,11 +2,12 @@ import React from "react";
|
|
|
2
2
|
import { Video as VideoPlayerComponent, ResizeMode as ExpoResizeMode, VideoFullscreenUpdate, } from "expo-av";
|
|
3
3
|
import { extractSizeStyles } from "../../../utilities";
|
|
4
4
|
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
5
|
-
import { mapToMediaPlayerStatus } from "../MediaPlayerCommon";
|
|
6
|
-
const VideoPlayer = React.forwardRef(({ style, resizeMode = "contain", posterResizeMode = "cover", onPlaybackStatusUpdate: onPlaybackStatusUpdateProp, onPlaybackFinish, ...rest }, ref) => {
|
|
5
|
+
import { mapToMediaPlayerStatus, normalizeBase64Source, useSourceDeepCompareEffect, } from "../MediaPlayerCommon";
|
|
6
|
+
const VideoPlayer = React.forwardRef(({ style, resizeMode = "contain", posterResizeMode = "cover", onPlaybackStatusUpdate: onPlaybackStatusUpdateProp, onPlaybackFinish, source, ...rest }, ref) => {
|
|
7
7
|
const [videoMediaObject, setVideoMediaObject] = React.useState();
|
|
8
8
|
const [isPlaying, setIsPlaying] = React.useState(false);
|
|
9
9
|
const [isFullscreen, setIsFullscreen] = React.useState(false);
|
|
10
|
+
const [currentSource, setCurrentSource] = React.useState();
|
|
10
11
|
const mediaPlaybackWrapperRef = React.useRef(null);
|
|
11
12
|
const sizeStyles = extractSizeStyles(style);
|
|
12
13
|
let mappedResizeMode;
|
|
@@ -64,12 +65,19 @@ const VideoPlayer = React.forwardRef(({ style, resizeMode = "contain", posterRes
|
|
|
64
65
|
// Include 'isPlaying' as dependency because 'togglePlayback' changes when it changes
|
|
65
66
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
67
|
[toggleFullscreen, isPlaying]);
|
|
68
|
+
useSourceDeepCompareEffect(() => {
|
|
69
|
+
const updateSource = async () => {
|
|
70
|
+
const finalSource = await normalizeBase64Source(source);
|
|
71
|
+
setCurrentSource(finalSource);
|
|
72
|
+
};
|
|
73
|
+
updateSource();
|
|
74
|
+
}, [source]);
|
|
67
75
|
return (React.createElement(MediaPlaybackWrapper, { media: videoMediaObject, isPlaying: isPlaying, ref: mediaPlaybackWrapperRef },
|
|
68
76
|
React.createElement(VideoPlayerComponent
|
|
69
77
|
// https://docs.expo.dev/versions/latest/sdk/av/#example-video to see why ref is handled this way
|
|
70
78
|
, {
|
|
71
79
|
// https://docs.expo.dev/versions/latest/sdk/av/#example-video to see why ref is handled this way
|
|
72
|
-
ref: (component) => setVideoMediaObject(component), style: style, videoStyle: sizeStyles, resizeMode: mappedResizeMode, posterStyle: [sizeStyles, { resizeMode: posterResizeMode }], onPlaybackStatusUpdate: onPlaybackStatusUpdate, onFullscreenUpdate: (e) => onFullscreenUpdate(e.fullscreenUpdate), ...rest })));
|
|
80
|
+
ref: (component) => setVideoMediaObject(component), style: style, videoStyle: sizeStyles, resizeMode: mappedResizeMode, posterStyle: [sizeStyles, { resizeMode: posterResizeMode }], onPlaybackStatusUpdate: onPlaybackStatusUpdate, onFullscreenUpdate: (e) => onFullscreenUpdate(e.fullscreenUpdate), source: currentSource, ...rest })));
|
|
73
81
|
});
|
|
74
82
|
export default VideoPlayer;
|
|
75
83
|
//# sourceMappingURL=VideoPlayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["VideoPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,KAAK,IAAI,oBAAoB,EAE7B,UAAU,IAAI,cAAc,EAE5B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["VideoPlayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -6,11 +6,16 @@ import {
|
|
|
6
6
|
ResizeMode as ExpoResizeMode,
|
|
7
7
|
AVPlaybackStatus,
|
|
8
8
|
VideoFullscreenUpdate,
|
|
9
|
+
AVPlaybackSource,
|
|
9
10
|
} from "expo-av";
|
|
10
11
|
import { extractSizeStyles } from "../../../utilities";
|
|
11
12
|
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
12
13
|
import type { Playback } from "expo-av/src/AV";
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
mapToMediaPlayerStatus,
|
|
16
|
+
normalizeBase64Source,
|
|
17
|
+
useSourceDeepCompareEffect,
|
|
18
|
+
} from "../MediaPlayerCommon";
|
|
14
19
|
import type { MediaPlayerRef, MediaPlayerProps } from "../MediaPlayerCommon";
|
|
15
20
|
|
|
16
21
|
type ResizeMode = "contain" | "cover" | "stretch";
|
|
@@ -36,6 +41,7 @@ const VideoPlayer = React.forwardRef<VideoPlayerRef, VideoPlayerProps>(
|
|
|
36
41
|
posterResizeMode = "cover",
|
|
37
42
|
onPlaybackStatusUpdate: onPlaybackStatusUpdateProp,
|
|
38
43
|
onPlaybackFinish,
|
|
44
|
+
source,
|
|
39
45
|
...rest
|
|
40
46
|
},
|
|
41
47
|
ref
|
|
@@ -44,6 +50,8 @@ const VideoPlayer = React.forwardRef<VideoPlayerRef, VideoPlayerProps>(
|
|
|
44
50
|
React.useState<VideoPlayerComponent | null>();
|
|
45
51
|
const [isPlaying, setIsPlaying] = React.useState(false);
|
|
46
52
|
const [isFullscreen, setIsFullscreen] = React.useState(false);
|
|
53
|
+
const [currentSource, setCurrentSource] =
|
|
54
|
+
React.useState<AVPlaybackSource>();
|
|
47
55
|
const mediaPlaybackWrapperRef = React.useRef<MediaPlayerRef>(null);
|
|
48
56
|
|
|
49
57
|
const sizeStyles = extractSizeStyles(style);
|
|
@@ -110,6 +118,14 @@ const VideoPlayer = React.forwardRef<VideoPlayerRef, VideoPlayerProps>(
|
|
|
110
118
|
[toggleFullscreen, isPlaying]
|
|
111
119
|
);
|
|
112
120
|
|
|
121
|
+
useSourceDeepCompareEffect(() => {
|
|
122
|
+
const updateSource = async () => {
|
|
123
|
+
const finalSource = await normalizeBase64Source(source);
|
|
124
|
+
setCurrentSource(finalSource);
|
|
125
|
+
};
|
|
126
|
+
updateSource();
|
|
127
|
+
}, [source]);
|
|
128
|
+
|
|
113
129
|
return (
|
|
114
130
|
<MediaPlaybackWrapper
|
|
115
131
|
media={videoMediaObject as Playback | undefined}
|
|
@@ -125,6 +141,7 @@ const VideoPlayer = React.forwardRef<VideoPlayerRef, VideoPlayerProps>(
|
|
|
125
141
|
posterStyle={[sizeStyles, { resizeMode: posterResizeMode }]}
|
|
126
142
|
onPlaybackStatusUpdate={onPlaybackStatusUpdate}
|
|
127
143
|
onFullscreenUpdate={(e) => onFullscreenUpdate(e.fullscreenUpdate)}
|
|
144
|
+
source={currentSource}
|
|
128
145
|
{...rest}
|
|
129
146
|
/>
|
|
130
147
|
</MediaPlaybackWrapper>
|