mirror of
https://github.com/mgerb/go-discord-bot
synced 2026-01-10 09:02:49 +00:00
UI done for video archiving
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import 'babel-polyfill';
|
import './scss/index.scss';
|
||||||
import { Provider } from 'mobx-react';
|
import { Provider } from 'mobx-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||||
import { Clips, Downloader, NotFound, Oauth, Soundboard, Stats } from './pages';
|
import { Clips, Downloader, NotFound, Oauth, Soundboard, Stats, VideoArchive } from './pages';
|
||||||
import { rootStoreInstance } from './stores';
|
import { rootStoreInstance } from './stores';
|
||||||
import { Wrapper } from './wrapper';
|
import { Wrapper } from './wrapper';
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@ const App: any = (): any => {
|
|||||||
<Route path="/clips" component={Clips} />
|
<Route path="/clips" component={Clips} />
|
||||||
<Route path="/oauth" component={Oauth} />
|
<Route path="/oauth" component={Oauth} />
|
||||||
<Route path="/stats" component={Stats} />
|
<Route path="/stats" component={Stats} />
|
||||||
|
<Route path="/video-archive" component={VideoArchive} />
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
|||||||
15
client/app/components/embedded-youtube/embedded-youtube.scss
Normal file
15
client/app/components/embedded-youtube/embedded-youtube.scss
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.embedded-youtube {
|
||||||
|
overflow: hidden;
|
||||||
|
padding-bottom: 56.25%;
|
||||||
|
position: relative;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
&__iframe {
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
client/app/components/embedded-youtube/embedded-youtube.tsx
Normal file
16
client/app/components/embedded-youtube/embedded-youtube.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import './embedded-youtube.scss';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
id: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EmbeddedYoutube = ({ id, className }: IProps) => {
|
||||||
|
const src = `https://www.youtube.com/embed/${id}`;
|
||||||
|
return (
|
||||||
|
<div className={`embedded-youtube ${className}`}>
|
||||||
|
<iframe src={src} className="embedded-youtube__iframe" allowFullScreen />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
&__title-container {
|
&__title-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './embedded-youtube/embedded-youtube';
|
||||||
export * from './header/header';
|
export * from './header/header';
|
||||||
export * from './navbar/navbar';
|
export * from './navbar/navbar';
|
||||||
export * from './sound-list/sound-list';
|
export * from './sound-list/sound-list';
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
transition: 0.2s left ease-in-out;
|
transition: 0.2s left ease-in-out;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
&--open {
|
&--open {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ export class Navbar extends React.Component<Props, State> {
|
|||||||
return (
|
return (
|
||||||
<div className={'navbar ' + openClass}>
|
<div className={'navbar ' + openClass}>
|
||||||
{this.renderNavLink('Soundboard', '/', { exact: true })}
|
{this.renderNavLink('Soundboard', '/', { exact: true })}
|
||||||
|
{this.renderNavLink('Video Archive', '/video-archive')}
|
||||||
{this.renderNavLink('Youtube Downloader', '/downloader')}
|
{this.renderNavLink('Youtube Downloader', '/downloader')}
|
||||||
{this.renderNavLink('Clips', '/clips')}
|
{this.renderNavLink('Clips', '/clips')}
|
||||||
{this.renderNavLink('Stats', '/stats')}
|
{this.renderNavLink('Stats', '/stats')}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from './claims';
|
export * from './claims';
|
||||||
export * from './permissions';
|
export * from './permissions';
|
||||||
|
export * from './video-archive';
|
||||||
|
|||||||
13
client/app/model/video-archive.ts
Normal file
13
client/app/model/video-archive.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export interface IVideoArchive {
|
||||||
|
author: string;
|
||||||
|
created_at: string;
|
||||||
|
date_published: string;
|
||||||
|
description: string;
|
||||||
|
duration: number;
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
updated_at: string;
|
||||||
|
uploaded_by: string;
|
||||||
|
url: string;
|
||||||
|
youtube_id: string;
|
||||||
|
}
|
||||||
@@ -4,3 +4,4 @@ export * from './not-found/not-found';
|
|||||||
export * from './oauth/oauth';
|
export * from './oauth/oauth';
|
||||||
export * from './soundboard/soundboard';
|
export * from './soundboard/soundboard';
|
||||||
export * from './stats/stats';
|
export * from './stats/stats';
|
||||||
|
export * from './video-archive/video-archive';
|
||||||
|
|||||||
14
client/app/pages/video-archive/video-archive.scss
Normal file
14
client/app/pages/video-archive/video-archive.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
.video-archive {
|
||||||
|
// custom card
|
||||||
|
&__card {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
padding: 0 0 10px;
|
||||||
|
max-width: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text-input {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
106
client/app/pages/video-archive/video-archive.tsx
Normal file
106
client/app/pages/video-archive/video-archive.tsx
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { DateTime } from 'luxon';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import React from 'react';
|
||||||
|
import { EmbeddedYoutube } from '../../components';
|
||||||
|
import { IVideoArchive, Permissions } from '../../model';
|
||||||
|
import { ArchiveService } from '../../services/archive.service';
|
||||||
|
import { AppStore } from '../../stores';
|
||||||
|
import './video-archive.scss';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
appStore: AppStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
archives: IVideoArchive[];
|
||||||
|
url: string;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@inject('appStore')
|
||||||
|
@observer
|
||||||
|
export class VideoArchive extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
archives: [],
|
||||||
|
url: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.loadArchives();
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadArchives() {
|
||||||
|
const archives = await ArchiveService.getVideoArchive();
|
||||||
|
if (archives) {
|
||||||
|
this.setState({
|
||||||
|
archives,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit = async (e: any) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { url } = this.state;
|
||||||
|
this.setState({ error: undefined });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ArchiveService.postVideoArchive({ url });
|
||||||
|
} catch (e) {
|
||||||
|
this.setState({ error: 'Invalid URL' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ url: '' });
|
||||||
|
this.loadArchives();
|
||||||
|
};
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
const { error, url } = this.state;
|
||||||
|
return (
|
||||||
|
<form className="flex flex--v-center" onSubmit={this.onSubmit}>
|
||||||
|
<input
|
||||||
|
className="input video-archive__text-input"
|
||||||
|
placeholder="Enter Youtube URL or ID..."
|
||||||
|
value={url}
|
||||||
|
onChange={e => this.setState({ url: e.target.value })}
|
||||||
|
/>
|
||||||
|
<input type="submit" className="button button--primary" style={{ marginLeft: '10px' }} />
|
||||||
|
{error && (
|
||||||
|
<span className="color__red" style={{ marginLeft: '5px' }}>
|
||||||
|
{error}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderArchives() {
|
||||||
|
return this.state.archives.map((v, k) => (
|
||||||
|
<div key={k} className="card video-archive__card test">
|
||||||
|
<EmbeddedYoutube id={v.youtube_id} />
|
||||||
|
<div style={{ padding: '10px 10px 0' }}>
|
||||||
|
<h3 style={{ margin: '0 0 5px' }} className="ellipsis" title={v.title}>
|
||||||
|
{v.title}
|
||||||
|
</h3>
|
||||||
|
<div>
|
||||||
|
<span className="color__red">{v.uploaded_by}</span> -{' '}
|
||||||
|
<small>{DateTime.fromISO(v.created_at).toLocaleString()}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { claims } = this.props.appStore;
|
||||||
|
return (
|
||||||
|
<div className="content">
|
||||||
|
{claims && claims.permissions > Permissions.User && this.renderForm()}
|
||||||
|
<div className="archive-grid">{this.renderArchives()}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
client/app/scss/grid.scss
Normal file
13
client/app/scss/grid.scss
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.archive-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 5px;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(500px, 1fr));
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
@import '~normalize.css/normalize.css';
|
@import '~normalize.css/normalize.css';
|
||||||
@import '~font-awesome/css/font-awesome.css';
|
@import '~font-awesome/css/font-awesome.css';
|
||||||
|
@import '~nprogress/nprogress.css';
|
||||||
|
|
||||||
|
@import './mixins.scss';
|
||||||
|
@import './variables.scss';
|
||||||
|
|
||||||
@import './style.scss';
|
@import './style.scss';
|
||||||
|
|
||||||
@import './button.scss';
|
@import './button.scss';
|
||||||
@import './card.scss';
|
@import './card.scss';
|
||||||
|
@import './input.scss';
|
||||||
|
@import './grid.scss';
|
||||||
|
@import './nprogress.scss';
|
||||||
|
|||||||
14
client/app/scss/input.scss
Normal file
14
client/app/scss/input.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
.input {
|
||||||
|
line-height: 38px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid $lightGray;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
height: 38px;
|
||||||
|
background: $gray5;
|
||||||
|
color: $white;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,3 +3,9 @@
|
|||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin smallScreen {
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
5
client/app/scss/nprogress.scss
Normal file
5
client/app/scss/nprogress.scss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// override nprogress css
|
||||||
|
|
||||||
|
#nprogress .bar {
|
||||||
|
background: $red;
|
||||||
|
}
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
@import './variables.scss';
|
|
||||||
@import './mixins.scss';
|
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
}
|
}
|
||||||
@@ -29,13 +26,16 @@ i {
|
|||||||
body {
|
body {
|
||||||
background-color: $gray1;
|
background-color: $gray1;
|
||||||
color: $white;
|
color: $white;
|
||||||
// padding-left: $navbarWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex--v-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@include tinyScreen {
|
@include tinyScreen {
|
||||||
@@ -43,16 +43,6 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid $lightGray;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
height: 30px;
|
|
||||||
background: $gray5;
|
|
||||||
color: $white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
@@ -65,3 +55,19 @@ body {
|
|||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color {
|
||||||
|
&__red {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__primary {
|
||||||
|
color: $primaryBlue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ $navbarWidth: 200px;
|
|||||||
|
|
||||||
// colors
|
// colors
|
||||||
$primaryBlue: #7289da;
|
$primaryBlue: #7289da;
|
||||||
|
$red: #dd6e6e;
|
||||||
$white: darken(white, 20%);
|
$white: darken(white, 20%);
|
||||||
|
|
||||||
$gray1: #2e3136;
|
$gray1: #2e3136;
|
||||||
|
|||||||
14
client/app/services/archive.service.ts
Normal file
14
client/app/services/archive.service.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import * as _ from 'lodash';
|
||||||
|
import { IVideoArchive } from '../model';
|
||||||
|
import { axios } from './axios.service';
|
||||||
|
|
||||||
|
export class ArchiveService {
|
||||||
|
public static async getVideoArchive(): Promise<IVideoArchive[]> {
|
||||||
|
const data = (await axios.get('/api/video-archive')).data.data;
|
||||||
|
return _.orderBy(data, 'created_at', ['desc']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static postVideoArchive(data: any): Promise<any> {
|
||||||
|
return axios.post('/api/video-archive', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,29 @@
|
|||||||
import ax from 'axios';
|
import ax from 'axios';
|
||||||
|
import nprogress from 'nprogress';
|
||||||
|
|
||||||
|
nprogress.configure({ showSpinner: false });
|
||||||
|
|
||||||
export const axios = ax.create();
|
export const axios = ax.create();
|
||||||
|
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
|
nprogress.start();
|
||||||
// Do something before request is sent
|
// Do something before request is sent
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
function(error) {
|
error => {
|
||||||
// Do something with request error
|
// Do something with request error
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
axios.interceptors.response.use(
|
||||||
|
config => {
|
||||||
|
nprogress.done();
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
nprogress.done();
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const getScreenWidth = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isMobileScreen = () => {
|
const isMobileScreen = () => {
|
||||||
return getScreenWidth() < 520;
|
return getScreenWidth() < 768;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Util = {
|
export const Util = {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import { inject, observer } from 'mobx-react';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import { Header, Navbar } from './components';
|
import { Header, Navbar } from './components';
|
||||||
//styling
|
|
||||||
import './scss/index.scss';
|
|
||||||
import { Util } from './util';
|
import { Util } from './util';
|
||||||
import './wrapper.scss';
|
import './wrapper.scss';
|
||||||
|
|
||||||
|
|||||||
68
client/package-lock.json
generated
68
client/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "go-discord-bot",
|
"name": "go-discord-bot",
|
||||||
"version": "0.6.0",
|
"version": "0.7.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -24,11 +24,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.110.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.110.tgz",
|
||||||
"integrity": "sha512-iXYLa6olt4tnsCA+ZXeP6eEW3tk1SulWeYyP/yooWfAtXjozqXgtX4+XUtMuOCfYjKGz3F34++qUc3Q+TJuIIw=="
|
"integrity": "sha512-iXYLa6olt4tnsCA+ZXeP6eEW3tk1SulWeYyP/yooWfAtXjozqXgtX4+XUtMuOCfYjKGz3F34++qUc3Q+TJuIIw=="
|
||||||
},
|
},
|
||||||
|
"@types/luxon": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-JziyQbl0YIE36lVLDMLhkEhZ1h3Do/+H6x908tXRhzPFrcGAyh7mJ44rhDff+R230RaeIUKeWnhoB8lH5SdsPA=="
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "10.3.4",
|
"version": "10.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.4.tgz",
|
||||||
"integrity": "sha512-YMLlzdeNnAyLrQew39IFRkMacAR5BqKGIEei9ZjdHsIZtv+ZWKYTu1i7QJhetxQ9ReXx8w5f+cixdHZG3zgMQA=="
|
"integrity": "sha512-YMLlzdeNnAyLrQew39IFRkMacAR5BqKGIEei9ZjdHsIZtv+ZWKYTu1i7QJhetxQ9ReXx8w5f+cixdHZG3zgMQA=="
|
||||||
},
|
},
|
||||||
|
"@types/nprogress": {
|
||||||
|
"version": "0.0.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.0.29.tgz",
|
||||||
|
"integrity": "sha1-BgvVEAIqAF8YQCNAMNMTL7kZVHE="
|
||||||
|
},
|
||||||
"@types/query-string": {
|
"@types/query-string": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/query-string/-/query-string-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/query-string/-/query-string-6.1.0.tgz",
|
||||||
@@ -351,6 +361,11 @@
|
|||||||
"uri-js": "3.0.2"
|
"uri-js": "3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ajv-errors": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk="
|
||||||
|
},
|
||||||
"ajv-keywords": {
|
"ajv-keywords": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz",
|
||||||
@@ -527,14 +542,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
|
||||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
|
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
|
||||||
},
|
},
|
||||||
"async": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
|
|
||||||
"requires": {
|
|
||||||
"lodash": "4.17.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"async-each": {
|
"async-each": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
||||||
@@ -3948,17 +3955,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extract-text-webpack-plugin": {
|
|
||||||
"version": "4.0.0-beta.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-4.0.0-beta.0.tgz",
|
|
||||||
"integrity": "sha512-Hypkn9jUTnFr0DpekNam53X47tXn3ucY08BQumv7kdGgeVUBLq3DJHJTi6HNxv4jl9W+Skxjz9+RnK0sJyqqjA==",
|
|
||||||
"requires": {
|
|
||||||
"async": "2.6.0",
|
|
||||||
"loader-utils": "1.1.0",
|
|
||||||
"schema-utils": "0.4.5",
|
|
||||||
"webpack-sources": "1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extract-zip": {
|
"extract-zip": {
|
||||||
"version": "1.6.6",
|
"version": "1.6.6",
|
||||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
|
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
|
||||||
@@ -5696,6 +5692,11 @@
|
|||||||
"yallist": "2.1.2"
|
"yallist": "2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"luxon": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-3CM0jpS3mbHwWoPYprX1/Zsd5esni0LkhMfSiSY6xQ3/M3pnct3OPWbWkQdEEl9MO9593k6PvDn1DhxCkpuZEw=="
|
||||||
|
},
|
||||||
"macaddress": {
|
"macaddress": {
|
||||||
"version": "0.2.8",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
|
||||||
@@ -5891,6 +5892,28 @@
|
|||||||
"dom-walk": "0.1.1"
|
"dom-walk": "0.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mini-css-extract-plugin": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-ots7URQH4wccfJq9Ssrzu2+qupbncAce4TmTzunI9CIwlQMp2XI+WNUw6xWF6MMAGAm1cbUVINrSjATaVMyKXg==",
|
||||||
|
"requires": {
|
||||||
|
"loader-utils": "1.1.0",
|
||||||
|
"schema-utils": "1.0.0",
|
||||||
|
"webpack-sources": "1.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"schema-utils": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
|
||||||
|
"requires": {
|
||||||
|
"ajv": "6.4.0",
|
||||||
|
"ajv-errors": "1.0.0",
|
||||||
|
"ajv-keywords": "3.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"minimalistic-assert": {
|
"minimalistic-assert": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
@@ -6292,6 +6315,11 @@
|
|||||||
"set-blocking": "2.0.0"
|
"set-blocking": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nprogress": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E="
|
||||||
|
},
|
||||||
"nth-check": {
|
"nth-check": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "go-discord-bot",
|
"name": "go-discord-bot",
|
||||||
"version": "0.6.0",
|
"version": "0.7.0",
|
||||||
"description": "Client for go-discord-bot",
|
"description": "Client for go-discord-bot",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "NODE_ENV=prod webpack -p --progress --colors",
|
"build": "NODE_ENV=prod webpack -p --progress --colors",
|
||||||
@@ -13,7 +13,9 @@
|
|||||||
"@types/chart.js": "^2.7.22",
|
"@types/chart.js": "^2.7.22",
|
||||||
"@types/jwt-decode": "^2.2.1",
|
"@types/jwt-decode": "^2.2.1",
|
||||||
"@types/lodash": "^4.14.110",
|
"@types/lodash": "^4.14.110",
|
||||||
|
"@types/luxon": "^1.2.2",
|
||||||
"@types/node": "^10.3.4",
|
"@types/node": "^10.3.4",
|
||||||
|
"@types/nprogress": "0.0.29",
|
||||||
"@types/query-string": "^6.1.0",
|
"@types/query-string": "^6.1.0",
|
||||||
"@types/react": "^16.4.1",
|
"@types/react": "^16.4.1",
|
||||||
"@types/react-chartjs-2": "^2.5.7",
|
"@types/react-chartjs-2": "^2.5.7",
|
||||||
@@ -32,17 +34,19 @@
|
|||||||
"chart.js": "^2.7.2",
|
"chart.js": "^2.7.2",
|
||||||
"clean-webpack-plugin": "^0.1.14",
|
"clean-webpack-plugin": "^0.1.14",
|
||||||
"css-loader": "^0.28.11",
|
"css-loader": "^0.28.11",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
|
||||||
"favicons-webpack-plugin": "0.0.9",
|
"favicons-webpack-plugin": "0.0.9",
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"jwt-decode": "^2.2.0",
|
"jwt-decode": "^2.2.0",
|
||||||
"lodash": "^4.17.10",
|
"lodash": "^4.17.10",
|
||||||
|
"luxon": "^1.3.3",
|
||||||
|
"mini-css-extract-plugin": "^0.4.2",
|
||||||
"mobx": "^5.0.3",
|
"mobx": "^5.0.3",
|
||||||
"mobx-react": "^5.2.5",
|
"mobx-react": "^5.2.5",
|
||||||
"node-sass": "^4.9.0",
|
"node-sass": "^4.9.0",
|
||||||
"normalize.css": "^8.0.0",
|
"normalize.css": "^8.0.0",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
"postcss-loader": "^2.1.5",
|
"postcss-loader": "^2.1.5",
|
||||||
"query-string": "^6.1.0",
|
"query-string": "^6.1.0",
|
||||||
"react": "^16.4.1",
|
"react": "^16.4.1",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
|
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@@ -29,17 +29,29 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
use: ExtractTextPlugin.extract({
|
use: [
|
||||||
fallback: 'style-loader',
|
{
|
||||||
use: ['css-loader', 'postcss-loader', 'sass-loader'],
|
loader: MiniCssExtractPlugin.loader,
|
||||||
}),
|
options: {
|
||||||
|
publicPath: './.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'css-loader',
|
||||||
|
// 'postcss-loader',
|
||||||
|
'sass-loader',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: ExtractTextPlugin.extract({
|
use: [
|
||||||
fallback: 'style-loader',
|
{
|
||||||
use: ['css-loader'],
|
loader: MiniCssExtractPlugin.loader,
|
||||||
}),
|
options: {
|
||||||
|
publicPath: './.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'css-loader',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
|
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
|
||||||
@@ -66,10 +78,9 @@ module.exports = {
|
|||||||
verbose: true,
|
verbose: true,
|
||||||
allowExternal: true,
|
allowExternal: true,
|
||||||
}),
|
}),
|
||||||
new ExtractTextPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: '[name].[hash].css',
|
filename: '[name].[hash].css',
|
||||||
disable: false,
|
chunkFilename: '[id].css',
|
||||||
allChunks: true,
|
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: 'index.html',
|
filename: 'index.html',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"client_id": "",
|
"client_id": "",
|
||||||
"client_secret": "",
|
"client_secret": "",
|
||||||
"redirect_uri": "https://localhost/oauth",
|
"redirect_uri": "https://localhost/oauth",
|
||||||
|
"default_room_id": "",
|
||||||
|
|
||||||
"bot_prefix": "#",
|
"bot_prefix": "#",
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var session *discordgo.Session
|
||||||
|
|
||||||
// Start the bot
|
// Start the bot
|
||||||
func Start(token string) *discordgo.Session {
|
func Start(token string) *discordgo.Session {
|
||||||
// initialize connection
|
// initialize connection
|
||||||
@@ -25,13 +27,34 @@ func Start(token string) *discordgo.Session {
|
|||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSession - get current discord session
|
||||||
|
func GetSession() *discordgo.Session {
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendEmbeddedNotification - sends notification to default room
|
||||||
|
func SendEmbeddedNotification(title, description string) {
|
||||||
|
if session == nil || config.Config.DefaultRoomID == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
embed := &discordgo.MessageEmbed{
|
||||||
|
Color: 0x42adf4,
|
||||||
|
Title: title,
|
||||||
|
Description: description,
|
||||||
|
}
|
||||||
|
|
||||||
|
session.ChannelMessageSendEmbed(config.Config.DefaultRoomID, embed)
|
||||||
|
}
|
||||||
|
|
||||||
func addHandler(session *discordgo.Session, handler interface{}) {
|
func addHandler(session *discordgo.Session, handler interface{}) {
|
||||||
session.AddHandler(handler)
|
session.AddHandler(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(token string) *discordgo.Session {
|
func connect(token string) *discordgo.Session {
|
||||||
// Create a new Discord session using the provided bot token.
|
// Create a new Discord session using the provided bot token.
|
||||||
session, err := discordgo.New("Bot " + token)
|
var err error
|
||||||
|
session, err = discordgo.New("Bot " + token)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ type configType struct {
|
|||||||
ServerAddr string `json:"server_addr"`
|
ServerAddr string `json:"server_addr"`
|
||||||
JWTSecret string `json:"jwt_secret"`
|
JWTSecret string `json:"jwt_secret"`
|
||||||
Logger bool `json:"logger"`
|
Logger bool `json:"logger"`
|
||||||
|
DefaultRoomID string `json:"default_room_id"`
|
||||||
|
|
||||||
// hard coded folder paths
|
// hard coded folder paths
|
||||||
SoundsPath string
|
SoundsPath string
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/mgerb/go-discord-bot/server/bot"
|
||||||
"github.com/mgerb/go-discord-bot/server/db"
|
"github.com/mgerb/go-discord-bot/server/db"
|
||||||
"github.com/mgerb/go-discord-bot/server/webserver/middleware"
|
"github.com/mgerb/go-discord-bot/server/webserver/middleware"
|
||||||
"github.com/mgerb/go-discord-bot/server/webserver/model"
|
"github.com/mgerb/go-discord-bot/server/webserver/model"
|
||||||
@@ -13,11 +14,11 @@ import (
|
|||||||
|
|
||||||
// AddVideoArchiveRoutes -
|
// AddVideoArchiveRoutes -
|
||||||
func AddVideoArchiveRoutes(group *gin.RouterGroup) {
|
func AddVideoArchiveRoutes(group *gin.RouterGroup) {
|
||||||
group.GET("/video-archives", listVideoArchivesHandler)
|
group.GET("/video-archive", listVideoArchivesHandler)
|
||||||
|
|
||||||
authGroup := group.Group("", middleware.AuthorizedJWT())
|
authGroup := group.Group("", middleware.AuthorizedJWT())
|
||||||
authGroup.POST("/video-archives", middleware.AuthPermissions(middleware.PermMod), postVideoArchivesHandler)
|
authGroup.POST("/video-archive", middleware.AuthPermissions(middleware.PermMod), postVideoArchivesHandler)
|
||||||
authGroup.DELETE("/video-archives/:id", middleware.AuthPermissions(middleware.PermAdmin), deleteVideoArchivesHandler)
|
authGroup.DELETE("/video-archive/:id", middleware.AuthPermissions(middleware.PermAdmin), deleteVideoArchivesHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listVideoArchivesHandler(c *gin.Context) {
|
func listVideoArchivesHandler(c *gin.Context) {
|
||||||
@@ -100,5 +101,9 @@ func postVideoArchivesHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostURL := "[Click here to see the full archive!](http://" + c.Request.Host + "/video-archive)"
|
||||||
|
youtubeURL := "https://youtu.be/" + videoArchive.YoutubeID
|
||||||
|
bot.SendEmbeddedNotification(videoArchive.Title, "**"+videoArchive.UploadedBy+"** archived a new video:\n"+youtubeURL+"\n\n"+hostURL)
|
||||||
|
|
||||||
response.Success(c, "saved")
|
response.Success(c, "saved")
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user