From a081549f2dbdc57c126400ed8ae5677899561dd7 Mon Sep 17 00:00:00 2001 From: Adam French Date: Thu, 22 Jan 2026 15:49:34 +0000 Subject: [PATCH] more stores --- nginx/vue/src/components/home/Feed.vue | 73 +++++-------------- nginx/vue/src/components/home/Listening.vue | 45 +++--------- nginx/vue/src/components/quick/Chat.vue | 26 ++----- nginx/vue/src/stores/auth.js | 10 +-- nginx/vue/src/stores/messages.js | 77 +++++++++++++++++++++ nginx/vue/src/stores/models.js | 48 +++++++++++++ nginx/vue/src/stores/posts.js | 51 ++++++++++++++ nginx/vue/src/stores/songs.js | 46 ++++++++++++ nginx/vue/src/stores/users.js | 0 nginx/vue/src/views/Home.vue | 2 +- 10 files changed, 262 insertions(+), 116 deletions(-) create mode 100644 nginx/vue/src/stores/messages.js create mode 100644 nginx/vue/src/stores/models.js create mode 100644 nginx/vue/src/stores/posts.js create mode 100644 nginx/vue/src/stores/songs.js create mode 100644 nginx/vue/src/stores/users.js diff --git a/nginx/vue/src/components/home/Feed.vue b/nginx/vue/src/components/home/Feed.vue index a3391da..43d6856 100644 --- a/nginx/vue/src/components/home/Feed.vue +++ b/nginx/vue/src/components/home/Feed.vue @@ -1,76 +1,41 @@ diff --git a/nginx/vue/src/components/home/Listening.vue b/nginx/vue/src/components/home/Listening.vue index bdcab4c..f84b5a9 100644 --- a/nginx/vue/src/components/home/Listening.vue +++ b/nginx/vue/src/components/home/Listening.vue @@ -1,55 +1,28 @@ diff --git a/nginx/vue/src/components/quick/Chat.vue b/nginx/vue/src/components/quick/Chat.vue index d5d4d0a..719309b 100644 --- a/nginx/vue/src/components/quick/Chat.vue +++ b/nginx/vue/src/components/quick/Chat.vue @@ -1,30 +1,14 @@ diff --git a/nginx/vue/src/stores/auth.js b/nginx/vue/src/stores/auth.js index 091070c..93110e3 100644 --- a/nginx/vue/src/stores/auth.js +++ b/nginx/vue/src/stores/auth.js @@ -4,10 +4,10 @@ import axios from "axios"; export const useAuthStore = defineStore("auth", () => { const user = ref({}); - checkToken(); - const loggedIn = computed(() => !!user.value.username); + checkToken(); + async function logOut() { try { const res = await axios.post("/api/auth/logout"); @@ -61,11 +61,13 @@ export const useAuthStore = defineStore("auth", () => { return { user, - checkToken, + + loggedIn, + logIn, + checkToken, refreshToken, logOut, createUser, - loggedIn, }; }); diff --git a/nginx/vue/src/stores/messages.js b/nginx/vue/src/stores/messages.js new file mode 100644 index 0000000..51b5730 --- /dev/null +++ b/nginx/vue/src/stores/messages.js @@ -0,0 +1,77 @@ +import { defineStore } from "pinia"; +import { ref, computed } from "vue"; + +const URL = "/api/ws"; + +const message_template = { + id: 0, + content: "Yo", +}; + +export const useMessagesStore = defineStore("messages", () => { + const socket = ref(null); + const messages = ref([message_template]); + const isConnected = ref(false); + const lastError = ref(null); + + const messagesCount = computed(() => messages.value.length); + + function connect() { + if (socket.value && isConnected.value) return; + + socket.value = new WebSocket(URL); + + socket.value.onopen = () => { + isConnected.value = true; + lastError.value = null; + }; + + socket.value.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + messages.value.push(data); + } catch { + // fallback if server sends plain text + messages.value.push(event.data); + } + }; + + socket.value.onerror = (error) => { + lastError.value = error; + }; + + socket.value.onclose = () => { + isConnected.value = false; + socket.value = null; + }; + } + + function disconnect() { + if (!socket.value) return; + socket.value.close(); + socket.value = null; + isConnected.value = false; + } + + function sendMessage(payload) { + if (!socket.value || !isConnected.value) return; + socket.value.send(JSON.stringify(payload)); + } + + function clearMessages() { + messages.value = []; + } + + return { + messages, + isConnected, + lastError, + + messagesCount, + + connect, + disconnect, + sendMessage, + clearMessages, + }; +}); diff --git a/nginx/vue/src/stores/models.js b/nginx/vue/src/stores/models.js new file mode 100644 index 0000000..20ce55d --- /dev/null +++ b/nginx/vue/src/stores/models.js @@ -0,0 +1,48 @@ +export class User { + constructor({ id, createdAt, updatedAt, deletedAt, username, admin }) { + this.id = id; + this.createdAt = new Date(createdAt); + this.updatedAt = new Date(updatedAt); + this.deletedAt = deletedAt ? new Date(deletedAt) : null; + this.username = username; + this.admin = admin; + } +} + +export class Message { + constructor({ id, text, author, createdAt, deletedAt }) { + this.id = id; + this.content = text; + this.author = author ? new User(author) : null; + this.createdAt = new Date(createdAt); + this.deletedAt = deletedAt ? new Date(deletedAt) : null; + } +} + +export class Post { + constructor({ + id, + title, + author, + authorID, + content, + createdAt, + updatedAt, + deletedAt, + }) { + this.id = id; + this.title = title; + this.authorID = authorID; + this.author = author ? new User(author) : null; + this.content = content; + this.createdAt = new Date(createdAt); + this.updatedAt = new Date(updatedAt); + this.deletedAt = deletedAt ? new Date(deletedAt) : null; + } +} + +// Utility function to parse posts from API +export function parsePosts(postsArray) { + if (!Array.isArray(postsArray)) return []; + return postsArray.map((post) => new Post(post)); +} diff --git a/nginx/vue/src/stores/posts.js b/nginx/vue/src/stores/posts.js new file mode 100644 index 0000000..46a98d3 --- /dev/null +++ b/nginx/vue/src/stores/posts.js @@ -0,0 +1,51 @@ +import { defineStore } from "pinia"; +import { computed, ref } from "vue"; +import axios from "axios"; + +const post_template = { + title: "Can't fetch from the db yo", + content: + "This is meant to be pulling from a database, but for some reason that isn't working and this is filler text that should hopefully never see the light of day. If you are reading this, something has gone horribly, horribly wrong. Please start crying and prepare for the incoming wrath of hell. Furthermore, this is very, very long because I am trying to test the scroll feature so thank you ^_^.", + author: { + username: "stp", + }, + createdAt: Date.now(), +}; + +export const usePostsStore = defineStore("posts", () => { + const posts = ref([post_template]); + + const postsCount = computed(() => posts.value.length); + + async function fetchPosts() { + try { + const res = await axios.get("/api/posts"); + if (!Array.isArray(res.data)) { + throw new Error("Invalid response from posts API"); + } + posts.value = res.data; + } catch (err) { + console.error("Cannot connect to Post API", err); + } + } + + async function deletePost(post) { + try { + const res = await axios.delete( + `/api/posts/${encodeURIComponent(post.id)}`, + ); + console.log("Deleted:", res.data); + fetchPosts(); + } catch (err) { + console.error("Delete failed:", err); + } + } + return { + posts, + + postsCount, + + fetchPosts, + deletePost, + }; +}); diff --git a/nginx/vue/src/stores/songs.js b/nginx/vue/src/stores/songs.js new file mode 100644 index 0000000..75bca4e --- /dev/null +++ b/nginx/vue/src/stores/songs.js @@ -0,0 +1,46 @@ +import { defineStore } from "pinia"; +import { ref, computed } from "vue"; +import axios from "axios"; + +const song_template = { + id: 1, + track: { + id: 1, + name: "^_^", + album: { images: [{ url: "/img/Untitled.png" }] }, + artists: [{ name: ">_<" }], + }, +}; + +export const useSongsStore = defineStore("songs", () => { + const songs = ref([song_template]); + + const songsCount = computed(() => songs.value.length); + + fetchSongs(); + + let refreshId = null; + refreshId = setTimeout(fetchSongs, 120000); + + async function fetchSongs() { + try { + const res = await axios.get("/api/spotify/recent"); + if (!Array.isArray(res.data)) { + throw new Error("Invalid response from Spotify API"); + } + songs.value = res.data; + refreshId = setTimeout(fetchSongs, 120000); + console.log("lol"); + } catch (err) { + console.error("Cannot connect to Spotify API", err); + } + } + + return { + songs, + + songsCount, + + fetchSongs, + }; +}); diff --git a/nginx/vue/src/stores/users.js b/nginx/vue/src/stores/users.js new file mode 100644 index 0000000..e69de29 diff --git a/nginx/vue/src/views/Home.vue b/nginx/vue/src/views/Home.vue index c1ed42f..040103d 100644 --- a/nginx/vue/src/views/Home.vue +++ b/nginx/vue/src/views/Home.vue @@ -20,7 +20,7 @@ import Watching from "@/components/home/Watching.vue";