Files
DTAN/src/page/torrent.tsx
2023-11-27 14:39:58 +00:00

78 lines
2.8 KiB
TypeScript

import { unwrap } from "@snort/shared";
import { NoteCollection, RequestBuilder, TaggedNostrEvent, parseNostrLink } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { FormatBytes, TorrentKind } from "../const";
import { ProfileImage } from "../element/profile-image";
import { MagnetLink } from "../element/magnet";
import { useLogin } from "../login";
import { Button } from "../element/button";
export function TorrentPage() {
const location = useLocation();
const { id } = useParams();
const evState = "kind" in location.state ? (location.state as TaggedNostrEvent) : undefined;
const rb = new RequestBuilder("torrent:event");
rb.withFilter()
.kinds([TorrentKind])
.link(parseNostrLink(unwrap(id)));
const evNew = useRequestBuilder(NoteCollection, evState ? null : rb);
const ev = evState ?? evNew.data?.at(0);
if (!ev) return;
return <TorrentDetail item={ev} />;
}
export function TorrentDetail({ item }: { item: TaggedNostrEvent }) {
const login = useLogin();
const navigate = useNavigate();
const name = item.tags.find((a) => a[0] === "title")?.at(1);
const size = Number(item.tags.find((a) => a[0] === "size")?.at(1));
const files = item.tags.filter(a => a[0] === "file");
const tags = item.tags.filter(a => a[0] === "t").map(a => a[1]);
async function deleteTorrent() {
const ev = await login?.builder?.delete(item.id);
if (ev) {
await login?.system.BroadcastEvent(ev);
navigate(-1);
}
}
return (
<div className="flex flex-col gap-2">
<div className="flex gap-2 items-center text-xl">
<ProfileImage pubkey={item.pubkey} />
{name}
</div>
<div className="flex flex-col gap-1 bg-slate-700 p-2 rounded">
<div>Size: {FormatBytes(size)}</div>
<div>Uploaded: {new Date(item.created_at * 1000).toLocaleDateString()}</div>
<div className="flex items-center gap-2">Tags: <div className="flex gap-1">
{tags.map(a => <div className="rounded p-1 bg-slate-400">#{a}</div>)}
</div>
</div>
<div>
<MagnetLink item={item} className="flex gap-1 items-center">
Get this torrent
</MagnetLink>
</div>
</div>
<h3>Description</h3>
<pre className="font-mono text-xs bg-slate-700 p-2 rounded overflow-y-auto">{item.content}</pre>
<h3>Files</h3>
<div className="flex flex-col gap-1 bg-slate-700 p-2 rounded">
{files.map(a => <div className="flex items-center gap-2">
{a[1]}
<small className="text-slate-500 font-semibold">{FormatBytes(Number(a[2]))}</small>
</div>)}
</div>
{item.pubkey == login?.publicKey && <Button className="bg-red-600 hover:bg-red-800" onClick={deleteTorrent}>
Delete
</Button>}
</div>
);
}