AddSongToPlaylist.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <modal title="Add Song To Playlist">
  3. <template v-slot:body>
  4. <h4 class="songTitle">
  5. {{ $parent.currentSong.title }}
  6. </h4>
  7. <h5 class="songArtist">
  8. {{ $parent.currentSong.artists }}
  9. </h5>
  10. <aside class="menu">
  11. <p class="menu-label">
  12. Playlists
  13. </p>
  14. <ul class="menu-list">
  15. <li v-for="(playlist, index) in playlistsArr" :key="index">
  16. <div class="playlist">
  17. <span
  18. v-if="playlists[playlist._id].hasSong"
  19. class="icon is-small"
  20. @click="removeSongFromPlaylist(playlist._id)"
  21. >
  22. <i class="material-icons">playlist_add_check</i>
  23. </span>
  24. <span
  25. v-else
  26. class="icon"
  27. @click="addSongToPlaylist(playlist._id)"
  28. >
  29. <i class="material-icons">playlist_add</i>
  30. </span>
  31. {{ playlist.displayName }}
  32. </div>
  33. </li>
  34. </ul>
  35. </aside>
  36. </template>
  37. </modal>
  38. </template>
  39. <script>
  40. import { Toast } from "vue-roaster";
  41. import Modal from "./Modal.vue";
  42. import io from "../../io";
  43. export default {
  44. components: { Modal },
  45. data() {
  46. return {
  47. playlists: {},
  48. playlistsArr: [],
  49. songId: null,
  50. song: null
  51. };
  52. },
  53. mounted() {
  54. this.songId = this.$parent.currentSong.songId;
  55. this.song = this.$parent.currentSong;
  56. io.getSocket(socket => {
  57. this.socket = socket;
  58. this.socket.emit("playlists.indexForUser", res => {
  59. if (res.status === "success") {
  60. res.data.forEach(playlist => {
  61. this.playlists[playlist._id] = playlist;
  62. });
  63. this.recalculatePlaylists();
  64. }
  65. });
  66. });
  67. },
  68. methods: {
  69. addSongToPlaylist(playlistId) {
  70. this.socket.emit(
  71. "playlists.addSongToPlaylist",
  72. this.$parent.currentSong.songId,
  73. playlistId,
  74. res => {
  75. Toast.methods.addToast(res.message, 4000);
  76. if (res.status === "success") {
  77. this.playlists[playlistId].songs.push(this.song);
  78. }
  79. this.recalculatePlaylists();
  80. // this.$parent.modals.addSongToPlaylist = false;
  81. }
  82. );
  83. },
  84. removeSongFromPlaylist(playlistId) {
  85. this.socket.emit(
  86. "playlists.removeSongFromPlaylist",
  87. this.songId,
  88. playlistId,
  89. res => {
  90. Toast.methods.addToast(res.message, 4000);
  91. if (res.status === "success") {
  92. this.playlists[playlistId].songs.forEach(
  93. (song, index) => {
  94. if (song.songId === this.songId)
  95. this.playlists[playlistId].songs.splice(
  96. index,
  97. 1
  98. );
  99. }
  100. );
  101. }
  102. this.recalculatePlaylists();
  103. // this.$parent.modals.addSongToPlaylist = false;
  104. }
  105. );
  106. },
  107. recalculatePlaylists() {
  108. this.playlistsArr = Object.values(this.playlists).map(playlist => {
  109. let hasSong = false;
  110. for (let i = 0; i < playlist.songs.length; i += 1) {
  111. if (playlist.songs[i].songId === this.songId) {
  112. hasSong = true;
  113. }
  114. }
  115. playlist.hasSong = hasSong; // eslint-disable-line no-param-reassign
  116. this.playlists[playlist._id] = playlist;
  117. return playlist;
  118. });
  119. }
  120. }
  121. };
  122. </script>
  123. <style lang="scss" scoped>
  124. @import "styles/global.scss";
  125. .icon.is-small {
  126. margin-right: 10px !important;
  127. }
  128. .songTitle {
  129. font-size: 22px;
  130. padding: 0 10px;
  131. }
  132. .songArtist {
  133. font-size: 19px;
  134. font-weight: 200;
  135. padding: 0 10px;
  136. }
  137. .menu-label {
  138. font-size: 16px;
  139. }
  140. </style>