|
@@ -1,3 +1,70 @@
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { useStore } from "vuex";
|
|
|
|
+import { computed } from "vue";
|
|
|
|
+import Toast from "toasters";
|
|
|
|
+import { useModalState } from "@/vuex_helpers";
|
|
|
|
+import validation from "@/validation";
|
|
|
|
+
|
|
|
|
+const props = defineProps({
|
|
|
|
+ modalUuid: { type: String, default: "" }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const store = useStore();
|
|
|
|
+
|
|
|
|
+const userId = computed(() => store.state.user.auth.userId);
|
|
|
|
+const userRole = computed(() => store.state.user.auth.role);
|
|
|
|
+
|
|
|
|
+const { socket } = store.state.websockets;
|
|
|
|
+
|
|
|
|
+const modalState = useModalState("modals/editPlaylist/MODAL_UUID", {
|
|
|
|
+ modalUuid: props.modalUuid
|
|
|
|
+});
|
|
|
|
+const playlist = computed(() => modalState.playlist);
|
|
|
|
+
|
|
|
|
+const isEditable = () =>
|
|
|
|
+ (playlist.value.type === "user" ||
|
|
|
|
+ playlist.value.type === "user-liked" ||
|
|
|
|
+ playlist.value.type === "user-disliked") &&
|
|
|
|
+ (userId.value === playlist.value.createdBy || userRole.value === "admin");
|
|
|
|
+
|
|
|
|
+const isAdmin = () => userRole.value === "admin";
|
|
|
|
+
|
|
|
|
+const renamePlaylist = () => {
|
|
|
|
+ const { displayName } = playlist.value;
|
|
|
|
+ if (!validation.isLength(displayName, 2, 32))
|
|
|
|
+ return new Toast("Display name must have between 2 and 32 characters.");
|
|
|
|
+ if (!validation.regex.ascii.test(displayName))
|
|
|
|
+ return new Toast(
|
|
|
|
+ "Invalid display name format. Only ASCII characters are allowed."
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ return socket.dispatch(
|
|
|
|
+ "playlists.updateDisplayName",
|
|
|
|
+ playlist.value._id,
|
|
|
|
+ playlist.value.displayName,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const updatePrivacy = () => {
|
|
|
|
+ const { privacy } = playlist.value;
|
|
|
|
+ if (privacy === "public" || privacy === "private") {
|
|
|
|
+ socket.dispatch(
|
|
|
|
+ playlist.value.type === "genre"
|
|
|
|
+ ? "playlists.updatePrivacyAdmin"
|
|
|
|
+ : "playlists.updatePrivacy",
|
|
|
|
+ playlist.value._id,
|
|
|
|
+ privacy,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+
|
|
<template>
|
|
<template>
|
|
<div class="settings-tab section">
|
|
<div class="settings-tab section">
|
|
<div
|
|
<div
|
|
@@ -54,84 +121,6 @@
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
-<script>
|
|
|
|
-import { mapState, mapGetters /* , mapActions */ } from "vuex";
|
|
|
|
-import Toast from "toasters";
|
|
|
|
-
|
|
|
|
-import { mapModalState } from "@/vuex_helpers";
|
|
|
|
-import validation from "@/validation";
|
|
|
|
-
|
|
|
|
-export default {
|
|
|
|
- props: {
|
|
|
|
- modalUuid: { type: String, default: "" }
|
|
|
|
- },
|
|
|
|
- data() {
|
|
|
|
- return {};
|
|
|
|
- },
|
|
|
|
- computed: {
|
|
|
|
- ...mapModalState("modals/editPlaylist/MODAL_UUID", {
|
|
|
|
- playlist: state => state.playlist
|
|
|
|
- }),
|
|
|
|
- ...mapGetters({
|
|
|
|
- socket: "websockets/getSocket"
|
|
|
|
- }),
|
|
|
|
- ...mapState({
|
|
|
|
- userId: state => state.user.auth.userId,
|
|
|
|
- userRole: state => state.user.auth.role
|
|
|
|
- })
|
|
|
|
- },
|
|
|
|
- methods: {
|
|
|
|
- isEditable() {
|
|
|
|
- return (
|
|
|
|
- (this.playlist.type === "user" ||
|
|
|
|
- this.playlist.type === "user-liked" ||
|
|
|
|
- this.playlist.type === "user-disliked") &&
|
|
|
|
- (this.userId === this.playlist.createdBy ||
|
|
|
|
- this.userRole === "admin")
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- isAdmin() {
|
|
|
|
- return this.userRole === "admin";
|
|
|
|
- },
|
|
|
|
- renamePlaylist() {
|
|
|
|
- const { displayName } = this.playlist;
|
|
|
|
- if (!validation.isLength(displayName, 2, 32))
|
|
|
|
- return new Toast(
|
|
|
|
- "Display name must have between 2 and 32 characters."
|
|
|
|
- );
|
|
|
|
- if (!validation.regex.ascii.test(displayName))
|
|
|
|
- return new Toast(
|
|
|
|
- "Invalid display name format. Only ASCII characters are allowed."
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- return this.socket.dispatch(
|
|
|
|
- "playlists.updateDisplayName",
|
|
|
|
- this.playlist._id,
|
|
|
|
- this.playlist.displayName,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- updatePrivacy() {
|
|
|
|
- const { privacy } = this.playlist;
|
|
|
|
- if (privacy === "public" || privacy === "private") {
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- this.playlist.type === "genre"
|
|
|
|
- ? "playlists.updatePrivacyAdmin"
|
|
|
|
- : "playlists.updatePrivacy",
|
|
|
|
- this.playlist._id,
|
|
|
|
- privacy,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
<style lang="less" scoped>
|
|
<style lang="less" scoped>
|
|
@media screen and (max-width: 1300px) {
|
|
@media screen and (max-width: 1300px) {
|
|
.section {
|
|
.section {
|