feat: use official wasm in worker and cached data info / warning

This commit is contained in:
Samuel 2025-01-21 20:18:39 +01:00
parent 36ff7afa4a
commit 851f19e82e
21 changed files with 492 additions and 398 deletions

View file

@ -6,7 +6,7 @@ import { Portal } from "solid-js/web";
import { Flex } from "~/components/ui/flex";
import { Progress, ProgressLabel, ProgressValueLabel } from "~/components/ui/progress";
import { loadDb } from "~/db/db-queries";
import { loadDb } from "~/db";
import { decryptBackup } from "~/lib/decryptor";
import { createDropzone, createFileUploader } from "@solid-primitives/upload";
import { Button } from "~/components/ui/button";
@ -37,29 +37,38 @@ export const Home: Component<RouteSectionProps> = () => {
const [loadingProgress, setLoadingProgress] = createSignal<number>();
// const [isLoadingDatabase, setIsLoadingDatabase] = createSignal(false);
const onSubmit: JSX.EventHandler<HTMLFormElement, SubmitEvent> = (event) => {
const onSubmit: JSX.EventHandler<HTMLFormElement, SubmitEvent> = async (event) => {
event.preventDefault();
const currentBackupFile = backupFile();
const currentPassphrase = passphrase();
if (currentBackupFile && currentPassphrase) {
decryptBackup(currentBackupFile, currentPassphrase, setDecryptionProgress)
.then(async (result) => {
setDecryptionProgress(undefined);
// setIsLoadingDatabase(true);
setLoadingProgress(0);
// const hashChunk = await currentBackupFile.slice(-1000).text();
// const hash = hashString(hashChunk);
await loadDb(result.database_statements, (newValue) => (console.log(newValue), setLoadingProgress(newValue)));
// if (hash === dbHash()) {
// return;
// }
// setIsLoadingDatabase(false);
setLoadingProgress(undefined);
// setDbHash(hash);
navigate("/overview");
})
.catch((error) => {
console.error("Decryption failed:", error);
});
try {
const decrypted = await decryptBackup(currentBackupFile, currentPassphrase, setDecryptionProgress);
setDecryptionProgress(undefined);
// setIsLoadingDatabase(true);
setLoadingProgress(0);
await loadDb(decrypted.database_statements, setLoadingProgress);
// setIsLoadingDatabase(false);
setLoadingProgress(undefined);
navigate("/overview");
} catch (error) {
console.error("Decryption failed:", error);
}
}
};

View file

@ -11,7 +11,9 @@ export const Overview: Component<RouteSectionProps> = () => {
const [allSelfSentMessagesCount] = createResource(() => overallSentMessagesQuery(SELF_ID));
const [roomOverview] = createResource<RoomOverview[] | undefined>(async () => {
return (await allThreadsOverviewQuery())?.map((row) => {
const overview = await allThreadsOverviewQuery();
return overview.map((row) => {
const isGroup = row.title !== null;
let name = "";
@ -41,9 +43,7 @@ export const Overview: Component<RouteSectionProps> = () => {
<div>
<p>All messages: {allSelfSentMessagesCount()?.messageCount as number}</p>
<Show when={!roomOverview.loading && roomOverview()} fallback="Loading...">
{(currentRoomOverview) => (
console.log(currentRoomOverview()), (<OverviewTable data={currentRoomOverview()} />)
)}
{(currentRoomOverview) => <OverviewTable data={currentRoomOverview()} />}
</Show>
</div>
</>

View file

@ -26,6 +26,7 @@ import { TextField, TextFieldInput } from "~/components/ui/text-field";
import { cn } from "~/lib/utils";
import { Flex } from "~/components/ui/flex";
import { dbLoaded, threadSentMessagesOverviewQuery } from "~/db";
export interface RoomOverview {
threadId: number;
@ -55,6 +56,18 @@ const isGroupFilterFn: FilterFn<RoomOverview> = (row, _columnId, filterValue) =>
return !row.original.isGroup;
};
const rowIsAvailable = (threadId: number): boolean => {
if (dbLoaded()) {
return true;
}
if (threadSentMessagesOverviewQuery.hasCacheFor(threadId)) {
return true;
}
return false;
};
const SortingDisplay: Component<{ sorting: false | SortDirection; class?: string; activeClass?: string }> = (props) => {
return (
<Switch>
@ -92,13 +105,14 @@ export const columns = [
cell: (props) => {
const isArchived = props.row.getValue("archived");
const isGroup = props.row.getValue("isGroup");
const isCached = !dbLoaded() && rowIsAvailable(props.row.original.threadId);
return (
<Flex class="w-full" flexDirection="row">
<span class="max-w-2xl overflow-hidden text-ellipsis whitespace-nowrap font-bold">
{props.cell.getValue()}
</span>
<Show when={isArchived || isGroup}>
<Show when={isArchived || isGroup || !isCached}>
<Flex flexDirection="row" class="ml-auto gap-2">
<Show when={isArchived}>
<Badge variant="outline" class="ml-auto">
@ -110,6 +124,11 @@ export const columns = [
Group
</Badge>
</Show>
<Show when={!isCached}>
<Badge variant="outline" class="ml-auto">
Not available
</Badge>
</Show>
</Flex>
</Show>
</Flex>
@ -267,12 +286,12 @@ export const OverviewTable = (props: OverviewTableProps) => {
</div>
<div class="flex items-start space-x-2">
<Checkbox
id="show-archived"
id="show-groups"
checked={(table.getColumn("isGroup")?.getFilterValue() as boolean | undefined) ?? false}
onChange={(value) => table.getColumn("isGroup")?.setFilterValue(value)}
/>
<div class="grid gap-1.5 leading-none">
<Label for="show-archived">Show group chats (detailed analysis not implemented)</Label>
<Label for="show-groups">Show group chats (detailed analysis not implemented)</Label>
</div>
</div>
</div>
@ -315,32 +334,39 @@ export const OverviewTable = (props: OverviewTableProps) => {
{(row) => (
<TableRow
class="cursor-pointer [&:last-of-type>td:first-of-type]:rounded-bl-md [&:last-of-type>td:last-of-type]:rounded-br-md"
classList={{
"text-muted-foreground": !rowIsAvailable(row.original.threadId),
}}
data-state={row.getIsSelected() && "selected"}
onPointerEnter={(event) => {
const threadId = row.original.threadId;
const isGroup = row.original.isGroup;
const preloadTimeout = setTimeout(() => {
preload(`/${isGroup ? "group" : "dm"}/${threadId.toString()}`, {
preloadData: true,
});
}, 20);
if (rowIsAvailable(threadId)) {
const preloadTimeout = setTimeout(() => {
preload(`/${isGroup ? "group" : "dm"}/${threadId.toString()}`, {
preloadData: true,
});
}, 20);
event.currentTarget.addEventListener(
"pointerout",
() => {
clearTimeout(preloadTimeout);
},
{
once: true,
},
);
event.currentTarget.addEventListener(
"pointerout",
() => {
clearTimeout(preloadTimeout);
},
{
once: true,
},
);
}
}}
onClick={() => {
const threadId = row.original.threadId;
const isGroup = row.original.isGroup;
navigate(`/${isGroup ? "group" : "dm"}/${threadId.toString()}`);
if (rowIsAvailable(threadId)) {
navigate(`/${isGroup ? "group" : "dm"}/${threadId.toString()}`);
}
}}
>
<For each={row.getVisibleCells()}>