Răsfoiți Sursa

refactor: Converted websockets VueX store to Pinia store

Owen Diffey 2 ani în urmă
părinte
comite
a4b831fef9
59 a modificat fișierele cu 148 adăugiri și 151 ștergeri
  1. 2 2
      frontend/src/App.vue
  2. 2 1
      frontend/src/components/AddToPlaylistDropdown.vue
  3. 2 1
      frontend/src/components/AdvancedTable.vue
  4. 2 1
      frontend/src/components/LongJobs.vue
  5. 2 1
      frontend/src/components/PlaylistTabBase.vue
  6. 2 1
      frontend/src/components/Queue.vue
  7. 2 3
      frontend/src/components/Request.vue
  8. 2 1
      frontend/src/components/RunJobDropdown.vue
  9. 2 1
      frontend/src/components/StationInfoBox.vue
  10. 2 1
      frontend/src/components/global/MainHeader.vue
  11. 2 1
      frontend/src/components/modals/BulkActions.vue
  12. 2 1
      frontend/src/components/modals/CreatePlaylist.vue
  13. 2 1
      frontend/src/components/modals/CreateStation.vue
  14. 2 1
      frontend/src/components/modals/EditNews.vue
  15. 2 1
      frontend/src/components/modals/EditPlaylist/Tabs/ImportPlaylists.vue
  16. 2 1
      frontend/src/components/modals/EditPlaylist/Tabs/Settings.vue
  17. 2 1
      frontend/src/components/modals/EditPlaylist/index.vue
  18. 2 4
      frontend/src/components/modals/EditSong/Tabs/Discogs.vue
  19. 2 5
      frontend/src/components/modals/EditSong/Tabs/Reports.vue
  20. 2 1
      frontend/src/components/modals/EditSong/index.vue
  21. 2 1
      frontend/src/components/modals/EditSongs.vue
  22. 2 1
      frontend/src/components/modals/EditUser.vue
  23. 2 1
      frontend/src/components/modals/ImportAlbum.vue
  24. 2 4
      frontend/src/components/modals/ManageStation/Settings.vue
  25. 2 1
      frontend/src/components/modals/ManageStation/index.vue
  26. 2 1
      frontend/src/components/modals/RemoveAccount.vue
  27. 2 1
      frontend/src/components/modals/Report.vue
  28. 2 1
      frontend/src/components/modals/ViewApiRequest.vue
  29. 2 1
      frontend/src/components/modals/ViewPunishment.vue
  30. 2 1
      frontend/src/components/modals/ViewReport.vue
  31. 2 1
      frontend/src/components/modals/ViewYoutubeVideo.vue
  32. 2 5
      frontend/src/composables/useSearchMusare.ts
  33. 2 5
      frontend/src/composables/useSearchYoutube.ts
  34. 2 1
      frontend/src/composables/useSortablePlaylists.ts
  35. 2 1
      frontend/src/pages/Admin/News.vue
  36. 2 2
      frontend/src/pages/Admin/Songs/Import.vue
  37. 2 2
      frontend/src/pages/Admin/Songs/index.vue
  38. 2 2
      frontend/src/pages/Admin/Stations.vue
  39. 2 4
      frontend/src/pages/Admin/Statistics.vue
  40. 2 4
      frontend/src/pages/Admin/Users/DataRequests.vue
  41. 2 1
      frontend/src/pages/Admin/Users/Punishments.vue
  42. 2 2
      frontend/src/pages/Admin/YouTube/Videos.vue
  43. 2 3
      frontend/src/pages/Admin/YouTube/index.vue
  44. 2 2
      frontend/src/pages/Admin/index.vue
  45. 2 1
      frontend/src/pages/Home.vue
  46. 2 4
      frontend/src/pages/News.vue
  47. 2 2
      frontend/src/pages/Profile/Tabs/RecentActivity.vue
  48. 2 2
      frontend/src/pages/Profile/index.vue
  49. 2 1
      frontend/src/pages/ResetPassword.vue
  50. 2 2
      frontend/src/pages/Settings/Tabs/Account.vue
  51. 2 1
      frontend/src/pages/Settings/Tabs/Preferences.vue
  52. 2 1
      frontend/src/pages/Settings/Tabs/Profile.vue
  53. 2 2
      frontend/src/pages/Settings/Tabs/Security.vue
  54. 2 4
      frontend/src/pages/Settings/index.vue
  55. 2 2
      frontend/src/pages/Station/index.vue
  56. 0 3
      frontend/src/store/index.ts
  57. 0 45
      frontend/src/store/modules/websockets.ts
  58. 35 0
      frontend/src/stores/websockets.ts
  59. 3 3
      frontend/src/ws.ts

+ 2 - 2
frontend/src/App.vue

@@ -3,7 +3,7 @@ import { useStore } from "vuex";
 import { useRoute, useRouter } from "vue-router";
 import { defineAsyncComponent, ref, computed, watch, onMounted } from "vue";
 import Toast from "toasters";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 import aw from "@/aw";
 import keyboardShortcuts from "@/keyboardShortcuts";
@@ -31,7 +31,7 @@ const nightmode = computed(() => store.state.user.preferences.nightmode);
 const activityWatch = computed(
 	() => store.state.user.preferences.activityWatch
 );
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const apiDomain = ref("");
 const socketConnected = ref(true);

+ 2 - 1
frontend/src/components/AddToPlaylistDropdown.vue

@@ -2,6 +2,7 @@
 import { ref, computed, onMounted } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 const store = useStore();
@@ -23,7 +24,7 @@ const playlists = computed(() => store.state.user.playlists.playlists);
 const fetchedPlaylists = computed(
 	() => store.state.user.playlists.fetchedPlaylists
 );
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const setPlaylists = payload =>
 	store.dispatch("user/playlists/setPlaylists", payload);

+ 2 - 1
frontend/src/components/AdvancedTable.vue

@@ -13,6 +13,7 @@ import {
 import { useRoute, useRouter } from "vue-router";
 import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import keyboardShortcuts from "@/keyboardShortcuts";
 import ws from "@/ws";
 import useDragBox from "@/composables/useDragBox";
@@ -60,7 +61,7 @@ const store = useStore();
 
 const activeModals = computed(() => store.state.modalVisibility.activeModals);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const page = ref(1);
 const pageSize = ref(10);

+ 2 - 1
frontend/src/components/LongJobs.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { useStore } from "vuex";
 import { defineAsyncComponent, ref, computed, onMounted } from "vue";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const FloatingBox = defineAsyncComponent(
 	() => import("@/components/FloatingBox.vue")
@@ -13,7 +14,7 @@ const body = ref(document.body);
 const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const activeJobs = computed(() => store.state.longJobs.activeJobs);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const setJob = payload => store.dispatch("longJobs/setJob", payload);
 

+ 2 - 1
frontend/src/components/PlaylistTabBase.vue

@@ -4,6 +4,7 @@ import { useStore } from "vuex";
 import Toast from "toasters";
 import ws from "@/ws";
 
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState } from "@/vuex_helpers";
 
 import useSortablePlaylists from "@/composables/useSortablePlaylists";
@@ -28,7 +29,7 @@ const emit = defineEmits(["selected"]);
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const tab = ref("current");
 const search = reactive({

+ 2 - 1
frontend/src/components/Queue.vue

@@ -3,6 +3,7 @@ import { useStore } from "vuex";
 import { defineAsyncComponent, ref, computed, onUpdated } from "vue";
 import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const SongItem = defineAsyncComponent(
 	() => import("@/components/SongItem.vue")
@@ -19,7 +20,7 @@ const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const userId = computed(() => store.state.user.auth.userId);
 const userRole = computed(() => store.state.user.auth.role);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const repositionSongInList = payload => {
 	if (props.sector === "manageStation")

+ 2 - 3
frontend/src/components/Request.vue

@@ -1,9 +1,8 @@
 <script setup lang="ts">
 import { defineAsyncComponent, ref, computed, onMounted } from "vue";
 import { useStore } from "vuex";
-
 import Toast from "toasters";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import useSearchYoutube from "@/composables/useSearchYoutube";
 import useSearchMusare from "@/composables/useSearchMusare";
 
@@ -21,7 +20,7 @@ const store = useStore();
 const { youtubeSearch, searchForSongs, loadMoreSongs } = useSearchYoutube();
 const { musareSearch, searchForMusareSongs } = useSearchMusare();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" },

+ 2 - 1
frontend/src/components/RunJobDropdown.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { useStore } from "vuex";
 import { ref } from "vue";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 defineProps({
 	jobs: { type: Array, default: () => [] }
@@ -10,7 +11,7 @@ const showJobDropdown = ref(false);
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const setJob = payload => store.dispatch("longJobs/setJob", payload);
 

+ 2 - 1
frontend/src/components/StationInfoBox.vue

@@ -2,6 +2,7 @@
 import { computed } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const store = useStore();
 
@@ -15,7 +16,7 @@ const props = defineProps({
 const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const userId = computed(() => store.state.user.auth.userId);
 const role = computed(() => store.state.user.auth.role);
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 function isOwnerOnly() {
 	return loggedIn.value && userId.value === props.station.owner;

+ 2 - 1
frontend/src/components/global/MainHeader.vue

@@ -9,6 +9,7 @@ import {
 	nextTick
 } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const ChristmasLights = defineAsyncComponent(
 	() => import("@/components/ChristmasLights.vue")
@@ -36,7 +37,7 @@ const windowWidth = ref(0);
 const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const username = computed(() => store.state.user.auth.username);
 const role = computed(() => store.state.user.auth.role);
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const openModal = modal => store.dispatch("modalVisibility/openModal", modal);
 const logout = () => store.dispatch("user/auth/logout");

+ 2 - 1
frontend/src/components/modals/BulkActions.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { ref, defineAsyncComponent, onMounted, onBeforeUnmount } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState } from "@/vuex_helpers";
 import ws from "@/ws";
 
@@ -19,7 +20,7 @@ const closeCurrentModal = () =>
 	store.dispatch("modalVisibility/closeCurrentModal");
 const setJob = payload => store.dispatch("longJobs/setJob", payload);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { type } = useModalState("modals/bulkActions/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/CreatePlaylist.vue

@@ -3,6 +3,7 @@ import { useStore } from "vuex";
 import { ref, onBeforeUnmount } from "vue";
 import Toast from "toasters";
 import validation from "@/validation";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 defineProps({
 	modalUuid: { type: String, default: "" }
@@ -21,7 +22,7 @@ const openModal = payload =>
 const closeCurrentModal = () =>
 	store.dispatch("modalVisibility/closeCurrentModal");
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const createPlaylist = () => {
 	const { displayName } = playlist.value;

+ 2 - 1
frontend/src/components/modals/CreateStation.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { ref, onBeforeUnmount } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState } from "@/vuex_helpers";
 import validation from "@/validation";
 
@@ -11,7 +12,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { official } = useModalState("modals/createStation/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/EditNews.vue

@@ -6,6 +6,7 @@ import DOMPurify from "dompurify";
 import Toast from "toasters";
 import { formatDistance } from "date-fns";
 import { useModalState } from "@/vuex_helpers";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 const SaveButton = defineAsyncComponent(
@@ -18,7 +19,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { createNews, newsId } = useModalState("modals/editNews/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/EditPlaylist/Tabs/ImportPlaylists.vue

@@ -4,6 +4,7 @@ import { computed } from "vue";
 import Toast from "toasters";
 import { useModalState } from "@/vuex_helpers";
 import useSearchYoutube from "@/composables/useSearchYoutube";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
@@ -11,7 +12,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modalState = useModalState("modals/editPlaylist/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/EditPlaylist/Tabs/Settings.vue

@@ -4,6 +4,7 @@ import { computed } from "vue";
 import Toast from "toasters";
 import { useModalState } from "@/vuex_helpers";
 import validation from "@/validation";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
@@ -14,7 +15,7 @@ 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 { socket } = useWebsocketsStore();
 
 const modalState = useModalState("modals/editPlaylist/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/EditPlaylist/index.vue

@@ -9,6 +9,7 @@ import {
 } from "vue";
 import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import ws from "@/ws";
 import utils from "@/utils";
@@ -33,7 +34,7 @@ const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const userId = computed(() => store.state.user.auth.userId);
 const userRole = computed(() => store.state.user.auth.role);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const drag = ref(false);
 const apiDomain = ref("");

+ 2 - 4
frontend/src/components/modals/EditSong/Tabs/Discogs.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
-import { useStore } from "vuex";
 import { ref, computed, onMounted } from "vue";
 import Toast from "toasters";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import keyboardShortcuts from "@/keyboardShortcuts";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" },
@@ -14,9 +14,7 @@ const props = defineProps({
 	bulk: { type: Boolean, default: false }
 });
 
-const store = useStore();
-
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modalState = useModalState(props.modalModulePath, {
 	modalUuid: props.modalUuid

+ 2 - 5
frontend/src/components/modals/EditSong/Tabs/Reports.vue

@@ -1,17 +1,14 @@
 <script setup lang="ts">
 import { defineAsyncComponent, ref, computed, onMounted } from "vue";
-import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 
 const ReportInfoItem = defineAsyncComponent(
 	() => import("@/components/ReportInfoItem.vue")
 );
 
-const store = useStore();
-
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" },

+ 2 - 1
frontend/src/components/modals/EditSong/index.vue

@@ -14,6 +14,7 @@ import aw from "@/aw";
 import ws from "@/ws";
 import validation from "@/validation";
 import keyboardShortcuts from "@/keyboardShortcuts";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const FloatingBox = defineAsyncComponent(
 	() => import("@/components/FloatingBox.vue")
@@ -51,7 +52,7 @@ const emit = defineEmits([
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modals = computed(() => store.state.modalVisibility.modals);
 const activeModals = computed(() => store.state.modalVisibility.activeModals);

+ 2 - 1
frontend/src/components/modals/EditSongs.vue

@@ -12,6 +12,7 @@ import {
 import Toast from "toasters";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import editSongStore from "@/store/modules/modals/editSong";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const EditSongModal = defineAsyncComponent(
 	() => import("@/components/modals/EditSong/index.vue")
@@ -26,7 +27,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { youtubeIds, songPrefillData } = useModalState(
 	"modals/editSongs/MODAL_UUID",

+ 2 - 1
frontend/src/components/modals/EditUser.vue

@@ -6,6 +6,7 @@ import { storeToRefs } from "pinia";
 import ws from "@/ws";
 import validation from "@/validation";
 import { useEditUserStore } from "@/stores/editUser";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
@@ -14,7 +15,7 @@ const props = defineProps({
 const editUserStore = useEditUserStore(props);
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { userId, user } = storeToRefs(editUserStore);
 const { setUser } = editUserStore;

+ 2 - 1
frontend/src/components/modals/ImportAlbum.vue

@@ -10,6 +10,7 @@ import {
 } from "vue";
 import Toast from "toasters";
 import { Sortable } from "sortablejs-vue3";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import ws from "@/ws";
 
@@ -23,7 +24,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modalState = useModalState("modals/importAlbum/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 4
frontend/src/components/modals/ManageStation/Settings.vue

@@ -1,17 +1,15 @@
 <script setup lang="ts">
-import { useStore } from "vuex";
 import { ref, computed, onMounted } from "vue";
 import Toast from "toasters";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import validation from "@/validation";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
 });
 
-const store = useStore();
-
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modalState = useModalState("modals/manageStation/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/ManageStation/index.vue

@@ -10,6 +10,7 @@ import {
 } from "vue";
 import Toast from "toasters";
 import { useModalState, useModalActions } from "@/vuex_helpers";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const Queue = defineAsyncComponent(() => import("@/components/Queue.vue"));
 const SongItem = defineAsyncComponent(
@@ -34,7 +35,7 @@ const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const userId = computed(() => store.state.user.auth.userId);
 const role = computed(() => store.state.user.auth.role);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modalState = useModalState("modals/manageStation/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/RemoveAccount.vue

@@ -5,6 +5,7 @@ import { useRoute } from "vue-router";
 import Toast from "toasters";
 import { useModalState } from "@/vuex_helpers";
 import { useSettingsStore } from "@/stores/settings";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
@@ -15,7 +16,7 @@ const route = useRoute();
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { githubLinkConfirmed } = useModalState(
 	"modals/removeAccount/MODAL_UUID",

+ 2 - 1
frontend/src/components/modals/Report.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { defineAsyncComponent, ref, onMounted, onBeforeUnmount } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState } from "@/vuex_helpers";
 import ws from "@/ws";
 
@@ -18,7 +19,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { song } = useModalState("modals/report/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/ViewApiRequest.vue

@@ -3,6 +3,7 @@ import { useStore } from "vuex";
 import { ref, onMounted, onBeforeUnmount } from "vue";
 import Toast from "toasters";
 import VueJsonPretty from "vue-json-pretty";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import ws from "@/ws";
 import "vue-json-pretty/lib/styles.css";
@@ -13,7 +14,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { requestId, request, removeAction } = useModalState(
 	"modals/viewApiRequest/MODAL_UUID",

+ 2 - 1
frontend/src/components/modals/ViewPunishment.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { defineAsyncComponent, onMounted, onBeforeUnmount } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 import ws from "@/ws";
 
@@ -15,7 +16,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { punishmentId, punishment } = useModalState(
 	"modals/viewPunishment/MODAL_UUID",

+ 2 - 1
frontend/src/components/modals/ViewReport.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { defineAsyncComponent, ref, onMounted, onBeforeUnmount } from "vue";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState } from "@/vuex_helpers";
 import ws from "@/ws";
 
@@ -18,7 +19,7 @@ const props = defineProps({
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { reportId } = useModalState("modals/viewReport/MODAL_UUID", {
 	modalUuid: props.modalUuid

+ 2 - 1
frontend/src/components/modals/ViewYoutubeVideo.vue

@@ -4,6 +4,7 @@ import { onMounted, onBeforeUnmount, ref } from "vue";
 import Toast from "toasters";
 import aw from "@/aw";
 import ws from "@/ws";
+import { useWebsocketsStore } from "@/stores/websockets";
 import { useModalState, useModalActions } from "@/vuex_helpers";
 
 const store = useStore();
@@ -54,7 +55,7 @@ const openModal = payload =>
 const closeCurrentModal = () =>
 	store.dispatch("modalVisibility/closeCurrentModal");
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const remove = () => {
 	socket.dispatch("youtube.removeVideos", videoId, res => {

+ 2 - 5
frontend/src/composables/useSearchMusare.ts

@@ -1,11 +1,8 @@
 import { ref, computed } from "vue";
-import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 export default function useSearchMusare() {
-	const store = useStore();
-
 	const musareSearch = ref({
 		query: "",
 		searchedQuery: "",
@@ -24,7 +21,7 @@ export default function useSearchMusare() {
 		Math.min(musareSearch.value.pageSize, resultsLeftCount.value)
 	);
 
-	const { socket } = store.state.websockets;
+	const { socket } = useWebsocketsStore();
 
 	const searchForMusareSongs = (page, toast = true) => {
 		if (

+ 2 - 5
frontend/src/composables/useSearchYoutube.ts

@@ -1,11 +1,8 @@
 import { ref } from "vue";
-import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 export default function useSearchYoutube() {
-	const store = useStore();
-
 	const youtubeSearch = ref({
 		songs: {
 			results: [],
@@ -18,7 +15,7 @@ export default function useSearchYoutube() {
 		}
 	});
 
-	const { socket } = store.state.websockets;
+	const { socket } = useWebsocketsStore();
 
 	const searchForSongs = () => {
 		let { query } = youtubeSearch.value.songs;

+ 2 - 1
frontend/src/composables/useSortablePlaylists.ts

@@ -2,6 +2,7 @@ import { ref, computed, onMounted, onBeforeUnmount, nextTick } from "vue";
 import { useStore } from "vuex";
 import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 export default function useSortablePlaylists() {
@@ -26,7 +27,7 @@ export default function useSortablePlaylists() {
 		ghostClass: "draggable-list-ghost"
 	}));
 
-	const { socket } = store.state.websockets;
+	const { socket } = useWebsocketsStore();
 
 	const setPlaylists = playlists =>
 		store.dispatch("user/playlists/setPlaylists", playlists);

+ 2 - 1
frontend/src/pages/Admin/News.vue

@@ -2,6 +2,7 @@
 import { defineAsyncComponent, ref } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -9,7 +10,7 @@ const AdvancedTable = defineAsyncComponent(
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const columnDefault = ref({
 	sortable: true,

+ 2 - 2
frontend/src/pages/Admin/Songs/Import.vue

@@ -2,8 +2,8 @@
 import { defineAsyncComponent, ref } from "vue";
 import { useStore } from "vuex";
 import { useRouter } from "vue-router";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -12,7 +12,7 @@ const AdvancedTable = defineAsyncComponent(
 const store = useStore();
 const router = useRouter();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const createImport = ref({
 	stage: 2,

+ 2 - 2
frontend/src/pages/Admin/Songs/index.vue

@@ -2,8 +2,8 @@
 import { defineAsyncComponent, ref, onMounted } from "vue";
 import { useStore } from "vuex";
 import { useRoute } from "vue-router";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -17,7 +17,7 @@ const route = useRoute();
 
 const setJob = payload => store.dispatch("longJobs/setJob", payload);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const columnDefault = ref({
 	sortable: true,

+ 2 - 2
frontend/src/pages/Admin/Stations.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { defineAsyncComponent, ref } from "vue";
 import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -13,7 +13,7 @@ const RunJobDropdown = defineAsyncComponent(
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const columnDefault = ref({
 	sortable: true,

+ 2 - 4
frontend/src/pages/Admin/Statistics.vue

@@ -1,14 +1,12 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
-import { useStore } from "vuex";
 import { useRoute } from "vue-router";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
-const store = useStore();
 const route = useRoute();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const modules = ref([]);
 const activeModule = ref();

+ 2 - 4
frontend/src/pages/Admin/Users/DataRequests.vue

@@ -1,15 +1,13 @@
 <script setup lang="ts">
 import { defineAsyncComponent, ref } from "vue";
-import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
 );
 
-const store = useStore();
-
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const columnDefault = ref({
 	sortable: true,

+ 2 - 1
frontend/src/pages/Admin/Users/Punishments.vue

@@ -2,6 +2,7 @@
 import { defineAsyncComponent, ref } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -9,7 +10,7 @@ const AdvancedTable = defineAsyncComponent(
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const ipBan = ref({
 	expiresAt: "1h"

+ 2 - 2
frontend/src/pages/Admin/YouTube/Videos.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { defineAsyncComponent, ref } from "vue";
 import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const AdvancedTable = defineAsyncComponent(
 	() => import("@/components/AdvancedTable.vue")
@@ -15,7 +15,7 @@ const store = useStore();
 
 const setJob = payload => store.dispatch("longJobs/setJob", payload);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const columnDefault = ref({
 	sortable: true,

+ 2 - 3
frontend/src/pages/Admin/YouTube/index.vue

@@ -2,9 +2,8 @@
 import { defineAsyncComponent, ref, onMounted } from "vue";
 import { useStore } from "vuex";
 import { useRoute } from "vue-router";
-
 import Toast from "toasters";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 const AdvancedTable = defineAsyncComponent(
@@ -20,7 +19,7 @@ const LineChart = defineAsyncComponent(
 const store = useStore();
 const route = useRoute();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const quotaStatus = ref({});
 const fromDate = ref();

+ 2 - 2
frontend/src/pages/Admin/index.vue

@@ -9,7 +9,7 @@ import {
 } from "vue";
 import { useStore } from "vuex";
 import { useRoute, useRouter } from "vue-router";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import keyboardShortcuts from "@/keyboardShortcuts";
 
 const FloatingBox = defineAsyncComponent(
@@ -20,7 +20,7 @@ const store = useStore();
 const route = useRoute();
 const router = useRouter();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const currentTab = ref("");
 const siteSettings = ref({

+ 2 - 1
frontend/src/pages/Home.vue

@@ -4,6 +4,7 @@ import { useRoute, useRouter } from "vue-router";
 import { ref, computed, onMounted, onBeforeUnmount } from "vue";
 import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import keyboardShortcuts from "@/keyboardShortcuts";
 import ws from "@/ws";
 
@@ -15,7 +16,7 @@ const loggedIn = computed(() => store.state.user.auth.loggedIn);
 const userId = computed(() => store.state.user.auth.userId);
 const role = computed(() => store.state.user.auth.role);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const stations = ref([]);
 const searchQuery = ref("");

+ 2 - 4
frontend/src/pages/News.vue

@@ -1,16 +1,14 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
-import { useStore } from "vuex";
 
 import { formatDistance } from "date-fns";
 import { marked } from "marked";
 import DOMPurify from "dompurify";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 import ws from "@/ws";
 
-const store = useStore();
-
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const news = ref([]);
 

+ 2 - 2
frontend/src/pages/Profile/Tabs/RecentActivity.vue

@@ -8,7 +8,7 @@ import {
 } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 const ActivityItem = defineAsyncComponent(
@@ -17,7 +17,7 @@ const ActivityItem = defineAsyncComponent(
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const props = defineProps({
 	userId: {

+ 2 - 2
frontend/src/pages/Profile/index.vue

@@ -3,8 +3,8 @@ import { defineAsyncComponent, ref, computed, onMounted } from "vue";
 import { useStore } from "vuex";
 import { useRoute, useRouter } from "vue-router";
 import { format, parseISO } from "date-fns";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
-
 import useTabQueryHandler from "@/composables/useTabQueryHandler";
 
 const ProfilePicture = defineAsyncComponent(
@@ -20,7 +20,7 @@ const route = useRoute();
 const router = useRouter();
 const { tab, showTab } = useTabQueryHandler("recent-activity");
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const user = ref();
 const userId = ref("");

+ 2 - 1
frontend/src/pages/ResetPassword.vue

@@ -3,6 +3,7 @@ import { useStore } from "vuex";
 import { defineAsyncComponent, ref, computed, watch, onMounted } from "vue";
 import Toast from "toasters";
 import validation from "@/validation";
+import { useWebsocketsStore } from "@/stores/websockets";
 
 const InputHelpBox = defineAsyncComponent(
 	() => import("@/components/InputHelpBox.vue")
@@ -16,7 +17,7 @@ const store = useStore();
 
 const accountEmail = computed(() => store.state.user.auth.email);
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const code = ref("");
 const inputs = ref({

+ 2 - 2
frontend/src/pages/Settings/Tabs/Account.vue

@@ -11,7 +11,7 @@ import { useStore } from "vuex";
 import { useRoute } from "vue-router";
 import Toast from "toasters";
 import { useSettingsStore } from "@/stores/settings";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import _validation from "@/validation";
 
 const InputHelpBox = defineAsyncComponent(
@@ -25,7 +25,7 @@ const settingsStore = useSettingsStore();
 const store = useStore();
 const route = useRoute();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const saveButton = ref();
 

+ 2 - 1
frontend/src/pages/Settings/Tabs/Preferences.vue

@@ -2,6 +2,7 @@
 import { defineAsyncComponent, ref, computed, onMounted } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
 
 const SaveButton = defineAsyncComponent(
@@ -10,7 +11,7 @@ const SaveButton = defineAsyncComponent(
 
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const saveButton = ref();
 

+ 2 - 1
frontend/src/pages/Settings/Tabs/Profile.vue

@@ -3,6 +3,7 @@ import { defineAsyncComponent, ref, computed } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
 import { useSettingsStore } from "@/stores/settings";
+import { useWebsocketsStore } from "@/stores/websockets";
 import validation from "@/validation";
 
 const ProfilePicture = defineAsyncComponent(
@@ -15,7 +16,7 @@ const SaveButton = defineAsyncComponent(
 const settingsStore = useSettingsStore();
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const saveButton = ref();
 

+ 2 - 2
frontend/src/pages/Settings/Tabs/Security.vue

@@ -10,7 +10,7 @@ import {
 import { useStore } from "vuex";
 import Toast from "toasters";
 import { useSettingsStore } from "@/stores/settings";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import _validation from "@/validation";
 
 const InputHelpBox = defineAsyncComponent(
@@ -20,7 +20,7 @@ const InputHelpBox = defineAsyncComponent(
 const settingsStore = useSettingsStore();
 const store = useStore();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const apiDomain = ref("");
 const siteSettings = ref({

+ 2 - 4
frontend/src/pages/Settings/index.vue

@@ -1,11 +1,10 @@
 <script setup lang="ts">
-import { useStore } from "vuex";
 import { useRoute } from "vue-router";
 import { onMounted, defineAsyncComponent } from "vue";
 import Toast from "toasters";
 import { useSettingsStore } from "@/stores/settings";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ws from "@/ws";
-
 import useTabQueryHandler from "@/composables/useTabQueryHandler";
 
 const SecuritySettings = defineAsyncComponent(
@@ -22,11 +21,10 @@ const PreferencesSettings = defineAsyncComponent(
 );
 
 const settingsStore = useSettingsStore();
-const store = useStore();
 const route = useRoute();
 const { tab, showTab } = useTabQueryHandler("");
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 const { setUser, updateOriginalUser } = settingsStore;
 

+ 2 - 2
frontend/src/pages/Station/index.vue

@@ -12,7 +12,7 @@ import { useRoute, useRouter } from "vue-router";
 import Toast from "toasters";
 import { ContentLoader } from "vue-content-loader";
 import canAutoPlay from "can-autoplay";
-
+import { useWebsocketsStore } from "@/stores/websockets";
 import aw from "@/aw";
 import ms from "@/ms";
 import ws from "@/ws";
@@ -40,7 +40,7 @@ const store = useStore();
 const route = useRoute();
 const router = useRouter();
 
-const { socket } = store.state.websockets;
+const { socket } = useWebsocketsStore();
 
 // TODO this might need a different place, like onMounted
 const isApple = ref(

+ 0 - 3
frontend/src/store/index.ts

@@ -1,8 +1,6 @@
 /* eslint-disable import/no-cycle */
 import { createStore } from "vuex";
 
-import websockets from "./modules/websockets";
-
 import user from "./modules/user";
 import modalVisibility from "./modules/modalVisibility";
 import station from "./modules/station";
@@ -15,7 +13,6 @@ const emptyModule = {
 
 export default createStore({
 	modules: {
-		websockets,
 		user,
 		station,
 		admin,

+ 0 - 45
frontend/src/store/modules/websockets.ts

@@ -1,45 +0,0 @@
-/* eslint no-param-reassign: 0 */
-
-const state = {
-	socket: {
-		dispatcher: {}
-	}
-};
-
-const getters = {
-	getSocket: state => state.socket
-};
-
-const actions = {
-	createSocket: ({ commit }, socket) => commit("createSocket", socket)
-};
-
-const mutations = {
-	createSocket(state, socket) {
-		const { listeners } = state.socket.dispatcher;
-		state.socket = socket;
-
-		// only executes if the websocket object is being replaced
-		if (listeners) {
-			// for each listener type
-			Object.keys(listeners).forEach(listenerType =>
-				// for each callback previously present for the listener type
-				listeners[listenerType].forEach(element => {
-					// add the listener back after the websocket object is reset
-					state.socket.dispatcher.addEventListener(
-						listenerType,
-						element.cb
-					);
-				})
-			);
-		}
-	}
-};
-
-export default {
-	namespaced: true,
-	state,
-	getters,
-	actions,
-	mutations
-};

+ 35 - 0
frontend/src/stores/websockets.ts

@@ -0,0 +1,35 @@
+import { defineStore } from "pinia";
+
+// TODO fix/decide eslint rule properly
+// eslint-disable-next-line
+export const useWebsocketsStore = defineStore("websockets", {
+	state: () => ({
+		socket: {
+			dispatcher: {}
+		}
+	}),
+	actions: {
+		createSocket(socket) {
+			const { listeners } = this.socket.dispatcher;
+			this.socket = socket;
+
+			// only executes if the websocket object is being replaced
+			if (listeners) {
+				// for each listener type
+				Object.keys(listeners).forEach(listenerType =>
+					// for each callback previously present for the listener type
+					listeners[listenerType].forEach(element => {
+						// add the listener back after the websocket object is reset
+						this.socket.dispatcher.addEventListener(
+							listenerType,
+							element.cb
+						);
+					})
+				);
+			}
+		}
+	},
+	getters: {
+		getSocket: state => state.socket
+	}
+});

+ 3 - 3
frontend/src/ws.ts

@@ -1,5 +1,4 @@
-// eslint-disable-next-line import/no-cycle
-import store from "./store";
+import { useWebsocketsStore } from "@/stores/websockets";
 import ListenerHandler from "./classes/ListenerHandler.class";
 
 const onConnect = [];
@@ -127,7 +126,8 @@ export default {
 		}
 
 		this.socket = new CustomWebSocket();
-		store.dispatch("websockets/createSocket", this.socket);
+		const { createSocket } = useWebsocketsStore();
+		createSocket(this.socket);
 
 		this.socket.onopen = () => {
 			console.log("WS: SOCKET OPENED");