useSortablePlaylists.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import { ref, computed, onMounted, onBeforeUnmount, nextTick } from "vue";
  2. import Toast from "toasters";
  3. import { storeToRefs } from "pinia";
  4. import { DraggableList } from "vue-draggable-list";
  5. import { useWebsocketsStore } from "@/stores/websockets";
  6. import { useUserAuthStore } from "@/stores/userAuth";
  7. import { useUserPlaylistsStore } from "@/stores/userPlaylists";
  8. export const useSortablePlaylists = () => {
  9. const orderOfPlaylists = ref([]);
  10. const drag = ref(false);
  11. const userId = ref();
  12. const userAuthStore = useUserAuthStore();
  13. const userPlaylistsStore = useUserPlaylistsStore();
  14. const { userId: myUserId } = storeToRefs(userAuthStore);
  15. const playlists = computed({
  16. get: () => userPlaylistsStore.playlists,
  17. set: playlists => {
  18. userPlaylistsStore.updatePlaylists(playlists);
  19. }
  20. });
  21. const isCurrentUser = computed(() => userId.value === myUserId.value);
  22. const { socket } = useWebsocketsStore();
  23. const { setPlaylists, addPlaylist, removePlaylist } = userPlaylistsStore;
  24. const calculatePlaylistOrder = () => {
  25. const calculatedOrder = [];
  26. playlists.value.forEach(playlist => calculatedOrder.push(playlist._id));
  27. return calculatedOrder;
  28. };
  29. const savePlaylistOrder = () => {
  30. const recalculatedOrder = calculatePlaylistOrder();
  31. if (
  32. JSON.stringify(orderOfPlaylists.value) ===
  33. JSON.stringify(recalculatedOrder)
  34. )
  35. return; // nothing has changed
  36. socket.dispatch(
  37. "users.updateOrderOfPlaylists",
  38. recalculatedOrder,
  39. res => {
  40. if (res.status === "error") return new Toast(res.message);
  41. orderOfPlaylists.value = calculatePlaylistOrder(); // new order in regards to the database
  42. return new Toast(res.message);
  43. }
  44. );
  45. };
  46. onMounted(async () => {
  47. await nextTick();
  48. if (!userId.value) userId.value = myUserId.value;
  49. socket.onConnect(() => {
  50. if (!isCurrentUser.value)
  51. socket.dispatch(
  52. "apis.joinRoom",
  53. `profile.${userId.value}.playlists`,
  54. () => {}
  55. );
  56. socket.dispatch("playlists.indexForUser", userId.value, res => {
  57. if (res.status === "success") setPlaylists(res.data.playlists);
  58. orderOfPlaylists.value = calculatePlaylistOrder(); // order in regards to the database
  59. });
  60. });
  61. socket.on(
  62. "event:playlist.created",
  63. res => addPlaylist(res.data.playlist),
  64. { replaceable: true }
  65. );
  66. socket.on(
  67. "event:playlist.deleted",
  68. res => removePlaylist(res.data.playlistId),
  69. { replaceable: true }
  70. );
  71. socket.on(
  72. "event:playlist.song.added",
  73. res => {
  74. playlists.value.forEach((playlist, index) => {
  75. if (playlist._id === res.data.playlistId) {
  76. playlists.value[index].songs.push(res.data.song);
  77. }
  78. });
  79. },
  80. { replaceable: true }
  81. );
  82. socket.on(
  83. "event:playlist.song.removed",
  84. res => {
  85. playlists.value.forEach((playlist, playlistIndex) => {
  86. if (playlist._id === res.data.playlistId) {
  87. playlists.value[playlistIndex].songs.forEach(
  88. (song, songIndex) => {
  89. if (song.mediaSource === res.data.mediaSource) {
  90. playlists.value[playlistIndex].songs.splice(
  91. songIndex,
  92. 1
  93. );
  94. }
  95. }
  96. );
  97. }
  98. });
  99. },
  100. { replaceable: true }
  101. );
  102. socket.on(
  103. "event:playlist.song.replaced",
  104. res => {
  105. playlists.value.forEach((playlist, index) => {
  106. if (playlist._id === res.data.playlistId) {
  107. playlists.value[index].songs = playlists.value[
  108. index
  109. ].songs.map(song =>
  110. song.mediaSource === res.data.oldMediaSource
  111. ? res.data.song
  112. : song
  113. );
  114. }
  115. });
  116. },
  117. { replaceable: true }
  118. );
  119. socket.on(
  120. "event:playlist.displayName.updated",
  121. res => {
  122. playlists.value.forEach((playlist, index) => {
  123. if (playlist._id === res.data.playlistId) {
  124. playlists.value[index].displayName =
  125. res.data.displayName;
  126. }
  127. });
  128. },
  129. { replaceable: true }
  130. );
  131. socket.on(
  132. "event:playlist.privacy.updated",
  133. res => {
  134. playlists.value.forEach((playlist, index) => {
  135. if (playlist._id === res.data.playlist._id) {
  136. playlists.value[index].privacy =
  137. res.data.playlist.privacy;
  138. }
  139. });
  140. },
  141. { replaceable: true }
  142. );
  143. socket.on(
  144. "event:user.orderOfPlaylists.updated",
  145. res => {
  146. const order = res.data.order.filter(playlistId =>
  147. playlists.value.find(
  148. playlist =>
  149. playlist._id === playlistId &&
  150. (isCurrentUser.value ||
  151. playlist.privacy === "public")
  152. )
  153. );
  154. const sortedPlaylists = [];
  155. playlists.value.forEach(playlist => {
  156. const playlistOrder = order.indexOf(playlist._id);
  157. if (playlistOrder >= 0)
  158. sortedPlaylists[playlistOrder] = playlist;
  159. });
  160. playlists.value = sortedPlaylists;
  161. orderOfPlaylists.value = calculatePlaylistOrder();
  162. },
  163. { replaceable: true }
  164. );
  165. });
  166. onBeforeUnmount(() => {
  167. if (!isCurrentUser.value)
  168. socket.dispatch(
  169. "apis.leaveRoom",
  170. `profile.${userId.value}.playlists`,
  171. () => {}
  172. );
  173. });
  174. return {
  175. DraggableList,
  176. drag,
  177. userId,
  178. isCurrentUser,
  179. playlists,
  180. orderOfPlaylists,
  181. myUserId,
  182. savePlaylistOrder,
  183. calculatePlaylistOrder
  184. };
  185. };