1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

refactored playerbar component

This commit is contained in:
Fedor Katurov 2021-11-21 17:31:50 +07:00
parent 6ca4c514bf
commit df217b41f7
9 changed files with 78 additions and 53 deletions

View file

@ -1,26 +1,21 @@
import React, { FC, useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState, VFC } from 'react';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon';
import { PLAYER_STATES } from '~/redux/player/constants';
import { connect } from 'react-redux';
import { pick } from 'ramda';
import { selectPlayer } from '~/redux/player/selectors';
import * as PLAYER_ACTIONS from '~/redux/player/actions';
import { IPlayerProgress, Player } from '~/utils/player';
import { PlayerState } from '~/redux/player/constants';
import { path } from 'ramda';
import { IPlayerProgress, Player } from '~/utils/player';
import { IFile } from '~/redux/types';
const mapStateToProps = state => pick(['status', 'file'], selectPlayer(state));
const mapDispatchToProps = {
playerPlay: PLAYER_ACTIONS.playerPlay,
playerPause: PLAYER_ACTIONS.playerPause,
playerSeek: PLAYER_ACTIONS.playerSeek,
playerStop: PLAYER_ACTIONS.playerStop,
};
interface Props {
status: PlayerState;
file?: IFile;
playerPlay: () => void;
playerPause: () => void;
playerSeek: (pos: number) => void;
playerStop: () => void;
}
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const PlayerBarUnconnected: FC<IProps> = ({
const PlayerBar: VFC<Props> = ({
status,
playerPlay,
playerPause,
@ -31,7 +26,7 @@ const PlayerBarUnconnected: FC<IProps> = ({
const [progress, setProgress] = useState<IPlayerProgress>({ progress: 0, current: 0, total: 0 });
const onClick = useCallback(() => {
if (status === PLAYER_STATES.PLAYING) return playerPause();
if (status === PlayerState.PLAYING) return playerPause();
return playerPlay();
}, [playerPlay, playerPause, status]);
@ -61,7 +56,7 @@ const PlayerBarUnconnected: FC<IProps> = ({
};
}, [onProgress]);
if (status === PLAYER_STATES.UNSET) return null;
if (status === PlayerState.UNSET) return null;
const metadata: IFile['metadata'] = path(['metadata'], file);
const title =
@ -73,7 +68,7 @@ const PlayerBarUnconnected: FC<IProps> = ({
<div className={styles.wrap}>
<div className={styles.status}>
<div className={styles.playpause} onClick={onClick}>
{status === PLAYER_STATES.PLAYING ? <Icon icon="pause" /> : <Icon icon="play" />}
{status === PlayerState.PLAYING ? <Icon icon="pause" /> : <Icon icon="play" />}
</div>
<div className={styles.info}>
@ -93,7 +88,4 @@ const PlayerBarUnconnected: FC<IProps> = ({
);
};
export const PlayerBar = connect(
mapStateToProps,
mapDispatchToProps
)(PlayerBarUnconnected);
export { PlayerBar };

View file

@ -3,12 +3,12 @@ import { connect } from 'react-redux';
import { selectPlayer } from '~/redux/player/selectors';
import * as PLAYER_ACTIONS from '~/redux/player/actions';
import { IFile } from '~/redux/types';
import { PLAYER_STATES } from '~/redux/player/constants';
import { IPlayerProgress, Player } from '~/utils/player';
import classNames from 'classnames';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon';
import { InputText } from '~/components/input/InputText';
import { PlayerState } from '~/redux/player/constants';
const mapStateToProps = state => ({
player: selectPlayer(state),
@ -52,7 +52,7 @@ const AudioPlayerUnconnected = memo(
if (isEditing) return;
if (current && current.id === file.id) {
if (status === PLAYER_STATES.PLAYING) return playerPause();
if (status === PlayerState.PLAYING) return playerPause();
return playerPlay();
}
@ -122,11 +122,7 @@ const AudioPlayerUnconnected = memo(
)}
<div className={styles.playpause}>
{playing && status === PLAYER_STATES.PLAYING ? (
<Icon icon="pause" />
) : (
<Icon icon="play" />
)}
{playing && status === PlayerState.PLAYING ? <Icon icon="pause" /> : <Icon icon="play" />}
</div>
{isEditing ? (

View file

@ -1,6 +1,6 @@
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { PlayerBar } from '~/components/bars/PlayerBar';
import { PlayerView } from '~/views/player/PlayerView';
type IProps = {};
@ -8,7 +8,7 @@ const BottomContainer: FC<IProps> = () => (
<div className={styles.wrap}>
<div className={styles.content}>
<div className={styles.padder}>
<PlayerBar />
<PlayerView />
</div>
</div>
</div>

View file

@ -16,8 +16,8 @@ export const PLAYER_ACTIONS = {
GET_YOUTUBE_INFO: `${prefix}GET_YOUTUBE_INFO`,
};
export const PLAYER_STATES = {
PLAYING: 'PLAYING',
PAUSED: 'PAUSED',
UNSET: 'UNSET',
};
export enum PlayerState {
PLAYING = 'PLAYING',
PAUSED = 'PAUSED',
UNSET = 'UNSET',
}

View file

@ -1,16 +1,16 @@
import { createReducer } from '~/utils/reducer';
import { PLAYER_HANDLERS } from './handlers';
import { PLAYER_STATES } from './constants';
import { IFile, IEmbed } from '../types';
import { PlayerState } from './constants';
import { IEmbed, IFile } from '../types';
export type IPlayerState = Readonly<{
status: typeof PLAYER_STATES[keyof typeof PLAYER_STATES];
status: PlayerState;
file?: IFile;
youtubes: Record<string, IEmbed>;
}>;
const INITIAL_STATE: IPlayerState = {
status: PLAYER_STATES.UNSET,
status: PlayerState.UNSET,
file: undefined,
youtubes: {},
};

View file

@ -1,11 +1,11 @@
import { takeLatest, put, fork, race, take, delay, call, select } from 'redux-saga/effects';
import { PLAYER_ACTIONS, PLAYER_STATES } from './constants';
import { call, delay, fork, put, race, select, take, takeLatest } from 'redux-saga/effects';
import { PLAYER_ACTIONS, PlayerState } from './constants';
import {
playerSetFile,
playerSeek,
playerSetStatus,
playerGetYoutubeInfo,
playerSeek,
playerSet,
playerSetFile,
playerSetStatus,
} from './actions';
import { Player } from '~/utils/player';
import { getURL } from '~/utils/dom';
@ -41,7 +41,7 @@ function seekSaga({ seek }: ReturnType<typeof playerSeek>) {
}
function* stoppedSaga() {
yield put(playerSetStatus(PLAYER_STATES.UNSET));
yield put(playerSetStatus(PlayerState.UNSET));
yield put(playerSetFile(undefined));
}

View file

@ -0,0 +1,17 @@
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectPlayer } from '~/redux/player/selectors';
import { useCallback } from 'react';
import { playerPause, playerPlay, playerSeek, playerStop } from '~/redux/player/actions';
import { useDispatch } from 'react-redux';
export const usePlayer = () => {
const { status, file } = useShallowSelect(selectPlayer);
const dispatch = useDispatch();
const onPlayerPlay = useCallback(() => dispatch(playerPlay()), [dispatch]);
const onPlayerPause = useCallback(() => dispatch(playerPause()), [dispatch]);
const onPlayerSeek = useCallback((pos: number) => dispatch(playerSeek(pos)), [dispatch]);
const onPlayerStop = useCallback(() => dispatch(playerStop()), [dispatch]);
return { status, file, onPlayerPlay, onPlayerSeek, onPlayerPause, onPlayerStop };
};

View file

@ -1,6 +1,6 @@
import { store } from '~/redux/store';
import { playerSetStatus, playerStopped } from '~/redux/player/actions';
import { PLAYER_STATES } from '~/redux/player/constants';
import { PlayerState } from '~/redux/player/constants';
type PlayerEventType = keyof HTMLMediaElementEventMap;
@ -81,10 +81,8 @@ export class PlayerClass {
const Player = new PlayerClass();
// Player.element.addEventListener('playprogress', ({ detail }: CustomEvent) => console.log(detail));
Player.on('play', () => store.dispatch(playerSetStatus(PLAYER_STATES.PLAYING)));
Player.on('pause', () => store.dispatch(playerSetStatus(PLAYER_STATES.PAUSED)));
Player.on('play', () => store.dispatch(playerSetStatus(PlayerState.PLAYING)));
Player.on('pause', () => store.dispatch(playerSetStatus(PlayerState.PAUSED)));
Player.on('stop', () => store.dispatch(playerStopped()));
Player.on('error', () => store.dispatch(playerStopped()));

View file

@ -0,0 +1,22 @@
import React, { VFC } from 'react';
import { PlayerBar } from '~/components/bars/PlayerBar';
import { usePlayer } from '~/utils/hooks/player/usePlayer';
interface PlayerViewProps {}
const PlayerView: VFC<PlayerViewProps> = () => {
const { status, file, onPlayerSeek, onPlayerStop, onPlayerPause, onPlayerPlay } = usePlayer();
return (
<PlayerBar
status={status}
playerPlay={onPlayerPlay}
playerPause={onPlayerPause}
playerSeek={onPlayerSeek}
playerStop={onPlayerStop}
file={file}
/>
);
};
export { PlayerView };