chore: update deps and add TypeScript null safety checks
This commit is contained in:
18
.npm/_logs/2025-11-30T10_05_40_911Z-debug-0.log
Normal file
18
.npm/_logs/2025-11-30T10_05_40_911Z-debug-0.log
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v22.21.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-11-30T10_05_40_911Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-11-30T10_05_40_911Z-debug-0.log
|
||||||
|
11 silly logfile done cleaning log files
|
||||||
|
12 verbose cwd /home/notebrook/backend
|
||||||
|
13 verbose os Linux 6.8.0-85-generic
|
||||||
|
14 verbose node v22.21.0
|
||||||
|
15 verbose npm v11.6.2
|
||||||
|
16 verbose exit 1
|
||||||
|
17 verbose code 1
|
||||||
19
.npm/_logs/2025-11-30T10_05_42_270Z-debug-0.log
Normal file
19
.npm/_logs/2025-11-30T10_05_42_270Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v22.21.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-11-30T10_05_42_270Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-11-30T10_05_42_270Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-85-generic
|
||||||
|
15 verbose node v22.21.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
19
.npm/_logs/2025-12-02T18_08_09_047Z-debug-0.log
Normal file
19
.npm/_logs/2025-12-02T18_08_09_047Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_09_047Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_09_047Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 2 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-87-generic
|
||||||
|
15 verbose node v25.2.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
13
.npm/_logs/2025-12-02T18_08_09_048Z-debug-0.log
Normal file
13
.npm/_logs/2025-12-02T18_08_09_048Z-debug-0.log
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/frontend-vue/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm run dev --host
|
||||||
|
8 verbose argv "run" "dev" "--" "--host"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_09_048Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_09_048Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 2 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
19
.npm/_logs/2025-12-02T18_08_11_876Z-debug-0.log
Normal file
19
.npm/_logs/2025-12-02T18_08_11_876Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_11_876Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_11_876Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-87-generic
|
||||||
|
15 verbose node v25.2.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
19
.npm/_logs/2025-12-02T18_08_13_400Z-debug-0.log
Normal file
19
.npm/_logs/2025-12-02T18_08_13_400Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_13_400Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_13_400Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-87-generic
|
||||||
|
15 verbose node v25.2.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
19
.npm/_logs/2025-12-02T18_08_14_897Z-debug-0.log
Normal file
19
.npm/_logs/2025-12-02T18_08_14_897Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_14_897Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_14_897Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-87-generic
|
||||||
|
15 verbose node v25.2.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
19
.npm/_logs/2025-12-02T18_08_16_430Z-debug-0.log
Normal file
19
.npm/_logs/2025-12-02T18_08_16_430Z-debug-0.log
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_08_16_430Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_08_16_430Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
|
13 verbose cwd /home/notebrook/backend
|
||||||
|
14 verbose os Linux 6.8.0-87-generic
|
||||||
|
15 verbose node v25.2.0
|
||||||
|
16 verbose npm v11.6.2
|
||||||
|
17 verbose exit 1
|
||||||
|
18 verbose code 1
|
||||||
13
.npm/_logs/2025-12-02T18_28_20_942Z-debug-0.log
Normal file
13
.npm/_logs/2025-12-02T18_28_20_942Z-debug-0.log
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.4
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-02T18_28_20_942Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-02T18_28_20_942Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
13
.npm/_logs/2025-12-04T06_22_30_604Z-debug-0.log
Normal file
13
.npm/_logs/2025-12-04T06_22_30_604Z-debug-0.log
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.4
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-04T06_22_30_604Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-04T06_22_30_604Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
13
.npm/_logs/2025-12-07T09_24_41_497Z-debug-0.log
Normal file
13
.npm/_logs/2025-12-07T09_24_41_497Z-debug-0.log
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@11.6.2
|
||||||
|
2 info using node@v25.2.0
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/home/notebrook/backend/.npmrc
|
||||||
|
5 silly config load:file:/home/notebrook/.npmrc
|
||||||
|
6 silly config load:file:/usr/etc/npmrc
|
||||||
|
7 verbose title npm start
|
||||||
|
8 verbose argv "start"
|
||||||
|
9 verbose logfile logs-max:10 dir:/home/notebrook/.npm/_logs/2025-12-07T09_24_41_497Z-
|
||||||
|
10 verbose logfile /home/notebrook/.npm/_logs/2025-12-07T09_24_41_497Z-debug-0.log
|
||||||
|
11 silly logfile start cleaning logs, removing 1 files
|
||||||
|
12 silly logfile done cleaning log files
|
||||||
0
.npm/_update-notifier-last-checked
Normal file
0
.npm/_update-notifier-last-checked
Normal file
2022
backend/package-lock.json
generated
2022
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -14,22 +14,22 @@
|
|||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/better-sqlite3": "^7.6.11",
|
"@types/better-sqlite3": "^7.6.13",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.19",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^5.0.6",
|
||||||
"@types/jsonwebtoken": "^9.0.6",
|
"@types/jsonwebtoken": "^9.0.10",
|
||||||
"@types/multer": "^1.4.11",
|
"@types/multer": "^2.0.0",
|
||||||
"@types/ws": "^8.5.12",
|
"@types/ws": "^8.18.1",
|
||||||
"better-sqlite3": "^11.2.1",
|
"better-sqlite3": "^12.5.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^17.2.3",
|
||||||
"express": "^4.19.2",
|
"express": "^5.2.1",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^2.0.2",
|
||||||
"ollama": "^0.5.8",
|
"ollama": "^0.6.3",
|
||||||
"openai": "^4.56.0",
|
"openai": "^6.9.1",
|
||||||
"selfsigned": "^2.4.1",
|
"selfsigned": "^5.2.0",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.34.5",
|
||||||
"tsx": "^4.18.0",
|
"tsx": "^4.21.0",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2419
frontend-vue/package-lock.json
generated
2419
frontend-vue/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,27 +12,27 @@
|
|||||||
"format": "prettier --write src/"
|
"format": "prettier --write src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.25",
|
||||||
"vue-router": "^4.4.5",
|
"vue-router": "^4.6.3",
|
||||||
"pinia": "^2.3.0",
|
"pinia": "^3.0.4",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.2",
|
||||||
"@vueuse/core": "^11.3.0",
|
"@vueuse/core": "^14.1.0",
|
||||||
"@vueuse/sound": "^2.0.1"
|
"@vueuse/sound": "^2.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^24.10.1",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^6.0.2",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.8.1",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^6.0.5",
|
"vite": "^7.2.6",
|
||||||
"vue-tsc": "^2.1.10",
|
"vue-tsc": "^3.1.5",
|
||||||
"vite-plugin-pwa": "^0.21.2",
|
"vite-plugin-pwa": "^1.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
||||||
"@typescript-eslint/parser": "^8.18.2",
|
"@typescript-eslint/parser": "^8.48.1",
|
||||||
"@vue/eslint-config-prettier": "^10.1.0",
|
"@vue/eslint-config-prettier": "^10.2.0",
|
||||||
"@vue/eslint-config-typescript": "^14.1.3",
|
"@vue/eslint-config-typescript": "^14.6.0",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.39.1",
|
||||||
"eslint-plugin-vue": "^9.32.0",
|
"eslint-plugin-vue": "^10.6.2",
|
||||||
"prettier": "^3.4.2"
|
"prettier": "^3.7.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,12 +108,12 @@ const trapFocus = (event: KeyboardEvent) => {
|
|||||||
if (event.shiftKey) {
|
if (event.shiftKey) {
|
||||||
if (document.activeElement === firstElement) {
|
if (document.activeElement === firstElement) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
lastElement.focus()
|
lastElement?.focus()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (document.activeElement === lastElement) {
|
if (document.activeElement === lastElement) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
firstElement.focus()
|
firstElement?.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ onMounted(() => {
|
|||||||
const getFocusedMessage = (): ExtendedMessage | UnsentMessage | null => {
|
const getFocusedMessage = (): ExtendedMessage | UnsentMessage | null => {
|
||||||
const messages = allMessages.value
|
const messages = allMessages.value
|
||||||
if (focusedMessageIndex.value >= 0 && focusedMessageIndex.value < messages.length) {
|
if (focusedMessageIndex.value >= 0 && focusedMessageIndex.value < messages.length) {
|
||||||
return messages[focusedMessageIndex.value]
|
return messages[focusedMessageIndex.value] ?? null
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,8 +207,8 @@ const switchCamera = async () => {
|
|||||||
|
|
||||||
// Determine if this is likely a front camera
|
// Determine if this is likely a front camera
|
||||||
const currentCamera = availableCameras.value[currentCameraIndex.value]
|
const currentCamera = availableCameras.value[currentCameraIndex.value]
|
||||||
isFrontCamera.value = currentCamera.label.toLowerCase().includes('front') ||
|
isFrontCamera.value = currentCamera?.label.toLowerCase().includes('front') ||
|
||||||
currentCamera.label.toLowerCase().includes('user')
|
currentCamera?.label.toLowerCase().includes('user') || false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await startCamera()
|
await startCamera()
|
||||||
|
|||||||
@@ -281,7 +281,10 @@ const performDelete = async () => {
|
|||||||
|
|
||||||
// Switch to first available channel if we were on the deleted channel
|
// Switch to first available channel if we were on the deleted channel
|
||||||
if (appStore.currentChannelId === props.channel.id && appStore.channels.length > 0) {
|
if (appStore.currentChannelId === props.channel.id && appStore.channels.length > 0) {
|
||||||
await appStore.setCurrentChannel(appStore.channels[0].id)
|
const firstChannel = appStore.channels[0]
|
||||||
|
if (firstChannel) {
|
||||||
|
await appStore.setCurrentChannel(firstChannel.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// For delete, we can't do offline fallback easily since it affects server state
|
// For delete, we can't do offline fallback easily since it affects server state
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ const uploadFiles = async () => {
|
|||||||
// For single file, use the filename as message content
|
// For single file, use the filename as message content
|
||||||
// For multiple files, show count
|
// For multiple files, show count
|
||||||
const messageContent = selectedFiles.value.length === 1
|
const messageContent = selectedFiles.value.length === 1
|
||||||
? selectedFiles.value[0].name
|
? selectedFiles.value[0]?.name || 'Uploaded file'
|
||||||
: `Uploaded ${selectedFiles.value.length} files`
|
: `Uploaded ${selectedFiles.value.length} files`
|
||||||
|
|
||||||
// Create a message first to attach files to
|
// Create a message first to attach files to
|
||||||
@@ -151,6 +151,10 @@ const uploadFiles = async () => {
|
|||||||
// Upload the first file (backend uses single file per message)
|
// Upload the first file (backend uses single file per message)
|
||||||
const file = selectedFiles.value[0]
|
const file = selectedFiles.value[0]
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
throw new Error('No file selected')
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uploadedFile = await apiService.uploadFile(appStore.currentChannelId, message.id, file)
|
const uploadedFile = await apiService.uploadFile(appStore.currentChannelId, message.id, file)
|
||||||
uploadProgress.value[0] = 100
|
uploadProgress.value[0] = 100
|
||||||
|
|||||||
@@ -161,11 +161,17 @@ const handleAlphanumericNavigation = (char: string, currentIndex: number) => {
|
|||||||
focusChannel(nextMatch)
|
focusChannel(nextMatch)
|
||||||
} else {
|
} else {
|
||||||
// Wrap around to the first match
|
// Wrap around to the first match
|
||||||
focusChannel(matchingIndices[0])
|
const firstMatch = matchingIndices[0]
|
||||||
|
if (firstMatch !== undefined) {
|
||||||
|
focusChannel(firstMatch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// New character: jump to first match
|
// New character: jump to first match
|
||||||
focusChannel(matchingIndices[0])
|
const firstMatch = matchingIndices[0]
|
||||||
|
if (firstMatch !== undefined) {
|
||||||
|
focusChannel(firstMatch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,14 +174,20 @@ export function useAudio() {
|
|||||||
console.log(`playWater called - global: ${globalWaterSounds.length}, reactive: ${waterSounds.value.length} water sounds available`)
|
console.log(`playWater called - global: ${globalWaterSounds.length}, reactive: ${waterSounds.value.length} water sounds available`)
|
||||||
if (globalWaterSounds.length > 0) {
|
if (globalWaterSounds.length > 0) {
|
||||||
const randomIndex = Math.floor(Math.random() * globalWaterSounds.length)
|
const randomIndex = Math.floor(Math.random() * globalWaterSounds.length)
|
||||||
await playSoundBuffer(globalWaterSounds[randomIndex])
|
const buffer = globalWaterSounds[randomIndex]
|
||||||
|
if (buffer) {
|
||||||
|
await playSoundBuffer(buffer)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('Water sounds not loaded - trying to load them now')
|
console.warn('Water sounds not loaded - trying to load them now')
|
||||||
if (globalAudioContext) {
|
if (globalAudioContext) {
|
||||||
await loadAllSounds()
|
await loadAllSounds()
|
||||||
if (globalWaterSounds.length > 0) {
|
if (globalWaterSounds.length > 0) {
|
||||||
const randomIndex = Math.floor(Math.random() * globalWaterSounds.length)
|
const randomIndex = Math.floor(Math.random() * globalWaterSounds.length)
|
||||||
await playSoundBuffer(globalWaterSounds[randomIndex])
|
const buffer = globalWaterSounds[randomIndex]
|
||||||
|
if (buffer) {
|
||||||
|
await playSoundBuffer(buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +196,10 @@ export function useAudio() {
|
|||||||
const playSent = async () => {
|
const playSent = async () => {
|
||||||
if (globalSentSounds.length > 0) {
|
if (globalSentSounds.length > 0) {
|
||||||
const randomIndex = Math.floor(Math.random() * globalSentSounds.length)
|
const randomIndex = Math.floor(Math.random() * globalSentSounds.length)
|
||||||
await playSoundBuffer(globalSentSounds[randomIndex])
|
const buffer = globalSentSounds[randomIndex]
|
||||||
|
if (buffer) {
|
||||||
|
await playSoundBuffer(buffer)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('Sent sounds not loaded')
|
console.warn('Sent sounds not loaded')
|
||||||
}
|
}
|
||||||
@@ -303,7 +312,7 @@ export function useAudio() {
|
|||||||
// Select default voice (prefer English voices)
|
// Select default voice (prefer English voices)
|
||||||
if (!selectedVoice.value && voices.length > 0) {
|
if (!selectedVoice.value && voices.length > 0) {
|
||||||
const englishVoice = voices.find(voice => voice.lang.startsWith('en'))
|
const englishVoice = voices.find(voice => voice.lang.startsWith('en'))
|
||||||
selectedVoice.value = englishVoice || voices[0]
|
selectedVoice.value = englishVoice || voices[0] || null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,8 +136,15 @@ export function useWebSocket() {
|
|||||||
const channels = [...appStore.channels]
|
const channels = [...appStore.channels]
|
||||||
const channelIndex = channels.findIndex(c => c.id === channelId)
|
const channelIndex = channels.findIndex(c => c.id === channelId)
|
||||||
if (channelIndex !== -1) {
|
if (channelIndex !== -1) {
|
||||||
channels[channelIndex] = { ...channels[channelIndex], name: data.name }
|
const existingChannel = channels[channelIndex]
|
||||||
appStore.setChannels(channels)
|
if (existingChannel) {
|
||||||
|
channels[channelIndex] = {
|
||||||
|
id: existingChannel.id,
|
||||||
|
name: data.name,
|
||||||
|
created_at: existingChannel.created_at
|
||||||
|
}
|
||||||
|
appStore.setChannels(channels)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,11 +73,16 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const channelMessages = messages.value[message.channel_id]
|
const channelMessages = messages.value[message.channel_id]
|
||||||
|
if (!channelMessages) return
|
||||||
|
|
||||||
const existingIndex = channelMessages.findIndex(m => m.id === message.id)
|
const existingIndex = channelMessages.findIndex(m => m.id === message.id)
|
||||||
|
|
||||||
if (existingIndex !== -1) {
|
if (existingIndex !== -1) {
|
||||||
// Upsert: update existing to avoid duplicates from WebSocket vs sync
|
// Upsert: update existing to avoid duplicates from WebSocket vs sync
|
||||||
channelMessages[existingIndex] = { ...channelMessages[existingIndex], ...message }
|
const existingMessage = channelMessages[existingIndex]
|
||||||
|
if (existingMessage) {
|
||||||
|
channelMessages[existingIndex] = { ...existingMessage, ...message }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
channelMessages.push(message)
|
channelMessages.push(message)
|
||||||
}
|
}
|
||||||
@@ -93,9 +98,14 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
const updateMessage = (messageId: number, updates: Partial<ExtendedMessage>) => {
|
const updateMessage = (messageId: number, updates: Partial<ExtendedMessage>) => {
|
||||||
for (const channelId in messages.value) {
|
for (const channelId in messages.value) {
|
||||||
const channelMessages = messages.value[parseInt(channelId)]
|
const channelMessages = messages.value[parseInt(channelId)]
|
||||||
|
if (!channelMessages) continue
|
||||||
|
|
||||||
const messageIndex = channelMessages.findIndex(m => m.id === messageId)
|
const messageIndex = channelMessages.findIndex(m => m.id === messageId)
|
||||||
if (messageIndex !== -1) {
|
if (messageIndex !== -1) {
|
||||||
channelMessages[messageIndex] = { ...channelMessages[messageIndex], ...updates }
|
const existingMessage = channelMessages[messageIndex]
|
||||||
|
if (existingMessage) {
|
||||||
|
channelMessages[messageIndex] = { ...existingMessage, ...updates }
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,6 +118,8 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
const removeMessage = (messageId: number) => {
|
const removeMessage = (messageId: number) => {
|
||||||
for (const channelId in messages.value) {
|
for (const channelId in messages.value) {
|
||||||
const channelMessages = messages.value[parseInt(channelId)]
|
const channelMessages = messages.value[parseInt(channelId)]
|
||||||
|
if (!channelMessages) continue
|
||||||
|
|
||||||
const messageIndex = channelMessages.findIndex(m => m.id === messageId)
|
const messageIndex = channelMessages.findIndex(m => m.id === messageId)
|
||||||
if (messageIndex !== -1) {
|
if (messageIndex !== -1) {
|
||||||
channelMessages.splice(messageIndex, 1)
|
channelMessages.splice(messageIndex, 1)
|
||||||
@@ -127,6 +139,11 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = sourceMessages[messageIndex]
|
const message = sourceMessages[messageIndex]
|
||||||
|
if (!message) {
|
||||||
|
console.warn(`Message ${messageId} not found at index ${messageIndex}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
sourceMessages.splice(messageIndex, 1)
|
sourceMessages.splice(messageIndex, 1)
|
||||||
|
|
||||||
// Update message's channel_id and add to target channel
|
// Update message's channel_id and add to target channel
|
||||||
@@ -137,6 +154,8 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const targetMessages = messages.value[targetChannelId]
|
const targetMessages = messages.value[targetChannelId]
|
||||||
|
if (!targetMessages) return
|
||||||
|
|
||||||
targetMessages.push(updatedMessage)
|
targetMessages.push(updatedMessage)
|
||||||
|
|
||||||
// Keep chronological order in target channel
|
// Keep chronological order in target channel
|
||||||
|
|||||||
@@ -443,6 +443,11 @@ const announceLastMessage = (position: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = messages[messageIndex]
|
const message = messages[messageIndex]
|
||||||
|
if (!message) {
|
||||||
|
toastStore.info('No message is available in this position')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const timeStr = formatTimestampForScreenReader(message.created_at)
|
const timeStr = formatTimestampForScreenReader(message.created_at)
|
||||||
const announcement = `${message.content}; sent ${timeStr}`
|
const announcement = `${message.content}; sent ${timeStr}`
|
||||||
|
|
||||||
@@ -608,7 +613,10 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 5. Auto-select first channel if none selected and we have channels
|
// 5. Auto-select first channel if none selected and we have channels
|
||||||
if (!appStore.currentChannelId && appStore.channels.length > 0) {
|
if (!appStore.currentChannelId && appStore.channels.length > 0) {
|
||||||
await selectChannel(appStore.channels[0].id)
|
const firstChannel = appStore.channels[0]
|
||||||
|
if (firstChannel) {
|
||||||
|
await selectChannel(firstChannel.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Auto-focus message input on page load
|
// 6. Auto-focus message input on page load
|
||||||
|
|||||||
Reference in New Issue
Block a user