diff --git a/src/components/comment/CommentContent/index.tsx b/src/components/comment/CommentContent/index.tsx index 38cef4a8..9999e9c2 100644 --- a/src/components/comment/CommentContent/index.tsx +++ b/src/components/comment/CommentContent/index.tsx @@ -18,7 +18,7 @@ import { Group } from '~/components/containers/Group'; import { AudioPlayer } from '~/components/media/AudioPlayer'; import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment'; import { UploadType } from '~/constants/uploads'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IComment, IFile } from '~/types'; import { formatCommentText, getPrettyDate, getURL } from '~/utils/dom'; import { append, assocPath, path, reduce } from '~/utils/ramda'; @@ -141,7 +141,7 @@ const CommentContent: FC = memo( onClick={() => onShowImageModal(groupped.image, index)} > {file.name} diff --git a/src/components/common/Avatar/index.tsx b/src/components/common/Avatar/index.tsx index 19d5a3f7..3f73ecea 100644 --- a/src/components/common/Avatar/index.tsx +++ b/src/components/common/Avatar/index.tsx @@ -3,7 +3,7 @@ import React, { forwardRef } from 'react'; import classNames from 'classnames'; import { Square } from '~/components/common/Square'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { getURLFromString } from '~/utils/dom'; import { DivProps } from '~/utils/types'; @@ -14,12 +14,12 @@ interface Props extends DivProps { url?: string; username?: string; size?: number; - preset?: typeof ImagePresets[keyof typeof ImagePresets]; + preset?: typeof imagePresets[keyof typeof imagePresets]; } const Avatar = forwardRef( ( - { url, username, size, className, preset = ImagePresets.avatar, ...rest }, + { url, username, size, className, preset = imagePresets.avatar, ...rest }, ref, ) => { return ( diff --git a/src/components/containers/CoverBackdrop/index.tsx b/src/components/containers/CoverBackdrop/index.tsx index 33aaa823..f9bc38a6 100644 --- a/src/components/containers/CoverBackdrop/index.tsx +++ b/src/components/containers/CoverBackdrop/index.tsx @@ -2,7 +2,7 @@ import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IUser } from '~/types/auth'; import { getURL } from '~/utils/dom'; @@ -19,14 +19,14 @@ const CoverBackdrop: FC = ({ cover }) => { const onLoad = useCallback(() => setIsLoaded(true), [setIsLoaded]); - const image = getURL(cover, ImagePresets.cover); + const image = getURL(cover, imagePresets.cover); useEffect(() => { if (!cover || !cover.url || !ref || !ref.current) return; ref.current.src = ''; setIsLoaded(false); - ref.current.src = getURL(cover, ImagePresets.cover); + ref.current.src = getURL(cover, imagePresets.cover); }, [cover]); if (!cover) return null; diff --git a/src/components/containers/PageCoverProvider/index.tsx b/src/components/containers/PageCoverProvider/index.tsx index 68c6c288..acdad00e 100644 --- a/src/components/containers/PageCoverProvider/index.tsx +++ b/src/components/containers/PageCoverProvider/index.tsx @@ -2,7 +2,7 @@ import React, { createContext, FC, useContext, useState } from 'react'; import { createPortal } from 'react-dom'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IFile } from '~/types'; import { getURL } from '~/utils/dom'; @@ -27,9 +27,11 @@ const PageCoverProvider: FC = ({ children }) => { createPortal(
, - document.body + document.body, )} {children} diff --git a/src/components/editors/EditorUploadCoverButton/index.tsx b/src/components/editors/EditorUploadCoverButton/index.tsx index cb792f88..b6f5f579 100644 --- a/src/components/editors/EditorUploadCoverButton/index.tsx +++ b/src/components/editors/EditorUploadCoverButton/index.tsx @@ -2,7 +2,7 @@ import React, { ChangeEvent, FC, useCallback, useEffect } from 'react'; import { Icon } from '~/components/input/Icon'; import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useUploader } from '~/hooks/data/useUploader'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { IEditorComponentProps } from '~/types/node'; @@ -18,10 +18,12 @@ const EditorUploadCoverButton: FC = () => { const { uploadFile, files, pendingImages } = useUploader( UploadSubject.Editor, UploadTarget.Nodes, - values.cover ? [values.cover] : [] + values.cover ? [values.cover] : [], ); - const background = values.cover ? getURL(values.cover, ImagePresets['300']) : null; + const background = values.cover + ? getURL(values.cover, imagePresets['300']) + : null; const preview = pendingImages?.[0]?.thumbnail || ''; const onDropCover = useCallback(() => { @@ -31,13 +33,13 @@ const EditorUploadCoverButton: FC = () => { const onInputChange = useCallback( async (event: ChangeEvent) => { const files = Array.from(event.target.files || []) - .filter(file => getFileType(file) === UploadType.Image) + .filter((file) => getFileType(file) === UploadType.Image) .slice(0, 1); const result = await uploadFile(files[0]); setFieldValue('cover', result); }, - [uploadFile, setFieldValue] + [uploadFile, setFieldValue], ); useEffect(() => { diff --git a/src/components/flow/FlowSwiperHero/index.tsx b/src/components/flow/FlowSwiperHero/index.tsx index 4aa6ddb8..d6e62839 100644 --- a/src/components/flow/FlowSwiperHero/index.tsx +++ b/src/components/flow/FlowSwiperHero/index.tsx @@ -7,7 +7,7 @@ import SwiperClass from 'swiper/types/swiper-class'; import { Icon } from '~/components/input/Icon'; import { LoaderCircle } from '~/components/input/LoaderCircle'; -import { ImagePresets, URLS } from '~/constants/urls'; +import { imagePresets, URLS } from '~/constants/urls'; import { useWindowSize } from '~/hooks/dom/useWindowSize'; import { useNavigation } from '~/hooks/navigation/useNavigation'; import { IFlowNode } from '~/types'; @@ -45,7 +45,7 @@ export const FlowSwiperHero: FC = ({ heroes }) => { >(undefined); const [currentIndex, setCurrentIndex] = useState(heroes.length); const preset = useMemo( - () => (isTablet ? ImagePresets.cover : ImagePresets.small_hero), + () => (isTablet ? imagePresets.cover : imagePresets.small_hero), [isTablet], ); diff --git a/src/components/main/UserButton/index.tsx b/src/components/main/UserButton/index.tsx index dd06a27b..b7e6c3c4 100644 --- a/src/components/main/UserButton/index.tsx +++ b/src/components/main/UserButton/index.tsx @@ -3,7 +3,7 @@ import { FC } from 'react'; import { Avatar } from '~/components/common/Avatar'; import { Group } from '~/components/containers/Group'; import { Icon } from '~/components/input/Icon'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IFile } from '~/types'; import { getURL } from '~/utils/dom'; @@ -20,7 +20,7 @@ const UserButton: FC = ({ username, photo, onClick }) => { ); diff --git a/src/components/media/ImagePreloader/index.tsx b/src/components/media/ImagePreloader/index.tsx index e650a8aa..f1b00ea3 100644 --- a/src/components/media/ImagePreloader/index.tsx +++ b/src/components/media/ImagePreloader/index.tsx @@ -1,4 +1,10 @@ -import React, { FC, MouseEventHandler, useCallback, useMemo, useState } from 'react'; +import React, { + FC, + MouseEventHandler, + useCallback, + useMemo, + useState, +} from 'react'; import classNames from 'classnames'; @@ -6,7 +12,7 @@ import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad'; import { Icon } from '~/components/input/Icon'; import { LoaderCircle } from '~/components/input/LoaderCircle'; import { DEFAULT_DOMINANT_COLOR } from '~/constants/node'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useResizeHandler } from '~/hooks/dom/useResizeHandler'; import { IFile } from '~/types'; import { getURL } from '~/utils/dom'; @@ -24,7 +30,13 @@ interface IProps { const DEFAULT_WIDTH = 1920; const DEFAULT_HEIGHT = 1020; -const ImagePreloader: FC = ({ file, color, onLoad, onClick, className }) => { +const ImagePreloader: FC = ({ + file, + color, + onLoad, + onClick, + className, +}) => { const [maxHeight, setMaxHeight] = useState(0); const [loaded, setLoaded] = useState(false); const [hasError, setHasError] = useState(false); @@ -47,8 +59,11 @@ const ImagePreloader: FC = ({ file, color, onLoad, onClick, className }) }, [setHasError]); const [width, height] = useMemo( - () => [file?.metadata?.width || DEFAULT_WIDTH, file?.metadata?.height || DEFAULT_HEIGHT], - [file] + () => [ + file?.metadata?.width || DEFAULT_WIDTH, + file?.metadata?.height || DEFAULT_HEIGHT, + ], + [file], ); useResizeHandler(onResize); @@ -74,11 +89,18 @@ const ImagePreloader: FC = ({ file, color, onLoad, onClick, className }) - + {!hasError && ( = ({ file, color, onLoad, onClick, className }) = ({ file, color, onLoad, onClick, className }) onError={onError} /> - {!loaded && !hasError && } + {!loaded && !hasError && ( + + )} {hasError && (
diff --git a/src/components/node/NodeAudioImageBlock/index.tsx b/src/components/node/NodeAudioImageBlock/index.tsx index 28726f0e..2563ae73 100644 --- a/src/components/node/NodeAudioImageBlock/index.tsx +++ b/src/components/node/NodeAudioImageBlock/index.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { INodeComponentProps } from '~/constants/node'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useNodeImages } from '~/hooks/node/useNodeImages'; import { getURL } from '~/utils/dom'; import { path } from '~/utils/ramda'; @@ -19,7 +19,12 @@ const NodeAudioImageBlock: FC = ({ node }) => {
); diff --git a/src/components/node/NodeImageSwiperBlock/index.tsx b/src/components/node/NodeImageSwiperBlock/index.tsx index 0e8b6102..040a3c44 100644 --- a/src/components/node/NodeImageSwiperBlock/index.tsx +++ b/src/components/node/NodeImageSwiperBlock/index.tsx @@ -1,5 +1,6 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import { observer } from 'mobx-react-lite'; import Image from 'next/future/image'; import SwiperCore, { @@ -7,22 +8,26 @@ import SwiperCore, { Navigation, Pagination, SwiperOptions, + Lazy, } from 'swiper'; import { Swiper, SwiperSlide } from 'swiper/react'; import SwiperClass from 'swiper/types/swiper-class'; import { ImagePreloader } from '~/components/media/ImagePreloader'; import { INodeComponentProps } from '~/constants/node'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useModal } from '~/hooks/modal/useModal'; import { useImageModal } from '~/hooks/navigation/useImageModal'; import { useNodeImages } from '~/hooks/node/useNodeImages'; +import { IFile } from '~/types'; import { normalizeBrightColor } from '~/utils/color'; import { getURL } from '~/utils/dom'; +import { imageSrcSets, ImagePreset } from '../../../constants/urls'; + import styles from './styles.module.scss'; -SwiperCore.use([Navigation, Pagination, Keyboard]); +SwiperCore.use([Navigation, Pagination, Keyboard, Lazy]); interface IProps extends INodeComponentProps {} @@ -34,6 +39,22 @@ const breakpoints: SwiperOptions['breakpoints'] = { const pagination = { type: 'fraction' as const }; +const lazy = { + enabled: true, + loadPrevNextAmount: 1, + loadOnTransitionStart: true, + loadPrevNext: true, + checkInView: true, +}; + +const generateSrcSet = (file: IFile) => + Object.keys(imageSrcSets) + .map( + (preset) => + `${getURL(file, preset as ImagePreset)} ${imageSrcSets[preset]}w`, + ) + .join(', '); + const NodeImageSwiperBlock: FC = observer(({ node }) => { const [controlledSwiper, setControlledSwiper] = useState< SwiperClass | undefined @@ -126,20 +147,22 @@ const NodeImageSwiperBlock: FC = observer(({ node }) => { autoHeight zoom navigation + watchSlidesProgress + lazy={lazy} > {images.map((file, i) => ( - onOpenPhotoSwipe(i)} - className={styles.image} + className={classNames(styles.image, 'swiper-lazy')} color={normalizeBrightColor(file?.metadata?.dominant_color)} alt="" - priority={i < 2} + sizes="(max-width: 560px) 100vw, 50vh" /> ))} diff --git a/src/components/node/NodeRelatedItem/index.tsx b/src/components/node/NodeRelatedItem/index.tsx index be7186f1..cba4585b 100644 --- a/src/components/node/NodeRelatedItem/index.tsx +++ b/src/components/node/NodeRelatedItem/index.tsx @@ -5,7 +5,7 @@ import classNames from 'classnames'; import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad'; import { Square } from '~/components/common/Square'; import { Icon } from '~/components/input/Icon'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { useGotoNode } from '~/hooks/node/useGotoNode'; import { INode } from '~/types'; @@ -42,7 +42,7 @@ const NodeRelatedItem: FC = memo(({ item }) => { const thumb = useMemo( () => item.thumbnail - ? getURL({ url: item.thumbnail }, ImagePresets.avatar) + ? getURL({ url: item.thumbnail }, imagePresets.avatar) : '', [item], ); @@ -68,7 +68,7 @@ const NodeRelatedItem: FC = memo(({ item }) => { }, [width]); const image = useMemo( - () => getURL({ url: item.thumbnail }, ImagePresets.avatar), + () => getURL({ url: item.thumbnail }, imagePresets.avatar), [item.thumbnail], ); diff --git a/src/components/profile/ProfileAvatar/index.tsx b/src/components/profile/ProfileAvatar/index.tsx index 4168d385..7cdd652c 100644 --- a/src/components/profile/ProfileAvatar/index.tsx +++ b/src/components/profile/ProfileAvatar/index.tsx @@ -2,7 +2,7 @@ import React, { ChangeEvent, FC, useCallback } from 'react'; import { Avatar } from '~/components/common/Avatar'; import { Button } from '~/components/input/Button'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IFile } from '~/types'; import { getURL } from '~/utils/dom'; diff --git a/src/components/sortable/SortableImageGrid/index.tsx b/src/components/sortable/SortableImageGrid/index.tsx index ecc9e7c7..3b547dc8 100644 --- a/src/components/sortable/SortableImageGrid/index.tsx +++ b/src/components/sortable/SortableImageGrid/index.tsx @@ -1,7 +1,7 @@ import React, { FC, useMemo } from 'react'; import { ImageUpload } from '~/components/upload/ImageUpload'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { UploadStatus } from '~/store/uploader/UploaderStore'; import { IFile } from '~/types'; import { getURL } from '~/utils/dom'; @@ -18,8 +18,18 @@ interface SortableImageGridProps { className?: string; size?: number; } -const renderItem = ({ item, onDelete }: { item: IFile; onDelete: (fileId: number) => void }) => ( - +const renderItem = ({ + item, + onDelete, +}: { + item: IFile; + onDelete: (fileId: number) => void; +}) => ( + ); const renderLocked = ({ @@ -29,7 +39,12 @@ const renderLocked = ({ locked: UploadStatus; onDelete: (fileId: number) => void; }) => ( - + ); const SortableImageGrid: FC = ({ @@ -46,8 +61,8 @@ const SortableImageGrid: FC = ({ it.id} - getLockedID={it => it.id} + getID={(it) => it.id} + getLockedID={(it) => it.id} renderItem={renderItem} renderItemProps={props} renderLocked={renderLocked} diff --git a/src/constants/urls.ts b/src/constants/urls.ts index 5f1fc6f7..9f3a8b7b 100644 --- a/src/constants/urls.ts +++ b/src/constants/urls.ts @@ -1,49 +1,61 @@ -import { FlowDisplayVariant, INode } from "~/types"; +import { FlowDisplayVariant, INode } from '~/types'; export const URLS = { - BASE: "/", - LAB: "/lab", - BORIS: "/boris", + BASE: '/', + LAB: '/lab', + BORIS: '/boris', AUTH: { - LOGIN: "/auth/login", + LOGIN: '/auth/login', }, EXAMPLES: { - EDITOR: "/examples/edit", - IMAGE: "/examples/image", + EDITOR: '/examples/edit', + IMAGE: '/examples/image', }, ERRORS: { - NOT_FOUND: "/lost", - BACKEND_DOWN: "/oopsie", + NOT_FOUND: '/lost', + BACKEND_DOWN: '/oopsie', }, - NODE_URL: (id: INode["id"] | string) => `/post${id}`, + NODE_URL: (id: INode['id'] | string) => `/post${id}`, PROFILE_PAGE: (username: string) => `/profile/${username}`, SETTINGS: { - BASE: "/settings", - NOTES: "/settings/notes", - TRASH: "/settings/trash", + BASE: '/settings', + NOTES: '/settings/notes', + TRASH: '/settings/trash', }, - NOTES: "/notes/", + NOTES: '/notes/', NOTE: (id: number) => `/notes/${id}`, }; -export const ImagePresets = { - "1600": "1600", - "600": "600", - "300": "300", - cover: "cover", - small_hero: "small_hero", - avatar: "avatar", - flow_square: "flow_square", - flow_vertical: "flow_vertical", - flow_horizontal: "flow_horizontal", +export const imagePresets = { + '1600': '1600', + '900': '900', + '1200': '1200', + '600': '600', + '300': '300', + cover: 'cover', + small_hero: 'small_hero', + avatar: 'avatar', + flow_square: 'flow_square', + flow_vertical: 'flow_vertical', + flow_horizontal: 'flow_horizontal', } as const; +export type ImagePreset = typeof imagePresets[keyof typeof imagePresets]; + +export const imageSrcSets: Partial> = { + [imagePresets[1600]]: 1600, + [imagePresets[900]]: 900, + [imagePresets[1200]]: 1200, + [imagePresets[600]]: 600, + [imagePresets[300]]: 300, +}; + export const flowDisplayToPreset: Record< FlowDisplayVariant, - typeof ImagePresets[keyof typeof ImagePresets] + typeof imagePresets[keyof typeof imagePresets] > = { - single: "flow_square", - quadro: "flow_square", - vertical: "flow_vertical", - horizontal: "flow_horizontal", + single: 'flow_square', + quadro: 'flow_square', + vertical: 'flow_vertical', + horizontal: 'flow_horizontal', }; diff --git a/src/containers/dialogs/PhotoSwipe/index.tsx b/src/containers/dialogs/PhotoSwipe/index.tsx index f64395b0..a66ed514 100644 --- a/src/containers/dialogs/PhotoSwipe/index.tsx +++ b/src/containers/dialogs/PhotoSwipe/index.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react-lite'; import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.js'; import PhotoSwipeJs from 'photoswipe/dist/photoswipe.js'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { useWindowSize } from '~/hooks/dom/useWindowSize'; import { useModal } from '~/hooks/modal/useModal'; import { IFile } from '~/types'; @@ -25,18 +25,18 @@ const PhotoSwipe: VFC = observer(({ index, items }) => { const { isTablet } = useWindowSize(); useEffect(() => { - new Promise(async resolve => { + new Promise(async (resolve) => { const images = await Promise.all( items.map( - image => - new Promise(resolveImage => { + (image) => + new Promise((resolveImage) => { const img = new Image(); img.onload = () => { resolveImage({ src: getURL( image, - isTablet ? ImagePresets[900] : ImagePresets[1600], + isTablet ? imagePresets[900] : imagePresets[1600], ), h: img.naturalHeight, w: img.naturalWidth, @@ -47,13 +47,13 @@ const PhotoSwipe: VFC = observer(({ index, items }) => { resolveImage({}); }; - img.src = getURL(image, ImagePresets[1600]); + img.src = getURL(image, imagePresets[1600]); }), ), ); resolve(images); - }).then(images => { + }).then((images) => { const ps = new PhotoSwipeJs(ref.current, PhotoSwipeUI_Default, images, { index: index || 0, closeOnScroll: false, diff --git a/src/containers/profile/ProfilePageLeft/index.tsx b/src/containers/profile/ProfilePageLeft/index.tsx index a5360f1e..b6f13062 100644 --- a/src/containers/profile/ProfilePageLeft/index.tsx +++ b/src/containers/profile/ProfilePageLeft/index.tsx @@ -3,7 +3,7 @@ import React, { FC } from 'react'; import { Avatar } from '~/components/common/Avatar'; import { Markdown } from '~/components/containers/Markdown'; import { Placeholder } from '~/components/placeholders/Placeholder'; -import { ImagePresets } from '~/constants/urls'; +import { imagePresets } from '~/constants/urls'; import { IUser } from '~/types/auth'; import { formatText } from '~/utils/dom'; @@ -22,7 +22,7 @@ const ProfilePageLeft: FC = ({ username, profile, isLoading }) => { username={username} url={profile?.photo?.url} className={styles.avatar} - preset={ImagePresets['600']} + preset={imagePresets['600']} />
diff --git a/src/utils/dom.ts b/src/utils/dom.ts index 8e93e4e5..1bed443a 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -5,8 +5,12 @@ import formatDistanceToNow from 'date-fns/formatDistanceToNow'; import isAfter from 'date-fns/isAfter'; import ru from 'date-fns/locale/ru'; -import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/constants/comment'; -import { ImagePresets } from '~/constants/urls'; +import { + COMMENT_BLOCK_DETECTORS, + COMMENT_BLOCK_TYPES, + ICommentBlock, +} from '~/constants/comment'; +import { imagePresets } from '~/constants/urls'; import { IFile, ValueOf } from '~/types'; import { CONFIG } from '~/utils/config'; import { @@ -22,6 +26,8 @@ import { import { pipe } from '~/utils/ramda'; import { splitTextByYoutube, splitTextOmitEmpty } from '~/utils/splitText'; +import { ImagePreset } from '../constants/urls'; + function polarToCartesian(centerX, centerY, radius, angleInDegrees) { const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; @@ -36,7 +42,7 @@ export const describeArc = ( y: number, radius: number, startAngle: number = 0, - endAngle: number = 360 + endAngle: number = 360, ): string => { const start = polarToCartesian(x, y, radius, endAngle); const end = polarToCartesian(x, y, radius, startAngle); @@ -64,12 +70,12 @@ export const describeArc = ( ].join(' '); }; -export const getURLFromString = ( - url?: string, - size?: typeof ImagePresets[keyof typeof ImagePresets] -): string => { +export const getURLFromString = (url?: string, size?: ImagePreset): string => { if (size) { - return (url || '').replace('REMOTE_CURRENT://', `${CONFIG.remoteCurrent}cache/${size}/`); + return (url || '').replace( + 'REMOTE_CURRENT://', + `${CONFIG.remoteCurrent}cache/${size}/`, + ); } return (url || '').replace('REMOTE_CURRENT://', CONFIG.remoteCurrent); @@ -77,7 +83,7 @@ export const getURLFromString = ( export const getURL = ( file: Partial | undefined, - size?: typeof ImagePresets[keyof typeof ImagePresets] + size?: ImagePreset, ) => { return file?.url ? getURLFromString(file.url, size) : ''; }; @@ -90,27 +96,34 @@ export const formatText = pipe( formatTextDash, formatTextMarkdown, formatTextSanitizeTags, - formatTextClickableUsernames + formatTextClickableUsernames, ); -export const formatTextParagraphs = (text: string): string => (text && formatText(text)) || ''; +export const formatTextParagraphs = (text: string): string => + (text && formatText(text)) || ''; -export const findBlockType = (line: string): ValueOf => { - const match = Object.values(COMMENT_BLOCK_DETECTORS).find(detector => line.match(detector.test)); +export const findBlockType = ( + line: string, +): ValueOf => { + const match = Object.values(COMMENT_BLOCK_DETECTORS).find((detector) => + line.match(detector.test), + ); return (match && match.type) || COMMENT_BLOCK_TYPES.TEXT; }; export const splitCommentByBlocks = (text: string): ICommentBlock[] => pipe( splitTextByYoutube, - splitTextOmitEmpty - )([text]).map(line => ({ + splitTextOmitEmpty, + )([text]).map((line) => ({ type: findBlockType(line), content: line, })); -export const formatCommentText = (author?: string, text?: string): ICommentBlock[] => - author && text ? splitCommentByBlocks(text) : []; +export const formatCommentText = ( + author?: string, + text?: string, +): ICommentBlock[] => (author && text ? splitCommentByBlocks(text) : []); export const getPrettyDate = (date?: string): string => { if (!date) { @@ -135,10 +148,12 @@ export const getYoutubeThumb = (url: string) => { const match = url && url.match( - /http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-_]*)(&(amp;)?[\w?=]*)?/ + /http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-_]*)(&(amp;)?[\w?=]*)?/, ); - return match && match[1] ? `https://i.ytimg.com/vi/${match[1]}/hqdefault.jpg` : null; + return match && match[1] + ? `https://i.ytimg.com/vi/${match[1]}/hqdefault.jpg` + : null; }; export const stringToColour = (str: string) => { @@ -191,5 +206,7 @@ export const sizeOf = (bytes: number): string => { return '0.00 B'; } let e = Math.floor(Math.log(bytes) / Math.log(1024)); - return (bytes / Math.pow(1024, e)).toFixed(2) + ' ' + ' KMGTP'.charAt(e) + 'B'; + return ( + (bytes / Math.pow(1024, e)).toFixed(2) + ' ' + ' KMGTP'.charAt(e) + 'B' + ); };