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

added new flow presets

This commit is contained in:
Fedor Katurov 2022-03-15 12:09:00 +07:00
parent 4e5a6d727a
commit 5cd1064140
18 changed files with 64 additions and 45 deletions

View file

@ -8,7 +8,7 @@ import { Group } from '~/components/containers/Group';
import { AudioPlayer } from '~/components/media/AudioPlayer'; import { AudioPlayer } from '~/components/media/AudioPlayer';
import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment'; import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment';
import { UploadType } from '~/constants/uploads'; import { UploadType } from '~/constants/uploads';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IComment, IFile } from '~/types'; import { IComment, IFile } from '~/types';
import { formatCommentText, getPrettyDate, getURL } from '~/utils/dom'; import { formatCommentText, getPrettyDate, getURL } from '~/utils/dom';
import { append, assocPath, path, reduce } from '~/utils/ramda'; import { append, assocPath, path, reduce } from '~/utils/ramda';
@ -101,7 +101,7 @@ const CommentContent: FC<IProps> = memo(
> >
{groupped.image.map((file, index) => ( {groupped.image.map((file, index) => (
<div key={file.id} onClick={() => onShowImageModal(groupped.image, index)}> <div key={file.id} onClick={() => onShowImageModal(groupped.image, index)}>
<img src={getURL(file, PRESETS['600'])} alt={file.name} /> <img src={getURL(file, ImagePresets['600'])} alt={file.name} />
</div> </div>
))} ))}
</div> </div>

View file

@ -3,24 +3,22 @@ import React, { forwardRef, useCallback } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Square } from '~/components/common/Square'; import { Square } from '~/components/common/Square';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { getURLFromString } from '~/utils/dom'; import { getURLFromString } from '~/utils/dom';
import { DivProps } from '~/utils/types'; import { DivProps } from '~/utils/types';
import { openUserProfile } from '~/utils/user'; import { openUserProfile } from '~/utils/user';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface Props extends DivProps { interface Props extends DivProps {
url?: string; url?: string;
username?: string; username?: string;
size?: number; size?: number;
preset?: typeof PRESETS[keyof typeof PRESETS]; preset?: typeof ImagePresets[keyof typeof ImagePresets];
} }
const Avatar = forwardRef<HTMLDivElement, Props>( const Avatar = forwardRef<HTMLDivElement, Props>(
({ url, username, size, className, preset = PRESETS.avatar, ...rest }, ref) => { ({ url, username, size, className, preset = ImagePresets.avatar, ...rest }, ref) => {
const onOpenProfile = useCallback(() => openUserProfile(username), [username]); const onOpenProfile = useCallback(() => openUserProfile(username), [username]);
return ( return (

View file

@ -2,7 +2,7 @@ import React, { FC, useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -19,14 +19,14 @@ const CoverBackdrop: FC<IProps> = ({ cover }) => {
const onLoad = useCallback(() => setIsLoaded(true), [setIsLoaded]); const onLoad = useCallback(() => setIsLoaded(true), [setIsLoaded]);
const image = getURL(cover, PRESETS.cover); const image = getURL(cover, ImagePresets.cover);
useEffect(() => { useEffect(() => {
if (!cover || !cover.url || !ref || !ref.current) return; if (!cover || !cover.url || !ref || !ref.current) return;
ref.current.src = ''; ref.current.src = '';
setIsLoaded(false); setIsLoaded(false);
ref.current.src = getURL(cover, PRESETS.cover); ref.current.src = getURL(cover, ImagePresets.cover);
}, [cover]); }, [cover]);
if (!cover) return null; if (!cover) return null;

View file

@ -2,7 +2,7 @@ import React, { createContext, FC, useContext, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -27,7 +27,7 @@ const PageCoverProvider: FC = ({ children }) => {
createPortal( createPortal(
<div <div
className={styles.wrap} className={styles.wrap}
style={{ backgroundImage: `url("${getURL(cover, PRESETS.cover)}")` }} style={{ backgroundImage: `url("${getURL(cover, ImagePresets.cover)}")` }}
/>, />,
document.body document.body
)} )}

View file

@ -2,7 +2,7 @@ import React, { ChangeEvent, FC, useCallback, useEffect } from 'react';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads'; import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { useUploader } from '~/hooks/data/useUploader'; import { useUploader } from '~/hooks/data/useUploader';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { IEditorComponentProps } from '~/types/node'; import { IEditorComponentProps } from '~/types/node';
@ -21,7 +21,7 @@ const EditorUploadCoverButton: FC<IProps> = () => {
values.cover ? [values.cover] : [] values.cover ? [values.cover] : []
); );
const background = values.cover ? getURL(values.cover, PRESETS['300']) : null; const background = values.cover ? getURL(values.cover, ImagePresets['300']) : null;
const preview = pendingImages?.[0]?.thumbnail || ''; const preview = pendingImages?.[0]?.thumbnail || '';
const onDropCover = useCallback(() => { const onDropCover = useCallback(() => {

View file

@ -5,7 +5,7 @@ import { SortableContainer } from 'react-sortable-hoc';
import { SortableImageGridItem } from '~/components/editors/SortableImageGridItem'; import { SortableImageGridItem } from '~/components/editors/SortableImageGridItem';
import { ImageUpload } from '~/components/upload/ImageUpload'; import { ImageUpload } from '~/components/upload/ImageUpload';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { UploadStatus } from '~/store/uploader/UploaderStore'; import { UploadStatus } from '~/store/uploader/UploaderStore';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -33,7 +33,11 @@ const SortableImageGrid = SortableContainer(
.filter(file => file && file.id) .filter(file => file && file.id)
.map((file, index) => ( .map((file, index) => (
<SortableImageGridItem key={file.id} index={index} collection={0}> <SortableImageGridItem key={file.id} index={index} collection={0}>
<ImageUpload id={file.id} thumb={getURL(file, PRESETS.cover)} onDrop={onDelete} /> <ImageUpload
id={file.id}
thumb={getURL(file, ImagePresets.cover)}
onDrop={onDelete}
/>
</SortableImageGridItem> </SortableImageGridItem>
))} ))}

View file

@ -3,7 +3,7 @@ import React, { FC, Fragment } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { FlowCell } from '~/components/flow/FlowCell'; import { FlowCell } from '~/components/flow/FlowCell';
import { PRESETS, URLS } from '~/constants/urls'; import { flowDisplayToPreset, ImagePresets, URLS } from '~/constants/urls';
import { FlowDisplay, IFlowNode, INode } from '~/types'; import { FlowDisplay, IFlowNode, INode } from '~/types';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
import { getURLFromString } from '~/utils/dom'; import { getURLFromString } from '~/utils/dom';
@ -30,7 +30,7 @@ export const FlowGrid: FC<Props> = ({ user, nodes, onChangeCellView }) => {
id={node.id} id={node.id}
color={node.flow.dominant_color} color={node.flow.dominant_color}
to={URLS.NODE_URL(node.id)} to={URLS.NODE_URL(node.id)}
image={getURLFromString(node.thumbnail, PRESETS.cover)} image={getURLFromString(node.thumbnail, flowDisplayToPreset[node.flow.display])}
flow={node.flow} flow={node.flow}
text={node.description} text={node.description}
title={node.title} title={node.title}

View file

@ -7,7 +7,7 @@ import SwiperClass from 'swiper/types/swiper-class';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { LoaderCircle } from '~/components/input/LoaderCircle'; import { LoaderCircle } from '~/components/input/LoaderCircle';
import { PRESETS, URLS } from '~/constants/urls'; import { ImagePresets, URLS } from '~/constants/urls';
import { useWindowSize } from '~/hooks/dom/useWindowSize'; import { useWindowSize } from '~/hooks/dom/useWindowSize';
import { useNavigation } from '~/hooks/navigation/useNavigation'; import { useNavigation } from '~/hooks/navigation/useNavigation';
import { IFlowNode } from '~/types'; import { IFlowNode } from '~/types';
@ -39,7 +39,7 @@ export const FlowSwiperHero: FC<Props> = ({ heroes }) => {
const [controlledSwiper, setControlledSwiper] = useState<SwiperClass | undefined>(undefined); const [controlledSwiper, setControlledSwiper] = useState<SwiperClass | undefined>(undefined);
const [currentIndex, setCurrentIndex] = useState(heroes.length); const [currentIndex, setCurrentIndex] = useState(heroes.length);
const preset = useMemo(() => (innerWidth <= 768 ? PRESETS.cover : PRESETS.small_hero), [ const preset = useMemo(() => (innerWidth <= 768 ? ImagePresets.cover : ImagePresets.small_hero), [
innerWidth, innerWidth,
]); ]);

View file

@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -30,7 +30,7 @@ const UserButton: FC<IProps> = ({ user: { username, photo }, authOpenProfile, on
<div <div
className={styles.user_avatar} className={styles.user_avatar}
style={{ backgroundImage: `url('${getURL(photo, PRESETS.avatar)}')` }} style={{ backgroundImage: `url('${getURL(photo, ImagePresets.avatar)}')` }}
> >
{(!photo || !photo.id) && <Icon icon="profile" />} {(!photo || !photo.id) && <Icon icon="profile" />}
</div> </div>

View file

@ -6,7 +6,7 @@ import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { LoaderCircle } from '~/components/input/LoaderCircle'; import { LoaderCircle } from '~/components/input/LoaderCircle';
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node'; import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { useResizeHandler } from '~/hooks/dom/useResizeHandler'; import { useResizeHandler } from '~/hooks/dom/useResizeHandler';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -78,7 +78,7 @@ const ImagePreloader: FC<IProps> = ({ file, color, onLoad, onClick, className })
{!hasError && ( {!hasError && (
<image <image
xlinkHref={getURL(file, PRESETS['300'])} xlinkHref={getURL(file, ImagePresets['300'])}
width="100%" width="100%"
height="100%" height="100%"
onLoad={onLoad} onLoad={onLoad}
@ -89,7 +89,7 @@ const ImagePreloader: FC<IProps> = ({ file, color, onLoad, onClick, className })
<ImageWithSSRLoad <ImageWithSSRLoad
className={classNames(styles.image, { [styles.is_loaded]: loaded }, className)} className={classNames(styles.image, { [styles.is_loaded]: loaded }, className)}
src={getURL(file, PRESETS['1600'])} src={getURL(file, ImagePresets['1600'])}
alt="" alt=""
key={file.id} key={file.id}
onLoad={onImageLoad} onLoad={onImageLoad}

View file

@ -1,7 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { INodeComponentProps } from '~/constants/node'; import { INodeComponentProps } from '~/constants/node';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { useNodeImages } from '~/hooks/node/useNodeImages'; import { useNodeImages } from '~/hooks/node/useNodeImages';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
import { path } from '~/utils/ramda'; import { path } from '~/utils/ramda';
@ -19,7 +19,7 @@ const NodeAudioImageBlock: FC<IProps> = ({ node }) => {
<div className={styles.wrap}> <div className={styles.wrap}>
<div <div
className={styles.slide} className={styles.slide}
style={{ backgroundImage: `url("${getURL(path([0], images), PRESETS.small_hero)}")` }} style={{ backgroundImage: `url("${getURL(path([0], images), ImagePresets.small_hero)}")` }}
/> />
</div> </div>
); );

View file

@ -4,7 +4,7 @@ import classNames from 'classnames';
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad'; import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
import { Square } from '~/components/common/Square'; import { Square } from '~/components/common/Square';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
import { useGotoNode } from '~/hooks/node/useGotoNode'; import { useGotoNode } from '~/hooks/node/useGotoNode';
import { INode } from '~/types'; import { INode } from '~/types';
@ -39,7 +39,7 @@ const NodeRelatedItem: FC<IProps> = memo(({ item }) => {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const thumb = useMemo( const thumb = useMemo(
() => (item.thumbnail ? getURL({ url: item.thumbnail }, PRESETS.avatar) : ''), () => (item.thumbnail ? getURL({ url: item.thumbnail }, ImagePresets.avatar) : ''),
[item] [item]
); );
@ -63,7 +63,9 @@ const NodeRelatedItem: FC<IProps> = memo(({ item }) => {
return 'small'; return 'small';
}, [width]); }, [width]);
const image = useMemo(() => getURL({ url: item.thumbnail }, PRESETS.avatar), [item.thumbnail]); const image = useMemo(() => getURL({ url: item.thumbnail }, ImagePresets.avatar), [
item.thumbnail,
]);
return ( return (
<div <div

View file

@ -3,7 +3,7 @@ import React, { FC } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import markdown from '~/styles/common/markdown.module.scss'; import markdown from '~/styles/common/markdown.module.scss';
import { IMessage } from '~/types'; import { IMessage } from '~/types';
import { formatText, getPrettyDate, getURL } from '~/utils/dom'; import { formatText, getPrettyDate, getURL } from '~/utils/dom';
@ -27,7 +27,7 @@ const Message: FC<IProps> = ({ message, incoming }) => {
<div <div
className={styles.avatar} className={styles.avatar}
style={{ backgroundImage: `url("${getURL(message.from.photo, PRESETS.avatar)}")` }} style={{ backgroundImage: `url("${getURL(message.from.photo, ImagePresets.avatar)}")` }}
/> />
<div className={styles.stamp}>{getPrettyDate(message.created_at)}</div> <div className={styles.stamp}>{getPrettyDate(message.created_at)}</div>

View file

@ -1,7 +1,7 @@
import React, { ChangeEvent, FC, useCallback } from 'react'; import React, { ChangeEvent, FC, useCallback } from 'react';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -26,7 +26,7 @@ const ProfileAvatar: FC<ProfileAvatarProps> = ({ photo, onChangePhoto, canEdit,
[onChangePhoto] [onChangePhoto]
); );
const backgroundImage = photo ? `url("${getURL(photo, PRESETS.avatar)}")` : undefined; const backgroundImage = photo ? `url("${getURL(photo, ImagePresets.avatar)}")` : undefined;
return ( return (
<div <div

View file

@ -1,4 +1,4 @@
import { INode } from '~/types'; import { FlowDisplay, FlowDisplayVariant, INode } from '~/types';
export const URLS = { export const URLS = {
BASE: '/', BASE: '/',
@ -23,11 +23,24 @@ export const URLS = {
PROFILE_PAGE: (username: string) => `/profile/${username}`, PROFILE_PAGE: (username: string) => `/profile/${username}`,
}; };
export const PRESETS = { export const ImagePresets = {
'1600': '1600', '1600': '1600',
'600': '600', '600': '600',
'300': '300', '300': '300',
cover: 'cover', cover: 'cover',
small_hero: 'small_hero', small_hero: 'small_hero',
avatar: 'avatar', avatar: 'avatar',
flow_square: 'flow_square',
flow_vertical: 'flow_vertical',
flow_horizontal: 'flow_horizontal',
} as const;
export const flowDisplayToPreset: Record<
FlowDisplayVariant,
typeof ImagePresets[keyof typeof ImagePresets]
> = {
single: 'flow_square',
quadro: 'flow_square',
vertical: 'flow_vertical',
horizontal: 'flow_horizontal',
}; };

View file

@ -5,7 +5,7 @@ import { observer } from 'mobx-react-lite';
import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.js'; import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.js';
import PhotoSwipeJs from 'photoswipe/dist/photoswipe.js'; import PhotoSwipeJs from 'photoswipe/dist/photoswipe.js';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { useModal } from '~/hooks/modal/useModal'; import { useModal } from '~/hooks/modal/useModal';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { DialogComponentProps } from '~/types/modal'; import { DialogComponentProps } from '~/types/modal';
@ -32,7 +32,10 @@ const PhotoSwipe: VFC<PhotoSwipeProps> = observer(({ index, items }) => {
img.onload = () => { img.onload = () => {
resolveImage({ resolveImage({
src: getURL(image, window.innerWidth < 768 ? PRESETS[900] : PRESETS[1600]), src: getURL(
image,
window.innerWidth < 768 ? ImagePresets[900] : ImagePresets[1600]
),
h: img.naturalHeight, h: img.naturalHeight,
w: img.naturalWidth, w: img.naturalWidth,
}); });
@ -42,7 +45,7 @@ const PhotoSwipe: VFC<PhotoSwipeProps> = observer(({ index, items }) => {
resolveImage({}); resolveImage({});
}; };
img.src = getURL(image, PRESETS[1600]); img.src = getURL(image, ImagePresets[1600]);
}) })
) )
); );

View file

@ -3,13 +3,12 @@ import React, { FC } from 'react';
import { Avatar } from '~/components/common/Avatar'; import { Avatar } from '~/components/common/Avatar';
import { Markdown } from '~/components/containers/Markdown'; import { Markdown } from '~/components/containers/Markdown';
import { Placeholder } from '~/components/placeholders/Placeholder'; import { Placeholder } from '~/components/placeholders/Placeholder';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
import { formatText } from '~/utils/dom'; import { formatText } from '~/utils/dom';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps { interface IProps {
profile: IUser; profile: IUser;
isLoading: boolean; isLoading: boolean;
@ -23,7 +22,7 @@ const ProfilePageLeft: FC<IProps> = ({ username, profile, isLoading }) => {
username={username} username={username}
url={profile?.photo?.url} url={profile?.photo?.url}
className={styles.avatar} className={styles.avatar}
preset={PRESETS['600']} preset={ImagePresets['600']}
/> />
<div className={styles.region}> <div className={styles.region}>

View file

@ -6,7 +6,7 @@ import isAfter from 'date-fns/isAfter';
import ru from 'date-fns/locale/ru'; import ru from 'date-fns/locale/ru';
import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/constants/comment'; import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/constants/comment';
import { PRESETS } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IFile, ValueOf } from '~/types'; import { IFile, ValueOf } from '~/types';
import { CONFIG } from '~/utils/config'; import { CONFIG } from '~/utils/config';
import { import {
@ -66,7 +66,7 @@ export const describeArc = (
export const getURLFromString = ( export const getURLFromString = (
url?: string, url?: string,
size?: typeof PRESETS[keyof typeof PRESETS] size?: typeof ImagePresets[keyof typeof ImagePresets]
): string => { ): string => {
if (size) { if (size) {
return (url || '').replace('REMOTE_CURRENT://', `${CONFIG.remoteCurrent}cache/${size}/`); return (url || '').replace('REMOTE_CURRENT://', `${CONFIG.remoteCurrent}cache/${size}/`);
@ -77,7 +77,7 @@ export const getURLFromString = (
export const getURL = ( export const getURL = (
file: Partial<IFile> | undefined, file: Partial<IFile> | undefined,
size?: typeof PRESETS[keyof typeof PRESETS] size?: typeof ImagePresets[keyof typeof ImagePresets]
) => { ) => {
return file?.url ? getURLFromString(file.url, size) : ''; return file?.url ? getURLFromString(file.url, size) : '';
}; };