mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-15 19:45:42 -04:00
fix(dashboard): block duplicate quick-watch clicks until refetch and use logical end inset
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+20
-15
No files matched your search
@@ -116,7 +116,7 @@ export function ContinueWatchingCard({ item }: { item: ContinueWatchingItemProps
|
||||
size="icon"
|
||||
aria-label={quickWatchLabel}
|
||||
disabled={pendingId === nextEpisode.id}
|
||||
className="absolute top-2 right-2 rounded-full bg-black/50 text-white backdrop-blur-sm hover:bg-black/70"
|
||||
className="absolute end-2 top-2 rounded-full bg-black/50 text-white backdrop-blur-sm hover:bg-black/70"
|
||||
onClick={() =>
|
||||
watchEpisode(
|
||||
nextEpisode.id,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { getErrorMessage } from "@/lib/error-messages";
|
||||
@@ -10,21 +11,25 @@ import { invalidateTrackingQueries } from "@/lib/orpc/invalidate";
|
||||
export function useQuickWatchEpisode() {
|
||||
const { t } = useLingui();
|
||||
const queryClient = useQueryClient();
|
||||
const { mutate, variables, isPending } = useMutation(orpc.tracking.watch.mutationOptions());
|
||||
|
||||
function watchEpisode(episodeId: string, label: string) {
|
||||
mutate(
|
||||
{ scope: "episode", ids: [episodeId] },
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success(t`Marked ${label} as watched`);
|
||||
void invalidateTrackingQueries(queryClient);
|
||||
},
|
||||
onError: (err) => {
|
||||
toast.error(getErrorMessage(err, t`Failed to mark episode`));
|
||||
},
|
||||
const [label, setLabel] = useState("");
|
||||
// Handlers live on the hook-level options so the mutation stays pending until
|
||||
// the tracking queries have refetched, which blocks duplicate clicks.
|
||||
const { mutate, variables, isPending } = useMutation(
|
||||
orpc.tracking.watch.mutationOptions({
|
||||
onSuccess: async () => {
|
||||
toast.success(t`Marked ${label} as watched`);
|
||||
await invalidateTrackingQueries(queryClient);
|
||||
},
|
||||
);
|
||||
onError: (err) => {
|
||||
toast.error(getErrorMessage(err, t`Failed to mark episode`));
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
function watchEpisode(episodeId: string, episodeLabel: string) {
|
||||
if (isPending) return;
|
||||
setLabel(episodeLabel);
|
||||
mutate({ scope: "episode", ids: [episodeId] });
|
||||
}
|
||||
|
||||
const pendingId = isPending ? (variables?.ids?.[0] ?? null) : null;
|
||||
|
||||
Reference in new issue
Block a user