|
@@ -1,5 +1,8 @@
|
|
<template>
|
|
<template>
|
|
- <div class="station-playlists">
|
|
|
|
|
|
+ <div class="playlist-tab-base">
|
|
|
|
+ <div v-if="$slots.info" class="top-info has-text-centered">
|
|
|
|
+ <slot name="info" />
|
|
|
|
+ </div>
|
|
<div class="tabs-container">
|
|
<div class="tabs-container">
|
|
<div class="tab-selection">
|
|
<div class="tab-selection">
|
|
<button
|
|
<button
|
|
@@ -39,48 +42,78 @@
|
|
>
|
|
>
|
|
<template #item-icon>
|
|
<template #item-icon>
|
|
<i
|
|
<i
|
|
- class="material-icons"
|
|
|
|
- v-if="isIncluded(featuredPlaylist._id)"
|
|
|
|
- content="This playlist is currently included"
|
|
|
|
|
|
+ class="material-icons blacklisted-icon"
|
|
|
|
+ v-if="
|
|
|
|
+ isSelected(
|
|
|
|
+ featuredPlaylist._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
|
|
+ "
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_arrow
|
|
|
|
|
|
+ block
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
- class="material-icons blacklisted-icon"
|
|
|
|
- v-else-if="isBlacklisted(featuredPlaylist._id)"
|
|
|
|
- content="This playlist is currently blacklisted"
|
|
|
|
|
|
+ class="material-icons"
|
|
|
|
+ v-else-if="isSelected(featuredPlaylist._id)"
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- block
|
|
|
|
|
|
+ play_arrow
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
class="material-icons"
|
|
class="material-icons"
|
|
v-else
|
|
v-else
|
|
- content="This playlist is currently not included or blacklisted"
|
|
|
|
|
|
+ :content="`This playlist is currently not ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_disabled
|
|
|
|
|
|
+ {{
|
|
|
|
+ type === "blacklist"
|
|
|
|
+ ? "block"
|
|
|
|
+ : "play_disabled"
|
|
|
|
+ }}
|
|
</i>
|
|
</i>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<template #actions>
|
|
<template #actions>
|
|
<i
|
|
<i
|
|
- v-if="isBlacklisted(featuredPlaylist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(
|
|
|
|
+ featuredPlaylist._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
|
|
+ "
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="This playlist is blacklisted in this station"
|
|
|
|
|
|
+ :content="`This playlist is ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )} in this station`"
|
|
v-tippy="{ theme: 'info' }"
|
|
v-tippy="{ theme: 'info' }"
|
|
>play_disabled</i
|
|
>play_disabled</i
|
|
>
|
|
>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="isIncluded(featuredPlaylist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(featuredPlaylist._id)
|
|
|
|
+ "
|
|
@confirm="
|
|
@confirm="
|
|
- removeIncludedPlaylist(featuredPlaylist._id)
|
|
|
|
|
|
+ deselectPlaylist(featuredPlaylist._id)
|
|
"
|
|
"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop playing songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
stop
|
|
stop
|
|
@@ -88,39 +121,66 @@
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
<i
|
|
<i
|
|
v-if="
|
|
v-if="
|
|
- !isIncluded(featuredPlaylist._id) &&
|
|
|
|
- !isBlacklisted(featuredPlaylist._id)
|
|
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ !isSelected(featuredPlaylist._id) &&
|
|
|
|
+ !isSelected(
|
|
|
|
+ featuredPlaylist._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
"
|
|
"
|
|
- @click="includePlaylist(featuredPlaylist)"
|
|
|
|
|
|
+ @click="selectPlaylist(featuredPlaylist)"
|
|
class="material-icons play-icon"
|
|
class="material-icons play-icon"
|
|
- :content="'Play songs from this playlist'"
|
|
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>play_arrow</i
|
|
>play_arrow</i
|
|
>
|
|
>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="!isBlacklisted(featuredPlaylist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ !isSelected(
|
|
|
|
+ featuredPlaylist._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
|
|
+ "
|
|
@confirm="
|
|
@confirm="
|
|
- blacklistPlaylist(featuredPlaylist._id)
|
|
|
|
|
|
+ selectPlaylist(
|
|
|
|
+ featuredPlaylist,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
"
|
|
"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Blacklist Playlist"
|
|
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} Playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>block</i
|
|
>block</i
|
|
>
|
|
>
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="isBlacklisted(featuredPlaylist._id)"
|
|
|
|
- @confirm="
|
|
|
|
- removeBlacklistedPlaylist(
|
|
|
|
- featuredPlaylist._id
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ isSelected(
|
|
|
|
+ featuredPlaylist._id,
|
|
|
|
+ 'blacklist'
|
|
)
|
|
)
|
|
"
|
|
"
|
|
|
|
+ @confirm="
|
|
|
|
+ deselectPlaylist(featuredPlaylist._id)
|
|
|
|
+ "
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop blacklisting songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
stop
|
|
stop
|
|
@@ -178,46 +238,68 @@
|
|
>
|
|
>
|
|
<template #item-icon>
|
|
<template #item-icon>
|
|
<i
|
|
<i
|
|
- class="material-icons"
|
|
|
|
- v-if="isIncluded(playlist._id)"
|
|
|
|
- content="This playlist is currently included"
|
|
|
|
|
|
+ class="material-icons blacklisted-icon"
|
|
|
|
+ v-if="isSelected(playlist._id, 'blacklist')"
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_arrow
|
|
|
|
|
|
+ block
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
- class="material-icons blacklisted-icon"
|
|
|
|
- v-else-if="isBlacklisted(playlist._id)"
|
|
|
|
- content="This playlist is currently blacklisted"
|
|
|
|
|
|
+ class="material-icons"
|
|
|
|
+ v-else-if="isSelected(playlist._id)"
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- block
|
|
|
|
|
|
+ play_arrow
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
class="material-icons"
|
|
class="material-icons"
|
|
v-else
|
|
v-else
|
|
- content="This playlist is currently not included or blacklisted"
|
|
|
|
|
|
+ :content="`This playlist is currently not ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_disabled
|
|
|
|
|
|
+ {{
|
|
|
|
+ type === "blacklist"
|
|
|
|
+ ? "block"
|
|
|
|
+ : "play_disabled"
|
|
|
|
+ }}
|
|
</i>
|
|
</i>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<template #actions>
|
|
<template #actions>
|
|
<i
|
|
<i
|
|
- v-if="isBlacklisted(playlist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(playlist._id, 'blacklist')
|
|
|
|
+ "
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="This playlist is blacklisted in this station"
|
|
|
|
|
|
+ :content="`This playlist is ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )} in this station`"
|
|
v-tippy="{ theme: 'info' }"
|
|
v-tippy="{ theme: 'info' }"
|
|
>play_disabled</i
|
|
>play_disabled</i
|
|
>
|
|
>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="isIncluded(playlist._id)"
|
|
|
|
- @confirm="removeIncludedPlaylist(playlist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(playlist._id)
|
|
|
|
+ "
|
|
|
|
+ @confirm="deselectPlaylist(playlist._id)"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop playing songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
stop
|
|
stop
|
|
@@ -225,35 +307,50 @@
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
<i
|
|
<i
|
|
v-if="
|
|
v-if="
|
|
- !isIncluded(playlist._id) &&
|
|
|
|
- !isBlacklisted(playlist._id)
|
|
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ !isSelected(playlist._id) &&
|
|
|
|
+ !isSelected(playlist._id, 'blacklist')
|
|
"
|
|
"
|
|
- @click="includePlaylist(playlist)"
|
|
|
|
|
|
+ @click="selectPlaylist(playlist)"
|
|
class="material-icons play-icon"
|
|
class="material-icons play-icon"
|
|
- :content="'Play songs from this playlist'"
|
|
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>play_arrow</i
|
|
>play_arrow</i
|
|
>
|
|
>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="!isBlacklisted(playlist._id)"
|
|
|
|
- @confirm="blacklistPlaylist(playlist._id)"
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ !isSelected(playlist._id, 'blacklist')
|
|
|
|
+ "
|
|
|
|
+ @confirm="selectPlaylist(playlist, 'blacklist')"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Blacklist Playlist"
|
|
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} Playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>block</i
|
|
>block</i
|
|
>
|
|
>
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
- v-if="isBlacklisted(playlist._id)"
|
|
|
|
- @confirm="
|
|
|
|
- removeBlacklistedPlaylist(playlist._id)
|
|
|
|
|
|
+ v-if="
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ isSelected(playlist._id, 'blacklist')
|
|
"
|
|
"
|
|
|
|
+ @confirm="deselectPlaylist(playlist._id)"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop blacklisting songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
stop
|
|
stop
|
|
@@ -289,6 +386,74 @@
|
|
</button>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
+ <div class="tab" v-show="tab === 'current'">
|
|
|
|
+ <div v-if="selectedPlaylists().length > 0">
|
|
|
|
+ <playlist-item
|
|
|
|
+ v-for="playlist in selectedPlaylists()"
|
|
|
|
+ :key="`key-${playlist._id}`"
|
|
|
|
+ :playlist="playlist"
|
|
|
|
+ :show-owner="true"
|
|
|
|
+ >
|
|
|
|
+ <template #item-icon>
|
|
|
|
+ <i
|
|
|
|
+ class="material-icons"
|
|
|
|
+ :class="{
|
|
|
|
+ 'blacklisted-icon': type === 'blacklist'
|
|
|
|
+ }"
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
|
|
+ v-tippy
|
|
|
|
+ >
|
|
|
|
+ {{
|
|
|
|
+ type === "blacklist"
|
|
|
|
+ ? "block"
|
|
|
|
+ : "play_arrow"
|
|
|
|
+ }}
|
|
|
|
+ </i>
|
|
|
|
+ </template>
|
|
|
|
+
|
|
|
|
+ <template #actions>
|
|
|
|
+ <quick-confirm
|
|
|
|
+ v-if="isOwnerOrAdmin()"
|
|
|
|
+ @confirm="deselectPlaylist(playlist._id)"
|
|
|
|
+ >
|
|
|
|
+ <i
|
|
|
|
+ class="material-icons stop-icon"
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
|
|
+ v-tippy
|
|
|
|
+ >
|
|
|
|
+ stop
|
|
|
|
+ </i>
|
|
|
|
+ </quick-confirm>
|
|
|
|
+ <i
|
|
|
|
+ v-if="playlist.createdBy === myUserId"
|
|
|
|
+ @click="showPlaylist(playlist._id)"
|
|
|
|
+ class="material-icons edit-icon"
|
|
|
|
+ content="Edit Playlist"
|
|
|
|
+ v-tippy
|
|
|
|
+ >edit</i
|
|
|
|
+ >
|
|
|
|
+ <i
|
|
|
|
+ v-if="
|
|
|
|
+ playlist.createdBy !== myUserId &&
|
|
|
|
+ (playlist.privacy === 'public' || isAdmin())
|
|
|
|
+ "
|
|
|
|
+ @click="showPlaylist(playlist._id)"
|
|
|
|
+ class="material-icons edit-icon"
|
|
|
|
+ content="View Playlist"
|
|
|
|
+ v-tippy
|
|
|
|
+ >visibility</i
|
|
|
|
+ >
|
|
|
|
+ </template>
|
|
|
|
+ </playlist-item>
|
|
|
|
+ </div>
|
|
|
|
+ <p v-else class="has-text-centered scrollable-list">
|
|
|
|
+ No playlists currently included.
|
|
|
|
+ </p>
|
|
|
|
+ </div>
|
|
<div
|
|
<div
|
|
v-if="station.type === 'community'"
|
|
v-if="station.type === 'community'"
|
|
class="tab"
|
|
class="tab"
|
|
@@ -324,89 +489,129 @@
|
|
>
|
|
>
|
|
<template #item-icon>
|
|
<template #item-icon>
|
|
<i
|
|
<i
|
|
- class="material-icons"
|
|
|
|
- v-if="isIncluded(element._id)"
|
|
|
|
- content="This playlist is currently included"
|
|
|
|
|
|
+ class="material-icons blacklisted-icon"
|
|
|
|
+ v-if="
|
|
|
|
+ isSelected(element._id, 'blacklist')
|
|
|
|
+ "
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_arrow
|
|
|
|
|
|
+ block
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
- class="material-icons blacklisted-icon"
|
|
|
|
- v-else-if="isBlacklisted(element._id)"
|
|
|
|
- content="This playlist is currently blacklisted"
|
|
|
|
|
|
+ class="material-icons"
|
|
|
|
+ v-else-if="isSelected(element._id)"
|
|
|
|
+ :content="`This playlist is currently ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- block
|
|
|
|
|
|
+ play_arrow
|
|
</i>
|
|
</i>
|
|
<i
|
|
<i
|
|
class="material-icons"
|
|
class="material-icons"
|
|
v-else
|
|
v-else
|
|
- content="This playlist is currently not included or blacklisted"
|
|
|
|
|
|
+ :content="`This playlist is currently not ${label(
|
|
|
|
+ 'past'
|
|
|
|
+ )}`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
- play_disabled
|
|
|
|
|
|
+ {{
|
|
|
|
+ type === "blacklist"
|
|
|
|
+ ? "block"
|
|
|
|
+ : "play_disabled"
|
|
|
|
+ }}
|
|
</i>
|
|
</i>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<template #actions>
|
|
<template #actions>
|
|
<i
|
|
<i
|
|
v-if="
|
|
v-if="
|
|
- isOwnerOrAdmin() &&
|
|
|
|
- !isIncluded(element._id)
|
|
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(element._id, 'blacklist')
|
|
"
|
|
"
|
|
- @click="includePlaylist(element)"
|
|
|
|
- class="material-icons play-icon"
|
|
|
|
- content="Play songs from this playlist"
|
|
|
|
- v-tippy
|
|
|
|
- >play_arrow</i
|
|
|
|
|
|
+ class="material-icons stop-icon"
|
|
|
|
+ :content="`This playlist is ${label(
|
|
|
|
+ 'past',
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )} in this station`"
|
|
|
|
+ v-tippy="{ theme: 'info' }"
|
|
|
|
+ >play_disabled</i
|
|
>
|
|
>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
v-if="
|
|
v-if="
|
|
- isOwnerOrAdmin() &&
|
|
|
|
- isIncluded(element._id)
|
|
|
|
- "
|
|
|
|
- @confirm="
|
|
|
|
- removeIncludedPlaylist(element._id)
|
|
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ isSelected(element._id)
|
|
"
|
|
"
|
|
|
|
+ @confirm="deselectPlaylist(element._id)"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop playing songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
- >stop</i
|
|
|
|
>
|
|
>
|
|
|
|
+ stop
|
|
|
|
+ </i>
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
|
|
+ <i
|
|
|
|
+ v-if="
|
|
|
|
+ type !== 'blacklist' &&
|
|
|
|
+ !isSelected(element._id) &&
|
|
|
|
+ !isSelected(
|
|
|
|
+ element._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
|
|
+ "
|
|
|
|
+ @click="selectPlaylist(element)"
|
|
|
|
+ class="material-icons play-icon"
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} songs from this playlist`"
|
|
|
|
+ v-tippy
|
|
|
|
+ >play_arrow</i
|
|
|
|
+ >
|
|
<quick-confirm
|
|
<quick-confirm
|
|
v-if="
|
|
v-if="
|
|
- isOwnerOrAdmin() &&
|
|
|
|
- !isBlacklisted(element._id)
|
|
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ !isSelected(
|
|
|
|
+ element._id,
|
|
|
|
+ 'blacklist'
|
|
|
|
+ )
|
|
"
|
|
"
|
|
@confirm="
|
|
@confirm="
|
|
- blacklistPlaylist(element._id)
|
|
|
|
|
|
+ selectPlaylist(element, 'blacklist')
|
|
"
|
|
"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Blacklist Playlist"
|
|
|
|
|
|
+ :content="`${label(
|
|
|
|
+ 'future',
|
|
|
|
+ null,
|
|
|
|
+ true
|
|
|
|
+ )} Playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>block</i
|
|
>block</i
|
|
>
|
|
>
|
|
</quick-confirm>
|
|
</quick-confirm>
|
|
<quick-confirm
|
|
<quick-confirm
|
|
v-if="
|
|
v-if="
|
|
- isOwnerOrAdmin() &&
|
|
|
|
- isBlacklisted(element._id)
|
|
|
|
- "
|
|
|
|
- @confirm="
|
|
|
|
- removeBlacklistedPlaylist(
|
|
|
|
- element._id
|
|
|
|
- )
|
|
|
|
|
|
+ type === 'blacklist' &&
|
|
|
|
+ isSelected(element._id, 'blacklist')
|
|
"
|
|
"
|
|
|
|
+ @confirm="deselectPlaylist(element._id)"
|
|
>
|
|
>
|
|
<i
|
|
<i
|
|
class="material-icons stop-icon"
|
|
class="material-icons stop-icon"
|
|
- content="Stop blacklisting songs from this playlist"
|
|
|
|
|
|
+ :content="`Stop ${label(
|
|
|
|
+ 'present'
|
|
|
|
+ )} songs from this playlist`"
|
|
v-tippy
|
|
v-tippy
|
|
>
|
|
>
|
|
stop
|
|
stop
|
|
@@ -429,74 +634,6 @@
|
|
You don't have any playlists!
|
|
You don't have any playlists!
|
|
</p>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
- <div class="tab" v-show="tab === 'current'">
|
|
|
|
- <div v-if="includedPlaylists.length > 0">
|
|
|
|
- <playlist-item
|
|
|
|
- v-for="playlist in includedPlaylists"
|
|
|
|
- :key="`key-${playlist._id}`"
|
|
|
|
- :playlist="playlist"
|
|
|
|
- :show-owner="true"
|
|
|
|
- >
|
|
|
|
- <template #item-icon>
|
|
|
|
- <i
|
|
|
|
- class="material-icons"
|
|
|
|
- content="This playlist is currently included"
|
|
|
|
- v-tippy
|
|
|
|
- >
|
|
|
|
- play_arrow
|
|
|
|
- </i>
|
|
|
|
- </template>
|
|
|
|
-
|
|
|
|
- <template #actions>
|
|
|
|
- <quick-confirm
|
|
|
|
- v-if="isOwnerOrAdmin()"
|
|
|
|
- @confirm="removeIncludedPlaylist(playlist._id)"
|
|
|
|
- >
|
|
|
|
- <i
|
|
|
|
- class="material-icons stop-icon"
|
|
|
|
- content="Stop playing songs from this playlist"
|
|
|
|
- v-tippy
|
|
|
|
- >
|
|
|
|
- stop
|
|
|
|
- </i>
|
|
|
|
- </quick-confirm>
|
|
|
|
- <quick-confirm
|
|
|
|
- v-if="isOwnerOrAdmin()"
|
|
|
|
- @confirm="blacklistPlaylist(playlist._id)"
|
|
|
|
- >
|
|
|
|
- <i
|
|
|
|
- class="material-icons stop-icon"
|
|
|
|
- content="Blacklist Playlist"
|
|
|
|
- v-tippy
|
|
|
|
- >block</i
|
|
|
|
- >
|
|
|
|
- </quick-confirm>
|
|
|
|
- <i
|
|
|
|
- v-if="playlist.createdBy === myUserId"
|
|
|
|
- @click="showPlaylist(playlist._id)"
|
|
|
|
- class="material-icons edit-icon"
|
|
|
|
- content="Edit Playlist"
|
|
|
|
- v-tippy
|
|
|
|
- >edit</i
|
|
|
|
- >
|
|
|
|
- <i
|
|
|
|
- v-if="
|
|
|
|
- playlist.createdBy !== myUserId &&
|
|
|
|
- (playlist.privacy === 'public' || isAdmin())
|
|
|
|
- "
|
|
|
|
- @click="showPlaylist(playlist._id)"
|
|
|
|
- class="material-icons edit-icon"
|
|
|
|
- content="View Playlist"
|
|
|
|
- v-tippy
|
|
|
|
- >visibility</i
|
|
|
|
- >
|
|
|
|
- </template>
|
|
|
|
- </playlist-item>
|
|
|
|
- </div>
|
|
|
|
- <p v-else class="has-text-centered scrollable-list">
|
|
|
|
- No playlists currently included.
|
|
|
|
- </p>
|
|
|
|
- </div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
@@ -516,9 +653,20 @@ export default {
|
|
PlaylistItem
|
|
PlaylistItem
|
|
},
|
|
},
|
|
mixins: [SortablePlaylists],
|
|
mixins: [SortablePlaylists],
|
|
|
|
+ props: {
|
|
|
|
+ type: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: ""
|
|
|
|
+ },
|
|
|
|
+ sector: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: "manageStation"
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ emits: ["selected"],
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- tab: "included",
|
|
|
|
|
|
+ tab: "current",
|
|
search: {
|
|
search: {
|
|
query: "",
|
|
query: "",
|
|
searchedQuery: "",
|
|
searchedQuery: "",
|
|
@@ -531,6 +679,36 @@ export default {
|
|
};
|
|
};
|
|
},
|
|
},
|
|
computed: {
|
|
computed: {
|
|
|
|
+ station: {
|
|
|
|
+ get() {
|
|
|
|
+ if (this.sector === "manageStation")
|
|
|
|
+ return this.$store.state.modals.manageStation.station;
|
|
|
|
+ return this.$store.state.station.station;
|
|
|
|
+ },
|
|
|
|
+ set(station) {
|
|
|
|
+ if (this.sector === "manageStation")
|
|
|
|
+ this.$store.commit(
|
|
|
|
+ "modals/manageStation/updateStation",
|
|
|
|
+ station
|
|
|
|
+ );
|
|
|
|
+ else this.$store.commit("station/updateStation", station);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ blacklist: {
|
|
|
|
+ get() {
|
|
|
|
+ if (this.sector === "manageStation")
|
|
|
|
+ return this.$store.state.modals.manageStation.blacklist;
|
|
|
|
+ return this.$store.state.station.blacklist;
|
|
|
|
+ },
|
|
|
|
+ set(blacklist) {
|
|
|
|
+ if (this.sector === "manageStation")
|
|
|
|
+ this.$store.commit(
|
|
|
|
+ "modals/manageStation/setBlacklist",
|
|
|
|
+ blacklist
|
|
|
|
+ );
|
|
|
|
+ else this.$store.commit("station/setBlacklist", blacklist);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
resultsLeftCount() {
|
|
resultsLeftCount() {
|
|
return this.search.count - this.search.results.length;
|
|
return this.search.count - this.search.results.length;
|
|
},
|
|
},
|
|
@@ -543,12 +721,11 @@ export default {
|
|
userId: state => state.user.auth.userId
|
|
userId: state => state.user.auth.userId
|
|
}),
|
|
}),
|
|
...mapState("modals/manageStation", {
|
|
...mapState("modals/manageStation", {
|
|
- parentTab: state => state.tab,
|
|
|
|
originalStation: state => state.originalStation,
|
|
originalStation: state => state.originalStation,
|
|
- station: state => state.station,
|
|
|
|
- includedPlaylists: state => state.includedPlaylists,
|
|
|
|
- blacklist: state => state.blacklist,
|
|
|
|
- songsList: state => state.songsList
|
|
|
|
|
|
+ includedPlaylists: state => state.includedPlaylists
|
|
|
|
+ }),
|
|
|
|
+ ...mapState("station", {
|
|
|
|
+ autoRequest: state => state.autoRequest
|
|
}),
|
|
}),
|
|
...mapGetters({
|
|
...mapGetters({
|
|
socket: "websockets/getSocket"
|
|
socket: "websockets/getSocket"
|
|
@@ -572,17 +749,18 @@ export default {
|
|
this.featuredPlaylists = res.data.playlists;
|
|
this.featuredPlaylists = res.data.playlists;
|
|
});
|
|
});
|
|
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- `stations.getStationIncludedPlaylistsById`,
|
|
|
|
- this.station._id,
|
|
|
|
- res => {
|
|
|
|
- if (res.status === "success") {
|
|
|
|
- this.station.includedPlaylists = res.data.playlists;
|
|
|
|
- this.originalStation.includedPlaylists =
|
|
|
|
- res.data.playlists;
|
|
|
|
|
|
+ if (this.type === "autofill")
|
|
|
|
+ this.socket.dispatch(
|
|
|
|
+ `stations.getStationIncludedPlaylistsById`,
|
|
|
|
+ this.station._id,
|
|
|
|
+ res => {
|
|
|
|
+ if (res.status === "success") {
|
|
|
|
+ this.station.includedPlaylists = res.data.playlists;
|
|
|
|
+ this.originalStation.includedPlaylists =
|
|
|
|
+ res.data.playlists;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- );
|
|
|
|
|
|
+ );
|
|
|
|
|
|
this.socket.dispatch(
|
|
this.socket.dispatch(
|
|
`stations.getStationBlacklistById`,
|
|
`stations.getStationBlacklistById`,
|
|
@@ -616,53 +794,126 @@ export default {
|
|
this.editPlaylist(playlistId);
|
|
this.editPlaylist(playlistId);
|
|
this.openModal("editPlaylist");
|
|
this.openModal("editPlaylist");
|
|
},
|
|
},
|
|
- includePlaylist(playlist) {
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- "stations.includePlaylist",
|
|
|
|
- this.station._id,
|
|
|
|
- playlist._id,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
|
|
+ label(tense = "future", typeOverwrite = null, capitalize = false) {
|
|
|
|
+ let label = typeOverwrite || this.type;
|
|
|
|
+
|
|
|
|
+ if (tense === "past") label = `${label}ed`;
|
|
|
|
+ if (tense === "present") label = `${label}ing`;
|
|
|
|
+
|
|
|
|
+ if (capitalize)
|
|
|
|
+ label = `${label.charAt(0).toUpperCase()}${label.slice(1)}`;
|
|
|
|
+
|
|
|
|
+ return label;
|
|
},
|
|
},
|
|
- removeIncludedPlaylist(id) {
|
|
|
|
- return new Promise(resolve => {
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- "stations.removeIncludedPlaylist",
|
|
|
|
- this.station._id,
|
|
|
|
- id,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
- resolve();
|
|
|
|
- }
|
|
|
|
|
|
+ selectedPlaylists(typeOverwrite) {
|
|
|
|
+ const type = typeOverwrite || this.type;
|
|
|
|
+
|
|
|
|
+ if (type === "autofill") return this.includedPlaylists;
|
|
|
|
+ if (type === "blacklist") return this.blacklist;
|
|
|
|
+ if (type === "autorequest") return this.autoRequest;
|
|
|
|
+ return [];
|
|
|
|
+ },
|
|
|
|
+ async selectPlaylist(playlist, typeOverwrite) {
|
|
|
|
+ const type = typeOverwrite || this.type;
|
|
|
|
+
|
|
|
|
+ if (this.isSelected(playlist._id, type))
|
|
|
|
+ return new Toast(
|
|
|
|
+ `Error: Playlist already ${this.label("past", type)}.`
|
|
);
|
|
);
|
|
- });
|
|
|
|
|
|
+
|
|
|
|
+ if (type === "autofill")
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ this.socket.dispatch(
|
|
|
|
+ "stations.includePlaylist",
|
|
|
|
+ this.station._id,
|
|
|
|
+ playlist._id,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ this.$emit("selected");
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ if (type === "blacklist") {
|
|
|
|
+ if (this.type !== "blacklist" && this.isSelected(playlist._id))
|
|
|
|
+ await this.deselectPlaylist(playlist._id);
|
|
|
|
+
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ this.socket.dispatch(
|
|
|
|
+ "stations.blacklistPlaylist",
|
|
|
|
+ this.station._id,
|
|
|
|
+ playlist._id,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ this.$emit("selected");
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if (type === "autorequest")
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ this.autoRequest.push(playlist);
|
|
|
|
+ new Toast(
|
|
|
|
+ "Successfully selected playlist to auto request songs."
|
|
|
|
+ );
|
|
|
|
+ this.$emit("selected");
|
|
|
|
+ resolve();
|
|
|
|
+ });
|
|
|
|
+ return false;
|
|
},
|
|
},
|
|
- removeBlacklistedPlaylist(id) {
|
|
|
|
- return new Promise(resolve => {
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- "stations.removeBlacklistedPlaylist",
|
|
|
|
- this.station._id,
|
|
|
|
- id,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
|
|
+ deselectPlaylist(playlistId, typeOverwrite) {
|
|
|
|
+ const type = typeOverwrite || this.type;
|
|
|
|
+
|
|
|
|
+ if (type === "autofill")
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ this.socket.dispatch(
|
|
|
|
+ "stations.removeIncludedPlaylist",
|
|
|
|
+ this.station._id,
|
|
|
|
+ playlistId,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ if (type === "blacklist")
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ this.socket.dispatch(
|
|
|
|
+ "stations.removeBlacklistedPlaylist",
|
|
|
|
+ this.station._id,
|
|
|
|
+ playlistId,
|
|
|
|
+ res => {
|
|
|
|
+ new Toast(res.message);
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ if (type === "autorequest")
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
+ let selected = false;
|
|
|
|
+ this.autoRequest.forEach((playlist, index) => {
|
|
|
|
+ if (playlist._id === playlistId) {
|
|
|
|
+ selected = true;
|
|
|
|
+ this.autoRequest.splice(index, 1);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ if (selected) {
|
|
|
|
+ new Toast("Successfully deselected playlist.");
|
|
|
|
+ resolve();
|
|
|
|
+ } else {
|
|
|
|
+ new Toast("Playlist not selected.");
|
|
resolve();
|
|
resolve();
|
|
}
|
|
}
|
|
- );
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- isIncluded(id) {
|
|
|
|
- let included = false;
|
|
|
|
- this.includedPlaylists.forEach(playlist => {
|
|
|
|
- if (playlist._id === id) included = true;
|
|
|
|
- });
|
|
|
|
- return included;
|
|
|
|
|
|
+ });
|
|
|
|
+ return false;
|
|
},
|
|
},
|
|
- isBlacklisted(id) {
|
|
|
|
|
|
+ isSelected(playlistId, typeOverwrite) {
|
|
|
|
+ const type = typeOverwrite || this.type;
|
|
let selected = false;
|
|
let selected = false;
|
|
- this.blacklist.forEach(playlist => {
|
|
|
|
- if (playlist._id === id) selected = true;
|
|
|
|
|
|
+
|
|
|
|
+ this.selectedPlaylists(type).forEach(playlist => {
|
|
|
|
+ if (playlist._id === playlistId) selected = true;
|
|
});
|
|
});
|
|
return selected;
|
|
return selected;
|
|
},
|
|
},
|
|
@@ -708,18 +959,6 @@ export default {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
},
|
|
},
|
|
- async blacklistPlaylist(id) {
|
|
|
|
- if (this.isIncluded(id)) await this.removeIncludedPlaylist(id);
|
|
|
|
-
|
|
|
|
- this.socket.dispatch(
|
|
|
|
- "stations.blacklistPlaylist",
|
|
|
|
- this.station._id,
|
|
|
|
- id,
|
|
|
|
- res => {
|
|
|
|
- new Toast(res.message);
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
...mapActions("modalVisibility", ["openModal"]),
|
|
...mapActions("modalVisibility", ["openModal"]),
|
|
...mapActions("user/playlists", ["editPlaylist", "setPlaylists"])
|
|
...mapActions("user/playlists", ["editPlaylist", "setPlaylists"])
|
|
}
|
|
}
|
|
@@ -746,7 +985,12 @@ export default {
|
|
color: var(--purple);
|
|
color: var(--purple);
|
|
}
|
|
}
|
|
|
|
|
|
-.station-playlists {
|
|
|
|
|
|
+.playlist-tab-base {
|
|
|
|
+ .top-info {
|
|
|
|
+ font-size: 15px;
|
|
|
|
+ margin-bottom: 15px;
|
|
|
|
+ }
|
|
|
|
+
|
|
.tabs-container {
|
|
.tabs-container {
|
|
.tab-selection {
|
|
.tab-selection {
|
|
display: flex;
|
|
display: flex;
|