import { deleteGameMutation, fixSourceMutation, gameInvalidationQuery, updateSourceMutation, validateSourceQuery } from "@/mainview/scripts/queries/romm";
import { FocusContext, setFocus, useFocusable } from "@noriginmedia/norigin-spatial-navigation";
import { useMutation, useQuery } from "@tanstack/react-query";
import { ContextList, DialogEntry, useContextDialog } from "../ContextDialog";
import { getErrorMessage } from "react-error-boundary";
import toast from "react-hot-toast";
import { Hammer, RefreshCcw, RefreshCcwDot, Settings, Trash, Trophy } from "lucide-react";
import MainActions from "./MainActions";
import ActionButton from "./ActionButton";
import { useLocalStorage } from "usehooks-ts";
import FocusTooltip from "../FocusTooltip";
import { useBlocker, useNavigate, useRouter } from "@tanstack/react-router";
import { FrontEndGameTypeDetailed } from "@/shared/types";
function AchievementsInfo (data: { game: FrontEndGameTypeDetailed; } & InteractParams)
{
if (!data.game.achievements)
{
return false;
}
return
{`${data.game.achievements.unlocked}/${data.game.achievements.total}`}
;
}
export default function ActionButtons (data: { game?: FrontEndGameTypeDetailed, source: string, id: string; })
{
const [, setDetailsSection] = useLocalStorage('details-section', 'screenshots');
const navigate = useNavigate();
const fixMutation = useMutation({
...fixSourceMutation,
onSuccess (data, variables, onMutateResult, context)
{
if (onMutateResult) toast.success("Updated Source");
context.client.invalidateQueries(gameInvalidationQuery(variables.id, variables.source)).then(() => router.history.back());
},
onError (error)
{
toast.error(getErrorMessage(error) ?? "Error While Trying To Fix");
}
});
const updateMutation = useMutation({
...updateSourceMutation,
onSuccess (data, variables, onMutateResult, context)
{
if (onMutateResult) toast.success("Updated Source");
context.client.invalidateQueries(gameInvalidationQuery(variables.id, variables.source));
},
onError (error)
{
toast.error(getErrorMessage(error) ?? "Error While Trying To Update");
}
});
const { data: validation } = useQuery(validateSourceQuery(data.source, data.id));
const { ref, focusKey, hasFocusedChild } = useFocusable({ focusKey: 'actions', forceFocus: true, trackChildren: true, preferredChildFocusKey: 'mainAction' });
const router = useRouter();
const deleteMutation = useMutation({
...deleteGameMutation({ id: data.id, source: data.source }),
onSuccess: (d, v, r, ctx) =>
{
ctx.client.invalidateQueries(gameInvalidationQuery(data.id, data.source));
router.history.back();
},
onError (error)
{
toast.error(getErrorMessage(error) ?? "Error While Deleting");
}
});
useBlocker({
shouldBlockFn: () =>
{
return deleteMutation.isPending || fixMutation.isPending || updateMutation.isPending;
}
});
const contextOptions: DialogEntry[] = [];
if (data.game?.local)
{
contextOptions.push({
id: 'delete',
action: (ctx) =>
{
deleteMutation.mutate();
ctx.close();
},
icon: deleteMutation.isPending ? : ,
content: deleteMutation.isPending ? "Deleting" : "Delete",
type: 'error'
});
}
if (!validation?.valid)
{
contextOptions.push({
id: "fix_source",
action (ctx)
{
if (!data.game) return;
fixMutation.mutate({ source: data.game.id.source, id: data.game.id.id }, {
onSuccess (data, variables, onMutateResult, context)
{
router.navigate({ replace: true });
},
});
ctx.close();
},
icon: fixMutation.isPending ? : ,
content: "Try Fix Source",
type: "warning"
});
} else if (data.game?.id.source === 'local')
{
contextOptions.push({
id: 'update_source',
async action (ctx)
{
if (data.game)
{
await updateMutation.mutateAsync({ source: data.game.id.source, id: data.game.id.id });
ctx.close();
router.navigate({ replace: true });
}
},
icon: updateMutation.isPending ? : ,
content: "Update Metadata",
type: "primary"
});
contextOptions.push({
id: 'update-custom',
action (ctx)
{
ctx.close();
navigate({ to: '/game/update/$source/$id', params: { source: data.source, id: data.id } });
},
icon: updateMutation.isPending ? : ,
content: "Update Metadata (Interactive)",
type: "primary"
});
}
const { setOpen, dialog: settingsDialog } = useContextDialog("settings-context", { content: , canClose: !deleteMutation.isPending });
return
{data.game &&
{
setDetailsSection("achievements");
if (data.game?.achievements?.entires[0])
{
setFocus(data.game.achievements.entires[0].id);
}
}} />}
setOpen(true, 'settings')} type="base" id="settings" icon={} >
{settingsDialog}
;
}