@draftbit/core 48.1.1-bfaf07.2 → 48.2.0
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/src/components/MediaPlayer/AudioPlayer/AudioPlayerCommon.d.ts +22 -0
- package/lib/src/components/MediaPlayer/AudioPlayer/AudioPlayerCommon.js.map +1 -0
- package/lib/src/components/MediaPlayer/AudioPlayer/AudioPlayerWithInterface.d.ts +7 -0
- package/lib/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerWithInterface.js +6 -6
- package/lib/src/components/MediaPlayer/AudioPlayer/AudioPlayerWithInterface.js.map +1 -0
- package/lib/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/HeadlessAudioPlayer.d.ts +3 -2
- package/lib/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/HeadlessAudioPlayer.js +9 -48
- package/lib/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js.map +1 -0
- package/lib/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/index.d.ts +5 -4
- package/{src/components → lib/src/components/MediaPlayer}/AudioPlayer/index.js +1 -1
- package/lib/src/components/MediaPlayer/AudioPlayer/index.js.map +1 -0
- package/lib/src/components/MediaPlayer/MediaPlaybackWrapper.d.ts +15 -0
- package/lib/src/components/MediaPlayer/MediaPlaybackWrapper.js +32 -0
- package/lib/src/components/MediaPlayer/MediaPlaybackWrapper.js.map +1 -0
- package/lib/src/components/MediaPlayer/MediaPlayerCommon.d.ts +21 -0
- package/lib/src/components/MediaPlayer/MediaPlayerCommon.js +24 -0
- package/lib/src/components/MediaPlayer/MediaPlayerCommon.js.map +1 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/VideoPlayer.d.ts +15 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js +73 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js.map +1 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/index.d.ts +2 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/index.js +2 -0
- package/lib/src/components/MediaPlayer/VideoPlayer/index.js.map +1 -0
- package/lib/src/components/NumberInput.d.ts +5 -3
- package/lib/src/components/NumberInput.js +13 -3
- package/lib/src/components/NumberInput.js.map +1 -1
- package/lib/src/components/TextField.d.ts +2 -1
- package/lib/src/components/TextField.js +3 -2
- package/lib/src/components/TextField.js.map +1 -1
- package/lib/src/components/TextInput.d.ts +8 -0
- package/lib/src/components/TextInput.js +15 -0
- package/lib/src/components/TextInput.js.map +1 -0
- package/lib/src/hooks.d.ts +1 -0
- package/lib/src/hooks.js +12 -0
- package/lib/src/hooks.js.map +1 -1
- package/lib/src/index.d.ts +3 -1
- package/lib/src/index.js +3 -1
- package/lib/src/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/components/MediaPlayer/AudioPlayer/AudioPlayerCommon.ts +25 -0
- package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerWithInterface.js +6 -6
- package/src/components/MediaPlayer/AudioPlayer/AudioPlayerWithInterface.js.map +1 -0
- package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerWithInterface.tsx +11 -9
- package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/HeadlessAudioPlayer.js +9 -48
- package/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js.map +1 -0
- package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/HeadlessAudioPlayer.tsx +19 -64
- package/{lib/src/components → src/components/MediaPlayer}/AudioPlayer/index.js +1 -1
- package/src/components/MediaPlayer/AudioPlayer/index.js.map +1 -0
- package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/index.tsx +4 -4
- package/src/components/MediaPlayer/MediaPlaybackWrapper.js +32 -0
- package/src/components/MediaPlayer/MediaPlaybackWrapper.js.map +1 -0
- package/src/components/MediaPlayer/MediaPlaybackWrapper.tsx +56 -0
- package/src/components/MediaPlayer/MediaPlayerCommon.js +24 -0
- package/src/components/MediaPlayer/MediaPlayerCommon.js.map +1 -0
- package/src/components/MediaPlayer/MediaPlayerCommon.ts +50 -0
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js +73 -0
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js.map +1 -0
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.tsx +136 -0
- package/src/components/MediaPlayer/VideoPlayer/index.js +2 -0
- package/src/components/MediaPlayer/VideoPlayer/index.js.map +1 -0
- package/src/components/MediaPlayer/VideoPlayer/index.ts +2 -0
- package/src/components/NumberInput.js +13 -3
- package/src/components/NumberInput.js.map +1 -1
- package/src/components/NumberInput.tsx +34 -5
- package/src/components/TextField.js +3 -2
- package/src/components/TextField.js.map +1 -1
- package/src/components/TextField.tsx +2 -2
- package/src/components/TextInput.js +15 -0
- package/src/components/TextInput.js.map +1 -0
- package/src/components/TextInput.tsx +35 -0
- package/src/hooks.js +12 -0
- package/src/hooks.js.map +1 -1
- package/src/hooks.ts +16 -0
- package/src/index.js +3 -1
- package/src/index.js.map +1 -1
- package/src/index.tsx +6 -1
- package/lib/src/components/AudioPlayer/AudioPlayerCommon.d.ts +0 -39
- package/lib/src/components/AudioPlayer/AudioPlayerCommon.js.map +0 -1
- package/lib/src/components/AudioPlayer/AudioPlayerWithInterface.d.ts +0 -6
- package/lib/src/components/AudioPlayer/AudioPlayerWithInterface.js.map +0 -1
- package/lib/src/components/AudioPlayer/HeadlessAudioPlayer.js.map +0 -1
- package/lib/src/components/AudioPlayer/index.js.map +0 -1
- package/src/components/AudioPlayer/AudioPlayerCommon.ts +0 -44
- package/src/components/AudioPlayer/AudioPlayerWithInterface.js.map +0 -1
- package/src/components/AudioPlayer/HeadlessAudioPlayer.js.map +0 -1
- package/src/components/AudioPlayer/index.js.map +0 -1
- /package/lib/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerCommon.js +0 -0
- /package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerCommon.js +0 -0
- /package/src/components/{AudioPlayer → MediaPlayer/AudioPlayer}/AudioPlayerCommon.js.map +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draftbit/core",
|
|
3
|
-
"version": "48.
|
|
3
|
+
"version": "48.2.0",
|
|
4
4
|
"description": "Core (non-native) Components",
|
|
5
5
|
"main": "lib/src/index.js",
|
|
6
6
|
"types": "lib/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": "48.2.0",
|
|
45
45
|
"@expo/vector-icons": "^13.0.0",
|
|
46
46
|
"@material-ui/core": "^4.11.0",
|
|
47
47
|
"@material-ui/pickers": "^3.2.10",
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
],
|
|
98
98
|
"testEnvironment": "node"
|
|
99
99
|
},
|
|
100
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "607fd3f8eee06a6def15d3709c263c3e5fb7ea3f"
|
|
101
101
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle, TextStyle } from "react-native";
|
|
2
|
+
import type { Theme } from "../../../styles/DefaultTheme";
|
|
3
|
+
import { MediaPlayerProps } from "../MediaPlayerCommon";
|
|
4
|
+
|
|
5
|
+
export type AudioInterruptionMode = "lower volume" | "stop";
|
|
6
|
+
|
|
7
|
+
export interface HeadlessAudioPlayerProps extends MediaPlayerProps {
|
|
8
|
+
interruptionMode?: AudioInterruptionMode;
|
|
9
|
+
playsInBackground?: boolean;
|
|
10
|
+
playsInSilentModeIOS?: boolean;
|
|
11
|
+
playThroughEarpieceAndroid?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface AudioPlayerInterfaceProps {
|
|
15
|
+
style?: StyleProp<ViewStyle & TextStyle>;
|
|
16
|
+
thumbColor?: string;
|
|
17
|
+
completedTrackColor?: string;
|
|
18
|
+
remainingTrackColor?: string;
|
|
19
|
+
togglePlaybackIconSize?: number;
|
|
20
|
+
togglePlaybackIconColor?: string;
|
|
21
|
+
hidePlaybackIcon?: boolean;
|
|
22
|
+
hideDuration?: boolean;
|
|
23
|
+
hideSlider?: boolean;
|
|
24
|
+
theme: Theme;
|
|
25
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Text, View, StyleSheet } from "react-native";
|
|
3
3
|
import { AntDesign } from "@expo/vector-icons";
|
|
4
|
-
import { withTheme } from "
|
|
4
|
+
import { withTheme } from "../../../theming";
|
|
5
5
|
import Slider from "@react-native-community/slider";
|
|
6
6
|
import HeadlessAudioPlayer from "./HeadlessAudioPlayer";
|
|
7
|
-
import Pressable from "
|
|
7
|
+
import Pressable from "../../Pressable";
|
|
8
8
|
/**
|
|
9
9
|
* Built on top of HeadlessAudioPlayer to provide a simple interface for playing audio
|
|
10
10
|
*/
|
|
@@ -72,7 +72,7 @@ const AudioPlayerWithInterface = React.forwardRef(({ style, theme, thumbColor =
|
|
|
72
72
|
}
|
|
73
73
|
return (React.createElement(React.Fragment, null,
|
|
74
74
|
React.createElement(HeadlessAudioPlayer, { ...rest, ref: headlessAudioPlayerRef, onPlaybackStatusUpdate: onPlaybackStatusUpdate, onPlaybackFinish: onPlaybackFinish }),
|
|
75
|
-
React.createElement(View, { style: [
|
|
75
|
+
React.createElement(View, { testID: "audio-player-interface", style: [
|
|
76
76
|
{
|
|
77
77
|
backgroundColor: theme.colors.background,
|
|
78
78
|
borderColor: theme.colors.divider,
|
|
@@ -80,9 +80,9 @@ const AudioPlayerWithInterface = React.forwardRef(({ style, theme, thumbColor =
|
|
|
80
80
|
styles.container,
|
|
81
81
|
viewStyles,
|
|
82
82
|
] },
|
|
83
|
-
!hidePlaybackIcon && (React.createElement(Pressable, { onPress: () => { var _a; return (_a = headlessAudioPlayerRef.current) === null || _a === void 0 ? void 0 : _a.togglePlayback(); }, style: styles.spacingEnd },
|
|
83
|
+
!hidePlaybackIcon && (React.createElement(Pressable, { testID: "audio-player-playback-icon", onPress: () => { var _a; return (_a = headlessAudioPlayerRef.current) === null || _a === void 0 ? void 0 : _a.togglePlayback(); }, style: styles.spacingEnd },
|
|
84
84
|
React.createElement(AntDesign, { name: iconName, size: togglePlaybackIconSize, color: togglePlaybackIconColor }))),
|
|
85
|
-
!hideDuration && (React.createElement(Text, { style: [
|
|
85
|
+
!hideDuration && (React.createElement(Text, { testID: "audio-player-duration", style: [
|
|
86
86
|
{ color: theme.colors.strong },
|
|
87
87
|
styles.spacingEnd,
|
|
88
88
|
{ ...textStyles },
|
|
@@ -91,7 +91,7 @@ const AudioPlayerWithInterface = React.forwardRef(({ style, theme, thumbColor =
|
|
|
91
91
|
" /",
|
|
92
92
|
" ",
|
|
93
93
|
formatDuration(durationMillis || 0))),
|
|
94
|
-
!hideSlider && (React.createElement(Slider, { style: styles.slider, minimumTrackTintColor: completedTrackColor, maximumTrackTintColor: remainingTrackColor, thumbTintColor: thumbColor, minimumValue: 0, value: sliderPositionMillis, maximumValue: durationMillis, onValueChange: onSliderChange, onSlidingComplete: onSlidingComplete })))));
|
|
94
|
+
!hideSlider && (React.createElement(Slider, { testID: "audio-player-slider", style: styles.slider, minimumTrackTintColor: completedTrackColor, maximumTrackTintColor: remainingTrackColor, thumbTintColor: thumbColor, minimumValue: 0, value: sliderPositionMillis, maximumValue: durationMillis, onValueChange: onSliderChange, onSlidingComplete: onSlidingComplete })))));
|
|
95
95
|
});
|
|
96
96
|
const styles = StyleSheet.create({
|
|
97
97
|
container: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioPlayerWithInterface.js","sourceRoot":"","sources":["AudioPlayerWithInterface.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Text, View, StyleSheet } from "react-native";
|
|
3
3
|
import { AntDesign } from "@expo/vector-icons";
|
|
4
|
-
import { withTheme } from "
|
|
4
|
+
import { withTheme } from "../../../theming";
|
|
5
5
|
import Slider from "@react-native-community/slider";
|
|
6
6
|
import HeadlessAudioPlayer from "./HeadlessAudioPlayer";
|
|
7
7
|
import {
|
|
8
8
|
AudioPlayerInterfaceProps,
|
|
9
|
-
AudioPlayerStatus,
|
|
10
9
|
HeadlessAudioPlayerProps,
|
|
11
|
-
HeadlessAudioPlayerRef,
|
|
12
10
|
} from "./AudioPlayerCommon";
|
|
13
|
-
import Pressable from "
|
|
11
|
+
import Pressable from "../../Pressable";
|
|
12
|
+
import { MediaPlayerRef, MediaPlayerStatus } from "../MediaPlayerCommon";
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Built on top of HeadlessAudioPlayer to provide a simple interface for playing audio
|
|
17
16
|
*/
|
|
18
17
|
const AudioPlayerWithInterface = React.forwardRef<
|
|
19
|
-
|
|
18
|
+
MediaPlayerRef,
|
|
20
19
|
AudioPlayerInterfaceProps & HeadlessAudioPlayerProps
|
|
21
20
|
>(
|
|
22
21
|
(
|
|
@@ -44,12 +43,11 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
44
43
|
>(1);
|
|
45
44
|
const [isDraggingSlider, setIsDraggingSlider] = React.useState(false);
|
|
46
45
|
const [sliderPositionMillis, setSliderPositionMillis] = React.useState(0);
|
|
47
|
-
const newHeadlessAudioPlayerRef =
|
|
48
|
-
React.useRef<HeadlessAudioPlayerRef>(null);
|
|
46
|
+
const newHeadlessAudioPlayerRef = React.useRef<MediaPlayerRef>(null);
|
|
49
47
|
|
|
50
48
|
// Use the provided ref or default to new ref when not provided
|
|
51
49
|
const headlessAudioPlayerRef = ref
|
|
52
|
-
? (ref as React.RefObject<
|
|
50
|
+
? (ref as React.RefObject<MediaPlayerRef>)
|
|
53
51
|
: newHeadlessAudioPlayerRef;
|
|
54
52
|
|
|
55
53
|
const {
|
|
@@ -81,7 +79,7 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
81
79
|
textDecorationStyle,
|
|
82
80
|
};
|
|
83
81
|
|
|
84
|
-
const onPlaybackStatusUpdate = (status:
|
|
82
|
+
const onPlaybackStatusUpdate = (status: MediaPlayerStatus) => {
|
|
85
83
|
setIsLoading(status.isLoading);
|
|
86
84
|
setDurationMillis(status.durationMillis);
|
|
87
85
|
setSliderPositionMillis(status.currentPositionMillis);
|
|
@@ -128,6 +126,7 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
128
126
|
onPlaybackFinish={onPlaybackFinish}
|
|
129
127
|
/>
|
|
130
128
|
<View
|
|
129
|
+
testID="audio-player-interface"
|
|
131
130
|
style={[
|
|
132
131
|
{
|
|
133
132
|
backgroundColor: theme.colors.background,
|
|
@@ -139,6 +138,7 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
139
138
|
>
|
|
140
139
|
{!hidePlaybackIcon && (
|
|
141
140
|
<Pressable
|
|
141
|
+
testID="audio-player-playback-icon"
|
|
142
142
|
onPress={() => headlessAudioPlayerRef.current?.togglePlayback()}
|
|
143
143
|
style={styles.spacingEnd}
|
|
144
144
|
>
|
|
@@ -151,6 +151,7 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
151
151
|
)}
|
|
152
152
|
{!hideDuration && (
|
|
153
153
|
<Text
|
|
154
|
+
testID="audio-player-duration"
|
|
154
155
|
style={[
|
|
155
156
|
{ color: theme.colors.strong },
|
|
156
157
|
styles.spacingEnd,
|
|
@@ -163,6 +164,7 @@ const AudioPlayerWithInterface = React.forwardRef<
|
|
|
163
164
|
)}
|
|
164
165
|
{!hideSlider && (
|
|
165
166
|
<Slider
|
|
167
|
+
testID="audio-player-slider"
|
|
166
168
|
style={styles.slider}
|
|
167
169
|
minimumTrackTintColor={completedTrackColor}
|
|
168
170
|
maximumTrackTintColor={remainingTrackColor}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Audio, InterruptionModeIOS, InterruptionModeAndroid, } from "expo-av";
|
|
3
|
+
import { mapToMediaPlayerStatus } from "../MediaPlayerCommon";
|
|
4
|
+
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
3
5
|
/**
|
|
4
6
|
* Audio Player component without an interface (UI).
|
|
5
7
|
* Only handles playing of the audio and provides callbacks and ref functions
|
|
@@ -31,33 +33,18 @@ const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lowe
|
|
|
31
33
|
playThroughEarpieceAndroid,
|
|
32
34
|
]);
|
|
33
35
|
const onPlaybackStatusUpdate = (status) => {
|
|
36
|
+
const mappedStatus = mapToMediaPlayerStatus(status);
|
|
37
|
+
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp(mappedStatus);
|
|
34
38
|
if (status.isLoaded) {
|
|
35
|
-
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp({
|
|
36
|
-
isPlaying: status.isPlaying,
|
|
37
|
-
isLoading: false,
|
|
38
|
-
isBuffering: status.isBuffering,
|
|
39
|
-
currentPositionMillis: status.positionMillis || 0,
|
|
40
|
-
durationMillis: status.durationMillis || 0,
|
|
41
|
-
bufferedDurationMillis: status.playableDurationMillis || 0,
|
|
42
|
-
isError: false,
|
|
43
|
-
});
|
|
44
39
|
if (status.didJustFinish) {
|
|
45
40
|
onPlaybackFinish === null || onPlaybackFinish === void 0 ? void 0 : onPlaybackFinish();
|
|
46
41
|
}
|
|
47
42
|
setIsPlaying(status.isPlaying);
|
|
48
43
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
isBuffering: false,
|
|
54
|
-
currentPositionMillis: 0,
|
|
55
|
-
durationMillis: 0,
|
|
56
|
-
bufferedDurationMillis: 0,
|
|
57
|
-
isError: true,
|
|
58
|
-
error: status.error,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
44
|
+
};
|
|
45
|
+
const onTogglePlayback = () => {
|
|
46
|
+
//Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
47
|
+
updateAudioMode();
|
|
61
48
|
};
|
|
62
49
|
const loadAudio = async () => {
|
|
63
50
|
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp({
|
|
@@ -73,37 +60,11 @@ const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lowe
|
|
|
73
60
|
setCurrentSound(sound);
|
|
74
61
|
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
|
|
75
62
|
};
|
|
76
|
-
const togglePlayback = React.useCallback(async () => {
|
|
77
|
-
//Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
78
|
-
await updateAudioMode();
|
|
79
|
-
if (isPlaying) {
|
|
80
|
-
await (currentSound === null || currentSound === void 0 ? void 0 : currentSound.pauseAsync());
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
await (currentSound === null || currentSound === void 0 ? void 0 : currentSound.playAsync());
|
|
84
|
-
}
|
|
85
|
-
}, [currentSound, updateAudioMode, isPlaying]);
|
|
86
|
-
const seekToPosition = React.useCallback(async (positionMillis) => {
|
|
87
|
-
await (currentSound === null || currentSound === void 0 ? void 0 : currentSound.setPositionAsync(positionMillis));
|
|
88
|
-
}, [currentSound]);
|
|
89
63
|
useSourceDeepCompareEffect(() => {
|
|
90
64
|
loadAudio();
|
|
91
65
|
// Ignore dependency of loadAudio
|
|
92
66
|
}, [source]);
|
|
93
|
-
React.
|
|
94
|
-
return currentSound
|
|
95
|
-
? () => {
|
|
96
|
-
currentSound.unloadAsync();
|
|
97
|
-
}
|
|
98
|
-
: undefined;
|
|
99
|
-
}, [currentSound]);
|
|
100
|
-
React.useImperativeHandle(ref, () => {
|
|
101
|
-
return {
|
|
102
|
-
seekToPosition,
|
|
103
|
-
togglePlayback,
|
|
104
|
-
};
|
|
105
|
-
}, [seekToPosition, togglePlayback]);
|
|
106
|
-
return null;
|
|
67
|
+
return (React.createElement(MediaPlaybackWrapper, { ref: ref, isPlaying: isPlaying, media: currentSound, onTogglePlayback: onTogglePlayback }));
|
|
107
68
|
});
|
|
108
69
|
// The source provided into the AudioPlayer can be of type {uri: "some uri"}
|
|
109
70
|
// In the case that this object is created inline, each rerender provides a new source object because a new object is initialized everytime
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeadlessAudioPlayer.js","sourceRoot":"","sources":["HeadlessAudioPlayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,17 +5,16 @@ import {
|
|
|
5
5
|
InterruptionModeIOS,
|
|
6
6
|
InterruptionModeAndroid,
|
|
7
7
|
} from "expo-av";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "./AudioPlayerCommon";
|
|
8
|
+
import { HeadlessAudioPlayerProps } from "./AudioPlayerCommon";
|
|
9
|
+
import { MediaPlayerRef, mapToMediaPlayerStatus } from "../MediaPlayerCommon";
|
|
10
|
+
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Audio Player component without an interface (UI).
|
|
15
14
|
* Only handles playing of the audio and provides callbacks and ref functions
|
|
16
15
|
*/
|
|
17
16
|
const HeadlessAudioPlayer = React.forwardRef<
|
|
18
|
-
|
|
17
|
+
MediaPlayerRef,
|
|
19
18
|
HeadlessAudioPlayerProps
|
|
20
19
|
>(
|
|
21
20
|
(
|
|
@@ -62,36 +61,22 @@ const HeadlessAudioPlayer = React.forwardRef<
|
|
|
62
61
|
]);
|
|
63
62
|
|
|
64
63
|
const onPlaybackStatusUpdate = (status: AVPlaybackStatus) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
isPlaying: status.isPlaying,
|
|
68
|
-
isLoading: false,
|
|
69
|
-
isBuffering: status.isBuffering,
|
|
70
|
-
currentPositionMillis: status.positionMillis || 0,
|
|
71
|
-
durationMillis: status.durationMillis || 0,
|
|
72
|
-
bufferedDurationMillis: status.playableDurationMillis || 0,
|
|
73
|
-
isError: false,
|
|
74
|
-
});
|
|
64
|
+
const mappedStatus = mapToMediaPlayerStatus(status);
|
|
65
|
+
onPlaybackStatusUpdateProp?.(mappedStatus);
|
|
75
66
|
|
|
67
|
+
if (status.isLoaded) {
|
|
76
68
|
if (status.didJustFinish) {
|
|
77
69
|
onPlaybackFinish?.();
|
|
78
70
|
}
|
|
79
|
-
|
|
80
71
|
setIsPlaying(status.isPlaying);
|
|
81
|
-
} else if (status.error) {
|
|
82
|
-
onPlaybackStatusUpdateProp?.({
|
|
83
|
-
isPlaying: false,
|
|
84
|
-
isLoading: false,
|
|
85
|
-
isBuffering: false,
|
|
86
|
-
currentPositionMillis: 0,
|
|
87
|
-
durationMillis: 0,
|
|
88
|
-
bufferedDurationMillis: 0,
|
|
89
|
-
isError: true,
|
|
90
|
-
error: status.error,
|
|
91
|
-
});
|
|
92
72
|
}
|
|
93
73
|
};
|
|
94
74
|
|
|
75
|
+
const onTogglePlayback = () => {
|
|
76
|
+
//Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
77
|
+
updateAudioMode();
|
|
78
|
+
};
|
|
79
|
+
|
|
95
80
|
const loadAudio = async () => {
|
|
96
81
|
onPlaybackStatusUpdateProp?.({
|
|
97
82
|
isPlaying: false,
|
|
@@ -108,50 +93,20 @@ const HeadlessAudioPlayer = React.forwardRef<
|
|
|
108
93
|
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
|
|
109
94
|
};
|
|
110
95
|
|
|
111
|
-
const togglePlayback = React.useCallback(async () => {
|
|
112
|
-
//Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
113
|
-
await updateAudioMode();
|
|
114
|
-
|
|
115
|
-
if (isPlaying) {
|
|
116
|
-
await currentSound?.pauseAsync();
|
|
117
|
-
} else {
|
|
118
|
-
await currentSound?.playAsync();
|
|
119
|
-
}
|
|
120
|
-
}, [currentSound, updateAudioMode, isPlaying]);
|
|
121
|
-
|
|
122
|
-
const seekToPosition = React.useCallback(
|
|
123
|
-
async (positionMillis: number) => {
|
|
124
|
-
await currentSound?.setPositionAsync(positionMillis);
|
|
125
|
-
},
|
|
126
|
-
[currentSound]
|
|
127
|
-
);
|
|
128
|
-
|
|
129
96
|
useSourceDeepCompareEffect(() => {
|
|
130
97
|
loadAudio();
|
|
131
98
|
|
|
132
99
|
// Ignore dependency of loadAudio
|
|
133
100
|
}, [source]);
|
|
134
101
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
React.useImperativeHandle(
|
|
144
|
-
ref,
|
|
145
|
-
() => {
|
|
146
|
-
return {
|
|
147
|
-
seekToPosition,
|
|
148
|
-
togglePlayback,
|
|
149
|
-
};
|
|
150
|
-
},
|
|
151
|
-
[seekToPosition, togglePlayback]
|
|
102
|
+
return (
|
|
103
|
+
<MediaPlaybackWrapper
|
|
104
|
+
ref={ref}
|
|
105
|
+
isPlaying={isPlaying}
|
|
106
|
+
media={currentSound}
|
|
107
|
+
onTogglePlayback={onTogglePlayback}
|
|
108
|
+
/>
|
|
152
109
|
);
|
|
153
|
-
|
|
154
|
-
return null;
|
|
155
110
|
}
|
|
156
111
|
);
|
|
157
112
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { withTheme } from "
|
|
2
|
+
import { withTheme } from "../../../theming";
|
|
3
3
|
import HeadlessAudioPlayer from "./HeadlessAudioPlayer";
|
|
4
4
|
import AudioPlayerWithInterface from "./AudioPlayerWithInterface";
|
|
5
5
|
const AudioPlayer = React.forwardRef(({ mode = "interface", ...rest }, ref) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,wBAAwB,MAAM,4BAA4B,CAAC;AAOlE,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAGlC,CAAC,EAAE,IAAI,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE;IACzC,QAAQ,IAAI,EAAE;QACZ,KAAK,UAAU;YACb,OAAO,oBAAC,mBAAmB,IAAC,GAAG,EAAE,GAAG,KAAM,IAAI,GAAI,CAAC;QACrD,KAAK,WAAW;YACd,gEAAgE;YAChE,OAAO,oBAAC,wBAAwB,IAAC,GAAG,EAAE,GAAG,KAAM,IAAI,GAAI,CAAC;KAC3D;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,SAAS,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { withTheme } from "
|
|
2
|
+
import { withTheme } from "../../../theming";
|
|
3
3
|
import {
|
|
4
4
|
AudioPlayerInterfaceProps,
|
|
5
5
|
HeadlessAudioPlayerProps,
|
|
6
|
-
HeadlessAudioPlayerRef,
|
|
7
6
|
} from "./AudioPlayerCommon";
|
|
8
7
|
import HeadlessAudioPlayer from "./HeadlessAudioPlayer";
|
|
9
8
|
import AudioPlayerWithInterface from "./AudioPlayerWithInterface";
|
|
9
|
+
import { MediaPlayerRef } from "../MediaPlayerCommon";
|
|
10
10
|
|
|
11
11
|
interface AudioPlayerProps {
|
|
12
12
|
mode?: "interface" | "headless";
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const AudioPlayer = React.forwardRef<
|
|
16
|
-
|
|
16
|
+
MediaPlayerRef,
|
|
17
17
|
AudioPlayerProps & AudioPlayerInterfaceProps & HeadlessAudioPlayerProps
|
|
18
18
|
>(({ mode = "interface", ...rest }, ref) => {
|
|
19
19
|
switch (mode) {
|
|
@@ -27,4 +27,4 @@ const AudioPlayer = React.forwardRef<
|
|
|
27
27
|
|
|
28
28
|
export default withTheme(AudioPlayer);
|
|
29
29
|
|
|
30
|
-
export {
|
|
30
|
+
export { MediaPlayerRef as AudioPlayerRef } from "../MediaPlayerCommon";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper component that handles common media playback operations that is reusable with audio and video players
|
|
4
|
+
*/
|
|
5
|
+
const MediaPlaybackWrapper = React.forwardRef(({ media, isPlaying, onTogglePlayback, children }, ref) => {
|
|
6
|
+
const togglePlayback = React.useCallback(async () => {
|
|
7
|
+
onTogglePlayback === null || onTogglePlayback === void 0 ? void 0 : onTogglePlayback();
|
|
8
|
+
if (isPlaying) {
|
|
9
|
+
await (media === null || media === void 0 ? void 0 : media.pauseAsync());
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
await (media === null || media === void 0 ? void 0 : media.playAsync());
|
|
13
|
+
}
|
|
14
|
+
}, [media, isPlaying, onTogglePlayback]);
|
|
15
|
+
const seekToPosition = React.useCallback(async (positionMillis) => {
|
|
16
|
+
await (media === null || media === void 0 ? void 0 : media.setPositionAsync(positionMillis));
|
|
17
|
+
}, [media]);
|
|
18
|
+
React.useEffect(() => {
|
|
19
|
+
return media
|
|
20
|
+
? () => {
|
|
21
|
+
media.unloadAsync();
|
|
22
|
+
}
|
|
23
|
+
: undefined;
|
|
24
|
+
}, [media]);
|
|
25
|
+
React.useImperativeHandle(ref, () => ({
|
|
26
|
+
seekToPosition,
|
|
27
|
+
togglePlayback,
|
|
28
|
+
}), [seekToPosition, togglePlayback]);
|
|
29
|
+
return React.createElement(React.Fragment, null, children);
|
|
30
|
+
});
|
|
31
|
+
export default MediaPlaybackWrapper;
|
|
32
|
+
//# sourceMappingURL=MediaPlaybackWrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPlaybackWrapper.js","sourceRoot":"","sources":["MediaPlaybackWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B;;GAEG;AACH,MAAM,oBAAoB,GAAG,KAAK,CAAC,UAAU,CAG3C,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;IAC1D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAClD,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAC;QAErB,IAAI,SAAS,EAAE;YACb,MAAM,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,UAAU,EAAE,CAAA,CAAC;SAC3B;aAAM;YACL,MAAM,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,EAAE,CAAA,CAAC;SAC1B;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEzC,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,KAAK,EAAE,cAAsB,EAAE,EAAE;QAC/B,MAAM,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,gBAAgB,CAAC,cAAc,CAAC,CAAA,CAAC;IAChD,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,KAAK;YACV,CAAC,CAAC,GAAG,EAAE;gBACH,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,CAAC;YACH,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,KAAK,CAAC,mBAAmB,CACvB,GAAG,EACH,GAAG,EAAE,CAAC,CAAC;QACL,cAAc;QACd,cAAc;KACf,CAAC,EACF,CAAC,cAAc,EAAE,cAAc,CAAC,CACjC,CAAC;IAEF,OAAO,0CAAG,QAAQ,CAAI,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Playback } from "expo-av/src/AV";
|
|
3
|
+
|
|
4
|
+
import { MediaPlayerRef } from "./MediaPlayerCommon";
|
|
5
|
+
|
|
6
|
+
interface MediaPlaybackWrapperProps {
|
|
7
|
+
media?: Playback;
|
|
8
|
+
isPlaying?: boolean;
|
|
9
|
+
onTogglePlayback?: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Wrapper component that handles common media playback operations that is reusable with audio and video players
|
|
14
|
+
*/
|
|
15
|
+
const MediaPlaybackWrapper = React.forwardRef<
|
|
16
|
+
MediaPlayerRef,
|
|
17
|
+
React.PropsWithChildren<MediaPlaybackWrapperProps>
|
|
18
|
+
>(({ media, isPlaying, onTogglePlayback, children }, ref) => {
|
|
19
|
+
const togglePlayback = React.useCallback(async () => {
|
|
20
|
+
onTogglePlayback?.();
|
|
21
|
+
|
|
22
|
+
if (isPlaying) {
|
|
23
|
+
await media?.pauseAsync();
|
|
24
|
+
} else {
|
|
25
|
+
await media?.playAsync();
|
|
26
|
+
}
|
|
27
|
+
}, [media, isPlaying, onTogglePlayback]);
|
|
28
|
+
|
|
29
|
+
const seekToPosition = React.useCallback(
|
|
30
|
+
async (positionMillis: number) => {
|
|
31
|
+
await media?.setPositionAsync(positionMillis);
|
|
32
|
+
},
|
|
33
|
+
[media]
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
React.useEffect(() => {
|
|
37
|
+
return media
|
|
38
|
+
? () => {
|
|
39
|
+
media.unloadAsync();
|
|
40
|
+
}
|
|
41
|
+
: undefined;
|
|
42
|
+
}, [media]);
|
|
43
|
+
|
|
44
|
+
React.useImperativeHandle(
|
|
45
|
+
ref,
|
|
46
|
+
() => ({
|
|
47
|
+
seekToPosition,
|
|
48
|
+
togglePlayback,
|
|
49
|
+
}),
|
|
50
|
+
[seekToPosition, togglePlayback]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return <>{children}</>;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export default MediaPlaybackWrapper;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function mapToMediaPlayerStatus(status) {
|
|
2
|
+
if (status.isLoaded) {
|
|
3
|
+
return {
|
|
4
|
+
isPlaying: status.isPlaying,
|
|
5
|
+
isLoading: false,
|
|
6
|
+
isBuffering: status.isBuffering,
|
|
7
|
+
currentPositionMillis: status.positionMillis || 0,
|
|
8
|
+
durationMillis: status.durationMillis || 0,
|
|
9
|
+
bufferedDurationMillis: status.playableDurationMillis || 0,
|
|
10
|
+
isError: false,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
isPlaying: false,
|
|
15
|
+
isLoading: false,
|
|
16
|
+
isBuffering: false,
|
|
17
|
+
currentPositionMillis: 0,
|
|
18
|
+
durationMillis: 0,
|
|
19
|
+
bufferedDurationMillis: 0,
|
|
20
|
+
isError: true,
|
|
21
|
+
error: status.error,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=MediaPlayerCommon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPlayerCommon.js","sourceRoot":"","sources":["MediaPlayerCommon.ts"],"names":[],"mappings":"AAwBA,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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AVPlaybackSource, AVPlaybackStatus } from "expo-av";
|
|
2
|
+
|
|
3
|
+
export interface MediaPlayerStatus {
|
|
4
|
+
isPlaying: boolean;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
isBuffering: boolean;
|
|
7
|
+
currentPositionMillis: number;
|
|
8
|
+
durationMillis: number;
|
|
9
|
+
bufferedDurationMillis: number;
|
|
10
|
+
isError: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface MediaPlayerRef {
|
|
15
|
+
seekToPosition: (positionMillis: number) => void;
|
|
16
|
+
togglePlayback: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MediaPlayerProps {
|
|
20
|
+
onPlaybackStatusUpdate?: (status: MediaPlayerStatus) => void;
|
|
21
|
+
onPlaybackFinish?: () => void;
|
|
22
|
+
source: AVPlaybackSource;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function mapToMediaPlayerStatus(
|
|
26
|
+
status: AVPlaybackStatus
|
|
27
|
+
): MediaPlayerStatus {
|
|
28
|
+
if (status.isLoaded) {
|
|
29
|
+
return {
|
|
30
|
+
isPlaying: status.isPlaying,
|
|
31
|
+
isLoading: false,
|
|
32
|
+
isBuffering: status.isBuffering,
|
|
33
|
+
currentPositionMillis: status.positionMillis || 0,
|
|
34
|
+
durationMillis: status.durationMillis || 0,
|
|
35
|
+
bufferedDurationMillis: status.playableDurationMillis || 0,
|
|
36
|
+
isError: false,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
isPlaying: false,
|
|
42
|
+
isLoading: false,
|
|
43
|
+
isBuffering: false,
|
|
44
|
+
currentPositionMillis: 0,
|
|
45
|
+
durationMillis: 0,
|
|
46
|
+
bufferedDurationMillis: 0,
|
|
47
|
+
isError: true,
|
|
48
|
+
error: status.error,
|
|
49
|
+
};
|
|
50
|
+
}
|