From 33d6c6b3edc01692898b9ffdef4c312af0ae3f96 Mon Sep 17 00:00:00 2001 From: duskflower Date: Fri, 24 Jan 2025 17:40:16 +0100 Subject: [PATCH 1/3] perf: load database parallel to decrypting --- bun.lock | 84 +++++++++---------- package.json | 6 +- src/lib/{decryptor.ts => backup-decryptor.ts} | 10 +-- src/pages/home.tsx | 16 ++-- 4 files changed, 60 insertions(+), 56 deletions(-) rename src/lib/{decryptor.ts => backup-decryptor.ts} (80%) diff --git a/bun.lock b/bun.lock index 0591354..b31794b 100644 --- a/bun.lock +++ b/bun.lock @@ -4,49 +4,49 @@ "": { "name": "signalstats", "dependencies": { - "@duskflower/signal-decrypt-backup-wasm": "^0.2.1", - "@kobalte/core": "^0.13.7", - "@kobalte/tailwindcss": "^0.9.0", - "@solid-primitives/refs": "^1.1.0", - "@solid-primitives/storage": "^4.3.0", - "@solid-primitives/upload": "^0.1.0", - "@solid-primitives/workers": "^0.4.0", - "@solidjs/meta": "^0.29.4", - "@solidjs/router": "^0.15.3", - "@sqlite.org/sqlite-wasm": "3.48.0-build3", - "@tanstack/solid-table": "^8.20.5", - "@types/umami": "^2.10.0", - "chart.js": "^4.4.7", - "chartjs-chart-wordcloud": "^4.4.4", - "chartjs-plugin-deferred": "^2.0.0", - "chartjs-plugin-zoom": "^2.2.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "date-fns": "^4.1.0", - "kysely": "^0.27.5", - "kysely-wasm": "^0.7.0", - "lucide-solid": "^0.474.0", - "seroval": "^1.2.0", - "solid-js": "^1.9.4", - "tailwind-merge": "^2.6.0", - "tailwindcss-animate": "^1.0.7", - "zen-mitt": "^3.0.0", + "@duskflower/signal-decrypt-backup-wasm": "latest", + "@kobalte/core": "latest", + "@kobalte/tailwindcss": "latest", + "@solid-primitives/refs": "latest", + "@solid-primitives/storage": "latest", + "@solid-primitives/upload": "latest", + "@solid-primitives/workers": "latest", + "@solidjs/meta": "latest", + "@solidjs/router": "latest", + "@sqlite.org/sqlite-wasm": "latest", + "@tanstack/solid-table": "latest", + "@types/umami": "latest", + "chart.js": "latest", + "chartjs-chart-wordcloud": "latest", + "chartjs-plugin-deferred": "latest", + "chartjs-plugin-zoom": "latest", + "class-variance-authority": "latest", + "clsx": "latest", + "date-fns": "latest", + "kysely": "latest", + "kysely-wasm": "latest", + "lucide-solid": "latest", + "seroval": "latest", + "solid-js": "latest", + "tailwind-merge": "latest", + "tailwindcss-animate": "latest", + "zen-mitt": "latest", }, "devDependencies": { - "@biomejs/biome": "1.9.4", - "@commitlint/cli": "^19.6.1", - "@commitlint/config-conventional": "^19.6.0", - "@tailwindcss/vite": "^4.0.0", - "@types/node": "^22.10.9", - "better-sqlite3": "^11.8.1", - "husky": "^9.1.7", - "kysely-codegen": "^0.17.0", - "lint-staged": "^15.4.2", - "tailwindcss": "^4.0.0", - "typescript": "^5.7.3", - "vite": "^6.0.11", - "vite-plugin-solid": "^2.11.0", - "vite-plugin-wasm": "^3.4.1", + "@biomejs/biome": "latest", + "@commitlint/cli": "latest", + "@commitlint/config-conventional": "latest", + "@tailwindcss/vite": "latest", + "@types/node": "latest", + "better-sqlite3": "latest", + "husky": "latest", + "kysely-codegen": "latest", + "lint-staged": "latest", + "tailwindcss": "latest", + "typescript": "latest", + "vite": "latest", + "vite-plugin-solid": "latest", + "vite-plugin-wasm": "latest", }, }, }, @@ -141,7 +141,7 @@ "@corvu/utils": ["@corvu/utils@0.4.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.11" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA=="], - "@duskflower/signal-decrypt-backup-wasm": ["@duskflower/signal-decrypt-backup-wasm@0.2.1", "https://git.duskflower.dev/api/packages/duskflower/npm/%40duskflower%2Fsignal-decrypt-backup-wasm/-/0.2.1/signal-decrypt-backup-wasm-0.2.1.tgz", {}, "sha512-lYwtubVOUU4kuJNw28Ns8N9Gh2nZB4j6BJz/vLpxF0Vc7zww3VIGnMCQToFWWSAwCs5+cABadeZMkv87SGfyQg=="], + "@duskflower/signal-decrypt-backup-wasm": ["@duskflower/signal-decrypt-backup-wasm@0.3.0", "https://git.duskflower.dev/api/packages/duskflower/npm/%40duskflower%2Fsignal-decrypt-backup-wasm/-/0.3.0/signal-decrypt-backup-wasm-0.3.0.tgz", {}, "sha512-1IMNFGz4bV4o29eXVelNbancqovsljmM0iZRrtau81gSy8bFE1lgwGFN05NAOFWlX/aZYzeUEeZVBrjUYIM0/w=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], diff --git a/package.json b/package.json index 64c8aaa..eac0529 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@commitlint/cli": "^19.6.1", "@commitlint/config-conventional": "^19.6.0", "@tailwindcss/vite": "^4.0.0", - "@types/node": "^22.10.9", + "@types/node": "^22.10.10", "better-sqlite3": "^11.8.1", "husky": "^9.1.7", "kysely-codegen": "^0.17.0", @@ -28,11 +28,11 @@ "vite-plugin-wasm": "^3.4.1" }, "dependencies": { - "@duskflower/signal-decrypt-backup-wasm": "^0.2.1", + "@duskflower/signal-decrypt-backup-wasm": "^0.3.0", "@kobalte/core": "^0.13.7", "@kobalte/tailwindcss": "^0.9.0", "@solid-primitives/refs": "^1.1.0", - "@solid-primitives/storage": "^4.3.0", + "@solid-primitives/storage": "^4.3.1", "@solid-primitives/upload": "^0.1.0", "@solid-primitives/workers": "^0.4.0", "@solidjs/meta": "^0.29.4", diff --git a/src/lib/decryptor.ts b/src/lib/backup-decryptor.ts similarity index 80% rename from src/lib/decryptor.ts rename to src/lib/backup-decryptor.ts index 1ad2d8f..86c13e5 100644 --- a/src/lib/decryptor.ts +++ b/src/lib/backup-decryptor.ts @@ -1,7 +1,4 @@ -import { - BackupDecryptor, - type DecryptionResult, -} from "@duskflower/signal-decrypt-backup-wasm"; +import { BackupDecryptor } from "@duskflower/signal-decrypt-backup-wasm"; const CHUNK_SIZE = 1024 * 1024 * 40; // 40MB chunks @@ -9,7 +6,8 @@ export async function decryptBackup( file: File, passphrase: string, progressCallback: (progress: number) => void, -): Promise { + statementsCallback?: (statements: string[]) => void | Promise, +): Promise { const fileSize = file.size; const decryptor = new BackupDecryptor(); decryptor.set_progress_callback(fileSize, progressCallback); @@ -34,6 +32,8 @@ export async function decryptBackup( } } + await statementsCallback?.(decryptor.get_new_decrypted_statements()); + offset += CHUNK_SIZE; } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index fa27c30..125426a 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -7,7 +7,7 @@ import { Flex } from "~/components/ui/flex"; import { Progress, ProgressLabel, ProgressValueLabel } from "~/components/ui/progress"; import { loadDb } from "~/db"; -import { decryptBackup } from "~/lib/decryptor"; +import { decryptBackup } from "~/lib/backup-decryptor"; import { createDropzone, createFileUploader } from "@solid-primitives/upload"; import { Button } from "~/components/ui/button"; import { TextField, TextFieldInput, TextFieldLabel } from "~/components/ui/text-field"; @@ -53,19 +53,23 @@ export const Home: Component = () => { // setDbHash(hash); - decryptBackup(currentBackupFile, currentPassphrase, setDecryptionProgress) - .then(async (decrypted) => { + console.time(); + decryptBackup(currentBackupFile, currentPassphrase, setDecryptionProgress, async (statements) => { + await loadDb(statements); + }) + .then(() => { umami.track("Decrypt backup"); setDecryptionProgress(undefined); // setIsLoadingDatabase(true); - setLoadingProgress(0); + // setLoadingProgress(0); - await loadDb(decrypted.database_statements, setLoadingProgress); + // await loadDb(decrypted.database_statements, setLoadingProgress); umami.track("Load database"); // setIsLoadingDatabase(false); - setLoadingProgress(undefined); + // setLoadingProgress(undefined); + console.timeEnd(); navigate("/overview"); }) .catch((error) => { From 12094316ee98eac9f4e1b2d8373f5acc1ee7a6df Mon Sep 17 00:00:00 2001 From: duskflower Date: Fri, 24 Jan 2025 18:10:00 +0100 Subject: [PATCH 2/3] feat: add new progress display for parallel loading --- src/pages/home.tsx | 56 +++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 125426a..4d79e75 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -1,16 +1,14 @@ -import { useNavigate, type RouteSectionProps } from "@solidjs/router"; -import { createSignal, type JSX, Show, type Component } from "solid-js"; - +import { createDropzone, createFileUploader } from "@solid-primitives/upload"; import { Title } from "@solidjs/meta"; +import { type RouteSectionProps, useNavigate } from "@solidjs/router"; +import { type Component, type JSX, Show, createSignal } from "solid-js"; import { Portal } from "solid-js/web"; +import { Button } from "~/components/ui/button"; import { Flex } from "~/components/ui/flex"; - import { Progress, ProgressLabel, ProgressValueLabel } from "~/components/ui/progress"; +import { TextField, TextFieldInput, TextFieldLabel } from "~/components/ui/text-field"; import { loadDb } from "~/db"; import { decryptBackup } from "~/lib/backup-decryptor"; -import { createDropzone, createFileUploader } from "@solid-primitives/upload"; -import { Button } from "~/components/ui/button"; -import { TextField, TextFieldInput, TextFieldLabel } from "~/components/ui/text-field"; export const Home: Component = () => { const navigate = useNavigate(); @@ -34,8 +32,8 @@ export const Home: Component = () => { const [backupFile, setBackupFile] = createSignal(); const [decryptionProgress, setDecryptionProgress] = createSignal(); - const [loadingProgress, setLoadingProgress] = createSignal(); - // const [isLoadingDatabase, setIsLoadingDatabase] = createSignal(false); + const [totalStatements, setTotalStatements] = createSignal(0); + const [executedStatements, setExecutedStatements] = createSignal(0); const onSubmit: JSX.EventHandler = (event) => { event.preventDefault(); @@ -44,31 +42,21 @@ export const Home: Component = () => { const currentPassphrase = passphrase(); if (currentBackupFile && currentPassphrase) { - // const hashChunk = await currentBackupFile.slice(-1000).text(); - // const hash = hashString(hashChunk); - - // if (hash === dbHash()) { - // return; - // } - - // setDbHash(hash); - console.time(); decryptBackup(currentBackupFile, currentPassphrase, setDecryptionProgress, async (statements) => { - await loadDb(statements); + const length = statements.length; + setTotalStatements((oldValue) => oldValue + length); + + await loadDb(statements, (progress) => { + setExecutedStatements((oldValue) => Math.round(oldValue + (progress / 100) * length)); + }); + + setExecutedStatements((oldValue) => oldValue + length); }) .then(() => { umami.track("Decrypt backup"); - setDecryptionProgress(undefined); - // setIsLoadingDatabase(true); - // setLoadingProgress(0); - - // await loadDb(decrypted.database_statements, setLoadingProgress); umami.track("Load database"); - // setIsLoadingDatabase(false); - // setLoadingProgress(undefined); - console.timeEnd(); navigate("/overview"); }) @@ -88,7 +76,7 @@ export const Home: Component = () => { class="fixed inset-0 gap-y-8 backdrop-blur-lg backdrop-filter" classList={{ // hidden: decryptionProgress() === undefined && !isLoadingDatabase(), - hidden: decryptionProgress() === undefined && loadingProgress() === undefined, + hidden: decryptionProgress() === undefined && totalStatements() === 0, }} > @@ -101,20 +89,18 @@ export const Home: Component = () => { class="w-[300px] space-y-1" >
- Processing... + Decrypting...
- - {/*

Loading database

-

This can take some time

*/} +

Loading database

`${value}%`} + maxValue={totalStatements()} + getValueLabel={({ value, max }) => `${value} of ${max}`} class="w-[300px] space-y-1" >
From 5a49648e64fe032e91ea5d20d44cf36df1c6048b Mon Sep 17 00:00:00 2001 From: duskflower Date: Fri, 24 Jan 2025 18:10:10 +0100 Subject: [PATCH 3/3] fmt: sort imports --- .vscode/settings.json | 3 +- bun.lock | 82 ++++++++++---------- src/App.tsx | 11 ++- src/db/db-queries.ts | 6 +- src/db/db.ts | 6 +- src/lib/kysely-official-wasm-worker/index.ts | 9 +-- src/lib/messages-worker.ts | 2 +- src/lib/messages.ts | 2 +- src/pages/dm/dm-id.tsx | 25 +++--- src/pages/dm/dm-messages-per-date.tsx | 2 +- src/pages/dm/dm-messages-per-daytime.tsx | 4 +- src/pages/dm/dm-messages-per-month.tsx | 2 +- src/pages/dm/dm-messages-per-recipients.tsx | 2 +- src/pages/dm/dm-messages-per-weekday.tsx | 2 +- src/pages/dm/dm-overview.tsx | 4 +- src/pages/dm/dm-wordcloud.tsx | 2 +- src/pages/group/group-id.tsx | 2 +- src/pages/overview/index.tsx | 8 +- src/pages/overview/overview-table.tsx | 15 ++-- vite.config.ts | 2 +- 20 files changed, 89 insertions(+), 102 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 84a28bd..f693212 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "editor.codeActionsOnSave": { - "quickfix.biome": "explicit" + "quickfix.biome": "explicit", + "source.organizeImports.biome": "explicit" }, "typescript.inlayHints.parameterNames.enabled": "all", "[typescript]": { diff --git a/bun.lock b/bun.lock index b31794b..38fc1e5 100644 --- a/bun.lock +++ b/bun.lock @@ -4,49 +4,49 @@ "": { "name": "signalstats", "dependencies": { - "@duskflower/signal-decrypt-backup-wasm": "latest", - "@kobalte/core": "latest", - "@kobalte/tailwindcss": "latest", - "@solid-primitives/refs": "latest", - "@solid-primitives/storage": "latest", - "@solid-primitives/upload": "latest", - "@solid-primitives/workers": "latest", - "@solidjs/meta": "latest", - "@solidjs/router": "latest", - "@sqlite.org/sqlite-wasm": "latest", - "@tanstack/solid-table": "latest", - "@types/umami": "latest", - "chart.js": "latest", - "chartjs-chart-wordcloud": "latest", - "chartjs-plugin-deferred": "latest", - "chartjs-plugin-zoom": "latest", - "class-variance-authority": "latest", - "clsx": "latest", - "date-fns": "latest", - "kysely": "latest", - "kysely-wasm": "latest", - "lucide-solid": "latest", - "seroval": "latest", - "solid-js": "latest", - "tailwind-merge": "latest", - "tailwindcss-animate": "latest", - "zen-mitt": "latest", + "@duskflower/signal-decrypt-backup-wasm": "^0.3.0", + "@kobalte/core": "^0.13.7", + "@kobalte/tailwindcss": "^0.9.0", + "@solid-primitives/refs": "^1.1.0", + "@solid-primitives/storage": "^4.3.1", + "@solid-primitives/upload": "^0.1.0", + "@solid-primitives/workers": "^0.4.0", + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.15.3", + "@sqlite.org/sqlite-wasm": "3.48.0-build3", + "@tanstack/solid-table": "^8.20.5", + "@types/umami": "^2.10.0", + "chart.js": "^4.4.7", + "chartjs-chart-wordcloud": "^4.4.4", + "chartjs-plugin-deferred": "^2.0.0", + "chartjs-plugin-zoom": "^2.2.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "date-fns": "^4.1.0", + "kysely": "^0.27.5", + "kysely-wasm": "^0.7.0", + "lucide-solid": "^0.474.0", + "seroval": "^1.2.0", + "solid-js": "^1.9.4", + "tailwind-merge": "^2.6.0", + "tailwindcss-animate": "^1.0.7", + "zen-mitt": "^3.0.0", }, "devDependencies": { - "@biomejs/biome": "latest", - "@commitlint/cli": "latest", - "@commitlint/config-conventional": "latest", - "@tailwindcss/vite": "latest", - "@types/node": "latest", - "better-sqlite3": "latest", - "husky": "latest", - "kysely-codegen": "latest", - "lint-staged": "latest", - "tailwindcss": "latest", - "typescript": "latest", - "vite": "latest", - "vite-plugin-solid": "latest", - "vite-plugin-wasm": "latest", + "@biomejs/biome": "1.9.4", + "@commitlint/cli": "^19.6.1", + "@commitlint/config-conventional": "^19.6.0", + "@tailwindcss/vite": "^4.0.0", + "@types/node": "^22.10.10", + "better-sqlite3": "^11.8.1", + "husky": "^9.1.7", + "kysely-codegen": "^0.17.0", + "lint-staged": "^15.4.2", + "tailwindcss": "^4.0.0", + "typescript": "^5.7.3", + "vite": "^6.0.11", + "vite-plugin-solid": "^2.11.0", + "vite-plugin-wasm": "^3.4.1", }, }, }, diff --git a/src/App.tsx b/src/App.tsx index 4ae175b..cdf0433 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,15 @@ import { A, Route, Router, useNavigate } from "@solidjs/router"; -import { createEffect, Show, Suspense, type Component } from "solid-js"; -import { DmId, GroupId, Home, Overview, preloadDmId, Privacy } from "./pages"; - +import { type Component, Show, Suspense, createEffect } from "solid-js"; +import { DmId, GroupId, Home, Overview, Privacy, preloadDmId } from "./pages"; import "./app.css"; +import { ColorModeProvider, ColorModeScript, createLocalStorageManager } from "@kobalte/core"; import { MetaProvider } from "@solidjs/meta"; import { Portal } from "solid-js/web"; -import { Callout, CalloutTitle, CalloutContent } from "./components/ui/callout"; +import { Callout, CalloutContent, CalloutTitle } from "./components/ui/callout"; +import { ModeToggle } from "./components/ui/mode-toggle"; import { dbLoaded } from "./db"; import { hasCashedData } from "./lib/db-cache"; import { isWasmSupported } from "./lib/utils"; -import { ColorModeProvider, ColorModeScript, createLocalStorageManager } from "@kobalte/core"; -import { ModeToggle } from "./components/ui/mode-toggle"; const NO_DATA_NEEDED_PAGES = ["/", "/privacy"]; diff --git a/src/db/db-queries.ts b/src/db/db-queries.ts index 4d1a87a..7193de8 100644 --- a/src/db/db-queries.ts +++ b/src/db/db-queries.ts @@ -1,7 +1,7 @@ -import { sql, type NotNull } from "kysely"; -import { worker, kyselyDb, SELF_ID, DB_FILENAME, setDbLoaded } from "./db"; -import { cached, clearDbCache } from "../lib/db-cache"; +import { type NotNull, sql } from "kysely"; import type { MainToWorkerMsg, WorkerToMainMsg } from "~/lib/kysely-official-wasm-worker/type"; +import { cached, clearDbCache } from "../lib/db-cache"; +import { DB_FILENAME, SELF_ID, kyselyDb, setDbLoaded, worker } from "./db"; export const loadDb = async (statements: string[], progressCallback?: (percentage: number) => void): Promise => { // try to persist storage, https://web.dev/articles/persistent-storage#request_persistent_storage diff --git a/src/db/db.ts b/src/db/db.ts index 584b868..b2168a7 100644 --- a/src/db/db.ts +++ b/src/db/db.ts @@ -1,8 +1,8 @@ import { Kysely } from "kysely"; -import type { DB } from "./db-schema"; -import { OfficialWasmWorkerDialect } from "~/lib/kysely-official-wasm-worker"; -import WasmWorker from "./db-worker?worker"; import { createSignal } from "solid-js"; +import { OfficialWasmWorkerDialect } from "~/lib/kysely-official-wasm-worker"; +import type { DB } from "./db-schema"; +import WasmWorker from "./db-worker?worker"; export const SELF_ID = 2; diff --git a/src/lib/kysely-official-wasm-worker/index.ts b/src/lib/kysely-official-wasm-worker/index.ts index 1886c71..9af4767 100644 --- a/src/lib/kysely-official-wasm-worker/index.ts +++ b/src/lib/kysely-official-wasm-worker/index.ts @@ -1,11 +1,4 @@ -import type { - DatabaseIntrospector, - Dialect, - DialectAdapter, - Driver, - Kysely, - QueryCompiler, -} from "kysely"; +import type { DatabaseIntrospector, Dialect, DialectAdapter, Driver, Kysely, QueryCompiler } from "kysely"; import { SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from "kysely"; import { OfficialWasmWorkerDriver } from "./driver"; import type { OfficialWasmWorkerDialectConfig } from "./type"; diff --git a/src/lib/messages-worker.ts b/src/lib/messages-worker.ts index d4cb339..94dff12 100644 --- a/src/lib/messages-worker.ts +++ b/src/lib/messages-worker.ts @@ -1,5 +1,5 @@ -import { getHourList, getMonthList, getWeekdayList } from "./date"; import type { MessageOverview, MessageStats, Recipients } from "~/types"; +import { getHourList, getMonthList, getWeekdayList } from "./date"; const hourNames = getHourList(); diff --git a/src/lib/messages.ts b/src/lib/messages.ts index 51c1539..f84d15a 100644 --- a/src/lib/messages.ts +++ b/src/lib/messages.ts @@ -1,6 +1,6 @@ import type { MessageOverview, MessageStats, Recipients } from "~/types"; -import { cached } from "./db-cache"; import { getHourList, getMonthList, getWeekdayList } from "./date"; +import { cached } from "./db-cache"; import MessageStatsWorker from "./messages-worker?worker"; export const hourNames = getHourList(); diff --git a/src/pages/dm/dm-id.tsx b/src/pages/dm/dm-id.tsx index 91d884a..6ee94fd 100644 --- a/src/pages/dm/dm-id.tsx +++ b/src/pages/dm/dm-id.tsx @@ -1,21 +1,20 @@ -import { Suspense, type Component } from "solid-js"; -import { createAsync, type RoutePreloadFunc, type RouteSectionProps } from "@solidjs/router"; - -import { dmPartnerRecipientQuery, threadMostUsedWordsQuery, threadSentMessagesOverviewQuery, SELF_ID } from "~/db"; -import { getNameFromRecipient } from "~/lib/get-name-from-recipient"; -import { Heading } from "~/components/ui/heading"; -import { Grid } from "~/components/ui/grid"; import { Title } from "@solidjs/meta"; +import { type RoutePreloadFunc, type RouteSectionProps, createAsync } from "@solidjs/router"; +import { type Component, Suspense } from "solid-js"; +import { Flex } from "~/components/ui/flex"; +import { Grid } from "~/components/ui/grid"; +import { Heading } from "~/components/ui/heading"; +import { SELF_ID, dmPartnerRecipientQuery, threadMostUsedWordsQuery, threadSentMessagesOverviewQuery } from "~/db"; +import { getNameFromRecipient } from "~/lib/get-name-from-recipient"; +import { createMessageStatsSources } from "~/lib/messages"; +import type { MessageOverview } from "~/types"; import { DmMessagesPerDate } from "./dm-messages-per-date"; -import { DmOverview } from "./dm-overview"; -import { DmWordCloud } from "./dm-wordcloud"; -import { DmMessagesPerMonth } from "./dm-messages-per-month"; import { DmMessagesPerDaytime } from "./dm-messages-per-daytime"; +import { DmMessagesPerMonth } from "./dm-messages-per-month"; import { DmMessagesPerRecipient } from "./dm-messages-per-recipients"; import { DmMessagesPerWeekday } from "./dm-messages-per-weekday"; -import type { MessageOverview } from "~/types"; -import { createMessageStatsSources } from "~/lib/messages"; -import { Flex } from "~/components/ui/flex"; +import { DmOverview } from "./dm-overview"; +import { DmWordCloud } from "./dm-wordcloud"; const getDmIdData = (dmId: number) => { // the other person in the chat with name and id diff --git a/src/pages/dm/dm-messages-per-date.tsx b/src/pages/dm/dm-messages-per-date.tsx index 9d3aea7..5e0a967 100644 --- a/src/pages/dm/dm-messages-per-date.tsx +++ b/src/pages/dm/dm-messages-per-date.tsx @@ -1,5 +1,5 @@ -import { Show, type Accessor, type Component } from "solid-js"; import type { ChartData } from "chart.js"; +import { type Accessor, type Component, Show } from "solid-js"; import { LineChart } from "~/components/ui/charts"; import type { MessageStats, Recipients } from "~/types"; diff --git a/src/pages/dm/dm-messages-per-daytime.tsx b/src/pages/dm/dm-messages-per-daytime.tsx index 1c12ff5..39765aa 100644 --- a/src/pages/dm/dm-messages-per-daytime.tsx +++ b/src/pages/dm/dm-messages-per-daytime.tsx @@ -1,8 +1,8 @@ -import { Show, type Accessor, type Component } from "solid-js"; import type { ChartData } from "chart.js"; +import { type Accessor, type Component, Show } from "solid-js"; import { BarChart } from "~/components/ui/charts"; -import type { MessageStats, Recipients } from "~/types"; import { hourNames } from "~/lib/messages"; +import type { MessageStats, Recipients } from "~/types"; export const DmMessagesPerDaytime: Component<{ daytimeStats: MessageStats["daytime"] | undefined; diff --git a/src/pages/dm/dm-messages-per-month.tsx b/src/pages/dm/dm-messages-per-month.tsx index 7bcceaf..762b6a1 100644 --- a/src/pages/dm/dm-messages-per-month.tsx +++ b/src/pages/dm/dm-messages-per-month.tsx @@ -1,5 +1,5 @@ -import { Show, type Accessor, type Component } from "solid-js"; import type { ChartData } from "chart.js"; +import { type Accessor, type Component, Show } from "solid-js"; import { RadarChart } from "~/components/ui/charts"; import { monthNames } from "~/lib/messages"; import type { MessageStats, Recipients } from "~/types"; diff --git a/src/pages/dm/dm-messages-per-recipients.tsx b/src/pages/dm/dm-messages-per-recipients.tsx index 8d43409..4639183 100644 --- a/src/pages/dm/dm-messages-per-recipients.tsx +++ b/src/pages/dm/dm-messages-per-recipients.tsx @@ -1,5 +1,5 @@ -import { Show, type Accessor, type Component } from "solid-js"; import type { ChartData } from "chart.js"; +import { type Accessor, type Component, Show } from "solid-js"; import { PieChart } from "~/components/ui/charts"; import type { MessageStats, Recipients } from "~/types"; diff --git a/src/pages/dm/dm-messages-per-weekday.tsx b/src/pages/dm/dm-messages-per-weekday.tsx index 4608298..1d66a81 100644 --- a/src/pages/dm/dm-messages-per-weekday.tsx +++ b/src/pages/dm/dm-messages-per-weekday.tsx @@ -1,5 +1,5 @@ -import { Show, type Accessor, type Component } from "solid-js"; import type { ChartData } from "chart.js"; +import { type Accessor, type Component, Show } from "solid-js"; import { RadarChart } from "~/components/ui/charts"; import { weekdayNames } from "~/lib/messages"; import type { MessageStats, Recipients } from "~/types"; diff --git a/src/pages/dm/dm-overview.tsx b/src/pages/dm/dm-overview.tsx index 1a1b464..e2aa17b 100644 --- a/src/pages/dm/dm-overview.tsx +++ b/src/pages/dm/dm-overview.tsx @@ -1,7 +1,7 @@ -import { Show, type Component } from "solid-js"; +import { CalendarArrowDown, CalendarArrowUp, CalendarClock, MessagesSquare } from "lucide-solid"; +import { type Component, Show } from "solid-js"; import { Flex } from "~/components/ui/flex"; import { Grid } from "~/components/ui/grid"; -import { CalendarArrowDown, CalendarArrowUp, CalendarClock, MessagesSquare } from "lucide-solid"; import { getDistanceBetweenDatesInDays } from "~/lib/date"; import type { MessageOverview } from "~/types"; diff --git a/src/pages/dm/dm-wordcloud.tsx b/src/pages/dm/dm-wordcloud.tsx index bd24624..e6237e8 100644 --- a/src/pages/dm/dm-wordcloud.tsx +++ b/src/pages/dm/dm-wordcloud.tsx @@ -1,5 +1,5 @@ import type { ChartData } from "chart.js"; -import { Show, type Accessor, type Component } from "solid-js"; +import { type Accessor, type Component, Show } from "solid-js"; import { WordCloudChart } from "~/components/ui/charts"; import type { threadMostUsedWordsQuery } from "~/db"; diff --git a/src/pages/group/group-id.tsx b/src/pages/group/group-id.tsx index 3ac5993..fa95ecc 100644 --- a/src/pages/group/group-id.tsx +++ b/src/pages/group/group-id.tsx @@ -1,5 +1,5 @@ -import type { Component } from "solid-js"; import type { RouteSectionProps } from "@solidjs/router"; +import type { Component } from "solid-js"; export const GroupId: Component = (props) => { const groupId = () => Number(props.params.groupid); diff --git a/src/pages/overview/index.tsx b/src/pages/overview/index.tsx index 61e52b6..423bf37 100644 --- a/src/pages/overview/index.tsx +++ b/src/pages/overview/index.tsx @@ -1,9 +1,7 @@ -import type { RouteSectionProps } from "@solidjs/router"; -import { type Component, createResource, Show } from "solid-js"; - -import { allThreadsOverviewQuery, overallSentMessagesQuery, SELF_ID } from "~/db"; - import { Title } from "@solidjs/meta"; +import type { RouteSectionProps } from "@solidjs/router"; +import { type Component, Show, createResource } from "solid-js"; +import { SELF_ID, allThreadsOverviewQuery, overallSentMessagesQuery } from "~/db"; import { getNameFromRecipient } from "~/lib/get-name-from-recipient"; import { OverviewTable, type RoomOverview } from "./overview-table"; diff --git a/src/pages/overview/overview-table.tsx b/src/pages/overview/overview-table.tsx index d0533e0..1ae9656 100644 --- a/src/pages/overview/overview-table.tsx +++ b/src/pages/overview/overview-table.tsx @@ -1,32 +1,29 @@ -import { type Component, createSignal, For, Match, Show, Switch } from "solid-js"; import { useNavigate, usePreloadRoute } from "@solidjs/router"; - import { type ColumnFiltersState, + type FilterFn, + type SortDirection, + type SortingState, createColumnHelper, createSolidTable, - type FilterFn, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, - type SortDirection, - type SortingState, } from "@tanstack/solid-table"; import { intlFormatDistance } from "date-fns"; import { ArrowDown, ArrowUp, ArrowUpDown } from "lucide-solid"; - +import { type Component, For, Match, Show, Switch, createSignal } from "solid-js"; import { Badge } from "~/components/ui/badge"; import { Button } from "~/components/ui/button"; import { Checkbox } from "~/components/ui/checkbox"; +import { Flex } from "~/components/ui/flex"; import { Label } from "~/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table"; import { TextField, TextFieldInput } from "~/components/ui/text-field"; - -import { cn } from "~/lib/utils"; -import { Flex } from "~/components/ui/flex"; import { dbLoaded, threadSentMessagesOverviewQuery } from "~/db"; +import { cn } from "~/lib/utils"; export interface RoomOverview { threadId: number; diff --git a/vite.config.ts b/vite.config.ts index c9270f0..d086c34 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,8 @@ import path from "path"; +import tailwind from "@tailwindcss/vite"; import { defineConfig } from "vite"; import solidPlugin from "vite-plugin-solid"; import wasm from "vite-plugin-wasm"; -import tailwind from "@tailwindcss/vite"; export default defineConfig({ plugins: [solidPlugin(), wasm(), tailwind()],