Fixes, theming & deploy files
This commit is contained in:
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FROM alpine:edge
|
||||||
|
MAINTAINER gltron
|
||||||
|
RUN apk --update add openjdk8-jre
|
||||||
|
COPY cloud32.jar /home/cloud32.jar
|
||||||
|
CMD ["java","-jar","/home/cloud32.jar"]
|
||||||
|
EXPOSE 8181
|
||||||
1
buildDocker.sh
Normal file
1
buildDocker.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
docker build . -t thomsb/c32java
|
||||||
8
buildJar.sh
Normal file
8
buildJar.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
cd client
|
||||||
|
npm run build
|
||||||
|
cp -r dist/* ../server/src/main/resources/public
|
||||||
|
cd ../server
|
||||||
|
mvn package
|
||||||
|
cp target/cloud32-0.0.1-SNAPSHOT.jar ../cloud32.jar
|
||||||
|
rm -rf ../client/dist
|
||||||
|
rm -rf src/main/resources/public/*
|
||||||
5
client/package-lock.json
generated
5
client/package-lock.json
generated
@@ -7313,6 +7313,11 @@
|
|||||||
"object-visit": "^1.0.0"
|
"object-visit": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"material-design-icons": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/material-design-icons/-/material-design-icons-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-mnHEh0chjrylHlGmbaaCA4zct78="
|
||||||
|
},
|
||||||
"md5.js": {
|
"md5.js": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||||
"buefy": "^0.8.20",
|
"buefy": "^0.8.20",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"material-design-icons": "^3.0.1",
|
||||||
"register-service-worker": "^1.7.1",
|
"register-service-worker": "^1.7.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-qrcode-reader": "^2.3.11",
|
"vue-qrcode-reader": "^2.3.11",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/2.5.94/css/materialdesignicons.min.css">
|
<link rel="stylesheet" href="//cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -3,17 +3,3 @@
|
|||||||
<router-view/>
|
<router-view/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
#app {
|
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
text-align: center;
|
|
||||||
color: #2c3e50;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav {
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
BIN
client/src/assets/Gravity-Regular.otf
Normal file
BIN
client/src/assets/Gravity-Regular.otf
Normal file
Binary file not shown.
289
client/src/assets/_overrides.scss
Normal file
289
client/src/assets/_overrides.scss
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
// Overrides
|
||||||
|
@import url("https://fonts.googleapis.com/css?family=Lato:400,700,400italic&display=swap");
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Gravity Regular';
|
||||||
|
src: url('Gravity-Regular.otf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
background-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
border-width: $border-width;
|
||||||
|
color: $white;
|
||||||
|
|
||||||
|
&.is-active,
|
||||||
|
&.is-focused,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 2px rgba($button-focus-border-color, 0.5);
|
||||||
|
}
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
&.is-hovered,
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($color, 7.5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active,
|
||||||
|
&.is-focused,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
border-color: $color;
|
||||||
|
box-shadow: 0 0 0 2px rgba($color, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: $grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input,
|
||||||
|
.textarea {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
box-shadow: none;
|
||||||
|
border-width: $border-width;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
&:after,
|
||||||
|
select {
|
||||||
|
border-width: $border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
&.has-addons {
|
||||||
|
.button,
|
||||||
|
.input,
|
||||||
|
.select {
|
||||||
|
margin-right: -$border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
background-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
$card-border-color: lighten($grey-darker, 5);
|
||||||
|
box-shadow: none;
|
||||||
|
border: $border-width solid $card-border-color;
|
||||||
|
background-color: $grey-darker;
|
||||||
|
border-radius: $radius;
|
||||||
|
|
||||||
|
.card-image {
|
||||||
|
img {
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: rgba($black-bis, 0.2);
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
background-color: rgba($black-bis, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer,
|
||||||
|
.card-footer-item {
|
||||||
|
border-width: $border-width;
|
||||||
|
border-color: $card-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
a:not(.button) {
|
||||||
|
color: $color-invert;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
border-radius: $radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
a {
|
||||||
|
transition: all 300ms ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-card-body {
|
||||||
|
background-color: $grey-darker;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-card-foot,
|
||||||
|
.modal-card-head {
|
||||||
|
border-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
background-color: $grey-dark;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-body {
|
||||||
|
border-width: $border-width;
|
||||||
|
border-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
border-radius: $radius;
|
||||||
|
|
||||||
|
&.is-transparent {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-primary {
|
||||||
|
.navbar-dropdown {
|
||||||
|
a.navbar-item.is-active {
|
||||||
|
background-color: $link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include touch {
|
||||||
|
.navbar-menu {
|
||||||
|
background-color: $navbar-background-color;
|
||||||
|
border-radius: 0 0 $radius $radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .navbar,
|
||||||
|
body > .navbar {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-link,
|
||||||
|
.pagination-next,
|
||||||
|
.pagination-previous {
|
||||||
|
border-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-block,
|
||||||
|
.panel-heading,
|
||||||
|
.panel-tabs {
|
||||||
|
border-width: $border-width;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-width: $border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-heading {
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tabs {
|
||||||
|
a {
|
||||||
|
border-width: $border-width;
|
||||||
|
margin-bottom: -$border-width;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
border-bottom-color: $link-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-block {
|
||||||
|
&:hover {
|
||||||
|
color: $link-hover;
|
||||||
|
|
||||||
|
.panel-icon {
|
||||||
|
color: $link-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
.panel-icon {
|
||||||
|
color: $link-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
a {
|
||||||
|
border-bottom-width: $border-width;
|
||||||
|
margin-bottom: -$border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
border-bottom-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-boxed {
|
||||||
|
a {
|
||||||
|
border-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.is-active a {
|
||||||
|
background-color: darken($grey-darker, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-toggle {
|
||||||
|
li a {
|
||||||
|
border-width: $border-width;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li + li {
|
||||||
|
margin-left: -$border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
// Colors
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
.navbar {
|
||||||
|
.navbar-dropdown {
|
||||||
|
.navbar-item:hover {
|
||||||
|
background-color: $navbar-dropdown-item-hover-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
114
client/src/assets/_variables.scss
Normal file
114
client/src/assets/_variables.scss
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
$grey-lighter: #dbdee0;
|
||||||
|
$grey-light: #8c9b9d;
|
||||||
|
$grey: darken($grey-light, 18);
|
||||||
|
$grey-dark: darken($grey, 18);
|
||||||
|
$grey-darker: darken($grey, 23);
|
||||||
|
|
||||||
|
$orange: #e67e22;
|
||||||
|
$yellow: #f1b70e;
|
||||||
|
$green: #2ecc71;
|
||||||
|
$turquoise: #26a8a2;
|
||||||
|
$blue: #3498db;
|
||||||
|
$purple: #8e44ad;
|
||||||
|
$red: #e74c3c;
|
||||||
|
$white-ter: #ecf0f1;
|
||||||
|
$primary: $turquoise;
|
||||||
|
$yellow-invert: #fff;
|
||||||
|
|
||||||
|
$family-sans-serif: "Gravity Regular", "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||||
|
"Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||||
|
$family-monospace: "Inconsolata", "Consolas", "Monaco", monospace;
|
||||||
|
|
||||||
|
$radius-small: 3px;
|
||||||
|
$radius: 0.4em;
|
||||||
|
$radius-large: 8px;
|
||||||
|
$size-6: 15px;
|
||||||
|
$size-7: 0.85em;
|
||||||
|
$title-weight: 500;
|
||||||
|
$subtitle-weight: 400;
|
||||||
|
$subtitle-color: $grey-dark;
|
||||||
|
|
||||||
|
$border-width: 2px;
|
||||||
|
$border: $grey;
|
||||||
|
|
||||||
|
$body-background-color: darken($grey-darker, 4);
|
||||||
|
$body-size: 15px;
|
||||||
|
|
||||||
|
$background: $grey-darker;
|
||||||
|
$footer-background-color: $background;
|
||||||
|
$button-background-color: $background;
|
||||||
|
$button-border-color: lighten($button-background-color, 15);
|
||||||
|
|
||||||
|
$title-color: #fff;
|
||||||
|
$subtitle-color: $grey-light;
|
||||||
|
$subtitle-strong-color: $grey-light;
|
||||||
|
|
||||||
|
$text: #fff;
|
||||||
|
$text-light: lighten($text, 10);
|
||||||
|
$text-strong: darken($text, 5);
|
||||||
|
|
||||||
|
$box-color: $text;
|
||||||
|
$box-background-color: $grey-dark;
|
||||||
|
$box-shadow: none;
|
||||||
|
|
||||||
|
$link: $turquoise;
|
||||||
|
$link-hover: lighten($link, 5);
|
||||||
|
$link-focus: darken($link, 5);
|
||||||
|
$link-active: darken($link, 5);
|
||||||
|
$link-focus-border: $grey-light;
|
||||||
|
|
||||||
|
$button-color: $primary;
|
||||||
|
$button-hover-color: darken($text, 5); // text-dark
|
||||||
|
$button-focus: darken($text, 5); // text-dark
|
||||||
|
$button-active-color: darken($text, 5); // text-dark
|
||||||
|
$button-disabled-background-color: $grey-light;
|
||||||
|
|
||||||
|
$control-height: 2.5em;
|
||||||
|
|
||||||
|
$input-color: $grey-darker;
|
||||||
|
$input-icon-color: $grey;
|
||||||
|
$input-icon-active-color: $input-color;
|
||||||
|
$input-hover-color: $grey-light;
|
||||||
|
$input-disabled-background-color: $grey-light;
|
||||||
|
$input-disabled-border: $grey-lighter;
|
||||||
|
|
||||||
|
$table-color: $text;
|
||||||
|
$table-head: $grey-lighter;
|
||||||
|
$table-background-color: $grey-dark;
|
||||||
|
$table-cell-border: 1px solid $grey;
|
||||||
|
|
||||||
|
$table-row-hover-background-color: $grey-darker;
|
||||||
|
$table-striped-row-even-background-color: $grey-darker;
|
||||||
|
$table-striped-row-even-hover-background-color: lighten($grey-darker, 2);
|
||||||
|
|
||||||
|
$pagination-color: $link;
|
||||||
|
$pagination-border-color: $border;
|
||||||
|
|
||||||
|
$navbar-height: 4rem;
|
||||||
|
|
||||||
|
$navbar-background-color: $primary;
|
||||||
|
$navbar-item-color: $text;
|
||||||
|
$navbar-item-hover-color: $link;
|
||||||
|
$navbar-item-hover-background-color: transparent;
|
||||||
|
$navbar-item-active-color: $link;
|
||||||
|
$navbar-dropdown-arrow: #fff;
|
||||||
|
$navbar-divider-background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
$navbar-dropdown-border-top: 1px solid $navbar-divider-background-color;
|
||||||
|
$navbar-dropdown-background-color: $primary;
|
||||||
|
$navbar-dropdown-item-hover-color: $grey-lighter;
|
||||||
|
$navbar-dropdown-item-hover-background-color: transparent;
|
||||||
|
$navbar-dropdown-item-active-background-color: transparent;
|
||||||
|
$navbar-dropdown-item-active-color: $link;
|
||||||
|
|
||||||
|
$dropdown-content-background-color: $background;
|
||||||
|
$dropdown-item-color: $text;
|
||||||
|
|
||||||
|
$progress-value-background-color: $grey-lighter;
|
||||||
|
|
||||||
|
$file-cta-background-color: $grey-darker;
|
||||||
|
|
||||||
|
$progress-bar-background-color: $grey-dark;
|
||||||
|
|
||||||
|
$panel-heading-background-color: $grey-dark;
|
||||||
|
|
||||||
|
$control-label: $grey-lighter;
|
||||||
6
client/src/assets/style.scss
Normal file
6
client/src/assets/style.scss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@import "~bulma/sass/utilities/_all";
|
||||||
|
@import "variables";
|
||||||
|
@import "~bulma";
|
||||||
|
@import "~buefy/src/scss/buefy";
|
||||||
|
@import "overrides";
|
||||||
|
// @import "~/node_modules/material-design-icons/iconfont/material-icons.css";
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<b-button @click="broadcastStatus">Force status update</b-button>
|
<b-button @click="broadcastStatus" icon-left="sync">Force status update</b-button>
|
||||||
|
<hr>
|
||||||
<b-table :data="usersList" striped hoverable>
|
<b-table :data="usersList" striped hoverable>
|
||||||
<template slot-scope="props">
|
<template slot-scope="props">
|
||||||
<b-table-column field="name" label="Name">
|
<b-table-column field="name" label="Name">
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column>
|
<b-table-column>
|
||||||
<b-button @click="kickUser" icon-left="karate" type="is-dark"/>
|
<b-button @click="kickUser(props.row.name)" icon-left="karate" type="is-dark"/>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
@@ -35,8 +36,8 @@ export default {
|
|||||||
broadcastStatus () {
|
broadcastStatus () {
|
||||||
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
|
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
|
||||||
},
|
},
|
||||||
kickUser () {
|
kickUser (target) {
|
||||||
|
this.$store.dispatch('rtc/kick', target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="invite">
|
||||||
<h1 class="subtitle">{{roomCode}}</h1>
|
<h1 class="subtitle">{{roomCode}}</h1>
|
||||||
<qrcode :value="roomCode" :options="{ width: 200 }"/>
|
<qrcode :value="roomCode" :options="{ width: 200 }"/>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,3 +21,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style local>
|
||||||
|
.invite {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<youtube
|
<youtube
|
||||||
ref="youtube"
|
ref="youtube"
|
||||||
|
v-bind:fitParent="true"
|
||||||
:video-id="roomStatus.current.linkID"
|
:video-id="roomStatus.current.linkID"
|
||||||
:player-vars="playerVars"
|
:player-vars="playerVars"
|
||||||
@playing="roomStatus.player.playing">
|
@playing="roomStatus.player.playing">
|
||||||
</youtube>
|
</youtube>
|
||||||
|
<hr>
|
||||||
<b-field position="is-centered">
|
<b-field position="is-centered">
|
||||||
<b-button class="playerButton" @click="play" icon-right="play"/>
|
<b-button class="playerButton" @click="play" :icon-right="roomStatus.player.playing ? 'pause' : 'play'"/>
|
||||||
<b-button class="playerButton" @click="mute" icon-right="volume-mute"/>
|
<b-button class="playerButton" @click="mute" icon-right="volume-mute"/>
|
||||||
<b-button class="playerButton" @click="skip" icon-right="skip-next" v-if="isAdmin"/>
|
<b-button class="playerButton" @click="skip" icon-right="skip-next" v-if="isAdmin"/>
|
||||||
<b-slider class="playerVolume" :min="0" :max="100" :value="100" @change="volume"/>
|
<b-slider class="playerVolume" :min="0" :max="100" :value="100" @change="volume"/>
|
||||||
@@ -22,7 +24,7 @@
|
|||||||
:disabled="!isAdmin"
|
:disabled="!isAdmin"
|
||||||
@change="seek"/>
|
@change="seek"/>
|
||||||
</b-field>
|
</b-field>
|
||||||
<h2 class="subtitle is-6">{{convertTimeCode(roomStatus.player.timeCode)}} / {{convertTimeCode(roomStatus.player.timeLength)}}</h2>
|
<h2 class="subtitle is-6 time">{{convertTimeCode(roomStatus.player.timeCode)}} / {{convertTimeCode(roomStatus.player.timeLength)}}</h2>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -43,14 +45,14 @@ export default {
|
|||||||
playerVars () {
|
playerVars () {
|
||||||
const adminVars = {
|
const adminVars = {
|
||||||
autoplay: 1,
|
autoplay: 1,
|
||||||
controls: 1,
|
controls: 0,
|
||||||
disablekb: 0,
|
disablekb: 0,
|
||||||
modestbranding: 1,
|
modestbranding: 1,
|
||||||
rel: 0
|
rel: 0
|
||||||
}
|
}
|
||||||
const userVars = {
|
const userVars = {
|
||||||
autoplay: 1,
|
autoplay: 1,
|
||||||
controls: 1,
|
controls: 0,
|
||||||
disablekb: 1,
|
disablekb: 1,
|
||||||
modestbranding: 1,
|
modestbranding: 1,
|
||||||
rel: 0
|
rel: 0
|
||||||
@@ -60,7 +62,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.player.addEventListener('onStateChange', this.playerStateChange)
|
this.player.addEventListener('onStateChange', this.playerStateChange)
|
||||||
setInterval(this.updateTimeCode, 1000)
|
// setInterval(this.updateTimeCode, 1000)
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
roomStatus: function (status) {
|
roomStatus: function (status) {
|
||||||
@@ -108,8 +110,10 @@ export default {
|
|||||||
if (this.settings.playLink) this.$store.dispatch('room/setTimeCode', await this.player.getCurrentTime())
|
if (this.settings.playLink) this.$store.dispatch('room/setTimeCode', await this.player.getCurrentTime())
|
||||||
},
|
},
|
||||||
convertTimeCode (timeCode) {
|
convertTimeCode (timeCode) {
|
||||||
const minutes = Math.round(timeCode / 60)
|
var minutes = Math.round(timeCode / 60)
|
||||||
const seconds = Math.round(timeCode % 60)
|
var seconds = Math.round(timeCode % 60)
|
||||||
|
if (minutes < 10) minutes = '0' + minutes
|
||||||
|
if (seconds < 10) seconds = '0' + seconds
|
||||||
return minutes + ':' + seconds
|
return minutes + ':' + seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,4 +135,8 @@ export default {
|
|||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<b-button icon-left="plus" @click="addLinkPrompt">Add link</b-button>
|
<b-button icon-left="plus" @click="addLinkPrompt">Add link</b-button>
|
||||||
|
<hr>
|
||||||
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
||||||
<template slot-scope="props">
|
<template slot-scope="props">
|
||||||
<b-table-column field="title" label="Title">
|
<b-table-column field="title" label="Title">
|
||||||
@@ -20,8 +21,9 @@
|
|||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column>
|
<b-table-column>
|
||||||
<b-button v-if="hasVoted(props.row)" icon-left="arrow-down-bold-outline" type="is-dark" @click="vote (props.row.link, props.row.linkID, false)"/>
|
<b-button v-if="hasVoted(props.row)" icon-left="arrow-down-bold-outline" type="is-primary" @click="vote (props.row.link, props.row.linkID, false)"/>
|
||||||
<b-button v-else icon-left="arrow-up-bold-outline" type="is-dark" @click="vote (props.row.link, props.row.linkID, true)"/>
|
<b-button v-else icon-left="arrow-up-bold-outline" type="is-primary" @click="vote (props.row.link, props.row.linkID, true)"/>
|
||||||
|
<b-button v-if="isAdmin" class="actionButton" icon-left="delete-forever" type="is-danger" @click="removePlay (props.row.linkID)"/>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
@@ -45,25 +47,27 @@ export default {
|
|||||||
message: 'Add a youtube link',
|
message: 'Add a youtube link',
|
||||||
trapFocus: true,
|
trapFocus: true,
|
||||||
inputAttrs: {
|
inputAttrs: {
|
||||||
placeholder: 'https://www.youtube.com/watch?v=YItIK09bpKk',
|
placeholder: 'https://www.youtube.com/watch?v=YItIK09bpKk'
|
||||||
minlength: 10
|
|
||||||
},
|
},
|
||||||
cancelText: 'Nah',
|
cancelText: 'Nah',
|
||||||
confirmText: 'Add',
|
confirmText: 'Add',
|
||||||
onConfirm: (link) => this.addLink(link)
|
onConfirm: (link) => this.addLink(link)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
addLink (link) {
|
async addLink (link) {
|
||||||
const linkID = this.$youtube.getIdFromUrl(link)
|
const linkID = this.$youtube.getIdFromUrl(link)
|
||||||
if (linkID === null) {
|
if (linkID === null) {
|
||||||
this.$buefy.toast.open('Invalid youtube link')
|
this.$buefy.toast.open('Invalid youtube link')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.vote(link, linkID, true)
|
const infos = await this.getInfos(linkID)
|
||||||
|
console.log(infos)
|
||||||
|
console.log(infos.title)
|
||||||
|
this.vote(infos.title, link, linkID, true)
|
||||||
},
|
},
|
||||||
vote (link, linkID, isPositive) {
|
vote (title, link, linkID, isPositive) {
|
||||||
if (this.isAdmin) {
|
if (this.isAdmin) {
|
||||||
this.$store.dispatch('room/vote', { link: link, linkID: linkID, isPositive: isPositive, voterName: this.$store.state.rtc.name })
|
this.$store.dispatch('room/vote', { title: title, link: link, linkID: linkID, isPositive: isPositive, voterName: this.$store.state.rtc.name })
|
||||||
} else {
|
} else {
|
||||||
this.sendVote(link, linkID, isPositive)
|
this.sendVote(link, linkID, isPositive)
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,20 @@ export default {
|
|||||||
},
|
},
|
||||||
hasVoted (play) {
|
hasVoted (play) {
|
||||||
return play.voters.includes(this.$store.state.rtc.name)
|
return play.voters.includes(this.$store.state.rtc.name)
|
||||||
|
},
|
||||||
|
removePlay (linkID) {
|
||||||
|
this.$store.dispatch('room/removePlay', linkID)
|
||||||
|
},
|
||||||
|
async getInfos (linkID) {
|
||||||
|
const response = await fetch('http://noembed.com/embed?format=json&' + 'url=https://www.youtube.com/watch?v=' + linkID)
|
||||||
|
return await response.json()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style local>
|
||||||
|
.actionButton {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
21
client/src/components/YTSearch.vue
Normal file
21
client/src/components/YTSearch.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'YTSearch',
|
||||||
|
methods: {
|
||||||
|
async search (query) {
|
||||||
|
const response = await fetch('https://www.googleapis.com/youtube/v3/search?q=' + query)
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -6,8 +6,8 @@ import store from './store'
|
|||||||
import Buefy from 'buefy'
|
import Buefy from 'buefy'
|
||||||
import VueYoutube from 'vue-youtube'
|
import VueYoutube from 'vue-youtube'
|
||||||
|
|
||||||
import 'buefy/dist/buefy.css'
|
// import 'buefy/dist/buefy.css'
|
||||||
// import './assets/style.scss'
|
import './assets/style.scss'
|
||||||
|
|
||||||
Vue.use(Buefy)
|
Vue.use(Buefy)
|
||||||
Vue.use(VueYoutube)
|
Vue.use(VueYoutube)
|
||||||
|
|||||||
@@ -1,205 +0,0 @@
|
|||||||
var name
|
|
||||||
var connections = new Map()
|
|
||||||
|
|
||||||
const configuration = {
|
|
||||||
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
|
|
||||||
}
|
|
||||||
|
|
||||||
const offerOptions = {
|
|
||||||
offerToReceiveAudio: 1,
|
|
||||||
offerToReceiveVideo: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleLogin (success) {
|
|
||||||
if (success === false) {
|
|
||||||
alert('try a different username')
|
|
||||||
} else {
|
|
||||||
loginDiv.style.display = 'none'
|
|
||||||
connectDiv.style.display = 'block'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createPeerConnection (target) {
|
|
||||||
console.log('CREATED PEER CONNECTION')
|
|
||||||
var connection = new RTCPeerConnection(configuration)
|
|
||||||
connections[target] = connection
|
|
||||||
|
|
||||||
connection.onicecandidate = function (event) {
|
|
||||||
if (event.candidate) {
|
|
||||||
send({
|
|
||||||
type: 'candidate',
|
|
||||||
name: name,
|
|
||||||
target: target,
|
|
||||||
candidate: event.candidate
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.onnegotiationneeded = function () { handleNegotiationNeededEvent(target) }
|
|
||||||
connection.ontrack = function (event) { handleTrackEvent(event) }
|
|
||||||
connection.onsignalingstatechange = function () { handleSignalingStateChangeEvent(connection) }
|
|
||||||
connection.oniceconnectionstatechange = function () { handleICEConnectionStateChangeEvent(connection) }
|
|
||||||
connection.onicegatheringstatechange = function () { handleICEGatheringStateChangeEvent(connection) }
|
|
||||||
|
|
||||||
// window.setInterval(getConnectionStats, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleICEConnectionStateChangeEvent (connection) {
|
|
||||||
console.log('ICE CONNECTION CHANGE ' + connection.iceConnectionState)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleICEGatheringStateChangeEvent (connection) {
|
|
||||||
console.log('ICE GATHERING CHANGE ' + connection.iceGatheringState)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function makeOffer (target) {
|
|
||||||
createPeerConnection(target)
|
|
||||||
|
|
||||||
var connection = connections[target]
|
|
||||||
|
|
||||||
var offer = await connection.createOffer()
|
|
||||||
send({
|
|
||||||
type: 'offer',
|
|
||||||
name: name,
|
|
||||||
target: target,
|
|
||||||
offer: offer
|
|
||||||
})
|
|
||||||
await connection.setLocalDescription(offer)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleOffer (offer, target) {
|
|
||||||
console.log('GOT OFFER FROM ' + target)
|
|
||||||
await createPeerConnection(target)
|
|
||||||
|
|
||||||
var connection = connections[target]
|
|
||||||
|
|
||||||
await connection.setRemoteDescription(new RTCSessionDescription(offer))
|
|
||||||
|
|
||||||
if (stream) {
|
|
||||||
console.log('STREAM DETECTED')
|
|
||||||
stream.getTracks().forEach((track) => {
|
|
||||||
console.log('ADDED TRACK')
|
|
||||||
connection.addTrack(track, stream)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var answer = await connection.createAnswer()
|
|
||||||
|
|
||||||
await connection.setLocalDescription(answer)
|
|
||||||
|
|
||||||
send({
|
|
||||||
type: 'answer',
|
|
||||||
name: name,
|
|
||||||
target: target,
|
|
||||||
answer: answer
|
|
||||||
})
|
|
||||||
|
|
||||||
for (let user of connections.keys()) {
|
|
||||||
console.log(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('CONNECTION SIZE ' + connections.size)
|
|
||||||
|
|
||||||
videoTitle.innerHTML = name + ' | ' + connections.size + ' users connected'
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleAnswer (answer, target) {
|
|
||||||
console.log('GOT ANSWER FROM ' + target)
|
|
||||||
var connection = connections[target]
|
|
||||||
await connection.setRemoteDescription(new RTCSessionDescription(answer))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleCandidate (candidate, target) {
|
|
||||||
console.log('GOT CANDIDATE FROM ' + target)
|
|
||||||
var connection = connections[target]
|
|
||||||
await connection.addIceCandidate(new RTCIceCandidate(candidate))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleNegotiationNeededEvent (target) {
|
|
||||||
console.log('NEGOTIATION NEEDED FROM ' + target)
|
|
||||||
|
|
||||||
var connection = connections[target]
|
|
||||||
var offer = await connection.createOffer(offerOptions)
|
|
||||||
|
|
||||||
await connection.setLocalDescription(offer)
|
|
||||||
|
|
||||||
send({
|
|
||||||
type: 'video-offer',
|
|
||||||
name: name,
|
|
||||||
target: target,
|
|
||||||
sdp: connection.localDescription
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleLeave () {
|
|
||||||
connections.forEach((connection) => {
|
|
||||||
connection.close()
|
|
||||||
connection = null
|
|
||||||
})
|
|
||||||
connections = new Map()
|
|
||||||
|
|
||||||
remoteVideo.pause()
|
|
||||||
remoteVideo.src = null
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleVideoOffer (sdp, target) {
|
|
||||||
console.log('GOT VIDEO OFFER FROM ' + target)
|
|
||||||
await createPeerConnection(target)
|
|
||||||
var connection = connections[target]
|
|
||||||
await connection.setRemoteDescription(new RTCSessionDescription(sdp))
|
|
||||||
|
|
||||||
if (stream) {
|
|
||||||
console.log('STREAM DETECTED')
|
|
||||||
stream.getTracks().forEach((track) => {
|
|
||||||
console.log('ADDED TRACK')
|
|
||||||
connection.addTrack(track, stream)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var answer = await connection.createAnswer()
|
|
||||||
await connection.setLocalDescription(answer)
|
|
||||||
|
|
||||||
send({
|
|
||||||
type: 'video-answer',
|
|
||||||
name: name,
|
|
||||||
target: target,
|
|
||||||
sdp: answer
|
|
||||||
})
|
|
||||||
|
|
||||||
// var keys = connections.keys().next().value
|
|
||||||
videoTitle.innerHTML = name + ' | connected to ' + target
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleVideoAnswer(sdp, target) {
|
|
||||||
console.log('GOT VIDEO ANSWER FROM ' + target)
|
|
||||||
|
|
||||||
var connection = connections[target]
|
|
||||||
await connection.setRemoteDescription(new RTCSessionDescription(sdp))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleSignalingStateChangeEvent (connection) {
|
|
||||||
console.log('STATE CHANGED TO : ' + connection.signalingState)
|
|
||||||
switch(connection.signalingState) {
|
|
||||||
case 'closed':
|
|
||||||
await connection.close()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTrackEvent (event) {
|
|
||||||
console.log('GOT TRACK')
|
|
||||||
remoteVideo.srcObject = event.streams[0]
|
|
||||||
videoDiv.style.display = 'block'
|
|
||||||
loadDiv.style.display = 'none'
|
|
||||||
}
|
|
||||||
|
|
||||||
function getConnectionStats () {
|
|
||||||
connections.forEach((connection, target) => {
|
|
||||||
console.log('[' + target + '] ' + connection.connectionState)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const rtc = {
|
|
||||||
send
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
const loginDiv = document.querySelector('#loginDiv')
|
|
||||||
const loginInput = document.querySelector('#loginInput')
|
|
||||||
const loginBt = document.querySelector('#loginBt')
|
|
||||||
|
|
||||||
const connectDiv = document.querySelector('#connectDiv')
|
|
||||||
const callInput = document.querySelector('#callInput')
|
|
||||||
const callDatalist = document.querySelector('#callDatalist')
|
|
||||||
const callBt = document.querySelector('#callBt')
|
|
||||||
const videoInput = document.querySelector('#videoInput')
|
|
||||||
|
|
||||||
const videoDiv = document.querySelector('#videoDiv')
|
|
||||||
const videoTitle = document.querySelector('#videoTitle')
|
|
||||||
const remoteVideo = document.querySelector('#video')
|
|
||||||
const disconnectBt = document.querySelector('#disconnectBt')
|
|
||||||
|
|
||||||
const loadDiv = document.querySelector('#loadDiv')
|
|
||||||
const titleDiv = document.querySelector('#titleDiv')
|
|
||||||
|
|
||||||
var stream
|
|
||||||
var users
|
|
||||||
|
|
||||||
loginDiv.style.display = 'block'
|
|
||||||
|
|
||||||
loginBt.addEventListener('click', function (event) {
|
|
||||||
name = loginInput.value
|
|
||||||
|
|
||||||
if (name.length > 0) {
|
|
||||||
send({
|
|
||||||
type: 'login',
|
|
||||||
name: name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
callBt.addEventListener('click', function () {
|
|
||||||
var callToUsername = callInput.value;
|
|
||||||
|
|
||||||
if (callToUsername.length > 0) {
|
|
||||||
makeOffer(callToUsername)
|
|
||||||
loadDiv.style.display = 'block'
|
|
||||||
titleDiv.style.display = 'none'
|
|
||||||
connectDiv.style.display = 'none'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
disconnectBt.addEventListener('click', function () {
|
|
||||||
send({
|
|
||||||
type: 'leave',
|
|
||||||
name: name
|
|
||||||
})
|
|
||||||
handleLeave()
|
|
||||||
videoDiv.style.display = 'none'
|
|
||||||
loginDiv.style.display = 'block'
|
|
||||||
titleDiv.style.display = 'block'
|
|
||||||
})
|
|
||||||
|
|
||||||
videoInput.addEventListener('change', function (event) {
|
|
||||||
remoteVideo.src = URL.createObjectURL(this.files[0])
|
|
||||||
|
|
||||||
videoDiv.style.display = 'block'
|
|
||||||
connectDiv.style.display = 'none'
|
|
||||||
titleDiv.style.display = 'none'
|
|
||||||
videoTitle.innerHTML = name + ' | ' + connections.size + ' users connected'
|
|
||||||
})
|
|
||||||
|
|
||||||
remoteVideo.onplay = function () {
|
|
||||||
console.log('ADD STREAM')
|
|
||||||
if (remoteVideo.mozCaptureStream()) stream = remoteVideo.mozCaptureStream()
|
|
||||||
else stream = remoteVideo.captureStream()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleUserlist(list) {
|
|
||||||
console.log('GOT USER LIST '+list)
|
|
||||||
users = Array.from(list)
|
|
||||||
console.log(' users '+users)
|
|
||||||
console.log(typeof users)
|
|
||||||
console.log(' users '+users)
|
|
||||||
callDatalist.innerHTML = ''
|
|
||||||
users.forEach(user => {
|
|
||||||
if(user != name) callDatalist.innerHTML += '<option value="'+user+'"/>'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleError(message) {
|
|
||||||
console.log('Error '+message)
|
|
||||||
alert(
|
|
||||||
'AWWW FUCK \n\n'
|
|
||||||
+message
|
|
||||||
+'\n\nYou should probably reload the page')
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// const conn = new WebSocket('wss://oozik.gltronic.ovh/')
|
|
||||||
const conn = new WebSocket('wss://localhost:8080')
|
|
||||||
|
|
||||||
conn.onopen = function () {
|
|
||||||
console.log('Connected to the signaling server')
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.onmessage = function (msg) {
|
|
||||||
console.log('Got message', msg.data)
|
|
||||||
|
|
||||||
var data = JSON.parse(msg.data)
|
|
||||||
|
|
||||||
switch (data.type) {
|
|
||||||
case 'login':
|
|
||||||
handleLogin(data.success)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'offer':
|
|
||||||
handleOffer(data.offer, data.name)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'answer':
|
|
||||||
handleAnswer(data.answer, data.name)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'candidate':
|
|
||||||
handleCandidate(data.candidate, data.name)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'userlist':
|
|
||||||
handleUserlist(data.users)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'leave':
|
|
||||||
handleLeave()
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'video-offer':
|
|
||||||
handleVideoOffer(data.sdp, data.name)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'video-answer':
|
|
||||||
handleVideoAnswer(data.sdp, data.name)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'error':
|
|
||||||
handleError(data.message)
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.onerror = function (err) {
|
|
||||||
console.log('Got error', err)
|
|
||||||
}
|
|
||||||
|
|
||||||
function send (message) {
|
|
||||||
console.log('Sended message', message)
|
|
||||||
conn.send(JSON.stringify(message))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const signal = {
|
|
||||||
send
|
|
||||||
}
|
|
||||||
@@ -38,10 +38,11 @@ const actions = {
|
|||||||
setTimeCode ({ commit }, timeCode) {
|
setTimeCode ({ commit }, timeCode) {
|
||||||
commit('SET_TIMECODE', timeCode)
|
commit('SET_TIMECODE', timeCode)
|
||||||
},
|
},
|
||||||
vote ({ commit, dispatch, state }, { link, linkID, isPositive, voterName }) {
|
vote ({ commit, dispatch, state }, { title, link, linkID, isPositive, voterName }) {
|
||||||
console.log('vote on ' + link + ' | ' + linkID + ' (' + isPositive + ') by ' + voterName)
|
console.log('vote on ' + link + ' | ' + linkID + ' (' + isPositive + ') by ' + voterName)
|
||||||
if (isPositive) {
|
if (isPositive) {
|
||||||
commit('ADD_VOTE', {
|
commit('ADD_VOTE', {
|
||||||
|
title: title,
|
||||||
linkID: linkID,
|
linkID: linkID,
|
||||||
link: link,
|
link: link,
|
||||||
voterName: voterName
|
voterName: voterName
|
||||||
@@ -54,6 +55,10 @@ const actions = {
|
|||||||
}
|
}
|
||||||
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
||||||
},
|
},
|
||||||
|
removePlay ({ commit, dispatch, state }, linkID) {
|
||||||
|
commit('REMOVE_PLAY', linkID)
|
||||||
|
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
||||||
|
},
|
||||||
setCurrent ({ commit, dispatch }, { playerStatus, timeCode, timeLength, title }) {
|
setCurrent ({ commit, dispatch }, { playerStatus, timeCode, timeLength, title }) {
|
||||||
switch (playerStatus) {
|
switch (playerStatus) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -114,10 +119,11 @@ const mutations = {
|
|||||||
SET_CURRENTTITLE (state, title) {
|
SET_CURRENTTITLE (state, title) {
|
||||||
state.roomStatus.current.title = title
|
state.roomStatus.current.title = title
|
||||||
},
|
},
|
||||||
ADD_VOTE (state, { link, linkID, voterName }) {
|
ADD_VOTE (state, { title, link, linkID, voterName }) {
|
||||||
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
||||||
if (play === undefined) {
|
if (play === undefined) {
|
||||||
play = {
|
play = {
|
||||||
|
title: title,
|
||||||
link: link,
|
link: link,
|
||||||
linkID: linkID,
|
linkID: linkID,
|
||||||
votes: 1,
|
votes: 1,
|
||||||
@@ -131,6 +137,10 @@ const mutations = {
|
|||||||
play.votes++
|
play.votes++
|
||||||
play.voters.push(voterName)
|
play.voters.push(voterName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.roomStatus.playlist.sort((a, b) => {
|
||||||
|
return b.votes - a.votes
|
||||||
|
})
|
||||||
},
|
},
|
||||||
REMOVE_VOTE (state, { linkID, voterName }) {
|
REMOVE_VOTE (state, { linkID, voterName }) {
|
||||||
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
||||||
@@ -140,12 +150,23 @@ const mutations = {
|
|||||||
play.voters.splice(index, 1)
|
play.voters.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (play.vote === 0) {
|
if (play.votes === 0) {
|
||||||
const index = state.roomStatus.playlist.indexOf(play)
|
const index = state.roomStatus.playlist.indexOf(play)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
state.roomStatus.playlist.splice(index, 1)
|
state.roomStatus.playlist.splice(index, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.roomStatus.playlist.sort((a, b) => {
|
||||||
|
return b.votes - a.votes
|
||||||
|
})
|
||||||
|
},
|
||||||
|
REMOVE_PLAY (state, linkID) {
|
||||||
|
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
||||||
|
const index = state.roomStatus.playlist.indexOf(play)
|
||||||
|
if (index > -1) {
|
||||||
|
state.roomStatus.playlist.splice(index, 1)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
CURRENT_END (state) {
|
CURRENT_END (state) {
|
||||||
if (state.roomStatus.playlist.length === 0) {
|
if (state.roomStatus.playlist.length === 0) {
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ const actions = {
|
|||||||
leave ({ commit }) {
|
leave ({ commit }) {
|
||||||
commit('LEAVE')
|
commit('LEAVE')
|
||||||
},
|
},
|
||||||
|
kick ({ commit }, target) {
|
||||||
|
commit('KICK', target)
|
||||||
|
},
|
||||||
broadcast ({ commit }, { message, type }) {
|
broadcast ({ commit }, { message, type }) {
|
||||||
commit('BROADCAST', { message: message, type: type })
|
commit('BROADCAST', { message: message, type: type })
|
||||||
}
|
}
|
||||||
@@ -129,6 +132,15 @@ const mutations = {
|
|||||||
})
|
})
|
||||||
state.peers = []
|
state.peers = []
|
||||||
},
|
},
|
||||||
|
KICK (state, target) {
|
||||||
|
var peer = state.peers.find(peer => peer.name === target)
|
||||||
|
peer.dataChannel.close()
|
||||||
|
peer.connection.close()
|
||||||
|
const index = state.peers.indexOf(peer)
|
||||||
|
if (index > -1) {
|
||||||
|
state.peers.splice(index, 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
BROADCAST (state, { message, type }) {
|
BROADCAST (state, { message, type }) {
|
||||||
const data = JSON.stringify({
|
const data = JSON.stringify({
|
||||||
type: type,
|
type: type,
|
||||||
|
|||||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
cloud32:
|
||||||
|
image: gltron/c32java
|
||||||
|
container_name: cloud32
|
||||||
|
ports:
|
||||||
|
- 8004:8181
|
||||||
|
volumes:
|
||||||
|
- /data/c32_data/:/data
|
||||||
|
restart: unless-stopped
|
||||||
Reference in New Issue
Block a user