mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
commit
437bee5905
354 changed files with 2083 additions and 998 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
**/node_modules
|
||||
node_modules
|
83
.drone.yml
83
.drone.yml
|
@ -7,44 +7,60 @@ platform:
|
|||
arch: amd64
|
||||
|
||||
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
|
||||
image: plugins/docker
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
environment:
|
||||
REACT_APP_API_HOST: https://pig.vault48.org/
|
||||
REACT_APP_REMOTE_CURRENT: https://pig.vault48.org/static/
|
||||
settings:
|
||||
dockerfile: docker/www/Dockerfile
|
||||
build_args_from_env:
|
||||
- REACT_APP_API_HOST
|
||||
- REACT_APP_REMOTE_CURRENT
|
||||
tag:
|
||||
- ${DRONE_BRANCH}
|
||||
custom_labels:
|
||||
- "commit=${DRONE_COMMIT_SHA}"
|
||||
username:
|
||||
from_secret: global_docker_login
|
||||
password:
|
||||
from_secret: global_docker_password
|
||||
registry:
|
||||
from_secret: global_docker_registry
|
||||
repo:
|
||||
from_secret: docker_repo
|
||||
NEXT_PUBLIC_API_HOST: https://pig.vault48.org/
|
||||
NEXT_PUBLIC_REMOTE_CURRENT: https://pig.vault48.org/static/
|
||||
settings:
|
||||
dockerfile: docker/nextjs/Dockerfile
|
||||
build_args_from_env:
|
||||
- NEXT_PUBLIC_API_HOST
|
||||
- NEXT_PUBLIC_REMOTE_CURRENT
|
||||
tag:
|
||||
- ${DRONE_BRANCH}
|
||||
custom_labels:
|
||||
- "commit=${DRONE_COMMIT_SHA}"
|
||||
username:
|
||||
from_secret: global_docker_login
|
||||
password:
|
||||
from_secret: global_docker_password
|
||||
registry:
|
||||
from_secret: global_docker_registry
|
||||
repo:
|
||||
from_secret: docker_repo
|
||||
- name: build-develop
|
||||
image: plugins/docker
|
||||
when:
|
||||
branch:
|
||||
- develop
|
||||
environment:
|
||||
REACT_APP_API_HOST: https://pig.staging.vault48.org/
|
||||
REACT_APP_REMOTE_CURRENT: https://pig.staging.vault48.org/static/
|
||||
NEXT_PUBLIC_API_HOST: https://pig.staging.vault48.org/
|
||||
NEXT_PUBLIC_REMOTE_CURRENT: https://pig.staging.vault48.org/static/
|
||||
settings:
|
||||
dockerfile: docker/www/Dockerfile
|
||||
dockerfile: docker/nextjs/Dockerfile
|
||||
build_args_from_env:
|
||||
- REACT_APP_API_HOST
|
||||
- REACT_APP_REMOTE_CURRENT
|
||||
- NEXT_PUBLIC_API_HOST
|
||||
- NEXT_PUBLIC_REMOTE_CURRENT
|
||||
tag:
|
||||
- ${DRONE_BRANCH}
|
||||
custom_labels:
|
||||
|
@ -57,3 +73,22 @@ steps:
|
|||
from_secret: global_docker_registry
|
||||
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: {}
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
#REACT_APP_API_HOST=http://localhost:3334/
|
||||
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/
|
||||
|
|
4
.eslintignore
Normal file
4
.eslintignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
build
|
||||
.next
|
||||
.husky
|
||||
node_modules
|
33
.eslintrc.js
Normal file
33
.eslintrc.js
Normal 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',
|
||||
};
|
|
@ -29,6 +29,29 @@ module.exports = {
|
|||
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: {
|
||||
|
|
12
docker/nextjs/Dockerfile
Normal file
12
docker/nextjs/Dockerfile
Normal 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"]
|
|
@ -1,7 +1,8 @@
|
|||
/** used to transpile UMD and CJS modules */
|
||||
const withTM = require('next-transpile-modules')(['ramda']);
|
||||
|
||||
module.exports = withTM({
|
||||
/* Your Next.js config */
|
||||
/** rewrite old-style node paths */
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
|
@ -10,4 +11,7 @@ module.exports = withTM({
|
|||
},
|
||||
];
|
||||
},
|
||||
|
||||
/** don't try to optimize fonts */
|
||||
optimizeFonts: false,
|
||||
});
|
||||
|
|
|
@ -55,7 +55,9 @@
|
|||
"build": "craco build",
|
||||
"ts-check": "tsc -p tsconfig.json --noEmit",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"prepare": "husky install"
|
||||
"prepare": "husky install",
|
||||
"next:build": "next build",
|
||||
"next:start": "next start -p 80"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
@ -76,6 +78,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@craco/craco": "^6.4.3",
|
||||
"@next/eslint-plugin-next": "^12.0.8",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/marked": "^1.2.2",
|
||||
"@types/node": "^11.13.22",
|
||||
|
@ -83,6 +86,7 @@
|
|||
"@types/throttle-debounce": "^2.1.0",
|
||||
"@types/yup": "^0.29.11",
|
||||
"craco-alias": "^2.3.1",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.1.6",
|
||||
"next-transpile-modules": "^9.0.0",
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import {
|
||||
ApiAttachSocialRequest,
|
||||
ApiAttachSocialResult,
|
||||
|
@ -22,6 +20,8 @@ import {
|
|||
ApiUserLoginRequest,
|
||||
ApiUserLoginResult,
|
||||
} from '~/api/auth/types';
|
||||
import { API } from '~/constants/api';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const apiUserLogin = ({ username, password }: ApiUserLoginRequest) =>
|
||||
api
|
||||
|
|
|
@ -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 { API } from '~/constants/api';
|
||||
import { IGetGithubIssuesResult, StatBackend } from '~/types/boris';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const getBorisBackendStats = () =>
|
||||
api.get<StatBackend>(API.BORIS.GET_BACKEND_STATS).then(cleanResult);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import { PostCellViewRequest, PostCellViewResult } from '~/types/node';
|
||||
import { GetSearchResultsRequest, GetSearchResultsResult } from '~/types/flow';
|
||||
import { PostCellViewRequest, PostCellViewResult } from '~/types/node';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const postCellView = ({ id, flow }: PostCellViewRequest) =>
|
||||
api
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import {
|
||||
GetLabNodesRequest,
|
||||
|
@ -6,6 +5,7 @@ import {
|
|||
GetLabStatsResult,
|
||||
GetLabUpdatesResult,
|
||||
} from '~/types/lab';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const getLabNodes = ({ after }: GetLabNodesRequest) =>
|
||||
api
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import {
|
||||
ApiDeleteMessageRequest,
|
||||
ApiDeleteMessageResult,
|
||||
|
@ -8,6 +6,8 @@ import {
|
|||
ApiSendMessageRequest,
|
||||
ApiSendMessageResult,
|
||||
} from '~/api/messages/types';
|
||||
import { API } from '~/constants/api';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const apiGetUserMessages = ({ username, after, before }: ApiGetUserMessagesRequest) =>
|
||||
api
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import { ApiGetEmbedYoutubeResult } from '~/api/metadata/types';
|
||||
import { API } from '~/constants/api';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const apiGetEmbedYoutube = (ids: string[]) =>
|
||||
api
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { IComment, INode } from '~/types';
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
|
||||
import { API } from '~/constants/api';
|
||||
import { COMMENTS_DISPLAY } from '~/constants/node';
|
||||
import { IComment, INode } from '~/types';
|
||||
import {
|
||||
ApiDeleteNodeTagsRequest,
|
||||
ApiDeleteNodeTagsResult,
|
||||
|
@ -24,7 +25,8 @@ import {
|
|||
GetNodeDiffRequest,
|
||||
GetNodeDiffResult,
|
||||
} from '~/types/node';
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
|
||||
export type ApiPostNodeRequest = { node: INode };
|
||||
export type ApiPostNodeResult = {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
import {
|
||||
ApiGetNodesOfTagRequest,
|
||||
|
@ -6,6 +5,7 @@ import {
|
|||
ApiGetTagSuggestionsRequest,
|
||||
ApiGetTagSuggestionsResult,
|
||||
} from '~/types/tags';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const apiGetNodesOfTag = ({ tag, offset, limit }: ApiGetNodesOfTagRequest) =>
|
||||
api
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
import { API } from '~/constants/api';
|
||||
import { ApiUploadFileRequest, ApiUploadFIleResult } from '~/api/uploads/types';
|
||||
import { API } from '~/constants/api';
|
||||
import { UploadTarget, UploadType } from '~/constants/uploads';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
|
||||
export const apiUploadFile = ({
|
||||
file,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IFile, IUploadProgressHandler } from '~/types';
|
||||
import { UploadTarget, UploadType } from '~/constants/uploads';
|
||||
import { IFile, IUploadProgressHandler } from '~/types';
|
||||
|
||||
export type ApiUploadFileRequest = {
|
||||
file: File;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Button } from '~/components/input/Button';
|
||||
|
||||
import { Grid } from '~/components/containers/Grid';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import styles from './styles.module.scss';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { OAuthProvider } from '~/types/auth';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
interface IProps {
|
||||
openOauthWindow: (provider: OAuthProvider) => void;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Button } from '~/components/input/Button';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React, { VFC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { ERROR_LITERAL, ERRORS } from '~/constants/errors';
|
||||
import { Button } from '~/components/input/Button';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface RestoreInvalidCodeProps {
|
||||
error: string;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
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 { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface RestoreSentProps {
|
||||
onClose: () => void;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { VFC } from 'react';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Button } from '~/components/input/Button';
|
||||
|
||||
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 RestoreSuccessProps {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import React, { useCallback, VFC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { path } from 'ramda';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { PlayerState } from '~/constants/player';
|
||||
import { path } from 'ramda';
|
||||
import { IFile } from '~/types';
|
||||
import { PlayerProgress } from '~/types/player';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props {
|
||||
progress: PlayerProgress;
|
||||
status: PlayerState;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
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 { useShowModal } from '~/hooks/modal/useShowModal';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
interface Props {
|
||||
isLab?: boolean;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props {
|
||||
icon: string;
|
||||
title: string;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { BorisContactItem } from '~/components/boris/BorisContactItem';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props {}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
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 { BorisStats } from '~/components/boris/BorisStats';
|
||||
import { BorisSuperpowers } from '~/components/boris/BorisSuperpowers';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import styles from '~/layouts/BorisLayout/styles.module.scss';
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
import { BorisStatsGit } from '../BorisStatsGit';
|
||||
|
||||
import { BorisStatsBackend } from '../BorisStatsBackend';
|
||||
import { BorisStatsGit } from '../BorisStatsGit';
|
||||
|
||||
interface IProps {
|
||||
stats: BorisUsageStats;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
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 { SubTitle } from '~/components/common/SubTitle';
|
||||
import { StatBackend } from '~/types/boris';
|
||||
import { sizeOf } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
stats: StatBackend;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import { GithubIssue } from '~/types/boris';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { GithubIssue } from '~/types/boris';
|
||||
|
||||
import { BorisStatsGitCard } from '../BorisStatsGitCard';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
issues: GithubIssue[];
|
||||
isLoading: boolean;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
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 { GithubIssue } from '~/types/boris';
|
||||
import { getPrettyDate } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
interface IProps {
|
||||
data: GithubIssue;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { Toggle } from '~/components/input/Toggle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
active?: boolean;
|
||||
onChange?: (val: boolean) => void;
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import React, { FC, useState } from 'react';
|
||||
|
||||
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 { Button } from '~/components/input/Button';
|
||||
import { InputText } from '~/components/input/InputText';
|
||||
import { useShowModal } from '~/hooks/modal/useShowModal';
|
||||
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 {}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { useAuth } from '~/hooks/auth/useAuth';
|
||||
|
||||
interface IProps {}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
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 { CommentContent } from '~/components/comment/CommentContent';
|
||||
import { CommentWrapper } from '~/components/containers/CommentWrapper';
|
||||
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> & {
|
||||
nodeId: number;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { IUser } from '~/types/auth';
|
||||
import { Avatar } from '~/components/common/Avatar';
|
||||
|
||||
import { path } from 'ramda';
|
||||
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 { IUser } from '~/types/auth';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props {
|
||||
user: IUser;
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
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 { PRESETS } from '~/constants/urls';
|
||||
import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment';
|
||||
import { CommentMenu } from '../CommentMenu';
|
||||
import { append, assocPath, path } from 'ramda';
|
||||
import reduce from 'ramda/es/reduce';
|
||||
|
||||
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 {
|
||||
nodeId: number;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
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 { ICommentBlockProps } from '~/constants/comment';
|
||||
import { useYoutubeMetadata } from '~/hooks/metadata/useYoutubeMetadata';
|
||||
import { getYoutubeThumb } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type Props = ICommentBlockProps & {};
|
||||
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { useCommentFormFormik } from '~/hooks/comments/useCommentFormFormik';
|
||||
|
||||
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 { 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 {
|
||||
comment?: IComment;
|
||||
nodeId: INode['id'];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { ButtonGroup } from '~/components/input/ButtonGroup';
|
||||
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { ButtonGroup } from '~/components/input/ButtonGroup';
|
||||
import { COMMENT_FILE_TYPES } from '~/constants/uploads';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
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 { 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 { useFileDropZone } from '~/hooks';
|
||||
import { IFile } from '~/types';
|
||||
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
|
||||
import { moveArrItem } from '~/utils/fn';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const CommentFormAttaches: FC = () => {
|
||||
const {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { FC, useCallback, useEffect } from 'react';
|
||||
import { ButtonGroup } from '~/components/input/ButtonGroup';
|
||||
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { ButtonGroup } from '~/components/input/ButtonGroup';
|
||||
import { useFormatWrapper, wrapTextInsideInput } from '~/hooks/dom/useFormatWrapper';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import { ICommentBlockProps } from '~/constants/comment';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { ICommentBlockProps } from '~/constants/comment';
|
||||
import markdown from '~/styles/common/markdown.module.scss';
|
||||
import { formatText } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps extends ICommentBlockProps {}
|
||||
|
||||
const CommentTextBlock: FC<IProps> = ({ block }) => {
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
import React, {
|
||||
forwardRef,
|
||||
KeyboardEventHandler,
|
||||
TextareaHTMLAttributes,
|
||||
useCallback,
|
||||
} from 'react';
|
||||
import React, { forwardRef, KeyboardEventHandler, TextareaHTMLAttributes, useCallback } from 'react';
|
||||
|
||||
import { Textarea } from '~/components/input/Textarea';
|
||||
import { useCommentFormContext } from '~/hooks/comments/useCommentFormFormik';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
import { useCommentFormContext } from '~/hooks/comments/useCommentFormFormik';
|
||||
|
||||
interface IProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
isLoading?: boolean;
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import React, { VFC } from 'react';
|
||||
import { LinkProps } from '~/utils/types';
|
||||
import { CONFIG } from '~/utils/config';
|
||||
|
||||
import NextLink from 'next/link';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { CONFIG } from '~/utils/config';
|
||||
import { LinkProps } from '~/utils/types';
|
||||
|
||||
interface AnchorProps extends LinkProps {}
|
||||
|
||||
const Anchor: VFC<AnchorProps> = ({ ref, href, ...rest }) =>
|
||||
const Anchor: VFC<AnchorProps> = ({ ref, href, children, ...rest }) =>
|
||||
CONFIG.isNextEnvironment ? (
|
||||
<NextLink href={href ?? ''} passHref>
|
||||
<a {...rest} />
|
||||
<a {...rest}>{children}</a>
|
||||
</NextLink>
|
||||
) : (
|
||||
<Link {...rest} to={href ?? ''} />
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import React, { FC, forwardRef, useCallback } from 'react';
|
||||
import { getURLFromString } from '~/utils/dom';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import styles from './styles.module.scss';
|
||||
import React, { forwardRef, useCallback } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { openUserProfile } from '~/utils/user';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
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 {
|
||||
url?: string;
|
||||
|
|
20
src/components/common/ImageWithSSRLoad/index.tsx
Normal file
20
src/components/common/ImageWithSSRLoad/index.tsx
Normal 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 };
|
22
src/components/common/LoadingProgress/index.tsx
Normal file
22
src/components/common/LoadingProgress/index.tsx
Normal 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 };
|
38
src/components/common/LoadingProgress/styles.module.scss
Normal file
38
src/components/common/LoadingProgress/styles.module.scss
Normal 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;
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from '~/components/flow/FlowCell/styles.module.scss';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { ButtonProps } from '~/utils/types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface Props extends ButtonProps {}
|
||||
|
||||
|
|
15
src/components/common/PageTitle/index.tsx
Normal file
15
src/components/common/PageTitle/index.tsx
Normal 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 };
|
|
@ -1,9 +1,12 @@
|
|||
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 { useScrollHeight } from '~/hooks/dom/useScrollHeight';
|
||||
import { useScrollToBottom } from '~/hooks/dom/useScrollToBottom';
|
||||
import { useScrollTop } from '~/hooks/dom/useScrollTop';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface ScrollHelperBottomProps {}
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import React, { forwardRef } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface SquareProps extends DivProps {
|
||||
image?: string;
|
||||
size?: number;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const StatsRow: FC<{ isLoading: boolean; label: string }> = ({ isLoading, label, children }) => (
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { DivProps } from '~/utils/types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props extends DivProps {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { useAuth } from '~/hooks/auth/useAuth';
|
||||
|
||||
interface IProps {}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { AllHTMLAttributes, FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean };
|
||||
|
||||
export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => (
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type IProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
seamless?: boolean;
|
||||
};
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import React, { FC, HTMLAttributes } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type IProps = HTMLAttributes<HTMLDivElement> & {
|
||||
children: any;
|
||||
size: number;
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
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 { IUser } from '~/types/auth';
|
||||
import { path } from 'ramda';
|
||||
import { CommentAvatar } from '~/components/comment/CommentAvatar';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
type IProps = DivProps & {
|
||||
user: IUser;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
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 { PRESETS } from '~/constants/urls';
|
||||
import { IUser } from '~/types/auth';
|
||||
import { getURL } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
cover: IUser['cover'];
|
||||
}
|
||||
|
@ -33,6 +36,9 @@ const CoverBackdrop: FC<IProps> = ({ cover }) => {
|
|||
className={classNames(styles.cover, { [styles.active]: is_loaded })}
|
||||
style={{ backgroundImage: `url("${image}")` }}
|
||||
>
|
||||
{
|
||||
// TODO: use ImageWithSSRLoad here if you will face any bugs
|
||||
}
|
||||
<img onLoad={onLoad} ref={ref} alt="" />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = React.HTMLAttributes<HTMLDivElement>;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
|
@ -32,20 +34,18 @@ const Grid: FC<IProps> = ({
|
|||
[styles.horizontal]: horizontal,
|
||||
[styles.vertical]: !horizontal,
|
||||
[styles.square]: square,
|
||||
[styles.stretchy]: stretchy
|
||||
[styles.stretchy]: stretchy,
|
||||
})}
|
||||
style={{
|
||||
...style,
|
||||
gridTemplateColumns: square
|
||||
? `repeat(auto-fill, ${(columns !== 'auto' && columns) || size})`
|
||||
: columns,
|
||||
gridTemplateRows: square
|
||||
? `repeat(auto-fill, ${(rows !== 'auto' && rows) || size})`
|
||||
: rows,
|
||||
gridTemplateRows: square ? `repeat(auto-fill, ${(rows !== 'auto' && rows) || size})` : rows,
|
||||
gridAutoRows: rows,
|
||||
gridAutoColumns: columns,
|
||||
gridRowGap: gap,
|
||||
gridColumnGap: gap
|
||||
gridColumnGap: gap,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
|
@ -31,7 +33,7 @@ const Group: FC<IProps> = ({
|
|||
[styles.wrap]: wrap,
|
||||
[styles.seamless]: seamless,
|
||||
},
|
||||
className,
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC, HTMLAttributes, useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps extends HTMLAttributes<HTMLDivElement> {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
|
||||
import styles from '~/styles/common/markdown.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from '~/styles/common/markdown.module.scss';
|
||||
|
||||
interface IProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {}
|
||||
|
||||
const Markdown: FC<IProps> = ({ className, ...props }) => (
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type IProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
padding?: number;
|
||||
vertical?: boolean;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import React, { createContext, FC, useContext, useState } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { createPortal } from 'react-dom';
|
||||
import { getURL } from '~/utils/dom';
|
||||
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import { IFile } from '~/types';
|
||||
import { getURL } from '~/utils/dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface CoverContextValue {
|
||||
cover: IFile | null;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect } from 'react';
|
||||
import { IFile } from '~/types';
|
||||
|
||||
import { usePageCoverContext } from '~/components/containers/PageCoverProvider/index';
|
||||
import { IFile } from '~/types';
|
||||
|
||||
export const usePageCover = (cover?: IFile) => {
|
||||
const { setCover } = usePageCoverContext();
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import React, { FC, HTMLAttributes } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type IProps = HTMLAttributes<HTMLDivElement> & {
|
||||
seamless?: boolean;
|
||||
stretchy?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
const Panel: FC<IProps> = ({
|
||||
className,
|
||||
children,
|
||||
seamless,
|
||||
stretchy,
|
||||
...props
|
||||
}) => (
|
||||
const Panel: FC<IProps> = ({ className, children, seamless, stretchy, ...props }) => (
|
||||
<div className={classNames(styles.panel, className, { seamless, stretchy })} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { DetailsHTMLAttributes, FC } from 'react';
|
||||
|
||||
import StickyBox from 'react-sticky-box';
|
||||
|
||||
interface IProps extends DetailsHTMLAttributes<HTMLDivElement> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC, HTMLAttributes } from 'react';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = HTMLAttributes<HTMLDivElement> & {};
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import React, { FC, MouseEventHandler, useEffect, useRef } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock';
|
||||
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
children: React.ReactChild;
|
||||
header?: JSX.Element;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC, ReactNode } from 'react';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC, MouseEventHandler } from 'react';
|
||||
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React, { createContext, FC, useContext, useMemo, useState, VFC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface TabProps {
|
||||
items: string[];
|
||||
}
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import React, { FC, useCallback, useMemo } from 'react';
|
||||
|
||||
import { values } from 'ramda';
|
||||
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
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 { 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 { values } from 'ramda';
|
||||
|
||||
import { AudioGrid } from '../AudioGrid';
|
||||
import { ImageGrid } from '../ImageGrid';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
|
||||
type IProps = NodeEditorProps;
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
|
||||
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 { moveArrItem } from '~/utils/fn';
|
||||
import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
import { UploadStatus } from '~/store/uploader/UploaderStore';
|
||||
import { useWindowSize } from '~/hooks/dom/useWindowSize';
|
||||
|
||||
|
||||
interface IProps {
|
||||
files: IFile[];
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import React, { createElement, FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { NODE_PANEL_COMPONENTS } from '~/constants/node';
|
||||
|
||||
import { has } from 'ramda';
|
||||
|
||||
import { NODE_PANEL_COMPONENTS } from '~/constants/node';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const EditorActionsPanel: FC = () => {
|
||||
const { values } = useNodeFormContext();
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
|
||||
import { UploadType } from '~/constants/uploads';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
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 { 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 { values, handleChange, isSubmitting } = useNodeFormContext();
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import { Button } from '~/components/input/Button';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
onApprove: () => void;
|
||||
onDecline: () => void;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = IEditorComponentProps & {};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
|
||||
import { UploadType } from '~/constants/uploads';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import styles from './styles.module.scss';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps extends IEditorComponentProps {}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
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 { UploadType } from '~/constants/uploads';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import { getFileType } from '~/utils/uploader';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import { useUploaderContext } from '~/utils/context/UploaderContextProvider';
|
||||
import { getFileType } from '~/utils/uploader';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = IEditorComponentProps & {
|
||||
accept?: string;
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
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 { UploadSubject, UploadTarget, UploadType } from '~/constants/uploads';
|
||||
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 { 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 & {};
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
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 { 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;
|
||||
|
||||
const ImageEditor: FC<IProps> = () => {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
|
||||
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 { moveArrItem } from '~/utils/fn';
|
||||
import { SortableImageGrid } from '~/components/editors/SortableImageGrid';
|
||||
import { UploadStatus } from '~/store/uploader/UploaderStore';
|
||||
import { useWindowSize } from '~/hooks/dom/useWindowSize';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface IProps {
|
||||
files: IFile[];
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import React from 'react';
|
||||
|
||||
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 { IFile } from '~/types';
|
||||
import { AudioPlayer } from '~/components/media/AudioPlayer';
|
||||
import { AudioUpload } from '~/components/upload/AudioUpload';
|
||||
import { UploadStatus } from '~/store/uploader/UploaderStore';
|
||||
import { IFile } from '~/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const SortableAudioGrid = SortableContainer(
|
||||
({
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
import { SortableElement } from 'react-sortable-hoc';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import React, { useCallback } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
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 { ImageUpload } from '~/components/upload/ImageUpload';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import { UploadStatus } from '~/store/uploader/UploaderStore';
|
||||
import { IFile } from '~/types';
|
||||
import { getURL } from '~/utils/dom';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import classNames from 'classnames';
|
||||
import { UploadStatus } from '~/store/uploader/UploaderStore';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
const SortableImageGrid = SortableContainer(
|
||||
({
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
import { SortableElement } from 'react-sortable-hoc';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { Textarea } from '~/components/input/Textarea';
|
||||
|
||||
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 { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = NodeEditorProps & {};
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
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 { getYoutubeThumb } from '~/utils/dom';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
import { path } from 'ramda';
|
||||
|
||||
import { InputText } from '~/components/input/InputText';
|
||||
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 & {};
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
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 { transparentize } from 'color2k';
|
||||
|
||||
import { DEFAULT_DOMINANT_COLOR } from '~/constants/node';
|
||||
import { normalizeBrightColor } from '~/utils/color';
|
||||
import { DivProps } from '~/utils/types';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
interface Props extends DivProps {
|
||||
color?: string;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
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 { 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 { 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 {
|
||||
id: INode['id'];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue