AddSongToPlaylist.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. const _this = this;
  55. this.songId = this.$parent.currentSong.songId;
  56. this.song = this.$parent.currentSong;
  57. io.getSocket(socket => {
  58. _this.socket = socket;
  59. _this.socket.emit("playlists.indexForUser", res => {
  60. if (res.status === "success") {
  61. res.data.forEach(playlist => {
  62. _this.playlists[playlist._id] = playlist;
  63. });
  64. _this.recalculatePlaylists();
  65. }
  66. });
  67. });
  68. },
  69. methods: {
  70. addSongToPlaylist(playlistId) {
  71. const _this = this;
  72. this.socket.emit(
  73. "playlists.addSongToPlaylist",
  74. this.$parent.currentSong.songId,
  75. playlistId,
  76. res => {
  77. Toast.methods.addToast(res.message, 4000);
  78. if (res.status === "success") {
  79. _this.playlists[playlistId].songs.push(_this.song);
  80. }
  81. _this.recalculatePlaylists();
  82. // this.$parent.modals.addSongToPlaylist = false;
  83. }
  84. );
  85. },
  86. removeSongFromPlaylist(playlistId) {
  87. const _this = this;
  88. this.socket.emit(
  89. "playlists.removeSongFromPlaylist",
  90. _this.songId,
  91. playlistId,
  92. res => {
  93. Toast.methods.addToast(res.message, 4000);
  94. if (res.status === "success") {
  95. _this.playlists[playlistId].songs.forEach(
  96. (song, index) => {
  97. if (song.songId === _this.songId)
  98. _this.playlists[playlistId].songs.splice(
  99. index,
  100. 1
  101. );
  102. }
  103. );
  104. }
  105. _this.recalculatePlaylists();
  106. // this.$parent.modals.addSongToPlaylist = false;
  107. }
  108. );
  109. },
  110. recalculatePlaylists() {
  111. const _this = this;
  112. _this.playlistsArr = Object.values(_this.playlists).map(
  113. playlist => {
  114. let hasSong = false;
  115. for (let i = 0; i < playlist.songs.length; i += 1) {
  116. if (playlist.songs[i].songId === _this.songId) {
  117. hasSong = true;
  118. }
  119. }
  120. playlist.hasSong = hasSong; // eslint-disable-line no-param-reassign
  121. _this.playlists[playlist._id] = playlist;
  122. return playlist;
  123. }
  124. );
  125. }
  126. }
  127. };
  128. </script>
  129. <style lang="scss" scoped>
  130. .icon.is-small {
  131. margin-right: 10px !important;
  132. }
  133. .songTitle {
  134. font-size: 22px;
  135. padding: 0 10px;
  136. }
  137. .songArtist {
  138. font-size: 19px;
  139. font-weight: 200;
  140. padding: 0 10px;
  141. }
  142. .menu-label {
  143. font-size: 16px;
  144. }
  145. </style>