Added linting and enforced code styling.

This commit is contained in:
Cameron Redmore 2025-04-25 08:14:48 +01:00
parent 8655eae39c
commit 86967b26cd
37 changed files with 3356 additions and 1875 deletions

View file

@ -2,7 +2,8 @@ import { defineStore } from 'pinia';
import { ref, computed, watch } from 'vue'; // Import watch
import axios from 'axios';
export const useChatStore = defineStore('chat', () => {
export const useChatStore = defineStore('chat', () =>
{
const isVisible = ref(false);
const currentThreadId = ref(null);
const messages = ref([]); // Array of { sender: 'user' | 'bot', content: string, createdAt?: Date, loading?: boolean }
@ -18,12 +19,14 @@ export const useChatStore = defineStore('chat', () => {
// --- Actions ---
// New action to create a thread if it doesn't exist
async function createThreadIfNotExists() {
async function createThreadIfNotExists()
{
if (currentThreadId.value) return; // Already have a thread
isLoading.value = true;
error.value = null;
try {
try
{
// Call the endpoint without content to just create the thread
const response = await axios.post('/api/chat/threads', {});
currentThreadId.value = response.data.threadId;
@ -31,37 +34,51 @@ export const useChatStore = defineStore('chat', () => {
console.log('Created new chat thread:', currentThreadId.value);
// Start polling now that we have a thread ID
startPolling();
} catch (err) {
}
catch (err)
{
console.error('Error creating chat thread:', err);
error.value = 'Failed to start chat.';
// Don't set isVisible to false, let the user see the error
} finally {
}
finally
{
isLoading.value = false;
}
}
function toggleChat() {
function toggleChat()
{
isVisible.value = !isVisible.value;
if (isVisible.value) {
if (!currentThreadId.value) {
if (isVisible.value)
{
if (!currentThreadId.value)
{
// If opening and no thread exists, create one
createThreadIfNotExists();
} else {
}
else
{
// If opening and thread exists, fetch messages if empty and start polling
if (messages.value.length === 0) {
fetchMessages();
if (messages.value.length === 0)
{
fetchMessages();
}
startPolling();
}
} else {
}
else
{
// If closing, stop polling
stopPolling();
}
}
async function fetchMessages() {
if (!currentThreadId.value) {
async function fetchMessages()
{
if (!currentThreadId.value)
{
console.log('No active thread to fetch messages for.');
// Don't try to fetch if no thread ID yet. createThreadIfNotExists handles the initial state.
return;
@ -69,33 +86,40 @@ export const useChatStore = defineStore('chat', () => {
// Avoid setting isLoading if polling, maybe use a different flag? For now, keep it simple.
// isLoading.value = true; // Might cause flickering during polling
error.value = null; // Clear previous errors on fetch attempt
try {
try
{
const response = await axios.get(`/api/chat/threads/${currentThreadId.value}/messages`);
const newMessages = response.data.map(msg => ({
sender: msg.sender,
content: msg.content,
createdAt: new Date(msg.createdAt),
loading: msg.content === 'Loading...'
sender: msg.sender,
content: msg.content,
createdAt: new Date(msg.createdAt),
loading: msg.content === 'Loading...'
})).sort((a, b) => a.createdAt - b.createdAt);
// Only update if messages have actually changed to prevent unnecessary re-renders
if (JSON.stringify(messages.value) !== JSON.stringify(newMessages)) {
messages.value = newMessages;
if (JSON.stringify(messages.value) !== JSON.stringify(newMessages))
{
messages.value = newMessages;
}
} catch (err) {
}
catch (err)
{
console.error('Error fetching messages:', err);
error.value = 'Failed to load messages.';
// Don't clear messages on polling error, keep the last known state
// messages.value = [];
stopPolling(); // Stop polling if there's an error fetching
} finally {
}
finally
{
// isLoading.value = false;
}
}
// Function to start polling
function startPolling() {
function startPolling()
{
if (pollingIntervalId.value) return; // Already polling
if (!currentThreadId.value) return; // No thread to poll for
@ -104,8 +128,10 @@ export const useChatStore = defineStore('chat', () => {
}
// Function to stop polling
function stopPolling() {
if (pollingIntervalId.value) {
function stopPolling()
{
if (pollingIntervalId.value)
{
console.log('Stopping chat polling.');
clearInterval(pollingIntervalId.value);
pollingIntervalId.value = null;
@ -113,12 +139,14 @@ export const useChatStore = defineStore('chat', () => {
}
async function sendMessage(content) {
async function sendMessage(content)
{
if (!content.trim()) return;
if (!currentThreadId.value) {
error.value = "Cannot send message: No active chat thread.";
console.error("Attempted to send message without a thread ID.");
return; // Should not happen if UI waits for thread creation
if (!currentThreadId.value)
{
error.value = 'Cannot send message: No active chat thread.';
console.error('Attempted to send message without a thread ID.');
return; // Should not happen if UI waits for thread creation
}
const userMessage = {
@ -137,7 +165,8 @@ export const useChatStore = defineStore('chat', () => {
isLoading.value = true; // Indicate activity
error.value = null;
try {
try
{
const payload = { content: userMessage.content };
// Always post to the existing thread once it's created
const response = await axios.post(`/api/chat/threads/${currentThreadId.value}/messages`, payload);
@ -151,15 +180,19 @@ export const useChatStore = defineStore('chat', () => {
// Immediately fetch messages after sending to get the updated list
await fetchMessages();
} catch (err) {
console.error('Error sending message:', err);
error.value = 'Failed to send message.';
// Remove loading indicator on error
messages.value = messages.value.filter(m => !m.loading);
// Optionally add an error message to the chat
// Ensure the object is correctly formatted
messages.value.push({ sender: 'bot', content: "Sorry, I couldn't send that message.", createdAt: new Date() });
} finally {
}
catch (err)
{
console.error('Error sending message:', err);
error.value = 'Failed to send message.';
// Remove loading indicator on error
messages.value = messages.value.filter(m => !m.loading);
// Optionally add an error message to the chat
// Ensure the object is correctly formatted
messages.value.push({ sender: 'bot', content: "Sorry, I couldn't send that message.", createdAt: new Date() });
}
finally
{
isLoading.value = false;
// Restart polling after sending attempt is complete
startPolling();
@ -167,7 +200,8 @@ export const useChatStore = defineStore('chat', () => {
}
// Call this when the user logs out or the app closes if you want to clear state
function resetChat() {
function resetChat()
{
stopPolling(); // Ensure polling stops on reset
isVisible.value = false;
currentThreadId.value = null;