+69
-5
src/routes/Home.tsx
+69
-5
src/routes/Home.tsx
···
13
13
import { createBackupDir, getBackupDir } from "@/lib/paths";
14
14
import { settingsManager } from "@/lib/settings";
15
15
import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
16
-
import { openPath } from "@tauri-apps/plugin-opener";
16
+
import { openPath, openUrl } from "@tauri-apps/plugin-opener";
17
17
import {
18
18
ChevronDown,
19
19
FileText,
···
25
25
LoaderCircleIcon,
26
26
Package,
27
27
Settings as SettingsIcon,
28
+
SquareArrowOutUpRight,
28
29
User,
29
30
Users,
30
31
} from "lucide-react";
31
32
import { useEffect, useRef, useState } from "react";
32
33
import { toast } from "sonner";
33
34
import Settings from "./Settings";
35
+
import {
36
+
Dialog,
37
+
DialogClose,
38
+
DialogContent,
39
+
DialogDescription,
40
+
DialogFooter,
41
+
DialogHeader,
42
+
DialogTitle,
43
+
DialogTrigger,
44
+
} from "@/components/ui/dialog";
34
45
35
46
export function Home({
36
47
profile,
···
451
462
<div className="flex items-center justify-between mb-2">
452
463
<div className="flex items-center gap-2">
453
464
{getRecordTypeIcon(type)}
454
-
<span className="text-white/80 text-sm font-medium">
455
-
{type}
456
-
</span>
465
+
<Dialog>
466
+
<DialogTrigger className="gap-2 p-0 text-inherit hover:underline flex items-center cursor-pointer">
467
+
<span className="text-white/80 text-sm font-medium">
468
+
{type}
469
+
</span>
470
+
</DialogTrigger>
471
+
<DialogContent>
472
+
<DialogHeader>
473
+
<DialogTitle>
474
+
Open link in browser
475
+
</DialogTitle>
476
+
<DialogDescription>
477
+
This will open the URL in your browser:
478
+
<div className="border-[1.8px] border-[--secondary] rounded-sm px-3 py-2 mt-3 text-base">
479
+
https://
480
+
<span className="font-semibold">
481
+
{getUrlFromNamespace(type)}
482
+
</span>
483
+
</div>
484
+
</DialogDescription>
485
+
<DialogFooter>
486
+
<DialogClose>
487
+
<Button
488
+
variant="outline"
489
+
className="cursor-pointer"
490
+
>
491
+
Cancel
492
+
</Button>
493
+
</DialogClose>
494
+
<DialogClose>
495
+
<Button
496
+
onClick={() =>
497
+
openUrl(
498
+
`https://${getUrlFromNamespace(
499
+
type
500
+
)}`
501
+
)
502
+
}
503
+
className="cursor-pointer"
504
+
>
505
+
Open{" "}
506
+
<SquareArrowOutUpRight size={14} />
507
+
</Button>
508
+
</DialogClose>
509
+
</DialogFooter>
510
+
</DialogHeader>
511
+
</DialogContent>
512
+
</Dialog>
457
513
</div>
458
514
<div className="flex items-center gap-2">
459
515
<span className="text-white font-semibold">
460
516
{count.toLocaleString()}
461
517
</span>
462
-
<span className="text-white/60 text-xs">
518
+
<span className="text-white/60 text-sm">
463
519
({percentage.toFixed(1)}%)
464
520
</span>
465
521
</div>
···
479
535
</div>
480
536
);
481
537
}
538
+
539
+
function getUrlFromNamespace(type: string) {
540
+
const parts = type.split(".");
541
+
if (parts.length >= 2) {
542
+
return `${parts[1]}.${parts[0]}`;
543
+
}
544
+
return type; // Not enough parts to swap
545
+
}