<template> <modal title="Edit Station"> <template v-slot:body> <label class="label">Name</label> <p class="control"> <input class="input" type="text" placeholder="Station Name" v-model="editing.name" /> </p> <label class="label">Display name</label> <p class="control"> <input class="input" type="text" placeholder="Station Display Name" v-model="editing.displayName" /> </p> <label class="label">Description</label> <p class="control"> <input class="input" type="text" placeholder="Station Description" v-model="editing.description" /> </p> <label class="label">Privacy</label> <p class="control"> <span class="select"> <select v-model="editing.privacy"> <option value="public">Public</option> <option value="unlisted">Unlisted</option> <option value="private">Private</option> </select> </span> </p> <br /> <p class="control"> <label class="checkbox party-mode-inner"> <input type="checkbox" v-model="editing.partyMode" /> Party mode </label> </p> <small>With party mode enabled, people can add songs to a queue that plays. With party mode disabled you can play a private playlist on loop.</small> <br /> <div v-if="station.partyMode"> <br /> <br /> <label class="label">Queue lock</label> <small v-if="station.partyMode" >With the queue locked, only owners (you) can add songs to the queue.</small> <br /> <button class="button is-danger" v-if="!station.locked" v-on:click="$parent.toggleLock()" >Lock the queue</button> <button class="button is-success" v-if="station.locked" v-on:click="$parent.toggleLock()" >Unlock the queue</button> </div> </template> <template v-slot:footer> <button class="button is-success" v-on:click="update()">Update Settings</button> <button class="button is-danger" v-on:click="deleteStation()" v-if="station.type === 'community'" >Delete station</button> </template> </modal> </template> <script> import { mapState } from "vuex"; import { Toast } from "vue-roaster"; import Modal from "./Modal.vue"; import io from "../../io"; import validation from "../../validation"; export default { computed: mapState("station", { station: state => state.station, editing: state => state.editing }), methods: { update: function() { if (this.station.name !== this.editing.name) this.updateName(); if (this.station.displayName !== this.editing.displayName) this.updateDisplayName(); if (this.station.description !== this.editing.description) this.updateDescription(); if (this.station.privacy !== this.editing.privacy) this.updatePrivacy(); if (this.station.partyMode !== this.editing.partyMode) this.updatePartyMode(); }, updateName: function() { const name = this.editing.name; if (!validation.isLength(name, 2, 16)) return Toast.methods.addToast( "Name must have between 2 and 16 characters.", 8000 ); if (!validation.regex.az09_.test(name)) return Toast.methods.addToast( "Invalid name format. Allowed characters: a-z, 0-9 and _.", 8000 ); this.socket.emit("stations.updateName", this.editing._id, name, res => { if (res.status === "success") { if (this.station) this.station.name = name; else { this.$parent.stations.forEach((station, index) => { if (station._id === this.editing._id) return (this.$parent.stations[index].name = name); }); } } Toast.methods.addToast(res.message, 8000); }); }, updateDisplayName: function() { let _this = this; const displayName = this.editing.displayName; if (!validation.isLength(displayName, 2, 32)) return Toast.methods.addToast( "Display name must have between 2 and 32 characters.", 8000 ); if (!validation.regex.azAZ09_.test(displayName)) return Toast.methods.addToast( "Invalid display name format. Allowed characters: a-z, A-Z, 0-9 and _.", 8000 ); this.socket.emit( "stations.updateDisplayName", this.editing._id, displayName, res => { if (res.status === "success") { if (this.station) this.station.displayName = displayName; else { this.$parent.stations.forEach((station, index) => { if (station._id === this.editing._id) return (this.$parent.stations[ index ].displayName = displayName); }); } } Toast.methods.addToast(res.message, 8000); } ); }, updateDescription: function() { let _this = this; const description = this.editing.description; if (!validation.isLength(description, 2, 200)) return Toast.methods.addToast( "Description must have between 2 and 200 characters.", 8000 ); let characters = description.split(""); characters = characters.filter(character => { return character.charCodeAt(0) === 21328; }); if (characters.length !== 0) return Toast.methods.addToast( "Invalid description format. Swastika's are not allowed.", 8000 ); this.socket.emit( "stations.updateDescription", this.editing._id, description, res => { if (res.status === "success") { if (_this.station) _this.station.description = description; else { _this.$parent.stations.forEach((station, index) => { if (station._id === station._id) return (_this.$parent.stations[ index ].description = description); }); } return Toast.methods.addToast(res.message, 4000); } Toast.methods.addToast(res.message, 8000); } ); }, updatePrivacy: function() { let _this = this; this.socket.emit( "stations.updatePrivacy", this.editing._id, this.editing.privacy, res => { if (res.status === "success") { if (_this.station) _this.station.privacy = _this.editing.privacy; else { _this.$parent.stations.forEach((station, index) => { if (station._id === station._id) return (_this.$parent.stations[index].privacy = _this.editing.privacy); }); } return Toast.methods.addToast(res.message, 4000); } Toast.methods.addToast(res.message, 8000); } ); }, updatePartyMode: function() { let _this = this; this.socket.emit( "stations.updatePartyMode", this.editing._id, this.editing.partyMode, res => { if (res.status === "success") { if (_this.station) _this.station.partyMode = _this.editing.partyMode; else { _this.$parent.stations.forEach((station, index) => { if (station._id === station._id) return (_this.$parent.stations[index].partyMode = _this.editing.partyMode); }); } return Toast.methods.addToast(res.message, 4000); } Toast.methods.addToast(res.message, 8000); } ); }, deleteStation: function() { let _this = this; this.socket.emit("stations.remove", this.editing._id, res => { Toast.methods.addToast(res.message, 8000); }); } }, mounted: function() { let _this = this; io.getSocket(socket => (_this.socket = socket)); }, components: { Modal } }; </script> <style lang='scss' scoped> .controls { display: flex; a { display: flex; align-items: center; } } .table { margin-bottom: 0; } h5 { padding: 20px 0; } .party-mode-inner, .party-mode-outer { display: flex; align-items: center; } .select:after { border-color: #029ce3; } </style>