mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
refactored some common components
This commit is contained in:
parent
5e9c111e0f
commit
a9a220273f
67 changed files with 238 additions and 220 deletions
|
@ -2,8 +2,8 @@ import React, { FC, MouseEventHandler, useEffect, useRef } from 'react';
|
|||
|
||||
import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import React, {
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -2,9 +2,9 @@ import React, { FC } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { LoaderCircleInner } from '~/components/input/LoaderCircleInner';
|
||||
import { SVGProps } from '~/utils/types';
|
||||
|
||||
import { LoaderCircleInner } from './components/LoaderCircleInner';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps extends SVGProps {
|
|
@ -3,11 +3,11 @@ import React, { FC, useMemo } from 'react';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import { Anchor } from '~/components/common/Anchor';
|
||||
import { MenuDots } from '~/components/common/MenuDots';
|
||||
import { CellShade } from '~/components/flow/CellShade';
|
||||
import { FlowCellImage } from '~/components/flow/FlowCellImage';
|
||||
import { FlowCellMenu } from '~/components/flow/FlowCellMenu';
|
||||
import { FlowCellText } from '~/components/flow/FlowCellText';
|
||||
import { MenuDots } from '~/components/menu/MenuDots';
|
||||
import { useClickOutsideFocus } from '~/hooks/dom/useClickOutsideFocus';
|
||||
import { useWindowSize } from '~/hooks/dom/useWindowSize';
|
||||
import { useFlowCellControls } from '~/hooks/flow/useFlowCellControls';
|
||||
|
|
|
@ -3,7 +3,7 @@ import React, { FC } from 'react';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Toggle } from '~/components/input/Toggle';
|
||||
import { FlowDisplayVariant } from '~/types';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { InfiniteScroll } from '~/components/common/InfiniteScroll';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { INode } from '~/types';
|
||||
|
||||
import { FlowRecentItem } from '../FlowRecentItem';
|
||||
|
|
|
@ -6,8 +6,8 @@ import { Autoplay, EffectFade, Navigation } from 'swiper/modules';
|
|||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import SwiperClass from 'swiper/types/swiper-class';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
import { imagePresets, URLS } from '~/constants/urls';
|
||||
import { useWindowSize } from '~/hooks/dom/useWindowSize';
|
||||
import { useNavigation } from '~/hooks/navigation/useNavigation';
|
||||
|
|
|
@ -9,8 +9,8 @@ import React, {
|
|||
import Tippy from '@tippyjs/react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
import { IIcon } from '~/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
const style = require('./style.scss');
|
||||
|
||||
interface IInfoProps {
|
||||
text?: string;
|
||||
children?: string;
|
||||
level?: string;
|
||||
}
|
||||
export const Info: React.FunctionComponent<IInfoProps> = ({
|
||||
text,
|
||||
children,
|
||||
level = 'normal',
|
||||
}) => (
|
||||
<div className={classNames(style.container, { [level]: true })}>
|
||||
{
|
||||
text || children || ''
|
||||
}
|
||||
</div>
|
||||
);
|
|
@ -1,28 +0,0 @@
|
|||
@import 'src/styles/variables';
|
||||
|
||||
.container {
|
||||
min-height: $info_height;
|
||||
border-radius: $radius;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font: $font_14_regular;
|
||||
line-height: 1.2em;
|
||||
padding: $gap;
|
||||
background: $gray_90;
|
||||
|
||||
&:global(.danger) {
|
||||
color: white;
|
||||
background: $content_bg_danger;
|
||||
}
|
||||
|
||||
&:global(.warning) {
|
||||
color: white;
|
||||
background: $content_bg_danger;
|
||||
}
|
||||
|
||||
&:global(.primary) {
|
||||
color: white;
|
||||
background: $content_bg_danger;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import React, {
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { InputWrapper } from '~/components/input/InputWrapper';
|
||||
import { useTranslatedError } from '~/hooks/data/useTranslatedError';
|
||||
import { useFocusEvent } from '~/hooks/dom/useFocusEvent';
|
||||
|
@ -50,17 +50,25 @@ const InputText: FC<InputTextProps> = ({
|
|||
|
||||
handler(target.value);
|
||||
},
|
||||
[handler]
|
||||
[handler],
|
||||
);
|
||||
|
||||
const toggleRevealed = useCallback(() => setRevealed(!revealed), [setRevealed, revealed]);
|
||||
const toggleRevealed = useCallback(
|
||||
() => setRevealed(!revealed),
|
||||
[setRevealed, revealed],
|
||||
);
|
||||
|
||||
const translatedError = useTranslatedError(error);
|
||||
|
||||
const type = props.type === 'password' && revealed ? 'text' : props.type;
|
||||
|
||||
return (
|
||||
<InputWrapper title={title} error={translatedError} focused={focused} notEmpty={!!value}>
|
||||
<InputWrapper
|
||||
title={title}
|
||||
error={translatedError}
|
||||
focused={focused}
|
||||
notEmpty={!!value}
|
||||
>
|
||||
<div
|
||||
className={classNames(styles.input, {
|
||||
[styles.has_error]: !!error,
|
||||
|
@ -83,7 +91,11 @@ const InputText: FC<InputTextProps> = ({
|
|||
<div className={styles.suffix}>
|
||||
{suffix}
|
||||
{props.type === 'password' && (
|
||||
<Icon icon="eye" onClick={toggleRevealed} className={styles.reveal} />
|
||||
<Icon
|
||||
icon="eye"
|
||||
onClick={toggleRevealed}
|
||||
className={styles.reveal}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { VFC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { InputText, InputTextProps } from '~/components/input/InputText';
|
||||
|
||||
interface SearchInputProps extends Omit<InputTextProps, 'prefix' | 'suffix'> {}
|
||||
|
|
|
@ -5,7 +5,7 @@ import classNames from 'classnames';
|
|||
import { Filler } from '~/components/common/Filler';
|
||||
import { Grid } from '~/components/common/Grid';
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { useNavigation } from '~/hooks/navigation/useNavigation';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { useNavigation } from '~/hooks/navigation/useNavigation';
|
||||
|
|
|
@ -3,7 +3,7 @@ import React, { FC } from 'react';
|
|||
import Tippy from '@tippyjs/react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { NodeComponentProps } from '~/constants/node';
|
||||
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { memo, useCallback, useMemo } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { InputText } from '~/components/input/InputText';
|
||||
import { PlayerState } from '~/constants/player';
|
||||
import { IFile } from '~/types';
|
||||
|
@ -17,113 +17,133 @@ type Props = {
|
|||
onTitleChange?: (file_id: IFile['id'], title: string) => void;
|
||||
};
|
||||
|
||||
const AudioPlayer = memo(({ file, onDelete, isEditing, onTitleChange }: Props) => {
|
||||
const { toPercent, file: currentFile, setFile, play, status, progress, pause } = useAudioPlayer();
|
||||
const AudioPlayer = memo(
|
||||
({ file, onDelete, isEditing, onTitleChange }: Props) => {
|
||||
const {
|
||||
toPercent,
|
||||
file: currentFile,
|
||||
setFile,
|
||||
play,
|
||||
status,
|
||||
progress,
|
||||
pause,
|
||||
} = useAudioPlayer();
|
||||
|
||||
const onPlay = useCallback(
|
||||
async event => {
|
||||
event.stopPropagation();
|
||||
const onPlay = useCallback(
|
||||
async (event) => {
|
||||
event.stopPropagation();
|
||||
|
||||
if (file.id !== currentFile?.id) {
|
||||
setFile(file);
|
||||
setTimeout(() => void play(), 0);
|
||||
return;
|
||||
}
|
||||
if (file.id !== currentFile?.id) {
|
||||
setFile(file);
|
||||
setTimeout(() => void play(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
status === PlayerState.PLAYING ? pause() : await play();
|
||||
},
|
||||
[play, pause, setFile, file, currentFile, status]
|
||||
);
|
||||
status === PlayerState.PLAYING ? pause() : await play();
|
||||
},
|
||||
[play, pause, setFile, file, currentFile, status],
|
||||
);
|
||||
|
||||
const onSeek = useCallback(
|
||||
event => {
|
||||
event.stopPropagation();
|
||||
const { clientX, target } = event;
|
||||
const { left, width } = target.getBoundingClientRect();
|
||||
toPercent(((clientX - left) / width) * 100);
|
||||
},
|
||||
[toPercent]
|
||||
);
|
||||
const onSeek = useCallback(
|
||||
(event) => {
|
||||
event.stopPropagation();
|
||||
const { clientX, target } = event;
|
||||
const { left, width } = target.getBoundingClientRect();
|
||||
toPercent(((clientX - left) / width) * 100);
|
||||
},
|
||||
[toPercent],
|
||||
);
|
||||
|
||||
const onDropClick = useCallback(() => {
|
||||
if (!onDelete) return;
|
||||
const onDropClick = useCallback(() => {
|
||||
if (!onDelete) return;
|
||||
|
||||
onDelete(file.id);
|
||||
}, [file, onDelete]);
|
||||
onDelete(file.id);
|
||||
}, [file, onDelete]);
|
||||
|
||||
const title = useMemo(
|
||||
() =>
|
||||
(file.metadata &&
|
||||
(file.metadata.title ||
|
||||
[file.metadata.id3artist, file.metadata.id3title].filter(el => el).join(' - '))) ||
|
||||
file.orig_name ||
|
||||
'',
|
||||
[file.metadata, file.orig_name]
|
||||
);
|
||||
const title = useMemo(
|
||||
() =>
|
||||
(file.metadata &&
|
||||
(file.metadata.title ||
|
||||
[file.metadata.id3artist, file.metadata.id3title]
|
||||
.filter((el) => el)
|
||||
.join(' - '))) ||
|
||||
file.orig_name ||
|
||||
'',
|
||||
[file.metadata, file.orig_name],
|
||||
);
|
||||
|
||||
const onRename = useCallback(
|
||||
(val: string) => {
|
||||
if (!onTitleChange) return;
|
||||
const onRename = useCallback(
|
||||
(val: string) => {
|
||||
if (!onTitleChange) return;
|
||||
|
||||
onTitleChange(file.id, val);
|
||||
},
|
||||
[onTitleChange, file.id]
|
||||
);
|
||||
onTitleChange(file.id, val);
|
||||
},
|
||||
[onTitleChange, file.id],
|
||||
);
|
||||
|
||||
const stopPropagation = useCallback(
|
||||
event => {
|
||||
if (!isEditing) {
|
||||
return;
|
||||
}
|
||||
const stopPropagation = useCallback(
|
||||
(event) => {
|
||||
if (!isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
},
|
||||
[isEditing]
|
||||
);
|
||||
event.stopPropagation();
|
||||
},
|
||||
[isEditing],
|
||||
);
|
||||
|
||||
const playing = currentFile?.id === file.id;
|
||||
const playing = currentFile?.id === file.id;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.wrap, {
|
||||
[styles.playing]: playing,
|
||||
})}
|
||||
>
|
||||
{onDelete && (
|
||||
<div className={styles.drop} onMouseDown={onDropClick}>
|
||||
<Icon icon="close" />
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.wrap, {
|
||||
[styles.playing]: playing,
|
||||
})}
|
||||
>
|
||||
{onDelete && (
|
||||
<div className={styles.drop} onMouseDown={onDropClick}>
|
||||
<Icon icon="close" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={styles.playpause}
|
||||
onClick={onPlay}
|
||||
onMouseDown={stopPropagation}
|
||||
>
|
||||
{playing && status === PlayerState.PLAYING ? (
|
||||
<Icon icon="pause" />
|
||||
) : (
|
||||
<Icon icon="play" />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.playpause} onClick={onPlay} onMouseDown={stopPropagation}>
|
||||
{playing && status === PlayerState.PLAYING ? <Icon icon="pause" /> : <Icon icon="play" />}
|
||||
</div>
|
||||
|
||||
{isEditing ? (
|
||||
<div className={styles.input}>
|
||||
<InputText
|
||||
placeholder={title}
|
||||
handler={onRename}
|
||||
value={file.metadata && file.metadata.title}
|
||||
onMouseDown={stopPropagation}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.content}>
|
||||
<div className={styles.title}>{title || ''}</div>
|
||||
|
||||
<div className={styles.progress} onClick={onSeek}>
|
||||
<div
|
||||
className={styles.bar}
|
||||
style={{
|
||||
width: `${progress.progress}%`,
|
||||
}}
|
||||
{isEditing ? (
|
||||
<div className={styles.input}>
|
||||
<InputText
|
||||
placeholder={title}
|
||||
handler={onRename}
|
||||
value={file.metadata && file.metadata.title}
|
||||
onMouseDown={stopPropagation}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
) : (
|
||||
<div className={styles.content}>
|
||||
<div className={styles.title}>{title || ''}</div>
|
||||
|
||||
<div className={styles.progress} onClick={onSeek}>
|
||||
<div
|
||||
className={styles.bar}
|
||||
style={{
|
||||
width: `${progress.progress}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export { AudioPlayer };
|
||||
|
|
|
@ -8,9 +8,9 @@ import React, {
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
|
||||
import { imagePresets } from '~/constants/urls';
|
||||
import { useResizeHandler } from '~/hooks/dom/useResizeHandler';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useCallback, useState, VFC } from 'react';
|
||||
|
||||
import { MenuDots } from '~/components/common/MenuDots';
|
||||
import { MenuDots } from '~/components/menu/MenuDots';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
@ -2,7 +2,7 @@ import React, { PropsWithChildren } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Placement } from '@popperjs/core';
|
|||
import classNames from 'classnames';
|
||||
import { usePopper } from 'react-popper';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { useFocusEvent } from '~/hooks/dom/useFocusEvent';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { ButtonProps } from '~/utils/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
@ -10,7 +10,11 @@ interface MenuItemWithIconProps {
|
|||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const MenuItemWithIcon: FC<MenuItemWithIconProps> = ({ children, icon, onClick }) => (
|
||||
const MenuItemWithIcon: FC<MenuItemWithIconProps> = ({
|
||||
children,
|
||||
icon,
|
||||
onClick,
|
||||
}) => (
|
||||
<button className={styles.item} onClick={onClick}>
|
||||
{icon && (
|
||||
<div className={styles.icon}>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { WithDescription } from '~/components/common/WithDescription';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
interface BacklinkProps {
|
||||
icon?: string;
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { VFC } from 'react';
|
|||
|
||||
import Tippy from '@tippyjs/react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { MenuButton } from '~/components/menu/MenuButton';
|
||||
import { MenuItemWithIcon } from '~/components/menu/MenuItemWithIcon';
|
||||
import { SeparatedMenu } from '~/components/menu/SeparatedMenu';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ import { FC, memo, useEffect, useMemo, useRef, useState } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
|
||||
import { Square } from '~/components/common/Square';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { imagePresets } from '~/constants/urls';
|
||||
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
||||
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useMemo, VFC } from 'react';
|
||||
|
||||
import { CornerMenu } from '~/components/common/CornerMenu';
|
||||
import { CornerMenu } from '~/components/menu/CornerMenu';
|
||||
|
||||
interface NoteMenuProps {
|
||||
onEdit: () => void;
|
||||
|
@ -16,7 +16,7 @@ const NoteMenu: VFC<NoteMenuProps> = ({ onEdit, onDelete }) => {
|
|||
},
|
||||
{ title: 'Удалить', action: onDelete },
|
||||
],
|
||||
[onEdit, onDelete]
|
||||
[onEdit, onDelete],
|
||||
);
|
||||
|
||||
return <CornerMenu actions={actions} />;
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import React, { FC, useCallback } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { ArcProgress } from '~/components/input/ArcProgress';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { ArcProgress } from '~/components/common/ArcProgress';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
@ -16,7 +16,13 @@ interface IProps {
|
|||
uploading?: boolean;
|
||||
}
|
||||
|
||||
const AudioUpload: FC<IProps> = ({ title, progress, uploading, id, onDrop }) => {
|
||||
const AudioUpload: FC<IProps> = ({
|
||||
title,
|
||||
progress,
|
||||
uploading,
|
||||
id,
|
||||
onDrop,
|
||||
}) => {
|
||||
const onDropFile = useCallback(() => {
|
||||
if (!id || !onDrop) return;
|
||||
onDrop(id);
|
||||
|
|
|
@ -2,8 +2,8 @@ import React, { FC, useCallback } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { ArcProgress } from '~/components/input/ArcProgress';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { ArcProgress } from '~/components/common/ArcProgress';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { IFile } from '~/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
@ -17,7 +17,13 @@ interface IProps {
|
|||
uploading?: boolean;
|
||||
}
|
||||
|
||||
const ImageUpload: FC<IProps> = ({ thumb, progress, uploading, id, onDrop }) => {
|
||||
const ImageUpload: FC<IProps> = ({
|
||||
thumb,
|
||||
progress,
|
||||
uploading,
|
||||
id,
|
||||
onDrop,
|
||||
}) => {
|
||||
const onDropFile = useCallback(() => {
|
||||
if (!id || !onDrop) return;
|
||||
onDrop(id);
|
||||
|
@ -32,7 +38,12 @@ const ImageUpload: FC<IProps> = ({ thumb, progress, uploading, id, onDrop }) =>
|
|||
)}
|
||||
|
||||
<div className={classNames(styles.thumb_wrap, { uploading: uploading })}>
|
||||
{thumb && <div className={styles.thumb} style={{ backgroundImage: `url("${thumb}")` }} />}
|
||||
{thumb && (
|
||||
<div
|
||||
className={styles.thumb}
|
||||
style={{ backgroundImage: `url("${thumb}")` }}
|
||||
/>
|
||||
)}
|
||||
{uploading && (
|
||||
<div className={styles.progress}>
|
||||
<ArcProgress size={72} progress={progress} />
|
||||
|
|
|
@ -4,7 +4,7 @@ import classnames from 'classnames';
|
|||
import classNames from 'classnames';
|
||||
import Dropzone from 'react-dropzone';
|
||||
|
||||
import { DropHereIcon } from '~/components/input/DropHereIcon';
|
||||
import { DropHereIcon } from '~/components/common/DropHereIcon';
|
||||
import { useDragDetector } from '~/hooks/dom/useDragDetector';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import TelegramLoginButton, {
|
|||
TelegramUser,
|
||||
} from '@v9v/ts-react-telegram-login';
|
||||
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { VFC } from 'react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { ERROR_LITERAL, ERRORS } from '~/constants/errors';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { VFC } from 'react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { VFC } from 'react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { WithDescription } from '~/components/common/WithDescription';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
interface Props {
|
||||
icon: string;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { ChangeEvent, FC, useCallback } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { UploadType } from '~/constants/uploads';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { ChangeEvent, FC, useCallback, useEffect } from 'react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
|
||||
import { imagePresets } from '~/constants/urls';
|
||||
import { useUploader } from '~/hooks/data/useUploader';
|
||||
|
|
|
@ -2,8 +2,8 @@ import React, { FC, useCallback } from 'react';
|
|||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
import { ModalWrapper } from '~/components/common/ModalWrapper';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
||||
import { useLoadNode } from '~/hooks/node/useLoadNode';
|
||||
import { useUpdateNode } from '~/hooks/node/useUpdateNode';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { VFC } from 'react';
|
||||
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import React, { FC, FormEvent, useCallback, useMemo } from 'react';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Superpower } from '~/components/common/Superpower';
|
||||
import { FlowRecent } from '~/components/flow/FlowRecent';
|
||||
import { FlowSearchResults } from '~/components/flow/FlowSearchResults';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { InputText } from '~/components/input/InputText';
|
||||
import { Toggle } from '~/components/input/Toggle';
|
||||
import { experimentalFeatures } from '~/constants/features';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC, useCallback, useState } from 'react';
|
|||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Dialog } from '~/constants/modal';
|
||||
import { useShowModal } from '~/hooks/modal/useShowModal';
|
||||
|
||||
|
@ -23,7 +23,7 @@ const SubmitBar: FC<SubmitBarProps> = ({ isLab }) => {
|
|||
(type: string) => () => {
|
||||
showModal({ type, isInLab: !!isLab });
|
||||
},
|
||||
[isLab, showModal]
|
||||
[isLab, showModal],
|
||||
);
|
||||
|
||||
const icon = isLab ? 'lab' : 'plus';
|
||||
|
@ -48,7 +48,12 @@ const SubmitBar: FC<SubmitBarProps> = ({ isLab }) => {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<button className={styles.button} onFocus={onFocus} onBlur={onBlur} type="button">
|
||||
<button
|
||||
className={styles.button}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
type="button"
|
||||
>
|
||||
<Icon icon={icon} />
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import React, { FC, memo, useMemo } from 'react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { ICommentBlockProps } from '~/constants/comment';
|
||||
import { useYoutubeMetadata } from '~/hooks/metadata/useYoutubeMetadata';
|
||||
import { getYoutubeThumb } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type Props = ICommentBlockProps & {};
|
||||
|
||||
const CommentEmbedBlock: FC<Props> = memo(({ block }) => {
|
||||
const id = useMemo(() => {
|
||||
const match = block.content.match(
|
||||
/https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([\w\-=]+)/
|
||||
/https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([\w\-=]+)/,
|
||||
);
|
||||
|
||||
return (match && match[1]) || '';
|
||||
|
@ -21,7 +20,10 @@ const CommentEmbedBlock: FC<Props> = memo(({ block }) => {
|
|||
|
||||
const url = useMemo(() => `https://youtube.com/watch?v=${id}`, [id]);
|
||||
|
||||
const preview = useMemo(() => getYoutubeThumb(block.content), [block.content]);
|
||||
const preview = useMemo(
|
||||
() => getYoutubeThumb(block.content),
|
||||
[block.content],
|
||||
);
|
||||
|
||||
const metadata = useYoutubeMetadata(id);
|
||||
const title = metadata?.metadata?.title || '';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { FC } from 'react';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import { Hoverable } from '~/components/common/Hoverable';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { imagePresets } from '~/constants/urls';
|
||||
import { IFile } from '~/types';
|
||||
import { getURL } from '~/utils/dom';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
|||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
|
||||
import { CornerMenu } from '~/components/common/CornerMenu';
|
||||
import { CornerMenu } from '~/components/menu/CornerMenu';
|
||||
|
||||
interface IProps {
|
||||
onEdit: () => void;
|
||||
|
@ -16,7 +16,7 @@ const CommentMenu: FC<IProps> = ({ onEdit, onDelete }) => {
|
|||
},
|
||||
{ title: 'Удалить', action: onDelete },
|
||||
],
|
||||
[onEdit, onDelete]
|
||||
[onEdit, onDelete],
|
||||
);
|
||||
|
||||
return <CornerMenu actions={actions} />;
|
||||
|
|
|
@ -3,9 +3,9 @@ import { FC, useCallback, useEffect } from 'react';
|
|||
import classNames from 'classnames';
|
||||
import { isAfter, parseISO } from 'date-fns';
|
||||
|
||||
import { LoaderScreen } from '~/components/common/LoaderScreen';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { InputRow } from '~/components/input/InputRow';
|
||||
import { LoaderScreen } from '~/components/input/LoaderScreen';
|
||||
import { NotificationComment } from '~/components/notifications/NotificationComment';
|
||||
import { NotificationNode } from '~/components/notifications/NotificationNode';
|
||||
import { useNotificationsList } from '~/hooks/notifications/useNotificationsList';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useCallback, VFC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { PlayerState } from '~/constants/player';
|
||||
import { IFile } from '~/types';
|
||||
import { PlayerProgress } from '~/types/player';
|
||||
|
@ -33,13 +33,13 @@ const PlayerBar: VFC<Props> = ({
|
|||
}, [playerPlay, playerPause, status]);
|
||||
|
||||
const onSeek = useCallback(
|
||||
event => {
|
||||
(event) => {
|
||||
event.stopPropagation();
|
||||
const { clientX, target } = event;
|
||||
const { left, width } = target.getBoundingClientRect();
|
||||
playerSeek(((clientX - left) / width) * 100);
|
||||
},
|
||||
[playerSeek]
|
||||
[playerSeek],
|
||||
);
|
||||
|
||||
if (status === PlayerState.UNSET) return null;
|
||||
|
@ -47,21 +47,29 @@ const PlayerBar: VFC<Props> = ({
|
|||
const metadata: IFile['metadata'] = path(['metadata'], file);
|
||||
const title =
|
||||
metadata &&
|
||||
(metadata.title || [metadata.id3artist, metadata.id3title].filter(el => !!el).join(' - '));
|
||||
(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" />}
|
||||
{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
|
||||
className={styles.bar}
|
||||
style={{ width: `${progress.progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { FC, Fragment } from 'react';
|
||||
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { SOCIAL_ICONS } from '~/constants/auth/socials';
|
||||
import { useOAuth } from '~/hooks/auth/useOAuth';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { LoaderCircle } from '~/components/common/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ import React, { VFC } from 'react';
|
|||
|
||||
import { Filler } from '~/components/common/Filler';
|
||||
import { Group } from '~/components/common/Group';
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { Padder } from '~/components/common/Padder';
|
||||
import { FlowRecentItem } from '~/components/flow/FlowRecentItem';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { InputText } from '~/components/input/InputText';
|
||||
import { HorizontalMenu } from '~/components/menu/HorizontalMenu';
|
||||
import { useFlowStore } from '~/store/flow/useFlowStore';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useMemo, VFC } from 'react';
|
||||
|
||||
import { Icon } from '~/components/common/Icon';
|
||||
import { InfiniteScroll } from '~/components/common/InfiniteScroll';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { SidebarStack } from '~/components/sidebar/SidebarStack';
|
||||
import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard';
|
||||
import { SidebarWrapper } from '~/components/sidebar/SidebarWrapper';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue