allow to delete torrents

This commit is contained in:
2026-02-12 23:34:53 +03:00
parent 155cb3e726
commit 738917979e
4 changed files with 59 additions and 1 deletions

17
main.go
View File

@@ -322,6 +322,23 @@ func main() {
}{true}, 200)
})
mux.HandleFunc("DELETE /api/torrents/{id}", func(w http.ResponseWriter, r *http.Request) {
torrentId, err := strconv.Atoi(r.PathValue("id"))
if err != nil {
http.Error(w, err.Error(), 500)
return
}
if err := m.DeleteTorrentById(int64(torrentId)); err != nil {
http.Error(w, err.Error(), 404)
return
}
sendJSON(w, struct {
Ok bool `json:"ok"`
}{true}, 200)
})
addr := fmt.Sprintf("%s:%d", *hostname, *port)
fmt.Printf("starting http server on %s\n", addr)
if err := http.ListenAndServe(addr, mux); err != nil {

View File

@@ -41,3 +41,8 @@ func (m *Model) GetTorrentByGuidAndItemId(guid string, itemId int64) (*Torrent,
return torrent, nil
}
func (m *Model) DeleteTorrentById(torrentId int64) error {
_, err := m.db.Exec("DELETE FROM torrents WHERE id = ?", torrentId)
return err
}

View File

@@ -0,0 +1,13 @@
import { useMutation } from "@tanstack/react-query";
export const useDeleteTorrentMutation = () => {
return useMutation({
mutationFn: async ({ id }: { id: number }) => {
const resp = await fetch(`/api/torrents/${id}`, {
method: "DELETE",
});
const data = await resp.json();
return data;
},
});
};

View File

@@ -13,6 +13,7 @@ import { useDeleteItemMutation } from "../api/useDeleteItemMutation";
import { useQueryClient } from "@tanstack/react-query";
import dayjs from "dayjs";
import { humanFileSize } from "../utils/humanFileSize";
import { useDeleteTorrentMutation } from "../api/useDeleteTorrentMutation";
export type ItemProps = {
item: ItemDetails;
@@ -27,6 +28,7 @@ export const Item = ({ item }: ItemProps) => {
const deleteMutation = useDeleteItemMutation();
const downloadMutation = useDownloadTorrentMutation();
const deleteTorrentMutation = useDeleteTorrentMutation();
const Icon = open ? CaretUpIcon : CaretDownIcon;
@@ -49,6 +51,21 @@ export const Item = ({ item }: ItemProps) => {
);
};
const handleDeleteTorrent = (torrentId: number) => {
deleteTorrentMutation.mutate(
{
id: torrentId,
},
{
onSuccess() {
queryClient.invalidateQueries({
queryKey: ["items", item.id, "torrents"],
});
},
},
);
};
return (
<div className="border-t border-b border-neutral-900">
<div
@@ -74,7 +91,7 @@ export const Item = ({ item }: ItemProps) => {
torrents?.map((torrent) => (
<div
key={torrent.id}
className="flex justify-between items-center hover:bg-neutral-200"
className="flex justify-between items-center hover:bg-neutral-200 group"
>
<div className="flex items-center gap-2">
<span>
@@ -92,6 +109,12 @@ export const Item = ({ item }: ItemProps) => {
<CheckCircleIcon size={20} color="green" />
</span>
)}
<button
className="hidden group-hover:inline text-[#b00420] cursor-pointer"
onClick={() => handleDeleteTorrent(torrent.id)}
>
<TrashIcon size={16} />
</button>
</div>
<div className="flex items-center gap-1">
<span>Seeds: {torrent.seeders}</span>