@drawnagency/primitives 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAkC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAkC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAukBP"}
|
|
@@ -2,7 +2,9 @@ type BuildState = "idle" | "building" | "ready" | "error";
|
|
|
2
2
|
interface BuildStatusResult {
|
|
3
3
|
state: BuildState;
|
|
4
4
|
deployUrl: string | null;
|
|
5
|
+
elapsedSeconds: number;
|
|
5
6
|
startTracking: () => void;
|
|
7
|
+
dismiss: () => void;
|
|
6
8
|
}
|
|
7
9
|
export declare function useBuildStatus(): BuildStatusResult;
|
|
8
10
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAKD,wBAAgB,cAAc,IAAI,iBAAiB,CAsHlD"}
|
package/package.json
CHANGED
|
@@ -47,7 +47,7 @@ import { SplitButton } from "../shared/SplitButton";
|
|
|
47
47
|
import { IconButton } from "../shared/IconButton";
|
|
48
48
|
import { SegmentedControl } from "../shared/SegmentedControl";
|
|
49
49
|
import { SettingsIcon } from "../shared/icons";
|
|
50
|
-
import { ImageIcon } from "lucide-react";
|
|
50
|
+
import { ImageIcon, X } from "lucide-react";
|
|
51
51
|
import { ErrorBoundary } from "../shared/ErrorBoundary";
|
|
52
52
|
|
|
53
53
|
export { useMediaLibrary } from "./MediaLibraryContext";
|
|
@@ -585,6 +585,8 @@ export default function EditorShell({
|
|
|
585
585
|
}}
|
|
586
586
|
processingItems={mediaPipeline.processingItems}
|
|
587
587
|
buildState={buildStatus.state}
|
|
588
|
+
buildElapsed={buildStatus.elapsedSeconds}
|
|
589
|
+
onBuildDismiss={buildStatus.dismiss}
|
|
588
590
|
/>
|
|
589
591
|
|
|
590
592
|
<EditorContent
|
|
@@ -871,29 +873,71 @@ function GlobalModal() {
|
|
|
871
873
|
);
|
|
872
874
|
}
|
|
873
875
|
|
|
876
|
+
function LoadingEllipsis() {
|
|
877
|
+
const [dots, setDots] = useState(0);
|
|
878
|
+
useEffect(() => {
|
|
879
|
+
const id = setInterval(() => setDots((d) => (d + 1) % 4), 400);
|
|
880
|
+
return () => clearInterval(id);
|
|
881
|
+
}, []);
|
|
882
|
+
return <span className="absolute">{".".repeat(dots)}</span>;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
function formatElapsed(seconds: number): string {
|
|
886
|
+
const m = Math.floor(seconds / 60);
|
|
887
|
+
const s = seconds % 60;
|
|
888
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
function DismissButton({ onClick }: { onClick: () => void }) {
|
|
892
|
+
return (
|
|
893
|
+
<button type="button" onClick={onClick} className="text-base-content/30 hover:text-base-content/60 cursor-pointer" aria-label="Dismiss">
|
|
894
|
+
<X size={12} />
|
|
895
|
+
</button>
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
|
|
874
899
|
function StatusText({
|
|
875
900
|
publishAction,
|
|
876
901
|
publishFeedback,
|
|
877
902
|
buildState,
|
|
903
|
+
buildElapsed,
|
|
904
|
+
onDismiss,
|
|
878
905
|
}: {
|
|
879
906
|
publishAction: "idle" | "saving" | "publishing";
|
|
880
907
|
publishFeedback: string | null;
|
|
881
908
|
buildState: "idle" | "building" | "ready" | "error";
|
|
909
|
+
buildElapsed: number;
|
|
910
|
+
onDismiss: () => void;
|
|
882
911
|
}) {
|
|
883
912
|
if (publishAction === "saving") {
|
|
884
|
-
return
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
913
|
+
return (
|
|
914
|
+
<span className="relative text-xs font-medium text-base-content/60">
|
|
915
|
+
Saving changes<LoadingEllipsis />
|
|
916
|
+
</span>
|
|
917
|
+
);
|
|
888
918
|
}
|
|
889
|
-
if (buildState === "building") {
|
|
890
|
-
return
|
|
919
|
+
if (publishAction === "publishing" || buildState === "building") {
|
|
920
|
+
return (
|
|
921
|
+
<span className="text-xs font-medium text-orange-600">
|
|
922
|
+
Publishing ({formatElapsed(buildElapsed)})
|
|
923
|
+
</span>
|
|
924
|
+
);
|
|
891
925
|
}
|
|
892
926
|
if (buildState === "ready") {
|
|
893
|
-
return
|
|
927
|
+
return (
|
|
928
|
+
<span className="inline-flex items-center gap-1.5 text-xs font-medium text-green-600">
|
|
929
|
+
Published in {formatElapsed(buildElapsed)}
|
|
930
|
+
<DismissButton onClick={onDismiss} />
|
|
931
|
+
</span>
|
|
932
|
+
);
|
|
894
933
|
}
|
|
895
934
|
if (buildState === "error") {
|
|
896
|
-
return
|
|
935
|
+
return (
|
|
936
|
+
<span className="inline-flex items-center gap-1.5 text-xs font-medium text-red-600">
|
|
937
|
+
Publish failed
|
|
938
|
+
<DismissButton onClick={onDismiss} />
|
|
939
|
+
</span>
|
|
940
|
+
);
|
|
897
941
|
}
|
|
898
942
|
if (publishFeedback) {
|
|
899
943
|
return (
|
|
@@ -921,6 +965,8 @@ function EditorToolbar({
|
|
|
921
965
|
onMediaClick,
|
|
922
966
|
processingItems,
|
|
923
967
|
buildState,
|
|
968
|
+
buildElapsed,
|
|
969
|
+
onBuildDismiss,
|
|
924
970
|
}: {
|
|
925
971
|
buttonState: "synced" | "publish" | "saveAndPublish";
|
|
926
972
|
localChangesExist: boolean;
|
|
@@ -934,6 +980,8 @@ function EditorToolbar({
|
|
|
934
980
|
onMediaClick: () => void;
|
|
935
981
|
processingItems: QueueItem[];
|
|
936
982
|
buildState: "idle" | "building" | "ready" | "error";
|
|
983
|
+
buildElapsed: number;
|
|
984
|
+
onBuildDismiss: () => void;
|
|
937
985
|
}) {
|
|
938
986
|
const { isEditMode, viewBranch, setViewBranch, toggleEditMode } = useEditorContext();
|
|
939
987
|
|
|
@@ -981,6 +1029,8 @@ function EditorToolbar({
|
|
|
981
1029
|
publishAction={publishAction}
|
|
982
1030
|
publishFeedback={publishFeedback}
|
|
983
1031
|
buildState={buildState}
|
|
1032
|
+
buildElapsed={buildElapsed}
|
|
1033
|
+
onDismiss={onBuildDismiss}
|
|
984
1034
|
/>
|
|
985
1035
|
</div>
|
|
986
1036
|
<div className="flex items-center justify-end gap-2">
|
|
@@ -12,17 +12,33 @@ interface BuildStatusResponse {
|
|
|
12
12
|
interface BuildStatusResult {
|
|
13
13
|
state: BuildState;
|
|
14
14
|
deployUrl: string | null;
|
|
15
|
+
elapsedSeconds: number;
|
|
15
16
|
startTracking: () => void;
|
|
17
|
+
dismiss: () => void;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const POLL_INTERVAL = 5000;
|
|
21
|
+
const AUTO_CLEAR_DELAY = 5000;
|
|
19
22
|
|
|
20
23
|
export function useBuildStatus(): BuildStatusResult {
|
|
21
24
|
const [state, setState] = useState<BuildState>("idle");
|
|
22
25
|
const [deployUrl, setDeployUrl] = useState<string | null>(null);
|
|
26
|
+
const [elapsedSeconds, setElapsedSeconds] = useState(0);
|
|
23
27
|
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
28
|
+
const clearRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
29
|
+
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
24
30
|
const isPolling = useRef(false);
|
|
25
31
|
|
|
32
|
+
const stopTimer = useCallback(() => {
|
|
33
|
+
if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; }
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
const startTimer = useCallback(() => {
|
|
37
|
+
stopTimer();
|
|
38
|
+
setElapsedSeconds(0);
|
|
39
|
+
timerRef.current = setInterval(() => setElapsedSeconds((s) => s + 1), 1000);
|
|
40
|
+
}, [stopTimer]);
|
|
41
|
+
|
|
26
42
|
const stopPolling = useCallback(() => {
|
|
27
43
|
if (pollRef.current) {
|
|
28
44
|
clearInterval(pollRef.current);
|
|
@@ -63,6 +79,10 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
63
79
|
|
|
64
80
|
if (data.state === "ready" || data.state === "error") {
|
|
65
81
|
stopPolling();
|
|
82
|
+
stopTimer();
|
|
83
|
+
if (data.state === "ready") {
|
|
84
|
+
clearRef.current = setTimeout(() => setState("idle"), AUTO_CLEAR_DELAY);
|
|
85
|
+
}
|
|
66
86
|
}
|
|
67
87
|
},
|
|
68
88
|
[stopPolling],
|
|
@@ -97,14 +117,25 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
97
117
|
return () => {
|
|
98
118
|
cancelled = true;
|
|
99
119
|
stopPolling();
|
|
120
|
+
stopTimer();
|
|
121
|
+
if (clearRef.current) clearTimeout(clearRef.current);
|
|
100
122
|
};
|
|
101
123
|
}, [fetchStatus, handleStatusUpdate, startPolling, stopPolling]);
|
|
102
124
|
|
|
103
125
|
const startTracking = useCallback(() => {
|
|
126
|
+
if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
|
|
104
127
|
setState("building");
|
|
105
128
|
setDeployUrl(null);
|
|
129
|
+
startTimer();
|
|
106
130
|
startPolling();
|
|
107
|
-
}, [startPolling]);
|
|
131
|
+
}, [startPolling, startTimer]);
|
|
132
|
+
|
|
133
|
+
const dismiss = useCallback(() => {
|
|
134
|
+
if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
|
|
135
|
+
setState("idle");
|
|
136
|
+
stopPolling();
|
|
137
|
+
stopTimer();
|
|
138
|
+
}, [stopPolling, stopTimer]);
|
|
108
139
|
|
|
109
|
-
return { state, deployUrl, startTracking };
|
|
140
|
+
return { state, deployUrl, elapsedSeconds, startTracking, dismiss };
|
|
110
141
|
}
|