Compare commits
18 Commits
85870d1f7d
...
main
Author | SHA1 | Date |
---|---|---|
Derek | 4a93c2272b | |
Derek | 06adc19ea9 | |
Derek | 6d4bc1dac1 | |
Derek | 3149a48913 | |
Derek | 0db073f651 | |
Derek | 1a1a4be3f8 | |
Derek | a613f28dd0 | |
Derek | 8ca7d95a97 | |
Derek | bcd09d2521 | |
Derek | 285c86ed39 | |
Derek | b2e32aa105 | |
Derek | 81d909d5db | |
Derek | 370b845036 | |
Derek | 24b5dd835e | |
Derek | bf56ce9034 | |
Derek | 22ef8bb29c | |
Derek | 14ec6550fa | |
Derek | 0083793ba3 |
|
@ -0,0 +1,12 @@
|
||||||
|
const {
|
||||||
|
override,
|
||||||
|
addWebpackAlias,
|
||||||
|
} = require("customize-cra");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = override(
|
||||||
|
addWebpackAlias({
|
||||||
|
'@': path.resolve(__dirname, 'src/'),
|
||||||
|
'@components': path.resolve(__dirname, 'src/components'),
|
||||||
|
}),
|
||||||
|
);
|
|
@ -11,10 +11,16 @@
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
"@testing-library/jest-dom": "^5.16.1",
|
||||||
"@testing-library/react": "^12.1.2",
|
"@testing-library/react": "^12.1.2",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
"canvas-confetti": "^1.5.1",
|
||||||
|
"customize-cra": "^1.0.0",
|
||||||
|
"mfm-js": "^0.22.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-app-rewired": "^2.2.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-router-dom": "^6.2.1",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
|
"react-transition-group": "^4.4.2",
|
||||||
"styled-components": "^5.3.3"
|
"styled-components": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -4894,6 +4900,15 @@
|
||||||
"url": "https://opencollective.com/browserslist"
|
"url": "https://opencollective.com/browserslist"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/canvas-confetti": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-Ncz+oZJP6OvY7ti4E1slxVlyAV/3g7H7oQtcCDXgwGgARxPnwYY9PW5Oe+I8uvspYNtuHviAdgA0LfcKFWJfpg==",
|
||||||
|
"funding": {
|
||||||
|
"type": "donate",
|
||||||
|
"url": "https://www.paypal.me/kirilvatev"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/case-sensitive-paths-webpack-plugin": {
|
"node_modules/case-sensitive-paths-webpack-plugin": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
|
||||||
|
@ -5717,6 +5732,19 @@
|
||||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
|
||||||
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
|
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
|
||||||
|
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
|
||||||
|
},
|
||||||
|
"node_modules/customize-cra": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-DbtaLuy59224U+xCiukkxSq8clq++MOtJ1Et7LED1fLszWe88EoblEYFBJ895sB1mC6B4uu3xPT/IjClELhMbA==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash.flow": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
|
||||||
|
@ -6008,6 +6036,15 @@
|
||||||
"utila": "~0.4"
|
"utila": "~0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dom-helpers": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dom-serializer": {
|
"node_modules/dom-serializer": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||||
|
@ -7932,6 +7969,14 @@
|
||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/history": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hoist-non-react-statics": {
|
"node_modules/hoist-non-react-statics": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
@ -10787,6 +10832,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||||
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
|
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.flow": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
|
||||||
|
"integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o="
|
||||||
|
},
|
||||||
"node_modules/lodash.memoize": {
|
"node_modules/lodash.memoize": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||||
|
@ -10933,6 +10983,14 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mfm-js": {
|
||||||
|
"version": "0.22.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mfm-js/-/mfm-js-0.22.1.tgz",
|
||||||
|
"integrity": "sha512-UV5zvDKlWPpBFeABhyCzuOTJ3RwrNrmVpJ+zz/dFX6D/ntEywljgxkfsLamcy0ZSwUAr0O+WQxGHvAwyxUgsAQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"twemoji-parser": "14.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/micromatch": {
|
"node_modules/micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
|
@ -13131,6 +13189,28 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-app-rewired": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-uFQWTErXeLDrMzOJHKp0h8P1z0LV9HzPGsJ6adOtGlA/B9WfT6Shh4j2tLTTGlXOfiVx6w6iWpp7SOC5pvk+gA==",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^5.6.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"react-app-rewired": "bin/index.js"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react-scripts": ">=2.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-app-rewired/node_modules/semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dev-utils": {
|
"node_modules/react-dev-utils": {
|
||||||
"version": "12.0.0",
|
"version": "12.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
|
||||||
|
@ -13279,6 +13359,30 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||||
|
"dependencies": {
|
||||||
|
"history": "^5.2.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||||
|
"dependencies": {
|
||||||
|
"history": "^5.2.0",
|
||||||
|
"react-router": "6.2.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-scripts": {
|
"node_modules/react-scripts": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
||||||
|
@ -13351,6 +13455,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-transition-group": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
|
||||||
|
"integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"dom-helpers": "^5.0.1",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.6.0",
|
||||||
|
"react-dom": ">=16.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
@ -14991,6 +15110,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/twemoji-parser": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA=="
|
||||||
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
@ -19669,6 +19793,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz",
|
||||||
"integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g=="
|
"integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g=="
|
||||||
},
|
},
|
||||||
|
"canvas-confetti": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-Ncz+oZJP6OvY7ti4E1slxVlyAV/3g7H7oQtcCDXgwGgARxPnwYY9PW5Oe+I8uvspYNtuHviAdgA0LfcKFWJfpg=="
|
||||||
|
},
|
||||||
"case-sensitive-paths-webpack-plugin": {
|
"case-sensitive-paths-webpack-plugin": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
|
||||||
|
@ -20269,6 +20398,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "3.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
|
||||||
|
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
|
||||||
|
},
|
||||||
|
"customize-cra": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-DbtaLuy59224U+xCiukkxSq8clq++MOtJ1Et7LED1fLszWe88EoblEYFBJ895sB1mC6B4uu3xPT/IjClELhMbA==",
|
||||||
|
"requires": {
|
||||||
|
"lodash.flow": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"damerau-levenshtein": {
|
"damerau-levenshtein": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
|
||||||
|
@ -20496,6 +20638,15 @@
|
||||||
"utila": "~0.4"
|
"utila": "~0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dom-helpers": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dom-serializer": {
|
"dom-serializer": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||||
|
@ -21878,6 +22029,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||||
},
|
},
|
||||||
|
"history": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hoist-non-react-statics": {
|
"hoist-non-react-statics": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
@ -23943,6 +24102,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||||
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
|
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
|
||||||
},
|
},
|
||||||
|
"lodash.flow": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
|
||||||
|
"integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o="
|
||||||
|
},
|
||||||
"lodash.memoize": {
|
"lodash.memoize": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||||
|
@ -24061,6 +24225,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||||
},
|
},
|
||||||
|
"mfm-js": {
|
||||||
|
"version": "0.22.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mfm-js/-/mfm-js-0.22.1.tgz",
|
||||||
|
"integrity": "sha512-UV5zvDKlWPpBFeABhyCzuOTJ3RwrNrmVpJ+zz/dFX6D/ntEywljgxkfsLamcy0ZSwUAr0O+WQxGHvAwyxUgsAQ==",
|
||||||
|
"requires": {
|
||||||
|
"twemoji-parser": "14.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
|
@ -25489,6 +25661,21 @@
|
||||||
"whatwg-fetch": "^3.6.2"
|
"whatwg-fetch": "^3.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-app-rewired": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-uFQWTErXeLDrMzOJHKp0h8P1z0LV9HzPGsJ6adOtGlA/B9WfT6Shh4j2tLTTGlXOfiVx6w6iWpp7SOC5pvk+gA==",
|
||||||
|
"requires": {
|
||||||
|
"semver": "^5.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dev-utils": {
|
"react-dev-utils": {
|
||||||
"version": "12.0.0",
|
"version": "12.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
|
||||||
|
@ -25600,6 +25787,23 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||||
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
||||||
},
|
},
|
||||||
|
"react-router": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||||
|
"requires": {
|
||||||
|
"history": "^5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-router-dom": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||||
|
"requires": {
|
||||||
|
"history": "^5.2.0",
|
||||||
|
"react-router": "6.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
||||||
|
@ -25655,6 +25859,17 @@
|
||||||
"workbox-webpack-plugin": "^6.4.1"
|
"workbox-webpack-plugin": "^6.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-transition-group": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
|
||||||
|
"integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"dom-helpers": "^5.0.1",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
@ -26874,6 +27089,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"twemoji-parser": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA=="
|
||||||
|
},
|
||||||
"type-check": {
|
"type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
|
13
package.json
13
package.json
|
@ -6,17 +6,22 @@
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
"@testing-library/jest-dom": "^5.16.1",
|
||||||
"@testing-library/react": "^12.1.2",
|
"@testing-library/react": "^12.1.2",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
"canvas-confetti": "^1.5.1",
|
||||||
|
"customize-cra": "^1.0.0",
|
||||||
|
"mfm-js": "^0.22.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-app-rewired": "^2.2.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-router-dom": "^6.2.1",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
|
"react-transition-group": "^4.4.2",
|
||||||
"styled-components": "^5.3.3"
|
"styled-components": "^5.3.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-app-rewired start",
|
||||||
"build": "react-scripts build",
|
"build": "react-app-rewired build",
|
||||||
"test": "react-scripts test",
|
"test": "react-app-rewired test"
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { useRef, useCallback, useEffect } from 'react';
|
||||||
|
import confetti from 'canvas-confetti';
|
||||||
|
|
||||||
|
const commonOptions = (tier) => ({
|
||||||
|
ticks: 400,
|
||||||
|
particleCount: 25 * tier,
|
||||||
|
});
|
||||||
|
|
||||||
|
const delay = 1000;
|
||||||
|
|
||||||
|
export default function useZoom(count, tier) {
|
||||||
|
const canvasRef = useRef();
|
||||||
|
|
||||||
|
const doAnimation = useCallback(() => {
|
||||||
|
const confettiCannon = confetti.create(canvasRef.current, { useWorker: true });
|
||||||
|
let remainCount = count;
|
||||||
|
|
||||||
|
const pop = () => {
|
||||||
|
confettiCannon({
|
||||||
|
origin: { x: 0, y: 1 },
|
||||||
|
angle: 45,
|
||||||
|
drift: -0.5,
|
||||||
|
...commonOptions(tier),
|
||||||
|
});
|
||||||
|
confettiCannon({
|
||||||
|
origin: { x: 1, y: 1 },
|
||||||
|
angle: 135,
|
||||||
|
drift: 0.5,
|
||||||
|
...commonOptions(tier),
|
||||||
|
});
|
||||||
|
remainCount -= 1;
|
||||||
|
|
||||||
|
if (remainCount > 0) {
|
||||||
|
setTimeout(pop, Math.max(delay / remainCount, 200));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pop();
|
||||||
|
}, [canvasRef]);
|
||||||
|
|
||||||
|
return [canvasRef, doAnimation];
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { useRef, useCallback, useEffect } from 'react';
|
||||||
|
import XTERM_COLORS from '../xterm';
|
||||||
|
|
||||||
|
const RAIDERS_PER_SECOND = 5;
|
||||||
|
const MAX_SECONDS = 10;
|
||||||
|
const FPS_CAP = 120;
|
||||||
|
const LINE_HEIGHT = 5;
|
||||||
|
const LINE_WIDTH = 700;
|
||||||
|
// Speed is in "seconds to cross card width"
|
||||||
|
const START_SPEED = 0.06;
|
||||||
|
const MIN_SPEED = 0.2;
|
||||||
|
|
||||||
|
export default function useZoom(count) {
|
||||||
|
const canvasRef = useRef();
|
||||||
|
|
||||||
|
const doAnimation = useCallback(() => {
|
||||||
|
const canvas = canvasRef.current;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const height = canvas.height;
|
||||||
|
const width = canvas.width;
|
||||||
|
|
||||||
|
let delay = count / RAIDERS_PER_SECOND;
|
||||||
|
if (delay > MAX_SECONDS) { delay = MAX_SECONDS };
|
||||||
|
const lines = Array(count).fill(null).map(() => ({
|
||||||
|
y: Math.floor(Math.random() * height),
|
||||||
|
x: width + LINE_WIDTH,
|
||||||
|
offset: Math.floor(Math.random() * delay * 1000),
|
||||||
|
speed: width / START_SPEED,
|
||||||
|
decel: Math.random() * (width / (MIN_SPEED - START_SPEED)),
|
||||||
|
color: XTERM_COLORS[118 + Math.floor(Math.random() * 24)],
|
||||||
|
}));
|
||||||
|
|
||||||
|
const fpsInterval = FPS_CAP / 1000;
|
||||||
|
const start = Date.now();
|
||||||
|
let then = Date.now();
|
||||||
|
let now, dt, elapsed;
|
||||||
|
let animationFrameId = requestAnimationFrame(animStep);
|
||||||
|
|
||||||
|
function animStep() {
|
||||||
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
animationFrameId = requestAnimationFrame(animStep);
|
||||||
|
|
||||||
|
let alive = false;
|
||||||
|
now = Date.now();
|
||||||
|
dt = now - then;
|
||||||
|
if (dt < fpsInterval) return;
|
||||||
|
then = now - (dt % fpsInterval);
|
||||||
|
elapsed = now - start;
|
||||||
|
dt = dt / 1000;
|
||||||
|
|
||||||
|
lines.forEach((line, i) => {
|
||||||
|
if (line.x < 0) { return; }
|
||||||
|
alive = true;
|
||||||
|
if (line.offset > elapsed) return;
|
||||||
|
|
||||||
|
const nextX = line.x - (dt * line.speed);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = LINE_HEIGHT;
|
||||||
|
ctx.strokeStyle = line.color;
|
||||||
|
ctx.moveTo(line.x, line.y);
|
||||||
|
ctx.lineTo(nextX - LINE_WIDTH, line.y);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.closePath();
|
||||||
|
|
||||||
|
line.x = nextX;
|
||||||
|
if (line.speed - line.decel > (width / MIN_SPEED)) {
|
||||||
|
line.speed -= line.decel;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!alive) {
|
||||||
|
cancelAnimationFrame(animationFrameId);
|
||||||
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [canvasRef, count]);
|
||||||
|
|
||||||
|
return [canvasRef, doAnimation];
|
||||||
|
}
|
|
@ -1,36 +1,50 @@
|
||||||
import { useEffect, useState, useRef } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
|
import { useQuery } from '../../hooks';
|
||||||
|
|
||||||
import ChatLog from '../chat-log';
|
import ChatLog from '../chat-log';
|
||||||
|
|
||||||
const maxsize = 100;
|
const maxsize = 25;
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [messages, setMessages] = useState([]);
|
const [messages, setMessages] = useState(Array(maxsize).fill(null));
|
||||||
const socket = useRef(null);
|
const [socket, setSocket] = useState();
|
||||||
|
|
||||||
|
const query = useQuery();
|
||||||
|
const websocketAddress = query.get('ws') ?? 'ws://127.0.0.1:8080';
|
||||||
|
|
||||||
|
const onEvent = useCallback((event) => {
|
||||||
|
setMessages((state) => {
|
||||||
|
const newState = [...state];
|
||||||
|
newState.unshift(JSON.parse(event.data));
|
||||||
|
newState.pop();
|
||||||
|
return newState;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const onEvent = function (event) {
|
if (socket) {
|
||||||
setMessages((state) => {
|
const onDiscconect = () => setSocket(null);
|
||||||
if (state.length >= maxsize) {
|
socket.addEventListener('message', onEvent);
|
||||||
state.pop();
|
socket.addEventListener('error', onDiscconect);
|
||||||
|
socket.addEventListener('close', onDiscconect);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
socket.removeEventListener('message', onEvent);
|
||||||
|
socket.removeEventListener('error', onDiscconect);
|
||||||
|
socket.removeEventListener('close', onDiscconect);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const attemptConnect = () => {
|
||||||
|
try {
|
||||||
|
const ws = new WebSocket(websocketAddress);
|
||||||
|
setSocket(ws);
|
||||||
|
} catch (error) {
|
||||||
|
setTimeout(attemptConnect, 5000);
|
||||||
}
|
}
|
||||||
return [JSON.parse(event.data), ...state];
|
};
|
||||||
});
|
attemptConnect();
|
||||||
};
|
|
||||||
|
|
||||||
const attemptConnect = () => {
|
|
||||||
socket.current = new WebSocket('ws://127.0.0.1:13337');
|
|
||||||
const onError = () => setTimeout(attemptConnect, 1000);
|
|
||||||
socket.current.addEventListener('error', onError);
|
|
||||||
socket.current.addEventListener('message', onEvent);
|
|
||||||
};
|
|
||||||
attemptConnect();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket.current.removeEventListener('message', onEvent);
|
|
||||||
socket.current.close();
|
|
||||||
}
|
}
|
||||||
}, [socket, maxsize, setMessages]);
|
}, [socket, websocketAddress]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatLog log={messages} />
|
<ChatLog log={messages} />
|
||||||
|
|
|
@ -1,26 +1,45 @@
|
||||||
|
import { useRef, useLayoutEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import Message from './message';
|
import Message from './message';
|
||||||
|
import Raid from './event-card/raid';
|
||||||
|
import Subscription from './event-card/sub';
|
||||||
|
import Follow from './event-card/follow';
|
||||||
|
|
||||||
import { List } from './chat-log.style';
|
import { List, Spacer } from './chat-log.style';
|
||||||
|
|
||||||
const elementMap = {
|
const elementMap = {
|
||||||
Message,
|
Message,
|
||||||
|
Raid,
|
||||||
|
Follow,
|
||||||
|
Subscription,
|
||||||
|
null: Spacer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selfChats = ['self', 'birbspace'];
|
||||||
|
|
||||||
function ChatLog({
|
function ChatLog({
|
||||||
log,
|
log,
|
||||||
}) {
|
}) {
|
||||||
// TODO: Should look at full MRO
|
const listRef = useRef();
|
||||||
const renderableEvents = log.filter((event) => Object.keys(elementMap).includes(event.type[0]))
|
const renderableEvents = log.map((event) => {
|
||||||
|
if (!event?.type) {
|
||||||
|
event = { type: ['null'], data: { }};
|
||||||
|
}
|
||||||
|
const bestRenderableInterface = event.type.find((interfaceName) => Object.keys(elementMap).includes(interfaceName));
|
||||||
|
const renderer = elementMap[bestRenderableInterface];
|
||||||
|
const deemphasize = !selfChats.includes(event.data.via ?? 'unknown');
|
||||||
|
return [event, renderer, deemphasize];
|
||||||
|
}).filter(([event, renderer, deemphasize]) => !!renderer);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
listRef.current.scrollTop = -1;
|
||||||
|
}, [renderableEvents]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List>
|
<List ref={listRef}>
|
||||||
{renderableEvents.map((event) => {
|
{renderableEvents.map(([event, Element, deemphasize]) => (
|
||||||
const Element = elementMap[event.type[0]];
|
<Element key={event.data.id} deemphasize={deemphasize} {...event.data} />
|
||||||
return (
|
))}
|
||||||
<Element key={event.data.id} {...event.data} />
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</List>
|
</List>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import styled from 'styled-components';
|
||||||
|
|
||||||
export const List = styled.div`
|
export const List = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
@ -9,4 +10,34 @@ export const List = styled.div`
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
padding: 12px 8px;
|
padding: 12px 8px;
|
||||||
|
|
||||||
|
overflow: scroll;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
|
scrollbar-width: none;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
font-family: 'Source Code Pro', monospace;
|
||||||
|
font-size: 24px;
|
||||||
|
|
||||||
|
|
||||||
|
> * {
|
||||||
|
@keyframes slide {
|
||||||
|
from {
|
||||||
|
transform: translateX(-50px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animation: 0.3s slide cubic-bezier(.08,.82,.17,1);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Spacer = styled.div`
|
||||||
|
min-height: 2em;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import styled, { css } from 'styled-components';
|
||||||
|
import XTERM_COLORS from '../../../xterm';
|
||||||
|
|
||||||
|
export const Root = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
background-color: ${XTERM_COLORS[236]};
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Foreground = styled.div`
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-shadow: 0 0 4px rgba(0, 0, 0, 60%);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Background = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
`;
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Root, Foreground, Channel } from './follow.style';
|
||||||
|
|
||||||
|
const Follow = ({
|
||||||
|
user_name,
|
||||||
|
}) => (
|
||||||
|
<Root>
|
||||||
|
<Foreground>
|
||||||
|
<Channel>{user_name}</Channel>
|
||||||
|
<span>joins the roost~</span>
|
||||||
|
</Foreground>
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Follow;
|
|
@ -0,0 +1,8 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import XTERM_COLORS from '@/xterm';
|
||||||
|
|
||||||
|
export { Root, Background, Foreground } from '../common.styles';
|
||||||
|
|
||||||
|
export const Channel = styled.span`
|
||||||
|
color: ${XTERM_COLORS[6]};
|
||||||
|
`;
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './follow';
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './raid';
|
|
@ -0,0 +1,26 @@
|
||||||
|
import React, { useRef, useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
|
import { Root, Foreground, Background, Channel } from './raid.style';
|
||||||
|
import Canvas from '@components/responsive-canvas';
|
||||||
|
|
||||||
|
import useZoom from '@/animations/useZoom';
|
||||||
|
|
||||||
|
const Raid = ({
|
||||||
|
from_channel, user_count,
|
||||||
|
}) => {
|
||||||
|
const [canvasRef, doAnimation] = useZoom(user_count);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<Foreground>
|
||||||
|
<Channel>{from_channel}</Channel>
|
||||||
|
<span>soars in with their {user_count}-odd flock!</span>
|
||||||
|
</Foreground>
|
||||||
|
<Background>
|
||||||
|
<Canvas ref={canvasRef} onResize={doAnimation} />
|
||||||
|
</Background>
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Raid;
|
|
@ -0,0 +1,9 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import XTERM_COLORS from '@/xterm';
|
||||||
|
|
||||||
|
export { Root, Background, Foreground } from '../common.styles';
|
||||||
|
|
||||||
|
export const Channel = styled.span`
|
||||||
|
color: ${XTERM_COLORS[223]};
|
||||||
|
font-size: 28px;
|
||||||
|
`;
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './sub';
|
|
@ -0,0 +1,47 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Root, Foreground, Background,
|
||||||
|
Channel, Streak,
|
||||||
|
} from './sub.style';
|
||||||
|
import Canvas from '@components/responsive-canvas';
|
||||||
|
|
||||||
|
import useConfetti from '@/animations/useConfetti';
|
||||||
|
|
||||||
|
|
||||||
|
const Sub = ({
|
||||||
|
user_name, gifted_to, streak,
|
||||||
|
}) => {
|
||||||
|
const [canvasRef, doAnimation] = useConfetti(gifted_to?.length ?? 1, 1);
|
||||||
|
|
||||||
|
let msg;
|
||||||
|
if (gifted_to?.length) {
|
||||||
|
msg = (
|
||||||
|
<>
|
||||||
|
<Channel>{user_name}</Channel>
|
||||||
|
<span>gifted {gifted_to.length} subscriptions!</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
msg = (
|
||||||
|
<>
|
||||||
|
<Channel>{user_name}</Channel>
|
||||||
|
<span>has subscribed!</span>
|
||||||
|
{streak > 1 ? (
|
||||||
|
<Streak>{streak} times and counting!</Streak>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<Foreground>{msg}</Foreground>
|
||||||
|
<Background>
|
||||||
|
<Canvas ref={canvasRef} onResize={doAnimation} />
|
||||||
|
</Background>
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sub;
|
|
@ -0,0 +1,14 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import XTERM_COLORS from '@/xterm';
|
||||||
|
|
||||||
|
export { Root, Background, Foreground } from '../common.styles';
|
||||||
|
|
||||||
|
export const Channel = styled.span`
|
||||||
|
color: ${XTERM_COLORS[6]};
|
||||||
|
font-size: 28px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Streak = styled.span`
|
||||||
|
color: ${XTERM_COLORS[247]};
|
||||||
|
font-size: 16px;
|
||||||
|
`;
|
|
@ -1,8 +1,12 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { parse as mfmParse, toString as mfmUnparse } from 'mfm-js';
|
||||||
|
|
||||||
import { XTERM_COLORS } from '../../../index.style';
|
import XTERM_COLORS from '../../../xterm';
|
||||||
|
|
||||||
import { Wrapper, Author } from './message.style';
|
import { Wrapper, Author, Body, Emote, Attachments } from './message.style';
|
||||||
|
|
||||||
|
import * as mfmElements from './mfm';
|
||||||
|
|
||||||
const stringHashcode = (str) => {
|
const stringHashcode = (str) => {
|
||||||
var hash = 0, i, chr;
|
var hash = 0, i, chr;
|
||||||
|
@ -15,17 +19,62 @@ const stringHashcode = (str) => {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Message({
|
const elForType = {
|
||||||
user_id, user_name, user_type, user_color, text,
|
image: (src) => <img src={src} />,
|
||||||
deemphasize,
|
audio: (src) => <audio src={src} />,
|
||||||
}) {
|
video: (src) => <video src={src} />,
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderMfm = (mfmNode, note) => {
|
||||||
|
const ElForNode = mfmElements[mfmNode.type];
|
||||||
|
|
||||||
|
let node;
|
||||||
|
if (!ElForNode) {
|
||||||
|
const text = mfmUnparse(mfmNode);
|
||||||
|
const TextNode = mfmElements.text;
|
||||||
|
node = <TextNode note={note} text={text} />;
|
||||||
|
} else {
|
||||||
|
const children = mfmNode.children?.map((node) => renderMfm(node, note));
|
||||||
|
node = <ElForNode note={note} {...mfmNode.props} children={children} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Message(note) {
|
||||||
|
const {
|
||||||
|
user_id, user_name, user_type, user_color, text, emotes, attachments, deemphasize,
|
||||||
|
} = note;
|
||||||
|
|
||||||
const fallbackColor = XTERM_COLORS[(stringHashcode(user_id.toString()) % 144) + 88];
|
const fallbackColor = XTERM_COLORS[(stringHashcode(user_id.toString()) % 144) + 88];
|
||||||
|
const displayFiles = useMemo(() => {
|
||||||
|
if (attachments) {
|
||||||
|
const filtered = attachments
|
||||||
|
.map(([type, url]) => [type.split('/')[0], url])
|
||||||
|
.filter(([type, url]) => Object.keys(elForType).includes(type));
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, [attachments]);
|
||||||
|
|
||||||
|
const mfmTree = useMemo(() => mfmParse(text), [text]);
|
||||||
|
const tree = mfmTree.map((node) => renderMfm(node, note));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper type={user_type} color={user_color ?? fallbackColor} deemphasize={deemphasize}>
|
<Wrapper type={user_type} color={user_color ?? fallbackColor} deemphasize={deemphasize}>
|
||||||
<Author>
|
<Author>
|
||||||
[ {user_name} ]
|
[ {user_name} ]
|
||||||
</Author>
|
</Author>
|
||||||
{text}
|
{mfmTree.length !== 0 && (
|
||||||
|
<Body>
|
||||||
|
{tree}
|
||||||
|
</Body>
|
||||||
|
)}
|
||||||
|
{!!displayFiles && (
|
||||||
|
<Attachments>
|
||||||
|
{displayFiles.map(([type, url]) => elForType[type](url))}
|
||||||
|
</Attachments>
|
||||||
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -35,13 +84,20 @@ Message.propTypes = {
|
||||||
user_name: PropTypes.node.isRequired,
|
user_name: PropTypes.node.isRequired,
|
||||||
user_type: PropTypes.string.isRequired,
|
user_type: PropTypes.string.isRequired,
|
||||||
user_color: PropTypes.string,
|
user_color: PropTypes.string,
|
||||||
|
text: PropTypes.node,
|
||||||
|
emotes: PropTypes.shape({
|
||||||
|
[PropTypes.string]: PropTypes.string,
|
||||||
|
}),
|
||||||
deemphasize: PropTypes.bool,
|
deemphasize: PropTypes.bool,
|
||||||
text: PropTypes.node.isRequired,
|
attachments: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Message.defaultProps = {
|
Message.defaultProps = {
|
||||||
|
text: '',
|
||||||
user_color: undefined,
|
user_color: undefined,
|
||||||
|
emotes: {},
|
||||||
deemphasize: false,
|
deemphasize: false,
|
||||||
|
attachments: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Message;
|
export default Message;
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import { toColorString, getContrast, rgbToColorString } from 'polished';
|
import { toColorString, getContrast, rgbToColorString } from 'polished';
|
||||||
import { XTERM_COLORS } from '../../../index.style';
|
import XTERM_COLORS from '../../../xterm';
|
||||||
|
|
||||||
export const Author = styled.div`
|
export const Author = styled.div`
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const Body = styled.span`
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Emote = styled.img`
|
||||||
|
height: 2em;
|
||||||
|
vertical-align: middle;
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
export const normalizeColor = (color) => {
|
export const normalizeColor = (color) => {
|
||||||
if (color === null) {
|
if (color === null) {
|
||||||
return 'inherit';
|
return 'inherit';
|
||||||
|
@ -45,8 +54,6 @@ const setColors = ({ type, color, deemphasize }) => {
|
||||||
// console.log(contrasts);
|
// console.log(contrasts);
|
||||||
|
|
||||||
return css`
|
return css`
|
||||||
font-family: 'Source Code Pro', monospace;
|
|
||||||
font-size: 18px;
|
|
||||||
color: ${palette.text_fg};
|
color: ${palette.text_fg};
|
||||||
background-color: ${palette.text_bg};
|
background-color: ${palette.text_bg};
|
||||||
${Author} {
|
${Author} {
|
||||||
|
@ -62,19 +69,20 @@ export const Wrapper = styled.div`
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
|
`;
|
||||||
@keyframes dissapear {
|
|
||||||
0% {
|
export const Attachments = styled.div`
|
||||||
opacity: 1;
|
display: flex;
|
||||||
}
|
flex-direction: row;
|
||||||
15% {
|
flex-wrap: wrap;
|
||||||
opacity: 1;
|
gap: 8px 6px;
|
||||||
}
|
padding: 8px;
|
||||||
100% {
|
|
||||||
opacity: 0;
|
img {
|
||||||
}
|
flex: 1;
|
||||||
}
|
min-width: 33%;
|
||||||
|
max-width: 100%;
|
||||||
animation: 160s dissapear linear;
|
max-height: 300px;
|
||||||
animation-fill-mode: forwards;
|
object-fit: scale-down;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Embolden = styled.span`
|
||||||
|
font-weight: bold;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const BoldText = ({ children }) => (
|
||||||
|
<Embolden>{children}</Embolden>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default BoldText;
|
|
@ -0,0 +1,36 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Text from './text';
|
||||||
|
|
||||||
|
const Emote = styled.img`
|
||||||
|
height: 2em;
|
||||||
|
vertical-align: middle;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const EmojiCode = ({
|
||||||
|
note, name,
|
||||||
|
}) => {
|
||||||
|
if (note.emotes?.[name]) {
|
||||||
|
return (
|
||||||
|
<Emote src={note.emotes[name]} title={name} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Text text={`:${name}:`} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
EmojiCode.propTypes = {
|
||||||
|
note: PropTypes.shape({
|
||||||
|
emotes: PropTypes.shape({
|
||||||
|
[PropTypes.string]: PropTypes.string,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
EmojiCode.defaultProps = {
|
||||||
|
note: { emotes: {} },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EmojiCode;
|
|
@ -0,0 +1,178 @@
|
||||||
|
import styled, { css, keyframes } from 'styled-components';
|
||||||
|
|
||||||
|
const tada = keyframes`
|
||||||
|
from {
|
||||||
|
transform: scale3d(1, 1, 1);
|
||||||
|
}
|
||||||
|
10%, 20% {
|
||||||
|
transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
|
||||||
|
}
|
||||||
|
30%, 50%, 70%, 90% {
|
||||||
|
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
|
||||||
|
}
|
||||||
|
40%, 60%, 80% {
|
||||||
|
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: scale3d(1, 1, 1);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const spin = keyframes`
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
`;
|
||||||
|
const spinX = keyframes`
|
||||||
|
0% { transform: perspective(128px) rotateX(0deg); }
|
||||||
|
100% { transform: perspective(128px) rotateX(360deg); }
|
||||||
|
`;
|
||||||
|
const spinY = keyframes`
|
||||||
|
0% { transform: perspective(128px) rotateY(0deg); }
|
||||||
|
100% { transform: perspective(128px) rotateY(360deg); }
|
||||||
|
`;
|
||||||
|
const jump = keyframes`
|
||||||
|
0% { transform: translateY(0); }
|
||||||
|
25% { transform: translateY(-16px); }
|
||||||
|
50% { transform: translateY(0); }
|
||||||
|
75% { transform: translateY(-8px); }
|
||||||
|
100% { transform: translateY(0); }
|
||||||
|
`;
|
||||||
|
const bounce = keyframes`
|
||||||
|
0% { transform: translateY(0) scale(1, 1); }
|
||||||
|
25% { transform: translateY(-16px) scale(1, 1); }
|
||||||
|
50% { transform: translateY(0) scale(1, 1); }
|
||||||
|
75% { transform: translateY(0) scale(1.5, 0.75); }
|
||||||
|
100% { transform: translateY(0) scale(1, 1); }
|
||||||
|
`;
|
||||||
|
const twitch = keyframes`
|
||||||
|
0% { transform: translate(7px, -2px) }
|
||||||
|
5% { transform: translate(-3px, 1px) }
|
||||||
|
10% { transform: translate(-7px, -1px) }
|
||||||
|
15% { transform: translate(0px, -1px) }
|
||||||
|
20% { transform: translate(-8px, 6px) }
|
||||||
|
25% { transform: translate(-4px, -3px) }
|
||||||
|
30% { transform: translate(-4px, -6px) }
|
||||||
|
35% { transform: translate(-8px, -8px) }
|
||||||
|
40% { transform: translate(4px, 6px) }
|
||||||
|
45% { transform: translate(-3px, 1px) }
|
||||||
|
50% { transform: translate(2px, -10px) }
|
||||||
|
55% { transform: translate(-7px, 0px) }
|
||||||
|
60% { transform: translate(-2px, 4px) }
|
||||||
|
65% { transform: translate(3px, -8px) }
|
||||||
|
70% { transform: translate(6px, 7px) }
|
||||||
|
75% { transform: translate(-7px, -2px) }
|
||||||
|
80% { transform: translate(-7px, -8px) }
|
||||||
|
85% { transform: translate(9px, 3px) }
|
||||||
|
90% { transform: translate(-3px, -2px) }
|
||||||
|
95% { transform: translate(-10px, 2px) }
|
||||||
|
100% { transform: translate(-2px, -6px) }
|
||||||
|
`;
|
||||||
|
const shake = keyframes`
|
||||||
|
0% { transform: translate(-3px, -1px) rotate(-8deg) }
|
||||||
|
5% { transform: translate(0px, -1px) rotate(-10deg) }
|
||||||
|
10% { transform: translate(1px, -3px) rotate(0deg) }
|
||||||
|
15% { transform: translate(1px, 1px) rotate(11deg) }
|
||||||
|
20% { transform: translate(-2px, 1px) rotate(1deg) }
|
||||||
|
25% { transform: translate(-1px, -2px) rotate(-2deg) }
|
||||||
|
30% { transform: translate(-1px, 2px) rotate(-3deg) }
|
||||||
|
35% { transform: translate(2px, 1px) rotate(6deg) }
|
||||||
|
40% { transform: translate(-2px, -3px) rotate(-9deg) }
|
||||||
|
45% { transform: translate(0px, -1px) rotate(-12deg) }
|
||||||
|
50% { transform: translate(1px, 2px) rotate(10deg) }
|
||||||
|
55% { transform: translate(0px, -3px) rotate(8deg) }
|
||||||
|
60% { transform: translate(1px, -1px) rotate(8deg) }
|
||||||
|
65% { transform: translate(0px, -1px) rotate(-7deg) }
|
||||||
|
70% { transform: translate(-1px, -3px) rotate(6deg) }
|
||||||
|
75% { transform: translate(0px, -2px) rotate(4deg) }
|
||||||
|
80% { transform: translate(-2px, -1px) rotate(3deg) }
|
||||||
|
85% { transform: translate(1px, -3px) rotate(-10deg) }
|
||||||
|
90% { transform: translate(1px, 0px) rotate(3deg) }
|
||||||
|
95% { transform: translate(-2px, 0px) rotate(-3deg) }
|
||||||
|
100% { transform: translate(2px, 1px) rotate(2deg) }
|
||||||
|
`;
|
||||||
|
const rubberBand = keyframes`
|
||||||
|
from { transform: scale3d(1, 1, 1); }
|
||||||
|
30% { transform: scale3d(1.25, 0.75, 1); }
|
||||||
|
40% { transform: scale3d(0.75, 1.25, 1); }
|
||||||
|
50% { transform: scale3d(1.15, 0.85, 1); }
|
||||||
|
65% { transform: scale3d(0.95, 1.05, 1); }
|
||||||
|
75% { transform: scale3d(1.05, 0.95, 1); }
|
||||||
|
to { transform: scale3d(1, 1, 1); }
|
||||||
|
`;
|
||||||
|
const rainbow = keyframes`
|
||||||
|
0% { filter: hue-rotate(0deg) contrast(150%) saturate(150%); }
|
||||||
|
100% { filter: hue-rotate(360deg) contrast(150%) saturate(150%); }
|
||||||
|
`;
|
||||||
|
|
||||||
|
const validTime = (t, d = null) => {
|
||||||
|
if (t == null) return d;
|
||||||
|
return t.match(/^[0-9.]+s$/) ? t : d;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: font, sparkle
|
||||||
|
const mfmFnStyles = {
|
||||||
|
tada: css`
|
||||||
|
font-size: 150%;
|
||||||
|
animation: ${tada} 1s linear infinite both;
|
||||||
|
`,
|
||||||
|
jelly: css`animation: ${rubberBand} ${(props) => validTime(props.speed, '1s')} linear infinite both;`,
|
||||||
|
twitch: css`animation: ${twitch} ${(props) => validTime(props.speed, '0.5s')} ease infinite;`,
|
||||||
|
shake: css`animation: ${shake} ${(props) => validTime(props.speed, '0.5s')} ease infinite;`,
|
||||||
|
spin: (props) => {
|
||||||
|
let direction;
|
||||||
|
if (props.left) direction = 'reverse'
|
||||||
|
else if (props.alternate) direction = 'alternate'
|
||||||
|
else direction = 'normal';
|
||||||
|
|
||||||
|
let anime;
|
||||||
|
if (props.x) anime = spinX
|
||||||
|
else if (props.y) anime = spinY
|
||||||
|
else anime = spin;
|
||||||
|
|
||||||
|
return css`
|
||||||
|
animation: ${anime} ${(props) => validTime(props.speed, '1.5s')} linear infinite;
|
||||||
|
animation-direction: ${direction};
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
jump: css`animation: ${jump} 0.75s linear infinite;`,
|
||||||
|
bounce: css`
|
||||||
|
animation: ${bounce} 0.75s linear infinite;
|
||||||
|
transform-origin: center bottom;
|
||||||
|
`,
|
||||||
|
flip: (props) => {
|
||||||
|
let transRights;
|
||||||
|
if (props.h && props.v) transRights = 'scale(-1, -1)';
|
||||||
|
else if (props.v) transRights = 'scaleY(-1)';
|
||||||
|
else transRights = 'scaleX(-1)';
|
||||||
|
|
||||||
|
return css`
|
||||||
|
transform: ${transRights};
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
x2: css`font-size: 200%;`,
|
||||||
|
x3: css`font-size: 400%;`,
|
||||||
|
x4: css`font-size: 600%;`,
|
||||||
|
rainbow: css`
|
||||||
|
color: #f42069;
|
||||||
|
animation: ${rainbow} 1s linear infinite;`,
|
||||||
|
rotate: css`
|
||||||
|
transform: rotate(${(props) => parseInt(props.deg) || '90'}deg);
|
||||||
|
transform-origin: center center;
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MfmFnRunner = styled.span`
|
||||||
|
> span {
|
||||||
|
display: inline-block;
|
||||||
|
${(props) => mfmFnStyles[props.mfmFn]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MfmFunction = ({ children, name, args }) => (
|
||||||
|
<MfmFnRunner mfmFn={name} {...args}>
|
||||||
|
<span>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
</MfmFnRunner>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default MfmFunction;
|
|
@ -0,0 +1,7 @@
|
||||||
|
export { default as emojiCode } from './emojiCode';
|
||||||
|
export { default as italic } from './italic';
|
||||||
|
export { default as bold } from './bold';
|
||||||
|
export { default as fn } from './fn';
|
||||||
|
export { default as unicodeEmoji } from './unicodeEmoji';
|
||||||
|
export { default as url } from './url';
|
||||||
|
export { default as text } from './text';
|
|
@ -0,0 +1,11 @@
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Italic = styled.span`
|
||||||
|
font-style: italic;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ItalicText = ({ children }) => (
|
||||||
|
<Italic>{children}</Italic>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ItalicText;
|
|
@ -0,0 +1,5 @@
|
||||||
|
const Text = ({ text }) => (
|
||||||
|
<span>{text}</span>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Text;
|
|
@ -0,0 +1,5 @@
|
||||||
|
const UnicodeEmoji = ({ emoji }) => (
|
||||||
|
<span>{emoji}</span>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default UnicodeEmoji;
|
|
@ -0,0 +1,5 @@
|
||||||
|
const Url = ({ url }) => (
|
||||||
|
<a>{url}</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Url;
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* Copyright 2018 Ross Zurowski
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
*/
|
||||||
|
// via https://github.com/rosszurowski/react-responsive-canvas/blob/master/src/get-size.js
|
||||||
|
|
||||||
|
const parseNumber = prop => parseFloat(prop) || 0;
|
||||||
|
|
||||||
|
const getSize = (el: Element) => {
|
||||||
|
if (el === window || el === document.body) {
|
||||||
|
return [window.innerWidth, window.innerHeight];
|
||||||
|
}
|
||||||
|
|
||||||
|
let temporary = false;
|
||||||
|
|
||||||
|
if (!el.parentNode && document.body) {
|
||||||
|
temporary = true;
|
||||||
|
document.body.appendChild(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
const styles = getComputedStyle(el);
|
||||||
|
const height =
|
||||||
|
(rect.height | 0) +
|
||||||
|
parseNumber(styles.getPropertyValue('margin-top')) +
|
||||||
|
parseNumber(styles.getPropertyValue('margin-bottom'));
|
||||||
|
const width =
|
||||||
|
(rect.width | 0) +
|
||||||
|
parseNumber(styles.getPropertyValue('margin-left')) +
|
||||||
|
parseNumber(styles.getPropertyValue('margin-right'));
|
||||||
|
|
||||||
|
if (temporary && document.body) {
|
||||||
|
document.body.removeChild(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [width, height];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getSize;
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './responsive-canvas';
|
|
@ -0,0 +1,56 @@
|
||||||
|
import React, {
|
||||||
|
useEffect, useState, useCallback, useRef, useImperativeHandle, forwardRef,
|
||||||
|
} from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import getSize from './get-size';
|
||||||
|
|
||||||
|
const ResponsiveCanvas = forwardRef(({ scale, onResize }, ref) => {
|
||||||
|
const [width, setWidth] = useState(null);
|
||||||
|
const [height, setHeight] = useState(null);
|
||||||
|
const canvasRef = useRef();
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => canvasRef.current);
|
||||||
|
|
||||||
|
const handleResize = useCallback(() => {
|
||||||
|
const parent = canvasRef.current.parentElement;
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const [width, height] = getSize(parent);
|
||||||
|
setWidth(width);
|
||||||
|
setHeight(height);
|
||||||
|
}, [canvasRef]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('resize', handleResize, false);
|
||||||
|
handleResize();
|
||||||
|
return () => window.removeEventListener('resize', handleResize, false);
|
||||||
|
}, [handleResize]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (onResize && width !== null && height !== null) onResize();
|
||||||
|
}, [width, height, onResize]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<canvas
|
||||||
|
ref={canvasRef}
|
||||||
|
width={width * scale}
|
||||||
|
height={height * scale}
|
||||||
|
style={{ width, height }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ResponsiveCanvas.propTypes = {
|
||||||
|
onResize: PropTypes.func,
|
||||||
|
scale: PropTypes.number,
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultScale = typeof window !== 'undefined' ? window.devicePixelRatio : 1;
|
||||||
|
ResponsiveCanvas.defaultProps = {
|
||||||
|
onResize: undefined,
|
||||||
|
scale: defaultScale,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResponsiveCanvas;
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
export { default as useQuery } from './useQuery';
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
export default function useQuery() {
|
||||||
|
return new URLSearchParams(useLocation().search);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import App from './components/app/app';
|
import App from './components/app/app';
|
||||||
|
|
||||||
import { GlobalStyle } from './index.style';
|
import { GlobalStyle } from './index.style';
|
||||||
|
@ -7,7 +8,9 @@ import { GlobalStyle } from './index.style';
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
<App />
|
<BrowserRouter>
|
||||||
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import css, { createGlobalStyle } from 'styled-components';
|
import css, { createGlobalStyle } from 'styled-components';
|
||||||
import { normalize, rgb } from 'polished';
|
import { normalize, rgb } from 'polished';
|
||||||
|
|
||||||
import scpRegular from './fonts/SourceCodePro-Regular.ttf';
|
import scpRegular from './fonts/SourceCodePro-Regular.woff2';
|
||||||
import scpLight from './fonts/SourceCodePro-Light.ttf';
|
import scpLight from './fonts/SourceCodePro-Light.woff2';
|
||||||
import scpBold from './fonts/SourceCodePro-Bold.ttf';
|
import scpBold from './fonts/SourceCodePro-Bold.woff2';
|
||||||
import scpItalic from './fonts/SourceCodePro-Italic.ttf';
|
import scpItalic from './fonts/SourceCodePro-Italic.woff2';
|
||||||
import scpLightItalic from './fonts/SourceCodePro-LightItalic.ttf';
|
import scpLightItalic from './fonts/SourceCodePro-LightItalic.woff2';
|
||||||
import scpBoldItalic from './fonts/SourceCodePro-BoldItalic.ttf';
|
import scpBoldItalic from './fonts/SourceCodePro-BoldItalic.woff2';
|
||||||
|
|
||||||
export const GlobalStyle = createGlobalStyle`
|
export const GlobalStyle = createGlobalStyle`
|
||||||
${normalize()};
|
${normalize()};
|
||||||
|
@ -14,35 +14,35 @@ export const GlobalStyle = createGlobalStyle`
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
src: url(${scpRegular}) format("truetype");
|
src: url(${scpRegular}) format("woff2");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
src: url(${scpLight}) format("truetype");
|
src: url(${scpLight}) format("woff2");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
src: url(${scpBold}) format("truetype");
|
src: url(${scpBold}) format("woff2");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
src: url(${scpItalic}) format("truetype");
|
src: url(${scpItalic}) format("woff2");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
src: url(${scpLightItalic}) format("truetype");
|
src: url(${scpLightItalic}) format("woff2");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Source Code Pro";
|
font-family: "Source Code Pro";
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
src: url(${scpBoldItalic}) format("truetype");
|
src: url(${scpBoldItalic}) format("woff2");
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@ -62,262 +62,3 @@ export const GlobalStyle = createGlobalStyle`
|
||||||
overflow: none;
|
overflow: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const XTERM_COLORS = [
|
|
||||||
rgb(0, 0, 0), // #000000
|
|
||||||
rgb(128, 0, 0), // #800000
|
|
||||||
rgb(0, 128, 0), // #008000
|
|
||||||
rgb(128, 128, 0), // #808000
|
|
||||||
rgb(0, 0, 128), // #000080
|
|
||||||
rgb(128, 0, 128), // #800080
|
|
||||||
rgb(0, 128, 128), // #008080
|
|
||||||
rgb(192, 192, 192), // #c0c0c0
|
|
||||||
rgb(128, 128, 128), // #808080
|
|
||||||
rgb(255, 0, 0), // #ff0000
|
|
||||||
rgb(0, 255, 0), // #00ff00
|
|
||||||
rgb(255, 255, 0), // #ffff00
|
|
||||||
rgb(0, 0, 255), // #0000ff
|
|
||||||
rgb(255, 0, 255), // #ff00ff
|
|
||||||
rgb(0, 255, 255), // #00ffff
|
|
||||||
rgb(255, 255, 255), // #ffffff
|
|
||||||
rgb(0, 0, 0), // #000000
|
|
||||||
rgb(0, 0, 95), // #00005f
|
|
||||||
rgb(0, 0, 135), // #000087
|
|
||||||
rgb(0, 0, 175), // #0000af
|
|
||||||
rgb(0, 0, 215), // #0000d7
|
|
||||||
rgb(0, 0, 255), // #0000ff
|
|
||||||
rgb(0, 95, 0), // #005f00
|
|
||||||
rgb(0, 95, 95), // #005f5f
|
|
||||||
rgb(0, 95, 135), // #005f87
|
|
||||||
rgb(0, 95, 175), // #005faf
|
|
||||||
rgb(0, 95, 215), // #005fd7
|
|
||||||
rgb(0, 95, 255), // #005fff
|
|
||||||
rgb(0, 135, 0), // #008700
|
|
||||||
rgb(0, 135, 95), // #00875f
|
|
||||||
rgb(0, 135, 135), // #008787
|
|
||||||
rgb(0, 135, 175), // #0087af
|
|
||||||
rgb(0, 135, 215), // #0087d7
|
|
||||||
rgb(0, 135, 255), // #0087ff
|
|
||||||
rgb(0, 175, 0), // #00af00
|
|
||||||
rgb(0, 175, 95), // #00af5f
|
|
||||||
rgb(0, 175, 135), // #00af87
|
|
||||||
rgb(0, 175, 175), // #00afaf
|
|
||||||
rgb(0, 175, 215), // #00afd7
|
|
||||||
rgb(0, 175, 255), // #00afff
|
|
||||||
rgb(0, 215, 0), // #00d700
|
|
||||||
rgb(0, 215, 95), // #00d75f
|
|
||||||
rgb(0, 215, 135), // #00d787
|
|
||||||
rgb(0, 215, 175), // #00d7af
|
|
||||||
rgb(0, 215, 215), // #00d7d7
|
|
||||||
rgb(0, 215, 255), // #00d7ff
|
|
||||||
rgb(0, 255, 0), // #00ff00
|
|
||||||
rgb(0, 255, 95), // #00ff5f
|
|
||||||
rgb(0, 255, 135), // #00ff87
|
|
||||||
rgb(0, 255, 175), // #00ffaf
|
|
||||||
rgb(0, 255, 215), // #00ffd7
|
|
||||||
rgb(0, 255, 255), // #00ffff
|
|
||||||
rgb(95, 0, 0), // #5f0000
|
|
||||||
rgb(95, 0, 95), // #5f005f
|
|
||||||
rgb(95, 0, 135), // #5f0087
|
|
||||||
rgb(95, 0, 175), // #5f00af
|
|
||||||
rgb(95, 0, 215), // #5f00d7
|
|
||||||
rgb(95, 0, 255), // #5f00ff
|
|
||||||
rgb(95, 95, 0), // #5f5f00
|
|
||||||
rgb(95, 95, 95), // #5f5f5f
|
|
||||||
rgb(95, 95, 135), // #5f5f87
|
|
||||||
rgb(95, 95, 175), // #5f5faf
|
|
||||||
rgb(95, 95, 215), // #5f5fd7
|
|
||||||
rgb(95, 95, 255), // #5f5fff
|
|
||||||
rgb(95, 135, 0), // #5f8700
|
|
||||||
rgb(95, 135, 95), // #5f875f
|
|
||||||
rgb(95, 135, 135), // #5f8787
|
|
||||||
rgb(95, 135, 175), // #5f87af
|
|
||||||
rgb(95, 135, 215), // #5f87d7
|
|
||||||
rgb(95, 135, 255), // #5f87ff
|
|
||||||
rgb(95, 175, 0), // #5faf00
|
|
||||||
rgb(95, 175, 95), // #5faf5f
|
|
||||||
rgb(95, 175, 135), // #5faf87
|
|
||||||
rgb(95, 175, 175), // #5fafaf
|
|
||||||
rgb(95, 175, 215), // #5fafd7
|
|
||||||
rgb(95, 175, 255), // #5fafff
|
|
||||||
rgb(95, 215, 0), // #5fd700
|
|
||||||
rgb(95, 215, 95), // #5fd75f
|
|
||||||
rgb(95, 215, 135), // #5fd787
|
|
||||||
rgb(95, 215, 175), // #5fd7af
|
|
||||||
rgb(95, 215, 215), // #5fd7d7
|
|
||||||
rgb(95, 215, 255), // #5fd7ff
|
|
||||||
rgb(95, 255, 0), // #5fff00
|
|
||||||
rgb(95, 255, 95), // #5fff5f
|
|
||||||
rgb(95, 255, 135), // #5fff87
|
|
||||||
rgb(95, 255, 175), // #5fffaf
|
|
||||||
rgb(95, 255, 215), // #5fffd7
|
|
||||||
rgb(95, 255, 255), // #5fffff
|
|
||||||
rgb(135, 0, 0), // #870000
|
|
||||||
rgb(135, 0, 95), // #87005f
|
|
||||||
rgb(135, 0, 135), // #870087
|
|
||||||
rgb(135, 0, 175), // #8700af
|
|
||||||
rgb(135, 0, 215), // #8700d7
|
|
||||||
rgb(135, 0, 255), // #8700ff
|
|
||||||
rgb(135, 95, 0), // #875f00
|
|
||||||
rgb(135, 95, 95), // #875f5f
|
|
||||||
rgb(135, 95, 135), // #875f87
|
|
||||||
rgb(135, 95, 175), // #875faf
|
|
||||||
rgb(135, 95, 215), // #875fd7
|
|
||||||
rgb(135, 95, 255), // #875fff
|
|
||||||
rgb(135, 135, 0), // #878700
|
|
||||||
rgb(135, 135, 95), // #87875f
|
|
||||||
rgb(135, 135, 135), // #878787
|
|
||||||
rgb(135, 135, 175), // #8787af
|
|
||||||
rgb(135, 135, 215), // #8787d7
|
|
||||||
rgb(135, 135, 255), // #8787ff
|
|
||||||
rgb(135, 175, 0), // #87af00
|
|
||||||
rgb(135, 175, 95), // #87af5f
|
|
||||||
rgb(135, 175, 135), // #87af87
|
|
||||||
rgb(135, 175, 175), // #87afaf
|
|
||||||
rgb(135, 175, 215), // #87afd7
|
|
||||||
rgb(135, 175, 255), // #87afff
|
|
||||||
rgb(135, 215, 0), // #87d700
|
|
||||||
rgb(135, 215, 95), // #87d75f
|
|
||||||
rgb(135, 215, 135), // #87d787
|
|
||||||
rgb(135, 215, 175), // #87d7af
|
|
||||||
rgb(135, 215, 215), // #87d7d7
|
|
||||||
rgb(135, 215, 255), // #87d7ff
|
|
||||||
rgb(135, 255, 0), // #87ff00
|
|
||||||
rgb(135, 255, 95), // #87ff5f
|
|
||||||
rgb(135, 255, 135), // #87ff87
|
|
||||||
rgb(135, 255, 175), // #87ffaf
|
|
||||||
rgb(135, 255, 215), // #87ffd7
|
|
||||||
rgb(135, 255, 255), // #87ffff
|
|
||||||
rgb(175, 0, 0), // #af0000
|
|
||||||
rgb(175, 0, 95), // #af005f
|
|
||||||
rgb(175, 0, 135), // #af0087
|
|
||||||
rgb(175, 0, 175), // #af00af
|
|
||||||
rgb(175, 0, 215), // #af00d7
|
|
||||||
rgb(175, 0, 255), // #af00ff
|
|
||||||
rgb(175, 95, 0), // #af5f00
|
|
||||||
rgb(175, 95, 95), // #af5f5f
|
|
||||||
rgb(175, 95, 135), // #af5f87
|
|
||||||
rgb(175, 95, 175), // #af5faf
|
|
||||||
rgb(175, 95, 215), // #af5fd7
|
|
||||||
rgb(175, 95, 255), // #af5fff
|
|
||||||
rgb(175, 135, 0), // #af8700
|
|
||||||
rgb(175, 135, 95), // #af875f
|
|
||||||
rgb(175, 135, 135), // #af8787
|
|
||||||
rgb(175, 135, 175), // #af87af
|
|
||||||
rgb(175, 135, 215), // #af87d7
|
|
||||||
rgb(175, 135, 255), // #af87ff
|
|
||||||
rgb(175, 175, 0), // #afaf00
|
|
||||||
rgb(175, 175, 95), // #afaf5f
|
|
||||||
rgb(175, 175, 135), // #afaf87
|
|
||||||
rgb(175, 175, 175), // #afafaf
|
|
||||||
rgb(175, 175, 215), // #afafd7
|
|
||||||
rgb(175, 175, 255), // #afafff
|
|
||||||
rgb(175, 215, 0), // #afd700
|
|
||||||
rgb(175, 215, 95), // #afd75f
|
|
||||||
rgb(175, 215, 135), // #afd787
|
|
||||||
rgb(175, 215, 175), // #afd7af
|
|
||||||
rgb(175, 215, 215), // #afd7d7
|
|
||||||
rgb(175, 215, 255), // #afd7ff
|
|
||||||
rgb(175, 255, 0), // #afff00
|
|
||||||
rgb(175, 255, 95), // #afff5f
|
|
||||||
rgb(175, 255, 135), // #afff87
|
|
||||||
rgb(175, 255, 175), // #afffaf
|
|
||||||
rgb(175, 255, 215), // #afffd7
|
|
||||||
rgb(175, 255, 255), // #afffff
|
|
||||||
rgb(215, 0, 0), // #d70000
|
|
||||||
rgb(215, 0, 95), // #d7005f
|
|
||||||
rgb(215, 0, 135), // #d70087
|
|
||||||
rgb(215, 0, 175), // #d700af
|
|
||||||
rgb(215, 0, 215), // #d700d7
|
|
||||||
rgb(215, 0, 255), // #d700ff
|
|
||||||
rgb(215, 95, 0), // #d75f00
|
|
||||||
rgb(215, 95, 95), // #d75f5f
|
|
||||||
rgb(215, 95, 135), // #d75f87
|
|
||||||
rgb(215, 95, 175), // #d75faf
|
|
||||||
rgb(215, 95, 215), // #d75fd7
|
|
||||||
rgb(215, 95, 255), // #d75fff
|
|
||||||
rgb(215, 135, 0), // #d78700
|
|
||||||
rgb(215, 135, 95), // #d7875f
|
|
||||||
rgb(215, 135, 135), // #d78787
|
|
||||||
rgb(215, 135, 175), // #d787af
|
|
||||||
rgb(215, 135, 215), // #d787d7
|
|
||||||
rgb(215, 135, 255), // #d787ff
|
|
||||||
rgb(215, 175, 0), // #d7af00
|
|
||||||
rgb(215, 175, 95), // #d7af5f
|
|
||||||
rgb(215, 175, 135), // #d7af87
|
|
||||||
rgb(215, 175, 175), // #d7afaf
|
|
||||||
rgb(215, 175, 215), // #d7afd7
|
|
||||||
rgb(215, 175, 255), // #d7afff
|
|
||||||
rgb(215, 215, 0), // #d7d700
|
|
||||||
rgb(215, 215, 95), // #d7d75f
|
|
||||||
rgb(215, 215, 135), // #d7d787
|
|
||||||
rgb(215, 215, 175), // #d7d7af
|
|
||||||
rgb(215, 215, 215), // #d7d7d7
|
|
||||||
rgb(215, 215, 255), // #d7d7ff
|
|
||||||
rgb(215, 255, 0), // #d7ff00
|
|
||||||
rgb(215, 255, 95), // #d7ff5f
|
|
||||||
rgb(215, 255, 135), // #d7ff87
|
|
||||||
rgb(215, 255, 175), // #d7ffaf
|
|
||||||
rgb(215, 255, 215), // #d7ffd7
|
|
||||||
rgb(215, 255, 255), // #d7ffff
|
|
||||||
rgb(255, 0, 0), // #ff0000
|
|
||||||
rgb(255, 0, 95), // #ff005f
|
|
||||||
rgb(255, 0, 135), // #ff0087
|
|
||||||
rgb(255, 0, 175), // #ff00af
|
|
||||||
rgb(255, 0, 215), // #ff00d7
|
|
||||||
rgb(255, 0, 255), // #ff00ff
|
|
||||||
rgb(255, 95, 0), // #ff5f00
|
|
||||||
rgb(255, 95, 95), // #ff5f5f
|
|
||||||
rgb(255, 95, 135), // #ff5f87
|
|
||||||
rgb(255, 95, 175), // #ff5faf
|
|
||||||
rgb(255, 95, 215), // #ff5fd7
|
|
||||||
rgb(255, 95, 255), // #ff5fff
|
|
||||||
rgb(255, 135, 0), // #ff8700
|
|
||||||
rgb(255, 135, 95), // #ff875f
|
|
||||||
rgb(255, 135, 135), // #ff8787
|
|
||||||
rgb(255, 135, 175), // #ff87af
|
|
||||||
rgb(255, 135, 215), // #ff87d7
|
|
||||||
rgb(255, 135, 255), // #ff87ff
|
|
||||||
rgb(255, 175, 0), // #ffaf00
|
|
||||||
rgb(255, 175, 95), // #ffaf5f
|
|
||||||
rgb(255, 175, 135), // #ffaf87
|
|
||||||
rgb(255, 175, 175), // #ffafaf
|
|
||||||
rgb(255, 175, 215), // #ffafd7
|
|
||||||
rgb(255, 175, 255), // #ffafff
|
|
||||||
rgb(255, 215, 0), // #ffd700
|
|
||||||
rgb(255, 215, 95), // #ffd75f
|
|
||||||
rgb(255, 215, 135), // #ffd787
|
|
||||||
rgb(255, 215, 175), // #ffd7af
|
|
||||||
rgb(255, 215, 215), // #ffd7d7
|
|
||||||
rgb(255, 215, 255), // #ffd7ff
|
|
||||||
rgb(255, 255, 0), // #ffff00
|
|
||||||
rgb(255, 255, 95), // #ffff5f
|
|
||||||
rgb(255, 255, 135), // #ffff87
|
|
||||||
rgb(255, 255, 175), // #ffffaf
|
|
||||||
rgb(255, 255, 215), // #ffffd7
|
|
||||||
rgb(255, 255, 255), // #ffffff
|
|
||||||
rgb(8, 8, 8), // #080808
|
|
||||||
rgb(18, 18, 18), // #121212
|
|
||||||
rgb(28, 28, 28), // #1c1c1c
|
|
||||||
rgb(38, 38, 38), // #262626
|
|
||||||
rgb(48, 48, 48), // #303030
|
|
||||||
rgb(58, 58, 58), // #3a3a3a
|
|
||||||
rgb(68, 68, 68), // #444444
|
|
||||||
rgb(78, 78, 78), // #4e4e4e
|
|
||||||
rgb(88, 88, 88), // #585858
|
|
||||||
rgb(98, 98, 98), // #626262
|
|
||||||
rgb(108, 108, 108), // #6c6c6c
|
|
||||||
rgb(118, 118, 118), // #767676
|
|
||||||
rgb(128, 128, 128), // #808080
|
|
||||||
rgb(138, 138, 138), // #8a8a8a
|
|
||||||
rgb(148, 148, 148), // #949494
|
|
||||||
rgb(158, 158, 158), // #9e9e9e
|
|
||||||
rgb(168, 168, 168), // #a8a8a8
|
|
||||||
rgb(178, 178, 178), // #b2b2b2
|
|
||||||
rgb(188, 188, 188), // #bcbcbc
|
|
||||||
rgb(198, 198, 198), // #c6c6c6
|
|
||||||
rgb(208, 208, 208), // #d0d0d0
|
|
||||||
rgb(218, 218, 218), // #dadada
|
|
||||||
rgb(228, 228, 228), // #e4e4e4
|
|
||||||
rgb(238, 238, 238), // #eeeeee
|
|
||||||
];
|
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
import { rgb } from 'polished'; export default [ rgb(0, 0, 0), // #000000
|
||||||
|
rgb(128, 0, 0), // #800000
|
||||||
|
rgb(0, 128, 0), // #008000
|
||||||
|
rgb(128, 128, 0), // #808000
|
||||||
|
rgb(0, 0, 128), // #000080
|
||||||
|
rgb(128, 0, 128), // #800080
|
||||||
|
rgb(0, 128, 128), // #008080
|
||||||
|
rgb(192, 192, 192), // #c0c0c0
|
||||||
|
rgb(128, 128, 128), // #808080
|
||||||
|
rgb(255, 0, 0), // #ff0000
|
||||||
|
rgb(0, 255, 0), // #00ff00
|
||||||
|
rgb(255, 255, 0), // #ffff00
|
||||||
|
rgb(0, 0, 255), // #0000ff
|
||||||
|
rgb(255, 0, 255), // #ff00ff
|
||||||
|
rgb(0, 255, 255), // #00ffff
|
||||||
|
rgb(255, 255, 255), // #ffffff
|
||||||
|
rgb(0, 0, 0), // #000000
|
||||||
|
rgb(0, 0, 95), // #00005f
|
||||||
|
rgb(0, 0, 135), // #000087
|
||||||
|
rgb(0, 0, 175), // #0000af
|
||||||
|
rgb(0, 0, 215), // #0000d7
|
||||||
|
rgb(0, 0, 255), // #0000ff
|
||||||
|
rgb(0, 95, 0), // #005f00
|
||||||
|
rgb(0, 95, 95), // #005f5f
|
||||||
|
rgb(0, 95, 135), // #005f87
|
||||||
|
rgb(0, 95, 175), // #005faf
|
||||||
|
rgb(0, 95, 215), // #005fd7
|
||||||
|
rgb(0, 95, 255), // #005fff
|
||||||
|
rgb(0, 135, 0), // #008700
|
||||||
|
rgb(0, 135, 95), // #00875f
|
||||||
|
rgb(0, 135, 135), // #008787
|
||||||
|
rgb(0, 135, 175), // #0087af
|
||||||
|
rgb(0, 135, 215), // #0087d7
|
||||||
|
rgb(0, 135, 255), // #0087ff
|
||||||
|
rgb(0, 175, 0), // #00af00
|
||||||
|
rgb(0, 175, 95), // #00af5f
|
||||||
|
rgb(0, 175, 135), // #00af87
|
||||||
|
rgb(0, 175, 175), // #00afaf
|
||||||
|
rgb(0, 175, 215), // #00afd7
|
||||||
|
rgb(0, 175, 255), // #00afff
|
||||||
|
rgb(0, 215, 0), // #00d700
|
||||||
|
rgb(0, 215, 95), // #00d75f
|
||||||
|
rgb(0, 215, 135), // #00d787
|
||||||
|
rgb(0, 215, 175), // #00d7af
|
||||||
|
rgb(0, 215, 215), // #00d7d7
|
||||||
|
rgb(0, 215, 255), // #00d7ff
|
||||||
|
rgb(0, 255, 0), // #00ff00
|
||||||
|
rgb(0, 255, 95), // #00ff5f
|
||||||
|
rgb(0, 255, 135), // #00ff87
|
||||||
|
rgb(0, 255, 175), // #00ffaf
|
||||||
|
rgb(0, 255, 215), // #00ffd7
|
||||||
|
rgb(0, 255, 255), // #00ffff
|
||||||
|
rgb(95, 0, 0), // #5f0000
|
||||||
|
rgb(95, 0, 95), // #5f005f
|
||||||
|
rgb(95, 0, 135), // #5f0087
|
||||||
|
rgb(95, 0, 175), // #5f00af
|
||||||
|
rgb(95, 0, 215), // #5f00d7
|
||||||
|
rgb(95, 0, 255), // #5f00ff
|
||||||
|
rgb(95, 95, 0), // #5f5f00
|
||||||
|
rgb(95, 95, 95), // #5f5f5f
|
||||||
|
rgb(95, 95, 135), // #5f5f87
|
||||||
|
rgb(95, 95, 175), // #5f5faf
|
||||||
|
rgb(95, 95, 215), // #5f5fd7
|
||||||
|
rgb(95, 95, 255), // #5f5fff
|
||||||
|
rgb(95, 135, 0), // #5f8700
|
||||||
|
rgb(95, 135, 95), // #5f875f
|
||||||
|
rgb(95, 135, 135), // #5f8787
|
||||||
|
rgb(95, 135, 175), // #5f87af
|
||||||
|
rgb(95, 135, 215), // #5f87d7
|
||||||
|
rgb(95, 135, 255), // #5f87ff
|
||||||
|
rgb(95, 175, 0), // #5faf00
|
||||||
|
rgb(95, 175, 95), // #5faf5f
|
||||||
|
rgb(95, 175, 135), // #5faf87
|
||||||
|
rgb(95, 175, 175), // #5fafaf
|
||||||
|
rgb(95, 175, 215), // #5fafd7
|
||||||
|
rgb(95, 175, 255), // #5fafff
|
||||||
|
rgb(95, 215, 0), // #5fd700
|
||||||
|
rgb(95, 215, 95), // #5fd75f
|
||||||
|
rgb(95, 215, 135), // #5fd787
|
||||||
|
rgb(95, 215, 175), // #5fd7af
|
||||||
|
rgb(95, 215, 215), // #5fd7d7
|
||||||
|
rgb(95, 215, 255), // #5fd7ff
|
||||||
|
rgb(95, 255, 0), // #5fff00
|
||||||
|
rgb(95, 255, 95), // #5fff5f
|
||||||
|
rgb(95, 255, 135), // #5fff87
|
||||||
|
rgb(95, 255, 175), // #5fffaf
|
||||||
|
rgb(95, 255, 215), // #5fffd7
|
||||||
|
rgb(95, 255, 255), // #5fffff
|
||||||
|
rgb(135, 0, 0), // #870000
|
||||||
|
rgb(135, 0, 95), // #87005f
|
||||||
|
rgb(135, 0, 135), // #870087
|
||||||
|
rgb(135, 0, 175), // #8700af
|
||||||
|
rgb(135, 0, 215), // #8700d7
|
||||||
|
rgb(135, 0, 255), // #8700ff
|
||||||
|
rgb(135, 95, 0), // #875f00
|
||||||
|
rgb(135, 95, 95), // #875f5f
|
||||||
|
rgb(135, 95, 135), // #875f87
|
||||||
|
rgb(135, 95, 175), // #875faf
|
||||||
|
rgb(135, 95, 215), // #875fd7
|
||||||
|
rgb(135, 95, 255), // #875fff
|
||||||
|
rgb(135, 135, 0), // #878700
|
||||||
|
rgb(135, 135, 95), // #87875f
|
||||||
|
rgb(135, 135, 135), // #878787
|
||||||
|
rgb(135, 135, 175), // #8787af
|
||||||
|
rgb(135, 135, 215), // #8787d7
|
||||||
|
rgb(135, 135, 255), // #8787ff
|
||||||
|
rgb(135, 175, 0), // #87af00
|
||||||
|
rgb(135, 175, 95), // #87af5f
|
||||||
|
rgb(135, 175, 135), // #87af87
|
||||||
|
rgb(135, 175, 175), // #87afaf
|
||||||
|
rgb(135, 175, 215), // #87afd7
|
||||||
|
rgb(135, 175, 255), // #87afff
|
||||||
|
rgb(135, 215, 0), // #87d700
|
||||||
|
rgb(135, 215, 95), // #87d75f
|
||||||
|
rgb(135, 215, 135), // #87d787
|
||||||
|
rgb(135, 215, 175), // #87d7af
|
||||||
|
rgb(135, 215, 215), // #87d7d7
|
||||||
|
rgb(135, 215, 255), // #87d7ff
|
||||||
|
rgb(135, 255, 0), // #87ff00
|
||||||
|
rgb(135, 255, 95), // #87ff5f
|
||||||
|
rgb(135, 255, 135), // #87ff87
|
||||||
|
rgb(135, 255, 175), // #87ffaf
|
||||||
|
rgb(135, 255, 215), // #87ffd7
|
||||||
|
rgb(135, 255, 255), // #87ffff
|
||||||
|
rgb(175, 0, 0), // #af0000
|
||||||
|
rgb(175, 0, 95), // #af005f
|
||||||
|
rgb(175, 0, 135), // #af0087
|
||||||
|
rgb(175, 0, 175), // #af00af
|
||||||
|
rgb(175, 0, 215), // #af00d7
|
||||||
|
rgb(175, 0, 255), // #af00ff
|
||||||
|
rgb(175, 95, 0), // #af5f00
|
||||||
|
rgb(175, 95, 95), // #af5f5f
|
||||||
|
rgb(175, 95, 135), // #af5f87
|
||||||
|
rgb(175, 95, 175), // #af5faf
|
||||||
|
rgb(175, 95, 215), // #af5fd7
|
||||||
|
rgb(175, 95, 255), // #af5fff
|
||||||
|
rgb(175, 135, 0), // #af8700
|
||||||
|
rgb(175, 135, 95), // #af875f
|
||||||
|
rgb(175, 135, 135), // #af8787
|
||||||
|
rgb(175, 135, 175), // #af87af
|
||||||
|
rgb(175, 135, 215), // #af87d7
|
||||||
|
rgb(175, 135, 255), // #af87ff
|
||||||
|
rgb(175, 175, 0), // #afaf00
|
||||||
|
rgb(175, 175, 95), // #afaf5f
|
||||||
|
rgb(175, 175, 135), // #afaf87
|
||||||
|
rgb(175, 175, 175), // #afafaf
|
||||||
|
rgb(175, 175, 215), // #afafd7
|
||||||
|
rgb(175, 175, 255), // #afafff
|
||||||
|
rgb(175, 215, 0), // #afd700
|
||||||
|
rgb(175, 215, 95), // #afd75f
|
||||||
|
rgb(175, 215, 135), // #afd787
|
||||||
|
rgb(175, 215, 175), // #afd7af
|
||||||
|
rgb(175, 215, 215), // #afd7d7
|
||||||
|
rgb(175, 215, 255), // #afd7ff
|
||||||
|
rgb(175, 255, 0), // #afff00
|
||||||
|
rgb(175, 255, 95), // #afff5f
|
||||||
|
rgb(175, 255, 135), // #afff87
|
||||||
|
rgb(175, 255, 175), // #afffaf
|
||||||
|
rgb(175, 255, 215), // #afffd7
|
||||||
|
rgb(175, 255, 255), // #afffff
|
||||||
|
rgb(215, 0, 0), // #d70000
|
||||||
|
rgb(215, 0, 95), // #d7005f
|
||||||
|
rgb(215, 0, 135), // #d70087
|
||||||
|
rgb(215, 0, 175), // #d700af
|
||||||
|
rgb(215, 0, 215), // #d700d7
|
||||||
|
rgb(215, 0, 255), // #d700ff
|
||||||
|
rgb(215, 95, 0), // #d75f00
|
||||||
|
rgb(215, 95, 95), // #d75f5f
|
||||||
|
rgb(215, 95, 135), // #d75f87
|
||||||
|
rgb(215, 95, 175), // #d75faf
|
||||||
|
rgb(215, 95, 215), // #d75fd7
|
||||||
|
rgb(215, 95, 255), // #d75fff
|
||||||
|
rgb(215, 135, 0), // #d78700
|
||||||
|
rgb(215, 135, 95), // #d7875f
|
||||||
|
rgb(215, 135, 135), // #d78787
|
||||||
|
rgb(215, 135, 175), // #d787af
|
||||||
|
rgb(215, 135, 215), // #d787d7
|
||||||
|
rgb(215, 135, 255), // #d787ff
|
||||||
|
rgb(215, 175, 0), // #d7af00
|
||||||
|
rgb(215, 175, 95), // #d7af5f
|
||||||
|
rgb(215, 175, 135), // #d7af87
|
||||||
|
rgb(215, 175, 175), // #d7afaf
|
||||||
|
rgb(215, 175, 215), // #d7afd7
|
||||||
|
rgb(215, 175, 255), // #d7afff
|
||||||
|
rgb(215, 215, 0), // #d7d700
|
||||||
|
rgb(215, 215, 95), // #d7d75f
|
||||||
|
rgb(215, 215, 135), // #d7d787
|
||||||
|
rgb(215, 215, 175), // #d7d7af
|
||||||
|
rgb(215, 215, 215), // #d7d7d7
|
||||||
|
rgb(215, 215, 255), // #d7d7ff
|
||||||
|
rgb(215, 255, 0), // #d7ff00
|
||||||
|
rgb(215, 255, 95), // #d7ff5f
|
||||||
|
rgb(215, 255, 135), // #d7ff87
|
||||||
|
rgb(215, 255, 175), // #d7ffaf
|
||||||
|
rgb(215, 255, 215), // #d7ffd7
|
||||||
|
rgb(215, 255, 255), // #d7ffff
|
||||||
|
rgb(255, 0, 0), // #ff0000
|
||||||
|
rgb(255, 0, 95), // #ff005f
|
||||||
|
rgb(255, 0, 135), // #ff0087
|
||||||
|
rgb(255, 0, 175), // #ff00af
|
||||||
|
rgb(255, 0, 215), // #ff00d7
|
||||||
|
rgb(255, 0, 255), // #ff00ff
|
||||||
|
rgb(255, 95, 0), // #ff5f00
|
||||||
|
rgb(255, 95, 95), // #ff5f5f
|
||||||
|
rgb(255, 95, 135), // #ff5f87
|
||||||
|
rgb(255, 95, 175), // #ff5faf
|
||||||
|
rgb(255, 95, 215), // #ff5fd7
|
||||||
|
rgb(255, 95, 255), // #ff5fff
|
||||||
|
rgb(255, 135, 0), // #ff8700
|
||||||
|
rgb(255, 135, 95), // #ff875f
|
||||||
|
rgb(255, 135, 135), // #ff8787
|
||||||
|
rgb(255, 135, 175), // #ff87af
|
||||||
|
rgb(255, 135, 215), // #ff87d7
|
||||||
|
rgb(255, 135, 255), // #ff87ff
|
||||||
|
rgb(255, 175, 0), // #ffaf00
|
||||||
|
rgb(255, 175, 95), // #ffaf5f
|
||||||
|
rgb(255, 175, 135), // #ffaf87
|
||||||
|
rgb(255, 175, 175), // #ffafaf
|
||||||
|
rgb(255, 175, 215), // #ffafd7
|
||||||
|
rgb(255, 175, 255), // #ffafff
|
||||||
|
rgb(255, 215, 0), // #ffd700
|
||||||
|
rgb(255, 215, 95), // #ffd75f
|
||||||
|
rgb(255, 215, 135), // #ffd787
|
||||||
|
rgb(255, 215, 175), // #ffd7af
|
||||||
|
rgb(255, 215, 215), // #ffd7d7
|
||||||
|
rgb(255, 215, 255), // #ffd7ff
|
||||||
|
rgb(255, 255, 0), // #ffff00
|
||||||
|
rgb(255, 255, 95), // #ffff5f
|
||||||
|
rgb(255, 255, 135), // #ffff87
|
||||||
|
rgb(255, 255, 175), // #ffffaf
|
||||||
|
rgb(255, 255, 215), // #ffffd7
|
||||||
|
rgb(255, 255, 255), // #ffffff
|
||||||
|
rgb(8, 8, 8), // #080808
|
||||||
|
rgb(18, 18, 18), // #121212
|
||||||
|
rgb(28, 28, 28), // #1c1c1c
|
||||||
|
rgb(38, 38, 38), // #262626
|
||||||
|
rgb(48, 48, 48), // #303030
|
||||||
|
rgb(58, 58, 58), // #3a3a3a
|
||||||
|
rgb(68, 68, 68), // #444444
|
||||||
|
rgb(78, 78, 78), // #4e4e4e
|
||||||
|
rgb(88, 88, 88), // #585858
|
||||||
|
rgb(98, 98, 98), // #626262
|
||||||
|
rgb(108, 108, 108), // #6c6c6c
|
||||||
|
rgb(118, 118, 118), // #767676
|
||||||
|
rgb(128, 128, 128), // #808080
|
||||||
|
rgb(138, 138, 138), // #8a8a8a
|
||||||
|
rgb(148, 148, 148), // #949494
|
||||||
|
rgb(158, 158, 158), // #9e9e9e
|
||||||
|
rgb(168, 168, 168), // #a8a8a8
|
||||||
|
rgb(178, 178, 178), // #b2b2b2
|
||||||
|
rgb(188, 188, 188), // #bcbcbc
|
||||||
|
rgb(198, 198, 198), // #c6c6c6
|
||||||
|
rgb(208, 208, 208), // #d0d0d0
|
||||||
|
rgb(218, 218, 218), // #dadada
|
||||||
|
rgb(228, 228, 228), // #e4e4e4
|
||||||
|
rgb(238, 238, 238), // #eeeeee
|
||||||
|
];
|
Loading…
Reference in New Issue