mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
fixed eslint
This commit is contained in:
parent
8c448f2ab6
commit
42fbacdd66
9 changed files with 327 additions and 102 deletions
|
@ -6,11 +6,8 @@ interface IProps {
|
|||
data: INode;
|
||||
setData: (val: INode) => void;
|
||||
onUpload: (val: File[]) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const EditorPanel: FC<IProps> = ({
|
||||
}) => (
|
||||
<div className={styles.panel} />
|
||||
);
|
||||
const EditorPanel: FC<IProps> = ({}) => <div className={styles.panel} />;
|
||||
|
||||
export { EditorPanel };
|
||||
|
|
|
@ -64,6 +64,11 @@ export interface IFile {
|
|||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface IFileWithUUID {
|
||||
temp_id?: UUID;
|
||||
file: File;
|
||||
}
|
||||
|
||||
export interface IBlock {
|
||||
type: 'image' | 'text' | 'media' | 'youtube' | 'video',
|
||||
temp_ids: UUID[];
|
||||
|
|
|
@ -4,6 +4,7 @@ const prefix = 'UPLOAD.';
|
|||
|
||||
export const UPLOAD_ACTIONS = {
|
||||
UPLOAD_FILES: `${prefix}UPLOAD_FILES`,
|
||||
UPLOAD_CANCEL: `${prefix}UPLOAD_CANCEL`,
|
||||
};
|
||||
|
||||
export const EMPTY_FILE: IFile = {
|
||||
|
|
|
@ -1,6 +1,94 @@
|
|||
import {takeEvery} from "redux-saga/effects";
|
||||
import {UPLOAD_ACTIONS} from "~/redux/uploads/constants";
|
||||
import { takeEvery, all, spawn, call, put, take, fork, race } from 'redux-saga/effects';
|
||||
import { UPLOAD_ACTIONS } from '~/redux/uploads/constants';
|
||||
import { uploadUploadFiles } from './actions';
|
||||
import { reqWrapper } from '../auth/sagas';
|
||||
import { createUploader, uploadGetThumb } from '~/utils/uploader';
|
||||
import { HTTP_RESPONSES } from '~/utils/api';
|
||||
import { VALIDATORS } from '~/utils/validators';
|
||||
import { UUID, IFileWithUUID, IResultWithStatus } from '../types';
|
||||
|
||||
function* uploadCall({ temp_id, onProgress, file }) {
|
||||
return yield call(reqWrapper, console.log, { file, onProgress });
|
||||
}
|
||||
|
||||
function* onUploadProgress(chan) {
|
||||
while (true) {
|
||||
const { progress, temp_id }: { progress: number; temp_id: string } = yield take(chan);
|
||||
console.log('progress', { progress, temp_id });
|
||||
// replace with the one, that changes upload status with progress
|
||||
// yield put(inventoryUploadSet(temp_id, { progress }));
|
||||
}
|
||||
}
|
||||
|
||||
function* uploadCancelWorker(id) {
|
||||
while (true) {
|
||||
const { temp_id } = yield take(UPLOAD_ACTIONS.UPLOAD_CANCEL);
|
||||
if (temp_id === id) break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function* uploadWorker(file: File, temp_id: UUID) {
|
||||
const [promise, chan] = createUploader<{ temp_id; file }, { temp_id }>(uploadCall, { temp_id });
|
||||
yield fork(onUploadProgress, chan);
|
||||
|
||||
return yield call(promise, { temp_id, file });
|
||||
}
|
||||
function* uploadFile({ file, temp_id }: IFileWithUUID): IResultWithStatus<any> {
|
||||
if (!file.type || !VALIDATORS.IS_IMAGE_MIME(file.type)) {
|
||||
return { error: 'File_Not_Image', status: HTTP_RESPONSES.BAD_REQUEST, data: {} };
|
||||
}
|
||||
|
||||
const preview = yield call(uploadGetThumb, file);
|
||||
|
||||
// yield put(inventoryUploadAdd( // replace with the one, what adds file upload status
|
||||
// temp_id,
|
||||
// {
|
||||
// ...EMPTY_INVENTORY_UPLOAD,
|
||||
// preview,
|
||||
// is_uploading: true,
|
||||
// type: file.type,
|
||||
// },
|
||||
// ));
|
||||
|
||||
const { result, cancel, cancel_editing, save_inventory } = yield race({
|
||||
result: call(uploadWorker, file, temp_id),
|
||||
cancel: call(uploadCancelWorker, temp_id),
|
||||
// add here CANCEL_UPLOADS worker, that will watch for subject
|
||||
// cancel_editing: take(UPLOAD_ACTIONS.CANCEL_EDITING),
|
||||
// save_inventory: take(INVENTORY_ACTIONS.SAVE_INVENTORY),
|
||||
}) as any;
|
||||
|
||||
if (cancel || cancel_editing || save_inventory) {
|
||||
// return yield put(inventoryUploadDrop(temp_id)); // replace with the one, that will delete file upload status record
|
||||
return { error: null, status: HTTP_RESPONSES.NOT_FOUND, data: {} };
|
||||
}
|
||||
|
||||
const { data, error } = result;
|
||||
|
||||
if (error) {
|
||||
// replace with the one, that changes file upload status to error
|
||||
// return yield put(inventoryUploadSet(temp_id, { is_uploading: false, error: data.detail || error }));
|
||||
return { error: null, status: HTTP_RESPONSES.NOT_FOUND, data: {} };
|
||||
}
|
||||
|
||||
// replace with the one, that updates upload status with actual data
|
||||
// yield put(inventoryUploadSet(temp_id, {
|
||||
// is_uploading: false,
|
||||
// error: null,
|
||||
// uuid: data.uuid,
|
||||
// url: data.url,
|
||||
// thumbnail_url: data.url,
|
||||
// }));
|
||||
|
||||
return { error: null, status: HTTP_RESPONSES.CREATED, data: {} }; // add file here as data
|
||||
}
|
||||
|
||||
function* uploadFiles({ files }: ReturnType<typeof uploadUploadFiles>) {
|
||||
yield all(files.map(file => spawn(uploadFile, file)));
|
||||
}
|
||||
|
||||
export default function* () {
|
||||
yield takeEvery(UPLOAD_ACTIONS.UPLOAD_FILES, console.log);
|
||||
yield takeEvery(UPLOAD_ACTIONS.UPLOAD_FILES, uploadFiles);
|
||||
}
|
||||
|
|
33
src/utils/uploader.ts
Normal file
33
src/utils/uploader.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { eventChannel, END } from 'redux-saga';
|
||||
import { VALIDATORS } from '~/utils/validators';
|
||||
|
||||
export const IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg'];
|
||||
|
||||
export function createUploader<T extends {}, R extends {}>
|
||||
(callback: (args: any) => any, payload: R):
|
||||
[(args: T) => (args: T & { onProgress: (current: number, total: number) => void }) => any, EventChannel<any>] {
|
||||
let emit;
|
||||
|
||||
const chan = eventChannel(emitter => {
|
||||
emit = emitter;
|
||||
return () => null;
|
||||
});
|
||||
|
||||
const onProgress = (current: number, total: number): void => {
|
||||
emit(current >= total ? END : { ...payload, progress: parseFloat((current / total).toFixed(1)) });
|
||||
};
|
||||
|
||||
const wrappedCallback = args => callback({ ...args, onProgress });
|
||||
|
||||
return [wrappedCallback, chan];
|
||||
}
|
||||
|
||||
export const uploadGetThumb = async file => {
|
||||
if (!file.type || !VALIDATORS.IS_IMAGE_MIME(file.type)) return '';
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result || '');
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
};
|
39
src/utils/validators.ts
Normal file
39
src/utils/validators.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { IMAGE_MIME_TYPES } from '~/utils/uploader';
|
||||
import isValid from 'date-fns/isValid';
|
||||
import { IAddress } from '~/redux/types';
|
||||
|
||||
const isValidEmail = (email: string): boolean =>
|
||||
!!email &&
|
||||
String(email) &&
|
||||
!!String(email).match(
|
||||
/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,
|
||||
);
|
||||
|
||||
const isLikeEmail = (email: string): boolean =>
|
||||
!!email && String(email) && !!String(email).match(/^([^\@]+)@([^\@]+)\.([^\@]+)$$/);
|
||||
|
||||
const isNonEmpty = (value: string): boolean => !!value && value.trim().length > 0;
|
||||
const isLikePhone = isNonEmpty;
|
||||
|
||||
const isAtLeast = (length: number, value: string): boolean =>
|
||||
!!value && value.trim().length >= length;
|
||||
|
||||
const isMimeOfImage = (mime): boolean => !!mime && IMAGE_MIME_TYPES.indexOf(mime) >= 0;
|
||||
|
||||
const isDate = (val: string): boolean => !!val && isValid(new Date(val));
|
||||
const isStringDate = (val: string): boolean => !!val && !!val.match(/^[\d]{2,4}\-[\d]{2}-[\d]{2}/);
|
||||
const isAddrWithRaw = ({ raw }: Partial<IAddress>): boolean => !!raw && isNonEmpty(raw);
|
||||
|
||||
export const VALIDATORS = {
|
||||
EMAIL: isValidEmail,
|
||||
LIKE_PHONE: isLikePhone,
|
||||
LIKE_EMAIL: isLikeEmail,
|
||||
NON_EMPTY: isNonEmpty,
|
||||
AT_LEAST: length => isAtLeast.bind(null, length),
|
||||
IS_IMAGE_MIME: isMimeOfImage,
|
||||
IS_DATE: isDate,
|
||||
IS_STRINGY_DATE: isStringDate,
|
||||
IS_ADDRESS_WITH_RAW: isAddrWithRaw,
|
||||
EVOLVE: (validator: (val: any) => boolean, error: string) => (val: any) =>
|
||||
!val || !validator(val) ? error : null,
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue