From 4c6106b99ec3cb6edefed3f7718dab3285355735 Mon Sep 17 00:00:00 2001 From: dmgnr Date: Sun, 13 Sep 2026 18:05:36 +0700 Subject: [PATCH] feat(art): switch submit button to ActionButton --- app/(ui)/artifact/form.tsx | 29 ++++++++++++++++++--------- components/action-button.tsx | 10 ++++++--- components/action-submit-provider.tsx | 13 ++++++++++++ 3 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 components/action-submit-provider.tsx diff --git a/app/(ui)/artifact/form.tsx b/app/(ui)/artifact/form.tsx index e99aae9..50501e0 100755 --- a/app/(ui)/artifact/form.tsx +++ b/app/(ui)/artifact/form.tsx @@ -2,10 +2,12 @@ import { useRouter } from "next/navigation"; import posthog from "posthog-js"; -import { useState } from "react"; +import { useRef, useState } from "react"; import { toast } from "sonner"; import { checkEnkaStatus, submitArtifact } from "@/lib/api"; import { shared } from "@/lib/comms"; +import type { ActionSubmitContextData } from "@/components/action-submit-provider"; +import { ActionSubmitContext } from "@/components/action-submit-provider"; export function ArtifactFormWrapper({ edit, @@ -20,6 +22,12 @@ export function ArtifactFormWrapper({ const [, setWarningUid] = shared.state("warning.uid"); const [warningSrc, setWarningSrc] = shared.state("warning.src"); const [dataHold, setDataHold] = useState(); + const callback = useRef<() => void>(() => {}); + const context: ActionSubmitContextData = { + listenForComplete(complete) { + callback.current = complete; + }, + }; // Disable warning for 60 seconds shared.signal( @@ -53,15 +61,18 @@ export function ArtifactFormWrapper({ } catch {} router.refresh(); }) - .catch((e) => toast.error(`${e.message || e}`)); + .catch((e) => toast.error(`${e.message || e}`)) + .finally(callback.current); } return ( -
{ - e.preventDefault(); - submit(new FormData(e.target as HTMLFormElement)); - }} - /> + + { + e.preventDefault(); + submit(new FormData(e.target as HTMLFormElement)); + }} + /> + ); } diff --git a/components/action-button.tsx b/components/action-button.tsx index f054f96..817bdcf 100644 --- a/components/action-button.tsx +++ b/components/action-button.tsx @@ -3,10 +3,11 @@ import type { MaybePromise } from "bun"; import { Check } from "lucide-react"; import type { ComponentProps, ReactNode } from "react"; -import { useEffect, useState } from "react"; +import { use, useEffect, useState } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Spinner } from "@/components/ui/spinner"; +import { ActionSubmitContext } from "./action-submit-provider"; export function ActionButton({ action, @@ -15,10 +16,11 @@ export function ActionButton({ text, ...props }: ComponentProps & { - action: () => MaybePromise; + action: (() => MaybePromise) | "provider"; text?: string; }) { const [state, setState] = useState<0 | 1 | 2>(0); + const ctx = use(ActionSubmitContext); useEffect(() => { if (state !== 2) return; @@ -33,7 +35,9 @@ export function ActionButton({ onClick?.(ev); setState(1); try { - await action(); + if (action === "provider") + await new Promise(ctx.listenForComplete); + else await action(); setState(2); } catch (e) { toast.error("An error occured!"); diff --git a/components/action-submit-provider.tsx b/components/action-submit-provider.tsx new file mode 100644 index 0000000..d19dcbe --- /dev/null +++ b/components/action-submit-provider.tsx @@ -0,0 +1,13 @@ +"use client"; + +import { createContext } from "react"; + +export type ActionSubmitContextData = { + listenForComplete: (complete: () => void) => void; +}; + +export const ActionSubmitContext = createContext({ + listenForComplete: (r) => { + r(); + }, +});