1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-05-01 23:56:41 +07:00

Merge pull request from muerwre/develop

NextJS build
This commit is contained in:
muerwre 2022-01-19 17:34:38 +07:00 committed by GitHub
commit 437bee5905
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
354 changed files with 2083 additions and 998 deletions
.dockerignore.drone.yml.env.local.eslintignore.eslintrc.jscraco.config.js
docker/nextjs
next.config.jspackage.json
src
api
components
auth
login/LoginDialogButtons
oauth/LoginSocialRegisterButtons
restore
RestoreInvalidCode
RestoreSent
RestoreSuccess
bars
PlayerBar
SubmitBar
boris
BorisContactItem
BorisContacts
BorisSidebar
BorisStats
BorisStatsBackend
BorisStatsGit
BorisStatsGitCard
BorisSuperpowers
BorisUIDemo
Superpower
comment
Comment
CommentAvatar
CommentContent
CommentEmbedBlock
CommentForm
CommentFormAttachButtons
CommentFormAttaches
CommentFormFormatButtons
CommentMenu
CommentTextBlock
LocalCommentFormTextarea
common
Anchor
Avatar
ImageWithSSRLoad
LoadingProgress
MenuDots
PageTitle
ScrollHelperBottom
Square
StatsRow
SubTitle
containers
Authorized
BlurWrapper
Card
CellGrid
CommentWrapper
CoverBackdrop
Filler
Grid
Group
InfiniteScroll
Markdown
Padder
PageCoverProvider
Panel
Sticky
TagField
dialogs
BetterScrollDialog
DialogTitle
ModalWrapper
Tabs
editors
AudioEditor
AudioGrid
EditorActionsPanel
EditorAudioUploadButton
EditorButtons
EditorConfirmClose
EditorFiller
EditorImageUploadButton
EditorPublicSwitch
EditorUploadButton
EditorUploadCoverButton
ImageEditor
ImageGrid
SortableAudioGrid
SortableAudioGridItem
SortableImageGrid
SortableImageGridItem
TextEditor
VideoEditor
flow
CellShade
FlowCell

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
**/node_modules
node_modules

View file

@ -7,19 +7,35 @@ platform:
arch: amd64 arch: amd64
steps: steps:
# - name: restore-cache-with-filesystem
# image: meltwater/drone-cache:dev
# when:
# branch:
# - develop
# pull: true
# settings:
# backend: "filesystem"
# restore: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "package.json" }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
# archive_format: "gzip"
# mount:
# - '/app'
# volumes:
# - name: cache
# path: /tmp/cache
- name: build-master - name: build-master
image: plugins/docker image: plugins/docker
when: when:
branch: branch:
- master - master
environment: environment:
REACT_APP_API_HOST: https://pig.vault48.org/ NEXT_PUBLIC_API_HOST: https://pig.vault48.org/
REACT_APP_REMOTE_CURRENT: https://pig.vault48.org/static/ NEXT_PUBLIC_REMOTE_CURRENT: https://pig.vault48.org/static/
settings: settings:
dockerfile: docker/www/Dockerfile dockerfile: docker/nextjs/Dockerfile
build_args_from_env: build_args_from_env:
- REACT_APP_API_HOST - NEXT_PUBLIC_API_HOST
- REACT_APP_REMOTE_CURRENT - NEXT_PUBLIC_REMOTE_CURRENT
tag: tag:
- ${DRONE_BRANCH} - ${DRONE_BRANCH}
custom_labels: custom_labels:
@ -38,13 +54,13 @@ steps:
branch: branch:
- develop - develop
environment: environment:
REACT_APP_API_HOST: https://pig.staging.vault48.org/ NEXT_PUBLIC_API_HOST: https://pig.staging.vault48.org/
REACT_APP_REMOTE_CURRENT: https://pig.staging.vault48.org/static/ NEXT_PUBLIC_REMOTE_CURRENT: https://pig.staging.vault48.org/static/
settings: settings:
dockerfile: docker/www/Dockerfile dockerfile: docker/nextjs/Dockerfile
build_args_from_env: build_args_from_env:
- REACT_APP_API_HOST - NEXT_PUBLIC_API_HOST
- REACT_APP_REMOTE_CURRENT - NEXT_PUBLIC_REMOTE_CURRENT
tag: tag:
- ${DRONE_BRANCH} - ${DRONE_BRANCH}
custom_labels: custom_labels:
@ -57,3 +73,22 @@ steps:
from_secret: global_docker_registry from_secret: global_docker_registry
repo: repo:
from_secret: docker_repo from_secret: docker_repo
# - name: rebuild-cache-with-filesystem
# image: meltwater/drone-cache:dev
# when:
# branch:
# - develop
# pull: true
# settings:
# backend: "filesystem"
# rebuild: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "package.json" }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
# archive_format: "gzip"
# mount:
# - '/app'
# volumes:
# - name: cache
# path: /tmp/cache
#volumes:
# - name: cache
# temp: {}

View file

@ -1,4 +1,2 @@
#REACT_APP_API_HOST=http://localhost:3334/
NEXT_PUBLIC_API_HOST=https://pig.staging.vault48.org/ NEXT_PUBLIC_API_HOST=https://pig.staging.vault48.org/
#REACT_APP_API_HOST=https://pig.vault48.org/
NEXT_PUBLIC_REMOTE_CURRENT=https://pig.staging.vault48.org/static/ NEXT_PUBLIC_REMOTE_CURRENT=https://pig.staging.vault48.org/static/

4
.eslintignore Normal file
View file

@ -0,0 +1,4 @@
build
.next
.husky
node_modules

33
.eslintrc.js Normal file
View file

@ -0,0 +1,33 @@
module.exports = {
extends: ['plugin:react/recommended', 'plugin:@next/next/recommended'],
rules: {
'react/prop-types': 0,
'react/display-name': 0,
'react/react-in-jsx-scope': 0,
'@next/next/no-img-element': 0,
'import/order': [
'error',
{
alphabetize: { order: 'asc' },
'newlines-between': 'always',
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'unknown'],
pathGroups: [
{
pattern: 'react',
group: 'builtin',
position: 'before',
},
{ pattern: '~/**', group: 'internal' },
{ pattern: './**', group: 'sibling' },
],
pathGroupsExcludedImportTypes: ['react'],
},
],
},
parserOptions: {
ecmaVersion: 7,
sourceType: 'module',
},
plugins: ['import', 'react-hooks'],
parser: '@typescript-eslint/parser',
};

View file

@ -29,6 +29,29 @@ module.exports = {
allowSeparatedGroups: false, allowSeparatedGroups: false,
}, },
], ],
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'sibling', 'type', 'object'],
pathGroups: [
{
pattern: '~/**',
group: 'internal',
},
{
pattern: '../**',
group: 'sibling',
position: 'after',
},
{
pattern: './**',
group: 'sibling',
position: 'after',
},
],
'newlines-between': 'always',
},
],
}, },
}, },
jest: { jest: {

12
docker/nextjs/Dockerfile Normal file
View file

@ -0,0 +1,12 @@
FROM node:14-alpine as builder
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn
COPY . .
ARG NEXT_PUBLIC_API_HOST
ARG NEXT_PUBLIC_REMOTE_CURRENT
ENV NEXT_PUBLIC_API_HOST $NEXT_PUBLIC_API_HOST
ENV NEXT_PUBLIC_REMOTE_CURRENT $NEXT_PUBLIC_REMOTE_CURRENT
RUN yarn next:build
ENTRYPOINT ["yarn", "next:start"]

View file

@ -1,7 +1,8 @@
/** used to transpile UMD and CJS modules */
const withTM = require('next-transpile-modules')(['ramda']); const withTM = require('next-transpile-modules')(['ramda']);
module.exports = withTM({ module.exports = withTM({
/* Your Next.js config */ /** rewrite old-style node paths */
async rewrites() { async rewrites() {
return [ return [
{ {
@ -10,4 +11,7 @@ module.exports = withTM({
}, },
]; ];
}, },
/** don't try to optimize fonts */
optimizeFonts: false,
}); });

View file

@ -55,7 +55,9 @@
"build": "craco build", "build": "craco build",
"ts-check": "tsc -p tsconfig.json --noEmit", "ts-check": "tsc -p tsconfig.json --noEmit",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx", "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"prepare": "husky install" "prepare": "husky install",
"next:build": "next build",
"next:start": "next start -p 80"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
@ -76,6 +78,7 @@
}, },
"devDependencies": { "devDependencies": {
"@craco/craco": "^6.4.3", "@craco/craco": "^6.4.3",
"@next/eslint-plugin-next": "^12.0.8",
"@types/classnames": "^2.2.7", "@types/classnames": "^2.2.7",
"@types/marked": "^1.2.2", "@types/marked": "^1.2.2",
"@types/node": "^11.13.22", "@types/node": "^11.13.22",
@ -83,6 +86,7 @@
"@types/throttle-debounce": "^2.1.0", "@types/throttle-debounce": "^2.1.0",
"@types/yup": "^0.29.11", "@types/yup": "^0.29.11",
"craco-alias": "^2.3.1", "craco-alias": "^2.3.1",
"eslint-plugin-import": "^2.25.4",
"husky": "^7.0.4", "husky": "^7.0.4",
"lint-staged": "^12.1.6", "lint-staged": "^12.1.6",
"next-transpile-modules": "^9.0.0", "next-transpile-modules": "^9.0.0",

View file

@ -1,5 +1,3 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api';
import { import {
ApiAttachSocialRequest, ApiAttachSocialRequest,
ApiAttachSocialResult, ApiAttachSocialResult,
@ -22,6 +20,8 @@ import {
ApiUserLoginRequest, ApiUserLoginRequest,
ApiUserLoginResult, ApiUserLoginResult,
} from '~/api/auth/types'; } from '~/api/auth/types';
import { API } from '~/constants/api';
import { api, cleanResult } from '~/utils/api';
export const apiUserLogin = ({ username, password }: ApiUserLoginRequest) => export const apiUserLogin = ({ username, password }: ApiUserLoginRequest) =>
api api

View file

@ -1,8 +1,9 @@
import { API } from '~/constants/api';
import { api, cleanResult } from '~/utils/api';
import { IGetGithubIssuesResult, StatBackend } from '~/types/boris';
import axios from 'axios'; import axios from 'axios';
import { API } from '~/constants/api';
import { IGetGithubIssuesResult, StatBackend } from '~/types/boris';
import { api, cleanResult } from '~/utils/api';
export const getBorisBackendStats = () => export const getBorisBackendStats = () =>
api.get<StatBackend>(API.BORIS.GET_BACKEND_STATS).then(cleanResult); api.get<StatBackend>(API.BORIS.GET_BACKEND_STATS).then(cleanResult);

View file

@ -1,7 +1,7 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api'; import { API } from '~/constants/api';
import { PostCellViewRequest, PostCellViewResult } from '~/types/node';
import { GetSearchResultsRequest, GetSearchResultsResult } from '~/types/flow'; import { GetSearchResultsRequest, GetSearchResultsResult } from '~/types/flow';
import { PostCellViewRequest, PostCellViewResult } from '~/types/node';
import { api, cleanResult } from '~/utils/api';
export const postCellView = ({ id, flow }: PostCellViewRequest) => export const postCellView = ({ id, flow }: PostCellViewRequest) =>
api api

View file

@ -1,4 +1,3 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api'; import { API } from '~/constants/api';
import { import {
GetLabNodesRequest, GetLabNodesRequest,
@ -6,6 +5,7 @@ import {
GetLabStatsResult, GetLabStatsResult,
GetLabUpdatesResult, GetLabUpdatesResult,
} from '~/types/lab'; } from '~/types/lab';
import { api, cleanResult } from '~/utils/api';
export const getLabNodes = ({ after }: GetLabNodesRequest) => export const getLabNodes = ({ after }: GetLabNodesRequest) =>
api api

View file

@ -1,5 +1,3 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api';
import { import {
ApiDeleteMessageRequest, ApiDeleteMessageRequest,
ApiDeleteMessageResult, ApiDeleteMessageResult,
@ -8,6 +6,8 @@ import {
ApiSendMessageRequest, ApiSendMessageRequest,
ApiSendMessageResult, ApiSendMessageResult,
} from '~/api/messages/types'; } from '~/api/messages/types';
import { API } from '~/constants/api';
import { api, cleanResult } from '~/utils/api';
export const apiGetUserMessages = ({ username, after, before }: ApiGetUserMessagesRequest) => export const apiGetUserMessages = ({ username, after, before }: ApiGetUserMessagesRequest) =>
api api

View file

@ -1,6 +1,6 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api';
import { ApiGetEmbedYoutubeResult } from '~/api/metadata/types'; import { ApiGetEmbedYoutubeResult } from '~/api/metadata/types';
import { API } from '~/constants/api';
import { api, cleanResult } from '~/utils/api';
export const apiGetEmbedYoutube = (ids: string[]) => export const apiGetEmbedYoutube = (ids: string[]) =>
api api

View file

@ -1,7 +1,8 @@
import { api, cleanResult } from '~/utils/api'; import axios, { AxiosRequestConfig } from 'axios';
import { IComment, INode } from '~/types';
import { API } from '~/constants/api'; import { API } from '~/constants/api';
import { COMMENTS_DISPLAY } from '~/constants/node'; import { COMMENTS_DISPLAY } from '~/constants/node';
import { IComment, INode } from '~/types';
import { import {
ApiDeleteNodeTagsRequest, ApiDeleteNodeTagsRequest,
ApiDeleteNodeTagsResult, ApiDeleteNodeTagsResult,
@ -24,7 +25,8 @@ import {
GetNodeDiffRequest, GetNodeDiffRequest,
GetNodeDiffResult, GetNodeDiffResult,
} from '~/types/node'; } from '~/types/node';
import axios, { AxiosRequestConfig } from 'axios'; import { api, cleanResult } from '~/utils/api';
export type ApiPostNodeRequest = { node: INode }; export type ApiPostNodeRequest = { node: INode };
export type ApiPostNodeResult = { export type ApiPostNodeResult = {

View file

@ -1,4 +1,3 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api'; import { API } from '~/constants/api';
import { import {
ApiGetNodesOfTagRequest, ApiGetNodesOfTagRequest,
@ -6,6 +5,7 @@ import {
ApiGetTagSuggestionsRequest, ApiGetTagSuggestionsRequest,
ApiGetTagSuggestionsResult, ApiGetTagSuggestionsResult,
} from '~/types/tags'; } from '~/types/tags';
import { api, cleanResult } from '~/utils/api';
export const apiGetNodesOfTag = ({ tag, offset, limit }: ApiGetNodesOfTagRequest) => export const apiGetNodesOfTag = ({ tag, offset, limit }: ApiGetNodesOfTagRequest) =>
api api

View file

@ -1,8 +1,8 @@
import { api, cleanResult } from '~/utils/api';
import { API } from '~/constants/api';
import { ApiUploadFileRequest, ApiUploadFIleResult } from '~/api/uploads/types'; import { ApiUploadFileRequest, ApiUploadFIleResult } from '~/api/uploads/types';
import { API } from '~/constants/api';
import { UploadTarget, UploadType } from '~/constants/uploads'; import { UploadTarget, UploadType } from '~/constants/uploads';
import { api, cleanResult } from '~/utils/api';
export const apiUploadFile = ({ export const apiUploadFile = ({
file, file,

View file

@ -1,5 +1,5 @@
import { IFile, IUploadProgressHandler } from '~/types';
import { UploadTarget, UploadType } from '~/constants/uploads'; import { UploadTarget, UploadType } from '~/constants/uploads';
import { IFile, IUploadProgressHandler } from '~/types';
export type ApiUploadFileRequest = { export type ApiUploadFileRequest = {
file: File; file: File;

View file

@ -1,10 +1,13 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { Button } from '~/components/input/Button';
import { Grid } from '~/components/containers/Grid'; import { Grid } from '~/components/containers/Grid';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import styles from './styles.module.scss'; import { Button } from '~/components/input/Button';
import { OAuthProvider } from '~/types/auth'; import { OAuthProvider } from '~/types/auth';
import styles from './styles.module.scss';
interface IProps { interface IProps {
openOauthWindow: (provider: OAuthProvider) => void; openOauthWindow: (provider: OAuthProvider) => void;
} }

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps {} interface IProps {}

View file

@ -1,9 +1,11 @@
import React, { VFC } from 'react'; import React, { VFC } from 'react';
import styles from './styles.module.scss';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { ERROR_LITERAL, ERRORS } from '~/constants/errors'; import { ERROR_LITERAL, ERRORS } from '~/constants/errors';
import { Button } from '~/components/input/Button';
import styles from './styles.module.scss';
interface RestoreInvalidCodeProps { interface RestoreInvalidCodeProps {
error: string; error: string;

View file

@ -1,8 +1,10 @@
import React, { VFC } from 'react'; import React, { VFC } from 'react';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon';
import { Button } from '~/components/input/Button';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss';
interface RestoreSentProps { interface RestoreSentProps {
onClose: () => void; onClose: () => void;

View file

@ -1,7 +1,9 @@
import React, { VFC } from 'react'; import React, { VFC } from 'react';
import { Icon } from '~/components/input/Icon';
import { Button } from '~/components/input/Button';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface RestoreSuccessProps { interface RestoreSuccessProps {

View file

@ -1,11 +1,14 @@
import React, { useCallback, VFC } from 'react'; import React, { useCallback, VFC } from 'react';
import styles from './styles.module.scss';
import { path } from 'ramda';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { PlayerState } from '~/constants/player'; import { PlayerState } from '~/constants/player';
import { path } from 'ramda';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { PlayerProgress } from '~/types/player'; import { PlayerProgress } from '~/types/player';
import styles from './styles.module.scss';
interface Props { interface Props {
progress: PlayerProgress; progress: PlayerProgress;
status: PlayerState; status: PlayerState;

View file

@ -1,9 +1,13 @@
import React, { FC, useCallback, useState } from 'react'; import React, { FC, useCallback, useState } from 'react';
import { Icon } from '~/components/input/Icon';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
import { useShowModal } from '~/hooks/modal/useShowModal'; import { Icon } from '~/components/input/Icon';
import { Dialog } from '~/constants/modal'; import { Dialog } from '~/constants/modal';
import { useShowModal } from '~/hooks/modal/useShowModal';
import styles from './styles.module.scss';
interface Props { interface Props {
isLab?: boolean; isLab?: boolean;

View file

@ -1,7 +1,9 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss';
interface Props { interface Props {
icon: string; icon: string;
title: string; title: string;

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { BorisContactItem } from '~/components/boris/BorisContactItem'; import { BorisContactItem } from '~/components/boris/BorisContactItem';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface Props {} interface Props {}

View file

@ -1,9 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from '~/layouts/BorisLayout/styles.module.scss';
import { BorisSuperpowers } from '~/components/boris/BorisSuperpowers';
import { BorisContacts } from '~/components/boris/BorisContacts'; import { BorisContacts } from '~/components/boris/BorisContacts';
import { BorisStats } from '~/components/boris/BorisStats'; import { BorisStats } from '~/components/boris/BorisStats';
import { BorisSuperpowers } from '~/components/boris/BorisSuperpowers';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import styles from '~/layouts/BorisLayout/styles.module.scss';
import { BorisUsageStats } from '~/types/boris'; import { BorisUsageStats } from '~/types/boris';
interface Props { interface Props {

View file

@ -1,7 +1,9 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { BorisUsageStats } from '~/types/boris'; import { BorisUsageStats } from '~/types/boris';
import { BorisStatsGit } from '../BorisStatsGit';
import { BorisStatsBackend } from '../BorisStatsBackend'; import { BorisStatsBackend } from '../BorisStatsBackend';
import { BorisStatsGit } from '../BorisStatsGit';
interface IProps { interface IProps {
stats: BorisUsageStats; stats: BorisUsageStats;

View file

@ -1,9 +1,11 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { StatBackend } from '~/types/boris';
import styles from './styles.module.scss';
import { sizeOf } from '~/utils/dom';
import { StatsRow } from '~/components/common/StatsRow'; import { StatsRow } from '~/components/common/StatsRow';
import { SubTitle } from '~/components/common/SubTitle'; import { SubTitle } from '~/components/common/SubTitle';
import { StatBackend } from '~/types/boris';
import { sizeOf } from '~/utils/dom';
import styles from './styles.module.scss';
interface IProps { interface IProps {
stats: StatBackend; stats: StatBackend;

View file

@ -1,9 +1,12 @@
import React, { FC, useMemo } from 'react'; import React, { FC, useMemo } from 'react';
import { GithubIssue } from '~/types/boris';
import styles from './styles.module.scss';
import { Placeholder } from '~/components/placeholders/Placeholder'; import { Placeholder } from '~/components/placeholders/Placeholder';
import { GithubIssue } from '~/types/boris';
import { BorisStatsGitCard } from '../BorisStatsGitCard'; import { BorisStatsGitCard } from '../BorisStatsGitCard';
import styles from './styles.module.scss';
interface IProps { interface IProps {
issues: GithubIssue[]; issues: GithubIssue[];
isLoading: boolean; isLoading: boolean;

View file

@ -1,9 +1,13 @@
import React, { FC, useMemo } from 'react'; import React, { FC, useMemo } from 'react';
import styles from './styles.module.scss';
import { getPrettyDate } from '~/utils/dom';
import { GithubIssue } from '~/types/boris';
import classNames from 'classnames'; import classNames from 'classnames';
import { GithubIssue } from '~/types/boris';
import { getPrettyDate } from '~/utils/dom';
import styles from './styles.module.scss';
interface IProps { interface IProps {
data: GithubIssue; data: GithubIssue;
} }

View file

@ -1,7 +1,9 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { Toggle } from '~/components/input/Toggle'; import { Toggle } from '~/components/input/Toggle';
import styles from './styles.module.scss';
interface IProps { interface IProps {
active?: boolean; active?: boolean;
onChange?: (val: boolean) => void; onChange?: (val: boolean) => void;

View file

@ -1,12 +1,14 @@
import React, { FC, useState } from 'react'; import React, { FC, useState } from 'react';
import { Card } from '~/components/containers/Card'; import { Card } from '~/components/containers/Card';
import styles from './styles.module.scss';
import markdown from '~/styles/common/markdown.module.scss';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import { InputText } from '~/components/input/InputText'; import { InputText } from '~/components/input/InputText';
import { useShowModal } from '~/hooks/modal/useShowModal';
import { Dialog } from '~/constants/modal'; import { Dialog } from '~/constants/modal';
import { useShowModal } from '~/hooks/modal/useShowModal';
import markdown from '~/styles/common/markdown.module.scss';
import styles from './styles.module.scss';
interface IProps {} interface IProps {}

View file

@ -1,4 +1,5 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { useAuth } from '~/hooks/auth/useAuth'; import { useAuth } from '~/hooks/auth/useAuth';
interface IProps {} interface IProps {}

View file

@ -1,11 +1,18 @@
import React, { FC, HTMLAttributes, memo } from 'react'; import React, { FC, HTMLAttributes, memo } from 'react';
import { CommentWrapper } from '~/components/containers/CommentWrapper';
import { IComment, ICommentGroup, IFile } from '~/types';
import { CommentContent } from '~/components/comment/CommentContent';
import styles from './styles.module.scss';
import { CommendDeleted } from '../../node/CommendDeleted';
import classNames from 'classnames'; import classNames from 'classnames';
import { CommentContent } from '~/components/comment/CommentContent';
import { CommentWrapper } from '~/components/containers/CommentWrapper';
import { NEW_COMMENT_CLASSNAME } from '~/constants/comment'; import { NEW_COMMENT_CLASSNAME } from '~/constants/comment';
import { IComment, ICommentGroup, IFile } from '~/types';
import { CommendDeleted } from '../../node/CommendDeleted';
import styles from './styles.module.scss';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
nodeId: number; nodeId: number;

View file

@ -1,10 +1,13 @@
import React, { FC, useCallback, useState } from 'react'; import React, { FC, useCallback, useState } from 'react';
import { IUser } from '~/types/auth';
import { Avatar } from '~/components/common/Avatar';
import { path } from 'ramda'; import { path } from 'ramda';
import { Manager, Popper, Reference } from 'react-popper'; import { Manager, Popper, Reference } from 'react-popper';
import styles from './styles.module.scss';
import { Avatar } from '~/components/common/Avatar';
import { useRandomPhrase } from '~/constants/phrases'; import { useRandomPhrase } from '~/constants/phrases';
import { IUser } from '~/types/auth';
import styles from './styles.module.scss';
interface Props { interface Props {
user: IUser; user: IUser;

View file

@ -1,18 +1,25 @@
import React, { createElement, FC, Fragment, memo, useCallback, useMemo, useState } from 'react'; import React, { createElement, FC, Fragment, memo, useCallback, useMemo, useState } from 'react';
import { IComment, IFile } from '~/types';
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 { UploadType } from '~/constants/uploads';
import reduce from 'ramda/es/reduce';
import { AudioPlayer } from '~/components/media/AudioPlayer';
import classnames from 'classnames'; import classnames from 'classnames';
import classNames from 'classnames'; import classNames from 'classnames';
import { PRESETS } from '~/constants/urls'; import { append, assocPath, path } from 'ramda';
import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment'; import reduce from 'ramda/es/reduce';
import { CommentMenu } from '../CommentMenu';
import { CommentForm } from '~/components/comment/CommentForm'; import { CommentForm } from '~/components/comment/CommentForm';
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 { PRESETS } from '~/constants/urls';
import { IComment, IFile } from '~/types';
import { formatCommentText, getPrettyDate, getURL } from '~/utils/dom';
import { CommentMenu } from '../CommentMenu';
import styles from './styles.module.scss';
interface IProps { interface IProps {
nodeId: number; nodeId: number;

View file

@ -1,9 +1,12 @@
import React, { FC, memo, useMemo } from 'react'; import React, { FC, memo, useMemo } from 'react';
import { ICommentBlockProps } from '~/constants/comment';
import styles from './styles.module.scss';
import { getYoutubeThumb } from '~/utils/dom';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { ICommentBlockProps } from '~/constants/comment';
import { useYoutubeMetadata } from '~/hooks/metadata/useYoutubeMetadata'; import { useYoutubeMetadata } from '~/hooks/metadata/useYoutubeMetadata';
import { getYoutubeThumb } from '~/utils/dom';
import styles from './styles.module.scss';
type Props = ICommentBlockProps & {}; type Props = ICommentBlockProps & {};

View file

@ -1,24 +1,27 @@
import React, { FC, useCallback, useState } from 'react'; import React, { FC, useCallback, useState } from 'react';
import { useCommentFormFormik } from '~/hooks/comments/useCommentFormFormik';
import { FormikProvider } from 'formik'; import { FormikProvider } from 'formik';
import { LocalCommentFormTextarea } from '~/components/comment/LocalCommentFormTextarea';
import { Button } from '~/components/input/Button';
import { UploadSubject, UploadTarget } from '~/constants/uploads';
import { CommentFormAttachButtons } from '~/components/comment/CommentFormAttachButtons';
import { CommentFormFormatButtons } from '~/components/comment/CommentFormFormatButtons';
import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import { IComment, INode } from '~/types';
import { EMPTY_COMMENT } from '~/constants/node';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
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'; import { observer } from 'mobx-react-lite';
import { CommentFormAttachButtons } from '~/components/comment/CommentFormAttachButtons';
import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
import { CommentFormFormatButtons } from '~/components/comment/CommentFormFormatButtons';
import { LocalCommentFormTextarea } from '~/components/comment/LocalCommentFormTextarea';
import { Filler } from '~/components/containers/Filler';
import { Button } from '~/components/input/Button';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { ERROR_LITERAL } from '~/constants/errors';
import { EMPTY_COMMENT } from '~/constants/node';
import { UploadSubject, UploadTarget } from '~/constants/uploads';
import { useCommentFormFormik } from '~/hooks/comments/useCommentFormFormik';
import { useUploader } from '~/hooks/data/useUploader';
import { useInputPasteUpload } from '~/hooks/dom/useInputPasteUpload';
import { IComment, INode } from '~/types';
import { UploaderContextProvider } from '~/utils/context/UploaderContextProvider';
import styles from './styles.module.scss';
interface IProps { interface IProps {
comment?: IComment; comment?: IComment;
nodeId: INode['id']; nodeId: INode['id'];

View file

@ -1,6 +1,7 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import { ButtonGroup } from '~/components/input/ButtonGroup';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import { ButtonGroup } from '~/components/input/ButtonGroup';
import { COMMENT_FILE_TYPES } from '~/constants/uploads'; import { COMMENT_FILE_TYPES } from '~/constants/uploads';
interface IProps { interface IProps {

View file

@ -1,13 +1,16 @@
import React, { FC, useCallback } 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';
import { IFile } from '~/types';
import { SortEnd } from 'react-sortable-hoc'; import { SortEnd } from 'react-sortable-hoc';
import { moveArrItem } from '~/utils/fn';
import { useFileDropZone } from '~/hooks'; import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
import { COMMENT_FILE_TYPES } from '~/constants/uploads'; import { COMMENT_FILE_TYPES } from '~/constants/uploads';
import { useFileDropZone } from '~/hooks';
import { IFile } from '~/types';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider'; import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { moveArrItem } from '~/utils/fn';
import styles from './styles.module.scss';
const CommentFormAttaches: FC = () => { const CommentFormAttaches: FC = () => {
const { const {

View file

@ -1,7 +1,9 @@
import React, { FC, useCallback, useEffect } from 'react'; import React, { FC, useCallback, useEffect } from 'react';
import { ButtonGroup } from '~/components/input/ButtonGroup';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import { ButtonGroup } from '~/components/input/ButtonGroup';
import { useFormatWrapper, wrapTextInsideInput } from '~/hooks/dom/useFormatWrapper'; import { useFormatWrapper, wrapTextInsideInput } from '~/hooks/dom/useFormatWrapper';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps { interface IProps {

View file

@ -1,4 +1,5 @@
import React, { FC, useCallback, useState } from 'react'; import React, { FC, useCallback, useState } from 'react';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps { interface IProps {

View file

@ -1,10 +1,13 @@
import React, { FC, useMemo } from 'react'; import React, { FC, useMemo } from 'react';
import { ICommentBlockProps } from '~/constants/comment';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import { ICommentBlockProps } from '~/constants/comment';
import markdown from '~/styles/common/markdown.module.scss'; import markdown from '~/styles/common/markdown.module.scss';
import { formatText } from '~/utils/dom'; import { formatText } from '~/utils/dom';
import styles from './styles.module.scss';
interface IProps extends ICommentBlockProps {} interface IProps extends ICommentBlockProps {}
const CommentTextBlock: FC<IProps> = ({ block }) => { const CommentTextBlock: FC<IProps> = ({ block }) => {

View file

@ -1,12 +1,8 @@
import React, { import React, { forwardRef, KeyboardEventHandler, TextareaHTMLAttributes, useCallback } from 'react';
forwardRef,
KeyboardEventHandler,
TextareaHTMLAttributes,
useCallback,
} from 'react';
import { Textarea } from '~/components/input/Textarea'; import { Textarea } from '~/components/input/Textarea';
import { useCommentFormContext } from '~/hooks/comments/useCommentFormFormik';
import { useRandomPhrase } from '~/constants/phrases'; import { useRandomPhrase } from '~/constants/phrases';
import { useCommentFormContext } from '~/hooks/comments/useCommentFormFormik';
interface IProps extends TextareaHTMLAttributes<HTMLTextAreaElement> { interface IProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
isLoading?: boolean; isLoading?: boolean;

View file

@ -1,15 +1,17 @@
import React, { VFC } from 'react'; import React, { VFC } from 'react';
import { LinkProps } from '~/utils/types';
import { CONFIG } from '~/utils/config';
import NextLink from 'next/link'; import NextLink from 'next/link';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { CONFIG } from '~/utils/config';
import { LinkProps } from '~/utils/types';
interface AnchorProps extends LinkProps {} interface AnchorProps extends LinkProps {}
const Anchor: VFC<AnchorProps> = ({ ref, href, ...rest }) => const Anchor: VFC<AnchorProps> = ({ ref, href, children, ...rest }) =>
CONFIG.isNextEnvironment ? ( CONFIG.isNextEnvironment ? (
<NextLink href={href ?? ''} passHref> <NextLink href={href ?? ''} passHref>
<a {...rest} /> <a {...rest}>{children}</a>
</NextLink> </NextLink>
) : ( ) : (
<Link {...rest} to={href ?? ''} /> <Link {...rest} to={href ?? ''} />

View file

@ -1,11 +1,16 @@
import React, { FC, forwardRef, useCallback } from 'react'; import React, { forwardRef, useCallback } from 'react';
import { getURLFromString } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import { openUserProfile } from '~/utils/user';
import { DivProps } from '~/utils/types';
import { Square } from '~/components/common/Square'; import { Square } from '~/components/common/Square';
import { PRESETS } from '~/constants/urls';
import { getURLFromString } from '~/utils/dom';
import { DivProps } from '~/utils/types';
import { openUserProfile } from '~/utils/user';
import styles from './styles.module.scss';
interface Props extends DivProps { interface Props extends DivProps {
url?: string; url?: string;

View file

@ -0,0 +1,20 @@
import React, { useEffect, useRef, VFC } from 'react';
interface ImgProps
extends React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> {
onLoad?: () => void;
}
/** fixes the situation when img not fires onLoad at SSR */
const ImageWithSSRLoad: VFC<ImgProps> = ({ onLoad, ...rest }) => {
const ref = useRef<HTMLImageElement>(null);
useEffect(() => {
if (!ref.current?.complete || !onLoad) return;
onLoad();
}, [ref, onLoad]);
return <img {...rest} onLoad={onLoad} alt={rest.alt} ref={ref} />;
};
export { ImageWithSSRLoad };

View file

@ -0,0 +1,22 @@
import React, { Fragment, VFC } from 'react';
import { useSSRLoadingIndicator } from '~/hooks/dom/useSSRLoadingIndicator';
import styles from './styles.module.scss';
interface LoadingProgressProps {}
const LoadingProgress: VFC<LoadingProgressProps> = () => {
const shown = useSSRLoadingIndicator(300);
return shown ? (
<>
<div className={styles.loader} />
<div className={styles.label}>Секундочку...</div>
</>
) : (
<Fragment />
);
};
export { LoadingProgress };

View file

@ -0,0 +1,38 @@
@import "src/styles/variables";
@keyframes spin {
0% {
background-position: 0 0;
}
100% {
background-position: 100vw 0;
}
}
.loader {
display: flex;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
z-index: 100;
align-items: center;
justify-content: center;
background: linear-gradient(90deg, $dark_blue, $soft_blue, $dark_blue);
animation: spin infinite 1s linear;
}
.label {
position: fixed;
top: $gap + 4px;
left: 50%;
font: $font_12_semibold;
background: red;
z-index: 100;
transform: translate(-50%, 0);
padding: 2px 10px;
border-radius: 10px;
background: $cyan_gradient;
}

View file

@ -1,8 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames';
import styles from '~/components/flow/FlowCell/styles.module.scss'; import styles from '~/components/flow/FlowCell/styles.module.scss';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { ButtonProps } from '~/utils/types'; import { ButtonProps } from '~/utils/types';
import classNames from 'classnames';
interface Props extends ButtonProps {} interface Props extends ButtonProps {}

View file

@ -0,0 +1,15 @@
import React, { VFC } from 'react';
import Head from 'next/head';
interface PageTitleProps {
title: string;
}
const PageTitle: VFC<PageTitleProps> = ({ title }) => (
<Head>
<title>{title}</title>
</Head>
);
export { PageTitle };

View file

@ -1,9 +1,12 @@
import React, { VFC } from 'react'; import React, { VFC } from 'react';
import styles from './styles.module.scss';
import { useScrollTop } from '~/hooks/dom/useScrollTop';
import { useScrollHeight } from '~/hooks/dom/useScrollHeight';
import classNames from 'classnames'; import classNames from 'classnames';
import { useScrollHeight } from '~/hooks/dom/useScrollHeight';
import { useScrollToBottom } from '~/hooks/dom/useScrollToBottom'; import { useScrollToBottom } from '~/hooks/dom/useScrollToBottom';
import { useScrollTop } from '~/hooks/dom/useScrollTop';
import styles from './styles.module.scss';
interface ScrollHelperBottomProps {} interface ScrollHelperBottomProps {}

View file

@ -1,8 +1,11 @@
import React, { forwardRef } from 'react'; import React, { forwardRef } from 'react';
import styles from './styles.module.scss';
import { DivProps } from '~/utils/types';
import classNames from 'classnames'; import classNames from 'classnames';
import { DivProps } from '~/utils/types';
import styles from './styles.module.scss';
interface SquareProps extends DivProps { interface SquareProps extends DivProps {
image?: string; image?: string;
size?: number; size?: number;

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { Placeholder } from '~/components/placeholders/Placeholder'; import { Placeholder } from '~/components/placeholders/Placeholder';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
const StatsRow: FC<{ isLoading: boolean; label: string }> = ({ isLoading, label, children }) => ( const StatsRow: FC<{ isLoading: boolean; label: string }> = ({ isLoading, label, children }) => (

View file

@ -1,7 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames';
import { Placeholder } from '~/components/placeholders/Placeholder'; import { Placeholder } from '~/components/placeholders/Placeholder';
import { DivProps } from '~/utils/types'; import { DivProps } from '~/utils/types';
import classNames from 'classnames';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface Props extends DivProps { interface Props extends DivProps {

View file

@ -1,4 +1,5 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { useAuth } from '~/hooks/auth/useAuth'; import { useAuth } from '~/hooks/auth/useAuth';
interface IProps {} interface IProps {}

View file

@ -1,7 +1,9 @@
import React, { AllHTMLAttributes, FC } from 'react'; import React, { AllHTMLAttributes, FC } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean }; type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean };
export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => ( export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => (

View file

@ -1,8 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
type IProps = React.HTMLAttributes<HTMLDivElement> & { type IProps = React.HTMLAttributes<HTMLDivElement> & {
seamless?: boolean; seamless?: boolean;
}; };

View file

@ -1,8 +1,10 @@
import React, { FC, HTMLAttributes } from 'react'; import React, { FC, HTMLAttributes } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
children: any; children: any;
size: number; size: number;

View file

@ -1,11 +1,13 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { path } from 'ramda';
import { CommentAvatar } from '~/components/comment/CommentAvatar';
import { IUser } from '~/types/auth';
import { DivProps } from '~/utils/types';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
import { IUser } from '~/types/auth';
import { path } from 'ramda';
import { CommentAvatar } from '~/components/comment/CommentAvatar';
import { DivProps } from '~/utils/types';
type IProps = DivProps & { type IProps = DivProps & {
user: IUser; user: IUser;

View file

@ -1,10 +1,13 @@
import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import React, { FC, useCallback, useEffect, useRef, useState } from 'react';
import { IUser } from '~/types/auth';
import styles from './styles.module.scss';
import { getURL } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import classNames from 'classnames'; import classNames from 'classnames';
import { PRESETS } from '~/constants/urls';
import { IUser } from '~/types/auth';
import { getURL } from '~/utils/dom';
import styles from './styles.module.scss';
interface IProps { interface IProps {
cover: IUser['cover']; cover: IUser['cover'];
} }
@ -33,6 +36,9 @@ const CoverBackdrop: FC<IProps> = ({ cover }) => {
className={classNames(styles.cover, { [styles.active]: is_loaded })} className={classNames(styles.cover, { [styles.active]: is_loaded })}
style={{ backgroundImage: `url("${image}")` }} style={{ backgroundImage: `url("${image}")` }}
> >
{
// TODO: use ImageWithSSRLoad here if you will face any bugs
}
<img onLoad={onLoad} ref={ref} alt="" /> <img onLoad={onLoad} ref={ref} alt="" />
</div> </div>
); );

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = React.HTMLAttributes<HTMLDivElement>; type IProps = React.HTMLAttributes<HTMLDivElement>;

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = React.HTMLAttributes<HTMLDivElement> & { type IProps = React.HTMLAttributes<HTMLDivElement> & {
@ -32,20 +34,18 @@ const Grid: FC<IProps> = ({
[styles.horizontal]: horizontal, [styles.horizontal]: horizontal,
[styles.vertical]: !horizontal, [styles.vertical]: !horizontal,
[styles.square]: square, [styles.square]: square,
[styles.stretchy]: stretchy [styles.stretchy]: stretchy,
})} })}
style={{ style={{
...style, ...style,
gridTemplateColumns: square gridTemplateColumns: square
? `repeat(auto-fill, ${(columns !== 'auto' && columns) || size})` ? `repeat(auto-fill, ${(columns !== 'auto' && columns) || size})`
: columns, : columns,
gridTemplateRows: square gridTemplateRows: square ? `repeat(auto-fill, ${(rows !== 'auto' && rows) || size})` : rows,
? `repeat(auto-fill, ${(rows !== 'auto' && rows) || size})`
: rows,
gridAutoRows: rows, gridAutoRows: rows,
gridAutoColumns: columns, gridAutoColumns: columns,
gridRowGap: gap, gridRowGap: gap,
gridColumnGap: gap gridColumnGap: gap,
}} }}
{...props} {...props}
> >

View file

@ -1,5 +1,7 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = React.HTMLAttributes<HTMLDivElement> & { type IProps = React.HTMLAttributes<HTMLDivElement> & {
@ -31,7 +33,7 @@ const Group: FC<IProps> = ({
[styles.wrap]: wrap, [styles.wrap]: wrap,
[styles.seamless]: seamless, [styles.seamless]: seamless,
}, },
className, className
)} )}
{...props} {...props}
> >

View file

@ -1,4 +1,5 @@
import React, { FC, HTMLAttributes, useCallback, useEffect, useRef } from 'react'; import React, { FC, HTMLAttributes, useCallback, useEffect, useRef } from 'react';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps extends HTMLAttributes<HTMLDivElement> { interface IProps extends HTMLAttributes<HTMLDivElement> {

View file

@ -1,7 +1,9 @@
import React, { DetailedHTMLProps, FC, HTMLAttributes } from 'react'; import React, { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
import styles from '~/styles/common/markdown.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from '~/styles/common/markdown.module.scss';
interface IProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {} interface IProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {}
const Markdown: FC<IProps> = ({ className, ...props }) => ( const Markdown: FC<IProps> = ({ className, ...props }) => (

View file

@ -1,8 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
type IProps = React.HTMLAttributes<HTMLDivElement> & { type IProps = React.HTMLAttributes<HTMLDivElement> & {
padding?: number; padding?: number;
vertical?: boolean; vertical?: boolean;

View file

@ -1,9 +1,12 @@
import React, { createContext, FC, useContext, useState } from 'react'; import React, { createContext, FC, useContext, useState } from 'react';
import styles from './styles.module.scss';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { getURL } from '~/utils/dom';
import { PRESETS } from '~/constants/urls'; import { PRESETS } from '~/constants/urls';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom';
import styles from './styles.module.scss';
interface CoverContextValue { interface CoverContextValue {
cover: IFile | null; cover: IFile | null;

View file

@ -1,6 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { IFile } from '~/types';
import { usePageCoverContext } from '~/components/containers/PageCoverProvider/index'; import { usePageCoverContext } from '~/components/containers/PageCoverProvider/index';
import { IFile } from '~/types';
export const usePageCover = (cover?: IFile) => { export const usePageCover = (cover?: IFile) => {
const { setCover } = usePageCoverContext(); const { setCover } = usePageCoverContext();

View file

@ -1,20 +1,16 @@
import React, { FC, HTMLAttributes } from 'react'; import React, { FC, HTMLAttributes } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
seamless?: boolean; seamless?: boolean;
stretchy?: boolean; stretchy?: boolean;
} };
const Panel: FC<IProps> = ({ const Panel: FC<IProps> = ({ className, children, seamless, stretchy, ...props }) => (
className,
children,
seamless,
stretchy,
...props
}) => (
<div className={classNames(styles.panel, className, { seamless, stretchy })} {...props}> <div className={classNames(styles.panel, className, { seamless, stretchy })} {...props}>
{children} {children}
</div> </div>

View file

@ -1,4 +1,5 @@
import React, { DetailsHTMLAttributes, FC } from 'react'; import React, { DetailsHTMLAttributes, FC } from 'react';
import StickyBox from 'react-sticky-box'; import StickyBox from 'react-sticky-box';
interface IProps extends DetailsHTMLAttributes<HTMLDivElement> { interface IProps extends DetailsHTMLAttributes<HTMLDivElement> {

View file

@ -1,4 +1,5 @@
import React, { FC, HTMLAttributes } from 'react'; import React, { FC, HTMLAttributes } from 'react';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = HTMLAttributes<HTMLDivElement> & {}; type IProps = HTMLAttributes<HTMLDivElement> & {};

View file

@ -1,9 +1,12 @@
import React, { FC, MouseEventHandler, useEffect, useRef } from 'react'; import React, { FC, MouseEventHandler, useEffect, useRef } from 'react';
import styles from './styles.module.scss';
import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock'; import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock';
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 styles from './styles.module.scss';
interface IProps { interface IProps {
children: React.ReactChild; children: React.ReactChild;
header?: JSX.Element; header?: JSX.Element;

View file

@ -1,4 +1,5 @@
import React, { FC, ReactNode } from 'react'; import React, { FC, ReactNode } from 'react';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps { interface IProps {

View file

@ -1,5 +1,7 @@
import React, { FC, MouseEventHandler } from 'react'; import React, { FC, MouseEventHandler } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = { type IProps = {

View file

@ -1,7 +1,9 @@
import React, { createContext, FC, useContext, useMemo, useState, VFC } from 'react'; import React, { createContext, FC, useContext, useMemo, useState, VFC } from 'react';
import styles from './styles.module.scss';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './styles.module.scss';
interface TabProps { interface TabProps {
items: string[]; items: string[];
} }

View file

@ -1,15 +1,20 @@
import React, { FC, useCallback, useMemo } from 'react'; import React, { FC, useCallback, useMemo } from 'react';
import { values } from 'ramda';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { UploadType } from '~/constants/uploads'; import { UploadType } from '~/constants/uploads';
import { ImageGrid } from '../ImageGrid';
import { AudioGrid } from '../AudioGrid';
import styles from './styles.module.scss';
import { NodeEditorProps } from '~/types/node';
import { useNodeImages } from '~/hooks/node/useNodeImages';
import { useNodeAudios } from '~/hooks/node/useNodeAudios'; import { useNodeAudios } from '~/hooks/node/useNodeAudios';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { UploadDropzone } from '~/components/upload/UploadDropzone'; import { useNodeImages } from '~/hooks/node/useNodeImages';
import { NodeEditorProps } from '~/types/node';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider'; import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { values } from 'ramda';
import { AudioGrid } from '../AudioGrid';
import { ImageGrid } from '../ImageGrid';
import styles from './styles.module.scss';
type IProps = NodeEditorProps; type IProps = NodeEditorProps;

View file

@ -1,12 +1,15 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import { SortEnd } from 'react-sortable-hoc'; import { SortEnd } from 'react-sortable-hoc';
import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
import { useWindowSize } from '~/hooks/dom/useWindowSize';
import { UploadStatus } from '~/store/uploader/UploaderStore';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { moveArrItem } from '~/utils/fn'; import { moveArrItem } from '~/utils/fn';
import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
import { UploadStatus } from '~/store/uploader/UploaderStore';
import { useWindowSize } from '~/hooks/dom/useWindowSize';
interface IProps { interface IProps {
files: IFile[]; files: IFile[];

View file

@ -1,9 +1,12 @@
import React, { createElement, FC } from 'react'; import React, { createElement, FC } from 'react';
import styles from './styles.module.scss';
import { NODE_PANEL_COMPONENTS } from '~/constants/node';
import { has } from 'ramda'; import { has } from 'ramda';
import { NODE_PANEL_COMPONENTS } from '~/constants/node';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import styles from './styles.module.scss';
const EditorActionsPanel: FC = () => { const EditorActionsPanel: FC = () => {
const { values } = useNodeFormContext(); const { values } = useNodeFormContext();

View file

@ -1,4 +1,5 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { EditorUploadButton } from '~/components/editors/EditorUploadButton'; import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
import { UploadType } from '~/constants/uploads'; import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node'; import { IEditorComponentProps } from '~/types/node';

View file

@ -1,11 +1,12 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { EditorActionsPanel } from '~/components/editors/EditorActionsPanel';
import { Group } from '~/components/containers/Group';
import { InputText } from '~/components/input/InputText';
import { Button } from '~/components/input/Button';
import { Padder } from '~/components/containers/Padder';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { Filler } from '~/components/containers/Filler'; import { Filler } from '~/components/containers/Filler';
import { Group } from '~/components/containers/Group';
import { Padder } from '~/components/containers/Padder';
import { EditorActionsPanel } from '~/components/editors/EditorActionsPanel';
import { Button } from '~/components/input/Button';
import { InputText } from '~/components/input/InputText';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
const EditorButtons: FC = () => { const EditorButtons: FC = () => {
const { values, handleChange, isSubmitting } = useNodeFormContext(); const { values, handleChange, isSubmitting } = useNodeFormContext();

View file

@ -1,8 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from './styles.module.scss';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import styles from './styles.module.scss';
interface IProps { interface IProps {
onApprove: () => void; onApprove: () => void;
onDecline: () => void; onDecline: () => void;

View file

@ -1,6 +1,8 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { Filler } from '~/components/containers/Filler'; import { Filler } from '~/components/containers/Filler';
import { IEditorComponentProps } from '~/types/node'; import { IEditorComponentProps } from '~/types/node';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = IEditorComponentProps & {}; type IProps = IEditorComponentProps & {};

View file

@ -1,4 +1,5 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { EditorUploadButton } from '~/components/editors/EditorUploadButton'; import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
import { UploadType } from '~/constants/uploads'; import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node'; import { IEditorComponentProps } from '~/types/node';

View file

@ -1,9 +1,11 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import { IEditorComponentProps } from '~/types/node';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { IEditorComponentProps } from '~/types/node';
import styles from './styles.module.scss';
interface IProps extends IEditorComponentProps {} interface IProps extends IEditorComponentProps {}

View file

@ -1,12 +1,14 @@
import React, { ChangeEvent, FC, useCallback } from 'react'; import React, { ChangeEvent, FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { UploadType } from '~/constants/uploads'; import { UploadType } from '~/constants/uploads';
import { IEditorComponentProps } from '~/types/node';
import { getFileType } from '~/utils/uploader';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { Button } from '~/components/input/Button'; import { IEditorComponentProps } from '~/types/node';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider'; import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { getFileType } from '~/utils/uploader';
import styles from './styles.module.scss';
type IProps = IEditorComponentProps & { type IProps = IEditorComponentProps & {
accept?: string; accept?: string;

View file

@ -1,13 +1,15 @@
import React, { ChangeEvent, FC, useCallback, useEffect } from 'react'; import React, { ChangeEvent, FC, useCallback, useEffect } from 'react';
import styles from './styles.module.scss';
import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
import { getURL } from '~/utils/dom';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
import { PRESETS } from '~/constants/urls'; import { PRESETS } from '~/constants/urls';
import { IEditorComponentProps } from '~/types/node';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { getFileType } from '~/utils/uploader';
import { useUploader } from '~/hooks/data/useUploader'; import { useUploader } from '~/hooks/data/useUploader';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { IEditorComponentProps } from '~/types/node';
import { getURL } from '~/utils/dom';
import { getFileType } from '~/utils/uploader';
import styles from './styles.module.scss';
type IProps = IEditorComponentProps & {}; type IProps = IEditorComponentProps & {};

View file

@ -1,11 +1,14 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { ImageGrid } from '~/components/editors/ImageGrid';
import styles from './styles.module.scss';
import { NodeEditorProps } from '~/types/node';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import { values } from 'ramda'; import { values } from 'ramda';
import { ImageGrid } from '~/components/editors/ImageGrid';
import { UploadDropzone } from '~/components/upload/UploadDropzone';
import { NodeEditorProps } from '~/types/node';
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
import styles from './styles.module.scss';
type IProps = NodeEditorProps; type IProps = NodeEditorProps;
const ImageEditor: FC<IProps> = () => { const ImageEditor: FC<IProps> = () => {

View file

@ -1,11 +1,14 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import { SortEnd } from 'react-sortable-hoc'; import { SortEnd } from 'react-sortable-hoc';
import styles from './styles.module.scss';
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
import { useWindowSize } from '~/hooks/dom/useWindowSize';
import { UploadStatus } from '~/store/uploader/UploaderStore';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { moveArrItem } from '~/utils/fn'; import { moveArrItem } from '~/utils/fn';
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
import { UploadStatus } from '~/store/uploader/UploaderStore'; import styles from './styles.module.scss';
import { useWindowSize } from '~/hooks/dom/useWindowSize';
interface IProps { interface IProps {
files: IFile[]; files: IFile[];

View file

@ -1,11 +1,14 @@
import React from 'react'; import React from 'react';
import { SortableContainer } from 'react-sortable-hoc'; import { SortableContainer } from 'react-sortable-hoc';
import { AudioUpload } from '~/components/upload/AudioUpload';
import styles from './styles.module.scss';
import { SortableAudioGridItem } from '~/components/editors/SortableAudioGridItem'; import { SortableAudioGridItem } from '~/components/editors/SortableAudioGridItem';
import { IFile } from '~/types';
import { AudioPlayer } from '~/components/media/AudioPlayer'; import { AudioPlayer } from '~/components/media/AudioPlayer';
import { AudioUpload } from '~/components/upload/AudioUpload';
import { UploadStatus } from '~/store/uploader/UploaderStore'; import { UploadStatus } from '~/store/uploader/UploaderStore';
import { IFile } from '~/types';
import styles from './styles.module.scss';
const SortableAudioGrid = SortableContainer( const SortableAudioGrid = SortableContainer(
({ ({

View file

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { SortableElement } from 'react-sortable-hoc'; import { SortableElement } from 'react-sortable-hoc';
import styles from './styles.module.scss'; import styles from './styles.module.scss';

View file

@ -1,13 +1,16 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import classNames from 'classnames';
import { SortableContainer } from 'react-sortable-hoc'; import { SortableContainer } from 'react-sortable-hoc';
import { ImageUpload } from '~/components/upload/ImageUpload';
import styles from './styles.module.scss';
import { SortableImageGridItem } from '~/components/editors/SortableImageGridItem'; import { SortableImageGridItem } from '~/components/editors/SortableImageGridItem';
import { ImageUpload } from '~/components/upload/ImageUpload';
import { PRESETS } from '~/constants/urls';
import { UploadStatus } from '~/store/uploader/UploaderStore';
import { IFile } from '~/types'; import { IFile } from '~/types';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import classNames from 'classnames'; import styles from './styles.module.scss';
import { UploadStatus } from '~/store/uploader/UploaderStore';
const SortableImageGrid = SortableContainer( const SortableImageGrid = SortableContainer(
({ ({

View file

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { SortableElement } from 'react-sortable-hoc'; import { SortableElement } from 'react-sortable-hoc';
import styles from './styles.module.scss'; import styles from './styles.module.scss';

View file

@ -1,10 +1,13 @@
import React, { FC, useCallback } from 'react'; import React, { FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { Textarea } from '~/components/input/Textarea';
import { path } from 'ramda'; import { path } from 'ramda';
import { NodeEditorProps } from '~/types/node';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { Textarea } from '~/components/input/Textarea';
import { useRandomPhrase } from '~/constants/phrases'; import { useRandomPhrase } from '~/constants/phrases';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { NodeEditorProps } from '~/types/node';
import styles from './styles.module.scss';
type IProps = NodeEditorProps & {}; type IProps = NodeEditorProps & {};

View file

@ -1,11 +1,14 @@
import React, { FC, useCallback, useMemo } from 'react'; import React, { FC, useCallback, useMemo } from 'react';
import styles from './styles.module.scss';
import { path } from 'ramda';
import { InputText } from '~/components/input/InputText';
import classnames from 'classnames'; import classnames from 'classnames';
import { getYoutubeThumb } from '~/utils/dom'; import { path } from 'ramda';
import { NodeEditorProps } from '~/types/node';
import { InputText } from '~/components/input/InputText';
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik'; import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
import { NodeEditorProps } from '~/types/node';
import { getYoutubeThumb } from '~/utils/dom';
import styles from './styles.module.scss';
type IProps = NodeEditorProps & {}; type IProps = NodeEditorProps & {};

View file

@ -1,10 +1,13 @@
import React, { FC, useMemo } from 'react'; import React, { FC, useMemo } from 'react';
import styles from './styles.module.scss';
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
import { DivProps } from '~/utils/types';
import classNames from 'classnames'; import classNames from 'classnames';
import { transparentize } from 'color2k'; import { transparentize } from 'color2k';
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
import { normalizeBrightColor } from '~/utils/color'; import { normalizeBrightColor } from '~/utils/color';
import { DivProps } from '~/utils/types';
import styles from './styles.module.scss';
interface Props extends DivProps { interface Props extends DivProps {
color?: string; color?: string;

View file

@ -1,16 +1,18 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import styles from './styles.module.scss';
import { NavLink } from 'react-router-dom';
import { CellShade } from '~/components/flow/CellShade';
import { FlowDisplay, INode } from '~/types';
import { FlowCellText } from '~/components/flow/FlowCellText';
import classNames from 'classnames'; import classNames from 'classnames';
import { FlowCellMenu } from '~/components/flow/FlowCellMenu';
import { useFlowCellControls } from '~/hooks/flow/useFlowCellControls';
import { useClickOutsideFocus } from '~/hooks/dom/useClickOutsideFocus';
import { MenuDots } from '~/components/common/MenuDots';
import { FlowCellImage } from '~/components/flow/FlowCellImage';
import { Anchor } from '~/components/common/Anchor'; 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 { useClickOutsideFocus } from '~/hooks/dom/useClickOutsideFocus';
import { useFlowCellControls } from '~/hooks/flow/useFlowCellControls';
import { FlowDisplay, INode } from '~/types';
import styles from './styles.module.scss';
interface Props { interface Props {
id: INode['id']; id: INode['id'];

Some files were not shown because too many files have changed in this diff Show more