Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/hooks/VoicePlayer/dux/actionTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const actionTypes = {
INITIALIZE_AUDIO_UNIT: 'INITIALIZE_AUDIO_UNIT',
SET_CURRENT_PLAYER: 'SET_CURRENT_PLAYER',
ON_VOICE_PLAYER_PLAY: 'ON_VOICE_PLAYER_PLAY',
ON_VOICE_PLAYER_PAUSE: 'ON_VOICE_PLAYER_PAUSE',
ON_CURRENT_TIME_UPDATE: 'ON_CURRENT_TIME_UPDATE',
} as const;

type ObjectValues<T> = T[keyof T];
export type VoicePlayerActionType = ObjectValues<typeof actionTypes>;

export const INITIALIZE_AUDIO_UNIT: VoicePlayerActionType = 'INITIALIZE_AUDIO_UNIT';
export const SET_CURRENT_PLAYER: VoicePlayerActionType = 'SET_CURRENT_PLAYER';
export const ON_VOICE_PLAYER_PLAY: VoicePlayerActionType = 'ON_VOICE_PLAYER_PLAY';
export const ON_VOICE_PLAYER_PAUSE: VoicePlayerActionType = 'ON_VOICE_PLAYER_PAUSE';
export const ON_CURRENT_TIME_UPDATE: VoicePlayerActionType = 'ON_CURRENT_TIME_UPDATE';
35 changes: 35 additions & 0 deletions src/hooks/VoicePlayer/dux/initialState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { GroupKey } from '../utils';

export const VoicePlayerStatus = {
IDLE: 'IDLE',
PREPARING: 'PREPARING',
PLAYING: 'PLAYING',
PAUSED: 'PAUSED',
COMPLETED: 'COMPLETED',
} as const;
export type VoicePlayerStatus = typeof VoicePlayerStatus[keyof typeof VoicePlayerStatus];

export type AudioStorageUnit = {
playingStatus: VoicePlayerStatus;
audioFile: null | File;
playbackTime: number;
duration: number;
}
export const AudioUnitDefaultValue = (): AudioStorageUnit => ({
audioFile: null,
playbackTime: 0,
duration: 1000,
playingStatus: VoicePlayerStatus.IDLE,
});

export interface VoicePlayerInitialState {
currentPlayer: null | HTMLAudioElement;
currentGroupKey: string;
audioStorage: Record<GroupKey, AudioStorageUnit>;
}

export const voicePlayerInitialState: VoicePlayerInitialState = {
currentPlayer: null,
currentGroupKey: '',
audioStorage: {},
};
108 changes: 108 additions & 0 deletions src/hooks/VoicePlayer/dux/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {
INITIALIZE_AUDIO_UNIT,
ON_CURRENT_TIME_UPDATE,
ON_VOICE_PLAYER_PAUSE,
ON_VOICE_PLAYER_PLAY,
SET_CURRENT_PLAYER,
} from "./actionTypes";
import {
AudioStorageUnit,
AudioUnitDefaultValue,
VoicePlayerInitialState,
VoicePlayerStatus,
} from "./initialState";

type InitializeAudioUnitPayload = { groupKey: string };
type SetCurrentPlayerPayload = { audioPlayer: HTMLAudioElement, groupKey: string };
type OnVoicePlayerPlayPayload = { groupKey: string, audioFile: File };
type OnVoicePlayerPausePayload = { groupKey: string };
type OnCurrentTimeUpdatePayload = { groupKey: string };
type PayloadType = (
InitializeAudioUnitPayload
| SetCurrentPlayerPayload
| OnVoicePlayerPlayPayload
| OnVoicePlayerPausePayload
| OnCurrentTimeUpdatePayload
);
type ActionType = {
type: string;
payload: PayloadType;
}

export default function voicePlayerReducer(
state: VoicePlayerInitialState,
action: ActionType,
): VoicePlayerInitialState {
switch (action.type) {
case INITIALIZE_AUDIO_UNIT: {
const { groupKey } = action.payload as InitializeAudioUnitPayload;
const audioUnit = (state.audioStorage?.[groupKey] ? state.audioStorage[groupKey] : AudioUnitDefaultValue()) as AudioStorageUnit;
audioUnit.playingStatus = VoicePlayerStatus.PREPARING;
return {
...state,
audioStorage: {
...state.audioStorage,
[groupKey]: audioUnit,
},
};
}
case SET_CURRENT_PLAYER: {
const { audioPlayer, groupKey } = action.payload as SetCurrentPlayerPayload;
return {
...state,
currentPlayer: audioPlayer,
currentGroupKey: groupKey,
};
}
case ON_VOICE_PLAYER_PLAY: {
const { groupKey, audioFile } = action.payload as OnVoicePlayerPlayPayload;
const audioUnit = (state.audioStorage?.[groupKey] ? state.audioStorage[groupKey] : AudioUnitDefaultValue()) as AudioStorageUnit;
audioUnit.audioFile = audioFile;
audioUnit.playingStatus = VoicePlayerStatus.PLAYING;
return {
...state,
audioStorage: {
...state.audioStorage,
[groupKey]: audioUnit,
},
};
}
case ON_VOICE_PLAYER_PAUSE: {
const { groupKey } = action.payload as OnVoicePlayerPausePayload;
const audioUnit = (state.audioStorage?.[groupKey] ? state.audioStorage[groupKey] : AudioUnitDefaultValue()) as AudioStorageUnit;
audioUnit.playingStatus = VoicePlayerStatus.PAUSED;
const { currentTime, duration } = state.currentPlayer as HTMLAudioElement;
if (audioUnit.playbackTime === audioUnit.duration) {
audioUnit.playbackTime = 0;
} else if (currentTime > 0 && duration > 0) {
audioUnit.playbackTime = currentTime;
audioUnit.duration = duration;
}
return {
...state,
audioStorage: {
...state.audioStorage,
[groupKey]: audioUnit,
},
};
}
case ON_CURRENT_TIME_UPDATE: {
const { groupKey } = action.payload as OnCurrentTimeUpdatePayload;
const { currentTime, duration } = state.currentPlayer as HTMLAudioElement;
const audioUnit = (state.audioStorage?.[groupKey] ? state.audioStorage[groupKey] : AudioUnitDefaultValue()) as AudioStorageUnit;
if (currentTime > 0 && duration > 0) {
audioUnit.playbackTime = currentTime;
audioUnit.duration = duration;
}
return {
...state,
audioStorage: {
...state.audioStorage,
[groupKey]: audioUnit,
},
};
}
default:
return state;
}
}
Loading