diff --git a/packages/react-native-audio-api/package.json b/packages/react-native-audio-api/package.json index f6ef5e51b..f12024be0 100644 --- a/packages/react-native-audio-api/package.json +++ b/packages/react-native-audio-api/package.json @@ -12,6 +12,7 @@ "types": "lib/typescript/index.d.ts", "files": [ "src/", + "unstable/react/", "lib/", "common/", "android/src/main/AndroidManifest.xml", diff --git a/packages/react-native-audio-api/src/unstable/react/Audio/Audio.tsx b/packages/react-native-audio-api/src/unstable/react/Audio/Audio.tsx new file mode 100644 index 000000000..ed1986d23 --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/Audio/Audio.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +import type { AudioProps } from './types'; +import { useStableAudioProps } from './utils'; + +const Audio: React.FC = (inProps) => { + const { + autoPlay, + controls, + loop, + muted, + preload, + source, + playbackRate, + preservesPitch, + volume, + } = useStableAudioProps(inProps); + + return null; +}; + +export default Audio; diff --git a/packages/react-native-audio-api/src/unstable/react/Audio/Audio.web.tsx b/packages/react-native-audio-api/src/unstable/react/Audio/Audio.web.tsx new file mode 100644 index 000000000..e67bf7418 --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/Audio/Audio.web.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import type { AudioProps } from './types'; + +const Audio: React.FC = (props) => { + return null; +}; + +export default Audio; diff --git a/packages/react-native-audio-api/src/unstable/react/Audio/index.ts b/packages/react-native-audio-api/src/unstable/react/Audio/index.ts new file mode 100644 index 000000000..7789950e7 --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/Audio/index.ts @@ -0,0 +1,3 @@ +export { default } from './Audio'; + +export type { AudioProps, AudioSource, TimeRanges } from './types'; diff --git a/packages/react-native-audio-api/src/unstable/react/Audio/types.ts b/packages/react-native-audio-api/src/unstable/react/Audio/types.ts new file mode 100644 index 000000000..b7c6b1512 --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/Audio/types.ts @@ -0,0 +1,64 @@ +export interface AudioURISource { + uri?: string | undefined; + // bundle?: string | undefined; + method?: string | undefined; + headers?: { [key: string]: string } | undefined; + // cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached' | undefined; + body?: string | undefined; +} + +export type AudioRequireSource = number; + +export interface TimeRanges { + length: number; + start(index: number): number; + end(index: number): number; +} + +export type AudioSource = + | AudioURISource + | AudioRequireSource + | ReadonlyArray; + +export type PreloadType = 'auto' | 'metadata' | 'none'; + +interface AudioControlProps { + autoPlay: boolean; + controls: boolean; // TBD: should we support control display at all? + loop: boolean; + muted: boolean; + preload: PreloadType; + source: AudioSource; + playbackRate: number; + preservesPitch: boolean; + volume: number; +} + +interface AudioReadonlyProps { + // TODO: decide if we want to expose them this way + // duration: number; + // currentTime: number; + // ended: boolean; + // paused: boolean; + // buffered: TimeRanges; +} + +type TMPEmptyEventHandler = () => void; + +interface AudioEventProps { + onLoadStart?: TMPEmptyEventHandler; + onLoad?: TMPEmptyEventHandler; + onError?: TMPEmptyEventHandler; + onProgress?: TMPEmptyEventHandler; + onSeeked?: TMPEmptyEventHandler; + onEnded?: TMPEmptyEventHandler; + onPlay?: TMPEmptyEventHandler; + onPause?: TMPEmptyEventHandler; +} + +export interface AudioPropsBase + extends AudioControlProps, + AudioReadonlyProps, + AudioEventProps {} + +export type AudioProps = Partial & { source: AudioSource }; diff --git a/packages/react-native-audio-api/src/unstable/react/Audio/utils.ts b/packages/react-native-audio-api/src/unstable/react/Audio/utils.ts new file mode 100644 index 000000000..28741d93d --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/Audio/utils.ts @@ -0,0 +1,86 @@ +import { useMemo } from 'react'; +import { AudioProps, AudioPropsBase } from './types'; + +export function withPropsDefaults(props: AudioProps): AudioPropsBase { + return { + ...props, + autoPlay: props.autoPlay ?? false, + controls: props.controls ?? false, + loop: props.loop ?? false, + muted: props.muted ?? false, + preload: props.preload ?? 'auto', + source: props.source ?? [], + playbackRate: props.playbackRate ?? 1.0, + preservesPitch: props.preservesPitch ?? true, + volume: props.volume ?? 1.0, + }; +} + +export function useStableAudioProps(props: AudioProps): AudioPropsBase { + const { + // Control Props + autoPlay, + controls, + loop, + muted, + preload, + source, + playbackRate, + preservesPitch, + volume, + + // Event Props + onLoadStart, + onLoad, + onError, + onProgress, + onSeeked, + onEnded, + onPlay, + onPause, + } = withPropsDefaults(props); + + return useMemo( + () => ({ + // Control Props + autoPlay, + controls, + loop, + muted, + preload, + source, + playbackRate, + preservesPitch, + volume, + + // Event Props + onLoadStart, + onLoad, + onError, + onProgress, + onSeeked, + onEnded, + onPlay, + onPause, + }), + [ + autoPlay, + controls, + loop, + muted, + preload, + source, + playbackRate, + preservesPitch, + volume, + onLoadStart, + onLoad, + onError, + onProgress, + onSeeked, + onEnded, + onPlay, + onPause, + ] + ); +} diff --git a/packages/react-native-audio-api/src/unstable/react/index.ts b/packages/react-native-audio-api/src/unstable/react/index.ts new file mode 100644 index 000000000..f36f82cb4 --- /dev/null +++ b/packages/react-native-audio-api/src/unstable/react/index.ts @@ -0,0 +1,2 @@ +export * from './Audio'; +export { default as Audio } from './Audio'; diff --git a/packages/react-native-audio-api/unstable/react/package.json b/packages/react-native-audio-api/unstable/react/package.json new file mode 100644 index 000000000..cdb9e81a9 --- /dev/null +++ b/packages/react-native-audio-api/unstable/react/package.json @@ -0,0 +1,6 @@ +{ + "main": "../../lib/module/unstable/react/index", + "module": "../../lib/module/unstable/react/index", + "react-native": "../../src/unstable/react/index", + "types": "../../lib/typescript/unstable/react/index.d.ts" +}