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
|
yarn-error.log
|
||||||
.pnp/
|
.pnp/
|
||||||
.pnp.js
|
.pnp.js
|
||||||
|
|
||||||
# Yarn Integrity file
|
# Yarn Integrity file
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
|
||||||
|
package-lock.json
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,99 @@
|
||||||
## Music Service [ANSI / ASCII Only Chellenge]
|
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.gatsbyjs.org">
|
||||||
|
<img alt="Gatsby" src="https://www.gatsbyjs.org/monogram.svg" width="60" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h1 align="center">
|
||||||
|
Gatsby's default starter
|
||||||
|
</h1>
|
||||||
|
|
||||||
ReactJS / Redux / Gatsby / Sass
|
Kick off your project with this default boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
|
||||||
|
|
||||||
1. **Loading Page**
|
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.org/docs/gatsby-starters/)._
|
||||||
|
|
||||||

|
## 🚀 Quick start
|
||||||
|
|
||||||
2. **Track Page**
|
1. **Create a Gatsby site.**
|
||||||
|
|
||||||
Play audio
|
Use the Gatsby CLI to create a new site, specifying the default starter.
|
||||||
|
|
||||||

|
```shell
|
||||||
|
# create a new Gatsby site using the default starter
|
||||||
|
gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
|
||||||
|
```
|
||||||
|
|
||||||
Click on marked text (show text row description)
|
1. **Start developing.**
|
||||||
|
|
||||||

|
Navigate into your new site’s directory and start it up.
|
||||||
|
|
||||||
Click on input bar (show comments)
|
```shell
|
||||||
|
cd my-default-starter/
|
||||||
|
gatsby develop
|
||||||
|
```
|
||||||
|
|
||||||

|
1. **Open the source code and start editing!**
|
||||||
|
|
||||||
|
Your site is now running at `http://localhost:8000`!
|
||||||
|
|
||||||
|
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
|
||||||
|
|
||||||
|
Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
|
||||||
|
|
||||||
|
## 🧐 What's inside?
|
||||||
|
|
||||||
|
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
||||||
|
|
||||||
|
.
|
||||||
|
├── node_modules
|
||||||
|
├── src
|
||||||
|
├── .gitignore
|
||||||
|
├── .prettierrc
|
||||||
|
├── gatsby-browser.js
|
||||||
|
├── gatsby-config.js
|
||||||
|
├── gatsby-node.js
|
||||||
|
├── gatsby-ssr.js
|
||||||
|
├── LICENSE
|
||||||
|
├── package-lock.json
|
||||||
|
├── package.json
|
||||||
|
└── README.md
|
||||||
|
|
||||||
|
1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
|
||||||
|
|
||||||
|
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
|
||||||
|
|
||||||
|
3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
|
||||||
|
|
||||||
|
4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent.
|
||||||
|
|
||||||
|
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
|
||||||
|
|
||||||
|
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you’d like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
|
||||||
|
|
||||||
|
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
|
||||||
|
|
||||||
|
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
||||||
|
|
||||||
|
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
|
||||||
|
|
||||||
|
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won’t change this file directly).**
|
||||||
|
|
||||||
|
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project’s name, author, etc). This manifest is how npm knows which packages to install for your project.
|
||||||
|
|
||||||
|
12. **`README.md`**: A text file containing useful reference information about your project.
|
||||||
|
|
||||||
|
## 🎓 Learning Gatsby
|
||||||
|
|
||||||
|
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
|
||||||
|
|
||||||
|
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
|
||||||
|
|
||||||
|
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
|
||||||
|
|
||||||
|
## 💫 Deploy
|
||||||
|
|
||||||
|
[](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default)
|
||||||
|
|
||||||
|
[](https://zeit.co/import/project?template=https://github.com/gatsbyjs/gatsby-starter-default)
|
||||||
|
|
||||||
|
<!-- AUTO-GENERATED-CONTENT:END -->
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,14 @@ module.exports = {
|
||||||
//icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
|
//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
|
// this (optional) plugin enables Progressive Web App + Offline functionality
|
||||||
// To learn more, visit: https://gatsby.dev/offline
|
// To learn more, visit: https://gatsby.dev/offline
|
||||||
// `gatsby-plugin-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-manifest": "^2.4.0",
|
||||||
"gatsby-plugin-offline": "^3.2.0",
|
"gatsby-plugin-offline": "^3.2.0",
|
||||||
"gatsby-plugin-react-helmet": "^3.3.0",
|
"gatsby-plugin-react-helmet": "^3.3.0",
|
||||||
|
"gatsby-plugin-sass": "^2.3.10",
|
||||||
"gatsby-plugin-sharp": "^2.6.0",
|
"gatsby-plugin-sharp": "^2.6.0",
|
||||||
"gatsby-source-filesystem": "^2.3.0",
|
"gatsby-source-filesystem": "^2.3.0",
|
||||||
"gatsby-transformer-sharp": "^2.5.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",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.12.0",
|
"react": "^16.12.0",
|
||||||
"react-dom": "^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": {
|
"devDependencies": {
|
||||||
"prettier": "2.0.5"
|
"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++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div id='consoleDiv'>
|
||||||
<div>
|
<div id='0' style={displayNone}>
|
||||||
<div>
|
загрузка контента с функциональностью сайта
|
||||||
Ładowanie funkcjonalności / загрузка контента с функциональностью сайта
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div id='1' style={displayNone}>
|
||||||
Łączenie z serwerem / подключение к серверу
|
подключение к серверу
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div id='2' style={displayNone}>
|
||||||
Arłamów ============================ Петропавловск-Камчатский
|
>> >> Петропавловск-Камчатский
|
||||||
</div>
|
</div>
|
||||||
<div className='ASCIIview'>
|
<br />
|
||||||
|
<div className='ASCIIview' id='3' style={displayNone}>
|
||||||
<div className='ASCIIchars' id='Poland'>
|
<div className='ASCIIchars' id='Poland'>
|
||||||
=-¬¬ TF▄ <br />
|
=-¬¬ TF▄ <br />
|
||||||
.⌐ , .., <br />
|
.⌐ , .., <br />
|
||||||
|
|
@ -41,6 +115,9 @@ const indexConsole = ({ }) => {
|
||||||
` ∩ ─.-^ -, ▐ <br />
|
` ∩ ─.-^ -, ▐ <br />
|
||||||
` `'¬.[¬ <br />
|
` `'¬.[¬ <br />
|
||||||
` <br />
|
` <br />
|
||||||
|
</div>
|
||||||
|
<div className='ASCIIchars' id='connect'>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className='ASCIIchars' id='Russia'>
|
<div className='ASCIIchars' id='Russia'>
|
||||||
╓ⁿ`1 <br />
|
╓ⁿ`1 <br />
|
||||||
|
|
@ -93,8 +170,15 @@ const indexConsole = ({ }) => {
|
||||||
╙w,.═"``"^%,,,..^ ╢ <br />
|
╙w,.═"``"^%,,,..^ ╢ <br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<br />
|
||||||
Wczytywanie zasobów [###___________________________]
|
<div id='4' style={displayNone}>
|
||||||
|
Подключен!
|
||||||
|
</div>
|
||||||
|
<div id='5' style={displayNone}>
|
||||||
|
загрузка ресурсов
|
||||||
|
</div>
|
||||||
|
<div id='6' style={displayNone}>
|
||||||
|
[_________________________] 0%
|
||||||
</div>
|
</div>
|
||||||
</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,11 +4,27 @@ body {
|
||||||
font-family: Ubuntu;
|
font-family: Ubuntu;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
margin: 50px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ASCIIview {
|
// index interface
|
||||||
|
|
||||||
|
// index panel
|
||||||
|
|
||||||
|
#panelDiv {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 80%;
|
||||||
|
left: 400px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// index console
|
||||||
|
|
||||||
|
#consoleDiv {
|
||||||
|
padding: 50px;
|
||||||
|
|
||||||
|
.ASCIIview {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 70%;
|
height: 70%;
|
||||||
|
|
||||||
|
|
@ -31,4 +47,48 @@ body {
|
||||||
#Russia {
|
#Russia {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
|
#connect {
|
||||||
|
width: 630px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: left;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 290px;
|
||||||
|
margin-left: -120px;
|
||||||
|
transform: rotate(-14deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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