mirror of
https://github.com/KevinMidboe/zoff.git
synced 2026-01-13 04:55:38 +00:00
Compare commits
1 Commits
feat/vueti
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fef8ad5215 |
3
config/env/dev.env.js
vendored
3
config/env/dev.env.js
vendored
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
NODE_ENV: "development"
|
||||
};
|
||||
3
config/env/prod.env.js
vendored
3
config/env/prod.env.js
vendored
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
NODE_ENV: "production"
|
||||
};
|
||||
3
config/env/staging.env.js
vendored
3
config/env/staging.env.js
vendored
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
NODE_ENV: "staging"
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const _root = path.resolve(__dirname, "..");
|
||||
|
||||
exports.root = function(args) {
|
||||
args = Array.prototype.slice.call(arguments, 0);
|
||||
|
||||
return path.join.apply(path, [_root].concat(args));
|
||||
};
|
||||
|
||||
exports.assetsPath = function(_path) {
|
||||
return path.posix.join("static", _path);
|
||||
};
|
||||
@@ -1,85 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const VueLoaderPlugin = require("vue-loader/lib/plugin");
|
||||
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
|
||||
const helpers = require("./helpers");
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
|
||||
const webpackConfig = function(isDev) {
|
||||
return {
|
||||
entry: {
|
||||
main: ["@babel/polyfill", helpers.root("frontend", "main")]
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".js", ".vue"],
|
||||
alias: {
|
||||
vue$: isDev ? "vue/dist/vue.runtime.js" : "vue/dist/vue.runtime.min.js",
|
||||
"@": helpers.root("frontend")
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: "vue-loader",
|
||||
include: [helpers.root("frontend")]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: "babel-loader",
|
||||
include: [helpers.root("frontend")]
|
||||
},
|
||||
/*{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
isDev ? "vue-style-loader" : MiniCSSExtractPlugin.loader,
|
||||
{ loader: "css-loader", options: { sourceMap: isDev } }
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
isDev ? "vue-style-loader" : MiniCSSExtractPlugin.loader,
|
||||
{ loader: "css-loader", options: { sourceMap: isDev } },
|
||||
{ loader: "sass-loader", options: { sourceMap: isDev } }
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.sass$/,
|
||||
use: [
|
||||
isDev ? "vue-style-loader" : MiniCSSExtractPlugin.loader,
|
||||
{ loader: "css-loader", options: { sourceMap: isDev } },
|
||||
{ loader: "sass-loader", options: { sourceMap: isDev } }
|
||||
]
|
||||
},*/
|
||||
{
|
||||
test: /\.s(c|a)ss$/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
// Requires sass-loader@^7.0.0
|
||||
options: {
|
||||
implementation: require('sass'),
|
||||
fiber: require('fibers'),
|
||||
indentedSyntax: true // optional
|
||||
},
|
||||
// Requires sass-loader@^8.0.0
|
||||
options: {
|
||||
implementation: require('sass'),
|
||||
sassOptions: {
|
||||
fiber: require('fibers'),
|
||||
indentedSyntax: true // optional
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
plugins: [new VueLoaderPlugin()]
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = webpackConfig;
|
||||
@@ -1,44 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin");
|
||||
const HtmlPlugin = require("html-webpack-plugin");
|
||||
const helpers = require("./helpers");
|
||||
const commonConfig = require("./webpack.config.common");
|
||||
const environment = require("./env/dev.env");
|
||||
|
||||
const webpackConfig = merge(commonConfig(true), {
|
||||
mode: "development",
|
||||
devtool: "cheap-module-eval-source-map",
|
||||
output: {
|
||||
path: helpers.root("dist"),
|
||||
publicPath: "/",
|
||||
filename: "js/[name].bundle.js",
|
||||
chunkFilename: "js/[id].chunk.js"
|
||||
},
|
||||
optimization: {
|
||||
runtimeChunk: "single",
|
||||
splitChunks: {
|
||||
chunks: "all"
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin(environment),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new FriendlyErrorsPlugin(),
|
||||
new HtmlPlugin({ template: "frontend/index.html", chunksSortMode: "dependency" })
|
||||
],
|
||||
devServer: {
|
||||
compress: true,
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
overlay: true,
|
||||
port: 8000,
|
||||
stats: {
|
||||
normal: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = webpackConfig;
|
||||
@@ -1,55 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
|
||||
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
|
||||
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
|
||||
const CompressionPlugin = require("compression-webpack-plugin");
|
||||
const helpers = require("./helpers");
|
||||
const commonConfig = require("./webpack.config.common");
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
const environment = isProd
|
||||
? require("./env/prod.env")
|
||||
: require("./env/staging.env");
|
||||
|
||||
const webpackConfig = merge(commonConfig(false), {
|
||||
mode: "production",
|
||||
output: {
|
||||
path: helpers.root("dist"),
|
||||
publicPath: "/",
|
||||
filename: "js/[name].bundle.js"
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new OptimizeCSSAssetsPlugin({
|
||||
cssProcessorPluginOptions: {
|
||||
preset: ["default", { discardComments: { removeAll: true } }]
|
||||
}
|
||||
}),
|
||||
new UglifyJSPlugin({
|
||||
cache: true,
|
||||
parallel: false,
|
||||
sourceMap: !isProd
|
||||
})
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin(environment),
|
||||
new MiniCSSExtractPlugin({
|
||||
filename: "css/[name].css"
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
if (!isProd) {
|
||||
webpackConfig.devtool = "source-map";
|
||||
|
||||
if (process.env.npm_config_report) {
|
||||
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
|
||||
.BundleAnalyzerPlugin;
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = webpackConfig;
|
||||
@@ -1,9 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './styles/normalize';
|
||||
</style>
|
||||
@@ -1,35 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="parallel-containers">
|
||||
<Player class="player" />
|
||||
<Playlist class="playlist" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from "@/store";
|
||||
import Player from "@/components/player/Player";
|
||||
import Playlist from "@/components/playlist/Playlist";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Player,
|
||||
Playlist
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.parallel-containers {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
& .player {
|
||||
width: 100%;
|
||||
}
|
||||
& .playlist {
|
||||
width: 40vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<h1>Styleguide</h1>
|
||||
<div>
|
||||
<h2>Chat</h2>
|
||||
<Chat />
|
||||
</div>
|
||||
<div>
|
||||
<h2>Playlist-element</h2>
|
||||
<Playlist />
|
||||
</div>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import Playlist from "@/components/playlist/Playlist";
|
||||
import Chat from "@/components/chat/Chat";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Chat,
|
||||
Playlist
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
div {
|
||||
background: #2d2d2d;
|
||||
}
|
||||
</style>
|
||||
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<div class="chat-container">
|
||||
<ul>
|
||||
<li v-for="(message, i) in chat" :key="i">
|
||||
<Name :name="message.name" :icon="message.icon" />
|
||||
<span class="channel-name" v-if="message.channel != null">{{ message.channel }}</span>
|
||||
<span class="channel-message">: {{ message.message }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="chat-input">
|
||||
<ChatInput @sentMessage="sentMessage" @requestHelp="requestHelp" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Name from "@/components/chat/Name";
|
||||
import ChatInput from "@/components/chat/ChatInput";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Name,
|
||||
ChatInput
|
||||
},
|
||||
watch: {
|
||||
chat: function(_chat) {
|
||||
if (_chat.length > 30) {
|
||||
this.chat = _chat
|
||||
.reverse()
|
||||
.splice(0, 30)
|
||||
.reverse();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sentMessage: function(message) {
|
||||
this.chat.push({
|
||||
name: "pepega",
|
||||
icon: null,
|
||||
message: message,
|
||||
channel: "avicii"
|
||||
});
|
||||
},
|
||||
requestHelp: function() {
|
||||
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chat: [
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
},
|
||||
{
|
||||
name: "KasperRT",
|
||||
icon: "https://img.youtube.com/vi/fn_amMJehPU/mqdefault.jpg",
|
||||
message: "Hei på deg",
|
||||
channel: "summér"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
|
||||
& li {
|
||||
display: flex;
|
||||
color: white;
|
||||
|
||||
& .channel-name {
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
background: #00000040;
|
||||
}
|
||||
|
||||
&:nth-child(odd) {
|
||||
background: #00000050;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<v-row>
|
||||
<v-col cols="9">
|
||||
<v-text-field v-model="chatInput" label="Aa.." @keyup.enter="send"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="1">
|
||||
<v-btn @click="send">Send</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="1">
|
||||
<v-btn @click="requestHelp">Help</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chatInput: ""
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
send: function() {
|
||||
if (this.chatInput == "") {
|
||||
return;
|
||||
}
|
||||
this.$emit("sentMessage", this.chatInput);
|
||||
this.chatInput = "";
|
||||
},
|
||||
requestHelp: function() {
|
||||
console.log("emit for help here");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div class="name">
|
||||
<div class="icon-container" v-if="icon != undefined">
|
||||
<img :src="icon" />
|
||||
</div>
|
||||
<div class="name-container">{{ name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.name-container {
|
||||
padding: 0 5px 0 5px;
|
||||
color: orange;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<div class="conatiner">
|
||||
<YouTube
|
||||
@end="end('youtube')"
|
||||
@pause="pause('youtube')"
|
||||
@play="play('youtube')"
|
||||
@buffering="buffering('youtube')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from "@/store";
|
||||
import YouTube from "@/components/player/YouTube";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
YouTube
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
done: false,
|
||||
player: undefined
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.sockets.subscribe("np", msg => {
|
||||
this.gotNewNowPlaying(msg);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
gotNewNowPlaying: function(msg) {
|
||||
console.log("got now playing");
|
||||
const playlist = store.getters["playerModule/playlist"];
|
||||
const currentPlaying = playlist.find(song => song.now_playing == true);
|
||||
if (msg.np.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (msg.conf.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nowPlaying = msg.np[0];
|
||||
let channelSettings = msg.conf[0];
|
||||
let timeSinceStart =
|
||||
msg.time - channelSettings.startTime + nowPlaying.start;
|
||||
nowPlaying.seek = timeSinceStart;
|
||||
|
||||
const newNowPlaying = playlist.find(song => song.id == nowPlaying.id);
|
||||
newNowPlaying.now_playing = true;
|
||||
if (
|
||||
currentPlaying != undefined &&
|
||||
currentPlaying.id != newNowPlaying.id
|
||||
) {
|
||||
currentPlaying.now_playing = false;
|
||||
currentPlaying.added = channelSettings.startTime;
|
||||
console.log(currentPlaying);
|
||||
}
|
||||
console.log(this.predicate);
|
||||
playlist.sort(
|
||||
this.predicate(
|
||||
{
|
||||
name: "votes",
|
||||
reverse: true
|
||||
},
|
||||
{
|
||||
name: "added",
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
reverse: false
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
store.dispatch("playerModule/setPlaylist", playlist);
|
||||
store.dispatch("playerModule/setNowPlaying", nowPlaying);
|
||||
store.dispatch("playerModule/setChannelSettings", channelSettings);
|
||||
},
|
||||
play: function(source) {},
|
||||
pause: function(source) {},
|
||||
end: function(source) {},
|
||||
buffering: function(source) {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
@@ -1,185 +0,0 @@
|
||||
<template>
|
||||
<div id="youtubePlayer"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from "@/store";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
initialLoad: true,
|
||||
player: null,
|
||||
playerReady: false,
|
||||
currentPlaying: {},
|
||||
currentIsThis: false,
|
||||
gettingPosition: false,
|
||||
wasPaused: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
nowPlaying: {
|
||||
get: function() {
|
||||
return store.getters["playerModule/nowPlaying"];
|
||||
}
|
||||
},
|
||||
playerState: {
|
||||
get: function() {
|
||||
if (!this.currentIsThis) {
|
||||
return this.PLAYER_STATES.PAUSED;
|
||||
}
|
||||
return store.getters["playerModule/playerState"];
|
||||
},
|
||||
set: function(state) {
|
||||
if (!this.currentIsThis) {
|
||||
return;
|
||||
}
|
||||
store.dispatch("playerModule/setPlayerState");
|
||||
}
|
||||
},
|
||||
PLAYER_STATES: function() {
|
||||
return store.getters["playerModule/PLAYER_STATES"];
|
||||
},
|
||||
channelSettings: function() {
|
||||
return store.getters["playerModule/channelSettings"];
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
nowPlaying: function(nowPlaying) {
|
||||
this.currentIsThis = false;
|
||||
if (nowPlaying.source != "youtube") {
|
||||
return;
|
||||
}
|
||||
if (!this.playerReady) {
|
||||
return;
|
||||
}
|
||||
this.currentIsThis = true;
|
||||
|
||||
if (this.player == null) {
|
||||
this.createYoutubeObjectWithId(this.nowPlaying.id);
|
||||
} else {
|
||||
console.log("new np", this.currentPlaying.id, nowPlaying.id);
|
||||
if (this.currentPlaying.id != nowPlaying.id) {
|
||||
try {
|
||||
console.log("loading");
|
||||
this.player.loadVideoById(nowPlaying.id, {
|
||||
start: nowPlaying.seek,
|
||||
end: nowPlaying.end
|
||||
});
|
||||
} catch (e) {}
|
||||
} else {
|
||||
this.player.seekTo(nowPlaying.seek);
|
||||
console.log("seeking");
|
||||
}
|
||||
this.currentPlaying = nowPlaying;
|
||||
}
|
||||
},
|
||||
playerState: function(state) {
|
||||
if (!this.currentIsThis) {
|
||||
return;
|
||||
}
|
||||
if (state === this.PLAYER_STATES.PLAYING) {
|
||||
this.player.playVideo();
|
||||
} else if (state === this.PLAYER_STATES.PAUSED) {
|
||||
this.player.pauseVideo();
|
||||
} else if (state === this.PLAYER_STATES.ENDED) {
|
||||
this.player.stopVideo();
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
this.loadYoutubeIframe();
|
||||
},
|
||||
methods: {
|
||||
loadYoutubeIframe() {
|
||||
window.onYouTubeIframeAPIReady = this.onYouTubeIframeAPIReady;
|
||||
const tag = document.createElement("script");
|
||||
tag.src = "https://www.youtube.com/iframe_api";
|
||||
const firstScriptTag = document.getElementsByTagName("script")[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
},
|
||||
onYouTubeIframeAPIReady() {
|
||||
this.playerReady = true;
|
||||
if (
|
||||
this.nowPlaying != undefined &&
|
||||
this.nowPlaying.id != undefined &&
|
||||
this.player == null
|
||||
) {
|
||||
this.createYoutubeObjectWithId(this.nowPlaying.id);
|
||||
}
|
||||
},
|
||||
createYoutubeObjectWithId(id) {
|
||||
if (this.player == null) {
|
||||
this.player = new YT.Player("youtubePlayer", {
|
||||
videoId: id,
|
||||
playerVars: {
|
||||
rel: "0",
|
||||
autoplay: 1,
|
||||
wmode: "transparent",
|
||||
controls: "0",
|
||||
fs: "0",
|
||||
iv_load_policy: "3",
|
||||
theme: "light",
|
||||
color: "white",
|
||||
showinfo: 0
|
||||
},
|
||||
events: {
|
||||
onReady: this.onPlayerReady,
|
||||
onStateChange: this.onPlayerStateChange,
|
||||
onError: this.errorHandler
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
onPlayerReady(event) {
|
||||
console.log("event from onPlayerReady", event);
|
||||
|
||||
this.player.setVolume(0);
|
||||
event.target.playVideo();
|
||||
setInterval(() => {
|
||||
console.log(
|
||||
this.player.getCurrentTime() + " - " + this.player.getDuration()
|
||||
);
|
||||
}, 1000);
|
||||
},
|
||||
checkForInitialLoadAndSeek() {
|
||||
if (!this.initialLoad) {
|
||||
return;
|
||||
}
|
||||
this.initialLoad = false;
|
||||
this.player.seekTo(this.nowPlaying.seek);
|
||||
},
|
||||
onPlayerStateChange(event) {
|
||||
console.log("event change", event);
|
||||
if (event.data === this.PLAYER_STATES.PLAYING) {
|
||||
console.log("playing");
|
||||
this.checkForInitialLoadAndSeek();
|
||||
if (this.wasPaused) {
|
||||
this.wasPaused = false;
|
||||
this.$root.$options.methods.getPosition();
|
||||
}
|
||||
} else if (event.data === this.PLAYER_STATES.ENDED) {
|
||||
console.log("ended");
|
||||
this.$root.$options.methods.songEnd();
|
||||
} else if (event.data === this.PLAYER_STATES.UNSTARTED) {
|
||||
console.log("not started");
|
||||
} else if (event.data === this.PLAYER_STATES.BUFFERING) {
|
||||
console.log("buffering");
|
||||
} else if (event.data === this.PLAYER_STATES.PAUSED) {
|
||||
console.log("pasued");
|
||||
this.wasPaused = true;
|
||||
}
|
||||
},
|
||||
errorHandler(error) {
|
||||
console.log("error handling youtube player. Error:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#youtubePlayer {
|
||||
width: 100% !important;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,112 +0,0 @@
|
||||
<template>
|
||||
<div class="context-menu-container" :style="'top:' + mouseY + 'px;left:' + mouseX + 'px;'">
|
||||
<ul>
|
||||
<li @click="copyLink">Copy link</li>
|
||||
<li @click="findSimilar">Find similar</li>
|
||||
<li class="addedBy">Added by {{ addedBy }}</li>
|
||||
<hr />
|
||||
<li @click="deleteSong" :disabled="loggedIn">Delete</li>
|
||||
</ul>
|
||||
<div class="context-menu-background" @mouseout="closeSelf" @click="closeSelf"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
id: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
type: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
addedBy: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
mouseX: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
mouseY: {
|
||||
required: true,
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
loggedIn: function() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeSelf: function(e) {
|
||||
if (e.toElement == null || e.toElement.nodeName == null) {
|
||||
return;
|
||||
}
|
||||
if (e.toElement.nodeName == "UL" || e.toElement.nodeName == "LI") {
|
||||
return;
|
||||
}
|
||||
this.$emit("closeContextMenu");
|
||||
},
|
||||
copyLink: function() {
|
||||
console.log("copy link of", this.id);
|
||||
},
|
||||
findSimilar: function() {
|
||||
console.log("find similar of", this.id);
|
||||
},
|
||||
deleteSong: function() {
|
||||
console.log("delete song of", this.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.context-menu-background {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
position: absolute;
|
||||
left: -85%;
|
||||
top: -100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.context-menu-container {
|
||||
font-family: sans-serif;
|
||||
|
||||
position: absolute;
|
||||
background-color: #2d2d2d;
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
|
||||
& ul {
|
||||
z-index: 2;
|
||||
list-style: none;
|
||||
padding: 10px 0 10px 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
background-color: #2d2d2d;
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
|
||||
& li {
|
||||
cursor: pointer;
|
||||
padding: 5px 15px;
|
||||
|
||||
&:hover:not(.addedBy) {
|
||||
background-color: #ffffff15;
|
||||
}
|
||||
|
||||
&.addedBy {
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
|
||||
& hr {
|
||||
padding: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,198 +0,0 @@
|
||||
<template>
|
||||
<div class="playlist-conatiner">
|
||||
<div class="playlist-element" v-for="(song, i) in paginatedList" :key="i">
|
||||
<Song
|
||||
class="song"
|
||||
:title="song.title"
|
||||
:thumbnail="song.thumbnail"
|
||||
:votes="song.votes"
|
||||
:addedBy="song.added_by"
|
||||
:id="song.id"
|
||||
:type="song.type"
|
||||
:duration="song.duration"
|
||||
@contextmenu="moreInfo"
|
||||
/>
|
||||
</div>
|
||||
<div class="pagination-buttons">
|
||||
<v-btn text @click="firstPage" :disabled="disabledPrev" class="first"
|
||||
><</v-btn
|
||||
>
|
||||
<v-btn text @click="prevPage" :disabled="disabledPrev">previous</v-btn>
|
||||
<span>{{ page + 1 }} / {{ pages }}</span>
|
||||
<v-btn text @click="nextPage" :disabled="disabledNext">next</v-btn>
|
||||
<v-btn text @click="lastPage" :disabled="disabledNext" class="last"
|
||||
>></v-btn
|
||||
>
|
||||
</div>
|
||||
<ContextMenu
|
||||
v-if="contextMenuOpen"
|
||||
:addedBy="contextOnElement.added_by"
|
||||
:id="contextOnElement.id"
|
||||
:type="contextOnElement.type"
|
||||
:mouseX="mouseX"
|
||||
:mouseY="mouseY"
|
||||
@closeContextMenu="closeContextMenu"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from "@/store";
|
||||
import Song from "@/components/playlist/Song";
|
||||
import ContextMenu from "@/components/playlist/ContextMenu";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Song,
|
||||
ContextMenu
|
||||
},
|
||||
computed: {
|
||||
paginatedList: function() {
|
||||
return this.playlist
|
||||
.filter(song => !song.now_playing)
|
||||
.slice(this.page * this.perPage, (1 + this.page) * this.perPage);
|
||||
},
|
||||
disabledPrev: function() {
|
||||
return this.page == 0;
|
||||
},
|
||||
disabledNext: function() {
|
||||
return this.playlist.length < (this.page + 1) * this.perPage;
|
||||
},
|
||||
pages: function() {
|
||||
return Math.ceil(this.playlist.length / this.perPage);
|
||||
},
|
||||
playlist: function() {
|
||||
return store.getters["playerModule/playlist"];
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$socket);
|
||||
this.sockets.subscribe("channel", msg => {
|
||||
console.log("list", msg);
|
||||
if (msg.type == "list") {
|
||||
this.gotList(msg);
|
||||
} else if (msg.type == "vote") {
|
||||
this.voted(msg);
|
||||
} else if (msg.type == "shuffle") {
|
||||
this.gotList(msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
gotList: function(msg) {
|
||||
console.log(this);
|
||||
msg.playlist.sort(
|
||||
this.predicate(
|
||||
{
|
||||
name: "votes",
|
||||
reverse: true
|
||||
},
|
||||
{
|
||||
name: "added",
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
reverse: false
|
||||
}
|
||||
)
|
||||
);
|
||||
store.dispatch("playerModule/setPlaylist", msg.playlist);
|
||||
},
|
||||
voted: function(msg) {
|
||||
const playlist = store.getters["playerModule/playlist"];
|
||||
let songToUpdate = playlist.find(song => song.id == msg.value);
|
||||
console.log(songToUpdate);
|
||||
songToUpdate.votes += 1;
|
||||
songToUpdate.added = msg.time;
|
||||
store.dispatch("playerModule/setPlaylist", playlist);
|
||||
},
|
||||
moreInfo: function(e, id) {
|
||||
e.preventDefault();
|
||||
this.contextOnElement = this.playlist.find(song => song.id == id);
|
||||
this.mouseX = e.pageX;
|
||||
this.mouseY = e.pageY;
|
||||
this.contextMenuOpen = true;
|
||||
},
|
||||
closeContextMenu: function() {
|
||||
this.contextMenuOpen = false;
|
||||
this.contextOnElement = null;
|
||||
},
|
||||
firstPage: function() {
|
||||
this.page = 0;
|
||||
},
|
||||
lastPage: function() {
|
||||
this.page = Math.floor(this.playlist.length / this.perPage);
|
||||
},
|
||||
prevPage: function() {
|
||||
if (this.page == 0) {
|
||||
return;
|
||||
}
|
||||
this.page -= 1;
|
||||
},
|
||||
nextPage: function() {
|
||||
if (this.playlist.length < (this.page + 1) * this.perPage) {
|
||||
return;
|
||||
}
|
||||
this.page += 1;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
contextMenuOpen: false,
|
||||
contextOnElement: {},
|
||||
page: 0,
|
||||
perPage: 12
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.playlist-conatiner {
|
||||
background-color: inherit;
|
||||
padding-top: 5px;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
background: #2d2d2d;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
// & .playlist-element {
|
||||
// height: 100%;
|
||||
// }
|
||||
|
||||
.pagination-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: white;
|
||||
padding: 10px 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
|
||||
& span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
& button {
|
||||
width: 20%;
|
||||
height: 30px;
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: none;
|
||||
|
||||
&.first,
|
||||
&.last {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<v-card
|
||||
class="mx-auto song-element"
|
||||
@click="clickedSong"
|
||||
@contextmenu="$emit('contextmenu', $event, id)"
|
||||
>
|
||||
<v-img class="white--text align-end song-image" :src="thumbnail"></v-img>
|
||||
|
||||
<v-card-text class="white--text text-truncate text-no-wrap song-title">
|
||||
<div class="white--text text-truncate text-no-wrap text-truncate-inner">{{ title }}</div>
|
||||
|
||||
<div>{{ votes }} vote{{votes > 1 || votes == 0 ? "s" : null }}</div>
|
||||
</v-card-text>
|
||||
<div class="more-info-button" @click="$emit('contextmenu', $event, id)">. . .</div>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContextMenu from "@/components/playlist/ContextMenu";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ContextMenu
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
thumbnail: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
title: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
votes: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
addedBy: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
type: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
duration: {
|
||||
required: true,
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
contextMenuOpen: false,
|
||||
mouseX: 0,
|
||||
mouseY: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
durationInString: function() {
|
||||
let time = this.duration;
|
||||
let minutes = Math.floor(time / 60);
|
||||
time = time - minutes * 60;
|
||||
let minutesString = (minutes + "").padStart(2, "0");
|
||||
let secondString = (time + "").padStart(2, "0");
|
||||
return `${minutesString}:${secondString}`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clickedSong: function(e) {
|
||||
e.preventDefault();
|
||||
if (e.target.className === "more-info-button") {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$root.$options.methods.vote(this.id);
|
||||
console.log("Clicked on song with info", this.title, this.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.song-image {
|
||||
width: 120px;
|
||||
height: 90px;
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
border-bottom-left-radius: 2.5px !important;
|
||||
}
|
||||
.song-element {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
box-shadow: 0px 0px 2px #000000;
|
||||
background: #ffffff20;
|
||||
border-radius: 5px;
|
||||
margin: 5px 5px;
|
||||
cursor: pointer;
|
||||
margin-left: 8px;
|
||||
width: calc(100% - 16px);
|
||||
color: white;
|
||||
height: auto;
|
||||
|
||||
& .song-context-button {
|
||||
width: 10%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
}
|
||||
|
||||
.more-info-button {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.song-title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
border-top-right-radius: 0;
|
||||
color: white !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.text-truncate-inner {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Zoff</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,46 +0,0 @@
|
||||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import vuetify from "@/plugins/vuetify"; // path to vuetify export
|
||||
import router from "./routes";
|
||||
import store from "./store";
|
||||
import * as io from "socket.io-client";
|
||||
import VueSocketIO from "vue-socket.io";
|
||||
|
||||
import SortMixin from "@/mixins/SortMixin";
|
||||
import App from "./App.vue";
|
||||
|
||||
Vue.mixin(SortMixin);
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(
|
||||
new VueSocketIO({
|
||||
debug: true,
|
||||
connection: io("http://localhost:8080"),
|
||||
vuex: {
|
||||
store,
|
||||
actionPrefix: "SOCKET_",
|
||||
mutationPrefix: "SOCKET_"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
new Vue({
|
||||
sockets: {
|
||||
connect: function(msg) {
|
||||
console.log("connected");
|
||||
this.$socket.emit("list", {
|
||||
version: 6,
|
||||
channel: "summér"
|
||||
});
|
||||
},
|
||||
channel: function(msg) {
|
||||
console.log("channel-message", msg);
|
||||
},
|
||||
np: function(msg) {}
|
||||
},
|
||||
vuetify,
|
||||
el: "#app",
|
||||
router,
|
||||
store,
|
||||
components: { App },
|
||||
render: h => h(App)
|
||||
});
|
||||
@@ -1,222 +0,0 @@
|
||||
import store from "@/store";
|
||||
import io from "socket.io-client";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
alreadyCreated: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.alreadyCreated) {
|
||||
console.log("we already exist");
|
||||
return;
|
||||
}
|
||||
this.socket = io("localhost:8080");
|
||||
console.log("mounted");
|
||||
console.log(this.socket);
|
||||
this.addListeners();
|
||||
this.alreadyCreated = true;
|
||||
},
|
||||
computed: {
|
||||
nowPlaying: function() {
|
||||
return store.getters["playerModule/nowPlaying"];
|
||||
},
|
||||
channel: function() {
|
||||
return store.getters["playerModule/channel"];
|
||||
},
|
||||
socket: {
|
||||
set: function(socket) {
|
||||
store.dispatch("socketModule/setSocket", socket);
|
||||
},
|
||||
get: function() {
|
||||
console.log(store);
|
||||
return store.getters["socketModule/socket"];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
emitToBackend(event, msg) {
|
||||
store.getters["socketModule/socket"].emit(event, msg);
|
||||
},
|
||||
songEnd() {
|
||||
const nowPlaying = store.getters["playerModule/nowPlaying"];
|
||||
const channel = store.getters["playerModule/channel"];
|
||||
store.getters["socketModule/socket"].emit("end", {
|
||||
id: nowPlaying.id,
|
||||
channel: channel
|
||||
});
|
||||
},
|
||||
getPosition() {
|
||||
store.getters["socketModule/socket"].emit("pos", {
|
||||
channel: store.getters["playerModule/channel"]
|
||||
});
|
||||
},
|
||||
vote(id) {
|
||||
store.getters["socketModule/socket"].emit("vote", {
|
||||
channel: store.getters["playerModule/channel"],
|
||||
id: id,
|
||||
type: "pos"
|
||||
});
|
||||
},
|
||||
addListeners() {
|
||||
console.log(this.socket);
|
||||
this.socket.on("channel", msg => {
|
||||
console.log("list", msg);
|
||||
if (msg.type == "list") {
|
||||
msg.playlist.sort(
|
||||
predicate(
|
||||
{
|
||||
name: "votes",
|
||||
reverse: true
|
||||
},
|
||||
{
|
||||
name: "added",
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
reverse: false
|
||||
}
|
||||
)
|
||||
);
|
||||
store.dispatch("playerModule/setPlaylist", msg.playlist);
|
||||
} else if (msg.type == "vote") {
|
||||
const playlist = store.getters["playerModule/playlist"];
|
||||
let songToUpdate = playlist.find(song => song.id == msg.value);
|
||||
console.log(songToUpdate);
|
||||
songToUpdate.votes += 1;
|
||||
songToUpdate.added = msg.time;
|
||||
store.dispatch("playerModule/setPlaylist", playlist);
|
||||
}
|
||||
});
|
||||
|
||||
this.socket.on("conf", msg => {
|
||||
console.log("conf", msg);
|
||||
if (msg.length == 1) {
|
||||
store.dispatch("playerModule/setChannelSettings", msg[0]);
|
||||
}
|
||||
});
|
||||
this.socket.on("np", msg => {
|
||||
console.log("got now playing");
|
||||
const playlist = store.getters["playerModule/playlist"];
|
||||
const currentPlaying = playlist.find(song => song.now_playing == true);
|
||||
if (msg.np.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (msg.conf.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nowPlaying = msg.np[0];
|
||||
let channelSettings = msg.conf[0];
|
||||
let timeSinceStart =
|
||||
msg.time - channelSettings.startTime + nowPlaying.start;
|
||||
nowPlaying.seek = timeSinceStart;
|
||||
|
||||
const newNowPlaying = playlist.find(song => song.id == nowPlaying.id);
|
||||
newNowPlaying.now_playing = true;
|
||||
if (
|
||||
currentPlaying != undefined &&
|
||||
currentPlaying.id != newNowPlaying.id
|
||||
) {
|
||||
currentPlaying.now_playing = false;
|
||||
currentPlaying.added = channelSettings.startTime;
|
||||
console.log(currentPlaying);
|
||||
}
|
||||
|
||||
playlist.sort(
|
||||
predicate(
|
||||
{
|
||||
name: "votes",
|
||||
reverse: true
|
||||
},
|
||||
{
|
||||
name: "added",
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
reverse: false
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
store.dispatch("playerModule/setPlaylist", playlist);
|
||||
store.dispatch("playerModule/setNowPlaying", nowPlaying);
|
||||
store.dispatch("playerModule/setChannelSettings", channelSettings);
|
||||
});
|
||||
|
||||
this.socket.on("update_required", msg => {
|
||||
console.log("update required", msg);
|
||||
});
|
||||
this.socket.on("connect", msg => {
|
||||
this.socket.emit("list", {
|
||||
version: 6,
|
||||
channel: this.channel
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function predicate() {
|
||||
var fields = [],
|
||||
n_fields = arguments.length,
|
||||
field,
|
||||
name,
|
||||
cmp;
|
||||
|
||||
var default_cmp = function(a, b) {
|
||||
if (a == undefined) a = 0;
|
||||
if (b == undefined) b = 0;
|
||||
if (a === b) return 0;
|
||||
return a < b ? -1 : 1;
|
||||
},
|
||||
getCmpFunc = function(primer, reverse) {
|
||||
var dfc = default_cmp,
|
||||
// closer in scope
|
||||
cmp = default_cmp;
|
||||
if (primer) {
|
||||
cmp = function(a, b) {
|
||||
return dfc(primer(a), primer(b));
|
||||
};
|
||||
}
|
||||
if (reverse) {
|
||||
return function(a, b) {
|
||||
return -1 * cmp(a, b);
|
||||
};
|
||||
}
|
||||
return cmp;
|
||||
};
|
||||
|
||||
// preprocess sorting options
|
||||
for (var i = 0; i < n_fields; i++) {
|
||||
field = arguments[i];
|
||||
if (typeof field === "string") {
|
||||
name = field;
|
||||
cmp = default_cmp;
|
||||
} else {
|
||||
name = field.name;
|
||||
cmp = getCmpFunc(field.primer, field.reverse);
|
||||
}
|
||||
fields.push({
|
||||
name: name,
|
||||
cmp: cmp
|
||||
});
|
||||
}
|
||||
|
||||
// final comparison function
|
||||
return function(A, B) {
|
||||
var name, result;
|
||||
for (var i = 0; i < n_fields; i++) {
|
||||
result = 0;
|
||||
field = fields[i];
|
||||
name = field.name;
|
||||
|
||||
result = field.cmp(A[name], B[name]);
|
||||
if (result !== 0) break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
export default {
|
||||
methods: {
|
||||
predicate() {
|
||||
var fields = [],
|
||||
n_fields = arguments.length,
|
||||
field,
|
||||
name,
|
||||
cmp;
|
||||
|
||||
var default_cmp = function(a, b) {
|
||||
if (a == undefined) a = 0;
|
||||
if (b == undefined) b = 0;
|
||||
if (a === b) return 0;
|
||||
return a < b ? -1 : 1;
|
||||
},
|
||||
getCmpFunc = function(primer, reverse) {
|
||||
var dfc = default_cmp,
|
||||
// closer in scope
|
||||
cmp = default_cmp;
|
||||
if (primer) {
|
||||
cmp = function(a, b) {
|
||||
return dfc(primer(a), primer(b));
|
||||
};
|
||||
}
|
||||
if (reverse) {
|
||||
return function(a, b) {
|
||||
return -1 * cmp(a, b);
|
||||
};
|
||||
}
|
||||
return cmp;
|
||||
};
|
||||
|
||||
// preprocess sorting options
|
||||
for (var i = 0; i < n_fields; i++) {
|
||||
field = arguments[i];
|
||||
if (typeof field === "string") {
|
||||
name = field;
|
||||
cmp = default_cmp;
|
||||
} else {
|
||||
name = field.name;
|
||||
cmp = getCmpFunc(field.primer, field.reverse);
|
||||
}
|
||||
fields.push({
|
||||
name: name,
|
||||
cmp: cmp
|
||||
});
|
||||
}
|
||||
|
||||
// final comparison function
|
||||
return function(A, B) {
|
||||
var name, result;
|
||||
for (var i = 0; i < n_fields; i++) {
|
||||
result = 0;
|
||||
field = fields[i];
|
||||
name = field.name;
|
||||
|
||||
result = field.cmp(A[name], B[name]);
|
||||
if (result !== 0) break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,112 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
player: undefined,
|
||||
playlist: [],
|
||||
authenticatedAdmin: false,
|
||||
channelSettings: null,
|
||||
clientSettings: null,
|
||||
nowPlaying: null,
|
||||
userSuggested: [],
|
||||
externalSuggested: [],
|
||||
PLAYER_STATES: {
|
||||
BUFFERING: 3,
|
||||
CUED: 5,
|
||||
ENDED: 0,
|
||||
PAUSED: 2,
|
||||
PLAYING: 1,
|
||||
UNSTARTED: -1
|
||||
},
|
||||
channel: "summér"
|
||||
},
|
||||
getters: {
|
||||
channel: state => {
|
||||
return state.channel;
|
||||
},
|
||||
PLAYER_STATES: state => {
|
||||
return state.PLAYER_STATES;
|
||||
},
|
||||
authenticatedAdmin: state => {
|
||||
return state.authenticatedAdmin;
|
||||
},
|
||||
playlist: state => {
|
||||
return state.playlist;
|
||||
},
|
||||
channelSettings: state => {
|
||||
return state.channelSettings;
|
||||
},
|
||||
clientSettings: state => {
|
||||
return state.clientSettings;
|
||||
},
|
||||
nowPlaying: state => {
|
||||
return state.nowPlaying;
|
||||
},
|
||||
userSuggested: state => {
|
||||
return state.userSuggested;
|
||||
},
|
||||
externalSuggested: state => {
|
||||
return state.externalSuggested;
|
||||
},
|
||||
player: state => {
|
||||
return state.player;
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_CHANNEL: (state, channel) => {
|
||||
state.channel = channel;
|
||||
},
|
||||
SET_AUTHENTICATED_ADMIN: (state, authenticatedAdmin) => {
|
||||
state.authenticatedAdmin = authenticatedAdmin;
|
||||
},
|
||||
SET_PLAYLIST: (state, playlist) => {
|
||||
state.playlist = playlist;
|
||||
},
|
||||
SET_CHANNEL_SETTINGS: (state, channelSettings) => {
|
||||
state.channelSettings = channelSettings;
|
||||
},
|
||||
SET_CLIENT_SETTINGS: (state, clientSettings) => {
|
||||
state.clientSettings = clientSettings;
|
||||
},
|
||||
SET_NOW_PLAYING: (state, nowPlaying) => {
|
||||
state.nowPlaying = nowPlaying;
|
||||
},
|
||||
SET_USER_SUGGESTED: (state, userSuggested) => {
|
||||
state.userSuggested = userSuggested;
|
||||
},
|
||||
SET_EXTERNAL_SUGGESTED: (state, externalSuggested) => {
|
||||
state.externalSuggested = externalSuggested;
|
||||
},
|
||||
SET_PLAYER: (state, player) => {
|
||||
state.player = player;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setChannel({ commit }, channel) {
|
||||
commit("SET_CHANNEL", channel.toLowerCase());
|
||||
},
|
||||
setAuthenticatedAdmin({ commit }, authenticatedAdmin) {
|
||||
commit("SET_AUTHENTICATED_ADMIN", authenticatedAdmin);
|
||||
},
|
||||
setPlaylist({ commit }, playlist) {
|
||||
commit("SET_PLAYLIST", playlist);
|
||||
},
|
||||
setChannelSettings({ commit }, channelSettings) {
|
||||
commit("SET_CHANNEL_SETTINGS", channelSettings);
|
||||
},
|
||||
setClientSettings({ commit }, clientSettings) {
|
||||
commit("SET_CLIENT_SETTINGS", clientSettings);
|
||||
},
|
||||
setNowPlaying({ commit }, nowPlaying) {
|
||||
commit("SET_NOW_PLAYING", nowPlaying);
|
||||
},
|
||||
setUserSuggested({ commit }, userSuggested) {
|
||||
commit("SET_USER_SUGGESTED", userSuggested);
|
||||
},
|
||||
setExternalSuggested({ commit }, externalSuggested) {
|
||||
commit("SET_EXTERNAL_SUGGESTED", externalSuggested);
|
||||
},
|
||||
setPlayer({ commit }, player) {
|
||||
commit("SET_PLAYER", player);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
socket: null
|
||||
},
|
||||
getters: {
|
||||
socket: state => {
|
||||
return state.socket;
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_SOCKET: (state, socket) => {
|
||||
state.socket = socket;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setSocket({ commit }, socket) {
|
||||
commit("SET_SOCKET", socket);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuetify from 'vuetify'
|
||||
|
||||
Vue.use(Vuetify)
|
||||
|
||||
const opts = {}
|
||||
|
||||
export default new Vuetify(opts)
|
||||
@@ -1,43 +0,0 @@
|
||||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
let routes = [
|
||||
{
|
||||
name: "player",
|
||||
path: "/player",
|
||||
component: resolve => require(["./components/player/Player.vue"], resolve)
|
||||
},
|
||||
{
|
||||
name: "styleguide",
|
||||
path: "/styleguide",
|
||||
component: resolve => require(["./components/Styleguide.vue"], resolve)
|
||||
},
|
||||
|
||||
{
|
||||
name: "playlist",
|
||||
path: "/playlist",
|
||||
component: resolve =>
|
||||
require(["./components/playlist/Playlist.vue"], resolve)
|
||||
},
|
||||
{
|
||||
name: "channel",
|
||||
path: "/channel",
|
||||
component: resolve => require(["./components/Channel.vue"], resolve)
|
||||
}
|
||||
// {
|
||||
// name: '404',
|
||||
// path: '/404',
|
||||
// component: (resolve) => require(['./components/404.vue'], resolve)
|
||||
// }
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: "hash",
|
||||
base: "/",
|
||||
routes,
|
||||
linkActiveClass: "is-active"
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -1,16 +0,0 @@
|
||||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
|
||||
import playerModule from "@/modules/playerModule";
|
||||
import socketModule from "@/modules/socketModule";
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
playerModule,
|
||||
socketModule
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
||||
6
frontend/styles/normalize.scss
vendored
6
frontend/styles/normalize.scss
vendored
@@ -1,6 +0,0 @@
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
7828
package-lock.json
generated
7828
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@@ -5,7 +5,6 @@
|
||||
"main": "server/app.js",
|
||||
"scripts": {
|
||||
"start": "npm install --only=dev && npm install && $(npm bin)/gulp build && node server/app.js",
|
||||
"vue": "cross-env NODE_ENV=development webpack-dev-server --progress",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
@@ -21,56 +20,24 @@
|
||||
"url": "https://github.com/zoff-music/zoff/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "~7.2",
|
||||
"@babel/plugin-proposal-class-properties": "~7.3",
|
||||
"@babel/plugin-proposal-decorators": "~7.3",
|
||||
"@babel/plugin-proposal-json-strings": "~7.2",
|
||||
"@babel/plugin-syntax-dynamic-import": "~7.2",
|
||||
"@babel/plugin-syntax-import-meta": "~7.2",
|
||||
"@babel/preset-env": "~7.3",
|
||||
"babel-loader": "~8.0",
|
||||
"compression-webpack-plugin": "~2.0",
|
||||
"cross-env": "~5.2",
|
||||
"css-loader": "^3.2.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fibers": "^4.0.2",
|
||||
"friendly-errors-webpack-plugin": "~1.7",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"html-webpack-plugin": "~3.2",
|
||||
"mini-css-extract-plugin": "~0.5",
|
||||
"node-sass": "~4.11",
|
||||
"optimize-css-assets-webpack-plugin": "~3.2",
|
||||
"sass": "^1.23.6",
|
||||
"sass-loader": "^7.3.1",
|
||||
"uglifyjs-webpack-plugin": "~1.2",
|
||||
"vue-loader": "~15.6",
|
||||
"vue-style-loader": "~4.1",
|
||||
"vue-template-compiler": "~2.6",
|
||||
"webpack": "~4.29",
|
||||
"webpack-bundle-analyzer": "^3.6.0",
|
||||
"webpack-cli": "~3.2",
|
||||
"webpack-dev-server": "~3.1",
|
||||
"webpack-hot-middleware": "~2.24",
|
||||
"webpack-merge": "~4.2"
|
||||
"gulp-uglify": "^3.0.2"
|
||||
},
|
||||
"homepage": "https://github.com/zoff-music/zoff#readme",
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "~7.2",
|
||||
"bad-words": "^1.6.5",
|
||||
"bcrypt-nodejs": "0.0.3",
|
||||
"body-parser": "^1.18.3",
|
||||
"color-thief-jimp": "^2.0.2",
|
||||
"compression": "^1.7.3",
|
||||
"connect-mongo": "^3.1.2",
|
||||
"connect-mongo": "^2.0.3",
|
||||
"cookie-parser": "^1.4.4",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.16.4",
|
||||
"express-handlebars": "^3.0.2",
|
||||
"express-recaptcha": "^3.0.1",
|
||||
"express-session": "^1.15.6",
|
||||
"extract-text-webpack-plugin": "^3.0.2",
|
||||
"farmhash": "^3.0.0",
|
||||
"feature-policy": "^0.2.0",
|
||||
"gulp-clean-css": "^4.2.0",
|
||||
@@ -78,10 +45,10 @@
|
||||
"gulp-uglify-es": "^1.0.4",
|
||||
"helmet": "^3.21.1",
|
||||
"jimp": "^0.2.28",
|
||||
"mongodb": "^3.3.4",
|
||||
"mongojs": "^3.1.0",
|
||||
"mongodb": "^2.2.36",
|
||||
"mongojs": "^2.6.0",
|
||||
"mongojs-paginate": "^1.2.0",
|
||||
"mongoose": "^5.4.18",
|
||||
"mongoose": "^5.7.5",
|
||||
"mpromise": "^0.5.5",
|
||||
"nodemailer": "^4.7.0",
|
||||
"passport": "^0.4.0",
|
||||
@@ -90,14 +57,8 @@
|
||||
"referrer-policy": "^1.1.0",
|
||||
"request": "^2.88.0",
|
||||
"socket.io": "^2.2.0",
|
||||
"socket.io-client": "^2.3.0",
|
||||
"socket.io-redis": "^5.2.0",
|
||||
"sticky-session": "^1.1.2",
|
||||
"uniqid": "5.0.3",
|
||||
"vue": "~2.6",
|
||||
"vue-router": "~3.0",
|
||||
"vue-socket.io": "^3.0.7",
|
||||
"vuetify": "^2.1.10",
|
||||
"vuex": "^3.1.2"
|
||||
"uniqid": "5.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,12 +350,7 @@ temp_pass = "";
|
||||
|
||||
initializeCastApi = function() {
|
||||
try {
|
||||
if (
|
||||
cast == undefined ||
|
||||
chrome.cast == undefined ||
|
||||
chrome.cast.AutoJoinPolicy == undefined
|
||||
)
|
||||
return;
|
||||
if (cast == undefined) return;
|
||||
} catch (event) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const environment = (process.env.NODE_ENV || "development").trim();
|
||||
|
||||
if (environment === "development") {
|
||||
module.exports = require("./config/webpack.config.dev");
|
||||
} else {
|
||||
module.exports = require("./config/webpack.config.prod");
|
||||
}
|
||||
Reference in New Issue
Block a user