camox 0.67.0 → 0.68.0

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.
@@ -0,0 +1,139 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { studioStore } from "../studioStore.js";
3
+ import { plural } from "../draftLabel.js";
4
+ import { useDrafts } from "./DraftsControl.js";
5
+ import { c } from "react/compiler-runtime";
6
+ import * as React from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Button } from "@camox/ui/button";
9
+ import { FloatingToolbar } from "@camox/ui/floating-toolbar";
10
+
11
+ //#region src/features/studio/components/DraftBar.tsx
12
+ /**
13
+ * How long a draft goes without a change before its bar shows, so it doesn't pop up mid-edit.
14
+ */
15
+ const SETTLE_MS = 1500;
16
+ /**
17
+ * Asks what to do with the draft being viewed, once its edits settle: discard its changes or
18
+ * publish them. `stacked` places it in the Preview toolbar's column, just above the toolbar;
19
+ * otherwise it floats at the bottom of the screen on its own.
20
+ */
21
+ function DraftBar(t0) {
22
+ const $ = c(15);
23
+ const { stacked: t1 } = t0;
24
+ const stacked = t1 === void 0 ? false : t1;
25
+ const { projectId, current } = useDrafts();
26
+ const settled = useSettled(current?.id ?? null, current?.lastChangedAt ?? null);
27
+ if (!projectId || !current || !settled) return null;
28
+ const empty = current.changeCount === 0;
29
+ const t2 = stacked ? "pointer-events-auto relative left-auto translate-x-0" : "fixed bottom-2";
30
+ let t3;
31
+ if ($[0] !== t2) {
32
+ t3 = cn("w-max gap-4", t2);
33
+ $[0] = t2;
34
+ $[1] = t3;
35
+ } else t3 = $[1];
36
+ let t4;
37
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
38
+ t4 = /* @__PURE__ */ jsx("span", {
39
+ "aria-hidden": true,
40
+ className: "size-2 shrink-0 rounded-full bg-blue-500"
41
+ });
42
+ $[2] = t4;
43
+ } else t4 = $[2];
44
+ let t5;
45
+ if ($[3] !== current.changeCount || $[4] !== empty) {
46
+ t5 = empty ? "No changes yet" : plural(current.changeCount, "pending change");
47
+ $[3] = current.changeCount;
48
+ $[4] = empty;
49
+ $[5] = t5;
50
+ } else t5 = $[5];
51
+ let t6;
52
+ if ($[6] !== t5) {
53
+ t6 = /* @__PURE__ */ jsxs("span", {
54
+ className: "flex items-center gap-2 px-2 text-sm",
55
+ children: [t4, t5]
56
+ });
57
+ $[6] = t5;
58
+ $[7] = t6;
59
+ } else t6 = $[7];
60
+ let t7;
61
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
62
+ t7 = /* @__PURE__ */ jsx(Button, {
63
+ type: "button",
64
+ variant: "outline",
65
+ onClick: _temp,
66
+ children: "Discard"
67
+ });
68
+ $[8] = t7;
69
+ } else t7 = $[8];
70
+ let t8;
71
+ if ($[9] !== empty) {
72
+ t8 = /* @__PURE__ */ jsxs("div", {
73
+ className: "flex items-center gap-2",
74
+ children: [t7, /* @__PURE__ */ jsx(Button, {
75
+ type: "button",
76
+ disabled: empty,
77
+ onClick: _temp2,
78
+ children: "Publish…"
79
+ })]
80
+ });
81
+ $[9] = empty;
82
+ $[10] = t8;
83
+ } else t8 = $[10];
84
+ let t9;
85
+ if ($[11] !== t3 || $[12] !== t6 || $[13] !== t8) {
86
+ t9 = /* @__PURE__ */ jsxs(FloatingToolbar, {
87
+ "aria-label": "Draft",
88
+ className: t3,
89
+ children: [t6, t8]
90
+ });
91
+ $[11] = t3;
92
+ $[12] = t6;
93
+ $[13] = t8;
94
+ $[14] = t9;
95
+ } else t9 = $[14];
96
+ return t9;
97
+ }
98
+ function _temp2() {
99
+ return studioStore.send({ type: "openReviewDraftSheet" });
100
+ }
101
+ function _temp() {
102
+ return studioStore.send({ type: "openDeleteDraftDialog" });
103
+ }
104
+ /**
105
+ * Whether the draft went without a change for `SETTLE_MS`. Once settled it stays so for that
106
+ * draft, so the bar doesn't hide again on the next edit.
107
+ */
108
+ function useSettled(draftId, lastChangedAt) {
109
+ const $ = c(5);
110
+ const [settledDraft, setSettledDraft] = React.useState(null);
111
+ let t0;
112
+ let t1;
113
+ if ($[0] !== draftId || $[1] !== lastChangedAt || $[2] !== settledDraft) {
114
+ t0 = () => {
115
+ if (!draftId || settledDraft === draftId) return;
116
+ const wait = Math.max(0, (lastChangedAt ?? 0) + SETTLE_MS - Date.now());
117
+ const timer = setTimeout(() => setSettledDraft(draftId), wait);
118
+ return () => clearTimeout(timer);
119
+ };
120
+ t1 = [
121
+ draftId,
122
+ lastChangedAt,
123
+ settledDraft
124
+ ];
125
+ $[0] = draftId;
126
+ $[1] = lastChangedAt;
127
+ $[2] = settledDraft;
128
+ $[3] = t0;
129
+ $[4] = t1;
130
+ } else {
131
+ t0 = $[3];
132
+ t1 = $[4];
133
+ }
134
+ React.useEffect(t0, t1);
135
+ return !!draftId && settledDraft === draftId;
136
+ }
137
+
138
+ //#endregion
139
+ export { DraftBar, SETTLE_MS };
@@ -14,7 +14,6 @@ import { useSelector } from "@xstate/store-react";
14
14
  import { Button } from "@camox/ui/button";
15
15
  import { ChevronsUpDown } from "lucide-react";
16
16
  import { toast } from "@camox/ui/toaster";
17
- import { Badge } from "@camox/ui/badge";
18
17
  import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
19
18
 
20
19
  //#region src/features/studio/components/DraftsControl.tsx
@@ -374,7 +373,6 @@ function _temp5() {
374
373
  function _temp4() {
375
374
  studioStore.send({ type: "closeReviewDraftSheet" });
376
375
  studioStore.send({ type: "closeDeleteDraftDialog" });
377
- studioStore.send({ type: "closeKeepDraft" });
378
376
  }
379
377
  function _temp3(t0) {
380
378
  const { move } = t0;
@@ -387,47 +385,6 @@ function _temp(state) {
387
385
  return state.context.reviewDraftSheet;
388
386
  }
389
387
  /**
390
- * The current draft's pending changes, which open its review to publish or delete them. Live
391
- * has none, so it shows nothing there. An unnamed draft shows the Unnamed Draft Bar instead.
392
- */
393
- function PendingChanges() {
394
- const $ = c(7);
395
- const { current } = useDrafts();
396
- if (!current || current.name === null) return null;
397
- let t0;
398
- if ($[0] !== current.changeCount) {
399
- t0 = plural(current.changeCount, "change");
400
- $[0] = current.changeCount;
401
- $[1] = t0;
402
- } else t0 = $[1];
403
- const t1 = `Review ${t0}`;
404
- let t2;
405
- if ($[2] !== current.changeCount) {
406
- t2 = /* @__PURE__ */ jsx(Badge, {
407
- className: "bg-primary-foreground/20 text-primary-foreground min-w-5 px-1.5 tabular-nums",
408
- children: current.changeCount
409
- });
410
- $[2] = current.changeCount;
411
- $[3] = t2;
412
- } else t2 = $[3];
413
- let t3;
414
- if ($[4] !== t1 || $[5] !== t2) {
415
- t3 = /* @__PURE__ */ jsxs(Button, {
416
- type: "button",
417
- "aria-label": t1,
418
- onClick: _temp9,
419
- children: ["Review changes", t2]
420
- });
421
- $[4] = t1;
422
- $[5] = t2;
423
- $[6] = t3;
424
- } else t3 = $[6];
425
- return t3;
426
- }
427
- function _temp9() {
428
- return studioStore.send({ type: "openReviewDraftSheet" });
429
- }
430
- /**
431
388
  * The drafts controls' actions in the command palette, offered where the controls offer them. The palette only opens the review and the delete confirmation; it never publishes or
432
389
  * deletes by itself.
433
390
  */
@@ -453,7 +410,7 @@ function useDraftsActions(t0) {
453
410
  ],
454
411
  groupLabel: "Drafts",
455
412
  checkIfAvailable: () => inDraft,
456
- execute: _temp10
413
+ execute: _temp9
457
414
  },
458
415
  {
459
416
  id: "delete-draft",
@@ -469,22 +426,15 @@ function useDraftsActions(t0) {
469
426
  ],
470
427
  groupLabel: "Drafts",
471
428
  checkIfAvailable: () => inDraft,
472
- execute: _temp11
429
+ execute: _temp10
473
430
  },
474
431
  {
475
432
  id: "rename-draft",
476
- label: unnamed ? "Keep as draft…" : "Rename draft…",
477
- aliases: unnamed ? [
478
- "Name draft",
479
- "Rename draft",
480
- "Save draft"
481
- ] : ["Name draft"],
433
+ label: unnamed ? "Name draft…" : "Rename draft…",
434
+ aliases: unnamed ? ["Rename draft", "Save draft"] : ["Name draft"],
482
435
  groupLabel: "Drafts",
483
436
  checkIfAvailable: () => inDraft,
484
- execute: () => studioStore.send(unnamed ? { type: "openKeepDraft" } : {
485
- type: "openReviewDraftSheet",
486
- startRenaming: true
487
- })
437
+ execute: _temp11
488
438
  },
489
439
  {
490
440
  id: "switch-to-live",
@@ -561,9 +511,15 @@ function _temp13() {
561
511
  }
562
512
  function _temp12() {}
563
513
  function _temp11() {
564
- return studioStore.send({ type: "openDeleteDraftDialog" });
514
+ return studioStore.send({
515
+ type: "openReviewDraftSheet",
516
+ startRenaming: true
517
+ });
565
518
  }
566
519
  function _temp10() {
520
+ return studioStore.send({ type: "openDeleteDraftDialog" });
521
+ }
522
+ function _temp9() {
567
523
  return studioStore.send({ type: "openReviewDraftSheet" });
568
524
  }
569
525
  /** Who published Live last and when: a member, a release, or nobody yet. */
@@ -648,4 +604,4 @@ function DraftItem(t0) {
648
604
  }
649
605
 
650
606
  //#endregion
651
- export { DraftPicker, PendingChanges, useDrafts };
607
+ export { DraftPicker, useDrafts };
@@ -7,7 +7,8 @@ import { useLocalePath, useLocalizedPath } from "../../../lib/view-locale.js";
7
7
  import { STUDIO_BASE_PATH, STUDIO_CONTENT_PATH, STUDIO_SETTINGS_PATH } from "../routes.js";
8
8
  import { studioStore } from "../studioStore.js";
9
9
  import { UserButton } from "./UserButton.js";
10
- import { DraftPicker, PendingChanges } from "./DraftsControl.js";
10
+ import { ConnectAgent } from "./ConnectAgent.js";
11
+ import { DraftPicker } from "./DraftsControl.js";
11
12
  import { LocalePicker } from "./LocalePicker.js";
12
13
  import { ProjectMenu } from "./ProjectMenu.js";
13
14
  import { c } from "react/compiler-runtime";
@@ -144,7 +145,7 @@ const Navbar = (t0) => {
144
145
  if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
145
146
  t10 = /* @__PURE__ */ jsxs("div", {
146
147
  className: "flex items-center gap-2",
147
- children: [/* @__PURE__ */ jsx(PendingChanges, {}), /* @__PURE__ */ jsx(UserButton, {})]
148
+ children: [/* @__PURE__ */ jsx(ConnectAgent, {}), /* @__PURE__ */ jsx(UserButton, {})]
148
149
  });
149
150
  $[23] = t10;
150
151
  } else t10 = $[23];
@@ -9,7 +9,6 @@ import { useApplyTheme } from "../useTheme.js";
9
9
  import { c } from "react/compiler-runtime";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
11
11
  import { useSelector } from "@xstate/store-react";
12
- import { Button } from "@camox/ui/button";
13
12
  import { Check, Command, EyeOff, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
14
13
  import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
15
14
  import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
@@ -22,11 +21,7 @@ const UserButton = () => {
22
21
  if (!isAuthenticated || isLoading) {
23
22
  let t0;
24
23
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
25
- t0 = /* @__PURE__ */ jsx(Button, {
26
- variant: "outline",
27
- size: "icon",
28
- children: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" })
29
- });
24
+ t0 = /* @__PURE__ */ jsx(Avatar, { children: /* @__PURE__ */ jsx(AvatarFallback, { children: /* @__PURE__ */ jsx(User, { className: "size-4" }) }) });
30
25
  $[0] = t0;
31
26
  } else t0 = $[0];
32
27
  return t0;
@@ -62,11 +57,12 @@ function AuthenticatedUserButton({ theme, setTheme }) {
62
57
  const userImage = session?.user?.image;
63
58
  const userInitials = userName.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
64
59
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
65
- render: /* @__PURE__ */ jsx(Button, {
66
- variant: "outline",
67
- size: "icon"
68
- }),
69
- children: /* @__PURE__ */ jsx(User, { className: "text-muted-foreground" })
60
+ "aria-label": "Account",
61
+ className: "focus-visible:ring-ring/50 rounded-full outline-none focus-visible:ring-3",
62
+ children: /* @__PURE__ */ jsxs(Avatar, { children: [userImage && /* @__PURE__ */ jsx(AvatarImage, {
63
+ src: userImage,
64
+ alt: userName
65
+ }), /* @__PURE__ */ jsx(AvatarFallback, { children: userInitials })] })
70
66
  }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
71
67
  className: "w-72",
72
68
  align: "end",
@@ -10,7 +10,6 @@ const studioStore = createStore({
10
10
  startRenaming: false
11
11
  },
12
12
  isDeleteDraftDialogOpen: false,
13
- isKeepDraftOpen: false,
14
13
  localeDialog: null,
15
14
  websiteLocation: null,
16
15
  agentAsk: null,
@@ -79,18 +78,6 @@ const studioStore = createStore({
79
78
  isDeleteDraftDialogOpen: false
80
79
  };
81
80
  },
82
- openKeepDraft: (context) => {
83
- return {
84
- ...context,
85
- isKeepDraftOpen: true
86
- };
87
- },
88
- closeKeepDraft: (context) => {
89
- return {
90
- ...context,
91
- isKeepDraftOpen: false
92
- };
93
- },
94
81
  openLocaleDialog: (context, event) => {
95
82
  return {
96
83
  ...context,
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.67.0";
2
+ var version = "0.68.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };