diff --git a/frontend/package.json b/frontend/package.json index cede881..c33af11 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,4 +1,24 @@ { + "name": "frontend", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "dev": "vite dev", + "fix": "ultracite fix", + "lint": "ultracite check", + "prepare": "svelte-kit sync || echo ''", + "preview": "vite preview" + }, + "dependencies": { + "bits-ui": "^2.18.1", + "lottie-web": "^5.13.0", + "pako": "^3.0.0", + "uqr": "^0.1.3" + }, "devDependencies": { "@biomejs/biome": "2.5.13", "@sveltejs/adapter-auto": "^7.0.1", @@ -16,25 +36,5 @@ "typescript": "^7.0.0", "ultracite": "7.12.0", "vite": "^8.0.7" - }, - "name": "frontend", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", - "prepare": "svelte-kit sync || echo ''", - "lint": "ultracite check", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "fix": "ultracite fix" - }, - "type": "module", - "version": "0.0.1", - "private": true, - "dependencies": { - "bits-ui": "^2.18.1", - "lottie-web": "^5.13.0", - "pako": "^3.0.0", - "uqr": "^0.1.3" } } diff --git a/frontend/src/app.html b/frontend/src/app.html index cb9d355..cfa946b 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -2,8 +2,8 @@ - - + +
{#if chats.loading && list.length === 0} {#each skeletonRows as index (index)}
- +
- - + +
{/each} {:else if list.length === 0} {:else} -
+
{#each visible as chat (chat.chat_id)} goto(`/app/${chat.chat_id}`)} + selected={chat.chat_id === activeChatId} /> {/each}
diff --git a/frontend/src/lib/components/ChatListItem.svelte b/frontend/src/lib/components/ChatListItem.svelte index a45c123..20150e3 100644 --- a/frontend/src/lib/components/ChatListItem.svelte +++ b/frontend/src/lib/components/ChatListItem.svelte @@ -62,17 +62,17 @@ {#snippet children({ props })} @@ -69,10 +69,10 @@ {:else if type === "url" || type === "text_link" || type === "email" || type === "phone_number"} {@render tree(node.children)} {:else if type === "mention" || type === "text_mention" || type === "hashtag" || type === "cashtag" || type === "bot_command"} diff --git a/frontend/src/lib/components/FolderTabs.svelte b/frontend/src/lib/components/FolderTabs.svelte index f81c587..1bb81f8 100644 --- a/frontend/src/lib/components/FolderTabs.svelte +++ b/frontend/src/lib/components/FolderTabs.svelte @@ -62,21 +62,21 @@ }); -
+
{#each tabs as tab (tab.id)} - {/each}
diff --git a/frontend/src/lib/components/InlineButtons.svelte b/frontend/src/lib/components/InlineButtons.svelte index 773afe2..2b77b69 100644 --- a/frontend/src/lib/components/InlineButtons.svelte +++ b/frontend/src/lib/components/InlineButtons.svelte @@ -30,8 +30,8 @@ {button.text} ↗ @@ -39,8 +39,8 @@ {:else if button.kind === "callback" && button.data} diff --git a/frontend/src/lib/components/MediaAlbum.svelte b/frontend/src/lib/components/MediaAlbum.svelte index cd347d0..62e6c3d 100644 --- a/frontend/src/lib/components/MediaAlbum.svelte +++ b/frontend/src/lib/components/MediaAlbum.svelte @@ -38,7 +38,7 @@ {:else}
{#each media as item, index (item.id ?? index)} - onopen(index)} /> + onopen(index)} /> {/each}
{/if} diff --git a/frontend/src/lib/components/MediaVersionThumb.svelte b/frontend/src/lib/components/MediaVersionThumb.svelte index 572036d..55cfb9e 100644 --- a/frontend/src/lib/components/MediaVersionThumb.svelte +++ b/frontend/src/lib/components/MediaVersionThumb.svelte @@ -33,16 +33,16 @@ {#if result === null}
{:else if result.state === "ready" && vk === "image"} -
- {version.kind} + + {version.kind} {:else if result.state === "ready" && vk === "video"} - + @@ -50,10 +50,10 @@ {:else if result.state === "ready"} {version.kind} diff --git a/frontend/src/lib/components/MediaViewer.svelte b/frontend/src/lib/components/MediaViewer.svelte index b40f7c8..294a7d0 100644 --- a/frontend/src/lib/components/MediaViewer.svelte +++ b/frontend/src/lib/components/MediaViewer.svelte @@ -64,32 +64,23 @@ revoke(); loading = true; result = null; - kind = item.kind; - messageId = item.messageId; currentMediaId = null; - fileName = item.fileName; - fileSize = item.fileSize; fileOnly = false; - const current = ++token; + ({ kind, messageId, fileName, fileSize } = item); + token += 1; + const current = token; try { - let mediaId = item.mediaId; - let downloaded = item.downloaded; - let name = item.fileName; - let size = item.fileSize; - let mimeType = item.mime; + let { mediaId, downloaded, mime: mimeType } = item; + let { fileName: name, fileSize: size } = item; if (mediaId === null) { const meta = await getMessageMedia(chatId, item.messageId); - mediaId = meta.id; - downloaded = meta.downloaded; - kind = meta.kind; - name = meta.file_name; - size = meta.file_size; - mimeType = meta.mime; + ({ id: mediaId, downloaded, kind, mime: mimeType } = meta); + ({ file_name: name, file_size: size } = meta); } const plainFile = downloaded && !isPreviewable(kind, mimeType); let next: MediaResult; if (plainFile) { - next = { state: "ready", url: "", mime: mimeType }; + next = { mime: mimeType, state: "ready", url: "" }; } else if (downloaded) { next = await requestMedia(mediaId); } else { @@ -196,10 +187,10 @@ {#snippet children({ props })} @@ -214,15 +205,15 @@ {/snippet} {/if} - +
@@ -233,21 +224,21 @@ {#if loading} {:else if result?.state === "ready" && isImage} - {kind} + {kind} {:else if result?.state === "ready" && isVideo} {:else if result?.state === "ready" && isAudio} - + {:else if result?.state === "ready"}
@@ -255,7 +246,7 @@ {#if fileSize}

{formatBytes(fileSize)}

{/if} - @@ -263,7 +254,7 @@ {:else if result?.state === "not-downloaded"}

Файл ещё не скачан в архив.

-
@@ -273,20 +264,20 @@
{#if hasNav} diff --git a/frontend/src/lib/components/MessageBubble.svelte b/frontend/src/lib/components/MessageBubble.svelte index 756aa4c..3b6bbf1 100644 --- a/frontend/src/lib/components/MessageBubble.svelte +++ b/frontend/src/lib/components/MessageBubble.svelte @@ -109,6 +109,7 @@ ui.openMessagePanel("annotations", message.message_id); } function jumpToReply() { + // biome-ignore lint/suspicious/noEqualsToNull: optional chaining yields undefined here if (message.reply?.message_id != null) { onjump(message.reply.message_id); } @@ -134,24 +135,24 @@
{#if isGroupChat}
{#if lastInGroup && avatarId !== null} {/if}
@@ -165,7 +166,7 @@ {/if} {#if message.reply} - + {/if} {#if deleted} @@ -185,49 +186,49 @@ {#if !special} {#if message.media.length > 1} {:else if message.has_media} - onmedia(0)} /> + onmedia(0)} {own} /> {/if} {/if} {#if hasText}
{:else if !(message.has_media || deleted || special)}
(no text)
{/if} {#if message.web_page} - + {/if} {#if message.reactions.length} {/if} {#if linkCount > 0} - {/if} - + {#if message.inline_buttons.length} {/if} {#if hasCallbacks} - @@ -265,7 +266,7 @@ >Версии {/if} - {#if message.reply?.message_id != null} + {#if (message.reply?.message_id ?? null) !== null} Перейти к ответу diff --git a/frontend/src/lib/components/MessageList.svelte b/frontend/src/lib/components/MessageList.svelte index 14ac230..96810d2 100644 --- a/frontend/src/lib/components/MessageList.svelte +++ b/frontend/src/lib/components/MessageList.svelte @@ -70,7 +70,7 @@ const rows = $derived.by(() => { const out: Row[] = []; - for (let i = 0; i < messages.length; i++) { + for (let i = 0; i < messages.length; i += 1) { const message = messages[i]; const prev = messages[i - 1]; const next = messages[i + 1]; @@ -78,14 +78,14 @@ const samePrevDay = prev ? dayKey(prev.date) === day : false; const sameNextDay = next ? dayKey(next.date) === day : false; out.push({ - message, dayKey: day, - own: ownId !== null && message.sender_id === ownId, + daySeparator: samePrevDay ? null : formatDay(message.date), firstInGroup: !prev || prev.sender_id !== message.sender_id || !samePrevDay, lastInGroup: !next || next.sender_id !== message.sender_id || !sameNextDay, - daySeparator: samePrevDay ? null : formatDay(message.date), + message, + own: ownId !== null && message.sender_id === ownId, }); } return out; @@ -97,9 +97,11 @@ if (message.sender_id !== null) { ids.add(message.sender_id); } + // biome-ignore lint/suspicious/noEqualsToNull: optional chaining yields undefined here if (message.reply?.sender_id != null) { ids.add(message.reply.sender_id); } + // biome-ignore lint/suspicious/noEqualsToNull: optional chaining yields undefined here if (message.forward?.from_id != null) { ids.add(message.forward.from_id); } @@ -160,9 +162,9 @@ hasNewer = false; try { const page = await listMessages(chatId, { + include_deleted: true, limit: PAGE, offset: 0, - include_deleted: true, }); messages = [...page].reverse(); hasMore = page.length > 0; @@ -213,9 +215,9 @@ const prevTop = el.scrollTop; try { const page = await listMessages(chatId, { - limit: PAGE, before_id: messages[0].message_id, include_deleted: true, + limit: PAGE, }); const known = new Set(messages.map((m) => m.message_id)); const fresh = page.filter((m) => !known.has(m.message_id)); @@ -241,9 +243,9 @@ loadingNewer = true; try { const page = await listMessages(chatId, { - limit: PAGE, after_id: messages.at(-1)?.message_id, include_deleted: true, + limit: PAGE, }); const known = new Set(messages.map((m) => m.message_id)); const fresh = page.filter((m) => !known.has(m.message_id)); @@ -266,14 +268,14 @@ try { const [older, newer] = await Promise.all([ listMessages(chatId, { - limit: PAGE, before_id: messageId + 1, include_deleted: true, + limit: PAGE, }), listMessages(chatId, { - limit: PAGE, after_id: messageId, include_deleted: true, + limit: PAGE, }), ]); messages = [...[...older].reverse(), ...newer]; @@ -395,9 +397,9 @@ return; } const page = await listMessages(chatId, { + include_deleted: true, limit: PAGE, offset: 0, - include_deleted: true, }); const fresh = [...page].reverse(); const known = new Map(messages.map((m) => [m.message_id, m])); @@ -460,9 +462,9 @@
{#if loading && messages.length === 0}
@@ -481,8 +483,8 @@ {#if row.daySeparator}
{row.daySeparator}
@@ -491,16 +493,16 @@ {:else} openMedia(row.message, index)} onversions={() => openVersions(row.message.message_id)} + own={row.own} /> {/if} {/each} @@ -512,10 +514,10 @@
{#if hasNewer} @@ -523,15 +525,15 @@