Compare commits
61 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
646d918197 | |
|
|
2ea5127cb0 | |
|
|
1c04e7906d | |
|
|
ab722bea95 | |
|
|
15b88f1513 | |
|
|
3d8d21034b | |
|
|
40415680bc | |
|
|
13e9dc08d7 | |
|
|
0bdc490e38 | |
|
|
aceb9d92c5 | |
|
|
436c1bbc27 | |
|
|
3fa6d9cfbf | |
|
|
5ff1a6ae06 | |
|
|
57bb495b42 | |
|
|
8396f1918f | |
|
|
03f4d8065b | |
|
|
03d8f58a05 | |
|
|
67703a4a0c | |
|
|
13914f4283 | |
|
|
c44da28f4f | |
|
|
9dd88d8204 | |
|
|
64e5cafb7b | |
|
|
5942d09ca9 | |
|
|
ab7bfa194e | |
|
|
6a7d045405 | |
|
|
553feb7c62 | |
|
|
6561a90f17 | |
|
|
6ae3751377 | |
|
|
a17fbfa937 | |
|
|
5f3e045a7b | |
|
|
6598006210 | |
|
|
7b2b36f839 | |
|
|
9a6e68c54b | |
|
|
e4491fb43d | |
|
|
14ce07b9ab | |
|
|
58655e1086 | |
|
|
a12f2ee802 | |
|
|
02679b51d8 | |
|
|
69e6e07db6 | |
|
|
c492240baf | |
|
|
db4782acf0 | |
|
|
aca4eb0f2d | |
|
|
954ab9c7a6 | |
|
|
01584e640c | |
|
|
55f4ffe006 | |
|
|
74d7cc50c4 | |
|
|
7058f9d7ed | |
|
|
3401c16b2b | |
|
|
2500d99e99 | |
|
|
c504543f26 | |
|
|
e76544ea44 | |
|
|
fec739574c | |
|
|
eb8afe0c51 | |
|
|
8a24c550bb | |
|
|
74b3946868 | |
|
|
fe4f47547b | |
|
|
f91e1afc79 | |
|
|
c5e68af502 | |
|
|
b51aff371b | |
|
|
f9ab9235ed | |
|
|
298dfa6d41 |
|
|
@ -65,5 +65,10 @@ public
|
|||
yarn-error.log
|
||||
.pnp/
|
||||
.pnp.js
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# Gatsby files
|
||||
|
||||
package-lock.json
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ module.exports = {
|
|||
//icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
|
||||
},
|
||||
},
|
||||
// {
|
||||
// resolve: 'gatsby-plugin-typescript',
|
||||
// options: {
|
||||
// isTSX: true,
|
||||
// jsxPragma: `jsx`,
|
||||
// allExtensions: true,
|
||||
// },
|
||||
// },
|
||||
// this (optional) plugin enables Progressive Web App + Offline functionality
|
||||
// To learn more, visit: https://gatsby.dev/offline
|
||||
// `gatsby-plugin-offline`,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -10,13 +10,21 @@
|
|||
"gatsby-plugin-manifest": "^2.4.0",
|
||||
"gatsby-plugin-offline": "^3.2.0",
|
||||
"gatsby-plugin-react-helmet": "^3.3.0",
|
||||
"gatsby-plugin-sass": "^2.3.10",
|
||||
"gatsby-plugin-sharp": "^2.6.0",
|
||||
"gatsby-source-filesystem": "^2.3.0",
|
||||
"gatsby-transformer-sharp": "^2.5.0",
|
||||
"logrocket": "^1.0.10",
|
||||
"mobx": "^5.15.4",
|
||||
"node-sass": "^4.14.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-helmet": "^6.0.0"
|
||||
"react-helmet": "^6.0.0",
|
||||
"react-redux": "^7.2.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-csrf": "^1.1.0",
|
||||
"redux-thunk": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "2.0.5"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
sudo sysctl fs.inotify.max_user_watches=524288
|
||||
gatsby develop
|
||||
|
|
@ -0,0 +1 @@
|
|||
sudo ./ngrok http 8000
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
=-=-=as=-
|
||||
==- =-'
|
||||
=== ==-
|
||||
=-==-=-=-
|
||||
=-= ==-
|
||||
=-- =-=
|
||||
|
||||
-=-====-
|
||||
=-= =-=
|
||||
=-===-==
|
||||
=== =--
|
||||
-== -=-
|
||||
==-=-==
|
||||
|
||||
==-==
|
||||
=-= =-=
|
||||
=--
|
||||
=--
|
||||
=-= =-=
|
||||
=-=-=
|
||||
|
||||
===-=-
|
||||
=--=-=-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
==-=-=-=
|
||||
==--=-
|
||||
|
||||
=-=-=--=-
|
||||
=-"'""''
|
||||
-=_______
|
||||
=-'"""'*^
|
||||
=-______
|
||||
=-=-=-=-=
|
||||
|
||||
=-=-=--=-
|
||||
=--*^''"'
|
||||
-=-=-=--=
|
||||
-=-*^'"''
|
||||
=--
|
||||
=-=
|
||||
|
||||
=-=-=
|
||||
=-'""'-=
|
||||
=-=
|
||||
-=- =-==
|
||||
=-___-=
|
||||
=-=-=
|
||||
|
||||
=-= -=-
|
||||
=-= =-=
|
||||
=-==-=-=-
|
||||
=-==-=-=-
|
||||
=-= -=-
|
||||
=-= =--
|
||||
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
|
||||
=-=-==-==
|
||||
=-=-=-=-=
|
||||
=-=
|
||||
=- =-=
|
||||
=-=- -=-=
|
||||
==-===-
|
||||
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-==-==
|
||||
=-==-==
|
||||
=-- =-=
|
||||
=-= =-=
|
||||
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=-=--=-
|
||||
=--=-==-=
|
||||
|
||||
-=- -=-
|
||||
=-=- -=-=
|
||||
=-- ^ -==
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
|
||||
=-= =-=
|
||||
=-== =-=
|
||||
==--- -==
|
||||
=-==--=-=
|
||||
=-= --=-=
|
||||
=== ==-=
|
||||
|
||||
=-=-=
|
||||
=-=-=-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-=-===
|
||||
=-=--
|
||||
|
||||
=-=-=-==
|
||||
=-='"'===
|
||||
=-=-=-=-
|
||||
=-=*^'"
|
||||
=-=
|
||||
-==
|
||||
|
||||
=-==-=-=
|
||||
=-='"'==-
|
||||
-=-==-=-
|
||||
-=- -=-
|
||||
=-= -==
|
||||
=-= -==
|
||||
|
||||
=-=-=-
|
||||
=== -=
|
||||
=-=-
|
||||
====-
|
||||
=- =-=
|
||||
=-=-=-=
|
||||
|
||||
=-=-=-=-=
|
||||
=-=-=-=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
-=-==-==-
|
||||
-==-=--
|
||||
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-- -==
|
||||
=-= _ =-=
|
||||
=-== ==-=
|
||||
-=- -=-
|
||||
|
||||
=-=-=
|
||||
=-=-=-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-=-\\-
|
||||
=-=-\\
|
||||
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
--= =--
|
||||
--= =--
|
||||
--= =--
|
||||
-=-
|
||||
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
=-==
|
||||
==-=
|
||||
=-= =-=
|
||||
=-= =-=
|
||||
|
||||
=-= =-=
|
||||
--= =--
|
||||
--= =--
|
||||
=-=
|
||||
=-=
|
||||
=-=
|
||||
|
||||
=-=-=-=-=
|
||||
=-=-===-
|
||||
==-
|
||||
=-=
|
||||
-=-=-=-=
|
||||
=-=-=--=-
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
|
||||
export const alphabeth = {
|
||||
|
||||
'A':
|
||||
"=-=-=as=-\n"
|
||||
+ "==- =--\n"
|
||||
+ "=== ==-\n"
|
||||
+ "=-==-=-=-\n"
|
||||
+ "=-= ==-\n"
|
||||
+ "=-- =-=\n",
|
||||
|
||||
'Ą':
|
||||
"=-=-=as=-\n"
|
||||
+ "==- =--\n"
|
||||
+ "=== ==-\n"
|
||||
+ "=-==-=-=-\n"
|
||||
+ "=-= ==-\n"
|
||||
+ "=-- =\\\\\n",
|
||||
|
||||
'B':
|
||||
"-=-====- \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-===-== \n"
|
||||
+ "=== =--\n"
|
||||
+ "-== -=-\n"
|
||||
+ "==-=-== \n",
|
||||
|
||||
'C':
|
||||
" ==-== \n"
|
||||
+ " =-= =-=\n"
|
||||
+ "=-- \n"
|
||||
+ "=-- \n"
|
||||
+ " =-= =-=\n"
|
||||
+ " =-=-= \n",
|
||||
|
||||
'Ć':
|
||||
" ==//= \n"
|
||||
+ " =-= =-=\n"
|
||||
+ "=-- \n"
|
||||
+ "=-- \n"
|
||||
+ " =-= =-=\n"
|
||||
+ " =-=-= \n",
|
||||
|
||||
'D':
|
||||
"===-=- \n"
|
||||
+ "=-- -=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "==- -=-= \n"
|
||||
+ "==--=- \n",
|
||||
|
||||
'E':
|
||||
"=-=-=--=-\n"
|
||||
+ "=-****** \n"
|
||||
+ "-=_______\n"
|
||||
+ "=-******^\n"
|
||||
+ "=-______ \n"
|
||||
+ "=-=-=-=-=\n",
|
||||
|
||||
'Ę':
|
||||
"=-=-=--=-\n"
|
||||
+ "=-****** \n"
|
||||
+ "-=_______\n"
|
||||
+ "=-******^\n"
|
||||
+ "=-______ \n"
|
||||
+ "=-=-\\\\=-=\n",
|
||||
|
||||
'F':
|
||||
"=-=-=--=-\n"
|
||||
+ "=--*^****\n"
|
||||
+ "-=-=-=--=\n"
|
||||
+ "-=-*^****\n"
|
||||
+ "=-- \n"
|
||||
+ "=-= \n",
|
||||
|
||||
'G':
|
||||
" =-=-= \n"
|
||||
+ " =-****-=\n"
|
||||
+ "=-= \n"
|
||||
+ "-=- =-==\n"
|
||||
+ " =-___-= \n"
|
||||
+ " =-=-= \n",
|
||||
|
||||
'H':
|
||||
"=-= -=-\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-==-=-=-\n"
|
||||
+ "=-==-=-=-\n"
|
||||
+ "=-= -=-\n"
|
||||
+ "=-= =--\n",
|
||||
|
||||
'I':
|
||||
" =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'J':
|
||||
"=-=-==-==\n"
|
||||
+ "=-=-=-=-=\n"
|
||||
+ " =-=\n"
|
||||
+ "=- =-=\n"
|
||||
+ "=-=- -=-=\n"
|
||||
+ " ==-===- \n",
|
||||
|
||||
'K':
|
||||
"=-= =-=\n"
|
||||
+ "=-= =-= \n"
|
||||
+ "=-==-== \n"
|
||||
+ "=-==-== \n"
|
||||
+ "=-- =-= \n"
|
||||
+ "=-= =-=\n",
|
||||
|
||||
'L':
|
||||
"=-= \n"
|
||||
+ "=-= \n"
|
||||
+ "=-= \n"
|
||||
+ "=-= \n"
|
||||
+ "=-=-=--=-\n"
|
||||
+ "=--=-==-=\n",
|
||||
|
||||
'M':
|
||||
"-=- -=-\n"
|
||||
+ "=-=- -=-=\n"
|
||||
+ "=-- ^ -==\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n",
|
||||
|
||||
'N':
|
||||
"=-= =-=\n"
|
||||
+ "=-== =-=\n"
|
||||
+ "==--- -==\n"
|
||||
+ "=-==--=-=\n"
|
||||
+ "=-= --=-=\n"
|
||||
+ "=== ==-=\n",
|
||||
|
||||
'Ń':
|
||||
"=-= //=-=\n"
|
||||
+ "=-== =-=\n"
|
||||
+ "==--- -==\n"
|
||||
+ "=-==--=-=\n"
|
||||
+ "=-= --=-=\n"
|
||||
+ "=== ==-=\n",
|
||||
|
||||
'O':
|
||||
" =-=-= \n"
|
||||
+ " =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=== \n"
|
||||
+ " =-=-- \n",
|
||||
|
||||
'Ó':
|
||||
" =-//= \n"
|
||||
+ " =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=== \n"
|
||||
+ " =-=-- \n",
|
||||
|
||||
'P':
|
||||
"=-=-=-== \n"
|
||||
+ "=-=***===\n"
|
||||
+ "=-=-=-=- \n"
|
||||
+ "=-=*^** \n"
|
||||
+ "=-= \n"
|
||||
+ "-== \n",
|
||||
|
||||
'R':
|
||||
"=-==-=-= \n"
|
||||
+ "=-=***==-\n"
|
||||
+ "-=-==-=- \n"
|
||||
+ "-=- -=- \n"
|
||||
+ "=-= -== \n"
|
||||
+ "=-= -==\n",
|
||||
|
||||
'S':
|
||||
" =-=-=- \n"
|
||||
+ "=== -=\n"
|
||||
+ " =-=- \n"
|
||||
+ " ====- \n"
|
||||
+ "=- =-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'Ś':
|
||||
" =-//=- \n"
|
||||
+ "=== -=\n"
|
||||
+ " =-=- \n"
|
||||
+ " ====- \n"
|
||||
+ "=- =-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'T':
|
||||
"=-=-=-=-=\n"
|
||||
+ "=-=-=-=-=\n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'U':
|
||||
"=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "-=-==-==-\n"
|
||||
+ " -==-=-- \n",
|
||||
|
||||
'W':
|
||||
"=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-- -==\n"
|
||||
+ "=-= _ =-=\n"
|
||||
+ "=-== ==-=\n"
|
||||
+ "-=- -=-\n",
|
||||
|
||||
'Q':
|
||||
" =-=-= \n"
|
||||
+ " =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-\\\\- \n"
|
||||
+ " =-=-\\\\ \n",
|
||||
|
||||
'V':
|
||||
"=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "--= =--\n"
|
||||
+ "--= =--\n"
|
||||
+ " --= =-- \n"
|
||||
+ " -=- \n",
|
||||
|
||||
'X':
|
||||
"=-= =-=\n"
|
||||
+ " =-= =-= \n"
|
||||
+ " =-=== \n"
|
||||
+ " ==-== \n"
|
||||
+ " =-= =-= \n"
|
||||
+ "=-= =-=\n",
|
||||
|
||||
'Y':
|
||||
"=-= =-=\n"
|
||||
+ "--= =--\n"
|
||||
+ " --= =-- \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'Z':
|
||||
"=-=-=-=-=\n"
|
||||
+ "=-=-===- \n"
|
||||
+ " ==- \n"
|
||||
+ " =-= \n"
|
||||
+ " -=-=-=-=\n"
|
||||
+ "=-=-=--=-\n",
|
||||
|
||||
'Ź':
|
||||
"=-=-//=-=\n"
|
||||
+ "=-=-===- \n"
|
||||
+ " ==- \n"
|
||||
+ " =-= \n"
|
||||
+ " -=-=-=-=\n"
|
||||
+ "=-=-=--=-\n",
|
||||
|
||||
'Ż':
|
||||
"=-=-()=-=\n"
|
||||
+ "=-=-===- \n"
|
||||
+ " ==- \n"
|
||||
+ " =-= \n"
|
||||
+ " -=-=-=-=\n"
|
||||
+ "=-=-=--=-\n",
|
||||
|
||||
'#':
|
||||
" =- -= \n"
|
||||
+ "-=-=-=-=-\n"
|
||||
+ " =- -= \n"
|
||||
+ " =- -= \n"
|
||||
+ "-=-=-=-=-\n"
|
||||
+ " =- -= \n",
|
||||
|
||||
'0':
|
||||
" =-=-=-= \n"
|
||||
+ "=-=-*-=-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-=-_-=-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'1':
|
||||
" =-= \n"
|
||||
+ " =-=-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'2':
|
||||
" =-=-=-= \n"
|
||||
+ "=-=-=-=-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-= \n"
|
||||
+ " -=-=-=-=\n"
|
||||
+ "-=-=-=-==\n",
|
||||
|
||||
'3':
|
||||
" =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ " ___=-= \n"
|
||||
+ " ***=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'4':
|
||||
" =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-=_-=--\n"
|
||||
+ "=-=-==-=-\n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'5':
|
||||
"=-=-=-=-=\n"
|
||||
+ "=-= *-=\n"
|
||||
+ "=-=-=-=_ \n"
|
||||
+ " ^*=-=\n"
|
||||
+ "=-,._*=-=\n"
|
||||
+ "=-=-=-=-=\n",
|
||||
|
||||
'6':
|
||||
" =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-=-___ \n"
|
||||
+ "=-=-=--= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'7':
|
||||
"=-=-=-=-=\n"
|
||||
+ "=-=-=-=- \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n"
|
||||
+ " =-= \n",
|
||||
|
||||
'8':
|
||||
" =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ " -=-=-=- \n"
|
||||
+ "=-= =-=\n"
|
||||
+ "=-=-=-=-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
'9':
|
||||
" =-=-=-= \n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=-=-\n"
|
||||
+ " ***=-=\n"
|
||||
+ "=-= =-=\n"
|
||||
+ " =-=-=-= \n",
|
||||
|
||||
' ':
|
||||
"\n\n\n",
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
export const generateUrlCode = ( type ) => {
|
||||
let code = 'op?' + type + '='
|
||||
let hash = [
|
||||
'!', '@', '#', '$', '%', '^', '&', '*',
|
||||
'Q', 'W', 'X', 'S', 'q', 'w', 'x', 's'
|
||||
]
|
||||
code += hash[ randomInt(7, 14) ]
|
||||
+ hash[ randomInt(7, 14) ]
|
||||
+ hash[ randomInt(7, 14) ]
|
||||
+ hash[ randomInt(0, 7) ]
|
||||
+ hash[ randomInt(0, 7) ]
|
||||
+ hash[ randomInt(0, 7) ]
|
||||
+ randomInt(0, 9)
|
||||
+ randomInt(0, 9)
|
||||
+ randomInt(0, 9)
|
||||
return code
|
||||
}
|
||||
|
||||
const randomInt = (min, max) => {
|
||||
return min + Math.floor((max - min) * Math.random())
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import React from 'react'
|
||||
|
||||
import ConsoleLoad from '../consoleLoad'
|
||||
|
||||
const help = () => {
|
||||
return "register - register user by form \n"
|
||||
+ "login - login user by form \n"
|
||||
+ "start - start command \n"
|
||||
+ " -a --app - app flag - start music service app \n"
|
||||
+ "clean - clean screen \n"
|
||||
}
|
||||
|
||||
const helpUser = () => {
|
||||
return "logout - logout user \n"
|
||||
+ "start - start command \n"
|
||||
+ " -a --app - app flag - start music service app \n"
|
||||
+ "clean - clean screen \n"
|
||||
}
|
||||
|
||||
const register = () => {
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const startApp = () => {
|
||||
return (
|
||||
<div>
|
||||
<ConsoleLoad />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const undefined = (command) => {
|
||||
return 'command "'+ command + '" is undefined\n'
|
||||
+ ' type "help" for more commands\n'
|
||||
}
|
||||
|
||||
export default {
|
||||
help,
|
||||
helpUser,
|
||||
register,
|
||||
startApp,
|
||||
undefined
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Delete one row
|
||||
* @param {*} refList
|
||||
* @param {*} consoleHistory
|
||||
* @param {*} setConsoleHistory
|
||||
* @param {*} setMessage
|
||||
* @param {*} deleteAction
|
||||
* @param {*} token
|
||||
*/
|
||||
export const AbstractDelete = async (
|
||||
refList,
|
||||
consoleHistory, setConsoleHistory,
|
||||
setMessage,
|
||||
deleteAction,
|
||||
token
|
||||
) => {
|
||||
let id = refList[0].current.value
|
||||
setConsoleHistory( consoleHistory + 'id: ' + id + '\n')
|
||||
if ( id >= 0 ) {
|
||||
deleteAction(
|
||||
id,
|
||||
token
|
||||
).then( response => {
|
||||
setMessage( response['info'] + '\n' )
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Get one row && mapping
|
||||
* @param {*} refList
|
||||
* @param {*} consoleHistory
|
||||
* @param {*} setConsoleHistory
|
||||
* @param {*} setMessage
|
||||
* @param {*} getOneAction
|
||||
* @param {*} mapping
|
||||
*/
|
||||
export const AbstractGetOne = async (
|
||||
refList,
|
||||
consoleHistory, setConsoleHistory,
|
||||
setMessage,
|
||||
getOneAction,
|
||||
mapping,
|
||||
) => {
|
||||
let inputValue = refList[0].current.value
|
||||
setConsoleHistory( consoleHistory + 'id: ' + inputValue + '\n')
|
||||
if ( inputValue >= 0 ) {
|
||||
await getOneAction( inputValue ).then( response => {
|
||||
if ( response['info'] !== 'Not found.' ){
|
||||
setMessage(
|
||||
mapping(
|
||||
response['response']
|
||||
) + response['info'] + '\n'
|
||||
)
|
||||
} else{
|
||||
setMessage(
|
||||
response['info'] + '\n'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
export const validate = ( inputs ) => {
|
||||
let object = {}
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
if (
|
||||
inputs[i]['type'] === 'text'
|
||||
&& inputs[i]['ref'] !== undefined
|
||||
&& inputs[i]['ref'].current.value !== ''
|
||||
)
|
||||
object[ inputs[i]['name'] ] = inputs[i]['ref'].current.value
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
import React from 'react'
|
||||
|
||||
/**
|
||||
*
|
||||
* @param { [ {}, {}, ...{} ] } inputList - list of dicts with info about input
|
||||
* @param { [] } refList - react ref objects list for handler validation
|
||||
* @param { } action - fetch method
|
||||
*/
|
||||
export const FormGenerator = ({
|
||||
inputList, refList,
|
||||
action
|
||||
}) => {
|
||||
|
||||
const handler = async (event) => {
|
||||
event.preventDefault()
|
||||
for ( let i = 0; i < refList.length; i++ ) {
|
||||
if (
|
||||
refList[i].current.value === ''
|
||||
&& inputList[0].action !== 'Update'
|
||||
|| i === 0 && refList.length !== 1
|
||||
) {
|
||||
refList[i].current.focus()
|
||||
} else if ( i === refList.length - 1 ) {
|
||||
await action( refList )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let info
|
||||
|
||||
return (
|
||||
<form onSubmit={ event => handler( event ) }>
|
||||
{
|
||||
inputList.map( (input, key) => {
|
||||
|
||||
if ( input.type === 'info' ) {
|
||||
info = input
|
||||
} else if ( input.type === 'text' ) {
|
||||
return (
|
||||
<TextInputGenerator
|
||||
input={ input }
|
||||
info={ info }
|
||||
key={ key }
|
||||
/>
|
||||
)
|
||||
} else if ( input.type === 'file' ) {
|
||||
return (
|
||||
<UploadInputGenerator
|
||||
input={ input }
|
||||
info={ info }
|
||||
key={ key }
|
||||
/>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
<button type='submit' />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Text input generator, example:
|
||||
* @param {
|
||||
* {
|
||||
* type: 'text',
|
||||
* name: 'name',
|
||||
* ref: React.createRef()
|
||||
* } } input - basic text input
|
||||
* @param {
|
||||
* {
|
||||
* type: 'info',
|
||||
* action: 'Update'
|
||||
* endpoint: 'Album'
|
||||
* } } info - information about form
|
||||
*/
|
||||
const TextInputGenerator = ({
|
||||
input, info
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
{ input.name + ':' }
|
||||
<input
|
||||
id={ input.name + info.action + info.endpoint + 'Input' }
|
||||
autoComplete='off'
|
||||
ref={ input.ref }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file input generator, example:
|
||||
* @param {
|
||||
* {
|
||||
* type: 'file',
|
||||
* name: 'name',
|
||||
* endpoint: 'Album',
|
||||
* fileType: 'image' or 'audio',
|
||||
* dropInfo: dropInfo, setDropInfo: setDropInfo(), #useState
|
||||
* file: file, setFile: setFile() #useState
|
||||
* } } input -
|
||||
*/
|
||||
const UploadInputGenerator = ({
|
||||
input, info
|
||||
}) => {
|
||||
|
||||
const onLoadFile = async ( event ) => {
|
||||
event.preventDefault()
|
||||
let data = event.target.files[0]
|
||||
input.setFile( await toBase64( data ) )
|
||||
setDropInfos(data.name, data.size)
|
||||
}
|
||||
|
||||
const onLoadFileDrop = async ( event ) => {
|
||||
event.preventDefault()
|
||||
event.persist()
|
||||
let data = event.dataTransfer.files[0]
|
||||
input.setFile( await toBase64( data ) )
|
||||
setDropInfos(data.name, data.size)
|
||||
}
|
||||
|
||||
const toBase64 = ( file ) => new Promise( (resolve, reject) => {
|
||||
let fileReader = new FileReader()
|
||||
fileReader.readAsDataURL( file )
|
||||
fileReader.onload = () => resolve( fileReader.result )
|
||||
fileReader.onerror = error => reject( error )
|
||||
})
|
||||
|
||||
const setDropInfos = (name, size) => {
|
||||
input.setDropInfo(
|
||||
'name: "'
|
||||
+ name
|
||||
+ '"\nsize: '
|
||||
+ (Math.round(size / 100 + 'e-2') / 100 )
|
||||
+ ' MB'
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div onDrop={ event => onLoadFileDrop( event ) } >
|
||||
<pre style={ {marginTop: '25px', marginLeft: '40px'} }>
|
||||
{ input.dropInfo }
|
||||
</pre>
|
||||
<input
|
||||
style={ { marginTop: '-55px' } }
|
||||
id={ input.name + info.action + info.endpoint + 'Input' }
|
||||
className='uploadInput'
|
||||
type='file'
|
||||
accept={ input.fileType + '/*' }
|
||||
autoComplete='off'
|
||||
onChange={ event => onLoadFile( event ) }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormGenerator
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
export const mapAllRowsToString = (objects, type, fields) => {
|
||||
let list = '.' + type + '\n'
|
||||
for (let i = 0; i < objects.length; i++) {
|
||||
if (i !== objects.length - 1) {
|
||||
for (let j = 0; j < fields.length; j++) {
|
||||
if ( j === 0 ) {
|
||||
list += '├── ' + objects[i][ fields[j] ] + '\n'
|
||||
} else if (j !== fields.length - 1) {
|
||||
list += '│ ├── ' + fields[j] + ': ' + objects[i][ fields[j] ] + '\n'
|
||||
} else {
|
||||
list += '│ └── ' + fields[j] + ': ' + objects[i][ fields[j] ] + '\n'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < fields.length; j++) {
|
||||
if ( j === 0 ) {
|
||||
list += '└── ' + objects[i][ fields[j] ] + '\n'
|
||||
} else if (j !== fields.length - 1) {
|
||||
list += ' ├── ' + fields[j] + ': ' + objects[i][ fields[j] ] + '\n'
|
||||
} else {
|
||||
list += ' └── ' + fields[j] + ': ' + objects[i][ fields[j] ] + '\n'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
export const mapRowToString = ( object, fields ) => {
|
||||
let row = ''
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
if ( i === 0 ) {
|
||||
row += object[ fields[i] ] + '\n'
|
||||
} else if ( i !== fields.length - 1 ) {
|
||||
row += '├── ' + fields[i] + ': ' + object[ fields[i] ] + '\n'
|
||||
} else {
|
||||
row += '└── ' + fields[i] + ': ' + object[ fields[i] ] + '\n'
|
||||
}
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import React, { useState, useEffect } from "react"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param { method } resetState - reset State method
|
||||
* @param { [] } refList - reset react refs
|
||||
* @param { useState } message - for check message trigger
|
||||
* @param { useState } componentVisible - for focus first comp. input
|
||||
* @param { action } activateConsoleInput - activate general console input
|
||||
*/
|
||||
export const ResetComponent = ({
|
||||
resetState, refList,
|
||||
message,
|
||||
componentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
useEffect( () => {
|
||||
if ( componentVisible === true ) {
|
||||
refList[0].current.focus()
|
||||
if ( message !== '' ) {
|
||||
refList.forEach( resetRefs )
|
||||
resetState()
|
||||
activateConsoleInput()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div> </div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param { method } resetState - reset State method
|
||||
* @param { action } fetchAction - start fetch now
|
||||
* @param { method } mapObjectToString - map response to string
|
||||
* @param { useState } message - for check message trigger
|
||||
* @param { useState } setMessage - for set message trigger
|
||||
* @param { useState } componentVisible - for focus first comp. input
|
||||
* @param { action } activateConsoleInput - activate general console input
|
||||
*/
|
||||
export const ResetComponentWithoutInputs = ({
|
||||
resetState,
|
||||
fetchAction, mapObjectToString,
|
||||
message, setMessage,
|
||||
componentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
useEffect( () => {
|
||||
if (componentVisible) {
|
||||
fetchAction().then(response => {
|
||||
setMessage(
|
||||
mapObjectToString(
|
||||
response['response']
|
||||
) + response['info'] + '\n'
|
||||
)
|
||||
})
|
||||
if (message !== '') {
|
||||
resetState()
|
||||
activateConsoleInput()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div> </div>
|
||||
)
|
||||
}
|
||||
|
||||
const resetRefs = ( element, array ) => {
|
||||
element.current.value = ''
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
import React, { useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { createAlbum } from '../../../../../../stores/album/duck/operations'
|
||||
import { generateUrlCode } from '../../../../../generateUrlCode'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
|
||||
|
||||
const AlbumCreate = ({
|
||||
user,
|
||||
createAlbum,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
const [image, setImage] = useState('')
|
||||
const [imageInfo, setImageInfo] = useState('Drop/Click\nfor upload album image...')
|
||||
|
||||
const titleInput = React.createRef()
|
||||
const descriptionInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
titleInput,
|
||||
descriptionInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Create',
|
||||
endpoint: 'Album'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
ref: titleInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'description',
|
||||
ref: descriptionInput
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'image',
|
||||
fileType: 'image',
|
||||
dropInfo: imageInfo,
|
||||
setDropInfo: setImageInfo,
|
||||
file: image,
|
||||
setFile: setImage
|
||||
}
|
||||
]
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setImage('')
|
||||
setImageInfo('Drop/Click\nfor upload album image...')
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const createFetch = async ( refs ) => {
|
||||
let album = {
|
||||
user_id: user.id,
|
||||
title: refs[0].current.value,
|
||||
description: refs[1].current.value,
|
||||
image: image,
|
||||
url_code: generateUrlCode( 'album' ),
|
||||
}
|
||||
await createAlbum(
|
||||
album,
|
||||
user.token
|
||||
).then( response => {
|
||||
setMessage( response['info'] + '\n' )
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ createFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
createAlbum: (album, token) => createAlbum(album, token)
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumCreate)
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { deleteAlbum } from '../../../../../../stores/album/duck/operations'
|
||||
import { AbstractDelete } from '../Abstract Utils/AbstractDelete'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
|
||||
const AlbumDelete = ({
|
||||
user,
|
||||
deleteAlbum,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const idInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
idInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Delete',
|
||||
endpoint: 'Album'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: idInput
|
||||
}
|
||||
]
|
||||
|
||||
const deleteFetch = (event) => {
|
||||
AbstractDelete(
|
||||
refList,
|
||||
consoleHistory,
|
||||
setConsoleHistory,
|
||||
setMessage,
|
||||
deleteAlbum,
|
||||
user.token
|
||||
)
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ deleteFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
deleteAlbum: (id, token) => deleteAlbum(id, token)
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumDelete)
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import React, { useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { getAllAlbum } from '../../../../../../stores/album/duck/operations'
|
||||
import { ResetComponentWithoutInputs } from '../Abstract Utils/ResetComponent'
|
||||
import { mapAllRowsToString } from '../Abstract Utils/MapRowsToString'
|
||||
|
||||
const AlbumGetAll = ({
|
||||
getAllAlbum,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory(consoleHistory + message)
|
||||
setComponentVisible(false)
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const mapAlbumsToString = (albums) => {
|
||||
let mapFields = [
|
||||
'title',
|
||||
'id',
|
||||
'user_id',
|
||||
'url_code'
|
||||
]
|
||||
return mapAllRowsToString( albums, 'albums', mapFields )
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ResetComponentWithoutInputs
|
||||
resetState={ resetState }
|
||||
fetchAction={ getAllAlbum }
|
||||
mapObjectToString={ mapAlbumsToString }
|
||||
message={ message }
|
||||
setMessage={ setMessage }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
album: state.album
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getAllAlbum: () => dispatch(getAllAlbum())
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumGetAll)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { getOneAlbum } from '../../../../../../stores/album/duck/operations'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { mapRowToString } from '../Abstract Utils/MapRowsToString'
|
||||
import { AbstractGetOne } from '../Abstract Utils/AbstractGetOne'
|
||||
|
||||
const AlbumGetOne = ({
|
||||
album,
|
||||
getOneAlbum,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const getOneInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
getOneInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'GetOne',
|
||||
endpoint: 'Album'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: getOneInput
|
||||
}
|
||||
]
|
||||
|
||||
const mapAlbumToString = ( album ) => {
|
||||
let mapFields = [
|
||||
'title',
|
||||
'id',
|
||||
'user_id',
|
||||
'url_code'
|
||||
]
|
||||
return mapRowToString( album, mapFields )
|
||||
}
|
||||
|
||||
const getOneFetch = () => {
|
||||
AbstractGetOne(
|
||||
refList,
|
||||
consoleHistory,
|
||||
setConsoleHistory,
|
||||
setMessage,
|
||||
getOneAlbum,
|
||||
mapAlbumToString
|
||||
)
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ getOneFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
album: state.album
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getOneAlbum: (id) => dispatch( getOneAlbum(id) )
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumGetOne)
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { updateAlbum } from '../../../../../../stores/album/duck/operations'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
import { validate } from '../Abstract Utils/AbstractUpdate'
|
||||
|
||||
|
||||
const AlbumUpdate = ({
|
||||
user,
|
||||
updateAlbum,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
const [image, setImage] = useState('')
|
||||
const [imageInfo, setImageInfo] = useState('Drop/Click\nfor upload album image...')
|
||||
|
||||
const idInput = React.createRef()
|
||||
const userInput = React.createRef()
|
||||
const titleInput = React.createRef()
|
||||
const descriptionInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
idInput,
|
||||
userInput,
|
||||
titleInput,
|
||||
descriptionInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Update',
|
||||
endpoint: 'Album'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: idInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'user',
|
||||
ref: userInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
ref: titleInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'description',
|
||||
ref: descriptionInput
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'image',
|
||||
fileType: 'image',
|
||||
dropInfo: imageInfo,
|
||||
setDropInfo: setImageInfo,
|
||||
file: image,
|
||||
setFile: setImage
|
||||
}
|
||||
]
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setImage('')
|
||||
setImageInfo('Drop/Click\nfor upload album image...')
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const updateFetch = async ( refs ) => {
|
||||
let album = validate( inputList )
|
||||
await updateAlbum(
|
||||
album.id,
|
||||
album,
|
||||
user.token
|
||||
).then( response => {
|
||||
setMessage( response['info'] + '\n' )
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ updateFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
updateAlbum: (id, album, token) => updateAlbum(id, album, token)
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumUpdate)
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { postAuth } from '../../../../../stores/user/duck/operations'
|
||||
|
||||
|
||||
const Login = ({
|
||||
user,
|
||||
postAuth,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const loginInput = React.createRef()
|
||||
const passwInput = React.createRef()
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const login = async (event) => {
|
||||
event.preventDefault()
|
||||
|
||||
let login = loginInput.current.value
|
||||
let password = passwInput.current.value
|
||||
|
||||
if ( login !== '' && password !== '') {
|
||||
|
||||
postAuth(login, password)
|
||||
.then( response => {
|
||||
setMessage( response['error'] )
|
||||
})
|
||||
|
||||
} else if ( passwInput.current.value === '' ) {
|
||||
document.getElementById('passwInput').focus()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if ( componentVisible ) {
|
||||
document.getElementById('loginInput').focus()
|
||||
} else {
|
||||
activateConsoleInput()
|
||||
}
|
||||
if (message !== '') {
|
||||
let save = 'login: ' + loginInput.current.value + '\n'
|
||||
+ 'password: ' + hidePassword( passwInput.current.value ) + '\n'
|
||||
+ message + '\n'
|
||||
|
||||
loginInput.current.value = ''
|
||||
passwInput.current.value = ''
|
||||
|
||||
setConsoleHistory( consoleHistory + save )
|
||||
setComponentVisible( false )
|
||||
setMessage('')
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const hidePassword = (password) => {
|
||||
let hide = ''
|
||||
for (let i = 0; i < password.length; i++)
|
||||
hide += '*'
|
||||
return hide
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={ login }>
|
||||
login:
|
||||
<input
|
||||
id='loginInput'
|
||||
autoComplete='off'
|
||||
ref={ loginInput }
|
||||
/>
|
||||
<br />
|
||||
password:
|
||||
<input
|
||||
id='passwInput'
|
||||
autoComplete='off'
|
||||
type='password'
|
||||
ref={ passwInput }
|
||||
/>
|
||||
<br />
|
||||
<button type='submit' />
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
postAuth: (username, password) => dispatch( postAuth(username, password) )
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Login)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { deleteAuth } from '../../../../../stores/user/duck/operations'
|
||||
|
||||
const Logout = ({
|
||||
user,
|
||||
deleteAuth,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
const [oneRequest, setOne] = useState(false)
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if ( componentVisible && oneRequest === false ) {
|
||||
deleteAuth(user.token)
|
||||
.then( () => {
|
||||
setMessage( 'logout success' )
|
||||
}).catch( () => {
|
||||
setMessage( 'logout failed' )
|
||||
})
|
||||
setOne( !oneRequest )
|
||||
} else {
|
||||
activateConsoleInput()
|
||||
}
|
||||
if ( message !== '' ) {
|
||||
setConsoleHistory( consoleHistory + message + '\n' )
|
||||
setComponentVisible( false )
|
||||
setOne( false )
|
||||
setMessage('')
|
||||
activateConsoleInput()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<div></div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
deleteAuth: (token) => dispatch( deleteAuth( token ) )
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Logout)
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
import React, { useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { createTrack } from '../../../../../../stores/track/duck/operations'
|
||||
import { generateUrlCode } from '../../../../../generateUrlCode'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
|
||||
|
||||
const TrackCreate = ({
|
||||
user,
|
||||
createTrack,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const [image, setImage] = useState('')
|
||||
const [imageInfo, setImageInfo] = useState('Drop/Click\nfor upload track image...')
|
||||
const [audio, setAudio] = useState('')
|
||||
const [audioInfo, setAudioInfo] = useState('Drop/Click\nfor upload track audio...')
|
||||
|
||||
const albumIdInput = React.createRef()
|
||||
const titleInput = React.createRef()
|
||||
const descriptionInput = React.createRef()
|
||||
const textInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
albumIdInput,
|
||||
titleInput,
|
||||
descriptionInput,
|
||||
textInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Create',
|
||||
endpoint: 'Track'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'albumID',
|
||||
ref: albumIdInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
ref: titleInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'description',
|
||||
ref: descriptionInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'text',
|
||||
ref: textInput
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'image',
|
||||
fileType: 'image',
|
||||
dropInfo: imageInfo,
|
||||
setDropInfo: setImageInfo,
|
||||
file: image,
|
||||
setFile: setImage
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'audio',
|
||||
fileType: 'audio',
|
||||
dropInfo: audioInfo,
|
||||
setDropInfo: setAudioInfo,
|
||||
file: audio,
|
||||
setFile: setAudio
|
||||
}
|
||||
]
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setImage('')
|
||||
setImageInfo('Drop/Click\nfor upload track image...')
|
||||
setAudio('')
|
||||
setAudioInfo('Drop/Click\nfor upload track audio...')
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const createFetch = async ( refs ) => {
|
||||
let track = {
|
||||
user_id: user.id,
|
||||
album_id: refs[0].current.value,
|
||||
title: refs[1].current.value,
|
||||
description: refs[2].current.value,
|
||||
text: refs[3].current.value,
|
||||
image: image,
|
||||
audio: audio,
|
||||
url_code: generateUrlCode( 'track' ),
|
||||
}
|
||||
await createTrack(
|
||||
track,
|
||||
user.token
|
||||
).then( response => {
|
||||
setMessage( response['info'] + '\n' )
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ createFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
createTrack: (track, token) => createTrack(track, token)
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackCreate)
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { deleteTrack } from '../../../../../../stores/track/duck/operations'
|
||||
import { AbstractDelete } from '../Abstract Utils/AbstractDelete'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
|
||||
const TrackDelete = ({
|
||||
user,
|
||||
deleteTrack,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const idInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
idInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Delete',
|
||||
endpoint: 'Track'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: idInput
|
||||
}
|
||||
]
|
||||
|
||||
const deleteFetch = (event) => {
|
||||
AbstractDelete(
|
||||
refList,
|
||||
consoleHistory,
|
||||
setConsoleHistory,
|
||||
setMessage,
|
||||
deleteTrack,
|
||||
user.token
|
||||
)
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ deleteFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
deleteTrack: (id, token) => deleteTrack(id, token)
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackDelete)
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import React, { useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { getAllTrack } from '../../../../../../stores/track/duck/operations'
|
||||
import { ResetComponentWithoutInputs } from '../Abstract Utils/ResetComponent'
|
||||
import { mapAllRowsToString } from '../Abstract Utils/MapRowsToString'
|
||||
|
||||
const TrackGetAll = ({
|
||||
getAllTrack,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory(consoleHistory + message)
|
||||
setComponentVisible(false)
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const mapTracksToString = (albums) => {
|
||||
let mapFields = [
|
||||
'title',
|
||||
'id',
|
||||
'album_id',
|
||||
'user_id',
|
||||
'url_code'
|
||||
]
|
||||
return mapAllRowsToString( albums, 'albums', mapFields )
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ResetComponentWithoutInputs
|
||||
resetState={ resetState }
|
||||
fetchAction={ getAllTrack }
|
||||
mapObjectToString={ mapTracksToString }
|
||||
message={ message }
|
||||
setMessage={ setMessage }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
track: state.track
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getAllTrack: () => dispatch(getAllTrack())
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackGetAll)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { getOneTrack } from '../../../../../../stores/track/duck/operations'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { mapRowToString } from '../Abstract Utils/MapRowsToString'
|
||||
import { AbstractGetOne } from '../Abstract Utils/AbstractGetOne'
|
||||
|
||||
const TrackGetOne = ({
|
||||
getOneTrack,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const getOneInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
getOneInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'GetOne',
|
||||
endpoint: 'Track'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: getOneInput
|
||||
}
|
||||
]
|
||||
|
||||
const mapTrackToString = ( album ) => {
|
||||
let mapFields = [
|
||||
'title',
|
||||
'id',
|
||||
'album_id',
|
||||
'user_id',
|
||||
'url_code'
|
||||
]
|
||||
return mapRowToString( album, mapFields )
|
||||
}
|
||||
|
||||
const getOneFetch = () => {
|
||||
AbstractGetOne(
|
||||
refList,
|
||||
consoleHistory,
|
||||
setConsoleHistory,
|
||||
setMessage,
|
||||
getOneTrack,
|
||||
mapTrackToString
|
||||
)
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ getOneFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
track: state.track
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getOneTrack: (id) => dispatch( getOneTrack(id) )
|
||||
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackGetOne)
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
import React, { useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { updateTrack } from '../../../../../../stores/track/duck/operations'
|
||||
import { FormGenerator } from '../Abstract Utils/FormGenerator'
|
||||
import { ResetComponent } from '../Abstract Utils/ResetComponent'
|
||||
import { validate } from '../Abstract Utils/AbstractUpdate'
|
||||
|
||||
|
||||
const TrackUpdate = ({
|
||||
user,
|
||||
updateTrack,
|
||||
consoleHistory, setConsoleHistory,
|
||||
componentVisible, setComponentVisible,
|
||||
activateConsoleInput
|
||||
}) => {
|
||||
|
||||
const [message, setMessage] = useState('')
|
||||
|
||||
const [image, setImage] = useState('')
|
||||
const [imageInfo, setImageInfo] = useState('Drop/Click\nfor upload track image...')
|
||||
const [audio, setAudio] = useState('')
|
||||
const [audioInfo, setAudioInfo] = useState('Drop/Click\nfor upload track audio...')
|
||||
|
||||
const idInput = React.createRef()
|
||||
const userInput = React.createRef()
|
||||
const albumIdInput = React.createRef()
|
||||
const titleInput = React.createRef()
|
||||
const descriptionInput = React.createRef()
|
||||
const textInput = React.createRef()
|
||||
|
||||
let refList = [
|
||||
idInput,
|
||||
userInput,
|
||||
albumIdInput,
|
||||
titleInput,
|
||||
descriptionInput,
|
||||
textInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Update',
|
||||
endpoint: 'Track'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
ref: idInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'user',
|
||||
ref: userInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'albumID',
|
||||
ref: albumIdInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
ref: titleInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'description',
|
||||
ref: descriptionInput
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'text',
|
||||
ref: textInput
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'image',
|
||||
fileType: 'image',
|
||||
dropInfo: imageInfo,
|
||||
setDropInfo: setImageInfo,
|
||||
file: image,
|
||||
setFile: setImage
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
name: 'audio',
|
||||
fileType: 'audio',
|
||||
dropInfo: audioInfo,
|
||||
setDropInfo: setAudioInfo,
|
||||
file: audio,
|
||||
setFile: setAudio
|
||||
}
|
||||
]
|
||||
|
||||
const resetState = () => {
|
||||
setConsoleHistory( consoleHistory + message )
|
||||
setComponentVisible( false )
|
||||
setImage('')
|
||||
setImageInfo('Drop/Click\nfor upload track image...')
|
||||
setAudio('')
|
||||
setAudioInfo('Drop/Click\nfor upload track audio...')
|
||||
setMessage('')
|
||||
}
|
||||
|
||||
const updateFetch = async ( refs ) => {
|
||||
let track = validate( inputList )
|
||||
await updateTrack(
|
||||
track.id,
|
||||
track,
|
||||
user.token
|
||||
).then( response => {
|
||||
setMessage( response['info'] + '\n' )
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormGenerator
|
||||
inputList={ inputList }
|
||||
refList={ refList }
|
||||
action={ updateFetch }
|
||||
/>
|
||||
<ResetComponent
|
||||
resetState={ resetState }
|
||||
refList={ refList }
|
||||
message={ message }
|
||||
componentVisible={ componentVisible }
|
||||
activateConsoleInput={ activateConsoleInput }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
updateTrack: (track, token) => updateTrack(track, token)
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackUpdate)
|
||||
|
|
@ -1,22 +1,96 @@
|
|||
import React, {useState} from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
import '../styles/general.scss'
|
||||
import '../../../styles/general.scss'
|
||||
|
||||
const indexConsole = ({ }) => {
|
||||
const ConsoleLoad = () => {
|
||||
|
||||
useEffect( () => { loadingDivs() } )
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
const displayNone = {
|
||||
display: 'none'
|
||||
}
|
||||
|
||||
let iterationDivs = 0
|
||||
const loadingDivs = async() => {
|
||||
if (window.innerWidth < 900) {
|
||||
document.body.style.fontSize = '8px'
|
||||
document.getElementById('Poland').style.width = '180px'
|
||||
document.getElementById('Russia').style.width = '310px'
|
||||
document.getElementById('connect').style.width = '390px'
|
||||
document.getElementById('connect').style.marginTop = '170px'
|
||||
document.getElementById('connect').style.marginLeft = '-100px'
|
||||
}
|
||||
if (iterationDivs === 0)
|
||||
while (iterationDivs < 7) {
|
||||
document.getElementById(iterationDivs).style = 'display: block'
|
||||
if (iterationDivs === 2)
|
||||
await loadingLocation()
|
||||
if (iterationDivs === 3)
|
||||
await loadingConnect()
|
||||
if (iterationDivs === 6)
|
||||
await loadingBar()
|
||||
iterationDivs++
|
||||
await sleep(300)
|
||||
}
|
||||
}
|
||||
|
||||
const loadingLocation = async () => {
|
||||
const response = await fetch('https://ipapi.co/json/')
|
||||
let json = await response.json()
|
||||
document.getElementById('2').innerHTML = json.ip
|
||||
+ ' ( '
|
||||
+ json.city
|
||||
+ ' ) >> Петропавловск-Камчатский'
|
||||
}
|
||||
|
||||
let connectASCII = '$--a-sd--К-=;-/.=--=.-=а-=-=-;м-==-.=ч-=--'
|
||||
+ ';=-а-=-;=т-=;=-;=-с-=;-к-=-=-=и-=-=,.,/.//,/;--=-й-=-=;-=,.'
|
||||
+ ',..v,||=-;;=--__+-=-=-='
|
||||
let iterationASCII= 0
|
||||
const loadingConnect = async() => {
|
||||
let popChars = ''
|
||||
while (iterationASCII < connectASCII.length) {
|
||||
popChars = connectASCII.substring(0, iterationASCII)
|
||||
document.getElementById('connect').innerHTML = popChars
|
||||
await sleep(3)
|
||||
iterationASCII++
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
let procentage = 0
|
||||
const loadingBar = async() => {
|
||||
let loadingBar = document.getElementById('6').innerHTML
|
||||
let lastProcentage = procentage
|
||||
for (let i = 0; i < loadingBar.length; i++) {
|
||||
loadingBar = document.getElementById('6').innerHTML
|
||||
lastProcentage = procentage
|
||||
if (loadingBar[i] === '_') {
|
||||
procentage += 4
|
||||
document.getElementById('6').innerHTML = loadingBar
|
||||
.replace('_','#')
|
||||
.replace(lastProcentage, procentage)
|
||||
await sleep(30)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<div>
|
||||
<div>
|
||||
Ładowanie funkcjonalności / загрузка контента с функциональностью сайта
|
||||
return (
|
||||
<div id='consoleDiv'>
|
||||
<div id='0' style={displayNone}>
|
||||
загрузка контента с функциональностью сайта
|
||||
</div>
|
||||
<div>
|
||||
Łączenie z serwerem / подключение к серверу
|
||||
<div id='1' style={displayNone}>
|
||||
подключение к серверу
|
||||
</div>
|
||||
<div>
|
||||
Arłamów ============================ Петропавловск-Камчатский
|
||||
<div id='2' style={displayNone}>
|
||||
>> >> Петропавловск-Камчатский
|
||||
</div>
|
||||
<div className='ASCIIview'>
|
||||
<br />
|
||||
<div className='ASCIIview' id='3' style={displayNone}>
|
||||
<div className='ASCIIchars' id='Poland'>
|
||||
=-¬¬ TF▄ <br />
|
||||
.⌐ , .., <br />
|
||||
|
|
@ -41,6 +115,9 @@ const indexConsole = ({ }) => {
|
|||
` ∩ ─.-^ -, ▐ <br />
|
||||
` `'¬.[¬ <br />
|
||||
` <br />
|
||||
</div>
|
||||
<div className='ASCIIchars' id='connect'>
|
||||
|
||||
</div>
|
||||
<div className='ASCIIchars' id='Russia'>
|
||||
╓ⁿ`1 <br />
|
||||
|
|
@ -93,8 +170,15 @@ const indexConsole = ({ }) => {
|
|||
╙w,.═"``"^%,,,..^ ╢ <br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
Wczytywanie zasobów [###___________________________]
|
||||
<br />
|
||||
<div id='4' style={displayNone}>
|
||||
Подключен!
|
||||
</div>
|
||||
<div id='5' style={displayNone}>
|
||||
загрузка ресурсов
|
||||
</div>
|
||||
<div id='6' style={displayNone}>
|
||||
[_________________________] 0%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -102,4 +186,4 @@ const indexConsole = ({ }) => {
|
|||
|
||||
}
|
||||
|
||||
export default indexConsole
|
||||
export default ConsoleLoad
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import commands from './commands/commands'
|
||||
import Login from './commands/fetchCommands/Login'
|
||||
import Logout from './commands/fetchCommands/Logout'
|
||||
|
||||
import AlbumGetAll from './commands/fetchCommands/Album/GetAll'
|
||||
import AlbumGetOne from './commands/fetchCommands/Album/GetOne'
|
||||
import AlbumCreate from './commands/fetchCommands/Album/Create'
|
||||
import AlbumUpdate from './commands/fetchCommands/Album/Update'
|
||||
import AlbumDelete from './commands/fetchCommands/Album/Delete'
|
||||
|
||||
import '../../../styles/general.scss'
|
||||
|
||||
const IndexConsole = ({
|
||||
user
|
||||
}) => {
|
||||
|
||||
const [consoleHistory, setConsoleHistory] = useState('')
|
||||
|
||||
const [login, setLogin] = useState(false)
|
||||
const [logout, setLogout] = useState(false)
|
||||
const [register, setRegister] = useState(false)
|
||||
|
||||
const [albumGetAll, setAlbumGetAll] = useState(false)
|
||||
const [albumGetOne, setAlbumGetOne] = useState(false)
|
||||
const [albumCreate, setAlbumCreate] = useState(false)
|
||||
const [albumUpdate, setAlbumUpdate] = useState(false)
|
||||
const [albumDelete, setAlbumDelete] = useState(false)
|
||||
|
||||
const [trackGetAll, setTrackGetAll] = useState(false)
|
||||
const [trackGetOne, setTrackGetOne] = useState(false)
|
||||
const [trackCreate, setTrackCreate] = useState(false)
|
||||
const [trackUpdate, setTrackUpdate] = useState(false)
|
||||
const [trackDelete, setTrackDelete] = useState(false)
|
||||
|
||||
const [trackRowGetAll, setTrackRowGetAll] = useState(false)
|
||||
const [trackRowGetOne, setTrackRowGetOne] = useState(false)
|
||||
const [trackRowCreate, setTrackRowCreate] = useState(false)
|
||||
const [trackRowUpdate, setTrackRowUpdate] = useState(false)
|
||||
const [trackRowDelete, setTrackRowDelete] = useState(false)
|
||||
|
||||
const consoleInput = React.createRef()
|
||||
|
||||
let consoleUser = user.username !== ''
|
||||
? user.username + '@00x097 # > '
|
||||
: 'guest@00x097 * > '
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if ( user.username !== '' ) {
|
||||
consoleUser = user.username + '@00x097 # > '
|
||||
} else {
|
||||
consoleUser = 'guest@00x097 * > '
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
useEffect( () => resizeConsoleDiv(), [])
|
||||
|
||||
const resizeConsoleDiv = () => {
|
||||
let consoleDiv = document.getElementById('consoleDiv')
|
||||
consoleDiv.style.height = window.innerHeight - 100 + 'px'
|
||||
}
|
||||
|
||||
const detectCommand = (event) => {
|
||||
event.preventDefault()
|
||||
let inputValue = consoleInput.current.value
|
||||
consoleUser += inputValue + '\n'
|
||||
|
||||
let splitCommand = inputValue.split(' ')
|
||||
let choiceCRUD = splitCommand[ splitCommand.length - 1 ]
|
||||
let useCRUD = choiceCRUD === 'album'
|
||||
|| choiceCRUD === 'track'
|
||||
|| choiceCRUD === 'track-row'
|
||||
|| choiceCRUD === 'user'
|
||||
|
||||
if ( user.username !== '' ) {
|
||||
if ( inputValue === 'help' ){
|
||||
setConsoleHistory( consoleHistory + consoleUser + commands.helpUser() )
|
||||
} else if ( inputValue === 'logout' ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
setLogout( !logout )
|
||||
} else if ( useCRUD ) {
|
||||
runCRUD( inputValue, choiceCRUD )
|
||||
} else if ( inputValue === 'clean' ){
|
||||
setConsoleHistory( '' )
|
||||
} else {
|
||||
setConsoleHistory( consoleHistory + consoleUser + commands.undefined(inputValue) )
|
||||
}
|
||||
} else {
|
||||
if ( inputValue === 'help' ){
|
||||
setConsoleHistory( consoleHistory + consoleUser + commands.help() )
|
||||
} else if ( inputValue === 'login' ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
setLogin( !login )
|
||||
} else if ( inputValue === 'register' ) {
|
||||
|
||||
} else if ( inputValue === 'clean' ){
|
||||
setConsoleHistory( '' )
|
||||
} else {
|
||||
setConsoleHistory( consoleHistory + consoleUser + commands.undefined(inputValue) )
|
||||
}
|
||||
}
|
||||
consoleInput.current.value = ''
|
||||
activateInput()
|
||||
}
|
||||
|
||||
const runCRUD = ( inputValue, object ) => {
|
||||
if ( inputValue === 'get all ' + object ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
getAll( object )
|
||||
} else if ( inputValue === 'get one ' + object ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
getOneForm( object )
|
||||
} else if ( inputValue === 'create ' + object ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
createForm( object )
|
||||
} else if ( inputValue === 'update ' + object ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
updateForm( object )
|
||||
} else if ( inputValue === 'delete ' + object ) {
|
||||
setConsoleHistory( consoleHistory + consoleUser )
|
||||
deleteForm( object )
|
||||
}
|
||||
}
|
||||
|
||||
const getAll = ( object ) => {
|
||||
if (object === 'album') setAlbumGetAll( !albumGetAll )
|
||||
if (object === 'track') setTrackGetAll( !trackGetAll )
|
||||
if (object === 'track-row') setTrackRowGetAll( !trackRowGetAll )
|
||||
}
|
||||
|
||||
const getOneForm = ( object ) => {
|
||||
if (object === 'album') setAlbumGetOne( !albumGetOne )
|
||||
if (object === 'track') setTrackGetOne( !trackGetOne )
|
||||
if (object === 'track-row') setTrackRowGetOne( !trackRowGetOne )
|
||||
}
|
||||
|
||||
const createForm = ( object ) => {
|
||||
if (object === 'album') setAlbumCreate( !albumCreate )
|
||||
if (object === 'track') setTrackCreate( !trackCreate )
|
||||
if (object === 'track-row') setTrackRowCreate( !trackRowCreate )
|
||||
}
|
||||
|
||||
const updateForm = ( object ) => {
|
||||
if (object === 'album') setAlbumUpdate( !albumUpdate )
|
||||
if (object === 'track') setTrackUpdate( !trackUpdate )
|
||||
if (object === 'track-row') setTrackRowUpdate( !trackRowUpdate )
|
||||
}
|
||||
|
||||
const deleteForm = ( object ) => {
|
||||
if (object === 'album') setAlbumDelete( !albumDelete )
|
||||
if (object === 'track') setTrackDelete( !trackDelete )
|
||||
if (object === 'track-row') setTrackRowDelete( !trackRowDelete )
|
||||
}
|
||||
|
||||
const activateInput = () => {
|
||||
document.getElementById('consoleInput').focus()
|
||||
}
|
||||
|
||||
const checkVisible = ( bool ) => {
|
||||
return bool
|
||||
? { display: 'block' }
|
||||
: { display: 'none' }
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='consoleDiv' onClick={ activateInput }>
|
||||
<div id='consoleInfo'>
|
||||
00x097 system (Version 0.1.9) <br />
|
||||
type 'help' for more commands <br />
|
||||
type 'start -a' for start app
|
||||
<br /><br />
|
||||
</div>
|
||||
<pre id='consoleHistory'>
|
||||
{ consoleHistory }
|
||||
</pre>
|
||||
<div id='inputForms'>
|
||||
<div style={ checkVisible( login ) } >
|
||||
<Login
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ login }
|
||||
setComponentVisible={ setLogin }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( logout ) }>
|
||||
<Logout
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ logout }
|
||||
setComponentVisible={ setLogout }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( register ) } >
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style={ checkVisible( albumGetAll ) }>
|
||||
<AlbumGetAll
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ albumGetAll }
|
||||
setComponentVisible={ setAlbumGetAll }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( albumGetOne ) }>
|
||||
<AlbumGetOne
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ albumGetOne }
|
||||
setComponentVisible={ setAlbumGetOne }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( albumCreate ) }>
|
||||
<AlbumCreate
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ albumCreate }
|
||||
setComponentVisible={ setAlbumCreate }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( albumUpdate ) }>
|
||||
<AlbumUpdate
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ albumUpdate }
|
||||
setComponentVisible={ setAlbumUpdate }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
<div style={ checkVisible( albumDelete ) }>
|
||||
<AlbumDelete
|
||||
consoleHistory={ consoleHistory }
|
||||
setConsoleHistory={ setConsoleHistory }
|
||||
componentVisible={ albumDelete }
|
||||
setComponentVisible={ setAlbumDelete }
|
||||
activateConsoleInput={ activateInput }
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div style={ checkVisible( trackGetAll ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackGetOne ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackCreate ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackUpdate ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackDelete ) }>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style={ checkVisible( trackRowGetAll ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackRowGetOne ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackRowCreate ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackRowUpdate ) }>
|
||||
|
||||
</div>
|
||||
<div style={ checkVisible( trackRowDelete ) }>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<form onSubmit={ detectCommand } style={ checkVisible( !(
|
||||
register || login || logout ||
|
||||
albumGetAll || albumGetOne || albumCreate || albumUpdate || albumDelete ||
|
||||
trackGetAll || trackGetOne || trackCreate || trackUpdate || trackDelete ||
|
||||
trackRowGetAll || trackRowGetOne || trackRowCreate || trackRowUpdate || trackRowDelete
|
||||
) ) }>
|
||||
{ consoleUser }
|
||||
<input
|
||||
id='consoleInput'
|
||||
ref={consoleInput}
|
||||
autoComplete='off'
|
||||
autoFocus
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
user: state.user
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, )(IndexConsole)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react'
|
||||
|
||||
import AudioPlayer from './playerInterface/audioPlayer'
|
||||
import IndexPanel from './indexPanel/indexPanel'
|
||||
|
||||
const IndexInterface = () => {
|
||||
return (
|
||||
<div>
|
||||
<AudioPlayer />
|
||||
<IndexPanel />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default IndexInterface
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
|
||||
import SongPanel from './panels/songPanel'
|
||||
import AlbumPanel from './panels/albumPanel'
|
||||
|
||||
import '../../../styles/general.scss'
|
||||
|
||||
const IndexPanel = () => {
|
||||
|
||||
if ( 1 === 1 )
|
||||
return (
|
||||
<div id='panelDiv'>
|
||||
<SongPanel />
|
||||
</div>
|
||||
)
|
||||
else
|
||||
return (
|
||||
<div id='panelDiv'>
|
||||
<AlbumPanel />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default IndexPanel
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
|
||||
const AlbumPanel = () => {
|
||||
return (
|
||||
<div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default AlbumPanel
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import '../../../../styles/songPanel.scss'
|
||||
|
||||
const SongPanel = () => {
|
||||
|
||||
useEffect( () => generateTitleCode() )
|
||||
useEffect( () => setTextHeight() )
|
||||
|
||||
const [openDescription, setOpenDescription] = useState(-1)
|
||||
const [openComments, setOpenComments] = useState(false)
|
||||
|
||||
// ANSI: ▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏░▒▓▐▔▕▖▗▘▙▚▛▜▝▞▟
|
||||
|
||||
let title = '00x097 x track test'
|
||||
let address = '/op?song=aQ2ed#!WkL#csd435fk'
|
||||
let code = ''
|
||||
|
||||
const generateTitleCode = () => {
|
||||
let randomChars = '░▒'
|
||||
let charInRowCount = parseInt((document.getElementById('songCode').clientWidth) / 10) - 6
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let j = 0; j < charInRowCount; j++) {
|
||||
if (j === 0)
|
||||
code += '▐▐▐▐' //'▎▍▍▍▏'
|
||||
else
|
||||
code += randomChars[parseInt(Math.random() * randomChars.length)]
|
||||
}
|
||||
code += '<br />'
|
||||
}
|
||||
document.getElementById('songCode').innerHTML = code
|
||||
}
|
||||
|
||||
const setTextHeight = () => {
|
||||
let titleDivHeight = document.getElementById('songDetails').clientHeight
|
||||
let textDivHeight = window.innerHeight - titleDivHeight
|
||||
document.getElementById('songText').style = 'height: ' + (textDivHeight - 50) + 'px;'
|
||||
}
|
||||
|
||||
const activeCommentDiv = () => {
|
||||
let commentsDiv = document.getElementById('comments')
|
||||
let commentAddInput = document.getElementById('commentAddInput')
|
||||
let commentAddButton = document.getElementById('commentAddButton')
|
||||
if ( openComments ) {
|
||||
commentAddInput.placeholder = 'type comment (or click to exit)'
|
||||
commentsDiv.style = 'height: ' + ((window.innerHeight / 2) - 50) + 'px;'
|
||||
commentAddInput.style = 'width: 60%;'
|
||||
commentAddButton.style = 'display: block;'
|
||||
setOpenComments( !openComments )
|
||||
}
|
||||
else {
|
||||
commentAddInput.placeholder = '(click to show comments)'
|
||||
commentsDiv.style = 'height: 0px;'
|
||||
commentAddInput.style = 'width: 100%;'
|
||||
commentAddButton.style = 'display: none;'
|
||||
setOpenComments( !openComments )
|
||||
}
|
||||
}
|
||||
|
||||
let exampleText = [
|
||||
'[Zwrotka 00x097]\n',
|
||||
'Lorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\n[Zwrotka 00x097]\n',
|
||||
'Lorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
|
||||
'\nLorem ipsum dolor sit amet, consectetur adipi,\n',
|
||||
'Pharetra malesuada. Nunc vel nulla mattis, mollis dui a,\n',
|
||||
'Nulla nec lorem elementum, blandit libero auctor,\n',
|
||||
'Cras vestibulum pretium nunc, ac,\n',
|
||||
]
|
||||
|
||||
let exampleRowDetails = {
|
||||
1: {
|
||||
group: false,
|
||||
leader: true,
|
||||
text: 'Lorem ipsum dolor',
|
||||
description: 'row description test / row description test / row description test',
|
||||
image: ''
|
||||
},
|
||||
4: {
|
||||
group: false,
|
||||
leader: true,
|
||||
text: 'vestibulum pretium nunc, ac,',
|
||||
description: 'row description test / row description test / row description test',
|
||||
image: ''
|
||||
},
|
||||
14: {
|
||||
group: true,
|
||||
leader: false,
|
||||
link: 16,
|
||||
text: ''
|
||||
},
|
||||
15: {
|
||||
group: true,
|
||||
leader: false,
|
||||
link: 16,
|
||||
text: ''
|
||||
},
|
||||
16: {
|
||||
group: true,
|
||||
leader: true,
|
||||
text: '',
|
||||
description: 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum',
|
||||
image: ''
|
||||
}
|
||||
}
|
||||
|
||||
let exampleComments = [
|
||||
{
|
||||
ip: '192.168.0.1',
|
||||
city: 'Rzeszów',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.1.10',
|
||||
city: 'Arłamów',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
{
|
||||
ip: '192.168.2.20',
|
||||
city: 'Kraków',
|
||||
text: 'test comment'
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div id='songPanel'>
|
||||
<div className='songPanelColumn'>
|
||||
<div id='songDetails'>
|
||||
<div id='songCode'>
|
||||
</div>
|
||||
<div id='songThings'>
|
||||
<div id='songTitle'>
|
||||
{title}
|
||||
</div>
|
||||
<div id='songAddress'>
|
||||
{address}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='songText'>
|
||||
<div className='textSection'>
|
||||
{ exampleText.map( (row, key) => {
|
||||
|
||||
const textHighlight = (text, mark) => {
|
||||
let markRow = text.replace(RegExp(mark, 'g'), '<pre class="textHighlights">' + mark + '</pre>')
|
||||
return { __html: markRow }
|
||||
}
|
||||
if(exampleRowDetails[key] !== undefined) {
|
||||
if (exampleRowDetails[key].group === false && exampleRowDetails[key].leader === true){
|
||||
return (
|
||||
<div>
|
||||
<pre
|
||||
id={'row' + key}
|
||||
className='generalText'
|
||||
onClick={ openDescription === key ? () => setOpenDescription( -1 ) : () => setOpenDescription( key )}
|
||||
dangerouslySetInnerHTML={ textHighlight(row, exampleRowDetails[key].text) }>
|
||||
</pre>
|
||||
<pre
|
||||
id={'description' + key}
|
||||
className={ openDescription === key ? 'rowDetails rowDetailsOpen' : 'rowDetails'}>
|
||||
{exampleRowDetails[key].description}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
else if (exampleRowDetails[key].group === true && exampleRowDetails[key].leader === false) {
|
||||
let link = exampleRowDetails[key].link
|
||||
let text = exampleRowDetails[key].text
|
||||
return (
|
||||
<div>
|
||||
<pre
|
||||
id={'row' + key}
|
||||
className='generalText'
|
||||
onClick={ openDescription === link ? () => setOpenDescription( -1 ) : () => setOpenDescription( link )}
|
||||
dangerouslySetInnerHTML={ text === '' ? textHighlight(row, row) : textHighlight(row, text) }>
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
else if (exampleRowDetails[key].group === true && exampleRowDetails[key].leader === true) {
|
||||
let text = exampleRowDetails[key].text
|
||||
return (
|
||||
<div>
|
||||
<pre
|
||||
id={'row' + key}
|
||||
className='generalText'
|
||||
onClick={ openDescription === key ? () => setOpenDescription( -1 ) : () => setOpenDescription( key )}
|
||||
dangerouslySetInnerHTML={ text === '' ? textHighlight(row, row) : textHighlight(row, text) }>
|
||||
</pre>
|
||||
<pre
|
||||
id={'description' + key}
|
||||
className={ openDescription === key ? 'rowDetails rowDetailsOpen' : 'rowDetails'}>
|
||||
{exampleRowDetails[key].description}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<pre id={key} className='generalText'>
|
||||
{row}
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='songPanelColumn'>
|
||||
<div id='songComments'>
|
||||
<div id='comments'>
|
||||
{ exampleComments.map( (comment, key) => {
|
||||
return (
|
||||
<div id={'comment' + key} className='commentDiv'>
|
||||
<div className='commentInfo'>
|
||||
{ comment.ip + ' ( ' + comment.city + ' )' }
|
||||
</div>
|
||||
<div className='commentText'>
|
||||
{ comment.text }
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div id='commentAdd'>
|
||||
<input
|
||||
id='commentAddInput'
|
||||
placeholder='(click to show comments)'
|
||||
onClick={ () => activeCommentDiv() }>
|
||||
</input>
|
||||
<div id='commentAddButton'>
|
||||
Add comment
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='albumSongs'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default SongPanel
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
import '../../../styles/audioVisualizer.scss'
|
||||
import { alphabeth } from '../../alphabeth'
|
||||
import audioTest from '../../../images/audioTest0.wav'
|
||||
|
||||
|
||||
const AudioPlayer = () => {
|
||||
|
||||
const [play, setPlay] = useState(false)
|
||||
const [pause, setPause] = useState(false)
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
useEffect(() => loadAudio(), [])
|
||||
|
||||
const loadAudio = () => {
|
||||
let audio = document.getElementById("audio");
|
||||
audio.src = audioTest;
|
||||
audio.load();
|
||||
}
|
||||
|
||||
const controlAudio = async () => {
|
||||
if (play === false) {
|
||||
setPlay(!play)
|
||||
await playAudio()
|
||||
}
|
||||
else if (play === true && pause === false) {
|
||||
setPause(!pause)
|
||||
pauseAudio()
|
||||
}
|
||||
else if (play === true && pause === true) {
|
||||
setPause(!pause)
|
||||
resumeAudio()
|
||||
}
|
||||
}
|
||||
|
||||
const pauseAudio = () => {
|
||||
let audio = document.getElementById("audio");
|
||||
audio.pause()
|
||||
}
|
||||
|
||||
const resumeAudio = () => {
|
||||
let audio = document.getElementById("audio");
|
||||
audio.play()
|
||||
}
|
||||
|
||||
const playAudio = async () => {
|
||||
|
||||
let audio = document.getElementById("audio");
|
||||
// audio.src = audioTest;
|
||||
// audio.load();
|
||||
audio.play();
|
||||
let context = new AudioContext();
|
||||
let src = context.createMediaElementSource(audio);
|
||||
let analyser = context.createAnalyser();
|
||||
|
||||
let canvas = document.getElementById("canvas");
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
let ctx = canvas.getContext("2d");
|
||||
|
||||
src.connect(analyser);
|
||||
analyser.connect(context.destination);
|
||||
|
||||
analyser.fftSize = 256;
|
||||
|
||||
let bufferLength = analyser.frequencyBinCount;
|
||||
|
||||
let dataArray = new Uint8Array(bufferLength);
|
||||
|
||||
let WIDTH = canvas.width;
|
||||
let HEIGHT = canvas.height;
|
||||
|
||||
//let barWidth = (WIDTH / bufferLength) * 2.5;
|
||||
let barHeight;
|
||||
let x = 0;
|
||||
|
||||
let frameString = '===================================================='
|
||||
|
||||
let frameStrings = [] // 52 chars in row
|
||||
|
||||
for (let i = 0; i <= 200; i++) {
|
||||
frameStrings[i] = Math.random().toString(36)
|
||||
+ ""
|
||||
+ Math.random().toString(36)
|
||||
+ ""
|
||||
+ Math.random().toString(36)
|
||||
+ ""
|
||||
+ Math.random().toString(36);
|
||||
}
|
||||
|
||||
let frame
|
||||
|
||||
const renderFrame = () => {
|
||||
requestAnimationFrame(renderFrame);
|
||||
|
||||
x = 0;
|
||||
|
||||
analyser.getByteFrequencyData(dataArray);
|
||||
|
||||
ctx.fillStyle = "#000";
|
||||
ctx.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
timerAudio()
|
||||
|
||||
for (let i = 0; i < bufferLength; i++) {
|
||||
|
||||
barHeight = dataArray[i];
|
||||
|
||||
let r = barHeight + (25 * (i / bufferLength));
|
||||
let g = 36; //250 * ( i / bufferLength);
|
||||
let b = 36;
|
||||
|
||||
ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')';
|
||||
ctx.font = '15px Ubuntu'
|
||||
frame = frameString.slice(0, barHeight / 10) + '='
|
||||
ctx.fillText(frame, 0, x);
|
||||
|
||||
x += window.innerHeight / (bufferLength - 34);
|
||||
}
|
||||
}
|
||||
const timerAudio = () => {
|
||||
let maxMinutes = parseInt(audio.duration / 60)
|
||||
let maxSeconds = parseInt(audio.duration - (60 * maxMinutes))
|
||||
|
||||
let seconds = parseInt(audio.currentTime);
|
||||
let minutes = parseInt(seconds / 60);
|
||||
if (minutes > 0) {
|
||||
seconds = parseInt(seconds - (60 * minutes))
|
||||
}
|
||||
document.getElementById('audioCurrentTime').innerHTML = minutes
|
||||
+ ':'
|
||||
+ (seconds < 10 ? '0' : '')
|
||||
+ seconds
|
||||
document.getElementById('audioTime').innerHTML = maxMinutes
|
||||
+ ':'
|
||||
+ (maxSeconds < 10 ? '0' : '')
|
||||
+ maxSeconds
|
||||
}
|
||||
const progressBarAudio = async () => {
|
||||
await sleep(1000)
|
||||
let maxProgress = audio.duration
|
||||
let onePercent = maxProgress / 100
|
||||
let progress = 1
|
||||
let lastProgressValue = 0;
|
||||
while (progress <= 20) {
|
||||
await sleep(5000 * onePercent)
|
||||
let bar = document.getElementById('audioProgressBar').innerHTML
|
||||
progress = parseInt((audio.currentTime / onePercent) / 5);
|
||||
if (lastProgressValue !== progress) {
|
||||
document.getElementById('audioProgressBar').innerHTML = bar.replace('|', '#')
|
||||
lastProgressValue = progress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
audio.play()
|
||||
renderFrame()
|
||||
await viewTitleAudio()
|
||||
moveTitleAudio()
|
||||
await progressBarAudio()
|
||||
}
|
||||
|
||||
const barClick = (e) => {
|
||||
e.preventDefault()
|
||||
let rect = e.target.getBoundingClientRect()
|
||||
let y = e.clientY - rect.top
|
||||
let value = parseInt((y / 364) * 100)
|
||||
let audio = document.getElementById("audio");
|
||||
let maxProgress = audio.duration
|
||||
let onePercent = maxProgress / 100
|
||||
audio.currentTime = value * onePercent
|
||||
let progress = parseInt(value / 5)
|
||||
let i = 0
|
||||
while (i < 20) {
|
||||
let bar = document.getElementById('audioProgressBar').innerHTML
|
||||
document.getElementById('audioProgressBar').innerHTML = bar.replace('#', '|')
|
||||
i++
|
||||
}
|
||||
i = 0
|
||||
while (i <= progress) {
|
||||
let bar = document.getElementById('audioProgressBar').innerHTML
|
||||
document.getElementById('audioProgressBar').innerHTML = bar.replace('|', '#')
|
||||
i++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const viewTitleAudio = async() => {
|
||||
let title = '00x097 x test track'
|
||||
title = title.toUpperCase()
|
||||
let titleASCII = [];
|
||||
let i
|
||||
for (i = 0; i < title.length; i++) {
|
||||
titleASCII[i] = alphabeth[title[i]]
|
||||
titleASCII[i] += '\n'
|
||||
titleASCII[i].replace(',', '')
|
||||
}
|
||||
let titleASCIIFull = titleASCII.toString()
|
||||
while (i > 0) {
|
||||
titleASCIIFull = titleASCIIFull.replace(',','')
|
||||
i--
|
||||
}
|
||||
document.getElementById('audioTitle').innerText = titleASCIIFull
|
||||
}
|
||||
|
||||
const moveTitleAudio = async() => {
|
||||
let title = document.getElementById('audioTitle')
|
||||
let different = window.innerHeight - title.clientHeight
|
||||
await sleep(5000)
|
||||
while (true) {
|
||||
title.style = 'margin-top: ' + different + 'px;'
|
||||
await sleep(15000)
|
||||
title.style = 'margin-top: 10px;'
|
||||
await sleep(15000)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='audioVisualizerDiv'>
|
||||
<div id='audioMenu'>
|
||||
<div onClick={controlAudio}>
|
||||
{play === false || pause === true ? '>' : '||'}
|
||||
</div>
|
||||
<div id='audioCurrentTime' >
|
||||
0:00
|
||||
</div>
|
||||
<div>===</div>
|
||||
<div id='audioProgressBar' onClick={e => barClick(e)} onDrag={e => barClick(e)}>
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
|<br />
|
||||
</div>
|
||||
<div>===</div>
|
||||
<div id='audioTime'>
|
||||
0:00
|
||||
</div>
|
||||
</div>
|
||||
<canvas id='canvas'>
|
||||
</canvas>
|
||||
<pre id='audioTitle'>
|
||||
</pre>
|
||||
<audio id='audio'>
|
||||
</audio>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
export default AudioPlayer
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import IndexConsole from '../components/index/indexConsole/indexConsole'
|
||||
import { store } from '../stores/store'
|
||||
import { Provider } from 'react-redux'
|
||||
|
||||
// import LogRocket from 'logrocket';
|
||||
// LogRocket.init('ugbdf9/music-service');
|
||||
|
||||
const IndexPage = () => (
|
||||
<Provider store={ store }>
|
||||
<IndexConsole />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
export default IndexPage
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
const address = 'http://localhost:9090/'
|
||||
|
||||
export {
|
||||
address
|
||||
}
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
import { address } from './APIAddress'
|
||||
|
||||
// User Session Token
|
||||
|
||||
let defaultToken = 'empty token'
|
||||
|
||||
|
||||
// CRUD methods
|
||||
|
||||
/**
|
||||
* get list method
|
||||
* @param {string} endpoint - for example `user/`
|
||||
*/
|
||||
const _getList = async (endpoint) => {
|
||||
return await responseGD(address + endpoint, 'GET', defaultToken)
|
||||
}
|
||||
|
||||
/**
|
||||
* get one row / record
|
||||
* @param {string} endpoint - for example `user/`
|
||||
*/
|
||||
const _getOne = async (endpoint) => {
|
||||
return await responseGD(address + endpoint, 'GET', defaultToken)
|
||||
}
|
||||
|
||||
/**
|
||||
* universal post method
|
||||
* @param {string} endpoint - for example `user/`
|
||||
* @param {{}} body - body request
|
||||
* @param {string} token - token for verify user in API
|
||||
*/
|
||||
const _post = async (endpoint, body, token) => {
|
||||
return await responseCRU(address + endpoint, 'POST', body, token)
|
||||
}
|
||||
|
||||
/**
|
||||
* universal put method
|
||||
* @param {string} endpoint - for example `user/{id}/` where {id} is object id
|
||||
* @param {{}} body - body request
|
||||
* @param {string} token - token for verify user in API
|
||||
*/
|
||||
const _put = async (endpoint, body, token) => {
|
||||
return await responseCRU(address + endpoint, 'PUT', body, token)
|
||||
}
|
||||
|
||||
/**
|
||||
* universal patch method
|
||||
* @param {string} endpoint - for example `user/{id}/` where {id} is object id
|
||||
* @param {{}} body - body request
|
||||
* @param {string} token - token for verify user in API
|
||||
*/
|
||||
const _patch = async (endpoint, body, token) => {
|
||||
return await responseCRU(address + endpoint, 'PATCH', body, token)
|
||||
}
|
||||
|
||||
/**
|
||||
* universal delete method
|
||||
* @param {string} endpoint - for example `user/{id}/` where {id} is object id
|
||||
* @param {string} token - token for verify user in API
|
||||
*/
|
||||
const _delete = async (endpoint, token) => {
|
||||
return await responseGD(address + endpoint, 'DELETE', token)
|
||||
}
|
||||
|
||||
|
||||
// Utils
|
||||
// Fetch methods
|
||||
|
||||
/**
|
||||
* fetch `get` / `delete` type methods
|
||||
* @param {string} address - full endpoint address
|
||||
* @param {string} method - method like `get` / `delete`
|
||||
* @param {string} token - token for verify user in API
|
||||
*/
|
||||
const responseGD = async (address, method, token) => {
|
||||
try {
|
||||
const response = await fetch(address, {
|
||||
method: method,
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
"Authorization": token,
|
||||
"X-CSRFToken": csrftoken,
|
||||
"accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
if ( method === 'GET' )
|
||||
return await responseExceptions(
|
||||
await response.json(),
|
||||
response.status
|
||||
)
|
||||
else
|
||||
return await responseExceptions(
|
||||
await response,
|
||||
response.status
|
||||
)
|
||||
} catch (error) {
|
||||
return { info: error }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch `post` / `put` / `patch` type methods
|
||||
* @param {string} address - full endpoint address
|
||||
* @param {string} method - method like `post` / `put` / `patch`
|
||||
* @param {{}} body - body of request
|
||||
* @param {string} token - token for verify user session in API
|
||||
*/
|
||||
const responseCRU = async (address, method, body, token) => {
|
||||
try {
|
||||
const response = await fetch(address, {
|
||||
method: method,
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
"Authorization": token,
|
||||
"X-CSRFToken": csrftoken,
|
||||
"accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
return await responseExceptions(
|
||||
await response.json(),
|
||||
response.status
|
||||
)
|
||||
} catch (error) {
|
||||
return { info: error }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch bonus exceptions ( not blank fields in request / bad requests )
|
||||
* @param {Response} response - response from fetch
|
||||
* @param {number} status - request status
|
||||
*/
|
||||
const responseExceptions = async (response, status) => {
|
||||
try {
|
||||
//progressStream( response )
|
||||
if (status > 300) {
|
||||
let info = ''
|
||||
Object.keys(response).forEach(element => {
|
||||
if (element !== 'detail')
|
||||
info += element + ' - ' + response[element][0]
|
||||
else
|
||||
info += response[element]
|
||||
})
|
||||
return {
|
||||
response: response,
|
||||
info: info
|
||||
}
|
||||
}
|
||||
else
|
||||
return {
|
||||
response: response,
|
||||
info: 'operation success'
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
response: response,
|
||||
info: error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get CSRF Token
|
||||
|
||||
/**
|
||||
* get cookie method for CSRF verification
|
||||
* @param {string} name - name of handled cookie
|
||||
*/
|
||||
const getCookie = (name) => {
|
||||
if (!document.cookie) {
|
||||
return null;
|
||||
}
|
||||
const token = document.cookie.split(';')
|
||||
.map(c => c.trim())
|
||||
.filter(c => c.startsWith(name + '='));
|
||||
|
||||
if (token.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return decodeURIComponent(token[0].split('=')[1]);
|
||||
}
|
||||
|
||||
const csrftoken = getCookie('csrftoken')
|
||||
|
||||
// Get progress stream
|
||||
|
||||
/**
|
||||
* Fetch streaming (use in `then` statement) usefull for get request progress info
|
||||
* @param response - is a response from fetch
|
||||
*/
|
||||
export const progressStream = (response) => {
|
||||
const contentLength = response.headers.get('content-length')
|
||||
if (!contentLength)
|
||||
throw Error('Content-Length response header unavailable')
|
||||
const total = parseInt(contentLength, 10)
|
||||
let loaded = 0
|
||||
return new Response(
|
||||
new ReadableStream({
|
||||
start(controller) {
|
||||
const reader = response.body.getReader()
|
||||
read()
|
||||
function read() {
|
||||
reader.read()
|
||||
.then(({ done, value }) => {
|
||||
if (done) {
|
||||
controller.close()
|
||||
return
|
||||
}
|
||||
loaded += value.byteLength
|
||||
console.log(loaded / total * 100)
|
||||
controller.enqueue(value)
|
||||
read()
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error)
|
||||
controller.error(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export default {
|
||||
_getList,
|
||||
_getOne,
|
||||
_post,
|
||||
_put,
|
||||
_patch,
|
||||
_delete,
|
||||
defaultToken,
|
||||
progressStream
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import types from './types'
|
||||
|
||||
const getAll = item => ({
|
||||
type: types.GET_ALL, item
|
||||
})
|
||||
|
||||
const getOne = item => ({
|
||||
type: types.GET_ONE, item
|
||||
})
|
||||
|
||||
const getRatings = item => ({
|
||||
rype: types.GET_RATINGS, item
|
||||
})
|
||||
|
||||
export default {
|
||||
getAll,
|
||||
getOne,
|
||||
getRatings
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import albumReducer from './reducers'
|
||||
export { default as albumTypes } from './types'
|
||||
export { default as albumActions } from './actions'
|
||||
|
||||
export default albumReducer
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import AppService from '../../AppService'
|
||||
|
||||
import actions from './actions'
|
||||
|
||||
const endpoint = 'album/'
|
||||
|
||||
// Album CRUD
|
||||
|
||||
export const getAllAlbum = () => async (dispatch) => {
|
||||
return await AppService._getList(
|
||||
endpoint
|
||||
).then( response => {
|
||||
dispatch( actions.getAll( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const getOneAlbum = (id) => async( dispatch ) => {
|
||||
return await AppService._getOne(
|
||||
endpoint + id + '/'
|
||||
).then( response => {
|
||||
dispatch( actions.getOne( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const createAlbum = async (album, token) => {
|
||||
return await AppService._post(
|
||||
endpoint,
|
||||
album,
|
||||
token
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const updateAlbum = async (id, album, token) => {
|
||||
return await AppService._patch(
|
||||
endpoint + id + '/',
|
||||
album,
|
||||
token
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteAlbum = async (id, token) => {
|
||||
return await AppService._delete(
|
||||
endpoint + id + '/',
|
||||
token
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
// Album Ratings CRUD
|
||||
|
||||
export const getAllAlbumRating = (id) => async ( dispatch ) => {
|
||||
return await AppService._getList(
|
||||
endpoint + id + '/ratings/'
|
||||
).then( response => {
|
||||
dispatch( actions.getRatings( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const createAlbumRating = (album_id, rating, token) => async ( dispatch ) => {
|
||||
return await AppService._post(
|
||||
endpoint + album_id + '/rating/',
|
||||
rating,
|
||||
token
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteAlbumRating = (album_id, rating_id, token) => async ( dispatch ) => {
|
||||
return await AppService._delete(
|
||||
endpoint + album_id + '/rating/' + rating_id,
|
||||
token
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import types from './types'
|
||||
|
||||
const INITIAL_STATE = {
|
||||
actualAlbum: {
|
||||
id: -1,
|
||||
user_id: -1,
|
||||
title: '',
|
||||
description: '',
|
||||
image: '',
|
||||
url_code: '',
|
||||
tracks: [],
|
||||
ratings: []
|
||||
},
|
||||
albums: []
|
||||
}
|
||||
|
||||
const albumReducer = ( state = INITIAL_STATE, action ) => {
|
||||
switch(action.type) {
|
||||
case types.GET_ALL:
|
||||
return {
|
||||
...state,
|
||||
albums: action.item
|
||||
}
|
||||
case types.GET_ONE:
|
||||
return {
|
||||
...state,
|
||||
actualAlbum: {
|
||||
...state.actualAlbum,
|
||||
id: action.item.id,
|
||||
user_id: action.item.user_id,
|
||||
title: action.item.title,
|
||||
description: action.item.description,
|
||||
image: action.item.image,
|
||||
url_code: action.item.url_code,
|
||||
tracks: action.item.tracks,
|
||||
}
|
||||
}
|
||||
case types.GET_RATINGS:
|
||||
return {
|
||||
...state,
|
||||
actualAlbum: {
|
||||
...state.actualAlbum,
|
||||
ratings: action.item
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default albumReducer
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
const GET_ALL = 'GET_ALL'
|
||||
const GET_ONE = 'GET_ONE'
|
||||
const GET_RATINGS = 'GET_RATINGS'
|
||||
|
||||
export default ({
|
||||
GET_ALL,
|
||||
GET_ONE,
|
||||
GET_RATINGS
|
||||
})
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
export const loadState = () => {
|
||||
try {
|
||||
const serializedState = localStorage.getItem('state');
|
||||
|
||||
if (serializedState === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return JSON.parse(serializedState);
|
||||
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const saveState = (state) => {
|
||||
try {
|
||||
const serializedState = JSON.stringify(state);
|
||||
localStorage.setItem('state', serializedState);
|
||||
} catch ( error ) {
|
||||
console.log( error );
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { combineReducers } from 'redux'
|
||||
|
||||
import userReducer from './user/duck'
|
||||
import albumReducer from './album/duck'
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
user: userReducer,
|
||||
album: albumReducer
|
||||
})
|
||||
|
||||
export default rootReducer
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { saveState, loadState } from './loadStore'
|
||||
import rootReducer from './reducers'
|
||||
import loadash from 'lodash'
|
||||
import thunk from 'redux-thunk'
|
||||
|
||||
const persistedState = loadState()
|
||||
|
||||
export const store = createStore(rootReducer, persistedState, applyMiddleware(thunk))
|
||||
|
||||
|
||||
store.subscribe( () => {
|
||||
saveState({
|
||||
user: store.getState().user
|
||||
})
|
||||
})
|
||||
|
||||
store.subscribe( loadash.throttle( () => {
|
||||
saveState({
|
||||
user: store.getState().user
|
||||
})
|
||||
}, 1000))
|
||||
|
||||
export default preloadedState => {
|
||||
return createStore(rootReducer, preloadedState)
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import types from './types'
|
||||
|
||||
const getOne = item => ({
|
||||
type: types.GET_ONE, item
|
||||
})
|
||||
|
||||
const update = item => ({
|
||||
type: types.UPDATE, item
|
||||
})
|
||||
|
||||
const addRow = item => ({
|
||||
type: types.ADD_ROW, item
|
||||
})
|
||||
|
||||
export default ({
|
||||
getOne,
|
||||
update,
|
||||
addRow
|
||||
})
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import trackReducer from './reducers'
|
||||
export { default as trackTypes } from './types'
|
||||
export { default as trackActions } from './actions'
|
||||
|
||||
export default trackReducer
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
import AppService from '../../AppService'
|
||||
|
||||
import actions from './actions'
|
||||
|
||||
const trackEndpoint = 'track/'
|
||||
const trackRowEndpoint = 'track-row/'
|
||||
|
||||
// Track CRUD
|
||||
|
||||
export const getOneTrack = ( id ) => async (dispatch) => {
|
||||
return await AppService._getOne(
|
||||
trackEndpoint + id + '/'
|
||||
).then( response => {
|
||||
dispatch( actions.getOne( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const createTrack = async ( track, token ) => {
|
||||
return await AppService._post(
|
||||
trackEndpoint,
|
||||
track,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
export const updateTrack = async ( id, track, token ) => {
|
||||
return await AppService._patch(
|
||||
trackEndpoint + id + '/',
|
||||
track,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
export const deleteTrack = async ( id ) => {
|
||||
return await AppService._delete(
|
||||
trackEndpoint + id + '/',
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
// Track Row CRUD
|
||||
|
||||
export const getOneTrackRow = ( id ) => async (dispatch) => {
|
||||
return await AppService._getOne(
|
||||
trackRowEndpoint + id + '/'
|
||||
).then( response => {
|
||||
dispatch( actions.getOne( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const createTrackRow = async ( track, token ) => {
|
||||
return await AppService._post(
|
||||
trackRowEndpoint,
|
||||
track,
|
||||
token
|
||||
).then( response => {
|
||||
dispatch( actions.addRow( response ) )
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const updateTrackRow = async ( id, track, token ) => {
|
||||
return await AppService._patch(
|
||||
trackRowEndpoint + id + '/',
|
||||
track,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
export const deleteTrackRow = async ( id ) => {
|
||||
return await AppService._delete(
|
||||
trackRowEndpoint + id + '/',
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
// Track Ratings CRUD
|
||||
|
||||
export const getAllTrackRating = (id) => async ( dispatch ) => {
|
||||
return await AppService._getList(
|
||||
trackEndpoint + id + '/ratings/'
|
||||
).then( response => {
|
||||
dispatch( actions.getRatings( response ) )
|
||||
})
|
||||
}
|
||||
|
||||
export const createTrackRating = (track_id, rating, token) => {
|
||||
return await AppService._post(
|
||||
trackEndpoint + track_id + '/rating/',
|
||||
rating,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
||||
export const deleteTrackRating = (track_id, rating_id, token) => {
|
||||
return await AppService._delete(
|
||||
trackEndpoint + track_id + '/rating/' + rating_id,
|
||||
token
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import types from './types'
|
||||
|
||||
const INITIAL_STATE = {
|
||||
id: -1,
|
||||
album_id: -1,
|
||||
user_id: -1,
|
||||
title: '',
|
||||
description: '',
|
||||
text: '',
|
||||
image: '',
|
||||
audio: '',
|
||||
url_code: '',
|
||||
track_rows: []
|
||||
}
|
||||
|
||||
const trackReducer = ( state = INITIAL_STATE, action ) => {
|
||||
switch(action.type) {
|
||||
case types.GET_ONE:
|
||||
return {
|
||||
id: action.item.id,
|
||||
album_id: action.item.album_id,
|
||||
user_id: action.item.user_id,
|
||||
title: action.item.title,
|
||||
description: action.item.description,
|
||||
text: action.item.text,
|
||||
image: action.item.image,
|
||||
audio: action.item.audio,
|
||||
url_code: action.item.url_code,
|
||||
track_rows: action.item.track_rows
|
||||
}
|
||||
case types.UPDATE:
|
||||
return {
|
||||
...state,
|
||||
id: action.item.id,
|
||||
album_id: action.item.album_id,
|
||||
user_id: action.item.user_id,
|
||||
title: action.item.title,
|
||||
description: action.item.description,
|
||||
text: action.item.text,
|
||||
image: action.item.image,
|
||||
audio: action.item.audio,
|
||||
url_code: action.item.url_code,
|
||||
}
|
||||
case types.ADD_ROW:
|
||||
return {
|
||||
...state,
|
||||
track_rows: [ ...state.track_rows, action.item ]
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default trackReducer
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
const GET_ONE = 'GET_ONE'
|
||||
const UPDATE = 'UPDATE'
|
||||
const ADD_ROW = 'ADD_ROW'
|
||||
|
||||
export default ({
|
||||
GET_ONE,
|
||||
UPDATE,
|
||||
ADD_ROW
|
||||
})
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import types from './types'
|
||||
|
||||
const login = item => ({
|
||||
type: types.LOGIN_USER, item
|
||||
})
|
||||
|
||||
const logout = item => ({
|
||||
type: types.LOGOUT_USER, item
|
||||
})
|
||||
|
||||
export default {
|
||||
login,
|
||||
logout
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import userReducer from './reducers'
|
||||
export { default as userTypes } from './types'
|
||||
export { default as userActions } from './actions'
|
||||
|
||||
export default userReducer
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import AppService from '../../AppService'
|
||||
|
||||
import actions from './actions'
|
||||
|
||||
|
||||
let serviceUser = {}
|
||||
let response
|
||||
|
||||
const endpoint = 'user/'
|
||||
|
||||
// Authorization
|
||||
|
||||
export const postAuth = (username, password) => async (dispatch) => {
|
||||
let body = {
|
||||
username: username,
|
||||
password: password
|
||||
}
|
||||
return await AppService._post(
|
||||
endpoint + 'auth',
|
||||
body,
|
||||
AppService.defaultToken
|
||||
).then( response => {
|
||||
serviceUser = {
|
||||
id: response['response'].user.id,
|
||||
username: response['response'].user.username,
|
||||
email: response['response'].user.email,
|
||||
ip: response['response'].user.ip,
|
||||
city: response['response'].user.city,
|
||||
country: response['response'].user.country,
|
||||
token: response['response'].Authorization
|
||||
}
|
||||
dispatch(actions.login(serviceUser))
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteAuth = (token) => async (dispatch) => {
|
||||
response = await AppService._delete(
|
||||
endpoint + 'auth',
|
||||
token
|
||||
).then( () => {
|
||||
dispatch(actions.logout())
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
// User CRUD
|
||||
|
||||
export const registerUser = async (user) => {
|
||||
return await AppService._post(
|
||||
endpoint,
|
||||
user,
|
||||
AppService.defaultToken
|
||||
).then( response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUser = (user, id, token) => async (dispatch) => {
|
||||
return await AppService._patch(
|
||||
endpoint + id,
|
||||
user,
|
||||
token
|
||||
).then( response => {
|
||||
serviceUser = {
|
||||
id: response['response'].user.id,
|
||||
username: response['response'].user.username,
|
||||
email: response['response'].user.email,
|
||||
ip: response['response'].user.ip,
|
||||
city: response['response'].user.city,
|
||||
country: response['response'].user.country,
|
||||
token: response['response'].Authorization
|
||||
}
|
||||
dispatch(actions.login( serviceUser ))
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteUser = async (id, token) => {
|
||||
return await AppService._delete(
|
||||
endpoint + id,
|
||||
token
|
||||
).then( response => {
|
||||
deleteAuth(token)
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import types from './types'
|
||||
|
||||
const INITIAL_STATE = {
|
||||
id: -1,
|
||||
username: '',
|
||||
email: '',
|
||||
ip: '',
|
||||
city: '',
|
||||
country: '',
|
||||
token: ''
|
||||
}
|
||||
|
||||
const userReducer = (state = INITIAL_STATE, action) => {
|
||||
switch(action.type) {
|
||||
case types.LOGIN_USER:
|
||||
return {
|
||||
...state,
|
||||
id: action.item.id,
|
||||
username: action.item.username,
|
||||
email: action.item.email,
|
||||
ip: action.item.ip,
|
||||
city: action.item.city,
|
||||
country: action.item.country,
|
||||
token: action.item.token
|
||||
}
|
||||
case types.LOGOUT_USER:
|
||||
return {
|
||||
...state,
|
||||
id: -1,
|
||||
username: '',
|
||||
email: '',
|
||||
ip: '',
|
||||
city: '',
|
||||
country: '',
|
||||
token: ''
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default userReducer
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
const LOGIN_USER = 'LOGIN_USER'
|
||||
const LOGOUT_USER = 'LOGOUT_USER'
|
||||
|
||||
export default {
|
||||
LOGIN_USER,
|
||||
LOGOUT_USER
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#audioVisualizerDiv {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
|
||||
#audioMenu {
|
||||
height: 500px;
|
||||
width: 50px;
|
||||
left: 230px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
|
||||
div {
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#canvas {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#audioTitle {
|
||||
width: 50px;
|
||||
position: fixed;
|
||||
left: 310px;
|
||||
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
vertical-align: baseline;
|
||||
text-rendering: optimizeLegibility;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
text-align: center;
|
||||
|
||||
letter-spacing: -0.2em;
|
||||
line-height: 0.8em;
|
||||
|
||||
transition-duration: 10s;
|
||||
}
|
||||
|
||||
#audio {
|
||||
top: 90%;
|
||||
left: 300px;
|
||||
position: fixed;
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,31 +4,91 @@ body {
|
|||
font-family: Ubuntu;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
margin: 50px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ASCIIview {
|
||||
width: 100%;
|
||||
height: 70%;
|
||||
// index interface
|
||||
|
||||
.ASCIIchars {
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
vertical-align: baseline;
|
||||
text-rendering: optimizeLegibility;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
text-align: right;
|
||||
// index panel
|
||||
|
||||
letter-spacing: -0.2em;
|
||||
line-height: 0.8em;
|
||||
#panelDiv {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 80%;
|
||||
left: 400px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#Poland {
|
||||
width: 300px;
|
||||
// index console
|
||||
|
||||
#consoleDiv {
|
||||
padding: 50px;
|
||||
|
||||
.ASCIIview {
|
||||
width: 100%;
|
||||
height: 70%;
|
||||
|
||||
.ASCIIchars {
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
vertical-align: baseline;
|
||||
text-rendering: optimizeLegibility;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
text-align: right;
|
||||
|
||||
letter-spacing: -0.2em;
|
||||
line-height: 0.8em;
|
||||
}
|
||||
|
||||
#Poland {
|
||||
width: 300px;
|
||||
}
|
||||
#Russia {
|
||||
width: 600px;
|
||||
}
|
||||
#connect {
|
||||
width: 630px;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
margin-top: 290px;
|
||||
margin-left: -120px;
|
||||
transform: rotate(-14deg);
|
||||
}
|
||||
}
|
||||
#Russia {
|
||||
width: 600px;
|
||||
|
||||
input {
|
||||
background-color: rgba(0,0,0,0);
|
||||
color: rgb(172, 36, 36);
|
||||
font-family: Ubuntu;
|
||||
font-size: 16px;
|
||||
border: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
input:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.uploadInput {
|
||||
width: 0px !important;
|
||||
height: 0px !important;
|
||||
padding-top: 70px;
|
||||
padding-left: 400px;
|
||||
margin-left: 0px;
|
||||
color: rgba(172,36,36,1);
|
||||
font-family: Ubuntu;
|
||||
border: dashed 2px rgba(172,36,36,1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0px;
|
||||
font-family: Ubuntu;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
#songPanel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.songPanelColumn {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
|
||||
#songDetails {
|
||||
width: 95%;
|
||||
height: 85px;
|
||||
padding-right: 5%;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 25px;
|
||||
|
||||
#songCode {
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
#songThings {
|
||||
|
||||
#songAddress {
|
||||
text-align: right;
|
||||
padding-top: 10px;
|
||||
width: auto;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#songTitle {
|
||||
text-align: left;
|
||||
padding-top: 10px;
|
||||
width: auto;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#songText {
|
||||
width: 95%;
|
||||
overflow-y: scroll;
|
||||
padding-right: 5%;
|
||||
margin-bottom: 50px;
|
||||
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
|
||||
.textSection {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
||||
.generalText {
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
|
||||
.textHighlights {
|
||||
background-color: rgba(172,36,36,1);
|
||||
color: black;
|
||||
margin: 0;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.rowDetails {
|
||||
width: 90%;
|
||||
max-width: 90%;
|
||||
height: auto;
|
||||
display: none;
|
||||
|
||||
white-space: normal;
|
||||
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.rowDetailsOpen {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#songText::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#songComments {
|
||||
width: 90%;
|
||||
height: 50%;
|
||||
padding-right: 5%;
|
||||
margin-top: 50px;
|
||||
|
||||
#comments {
|
||||
height: 0px; //420px
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
transition-duration: 0.5s;
|
||||
|
||||
.commentDiv {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding-bottom: 20px;
|
||||
|
||||
.commentInfo {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.commentText {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#comments::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#commentAdd {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding-right: 5%;
|
||||
padding-left: 5%;
|
||||
height: 50px;
|
||||
color: rgba(172,36,36,1);
|
||||
font-family: Ubuntu;
|
||||
background-color: black;
|
||||
border: solid 1px rgba(172,36,36,1);
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
font-family: Ubuntu;
|
||||
color: rgba(172,36,36,1);
|
||||
}
|
||||
|
||||
#commentAddButton {
|
||||
width: 25%;
|
||||
height: 32.5px;
|
||||
padding-top: 18.5px;
|
||||
margin-left: 5%;
|
||||
display: none;
|
||||
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
border: solid 1px rgba(172,36,36,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#albumSongs {
|
||||
width: 90%;
|
||||
height: auto;
|
||||
padding: 5%;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue