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

removed upload redux store

This commit is contained in:
Fedor Katurov 2022-01-06 21:04:14 +07:00
parent 140e36b6b7
commit 95b92b643f
38 changed files with 398 additions and 691 deletions

View file

@ -4,7 +4,7 @@ import { append, assocPath, path } from 'ramda';
import { formatCommentText, getPrettyDate, getURL } from '~/utils/dom';
import { Group } from '~/components/containers/Group';
import styles from './styles.module.scss';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { UploadType } from '~/constants/uploads';
import reduce from 'ramda/es/reduce';
import { AudioPlayer } from '~/components/media/AudioPlayer';
import classnames from 'classnames';
@ -30,12 +30,12 @@ const CommentContent: FC<IProps> = memo(
const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]);
const stopEditing = useCallback(() => setIsEditing(false), [setIsEditing]);
const groupped = useMemo<Record<keyof typeof UPLOAD_TYPES, IFile[]>>(
const groupped = useMemo<Record<UploadType, IFile[]>>(
() =>
reduce(
(group, file) =>
file.type ? assocPath([file.type], append(file, group[file.type]), group) : group,
{},
{} as Record<UploadType, IFile[]>,
comment.files
),
[comment]

View file

@ -3,8 +3,7 @@ import { useCommentFormFormik } from '~/hooks/comments/useCommentFormFormik';
import { FormikProvider } from 'formik';
import { LocalCommentFormTextarea } from '~/components/comment/LocalCommentFormTextarea';
import { Button } from '~/components/input/Button';
import { FileUploaderProvider, useFileUploader } from '~/hooks/data/useFileUploader';
import { UPLOAD_SUBJECTS, UPLOAD_TARGETS } from '~/redux/uploads/constants';
import { UploadSubject, UploadTarget } from '~/constants/uploads';
import { CommentFormAttachButtons } from '~/components/comment/CommentFormAttachButtons';
import { CommentFormFormatButtons } from '~/components/comment/CommentFormFormatButtons';
import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
@ -16,6 +15,9 @@ import styles from './styles.module.scss';
import { ERROR_LITERAL } from '~/constants/errors';
import { useInputPasteUpload } from '~/hooks/dom/useInputPasteUpload';
import { Filler } from '~/components/containers/Filler';
import { useUploader } from '~/hooks/data/useUploader';
import { UploaderContextProvider } from '~/utils/context/UploaderContextProvider';
import { observer } from 'mobx-react-lite';
interface IProps {
comment?: IComment;
@ -24,13 +26,9 @@ interface IProps {
onCancelEdit?: () => void;
}
const CommentForm: FC<IProps> = ({ comment, nodeId, saveComment, onCancelEdit }) => {
const CommentForm: FC<IProps> = observer(({ comment, nodeId, saveComment, onCancelEdit }) => {
const [textarea, setTextArea] = useState<HTMLTextAreaElement | null>(null);
const uploader = useFileUploader(
UPLOAD_SUBJECTS.COMMENT,
UPLOAD_TARGETS.COMMENTS,
comment?.files
);
const uploader = useUploader(UploadSubject.Comment, UploadTarget.Comments, comment?.files);
const formik = useCommentFormFormik(
comment || EMPTY_COMMENT,
nodeId,
@ -61,7 +59,7 @@ const CommentForm: FC<IProps> = ({ comment, nodeId, saveComment, onCancelEdit })
<UploadDropzone onUpload={uploader.uploadFiles}>
<form onSubmit={formik.handleSubmit} className={styles.wrap}>
<FormikProvider value={formik}>
<FileUploaderProvider value={uploader}>
<UploaderContextProvider value={uploader}>
<div className={styles.input}>
<LocalCommentFormTextarea onPaste={onPaste} ref={setTextArea} />
@ -110,11 +108,11 @@ const CommentForm: FC<IProps> = ({ comment, nodeId, saveComment, onCancelEdit })
</Button>
</div>
</div>
</FileUploaderProvider>
</UploaderContextProvider>
</FormikProvider>
</form>
</UploadDropzone>
);
};
});
export { CommentForm };

View file

@ -1,7 +1,7 @@
import React, { FC, useCallback } from 'react';
import { ButtonGroup } from '~/components/input/ButtonGroup';
import { Button } from '~/components/input/Button';
import { COMMENT_FILE_TYPES } from '~/redux/uploads/constants';
import { COMMENT_FILE_TYPES } from '~/constants/uploads';
interface IProps {
onUpload: (files: File[]) => void;

View file

@ -1,4 +1,4 @@
import React, { FC, useCallback, useMemo } from 'react';
import React, { FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
@ -6,68 +6,59 @@ import { IFile } from '~/redux/types';
import { SortEnd } from 'react-sortable-hoc';
import { moveArrItem } from '~/utils/fn';
import { useFileDropZone } from '~/hooks';
import { COMMENT_FILE_TYPES, UPLOAD_TYPES } from '~/redux/uploads/constants';
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
import { COMMENT_FILE_TYPES } from '~/constants/uploads';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
const CommentFormAttaches: FC = () => {
const uploader = useFileUploaderContext();
const { files, pending, setFiles, uploadFiles } = uploader!;
const images = useMemo(() => files.filter(file => file && file.type === UPLOAD_TYPES.IMAGE), [
const {
files,
]);
const pendingImages = useMemo(() => pending.filter(item => item.type === UPLOAD_TYPES.IMAGE), [
pending,
]);
const audios = useMemo(() => files.filter(file => file && file.type === UPLOAD_TYPES.AUDIO), [
files,
]);
const pendingAudios = useMemo(() => pending.filter(item => item.type === UPLOAD_TYPES.AUDIO), [
pending,
]);
pendingImages,
pendingAudios,
filesAudios,
filesImages,
uploadFiles,
setFiles,
} = useUploaderContext();
const onDrop = useFileDropZone(uploadFiles, COMMENT_FILE_TYPES);
const hasImageAttaches = images.length > 0 || pendingImages.length > 0;
const hasAudioAttaches = audios.length > 0 || pendingAudios.length > 0;
const hasImageAttaches = filesImages.length > 0 || pendingImages.length > 0;
const hasAudioAttaches = filesAudios.length > 0 || pendingAudios.length > 0;
const hasAttaches = hasImageAttaches || hasAudioAttaches;
const onImageMove = useCallback(
({ oldIndex, newIndex }: SortEnd) => {
setFiles([
...audios,
...filesAudios,
...(moveArrItem(
oldIndex,
newIndex,
images.filter(file => !!file)
filesImages.filter(file => !!file)
) as IFile[]),
]);
},
[images, audios, setFiles]
[setFiles, filesImages, filesAudios]
);
const onAudioMove = useCallback(
({ oldIndex, newIndex }: SortEnd) => {
setFiles([
...images,
...filesImages,
...(moveArrItem(
oldIndex,
newIndex,
audios.filter(file => !!file)
filesAudios.filter(file => !!file)
) as IFile[]),
]);
},
[images, audios, setFiles]
[setFiles, filesImages, filesAudios]
);
const onFileDelete = useCallback(
(fileId: IFile['id']) => {
setFiles(files.filter(file => file.id !== fileId));
},
[setFiles, files]
[files, setFiles]
);
const onAudioTitleChange = useCallback(
@ -90,7 +81,7 @@ const CommentFormAttaches: FC = () => {
onDelete={onFileDelete}
onSortEnd={onImageMove}
axis="xy"
items={images}
items={filesImages}
locked={pendingImages}
pressDelay={50}
helperClass={styles.helper}
@ -100,7 +91,7 @@ const CommentFormAttaches: FC = () => {
{hasAudioAttaches && (
<SortableAudioGrid
items={audios}
items={filesAudios}
onDelete={onFileDelete}
onTitleChange={onAudioTitleChange}
onSortEnd={onAudioMove}

View file

@ -1,5 +1,5 @@
import React, { FC, useCallback, useMemo } from 'react';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { UploadType } from '~/constants/uploads';
import { ImageGrid } from '../ImageGrid';
import { AudioGrid } from '../AudioGrid';
import styles from './styles.module.scss';
@ -7,25 +7,28 @@ import { NodeEditorProps } from '~/types/node';
import { useNodeImages } from '~/hooks/node/useNodeImages';
import { useNodeAudios } from '~/hooks/node/useNodeAudios';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { values } from 'ramda';
type IProps = NodeEditorProps;
const AudioEditor: FC<IProps> = () => {
const { values } = useNodeFormContext();
const { pending, setFiles, uploadFiles } = useFileUploaderContext()!;
const formik = useNodeFormContext();
const { pending, setFiles, uploadFiles } = useUploaderContext()!;
const images = useNodeImages(values);
const audios = useNodeAudios(values);
const images = useNodeImages(formik.values);
const audios = useNodeAudios(formik.values);
const pendingImages = useMemo(() => pending.filter(item => item.type === UPLOAD_TYPES.IMAGE), [
pending,
]);
const pendingImages = useMemo(
() => values(pending).filter(item => item.type === UploadType.Image),
[pending]
);
const pendingAudios = useMemo(() => pending.filter(item => item.type === UPLOAD_TYPES.AUDIO), [
pending,
]);
const pendingAudios = useMemo(
() => values(pending).filter(item => item.type === UploadType.Audio),
[pending]
);
const setImages = useCallback(values => setFiles([...values, ...audios]), [setFiles, audios]);

View file

@ -1,16 +1,16 @@
import React, { FC, useCallback } from 'react';
import { SortEnd } from 'react-sortable-hoc';
import { IFile } from '~/redux/types';
import { IUploadStatus } from '~/redux/uploads/reducer';
import { moveArrItem } from '~/utils/fn';
import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
import styles from './styles.module.scss';
import { UploadStatus } from '~/store/uploader/UploaderStore';
interface IProps {
files: IFile[];
setFiles: (val: IFile[]) => void;
locked: IUploadStatus[];
locked: UploadStatus[];
}
const AudioGrid: FC<IProps> = ({ files, setFiles, locked }) => {

View file

@ -1,6 +1,6 @@
import React, { FC } from 'react';
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node';
type IProps = IEditorComponentProps & {};
@ -9,7 +9,7 @@ const EditorAudioUploadButton: FC<IProps> = () => (
<EditorUploadButton
accept="audio/*"
icon="audio"
type={UPLOAD_TYPES.AUDIO}
type={UploadType.Audio}
label="Добавить аудио"
/>
);

View file

@ -1,6 +1,6 @@
import React, { FC } from 'react';
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node';
type IProps = IEditorComponentProps & {};
@ -9,7 +9,7 @@ const EditorImageUploadButton: FC<IProps> = () => (
<EditorUploadButton
accept="image/*"
icon="image"
type={UPLOAD_TYPES.IMAGE}
type={UploadType.Image}
label="Добавить фоточек"
/>
);

View file

@ -1,27 +1,27 @@
import React, { ChangeEvent, FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node';
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
import { getFileType } from '~/utils/uploader';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { Button } from '~/components/input/Button';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
type IProps = IEditorComponentProps & {
accept?: string;
icon?: string;
type?: typeof UPLOAD_TYPES[keyof typeof UPLOAD_TYPES];
type?: UploadType;
label?: string;
};
const EditorUploadButton: FC<IProps> = ({
accept = 'image/*',
icon = 'plus',
type = UPLOAD_TYPES.IMAGE,
type = UploadType.Image,
label,
}) => {
const { uploadFiles } = useFileUploaderContext()!;
const { uploadFiles } = useUploaderContext()!;
const { values } = useNodeFormContext();
const onInputChange = useCallback(

View file

@ -1,23 +1,26 @@
import React, { ChangeEvent, FC, useCallback, useEffect } from 'react';
import styles from './styles.module.scss';
import { UPLOAD_SUBJECTS, UPLOAD_TARGETS, UPLOAD_TYPES } from '~/redux/uploads/constants';
import { path } from 'ramda';
import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
import { getURL } from '~/utils/dom';
import { Icon } from '~/components/input/Icon';
import { PRESETS } from '~/constants/urls';
import { IEditorComponentProps } from '~/types/node';
import { useFileUploader } from '~/hooks/data/useFileUploader';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { getFileType } from '~/utils/uploader';
import { useUploader } from '~/hooks/data/useUploader';
type IProps = IEditorComponentProps & {};
const EditorUploadCoverButton: FC<IProps> = ({}) => {
const { values, setFieldValue } = useNodeFormContext();
const { uploadFiles, files } = useFileUploader(UPLOAD_SUBJECTS.EDITOR, UPLOAD_TARGETS.NODES, []);
const { uploadFiles, files, pendingImages } = useUploader(
UploadSubject.Editor,
UploadTarget.Nodes,
[]
);
const background = values.cover ? getURL(values.cover, PRESETS['300']) : null;
const preview = status && path(['preview'], status);
const preview = pendingImages?.[0]?.thumbnail || '';
const onDropCover = useCallback(() => {
setFieldValue('cover', null);
@ -26,7 +29,7 @@ const EditorUploadCoverButton: FC<IProps> = ({}) => {
const onInputChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
const files = Array.from(event.target.files || [])
.filter(file => getFileType(file) === UPLOAD_TYPES.IMAGE)
.filter(file => getFileType(file) === UploadType.Image)
.slice(0, 1);
uploadFiles(files);

View file

@ -2,18 +2,19 @@ import React, { FC } from 'react';
import { ImageGrid } from '~/components/editors/ImageGrid';
import styles from './styles.module.scss';
import { NodeEditorProps } from '~/types/node';
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { values } from 'ramda';
type IProps = NodeEditorProps;
const ImageEditor: FC<IProps> = () => {
const { pending, files, setFiles, uploadFiles } = useFileUploaderContext()!;
const { pending, files, setFiles, uploadFiles } = useUploaderContext()!;
return (
<UploadDropzone onUpload={uploadFiles} helperClassName={styles.dropzone}>
<div className={styles.wrap}>
<ImageGrid files={files} setFiles={setFiles} locked={pending} />
<ImageGrid files={files} setFiles={setFiles} locked={values(pending)} />
</div>
</UploadDropzone>
);

View file

@ -2,14 +2,14 @@ import React, { FC, useCallback } from 'react';
import { SortEnd } from 'react-sortable-hoc';
import styles from './styles.module.scss';
import { IFile } from '~/redux/types';
import { IUploadStatus } from '~/redux/uploads/reducer';
import { moveArrItem } from '~/utils/fn';
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
import { UploadStatus } from '~/store/uploader/UploaderStore';
interface IProps {
files: IFile[];
setFiles: (val: IFile[]) => void;
locked: IUploadStatus[];
locked: UploadStatus[];
}
const ImageGrid: FC<IProps> = ({ files, setFiles, locked }) => {

View file

@ -4,8 +4,8 @@ import { AudioUpload } from '~/components/upload/AudioUpload';
import styles from './styles.module.scss';
import { SortableAudioGridItem } from '~/components/editors/SortableAudioGridItem';
import { IFile } from '~/redux/types';
import { IUploadStatus } from '~/redux/uploads/reducer';
import { AudioPlayer } from '~/components/media/AudioPlayer';
import { UploadStatus } from '~/store/uploader/UploaderStore';
const SortableAudioGrid = SortableContainer(
({
@ -15,7 +15,7 @@ const SortableAudioGrid = SortableContainer(
onTitleChange,
}: {
items: IFile[];
locked: IUploadStatus[];
locked: UploadStatus[];
onDelete: (file_id: IFile['id']) => void;
onTitleChange: (file_id: IFile['id'], title: string) => void;
}) => {
@ -35,7 +35,7 @@ const SortableAudioGrid = SortableContainer(
))}
{locked.map((item, index) => (
<SortableAudioGridItem key={item.temp_id} index={index} collection={1} disabled>
<SortableAudioGridItem key={item.id} index={index} collection={1} disabled>
<AudioUpload title={item.name} progress={item.progress} is_uploading />
</SortableAudioGridItem>
))}

View file

@ -4,10 +4,10 @@ import { ImageUpload } from '~/components/upload/ImageUpload';
import styles from './styles.module.scss';
import { SortableImageGridItem } from '~/components/editors/SortableImageGridItem';
import { IFile } from '~/redux/types';
import { IUploadStatus } from '~/redux/uploads/reducer';
import { getURL } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import classNames from 'classnames';
import { UploadStatus } from '~/store/uploader/UploaderStore';
const SortableImageGrid = SortableContainer(
({
@ -17,7 +17,7 @@ const SortableImageGrid = SortableContainer(
className,
}: {
items: IFile[];
locked: IUploadStatus[];
locked: UploadStatus[];
onDelete: (file_id: IFile['id']) => void;
size?: number;
className?: string;
@ -35,8 +35,8 @@ const SortableImageGrid = SortableContainer(
))}
{locked.map((item, index) => (
<SortableImageGridItem key={item.temp_id} index={index} collection={1} disabled>
<ImageUpload thumb={item.preview} progress={item.progress} is_uploading />
<SortableImageGridItem key={item.id} index={index} collection={1} disabled>
<ImageUpload thumb={item.thumbnail} progress={item.progress} is_uploading />
</SortableImageGridItem>
))}
</div>

View file

@ -18,7 +18,7 @@
&:global(.is_uploading) {
.thumb {
filter: blur(16px);
filter: blur(10px);
}
}
}
@ -34,7 +34,6 @@
background: no-repeat 50% 50%;
background-size: cover;
opacity: 1;
// filter: saturate(0);
}
.progress {