mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 12:26:40 +07:00
sing create-react-app now
This commit is contained in:
parent
332d09e3bd
commit
a9c43e8976
41 changed files with 6207 additions and 15613 deletions
11
.babelrc
11
.babelrc
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"presets": ["env", "react","stage-2"],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel",
|
||||
"lodash",
|
||||
["transform-runtime", {
|
||||
"polyfill": false,
|
||||
"regenerator": true
|
||||
}]
|
||||
]
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
90
.eslintrc.js
90
.eslintrc.js
|
@ -1,90 +0,0 @@
|
|||
module.exports = {
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier/@typescript-eslint',
|
||||
'airbnb',
|
||||
'airbnb-base',
|
||||
'prettier',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'react', 'jsx-a11y', 'import', 'react-hooks'],
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: {},
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
// '@typescript-eslint/indent': ['warn', 2],
|
||||
'comma-dangle': 0,
|
||||
'no-restricted-syntax': 1,
|
||||
'react/prop-types': 0,
|
||||
'new-cap': 1,
|
||||
'no-continue': 1,
|
||||
'no-underscore-dangle': 1,
|
||||
'global-require': 1,
|
||||
'react/no-multi-comp': 1,
|
||||
'react/jsx-filename-extension': 0,
|
||||
'react/jsx-wrap-multilines': [
|
||||
'warn',
|
||||
{
|
||||
declaration: 'parens',
|
||||
assignment: 'parens',
|
||||
return: 'parens',
|
||||
arrow: 'parens',
|
||||
condition: 'ignore',
|
||||
logical: 'ignore',
|
||||
prop: 'ignore',
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/camelcase': 0,
|
||||
'@typescript-eslint/interface-name-prefix': 0,
|
||||
camelcase: 0,
|
||||
'import/no-unresolved': 1,
|
||||
'import/prefer-default-export': 1,
|
||||
'import/extensions': 1,
|
||||
'no-return-assign': 1,
|
||||
'max-len': 1,
|
||||
'jsx-a11y/no-static-element-interactions': 0,
|
||||
'jsx-a11y/click-events-have-key-events': 0,
|
||||
'jsx-a11y/interactive-supports-focus': 0,
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
'no-nested-ternary': 1,
|
||||
'import/prefer-default-export': 0,
|
||||
'max-line-length': [true, 100],
|
||||
// 'max-len': 100,
|
||||
// 'max-len': { "code": 100 },
|
||||
'max-len': ['warn', { code: 100 }],
|
||||
'template-curly-spacing': 'off',
|
||||
'comma-dangle': [
|
||||
'warn',
|
||||
{
|
||||
arrays: 'always-multiline',
|
||||
objects: 'always-multiline',
|
||||
imports: 'always-multiline',
|
||||
exports: 'always-multiline',
|
||||
functions: 'never',
|
||||
},
|
||||
],
|
||||
indent: 'off',
|
||||
'import/order': 'off',
|
||||
'arrow-parens': ['warn', 'as-needed'],
|
||||
},
|
||||
globals: {
|
||||
document: false,
|
||||
window: false,
|
||||
HTMLInputElement: false,
|
||||
HTMLDivElement: false,
|
||||
FormData: false,
|
||||
FileReader: false,
|
||||
Audio: false,
|
||||
CustomEvent: false,
|
||||
},
|
||||
};
|
22
.vscode/settings.json
vendored
22
.vscode/settings.json
vendored
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"eslint.enable": true,
|
||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
|
||||
"editor.rulers": [
|
||||
100
|
||||
],
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveTimeout": 750,
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveTimeout": 750,
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveTimeout": 750,
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveTimeout": 750,
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
}
|
49
Jenkinsfile
vendored
49
Jenkinsfile
vendored
|
@ -1,49 +0,0 @@
|
|||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
WWW = "${env.BRANCH_NAME == "master" ? env.VAULT_STABLE_WWW : env.VAULT_STAGING_WWW}"
|
||||
ENV = "${env.BRANCH_NAME == "master" ? env.VAULT_STABLE_ENV : env.VAULT_STAGING_ENV}"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('check') {
|
||||
steps {
|
||||
script {
|
||||
if("${WWW}" == "" || "${ENV}" == "") {
|
||||
currentBuild.result = 'FAILED'
|
||||
error "No valid deploy dirs"
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('copy env') {
|
||||
steps {
|
||||
sh "cp -a ${ENV}/. ${WORKSPACE}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('build') {
|
||||
steps {
|
||||
sh 'yarn'
|
||||
sh "mkdir -p ${WORKSPACE}/src/stats"
|
||||
sh "git log -n 50 --pretty=format:\' { \"commit\": \"%H\", \"subject\": \"%s\", \"timestamp\": \"%at\" }\' | awk \'BEGIN { print(\"[\") } { print(\$0\",\") } END { print(\" {}\\n]\") }\' > ${WORKSPACE}/src/stats/git.json"
|
||||
sh 'yarn build'
|
||||
}
|
||||
}
|
||||
|
||||
stage('deploy') {
|
||||
when {
|
||||
anyOf { branch 'master'; branch 'develop' }
|
||||
}
|
||||
|
||||
steps {
|
||||
sh "rm -rf ${WWW}"
|
||||
sh "mv ${WORKSPACE}/dist ${WWW}"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
46
craco.config.js
Normal file
46
craco.config.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
const CracoAlias = require('craco-alias');
|
||||
|
||||
module.exports = {
|
||||
webpack: {
|
||||
alias: {
|
||||
'~': `src`,
|
||||
},
|
||||
output: {
|
||||
publicPath: '/',
|
||||
},
|
||||
},
|
||||
eslint: {
|
||||
enable: false,
|
||||
mode: 'file',
|
||||
},
|
||||
// jest: {
|
||||
// setupTestFrameworkScriptFile: "<rootDir>/src/setupTests.js",
|
||||
// configure: {
|
||||
// moduleNameMapper: {
|
||||
// "^~/(.*)$": "<rootDir>/src/$1",
|
||||
// "^.+\\.scss$": "identity-obj-proxy"
|
||||
// },
|
||||
// snapshotSerializers: ["enzyme-to-json/serializer"],
|
||||
// moduleFileExtensions: ["js", "json", "ts", "tsx", "jsx", "node"],
|
||||
// verbose: true,
|
||||
// roots: ["<rootDir>/src"],
|
||||
// transform: {
|
||||
// "^.+\\.tsx?$": "ts-jest",
|
||||
// "^.+\\.ts?$": "babel-jest",
|
||||
// "^.+\\.js?$": "ts-jest",
|
||||
// "^.+\\.jsx?$": "babel-jest"
|
||||
// },
|
||||
// preset: "ts-jest/presets/js-with-ts",
|
||||
// testEnvironment: "node"
|
||||
// }
|
||||
// },
|
||||
plugins: [
|
||||
{
|
||||
plugin: CracoAlias,
|
||||
options: {
|
||||
source: 'tsconfig',
|
||||
tsConfigPath: 'tsconfig.paths.json',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
19
custom.d.ts
vendored
19
custom.d.ts
vendored
|
@ -1,19 +0,0 @@
|
|||
declare module '*.svg' {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module '*.scss' {
|
||||
const content: { [className: string]: string };
|
||||
export = content;
|
||||
}
|
||||
|
||||
declare module '*.less' {
|
||||
const content: { [className: string]: string };
|
||||
export = content;
|
||||
}
|
||||
|
||||
declare module '*.json' {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
150
package.json
150
package.json
|
@ -1,133 +1,75 @@
|
|||
{
|
||||
"name": "my-empty-react-project",
|
||||
"version": "2.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=development webpack-dev-server --mode development --hot --open --inline --progress",
|
||||
"build": "NODE_ENV=production webpack --env production --config=webpack.config.js --progress -p",
|
||||
"profile": "webpack --json > stats.json"
|
||||
},
|
||||
"author": "Fedor Katurov <gotham48@gmail.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/muerwre/my-empty-react-project"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.6.4",
|
||||
"@babel/preset-env": "^7.6.3",
|
||||
"@babel/types": "7.5.5",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/node": "^11.13.22",
|
||||
"@types/ramda": "^0.26.33",
|
||||
"@types/react": "16.9.11",
|
||||
"@types/react-redux": "^7.1.9",
|
||||
"@types/react-router": "^5.1.2",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"autoresponsive-react": "^1.1.31",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"circular-dependency-plugin": "^5.2.0",
|
||||
"css-loader": "^0.28.11",
|
||||
"file-loader": "^1.1.11",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"less-loader": "^4.1.0",
|
||||
"mini-css-extract-plugin": "^0.5.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
"path": "^0.12.7",
|
||||
"prettier": "^1.18.2",
|
||||
"resolve-url-loader": "^3.0.1",
|
||||
"style-loader": "^0.21.0",
|
||||
"ts-node": "^8.4.1",
|
||||
"typescript": "^3.7.2",
|
||||
"uglifyjs-webpack-plugin": "^1.3.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.9",
|
||||
"webpack-dev-server": "^3.8.2"
|
||||
},
|
||||
"license": "MIT",
|
||||
"name": "vault-cra",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@hot-loader/react-dom": "^16.10.2",
|
||||
"@popperjs/core": "^2.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "^1.13.0",
|
||||
"@typescript-eslint/parser": "^1.13.0",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"autosize": "^4.0.2",
|
||||
"axios": "^0.18.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"body-scroll-lock": "^2.6.4",
|
||||
"classnames": "^2.2.6",
|
||||
"clean-webpack-plugin": "^0.1.9",
|
||||
"connected-react-router": "^6.5.2",
|
||||
"date-fns": "^2.4.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"dotenv-webpack": "^1.7.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-airbnb": "^17.1.1",
|
||||
"eslint-config-prettier": "^6.4.0",
|
||||
"eslint-import-resolver-babel-module": "^4.0.0",
|
||||
"eslint-import-resolver-typescript": "^1.1.1",
|
||||
"eslint-import-resolver-webpack": "^0.9.0",
|
||||
"eslint-loader": "^2.2.1",
|
||||
"eslint-plugin-babel": "^5.3.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-react": "^7.16.0",
|
||||
"eslint-plugin-react-hooks": "^1.7.0",
|
||||
"flexbin": "^0.2.0",
|
||||
"history": "^4.10.1",
|
||||
"http-errors": "~1.6.2",
|
||||
"less": "^3.10.3",
|
||||
"less-middleware": "~2.2.1",
|
||||
"lodash": "^4.17.19",
|
||||
"node-sass": "^4.11.0",
|
||||
"node-sass": "4.14.1",
|
||||
"photoswipe": "^4.1.3",
|
||||
"raleway-cyrillic": "^4.0.2",
|
||||
"ramda": "^0.26.1",
|
||||
"react": "16.13.0",
|
||||
"react-dom": "^16.13.0",
|
||||
"react-hot-loader": "^4.12.15",
|
||||
"react-packery-component": "^1.0.2",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-popper": "^2.2.3",
|
||||
"react-redux": "^6.0.1",
|
||||
"react-router": "^5.1.2",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.4.4",
|
||||
"react-sortable-hoc": "^1.11",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"redux": "^4.0.1",
|
||||
"redux-persist": "^5.10.0",
|
||||
"redux-saga": "^1.1.1",
|
||||
"reduxsauce": "^1.0.0",
|
||||
"resize-sensor": "^0.0.6",
|
||||
"sass-loader": "^7.3.1",
|
||||
"sass-resources-loader": "^2.0.0",
|
||||
"scrypt": "^6.0.3",
|
||||
"sticky-sidebar": "^3.3.1",
|
||||
"throttle-debounce": "^2.1.0",
|
||||
"tiny-slider-react": "^0.5.3",
|
||||
"tinycolor": "^0.0.1",
|
||||
"tslint": "^5.20.0",
|
||||
"tslint-config-airbnb": "^5.11.2",
|
||||
"tslint-react": "^4.1.0",
|
||||
"tslint-react-hooks": "^2.2.1",
|
||||
"tt-react-custom-scrollbars": "latest",
|
||||
"uuid4": "^1.1.4"
|
||||
"typescript": "^4.0.5",
|
||||
"uuid4": "^1.1.4",
|
||||
"web-vitals": "^0.2.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"**/**/minimist": "^1.2.3",
|
||||
"**/**/acorn": "^6.4.1",
|
||||
"**/**/kind-of": "^6.0.3",
|
||||
"**/**/serialize-javascript": "^2.1.1",
|
||||
"**/**/js-yaml": "^3.13.1",
|
||||
"**/**/cryptiles": "^4.1.2",
|
||||
"**/**/hoek": "^4.2.1"
|
||||
"scripts": {
|
||||
"start": "craco start",
|
||||
"build": "craco build",
|
||||
"test": "craco test",
|
||||
"eject": "craco eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/node": "^11.13.22",
|
||||
"@types/ramda": "^0.26.33",
|
||||
"@types/react-redux": "^7.1.11",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"craco": "^0.0.3",
|
||||
"craco-alias": "^2.1.1",
|
||||
"prettier": "^1.18.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import App from "../src/containers/App";
|
||||
|
||||
const HomePage = () => (<App />)
|
||||
|
||||
export default HomePage
|
|
@ -12,7 +12,7 @@ import * as MODAL_ACTIONS from '~/redux/modal/actions';
|
|||
type IProps = HTMLAttributes<HTMLDivElement> & {
|
||||
is_empty?: boolean;
|
||||
is_loading?: boolean;
|
||||
comment_group?: ICommentGroup;
|
||||
comment_group: ICommentGroup;
|
||||
comment_data: INodeState['comment_data'];
|
||||
is_same?: boolean;
|
||||
can_edit?: boolean;
|
||||
|
@ -58,7 +58,7 @@ const Comment: FC<IProps> = memo(
|
|||
<CommentContent
|
||||
comment={comment}
|
||||
key={comment.id}
|
||||
can_edit={can_edit}
|
||||
can_edit={!!can_edit}
|
||||
onDelete={onDelete}
|
||||
onEdit={onEdit}
|
||||
modalShowPhotoswipe={modalShowPhotoswipe}
|
||||
|
|
|
@ -16,7 +16,7 @@ import * as UPLOAD_ACTIONS from '~/redux/uploads/actions';
|
|||
import { selectUploads } from '~/redux/uploads/selectors';
|
||||
import { IState } from '~/redux/store';
|
||||
import { getFileType } from '~/utils/uploader';
|
||||
import { getRandomPhrase } from '~/constants/phrases';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
import { ERROR_LITERAL } from '~/constants/errors';
|
||||
import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
|
||||
import { CommentFormAttachButtons } from '~/components/comment/CommentFormButtons';
|
||||
|
@ -153,7 +153,7 @@ const CommentFormUnconnected: FC<IProps> = memo(
|
|||
nodeCancelCommentEdit(id);
|
||||
}, [nodeCancelCommentEdit, comment.id]);
|
||||
|
||||
const placeholder = getRandomPhrase('SIMPLE');
|
||||
const placeholder = useRandomPhrase('SIMPLE');
|
||||
|
||||
const clearError = useCallback(() => nodeSetCommentData(id, { error: '' }), [
|
||||
id,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: url('~/sprites/stripes.svg') transparentize($color: #000000, $amount: 0.5);
|
||||
background: url('../../../sprites/stripes.svg') transparentize($color: #000000, $amount: 0.5);
|
||||
}
|
||||
|
||||
img {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url(~/sprites/stripes.svg) transparentize($content_bg, 0.2);
|
||||
background: url(../../../sprites/stripes.svg) transparentize($content_bg, 0.2);
|
||||
}
|
||||
|
||||
@include tablet {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { FC, ReactComponentElement, DetailsHTMLAttributes, useEffect, useRef } from 'react';
|
||||
import React, { DetailsHTMLAttributes, FC, useEffect, useRef } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import StickySidebar from 'sticky-sidebar';
|
||||
import classnames from 'classnames';
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
.text {
|
||||
font: $font_18_regular;
|
||||
line-height: 22px;
|
||||
background: transparentize($color: $content_bg, $amount: 0.3) url('~/sprites/stripes.svg');
|
||||
background: transparentize($color: $content_bg, $amount: 0.3) url('../../../sprites/stripes.svg');
|
||||
padding: $gap;
|
||||
box-sizing: border-box;
|
||||
border-radius: $radius;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url('~/sprites/stripes.svg') rgba(0, 0, 0, 0.3);
|
||||
background: url('../../../sprites/stripes.svg') rgba(0, 0, 0, 0.3);
|
||||
z-index: 4;
|
||||
pointer-events: none;
|
||||
box-shadow: inset transparentize($color: white, $amount: 0.85) 0 1px;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC, ChangeEvent, useCallback, useState, useEffect, LegacyRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import * as styles from '~/styles/common/inputs.module.scss';
|
||||
import styles from '~/styles/common/inputs.module.scss';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { IInputTextProps } from '~/redux/types';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
|
|
|
@ -11,7 +11,7 @@ import React, {
|
|||
import classNames from 'classnames';
|
||||
import autosize from 'autosize';
|
||||
|
||||
import * as styles from '~/styles/common/inputs.module.scss';
|
||||
import styles from '~/styles/common/inputs.module.scss';
|
||||
import { Icon } from '../Icon';
|
||||
|
||||
type IProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5) url('~/sprites/dots.svg');
|
||||
background: rgba(0, 0, 0, 0.5) url('../../../sprites/dots.svg');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
user-select: none;
|
||||
background: url('~/sprites/stripes.svg');
|
||||
background: url('../../../sprites/stripes.svg');
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { INotification, NOTIFICATION_TYPES } from '~/redux/types';
|
|||
import styles from './styles.module.scss';
|
||||
import { NotificationMessage } from '../NotificationMessage';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { getRandomPhrase } from '~/constants/phrases';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
|
||||
interface IProps {
|
||||
notifications: INotification[];
|
||||
|
@ -15,7 +15,7 @@ const NOTIFICATION_RENDERERS = {
|
|||
};
|
||||
|
||||
const NotificationBubble: FC<IProps> = ({ notifications, onClick }) => {
|
||||
const placeholder = getRandomPhrase('NOTHING_HERE');
|
||||
const placeholder = useRandomPhrase('NOTHING_HERE');
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
|
|
|
@ -2,11 +2,11 @@ import { IComment, INode } from '~/redux/types';
|
|||
import { ISocialProvider } from '~/redux/auth/types';
|
||||
|
||||
export const API = {
|
||||
BASE: process.env.API_HOST,
|
||||
BASE: process.env.REACT_APP_API_HOST,
|
||||
USER: {
|
||||
LOGIN: '/user/login',
|
||||
OAUTH_WINDOW: (provider: ISocialProvider) =>
|
||||
`${process.env.API_HOST}oauth/${provider}/redirect`,
|
||||
`${process.env.RACT_APP_API_HOST}oauth/${provider}/redirect`,
|
||||
ME: '/user/',
|
||||
PROFILE: (username: string) => `/user/user/${username}/profile`,
|
||||
MESSAGES: (username: string) => `/user/user/${username}/messages`,
|
||||
|
|
|
@ -39,5 +39,5 @@ export const PHRASES = {
|
|||
],
|
||||
};
|
||||
|
||||
export const getRandomPhrase = (key: keyof typeof PHRASES) =>
|
||||
export const useRandomPhrase = (key: keyof typeof PHRASES) =>
|
||||
useMemo(() => PHRASES[key][Math.floor(Math.random() * PHRASES[key].length)], []);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { ConnectedRouter } from 'connected-react-router';
|
||||
import { history } from '~/redux/store';
|
||||
import { MainLayout } from '~/containers/main/MainLayout';
|
||||
|
@ -40,4 +39,4 @@ const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(hot(module)(Component));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Component);
|
||||
|
|
|
@ -8,7 +8,7 @@ import styles from './styles.module.scss';
|
|||
import { Group } from '~/components/containers/Group';
|
||||
import boris from '~/sprites/boris_robot.svg';
|
||||
import { NodeNoComments } from '~/components/node/NodeNoComments';
|
||||
import { getRandomPhrase } from '~/constants/phrases';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
||||
|
||||
import * as NODE_ACTIONS from '~/redux/node/actions';
|
||||
|
@ -19,7 +19,6 @@ import isBefore from 'date-fns/isBefore';
|
|||
import { Card } from '~/components/containers/Card';
|
||||
import { Footer } from '~/components/main/Footer';
|
||||
import { Sticky } from '~/components/containers/Sticky';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { selectBorisStats } from '~/redux/boris/selectors';
|
||||
import { BorisStats } from '~/components/boris/BorisStats';
|
||||
|
||||
|
@ -58,7 +57,7 @@ const BorisLayoutUnconnected: FC<IProps> = ({
|
|||
borisLoadStats,
|
||||
stats,
|
||||
}) => {
|
||||
const title = getRandomPhrase('BORIS_TITLE');
|
||||
const title = useRandomPhrase('BORIS_TITLE');
|
||||
|
||||
useEffect(() => {
|
||||
const last_comment = comments[0];
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: 50% 0% no-repeat url('~/sprites/boris_bg.svg');
|
||||
background: 50% 0% no-repeat url('../../../sprites/boris_bg.svg');
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
background: url('~/sprites/lost.svg') 50% 50% no-repeat;
|
||||
background: url('../../../sprites/lost.svg') 50% 50% no-repeat;
|
||||
background-size: cover;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="theme-color" content="#222222">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500,600,700,800&display=swap&subset=cyrillic"
|
||||
rel="stylesheet" />
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<style>
|
||||
#main_loader {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #222222;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font: 600 22px 'Montserrat';
|
||||
color: white;
|
||||
}
|
||||
|
||||
#main_loader>div {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
@keyframes erdball {
|
||||
0% {
|
||||
transform: translate(0, 100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#preload_shade {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
box-shadow: white 0 0 0 3px;
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin-bottom: 15px !important;
|
||||
}
|
||||
|
||||
#preload_shade>span {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: white 0 0 0 2px;
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
animation: erdball 3s infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
#preload_shade>span:nth-child(2) {
|
||||
animation-delay: -1s;
|
||||
}
|
||||
|
||||
#preload_shade>span:nth-child(3) {
|
||||
animation-delay: -2s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="main_loader">
|
||||
<div id="preload_shade">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div>СМИРЕННО</div>
|
||||
<div>ОЖИДАЙТЕ</div>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -17,55 +17,3 @@ render(
|
|||
</Provider>,
|
||||
document.getElementById('app')
|
||||
);
|
||||
|
||||
/*
|
||||
[stage 1]
|
||||
- check if email is registered at social login
|
||||
- profile cover upload
|
||||
- illustrate login
|
||||
- illustrate restoreRequestDialog
|
||||
- friendship
|
||||
- signup?
|
||||
- text post can also has songs http://vault48.org/post5052
|
||||
- fulltext search: https://github.com/typeorm/typeorm/issues/3191
|
||||
- zoom: https://manuelstofer.github.io/pinchzoom/
|
||||
|
||||
- notifications (node, comment)
|
||||
|
||||
- social integration (assimilate)
|
||||
- comment editing
|
||||
|
||||
Done:
|
||||
- set file target on comment save, node save, profile upload
|
||||
- delete comments
|
||||
- import videos (partially)
|
||||
- delete nodes
|
||||
- user access time update
|
||||
- import graffiti
|
||||
- <...> format
|
||||
- youtube embeds
|
||||
- mobile header
|
||||
- sticky header
|
||||
- password restore
|
||||
- avatar upload
|
||||
- flow updates
|
||||
- flow infinite scroll
|
||||
- better node brief update
|
||||
- fix: text nodes cell has no preview (actually, that's a problem of brief)
|
||||
- relocate files
|
||||
- backend: exclude node covers on import
|
||||
- profile editing
|
||||
- notifications (messages)
|
||||
- profile modal
|
||||
- messages
|
||||
- better dialogs: https://codepen.io/muemue/pen/abbEMMy
|
||||
- imagecaching at backend
|
||||
- social integration (login, signup)
|
||||
- boris with comments (import)
|
||||
- boris with comments (layout)
|
||||
- fix: user receives his own notifications :-(
|
||||
- fix: node related and albums should exclude node itself
|
||||
- fix: select node and edit it. All images will be not loaded
|
||||
- fix: text nodes cell not clickable
|
||||
- fix: text nodes should not have 'no comments yet badge
|
||||
*/
|
||||
|
|
7
src/react-app-env.d.ts
vendored
Normal file
7
src/react-app-env.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react-scripts" />
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
readonly REACT_APP_API_URL: string;
|
||||
readonly REACT_APP_REMOTE_CURRENT: string;
|
||||
}
|
||||
}
|
13
src/reportWebVitals.js
Normal file
13
src/reportWebVitals.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
5
src/setupTests.js
Normal file
5
src/setupTests.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
|
@ -1,4 +1,5 @@
|
|||
// @import '~raleway-cyrillic/raleway.css';
|
||||
@import "src/styles/variables";
|
||||
|
||||
html {
|
||||
min-height: 100vh;
|
||||
|
|
|
@ -69,13 +69,13 @@ export const getURLFromString = (
|
|||
): string => {
|
||||
if (size) {
|
||||
return url
|
||||
.replace('REMOTE_CURRENT://', `${process.env.REMOTE_CURRENT}cache/${size}/`)
|
||||
.replace('REMOTE_OLD://', process.env.REMOTE_OLD);
|
||||
.replace('REMOTE_CURRENT://', `${process.env.REACT_APP_REMOTE_CURRENT}cache/${size}/`)
|
||||
.replace('REMOTE_OLD://', process.env.REACT_APP_REMOTE_OLD);
|
||||
}
|
||||
|
||||
return url
|
||||
.replace('REMOTE_CURRENT://', process.env.REMOTE_CURRENT)
|
||||
.replace('REMOTE_OLD://', process.env.REMOTE_OLD);
|
||||
.replace('REMOTE_CURRENT://', process.env.REACT_APP_REMOTE_CURRENT)
|
||||
.replace('REMOTE_OLD://', process.env.REACT_APP_REMOTE_OLD);
|
||||
};
|
||||
|
||||
export const getURL = (file: Partial<IFile>, size?: typeof PRESETS[keyof typeof PRESETS]) => {
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
{
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"extends": "./tsconfig.paths.json",
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"outDir": "./dist/",
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"removeComments": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"target": "es2018",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react",
|
||||
"lib": ["es2015", "dom", "es6"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
"noImplicitAny": false
|
||||
},
|
||||
"include": ["./src/**/*.ts", "./src/**/*.tsx", "./custom.d.ts"],
|
||||
"exclude": ["./__tests__/**/*"]
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
|
|
8
tsconfig.paths.json
Normal file
8
tsconfig.paths.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
}
|
||||
}
|
29
tslint.json
29
tslint.json
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": ["tslint-config-airbnb", "tslint-react", "tslint:recommended", "tslint-react-hooks"],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"quotemark": [true, "single", "jsx-double"],
|
||||
"react-hooks-nesting": "error",
|
||||
"ordered-imports": false,
|
||||
"import-name": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-console": [true, "warning"],
|
||||
"arrow-parens": [true, "ban-single-arg-parens"],
|
||||
"ter-arrow-parens": [true, "as-needed"],
|
||||
"curly": false,
|
||||
"variable-name": [true, "ban-keywords", "allow-snake-case", "allow-pascal-case"],
|
||||
"no-var-requires": false,
|
||||
"no-nested-ternary": true,
|
||||
"jsx-key": true,
|
||||
"jsx-self-close": true,
|
||||
"jsx-wrap-multiline": true,
|
||||
"jsx-alignment": true,
|
||||
"jsx-curly-spacing": [true, "never"],
|
||||
"jsx-equals-spacing": [true, "never"],
|
||||
"jsx-no-multiline-js": false,
|
||||
"jsx-boolean-value": false,
|
||||
"prefer-array-literal": false
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
const webpack = require('webpack');
|
||||
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
const { join } = require('path');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const Dotenv = require('dotenv-webpack');
|
||||
const CircularDependencyPlugin = require('circular-dependency-plugin');
|
||||
|
||||
const htmlPlugin = new HtmlWebPackPlugin({
|
||||
template: './src/index.html',
|
||||
filename: './index.html',
|
||||
title: 'VAULT',
|
||||
hash: false,
|
||||
favicon: 'src/sprites/favicon.ico',
|
||||
});
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
const devtool = isDevelopment ? 'cheap-module-eval-source-map' : 'source-map';
|
||||
|
||||
const resolve = {
|
||||
alias: {
|
||||
'react-dom': '@hot-loader/react-dom',
|
||||
'~': join(__dirname, 'src'),
|
||||
},
|
||||
extensions: ['*', '.ts', '.tsx', '.js', '.jsx', '.json', '.scss'],
|
||||
};
|
||||
|
||||
/* Configuration */
|
||||
|
||||
module.exports = () => {
|
||||
/* Export */
|
||||
const plugins = [
|
||||
htmlPlugin,
|
||||
// miniCssExractPlugin,
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
new Dotenv(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contenthash].css',
|
||||
chunkFilename: '[id].[contenthash].css',
|
||||
}),
|
||||
new CircularDependencyPlugin({
|
||||
// exclude: /node_modules/,
|
||||
include: /LoginDialog/,
|
||||
failOnError: true,
|
||||
allowAsyncCycles: false,
|
||||
cwd: process.cwd(),
|
||||
}),
|
||||
];
|
||||
|
||||
return {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{ loader: isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader },
|
||||
// { loader: MiniCssExtractPlugin.loader },
|
||||
// { loader: 'css-loader' },
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
sourceMap: true,
|
||||
importLoaders: 2,
|
||||
localIdentName: '[folder]__[local]__[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
{ loader: 'less-loader' },
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
{ loader: isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader },
|
||||
// { loader: MiniCssExtractPlugin.loader, options: { filename: '[name].[hash].css' } },
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
sourceMap: true,
|
||||
importLoaders: 2,
|
||||
localIdentName: '[folder]__[local]__[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
{ loader: 'resolve-url-loader' },
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
sourceMapContents: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-resources-loader',
|
||||
options: {
|
||||
resources: ['src/styles/variables.scss'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(ts|tsx|js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{ test: /\.(ts|tsx)?$/, loader: 'awesome-typescript-loader' },
|
||||
{
|
||||
test: /\.(eot|ttf|woff|woff2|otf)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
// outputPath: '/font'
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(png|svg|gif)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
devtool,
|
||||
resolve,
|
||||
plugins,
|
||||
entry: {
|
||||
app: './src/index.tsx',
|
||||
},
|
||||
output: {
|
||||
publicPath: '/',
|
||||
filename: isDevelopment ? '[name].[hash].js' : '[name].[contenthash].js',
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
name: 'vendor',
|
||||
chunks: 'all',
|
||||
test: /node_modules/,
|
||||
priority: 20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
commons: {
|
||||
name: 'commons',
|
||||
chunks: 'initial',
|
||||
minChunks: 2,
|
||||
minSize: 0,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [
|
||||
new UglifyJsPlugin({
|
||||
cache: true,
|
||||
parallel: true,
|
||||
sourceMap: true, // set to true if you want JS source maps
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
],
|
||||
occurrenceOrder: true, // To keep filename consistent between different modes (for example building only)
|
||||
},
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
port: 4848,
|
||||
// host: '192.168.88.40',
|
||||
contentBase: 'dist',
|
||||
publicPath: '/',
|
||||
hot: true,
|
||||
open: false,
|
||||
},
|
||||
};
|
||||
};
|
10576
yarn-error.log
10576
yarn-error.log
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue