Scrapboard.org client

feat: add tangled.sh

+94 -8
+5
bun.lock
··· 19 19 "@radix-ui/react-scroll-area": "^1.2.9", 20 20 "@radix-ui/react-slot": "^1.2.3", 21 21 "@radix-ui/react-tabs": "^1.1.12", 22 + "@radix-ui/react-tooltip": "^1.2.7", 22 23 "class-variance-authority": "^0.7.1", 23 24 "clsx": "^2.1.1", 24 25 "cmdk": "^1.1.1", ··· 395 396 396 397 "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw=="], 397 398 399 + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.7", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw=="], 400 + 398 401 "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], 399 402 400 403 "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], ··· 410 413 "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], 411 414 412 415 "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], 416 + 417 + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], 413 418 414 419 "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], 415 420
+1
package.json
··· 27 27 "@radix-ui/react-scroll-area": "^1.2.9", 28 28 "@radix-ui/react-slot": "^1.2.3", 29 29 "@radix-ui/react-tabs": "^1.1.12", 30 + "@radix-ui/react-tooltip": "^1.2.7", 30 31 "class-variance-authority": "^0.7.1", 31 32 "clsx": "^2.1.1", 32 33 "cmdk": "^1.1.1",
+5 -3
src/components/DeleteButton.tsx
··· 97 97 LIST_COLLECTION, 98 98 rkey 99 99 ); 100 - const items = boardItems 101 - .entries() 102 - .filter((e) => AtUri.make(e[1].list).rkey == listUri.rkey); 100 + const items = Array.from( 101 + boardItems 102 + .entries() 103 + .filter((e) => AtUri.make(e[1].list).rkey == listUri.rkey) 104 + ); 103 105 104 106 setTotalItems(items.length + 1); // +1 for the board itself 105 107 setProgress(0);
+61
src/components/ui/tooltip.tsx
··· 1 + "use client" 2 + 3 + import * as React from "react" 4 + import * as TooltipPrimitive from "@radix-ui/react-tooltip" 5 + 6 + import { cn } from "@/lib/utils" 7 + 8 + function TooltipProvider({ 9 + delayDuration = 0, 10 + ...props 11 + }: React.ComponentProps<typeof TooltipPrimitive.Provider>) { 12 + return ( 13 + <TooltipPrimitive.Provider 14 + data-slot="tooltip-provider" 15 + delayDuration={delayDuration} 16 + {...props} 17 + /> 18 + ) 19 + } 20 + 21 + function Tooltip({ 22 + ...props 23 + }: React.ComponentProps<typeof TooltipPrimitive.Root>) { 24 + return ( 25 + <TooltipProvider> 26 + <TooltipPrimitive.Root data-slot="tooltip" {...props} /> 27 + </TooltipProvider> 28 + ) 29 + } 30 + 31 + function TooltipTrigger({ 32 + ...props 33 + }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) { 34 + return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} /> 35 + } 36 + 37 + function TooltipContent({ 38 + className, 39 + sideOffset = 0, 40 + children, 41 + ...props 42 + }: React.ComponentProps<typeof TooltipPrimitive.Content>) { 43 + return ( 44 + <TooltipPrimitive.Portal> 45 + <TooltipPrimitive.Content 46 + data-slot="tooltip-content" 47 + sideOffset={sideOffset} 48 + className={cn( 49 + "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", 50 + className 51 + )} 52 + {...props} 53 + > 54 + {children} 55 + <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" /> 56 + </TooltipPrimitive.Content> 57 + </TooltipPrimitive.Portal> 58 + ) 59 + } 60 + 61 + export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
+22 -5
src/nav/navbar.tsx
··· 3 3 import Link from "next/link"; 4 4 import { Button } from "@/components/ui/button"; 5 5 import { ModeToggle } from "./ModeToggle"; // for dark mode toggle 6 - import { Github, LoaderCircle, Menu, X } from "lucide-react"; 6 + import { Code, Github, LoaderCircle, Menu, X } from "lucide-react"; 7 7 import { useState } from "react"; 8 8 import { useAuth } from "@/lib/hooks/useAuth"; 9 9 import { ··· 27 27 } from "@/components/ui/dropdown-menu"; 28 28 import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; 29 29 import { motion } from "motion/react"; 30 + import { 31 + Tooltip, 32 + TooltipContent, 33 + TooltipTrigger, 34 + } from "@/components/ui/tooltip"; 30 35 31 36 export function Navbar() { 32 37 const [open, setOpen] = useState(false); ··· 63 68 </nav> 64 69 65 70 <div className="flex items-center gap-2"> 66 - <Link target="_blank" href={"https://github.com/Turtlepaw/scribble/"}> 67 - <Button variant="ghost" size="icon" className="cursor-pointer"> 68 - <Github /> 69 - </Button> 71 + <Link 72 + target="_blank" 73 + href={ 74 + "https://tangled.sh/@did:plc:u2grpouz5553mrn4x772pyfa/pin.to.it/" 75 + } 76 + > 77 + <Tooltip> 78 + <TooltipTrigger> 79 + <Button variant="ghost" size="icon" className="cursor-pointer"> 80 + <Code /> 81 + </Button> 82 + </TooltipTrigger> 83 + <TooltipContent> 84 + <p>Source code</p> 85 + </TooltipContent> 86 + </Tooltip> 70 87 </Link> 71 88 <ModeToggle /> 72 89 {session ? (