diff --git a/client/app/app.tsx b/client/app/app.tsx
index eb1f83f..a4a755e 100644
--- a/client/app/app.tsx
+++ b/client/app/app.tsx
@@ -1,9 +1,9 @@
-import 'babel-polyfill';
+import './scss/index.scss';
import { Provider } from 'mobx-react';
import React from 'react';
import ReactDOM from 'react-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 { Wrapper } from './wrapper';
@@ -18,6 +18,7 @@ const App: any = (): any => {
+
diff --git a/client/app/components/embedded-youtube/embedded-youtube.scss b/client/app/components/embedded-youtube/embedded-youtube.scss
new file mode 100644
index 0000000..5a5e64e
--- /dev/null
+++ b/client/app/components/embedded-youtube/embedded-youtube.scss
@@ -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;
+ }
+}
diff --git a/client/app/components/embedded-youtube/embedded-youtube.tsx b/client/app/components/embedded-youtube/embedded-youtube.tsx
new file mode 100644
index 0000000..0f887a2
--- /dev/null
+++ b/client/app/components/embedded-youtube/embedded-youtube.tsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/client/app/components/header/header.scss b/client/app/components/header/header.scss
index d57bf01..5dbd65f 100644
--- a/client/app/components/header/header.scss
+++ b/client/app/components/header/header.scss
@@ -11,6 +11,7 @@
align-items: center;
justify-content: space-between;
padding-right: 20px;
+ z-index: 100;
&__title-container {
display: flex;
diff --git a/client/app/components/index.ts b/client/app/components/index.ts
index 42edd04..732c2bb 100644
--- a/client/app/components/index.ts
+++ b/client/app/components/index.ts
@@ -1,3 +1,4 @@
+export * from './embedded-youtube/embedded-youtube';
export * from './header/header';
export * from './navbar/navbar';
export * from './sound-list/sound-list';
diff --git a/client/app/components/navbar/navbar.scss b/client/app/components/navbar/navbar.scss
index f6cf9b1..e123406 100644
--- a/client/app/components/navbar/navbar.scss
+++ b/client/app/components/navbar/navbar.scss
@@ -13,6 +13,7 @@
overflow-y: auto;
padding-bottom: 10px;
transition: 0.2s left ease-in-out;
+ z-index: 100;
&--open {
left: 0;
diff --git a/client/app/components/navbar/navbar.tsx b/client/app/components/navbar/navbar.tsx
index 1dcea14..b27a7ab 100644
--- a/client/app/components/navbar/navbar.tsx
+++ b/client/app/components/navbar/navbar.tsx
@@ -74,6 +74,7 @@ export class Navbar extends React.Component {
return (
{this.renderNavLink('Soundboard', '/', { exact: true })}
+ {this.renderNavLink('Video Archive', '/video-archive')}
{this.renderNavLink('Youtube Downloader', '/downloader')}
{this.renderNavLink('Clips', '/clips')}
{this.renderNavLink('Stats', '/stats')}
diff --git a/client/app/model/index.ts b/client/app/model/index.ts
index 5de7268..8a13ade 100644
--- a/client/app/model/index.ts
+++ b/client/app/model/index.ts
@@ -1,2 +1,3 @@
export * from './claims';
export * from './permissions';
+export * from './video-archive';
diff --git a/client/app/model/video-archive.ts b/client/app/model/video-archive.ts
new file mode 100644
index 0000000..3021409
--- /dev/null
+++ b/client/app/model/video-archive.ts
@@ -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;
+}
diff --git a/client/app/pages/index.ts b/client/app/pages/index.ts
index 34cca60..055d80e 100644
--- a/client/app/pages/index.ts
+++ b/client/app/pages/index.ts
@@ -4,3 +4,4 @@ export * from './not-found/not-found';
export * from './oauth/oauth';
export * from './soundboard/soundboard';
export * from './stats/stats';
+export * from './video-archive/video-archive';
diff --git a/client/app/pages/video-archive/video-archive.scss b/client/app/pages/video-archive/video-archive.scss
new file mode 100644
index 0000000..90b2fd5
--- /dev/null
+++ b/client/app/pages/video-archive/video-archive.scss
@@ -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;
+ }
+}
diff --git a/client/app/pages/video-archive/video-archive.tsx b/client/app/pages/video-archive/video-archive.tsx
new file mode 100644
index 0000000..59c0d10
--- /dev/null
+++ b/client/app/pages/video-archive/video-archive.tsx
@@ -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
{
+ 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 (
+
+ );
+ }
+
+ renderArchives() {
+ return this.state.archives.map((v, k) => (
+
+
+
+
+ {v.title}
+
+
+ {v.uploaded_by} -{' '}
+ {DateTime.fromISO(v.created_at).toLocaleString()}
+
+
+
+ ));
+ }
+
+ render() {
+ const { claims } = this.props.appStore;
+ return (
+
+ {claims && claims.permissions > Permissions.User && this.renderForm()}
+
{this.renderArchives()}
+
+ );
+ }
+}
diff --git a/client/app/scss/grid.scss b/client/app/scss/grid.scss
new file mode 100644
index 0000000..8c03ae5
--- /dev/null
+++ b/client/app/scss/grid.scss
@@ -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;
+ }
+}
diff --git a/client/app/scss/index.scss b/client/app/scss/index.scss
index fa71f5e..85dbf16 100644
--- a/client/app/scss/index.scss
+++ b/client/app/scss/index.scss
@@ -1,5 +1,14 @@
@import '~normalize.css/normalize.css';
@import '~font-awesome/css/font-awesome.css';
+@import '~nprogress/nprogress.css';
+
+@import './mixins.scss';
+@import './variables.scss';
+
@import './style.scss';
+
@import './button.scss';
@import './card.scss';
+@import './input.scss';
+@import './grid.scss';
+@import './nprogress.scss';
diff --git a/client/app/scss/input.scss b/client/app/scss/input.scss
new file mode 100644
index 0000000..d8ebeda
--- /dev/null
+++ b/client/app/scss/input.scss
@@ -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;
+ }
+}
diff --git a/client/app/scss/mixins.scss b/client/app/scss/mixins.scss
index eb435c4..34e07af 100644
--- a/client/app/scss/mixins.scss
+++ b/client/app/scss/mixins.scss
@@ -3,3 +3,9 @@
@content;
}
}
+
+@mixin smallScreen {
+ @media only screen and (max-width: 768px) {
+ @content;
+ }
+}
diff --git a/client/app/scss/nprogress.scss b/client/app/scss/nprogress.scss
new file mode 100644
index 0000000..410bf15
--- /dev/null
+++ b/client/app/scss/nprogress.scss
@@ -0,0 +1,5 @@
+// override nprogress css
+
+#nprogress .bar {
+ background: $red;
+}
diff --git a/client/app/scss/style.scss b/client/app/scss/style.scss
index 2160d80..ac9b3f0 100644
--- a/client/app/scss/style.scss
+++ b/client/app/scss/style.scss
@@ -1,6 +1,3 @@
-@import './variables.scss';
-@import './mixins.scss';
-
html {
font-family: 'Roboto', sans-serif;
}
@@ -29,13 +26,16 @@ i {
body {
background-color: $gray1;
color: $white;
- // padding-left: $navbarWidth;
}
.flex {
display: flex;
}
+.flex--v-center {
+ align-items: center;
+}
+
.content {
padding: 20px;
@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 {
flex: 1;
@@ -65,3 +55,19 @@ body {
word-break: break-word;
word-wrap: break-word;
}
+
+.color {
+ &__red {
+ color: $red;
+ }
+
+ &__primary {
+ color: $primaryBlue;
+ }
+}
+
+.ellipsis {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
diff --git a/client/app/scss/variables.scss b/client/app/scss/variables.scss
index b8f1972..d82be8e 100644
--- a/client/app/scss/variables.scss
+++ b/client/app/scss/variables.scss
@@ -2,6 +2,7 @@ $navbarWidth: 200px;
// colors
$primaryBlue: #7289da;
+$red: #dd6e6e;
$white: darken(white, 20%);
$gray1: #2e3136;
diff --git a/client/app/services/archive.service.ts b/client/app/services/archive.service.ts
new file mode 100644
index 0000000..2e0cb79
--- /dev/null
+++ b/client/app/services/archive.service.ts
@@ -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 {
+ const data = (await axios.get('/api/video-archive')).data.data;
+ return _.orderBy(data, 'created_at', ['desc']);
+ }
+
+ public static postVideoArchive(data: any): Promise {
+ return axios.post('/api/video-archive', data);
+ }
+}
diff --git a/client/app/services/axios.service.ts b/client/app/services/axios.service.ts
index b9f16f4..12ff7c0 100644
--- a/client/app/services/axios.service.ts
+++ b/client/app/services/axios.service.ts
@@ -1,14 +1,29 @@
import ax from 'axios';
+import nprogress from 'nprogress';
+
+nprogress.configure({ showSpinner: false });
export const axios = ax.create();
axios.interceptors.request.use(
config => {
+ nprogress.start();
// Do something before request is sent
return config;
},
- function(error) {
+ error => {
// Do something with request error
return Promise.reject(error);
},
);
+
+axios.interceptors.response.use(
+ config => {
+ nprogress.done();
+ return config;
+ },
+ error => {
+ nprogress.done();
+ return Promise.reject(error);
+ },
+);
diff --git a/client/app/util.ts b/client/app/util.ts
index e93b9c8..dbaca99 100644
--- a/client/app/util.ts
+++ b/client/app/util.ts
@@ -8,7 +8,7 @@ const getScreenWidth = () => {
};
const isMobileScreen = () => {
- return getScreenWidth() < 520;
+ return getScreenWidth() < 768;
};
export const Util = {
diff --git a/client/app/wrapper.tsx b/client/app/wrapper.tsx
index 8e26563..7940396 100644
--- a/client/app/wrapper.tsx
+++ b/client/app/wrapper.tsx
@@ -2,8 +2,6 @@ import { inject, observer } from 'mobx-react';
import React from 'react';
import { withRouter } from 'react-router';
import { Header, Navbar } from './components';
-//styling
-import './scss/index.scss';
import { Util } from './util';
import './wrapper.scss';
diff --git a/client/package-lock.json b/client/package-lock.json
index 42abe9b..c402bea 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "go-discord-bot",
- "version": "0.6.0",
+ "version": "0.7.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -24,11 +24,21 @@
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.110.tgz",
"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": {
"version": "10.3.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.4.tgz",
"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": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/query-string/-/query-string-6.1.0.tgz",
@@ -351,6 +361,11 @@
"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": {
"version": "3.1.0",
"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",
"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": {
"version": "1.0.1",
"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": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
@@ -5696,6 +5692,11 @@
"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": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
@@ -5891,6 +5892,28 @@
"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": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -6292,6 +6315,11 @@
"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": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
diff --git a/client/package.json b/client/package.json
index 7ae7a10..ef1a3f7 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "go-discord-bot",
- "version": "0.6.0",
+ "version": "0.7.0",
"description": "Client for go-discord-bot",
"scripts": {
"build": "NODE_ENV=prod webpack -p --progress --colors",
@@ -13,7 +13,9 @@
"@types/chart.js": "^2.7.22",
"@types/jwt-decode": "^2.2.1",
"@types/lodash": "^4.14.110",
+ "@types/luxon": "^1.2.2",
"@types/node": "^10.3.4",
+ "@types/nprogress": "0.0.29",
"@types/query-string": "^6.1.0",
"@types/react": "^16.4.1",
"@types/react-chartjs-2": "^2.5.7",
@@ -32,17 +34,19 @@
"chart.js": "^2.7.2",
"clean-webpack-plugin": "^0.1.14",
"css-loader": "^0.28.11",
- "extract-text-webpack-plugin": "^4.0.0-beta.0",
"favicons-webpack-plugin": "0.0.9",
"file-loader": "^1.1.11",
"font-awesome": "^4.7.0",
"html-webpack-plugin": "^3.2.0",
"jwt-decode": "^2.2.0",
"lodash": "^4.17.10",
+ "luxon": "^1.3.3",
+ "mini-css-extract-plugin": "^0.4.2",
"mobx": "^5.0.3",
"mobx-react": "^5.2.5",
"node-sass": "^4.9.0",
"normalize.css": "^8.0.0",
+ "nprogress": "^0.2.0",
"postcss-loader": "^2.1.5",
"query-string": "^6.1.0",
"react": "^16.4.1",
diff --git a/client/webpack.config.js b/client/webpack.config.js
index 9f1f2b8..5d6c264 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -1,5 +1,5 @@
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 FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const path = require('path');
@@ -29,17 +29,29 @@ module.exports = {
},
{
test: /\.scss$/,
- use: ExtractTextPlugin.extract({
- fallback: 'style-loader',
- use: ['css-loader', 'postcss-loader', 'sass-loader'],
- }),
+ use: [
+ {
+ loader: MiniCssExtractPlugin.loader,
+ options: {
+ publicPath: './.',
+ },
+ },
+ 'css-loader',
+ // 'postcss-loader',
+ 'sass-loader',
+ ],
},
{
test: /\.css$/,
- use: ExtractTextPlugin.extract({
- fallback: 'style-loader',
- use: ['css-loader'],
- }),
+ use: [
+ {
+ loader: MiniCssExtractPlugin.loader,
+ options: {
+ publicPath: './.',
+ },
+ },
+ 'css-loader',
+ ],
},
{
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
@@ -66,10 +78,9 @@ module.exports = {
verbose: true,
allowExternal: true,
}),
- new ExtractTextPlugin({
+ new MiniCssExtractPlugin({
filename: '[name].[hash].css',
- disable: false,
- allChunks: true,
+ chunkFilename: '[id].css',
}),
new HtmlWebpackPlugin({
filename: 'index.html',
diff --git a/config.template.json b/config.template.json
index 3022f04..8097668 100644
--- a/config.template.json
+++ b/config.template.json
@@ -3,6 +3,7 @@
"client_id": "",
"client_secret": "",
"redirect_uri": "https://localhost/oauth",
+ "default_room_id": "",
"bot_prefix": "#",
diff --git a/server/bot/bot.go b/server/bot/bot.go
index fd57309..b5cceba 100644
--- a/server/bot/bot.go
+++ b/server/bot/bot.go
@@ -7,6 +7,8 @@ import (
log "github.com/sirupsen/logrus"
)
+var session *discordgo.Session
+
// Start the bot
func Start(token string) *discordgo.Session {
// initialize connection
@@ -25,13 +27,34 @@ func Start(token string) *discordgo.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{}) {
session.AddHandler(handler)
}
func connect(token string) *discordgo.Session {
// 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 {
log.Error(err)
diff --git a/server/config/config.go b/server/config/config.go
index 51b9751..87f4426 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -13,16 +13,17 @@ var (
)
type configType struct {
- Token string `json:"token"`
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
- RedirectURI string `json:"redirect_uri"`
- BotPrefix string `json:"bot_prefix"` //prefix to use for bot commands
- AdminEmails []string `json:"admin_emails"`
- ModEmails []string `json:"mod_emails"`
- ServerAddr string `json:"server_addr"`
- JWTSecret string `json:"jwt_secret"`
- Logger bool `json:"logger"`
+ Token string `json:"token"`
+ ClientID string `json:"client_id"`
+ ClientSecret string `json:"client_secret"`
+ RedirectURI string `json:"redirect_uri"`
+ BotPrefix string `json:"bot_prefix"` //prefix to use for bot commands
+ AdminEmails []string `json:"admin_emails"`
+ ModEmails []string `json:"mod_emails"`
+ ServerAddr string `json:"server_addr"`
+ JWTSecret string `json:"jwt_secret"`
+ Logger bool `json:"logger"`
+ DefaultRoomID string `json:"default_room_id"`
// hard coded folder paths
SoundsPath string
diff --git a/server/webserver/routes/video_archive.go b/server/webserver/routes/video-archive.go
similarity index 76%
rename from server/webserver/routes/video_archive.go
rename to server/webserver/routes/video-archive.go
index 401ba8e..334dbb4 100644
--- a/server/webserver/routes/video_archive.go
+++ b/server/webserver/routes/video-archive.go
@@ -4,6 +4,7 @@ import (
"errors"
"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/webserver/middleware"
"github.com/mgerb/go-discord-bot/server/webserver/model"
@@ -13,11 +14,11 @@ import (
// AddVideoArchiveRoutes -
func AddVideoArchiveRoutes(group *gin.RouterGroup) {
- group.GET("/video-archives", listVideoArchivesHandler)
+ group.GET("/video-archive", listVideoArchivesHandler)
authGroup := group.Group("", middleware.AuthorizedJWT())
- authGroup.POST("/video-archives", middleware.AuthPermissions(middleware.PermMod), postVideoArchivesHandler)
- authGroup.DELETE("/video-archives/:id", middleware.AuthPermissions(middleware.PermAdmin), deleteVideoArchivesHandler)
+ authGroup.POST("/video-archive", middleware.AuthPermissions(middleware.PermMod), postVideoArchivesHandler)
+ authGroup.DELETE("/video-archive/:id", middleware.AuthPermissions(middleware.PermAdmin), deleteVideoArchivesHandler)
}
func listVideoArchivesHandler(c *gin.Context) {
@@ -100,5 +101,9 @@ func postVideoArchivesHandler(c *gin.Context) {
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")
}