Ver código fonte

refactor: Unify station update functions and events

Owen Diffey 3 anos atrás
pai
commit
9730092baf

Diferenças do arquivo suprimidas por serem muito extensas
+ 67 - 1172
backend/logic/actions/stations.js


+ 113 - 295
frontend/src/components/modals/ManageStation/Tabs/Settings.vue

@@ -1,93 +1,50 @@
 <template>
 	<div class="station-settings">
 		<label class="label">Name</label>
-		<div class="control is-grouped input-with-button">
-			<p class="control is-expanded">
-				<input class="input" type="text" v-model="station.name" />
-			</p>
-			<p class="control">
-				<a class="button is-info" @click.prevent="updateName()">Save</a>
-			</p>
+		<div class="control is-expanded">
+			<input class="input" type="text" v-model="local.name" />
 		</div>
 
 		<label class="label">Display Name</label>
-		<div class="control is-grouped input-with-button">
-			<p class="control is-expanded">
-				<input
-					class="input"
-					type="text"
-					v-model="station.displayName"
-				/>
-			</p>
-			<p class="control">
-				<a class="button is-info" @click.prevent="updateDisplayName()"
-					>Save</a
-				>
-			</p>
+		<div class="control is-expanded">
+			<input class="input" type="text" v-model="local.displayName" />
 		</div>
 
 		<label class="label">Description</label>
-		<div class="control is-grouped input-with-button">
-			<p class="control is-expanded">
-				<input
-					class="input"
-					type="text"
-					v-model="station.description"
-				/>
-			</p>
-			<p class="control">
-				<a class="button is-info" @click.prevent="updateDescription()"
-					>Save</a
-				>
-			</p>
+		<div class="control is-expanded">
+			<input class="input" type="text" v-model="local.description" />
 		</div>
 
 		<div class="settings-buttons">
 			<div class="small-section">
 				<label class="label">Theme</label>
-				<div class="control is-grouped input-with-button">
-					<p class="control is-expanded select">
-						<select v-model="station.theme">
-							<option value="blue" selected>Blue</option>
-							<option value="purple">Purple</option>
-							<option value="teal">Teal</option>
-							<option value="orange">Orange</option>
-							<option value="red">Red</option>
-						</select>
-					</p>
-					<p class="control">
-						<a class="button is-info" @click.prevent="updateTheme()"
-							>Save</a
-						>
-					</p>
+				<div class="control is-expanded select">
+					<select v-model="local.theme">
+						<option value="blue" selected>Blue</option>
+						<option value="purple">Purple</option>
+						<option value="teal">Teal</option>
+						<option value="orange">Orange</option>
+						<option value="red">Red</option>
+					</select>
 				</div>
 			</div>
 
 			<div class="small-section">
 				<label class="label">Privacy</label>
-				<div class="control is-grouped input-with-button">
-					<p class="control is-expanded select">
-						<select v-model="station.privacy">
-							<option value="public">Public</option>
-							<option value="unlisted">Unlisted</option>
-							<option value="private" selected>Private</option>
-						</select>
-					</p>
-					<p class="control">
-						<a
-							class="button is-info"
-							@click.prevent="updatePrivacy()"
-							>Save</a
-						>
-					</p>
+				<div class="control is-expanded select">
+					<select v-model="local.privacy">
+						<option value="public">Public</option>
+						<option value="unlisted">Unlisted</option>
+						<option value="private" selected>Private</option>
+					</select>
 				</div>
 			</div>
 
 			<hr class="section-horizontal-rule" />
 
 			<div
-				class="queue-settings"
-				:class="{ enabled: queue.enabled }"
+				class="requests-settings"
+				:class="{ enabled: local.requests.enabled }"
 				style="
 					display: flex;
 					flex-wrap: wrap;
@@ -97,7 +54,7 @@
 			>
 				<div style="display: flex; width: 100%">
 					<label class="label" style="display: flex; flex-grow: 1"
-						>Queue requests</label
+						>Requests</label
 					>
 					<p
 						class="is-expanded checkbox-control"
@@ -106,55 +63,31 @@
 						<label class="switch">
 							<input
 								type="checkbox"
-								id="toggle-queue"
-								v-model="queue.enabled"
+								id="toggle-requests"
+								v-model="local.requests.enabled"
 							/>
 							<span class="slider round"></span>
 						</label>
 
-						<label for="toggle-queue">
+						<label for="toggle-requests">
 							<p>
-								{{ queue.enabled ? "Disable" : "Enable" }}
+								{{
+									local.requests.enabled
+										? "Disable"
+										: "Enable"
+								}}
 							</p>
 						</label>
 					</p>
 				</div>
 
-				<div v-if="queue.enabled" class="small-section">
+				<div v-if="local.requests.enabled" class="control is-expanded">
 					<label class="label">Minimum access</label>
-					<div class="control is-grouped input-with-button">
-						<p class="control is-expanded select">
-							<select v-model="queue.access">
-								<option value="owner" selected>Owner</option>
-								<option value="user">User</option>
-							</select>
-						</p>
-						<p class="control">
-							<a
-								class="button is-info"
-								@click.prevent="updateQueuePrivacy()"
-								>Save</a
-							>
-						</p>
-					</div>
-				</div>
-
-				<div v-if="queue.enabled" class="small-section">
-					<label class="label">Lock</label>
-					<div class="control is-grouped input-with-button">
-						<p class="control is-expanded select">
-							<select v-model="station.locked">
-								<option value="true">Locked</option>
-								<option value="false" selected>Unlocked</option>
-							</select>
-						</p>
-						<p class="control">
-							<a
-								class="button is-info"
-								@click.prevent="updateQueueLock()"
-								>Save</a
-							>
-						</p>
+					<div class="control is-expanded select">
+						<select v-model="local.requests.access">
+							<option value="owner" selected>Owner</option>
+							<option value="user">User</option>
+						</select>
 					</div>
 				</div>
 			</div>
@@ -163,7 +96,7 @@
 
 			<div
 				class="autofill-settings"
-				:class="{ enabled: autofill.enabled }"
+				:class="{ enabled: local.autofill.enabled }"
 				style="
 					display: flex;
 					flex-wrap: wrap;
@@ -183,61 +116,53 @@
 							<input
 								type="checkbox"
 								id="toggle-autofill"
-								v-model="autofill.enabled"
+								v-model="local.autofill.enabled"
 							/>
 							<span class="slider round"></span>
 						</label>
 
 						<label for="toggle-autofill">
 							<p>
-								{{ autofill.enabled ? "Disable" : "Enable" }}
+								{{
+									local.autofill.enabled
+										? "Disable"
+										: "Enable"
+								}}
 							</p>
 						</label>
 					</p>
 				</div>
 
-				<div v-if="autofill.enabled" class="small-section">
+				<div v-if="local.autofill.enabled" class="small-section">
 					<label class="label">Song limit</label>
-					<div class="control is-grouped input-with-button">
-						<p class="control is-expanded">
-							<input
-								class="input"
-								type="number"
-								min="1"
-								max="30"
-								v-model="autofill.limit"
-							/>
-						</p>
-						<p class="control">
-							<a
-								class="button is-info"
-								@click.prevent="updateAutofillLimit()"
-								>Save</a
-							>
-						</p>
+					<div class="control is-expanded">
+						<input
+							class="input"
+							type="number"
+							min="1"
+							max="30"
+							v-model="local.autofill.limit"
+						/>
 					</div>
 				</div>
 
-				<div v-if="autofill.enabled" class="small-section">
+				<div v-if="local.autofill.enabled" class="small-section">
 					<label class="label">Play mode</label>
-					<div class="control is-grouped input-with-button">
-						<p class="control is-expanded select">
-							<select v-model="station.playMode">
-								<option value="random" selected>Random</option>
-								<option value="sequential">Sequential</option>
-							</select>
-						</p>
-						<p class="control">
-							<a
-								class="button is-info"
-								@click.prevent="updatePlayMode()"
-								>Save</a
-							>
-						</p>
+					<div class="control is-expanded select">
+						<select v-model="local.autofill.mode">
+							<option value="random" selected>Random</option>
+							<option value="sequential">Sequential</option>
+						</select>
 					</div>
 				</div>
 			</div>
 		</div>
+
+		<hr />
+
+		<button class="control is-expanded button is-primary" @click="update()">
+			Save Changes
+		</button>
 	</div>
 </template>
 
@@ -251,27 +176,21 @@ import validation from "@/validation";
 export default {
 	data() {
 		return {
-			privacyButtons: {
-				public: {
-					style: "green",
-					iconName: "public"
-				},
-				private: {
-					style: "red",
-					iconName: "lock"
+			local: {
+				name: "",
+				displayName: "",
+				description: "",
+				theme: "blue",
+				privacy: "private",
+				requests: {
+					enabled: true,
+					access: "owner"
 				},
-				unlisted: {
-					style: "orange",
-					iconName: "link"
+				autofill: {
+					enabled: true,
+					limit: 30,
+					mode: "random"
 				}
-			},
-			autofill: {
-				enabled: true,
-				limit: 30
-			},
-			queue: {
-				enabled: true,
-				access: "owner"
 			}
 		};
 	},
@@ -284,169 +203,68 @@ export default {
 			socket: "websockets/getSocket"
 		})
 	},
+	mounted() {
+		this.local = {
+			...this.station,
+			requests: {
+				enabled: true,
+				access: "owner"
+			},
+			autofill: {
+				enabled: true,
+				limit: 30,
+				mode: this.station.playMode
+			}
+		};
+	},
 	methods: {
-		updateName() {
-			if (this.originalStation.name !== this.station.name) {
-				const { name } = this.station;
-				if (!validation.isLength(name, 2, 16)) {
+		update() {
+			if (this.originalStation !== this.local) {
+				const { name, displayName, description } = this.local;
+
+				if (!validation.isLength(name, 2, 16))
 					new Toast("Name must have between 2 and 16 characters.");
-				} else if (!validation.regex.az09_.test(name)) {
+				else if (!validation.regex.az09_.test(name))
 					new Toast(
 						"Invalid name format. Allowed characters: a-z, 0-9 and _."
 					);
-				} else {
-					this.socket.dispatch(
-						"stations.updateName",
-						this.station._id,
-						name,
-						res => {
-							new Toast(res.message);
-
-							if (res.status === "success") {
-								this.station.name = name;
-								this.originalStation.name = name;
-							}
-						}
-					);
-				}
-			} else {
-				new Toast("Please make a change before saving.");
-			}
-		},
-		updateDisplayName() {
-			if (this.originalStation.displayName !== this.station.displayName) {
-				const { displayName } = this.station;
-				if (!validation.isLength(displayName, 2, 32)) {
+				else if (!validation.isLength(displayName, 2, 32))
 					new Toast(
 						"Display name must have between 2 and 32 characters."
 					);
-				} else if (!validation.regex.ascii.test(displayName)) {
+				else if (!validation.regex.ascii.test(displayName))
 					new Toast(
 						"Invalid display name format. Only ASCII characters are allowed."
 					);
-				} else {
-					this.socket.dispatch(
-						"stations.updateDisplayName",
-						this.station._id,
-						displayName,
-						res => {
-							new Toast(res.message);
-
-							if (res.status === "success") {
-								this.station.displayName = displayName;
-								this.originalStation.displayName = displayName;
-							}
-						}
-					);
-				}
-			} else {
-				new Toast("Please make a change before saving.");
-			}
-		},
-		updateDescription() {
-			if (this.originalStation.description !== this.station.description) {
-				const { description } = this.station;
-				const characters = description
-					.split("")
-					.filter(character => character.charCodeAt(0) === 21328);
-				if (!validation.isLength(description, 2, 200)) {
+				else if (!validation.isLength(description, 2, 200))
 					new Toast(
 						"Description must have between 2 and 200 characters."
 					);
-				} else if (characters.length !== 0) {
+				else if (
+					description
+						.split("")
+						.filter(character => character.charCodeAt(0) === 21328)
+						.length !== 0
+				)
 					new Toast("Invalid description format.");
-				} else {
+				else
 					this.socket.dispatch(
-						"stations.updateDescription",
+						"stations.update",
 						this.station._id,
-						description,
+						this.local,
 						res => {
 							new Toast(res.message);
 
 							if (res.status === "success") {
-								this.station.description = description;
-								this.originalStation.description = description;
+								this.station = this.local;
+								this.originalStation = this.local;
 							}
 						}
 					);
-				}
 			} else {
 				new Toast("Please make a change before saving.");
 			}
-		},
-		updateTheme() {
-			if (this.station.theme !== this.originalStation.theme) {
-				this.socket.dispatch(
-					"stations.updateTheme",
-					this.station._id,
-					this.station.theme,
-					res => {
-						new Toast(res.message);
-
-						if (res.status === "success") {
-							this.originalStation.theme = this.station.theme;
-						}
-					}
-				);
-			}
-		},
-		updatePrivacy() {
-			if (this.station.privacy !== this.originalStation.privacy) {
-				this.socket.dispatch(
-					"stations.updatePrivacy",
-					this.station._id,
-					this.station.privacy,
-					res => {
-						new Toast(res.message);
-
-						if (res.status === "success") {
-							this.originalStation.privacy = this.station.privacy;
-						}
-					}
-				);
-			}
-		},
-		updatePlayMode() {
-			if (this.station.playMode !== this.originalStation.playMode) {
-				this.socket.dispatch(
-					"stations.updatePlayMode",
-					this.station._id,
-					this.station.playMode,
-					res => {
-						new Toast(res.message);
-
-						if (res.status === "success") {
-							this.originalStation.playMode =
-								this.station.playMode;
-						}
-					}
-				);
-			}
-		},
-		updateQueueLock() {
-			if (this.station.locked !== this.originalStation.locked) {
-				this.socket.dispatch(
-					"stations.toggleLock",
-					this.station._id,
-					res => {
-						if (res.status === "success") {
-							if (this.originalStation) {
-								this.station.locked = res.data.locked;
-								this.originalStation.locked = res.data.locked;
-							}
-
-							new Toast(
-								`Toggled queue lock successfully to ${res.data.locked}`
-							);
-						} else {
-							new Toast("Failed to toggle queue lock.");
-						}
-					}
-				);
-			}
-		},
-		updateAutofillLimit() {},
-		updateQueuePrivacy() {}
+		}
 	}
 };
 </script>

+ 4 - 61
frontend/src/components/modals/ManageStation/index.vue

@@ -301,67 +301,9 @@ export default {
 				);
 
 				this.socket.on(
-					"event:station.name.updated",
+					"event:station.updated",
 					res => {
-						this.station.name = res.data.name;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.displayName.updated",
-					res => {
-						this.station.displayName = res.data.displayName;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.description.updated",
-					res => {
-						this.station.description = res.data.description;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.partyMode.updated",
-					res => {
-						if (this.station.type === "community")
-							this.station.partyMode = res.data.partyMode;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.playMode.updated",
-					res => {
-						this.station.playMode = res.data.playMode;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.theme.updated",
-					res => {
-						const { theme } = res.data;
-						this.station.theme = theme;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.privacy.updated",
-					res => {
-						this.station.privacy = res.data.privacy;
-					},
-					{ modal: "manageStation" }
-				);
-
-				this.socket.on(
-					"event:station.queue.lock.toggled",
-					res => {
-						this.station.locked = res.data.locked;
+						this.updateStation(res.data.station);
 					},
 					{ modal: "manageStation" }
 				);
@@ -641,7 +583,8 @@ export default {
 			"updateStationPlaylist",
 			"repositionSongInList",
 			"updateStationPaused",
-			"updateCurrentSong"
+			"updateCurrentSong",
+			"updateStation"
 		]),
 		...mapActions({
 			showTab(dispatch, payload) {

+ 1 - 1
frontend/src/pages/Admin/Stations.vue

@@ -346,7 +346,7 @@ export default {
 			events: {
 				adminRoom: "stations",
 				updated: {
-					event: "admin.station.updated",
+					event: "station.updated",
 					id: "station._id",
 					item: "station"
 				},

+ 11 - 37
frontend/src/pages/Home.vue

@@ -635,45 +635,19 @@ export default {
 			if (station) station.userCount = res.data.userCount;
 		});
 
-		this.socket.on("event:station.privacy.updated", res => {
-			const station = this.stations.find(
-				station => station._id === res.data.stationId
-			);
-
-			if (station) station.privacy = res.data.privacy;
-		});
-
-		this.socket.on("event:station.name.updated", res => {
-			const station = this.stations.find(
-				station => station._id === res.data.stationId
-			);
-
-			if (station) station.name = res.data.name;
-		});
-
-		this.socket.on("event:station.displayName.updated", res => {
-			const station = this.stations.find(
-				station => station._id === res.data.stationId
-			);
-
-			if (station) station.displayName = res.data.displayName;
-		});
-
-		this.socket.on("event:station.description.updated", res => {
-			const station = this.stations.find(
-				station => station._id === res.data.stationId
-			);
+		this.socket.on("event:station.updated", res => {
+			const stationIndex = this.stations
+				.map(station => station._id)
+				.indexOf(res.data.station._id);
 
-			if (station) station.description = res.data.description;
-		});
+			if (stationIndex !== -1) {
+				this.stations[stationIndex] = {
+					...this.stations[stationIndex],
+					...res.data.station
+				};
 
-		this.socket.on("event:station.theme.updated", res => {
-			const { stationId, theme } = res.data;
-			const station = this.stations.find(
-				station => station._id === stationId
-			);
-
-			if (station) station.theme = theme;
+				this.calculateFavoriteStations();
+			}
 		});
 
 		this.socket.on("event:station.nextSong", res => {

+ 25 - 44
frontend/src/pages/Station/index.vue

@@ -1132,38 +1132,33 @@ export default {
 				this.station.privatePlaylist = null;
 		});
 
-		this.socket.on("event:station.theme.updated", res => {
-			const { theme } = res.data;
-			this.station.theme = theme;
-			document.getElementsByTagName(
-				"html"
-			)[0].style.cssText = `--primary-color: var(--${theme})`;
-		});
-
-		this.socket.on("event:station.name.updated", async res => {
-			this.station.name = res.data.name;
-
-			await this.$router.push(
-				`${res.data.name}?${Object.keys(this.$route.query)
-					.map(
-						key =>
-							`${encodeURIComponent(key)}=${encodeURIComponent(
-								this.$route.query[key]
-							)}`
-					)
-					.join("&")}`
-			);
+		this.socket.on("event:station.updated", async res => {
+			const { name, theme } = res.data.station;
+
+			if (this.station.name !== name) {
+				await this.$router.push(
+					`${name}?${Object.keys(this.$route.query)
+						.map(
+							key =>
+								`${encodeURIComponent(
+									key
+								)}=${encodeURIComponent(
+									this.$route.query[key]
+								)}`
+						)
+						.join("&")}`
+				);
 
-			// eslint-disable-next-line no-restricted-globals
-			history.replaceState({ ...history.state, ...{} }, null);
-		});
+				// eslint-disable-next-line no-restricted-globals
+				history.replaceState({ ...history.state, ...{} }, null);
+			}
 
-		this.socket.on("event:station.displayName.updated", res => {
-			this.station.displayName = res.data.displayName;
-		});
+			if (this.station.theme !== theme)
+				document.getElementsByTagName(
+					"html"
+				)[0].style.cssText = `--primary-color: var(--${theme})`;
 
-		this.socket.on("event:station.description.updated", res => {
-			this.station.description = res.data.description;
+			this.updateStation(res.data.station);
 		});
 
 		this.socket.on("event:station.users.updated", res =>
@@ -1174,10 +1169,6 @@ export default {
 			this.updateUserCount(res.data.userCount)
 		);
 
-		this.socket.on("event:station.queue.lock.toggled", res => {
-			this.station.locked = res.data.locked;
-		});
-
 		this.socket.on("event:user.station.favorited", res => {
 			if (res.data.stationId === this.station._id)
 				this.updateIfStationIsFavorited({ isFavorited: true });
@@ -1717,17 +1708,6 @@ export default {
 			if (duration <= songDuration)
 				this.timeElapsed = utils.formatTime(duration);
 		},
-		toggleLock() {
-			window.socket.dispatch(
-				"stations.toggleLock",
-				this.station._id,
-				res => {
-					if (res.status === "success") {
-						new Toast("Successfully toggled the queue lock.");
-					} else new Toast(res.message);
-				}
-			);
-		},
 		changeVolume() {
 			const volume = this.volumeSliderValue;
 			localStorage.setItem("volume", volume);
@@ -2264,6 +2244,7 @@ export default {
 		...mapActions("station", [
 			"joinStation",
 			"leaveStation",
+			"updateStation",
 			"updateUserCount",
 			"updateUsers",
 			"updateCurrentSong",

+ 5 - 1
frontend/src/store/modules/modals/manageStation.js

@@ -31,7 +31,8 @@ export default {
 		updateStationPaused: ({ commit }, stationPaused) =>
 			commit("updateStationPaused", stationPaused),
 		updateCurrentSong: ({ commit }, currentSong) =>
-			commit("updateCurrentSong", currentSong)
+			commit("updateCurrentSong", currentSong),
+		updateStation: ({ commit }, station) => commit("updateStation", station)
 	},
 	mutations: {
 		showTab(state, tab) {
@@ -87,6 +88,9 @@ export default {
 		},
 		updateCurrentSong(state, currentSong) {
 			state.currentSong = currentSong;
+		},
+		updateStation(state, station) {
+			state.station = { ...state.station, ...station };
 		}
 	}
 };

+ 6 - 0
frontend/src/store/modules/station.js

@@ -31,6 +31,9 @@ const actions = {
 	editStation: ({ commit }, station) => {
 		commit("editStation", station);
 	},
+	updateStation: ({ commit }, station) => {
+		commit("updateStation", station);
+	},
 	updateUserCount: ({ commit }, userCount) => {
 		commit("updateUserCount", userCount);
 	},
@@ -109,6 +112,9 @@ const mutations = {
 	editStation(state, station) {
 		state.editing = { ...station };
 	},
+	updateStation(state, station) {
+		state.station = { ...state.station, ...station };
+	},
 	updateUserCount(state, userCount) {
 		state.userCount = userCount;
 	},

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff