diff --git a/.gitignore b/.gitignore index 0e2d0f8..e927834 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,14 @@ node_modules yarn-error* vendor bot -sounds -clips debug -youtube go-discord-bot -data.db .wwp-cache -data +tmp + +/sounds +/clips +/youtube + +/data +/data.db diff --git a/.vscode/settings.json b/.vscode/settings.json index ad92582..1589eb1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "editor.formatOnSave": true + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": true + } } diff --git a/client/app/Wrapper.tsx b/client/app/Wrapper.tsx deleted file mode 100644 index 9863fc9..0000000 --- a/client/app/Wrapper.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { Navbar } from './components/Navbar'; - -//styling -import './scss/index.scss'; - -export class Wrapper extends React.Component { - constructor(props: any) { - super(props); - } - - render() { - return ( -
- -
{this.props.children}
-
- ); - } -} diff --git a/client/app/app.tsx b/client/app/app.tsx index d044ac4..eb1f83f 100644 --- a/client/app/app.tsx +++ b/client/app/app.tsx @@ -1,31 +1,27 @@ +import 'babel-polyfill'; +import { Provider } from 'mobx-react'; import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; - -import { Wrapper } from './Wrapper'; -import { Home } from './pages/Home/Home'; -import { Soundboard } from './pages/Soundboard/Soundboard'; -import { NotFound } from './pages/NotFound/NotFound'; -import { Downloader } from './pages/Downloader/Downloader'; -import { Clips } from './pages/Clips'; -import { Oauth } from './pages/oauth/oauth'; -import { Stats } from './pages/stats/stats'; -import 'babel-polyfill'; +import { Clips, Downloader, NotFound, Oauth, Soundboard, Stats } from './pages'; +import { rootStoreInstance } from './stores'; +import { Wrapper } from './wrapper'; const App: any = (): any => { return ( - - - - - - - - - - - + + + + + + + + + + + + ); }; diff --git a/client/app/components/Navbar/Navbar.tsx b/client/app/components/Navbar/Navbar.tsx deleted file mode 100644 index 581267f..0000000 --- a/client/app/components/Navbar/Navbar.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React from 'react'; -import { NavLink } from 'react-router-dom'; -import jwt_decode from 'jwt-decode'; -import { OauthService, StorageService } from '../../services'; -import './Navbar.scss'; - -interface Props {} - -interface State { - token: string | null; - email?: string; - oauthUrl?: string; -} - -export class Navbar extends React.Component { - constructor(props: Props) { - super(props); - this.state = { - token: null, - }; - } - - componentDidMount() { - this.loadOauthUrl(); - const token = StorageService.getJWT(); - - if (token) { - const claims: any = jwt_decode(token); - const email = claims['email']; - this.setState({ token, email }); - } - } - - async loadOauthUrl() { - try { - const oauthUrl = await OauthService.getOauthUrl(); - this.setState({ oauthUrl }); - } catch (e) { - console.error(e); - } - } - - private logout = () => { - StorageService.clear(); - window.location.href = '/'; - }; - - renderLoginButton() { - if (!this.state.oauthUrl) { - return null; - } - - return !this.state.token ? ( - - Login - - ) : ( - - Logout - - ); - } - - render() { - return ( -
-
Sound Bot
- - Home - - - Soundboard - - - Youtube Downloader - - - Clips - - - Stats - - - {this.renderLoginButton()} - - {this.state.email &&
{this.state.email}
} -
- ); - } -} diff --git a/client/app/components/Navbar/index.ts b/client/app/components/Navbar/index.ts deleted file mode 100644 index e8a6562..0000000 --- a/client/app/components/Navbar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Navbar'; diff --git a/client/app/components/SoundList/index.ts b/client/app/components/SoundList/index.ts deleted file mode 100644 index 81dc08b..0000000 --- a/client/app/components/SoundList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SoundList'; diff --git a/client/app/components/header/header.scss b/client/app/components/header/header.scss new file mode 100644 index 0000000..d57bf01 --- /dev/null +++ b/client/app/components/header/header.scss @@ -0,0 +1,37 @@ +@import '../../scss/variables'; + +.header { + position: fixed; + top: 0; + left: 0; + background: linear-gradient(to right, $primaryBlue, darken($primaryBlue, 20%)); + height: 50px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + padding-right: 20px; + + &__title-container { + display: flex; + align-items: center; + } + + &__nav-button { + display: flex; + justify-content: center; + align-items: center; + width: 50px; + height: 50px; + margin-right: 10px; + background: $primaryBlue; + border: none; + color: $white; + border-right: 1px solid darken($primaryBlue, 2%); + cursor: pointer; + outline: none; + &:hover { + background: darken($primaryBlue, 5%); + } + } +} diff --git a/client/app/components/header/header.tsx b/client/app/components/header/header.tsx new file mode 100644 index 0000000..443ddaa --- /dev/null +++ b/client/app/components/header/header.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import './header.scss'; + +interface IProps { + onButtonClick: () => void; +} + +export class Header extends React.Component { + constructor(props: IProps) { + super(props); + } + + render() { + return ( +
+
+ +

Sound Bot

+
+ +
+ ); + } +} diff --git a/client/app/components/index.ts b/client/app/components/index.ts new file mode 100644 index 0000000..42edd04 --- /dev/null +++ b/client/app/components/index.ts @@ -0,0 +1,4 @@ +export * from './header/header'; +export * from './navbar/navbar'; +export * from './sound-list/sound-list'; +export * from './uploader/uploader'; diff --git a/client/app/components/Navbar/Navbar.scss b/client/app/components/navbar/navbar.scss similarity index 70% rename from client/app/components/Navbar/Navbar.scss rename to client/app/components/navbar/navbar.scss index 4d9350d..f6cf9b1 100644 --- a/client/app/components/Navbar/Navbar.scss +++ b/client/app/components/navbar/navbar.scss @@ -1,31 +1,25 @@ @import '../../scss/variables'; -.Navbar { +.navbar { position: fixed; display: flex; flex-direction: column; - top: 0; - left: 0; - height: 100%; + left: -$navbarWidth; + top: 50px; + height: calc(100% - 50px); width: $navbarWidth; background-color: $gray2; border-right: 1px solid darken($gray2, 2%); overflow-y: auto; padding-bottom: 10px; + transition: 0.2s left ease-in-out; + + &--open { + left: 0; + } } -.Navbar__header { - font-size: 25px; - min-height: 100px; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - background-color: $primaryBlue; - border-bottom: 1px solid $gray3; -} - -.Navbar__item { +.navbar__item { min-height: 50px; text-decoration: none; display: flex; @@ -39,18 +33,18 @@ background-color: $gray1; } - & + .Navbar__item { + & + & { border-top: 1px solid $gray3; } } -.Navbar__item--active { +.navbar__item--active { padding-left: 4px; border-right: 4px solid $primaryBlue; color: $primaryBlue !important; } -.Navbar__email { +.navbar__email { padding-top: 10px; flex: 1; display: flex; diff --git a/client/app/components/navbar/navbar.tsx b/client/app/components/navbar/navbar.tsx new file mode 100644 index 0000000..1dcea14 --- /dev/null +++ b/client/app/components/navbar/navbar.tsx @@ -0,0 +1,86 @@ +import React from 'react'; +import { NavLink } from 'react-router-dom'; +import { IClaims } from '../../model'; +import { OauthService, StorageService } from '../../services'; +import './navbar.scss'; + +interface Props { + claims?: IClaims; + open: boolean; + onNavClick: () => void; +} + +interface State { + oauthUrl?: string; +} + +export class Navbar extends React.Component { + constructor(props: Props) { + super(props); + this.state = {}; + } + + componentDidMount() { + this.loadOauthUrl(); + } + + async loadOauthUrl() { + const oauthUrl = await OauthService.getOauthUrl(); + if (oauthUrl) { + this.setState({ oauthUrl }); + } + } + + private logout = () => { + StorageService.clear(); + window.location.href = '/'; + }; + + renderLoginButton() { + const { claims } = this.props; + + if (!this.state.oauthUrl) { + return null; + } + + return !claims ? ( + + Login + + ) : ( + + Logout + + ); + } + + renderNavLink = (title: string, to: string, params?: any) => { + return ( + + {title} + + ); + }; + + render() { + const { claims, open } = this.props; + const openClass = open ? 'navbar--open' : ''; + return ( +
+ {this.renderNavLink('Soundboard', '/', { exact: true })} + {this.renderNavLink('Youtube Downloader', '/downloader')} + {this.renderNavLink('Clips', '/clips')} + {this.renderNavLink('Stats', '/stats')} + {this.renderLoginButton()} + + {claims && claims.email &&
{claims.email}
} +
+ ); + } +} diff --git a/client/app/components/SoundList/SoundList.scss b/client/app/components/sound-list/sound-list.scss similarity index 78% rename from client/app/components/SoundList/SoundList.scss rename to client/app/components/sound-list/sound-list.scss index 23cf2e1..66035d8 100644 --- a/client/app/components/SoundList/SoundList.scss +++ b/client/app/components/sound-list/sound-list.scss @@ -1,12 +1,12 @@ @import '../../scss/variables'; -.SoundList__item { +.sound-list__item { display: flex; justify-content: space-between; align-items: center; height: 50px; - & + .SoundList__item { + & + .sound-list__item { border-top: 1px solid $gray3; } } diff --git a/client/app/components/SoundList/SoundList.tsx b/client/app/components/sound-list/sound-list.tsx similarity index 91% rename from client/app/components/SoundList/SoundList.tsx rename to client/app/components/sound-list/sound-list.tsx index ea9a922..9cc9dd0 100644 --- a/client/app/components/SoundList/SoundList.tsx +++ b/client/app/components/sound-list/sound-list.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import './SoundList.scss'; +import './sound-list.scss'; interface Props { soundList: SoundType[]; @@ -64,8 +63,8 @@ export class SoundList extends React.Component { {soundList.length > 0 ? soundList.map((sound: SoundType, index: number) => { return ( -
-
{(sound.prefix || '') + sound.name}
+
+
{(sound.prefix || '') + sound.name}
{this.checkExtension(sound.extension) && this.state.showAudioControls[index] ? (