diff --git a/src/App.tsx b/src/App.tsx index a224bd4..02f2f9b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,18 +1,104 @@ -import { Route } from "@solidjs/router"; -import { type Component } from "solid-js"; +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 "./app.css"; +import { MetaProvider } from "@solidjs/meta"; +import { Portal } from "solid-js/web"; +import { Callout, CalloutTitle, CalloutContent } from "./components/ui/callout"; +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"]; const App: Component = () => { + const storageManager = createLocalStorageManager("vite-ui-theme"); return ( - <> - - - - - - +
+ + { + const navigate = useNavigate(); + + createEffect(() => { + if (!dbLoaded() && !hasCashedData() && !NO_DATA_NEEDED_PAGES.includes(props.location.pathname)) { + navigate("/"); + } + }); + + const wasmSupport = isWasmSupported(); + + return ( + <> + + +
+ +
+ + +
+ + Your browser does not support WebAssembly, which is required for this site to work with the + big amount of data a signal backup contains. +
+ Please try a different browser. +
+
+
+
+ + + There is currently no backup database loaded, but you can watch statistics that have been + cached, meaning only chats you already opened or chats that were preloaded. +
+ { + umami.track("Watch cached statistics"); + }} + > + Watch cached statistics + +
+
+ } + > + + You are watching cached statistics + + Currently there is no backup database loaded. You can only watch statistics that have been + cached, meaning only chats you already opened or chats that were preloaded. +
+ Load a backup +
+
+ +
+ {props.children} +
+ +
+ + ); + }} + > + + + + + {" "} +
+
+
); }; diff --git a/src/app.css b/src/app.css index 6f4d1e4..cae59d8 100644 --- a/src/app.css +++ b/src/app.css @@ -28,8 +28,8 @@ --secondary: 240 4.8% 95.9%; --secondary-foreground: 240 5.9% 10%; - --accent: 240 4.8% 95.9%; - --accent-foreground: 240 5.9% 10%; + --accent: 226, 90%, 85%; + --accent-foreground: 226, 90%, 57%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; @@ -59,8 +59,8 @@ --muted: 240 3.7% 15.9%; --muted-foreground: 240 5% 64.9%; - --accent: 240 3.7% 15.9%; - --accent-foreground: 0 0% 98%; + --accent: 226, 90%, 20%; + --accent-foreground: 226, 90%, 57%; --popover: 240 10% 3.9%; --popover-foreground: 0 0% 98%; diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..9ff7a0a --- /dev/null +++ b/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,260 @@ +import type { Component, ComponentProps, JSX, ValidComponent } from "solid-js" +import { splitProps } from "solid-js" + +import * as DropdownMenuPrimitive from "@kobalte/core/dropdown-menu" +import type { PolymorphicProps } from "@kobalte/core/polymorphic" + +import { cn } from "~/lib/utils" + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger +const DropdownMenuPortal = DropdownMenuPrimitive.Portal +const DropdownMenuSub = DropdownMenuPrimitive.Sub +const DropdownMenuGroup = DropdownMenuPrimitive.Group +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenu: Component = (props) => { + return +} + +type DropdownMenuContentProps = + DropdownMenuPrimitive.DropdownMenuContentProps & { + class?: string | undefined + } + +const DropdownMenuContent = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuContentProps, ["class"]) + return ( + + + + ) +} + +type DropdownMenuItemProps = + DropdownMenuPrimitive.DropdownMenuItemProps & { + class?: string | undefined + } + +const DropdownMenuItem = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuItemProps, ["class"]) + return ( + + ) +} + +const DropdownMenuShortcut: Component> = (props) => { + const [, rest] = splitProps(props, ["class"]) + return +} + +const DropdownMenuLabel: Component & { inset?: boolean }> = (props) => { + const [, rest] = splitProps(props, ["class", "inset"]) + return ( +
+ ) +} + +type DropdownMenuSeparatorProps = + DropdownMenuPrimitive.DropdownMenuSeparatorProps & { + class?: string | undefined + } + +const DropdownMenuSeparator = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuSeparatorProps, ["class"]) + return ( + + ) +} + +type DropdownMenuSubTriggerProps = + DropdownMenuPrimitive.DropdownMenuSubTriggerProps & { + class?: string | undefined + children?: JSX.Element + } + +const DropdownMenuSubTrigger = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuSubTriggerProps, ["class", "children"]) + return ( + + {props.children} + + + + + ) +} + +type DropdownMenuSubContentProps = + DropdownMenuPrimitive.DropdownMenuSubContentProps & { + class?: string | undefined + } + +const DropdownMenuSubContent = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuSubContentProps, ["class"]) + return ( + + ) +} + +type DropdownMenuCheckboxItemProps = + DropdownMenuPrimitive.DropdownMenuCheckboxItemProps & { + class?: string | undefined + children?: JSX.Element + } + +const DropdownMenuCheckboxItem = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuCheckboxItemProps, ["class", "children"]) + return ( + + + + + + + + + {props.children} + + ) +} + +type DropdownMenuGroupLabelProps = + DropdownMenuPrimitive.DropdownMenuGroupLabelProps & { + class?: string | undefined + } + +const DropdownMenuGroupLabel = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuGroupLabelProps, ["class"]) + return ( + + ) +} + +type DropdownMenuRadioItemProps = + DropdownMenuPrimitive.DropdownMenuRadioItemProps & { + class?: string | undefined + children?: JSX.Element + } + +const DropdownMenuRadioItem = ( + props: PolymorphicProps> +) => { + const [, rest] = splitProps(props as DropdownMenuRadioItemProps, ["class", "children"]) + return ( + + + + + + + + + {props.children} + + ) +} + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuPortal, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuShortcut, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, + DropdownMenuCheckboxItem, + DropdownMenuGroup, + DropdownMenuGroupLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem +} diff --git a/src/components/ui/mode-toggle.tsx b/src/components/ui/mode-toggle.tsx new file mode 100644 index 0000000..271f8cc --- /dev/null +++ b/src/components/ui/mode-toggle.tsx @@ -0,0 +1,33 @@ +import { useColorMode } from "@kobalte/core"; + +import { Button } from "./button"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./dropdown-menu"; +import { Sun, Moon, Laptop } from "lucide-solid"; + +export function ModeToggle() { + const { setColorMode } = useColorMode(); + + return ( + + } variant="ghost" size="sm" class="w-9 px-0"> + + + Toggle theme + + + setColorMode("light")}> + + Light + + setColorMode("dark")}> + + Dark + + setColorMode("system")}> + + System + + + + ); +} diff --git a/src/index.tsx b/src/index.tsx index f79407a..5d6f8e4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,14 +1,5 @@ -/* @refresh reload */ -import { MetaProvider } from "@solidjs/meta"; -import { Router, useNavigate } from "@solidjs/router"; -import { Portal, render } from "solid-js/web"; +import { render } from "solid-js/web"; import App from "./App"; -import { hasCashedData } from "./lib/db-cache"; -import { createEffect, Show } from "solid-js"; -import { dbLoaded } from "./db"; -import { Callout, CalloutContent, CalloutTitle } from "./components/ui/callout"; -import { A } from "./components/ui/A"; -import { isWasmSupported } from "./lib/utils"; const root = document.getElementById("root"); @@ -26,82 +17,6 @@ if (import.meta.env.DEV && !("umami" in window)) { }; } -const NO_DATA_NEEDED_PAGES = ["/", "/privacy"]; - if (root) { - render( - () => ( -
- - { - const navigate = useNavigate(); - - createEffect(() => { - if (!dbLoaded() && !hasCashedData() && !NO_DATA_NEEDED_PAGES.includes(props.location.pathname)) { - navigate("/"); - } - }); - - const wasmSupport = isWasmSupported(); - - return ( - <> - - -
- - Your browser does not support WebAssembly, which is required for this site to work with the - big amount of data a signal backup contains. -
- Please try a different browser. -
-
-
-
- - - There is currently no backup database loaded, but you can watch statistics that have been - cached, meaning only chats you already opened or chats that were preloaded. -
- { - umami.track("Watch cached statistics"); - }} - > - Watch cached statistics - -
-
- } - > - - You are watching cached statistics - - Currently there is no backup database loaded. You can only watch statistics that have been - cached, meaning only chats you already opened or chats that were preloaded. -
- Load a backup -
-
- -
{props.children}
- - - ); - }} - > - -
-
-
- ), - root, - ); + render(() => , root); } diff --git a/src/pages/dm/dm-messages-per-date.tsx b/src/pages/dm/dm-messages-per-date.tsx index d87d4ce..9d3aea7 100644 --- a/src/pages/dm/dm-messages-per-date.tsx +++ b/src/pages/dm/dm-messages-per-date.tsx @@ -21,6 +21,8 @@ export const DmMessagesPerDate: Component<{ label: "Total", data: currentDmMessagesValues.map((row) => row.totalMessages), borderWidth: 2, + pointRadius: 0, + pointHitRadius: 6, }, ...currentRecipients.map((recipient) => { return { @@ -28,6 +30,8 @@ export const DmMessagesPerDate: Component<{ label: recipient.name.toString(), data: currentDmMessagesValues.map((date) => date[recipient.recipientId]), borderWidth: 2, + pointRadius: 0, + pointHitRadius: 6, }; }), ], @@ -41,7 +45,7 @@ export const DmMessagesPerDate: Component<{ )} diff --git a/src/pages/dm/dm-overview.tsx b/src/pages/dm/dm-overview.tsx index 5232def..1a1b464 100644 --- a/src/pages/dm/dm-overview.tsx +++ b/src/pages/dm/dm-overview.tsx @@ -23,7 +23,7 @@ export const DmOverview: Component<{ }; return ( - + diff --git a/src/pages/home.tsx b/src/pages/home.tsx index f966207..fa27c30 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -122,16 +122,16 @@ export const Home: Component = () => { Signal stats -
+ setPassphrase(value)}> Passphrase - + = () => { {backupFile() ? backupFile()?.name : "or drop the file here"} -