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

remove bars components

This commit is contained in:
Fedor Katurov 2023-11-19 17:07:58 +06:00
parent 92efb1e97e
commit 8ec77986bf
7 changed files with 13 additions and 3 deletions

View file

@ -0,0 +1,58 @@
import React, { FC, useCallback, useState } from 'react';
import classNames from 'classnames';
import { Icon } from '~/components/input/Icon';
import { Dialog } from '~/constants/modal';
import { useShowModal } from '~/hooks/modal/useShowModal';
import styles from './styles.module.scss';
export interface SubmitBarProps {
isLab?: boolean;
}
const SubmitBar: FC<SubmitBarProps> = ({ isLab }) => {
const showModal = useShowModal(Dialog.CreateNode);
const [focused, setFocused] = useState(false);
const onFocus = useCallback(() => setFocused(true), [setFocused]);
const onBlur = useCallback(() => setFocused(false), [setFocused]);
const createUrl = useCallback(
(type: string) => () => {
showModal({ type, isInLab: !!isLab });
},
[isLab, showModal]
);
const icon = isLab ? 'lab' : 'plus';
return (
<div className={classNames(styles.wrap, { [styles.lab]: isLab })}>
<div className={classNames(styles.panel, { [styles.active]: focused })}>
<button onClick={createUrl('image')} className={styles.link}>
<Icon icon="image" size={32} />
</button>
<button onClick={createUrl('text')} className={styles.link}>
<Icon icon="text" size={32} />
</button>
<button onClick={createUrl('video')} className={styles.link}>
<Icon icon="video" size={32} />
</button>
<button onClick={createUrl('audio')} className={styles.link}>
<Icon icon="audio" size={32} />
</button>
</div>
<button className={styles.button} onFocus={onFocus} onBlur={onBlur} type="button">
<Icon icon={icon} />
</button>
</div>
);
};
export { SubmitBar };

View file

@ -0,0 +1,7 @@
import dynamic from 'next/dynamic';
import type { SubmitBarProps } from './index';
export const SubmitBarSSR = dynamic<SubmitBarProps>(
() => import('./index').then(it => it.SubmitBar),
{ ssr: false });

View file

@ -0,0 +1,77 @@
@import 'src/styles/variables';
.wrap {
position: fixed;
bottom: 0;
left: 50%;
transform: translate($content_width * 0.5 + $gap, 0);
z-index: 14;
@media (max-width: $content_width + ($bar_height + $gap) * 2) {
left: 100%;
transform: translate(-$bar_height, 0);
}
}
.button {
background: $flow_gradient;
width: $bar_height;
height: $bar_height;
border-radius: $bar_height * 0.5;
display: flex;
align-items: center;
justify-content: center;
border-radius: $radius $radius 0 0;
cursor: pointer;
position: relative;
z-index: 2;
border: none;
outline: none;
svg {
width: 32px;
height: 32px;
}
.lab & {
background: $info_gradient;
}
}
.panel {
background: $content_bg_lighter;
position: absolute;
bottom: 0;
z-index: 1;
padding-bottom: $bar_height;
border-radius: $radius $radius 0 0;
transform: translate(0, 100%);
transition: transform 250ms 250ms;
&.active {
transform: translate(0, 0);
transition: transform 250ms;
}
}
.link {
@include row_shadow;
height: $bar_height;
width: $bar_height;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
fill: white;
color: white;
svg {
width: 32px;
height: 32px;
}
&:first-child {
border-radius: $radius $radius 0 0;
}
}

View file

@ -1,8 +1,9 @@
import React, { FC } from 'react';
import { SubmitBarSSR } from '~/components/bars/SubmitBar/ssr';
import { Authorized } from '~/components/containers/Authorized';
import { SubmitBarSSR } from './components/SubmitBar/ssr';
interface IProps {
prefix?: string;
isLab?: boolean;

View file

@ -0,0 +1,77 @@
import React, { useCallback, VFC } from 'react';
import { Icon } from '~/components/input/Icon';
import { PlayerState } from '~/constants/player';
import { IFile } from '~/types';
import { PlayerProgress } from '~/types/player';
import { path } from '~/utils/ramda';
import styles from './styles.module.scss';
interface Props {
progress: PlayerProgress;
status: PlayerState;
file?: IFile;
playerPlay: () => void;
playerPause: () => void;
playerSeek: (pos: number) => void;
playerStop: () => void;
}
const PlayerBar: VFC<Props> = ({
status,
playerPlay,
playerPause,
playerSeek,
playerStop,
progress,
file,
}) => {
const onClick = useCallback(() => {
if (status === PlayerState.PLAYING) return playerPause();
return playerPlay();
}, [playerPlay, playerPause, status]);
const onSeek = useCallback(
event => {
event.stopPropagation();
const { clientX, target } = event;
const { left, width } = target.getBoundingClientRect();
playerSeek(((clientX - left) / width) * 100);
},
[playerSeek]
);
if (status === PlayerState.UNSET) return null;
const metadata: IFile['metadata'] = path(['metadata'], file);
const title =
metadata &&
(metadata.title || [metadata.id3artist, metadata.id3title].filter(el => !!el).join(' - '));
return (
<div className={styles.place}>
<div className={styles.wrap}>
<div className={styles.status}>
<div className={styles.playpause} onClick={onClick}>
{status === PlayerState.PLAYING ? <Icon icon="pause" /> : <Icon icon="play" />}
</div>
<div className={styles.info}>
<div className={styles.title}>{title}</div>
<div className={styles.progress} onClick={onSeek}>
<div className={styles.bar} style={{ width: `${progress.progress}%` }} />
</div>
</div>
<div className={styles.close} onClick={playerStop}>
<Icon icon="close" />
</div>
</div>
</div>
</div>
);
};
export { PlayerBar };

View file

@ -0,0 +1,106 @@
@import 'src/styles/variables';
.place {
position: relative;
height: $bar_height;
flex: 0 1 500px;
display: flex;
}
.wrap {
@include outer_shadow();
display: flex;
border-radius: $radius $radius 0 0;
align-items: center;
background: $content_bg_lightest;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: $bar_height;
flex-direction: column;
transform: translate(0, 0);
z-index: 3;
min-width: 0;
}
.status {
flex: 0 0 $bar_height;
display: flex;
flex-direction: row;
width: 100%;
position: absolute;
z-index: 1;
height: $bar_height;
}
.playpause,
.close {
flex: 0 0 $bar_height;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
svg {
width: 32px;
height: 32px;
fill: $gray_50;
stroke: none;
}
}
.close {
svg {
width: 24px;
height: 24px;
}
}
.info {
flex: 1;
display: flex;
min-width: 0;
align-items: center;
justify-content: center;
padding: 10px;
flex-direction: column;
}
.title {
color: $gray_50;
font: $font_14_semibold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}
.progress {
position: relative;
height: 20px;
width: 100%;
cursor: pointer;
&::after {
content: ' ';
top: 9px;
left: 0;
width: 100%;
height: 2px;
background: $gray_50;
position: absolute;
border-radius: 2px;
opacity: 0.5;
}
}
.bar {
top: 7px;
left: 0;
width: 100%;
height: 6px;
background: $gray_50;
position: absolute;
border-radius: 2px;
}

View file

@ -1,12 +1,21 @@
import React, { VFC } from 'react';
import { PlayerBar } from '~/components/bars/PlayerBar';
import { useAudioPlayer } from '~/utils/providers/AudioPlayerProvider';
import { PlayerBar } from './components/PlayerBar';
interface PlayerViewProps {}
const PlayerView: VFC<PlayerViewProps> = () => {
const { file, play, toPercent: seek, stop, pause, status, progress } = useAudioPlayer();
const {
file,
play,
toPercent: seek,
stop,
pause,
status,
progress,
} = useAudioPlayer();
return (
<PlayerBar