feat: use official wasm in worker and cached data info / warning
This commit is contained in:
parent
a2bc4115a2
commit
ff23486fd2
21 changed files with 492 additions and 398 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
|
|
|
@ -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()}>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue