@dxos/plugin-space 0.6.14-main.8b352a0 → 0.6.14-staging.54a8bab

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.
Files changed (58) hide show
  1. package/dist/lib/browser/{chunk-FOI7DAUV.mjs → chunk-WZAM3FNP.mjs} +1 -1
  2. package/dist/lib/browser/{chunk-FOI7DAUV.mjs.map → chunk-WZAM3FNP.mjs.map} +2 -2
  3. package/dist/lib/browser/index.mjs +432 -387
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/types/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-OTDRTHT4.cjs → chunk-HTAM5LQD.cjs} +4 -4
  8. package/dist/lib/node/{chunk-OTDRTHT4.cjs.map → chunk-HTAM5LQD.cjs.map} +2 -2
  9. package/dist/lib/node/index.cjs +474 -433
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/types/index.cjs +11 -11
  13. package/dist/lib/node/types/index.cjs.map +1 -1
  14. package/dist/lib/node-esm/{chunk-FYDGMPSC.mjs → chunk-TRJKV4PK.mjs} +1 -1
  15. package/dist/lib/node-esm/{chunk-FYDGMPSC.mjs.map → chunk-TRJKV4PK.mjs.map} +2 -2
  16. package/dist/lib/node-esm/index.mjs +432 -387
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/types/index.mjs +1 -1
  20. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  21. package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +1 -1
  22. package/dist/types/src/components/SyncStatus/Space.d.ts +8 -0
  23. package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -0
  24. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -2
  25. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  26. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +5 -20
  27. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/SyncStatus/save-tracker.d.ts +3 -0
  29. package/dist/types/src/components/SyncStatus/save-tracker.d.ts.map +1 -0
  30. package/dist/types/src/components/SyncStatus/status.d.ts +9 -0
  31. package/dist/types/src/components/SyncStatus/status.d.ts.map +1 -0
  32. package/dist/types/src/components/SyncStatus/{types.d.ts → sync-state.d.ts} +1 -1
  33. package/dist/types/src/components/SyncStatus/sync-state.d.ts.map +1 -0
  34. package/dist/types/src/components/index.d.ts +0 -2
  35. package/dist/types/src/components/index.d.ts.map +1 -1
  36. package/dist/types/src/translations.d.ts +6 -0
  37. package/dist/types/src/translations.d.ts.map +1 -1
  38. package/dist/types/src/types/types.d.ts +2 -1
  39. package/dist/types/src/types/types.d.ts.map +1 -1
  40. package/package.json +34 -33
  41. package/src/SpacePlugin.tsx +55 -30
  42. package/src/components/SpaceSettings.tsx +5 -5
  43. package/src/components/SpaceSettingsPanel.tsx +18 -8
  44. package/src/components/SyncStatus/Space.tsx +109 -0
  45. package/src/components/SyncStatus/SyncStatus.stories.tsx +13 -4
  46. package/src/components/SyncStatus/SyncStatus.tsx +43 -129
  47. package/src/components/{SaveStatus.tsx → SyncStatus/save-tracker.ts} +1 -25
  48. package/src/components/SyncStatus/status.ts +44 -0
  49. package/src/components/index.ts +0 -2
  50. package/src/translations.ts +6 -0
  51. package/src/types/types.ts +3 -1
  52. package/dist/types/src/components/MissingObject.d.ts +0 -5
  53. package/dist/types/src/components/MissingObject.d.ts.map +0 -1
  54. package/dist/types/src/components/SaveStatus.d.ts +0 -3
  55. package/dist/types/src/components/SaveStatus.d.ts.map +0 -1
  56. package/dist/types/src/components/SyncStatus/types.d.ts.map +0 -1
  57. package/src/components/MissingObject.tsx +0 -54
  58. /package/src/components/SyncStatus/{types.ts → sync-state.ts} +0 -0
@@ -16,12 +16,12 @@ import {
16
16
  ThreadStatus,
17
17
  ThreadType,
18
18
  parseSpaceInitPlugin
19
- } from "./chunk-FYDGMPSC.mjs";
19
+ } from "./chunk-TRJKV4PK.mjs";
20
20
 
21
21
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
22
22
  import { signal } from "@preact/signals-core";
23
- import React18 from "react";
24
- import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction3, Surface as Surface2, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin3, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
23
+ import React17 from "react";
24
+ import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction3, Surface as Surface2, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin2, parseLayoutPlugin, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
25
25
  import { EventSubscriptions } from "@dxos/async";
26
26
  import { isReactiveObject as isReactiveObject2 } from "@dxos/echo-schema";
27
27
  import { scheduledEffect } from "@dxos/echo-signals/core";
@@ -33,7 +33,7 @@ import { parseClientPlugin } from "@dxos/plugin-client";
33
33
  import { createExtension, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
34
34
  import { ObservabilityAction } from "@dxos/plugin-observability/meta";
35
35
  import { PublicKey as PublicKey2 } from "@dxos/react-client";
36
- import { Expando, Filter, SpaceState as SpaceState3, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId } from "@dxos/react-client/echo";
36
+ import { Expando, Filter, SpaceState as SpaceState3, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId, FQ_ID_LENGTH } from "@dxos/react-client/echo";
37
37
  import { Dialog } from "@dxos/react-ui";
38
38
  import { ClipboardProvider as ClipboardProvider2, InvitationManager, osTranslations } from "@dxos/shell/react";
39
39
  import { ComplexMap as ComplexMap2, nonNullable, reduceGroupBy } from "@dxos/util";
@@ -759,66 +759,25 @@ var MenuFooter = ({ object }) => {
759
759
  }), toLocalizedString(spaceName, t)))) : null;
760
760
  };
761
761
 
762
- // packages/plugins/plugin-space/src/components/MissingObject.tsx
763
- import React6, { useEffect as useEffect2, useState as useState2 } from "react";
764
- import { parseIntentPlugin as parseIntentPlugin2, useResolvePlugin as useResolvePlugin2 } from "@dxos/app-framework";
765
- import { Status, useTranslation as useTranslation6 } from "@dxos/react-ui";
766
- import { baseSurface as baseSurface2, descriptionText as descriptionText2, mx as mx3 } from "@dxos/react-ui-theme";
767
- var WAIT_FOR_OBJECT_TIMEOUT2 = 1e3;
768
- var MissingObject = ({ id }) => {
769
- const { t } = useTranslation6(SPACE_PLUGIN);
770
- const [waiting, setWaiting] = useState2(false);
771
- const intentPlugin = useResolvePlugin2(parseIntentPlugin2);
772
- useEffect2(() => {
773
- if (!intentPlugin) {
774
- return;
775
- }
776
- const timeout = setTimeout(async () => {
777
- setWaiting(true);
778
- await intentPlugin.provides.intent.dispatch({
779
- plugin: SPACE_PLUGIN,
780
- action: SpaceAction.WAIT_FOR_OBJECT,
781
- data: {
782
- id
783
- }
784
- });
785
- }, WAIT_FOR_OBJECT_TIMEOUT2);
786
- return () => clearTimeout(timeout);
787
- }, [
788
- intentPlugin,
789
- id
790
- ]);
791
- return /* @__PURE__ */ React6.createElement("div", {
792
- role: "none",
793
- className: mx3(baseSurface2, "min-bs-screen is-full flex items-center justify-center p-8")
794
- }, waiting ? /* @__PURE__ */ React6.createElement("p", {
795
- role: "alert",
796
- className: mx3(descriptionText2, "border border-dashed border-neutral-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
797
- }, t("missing object message")) : /* @__PURE__ */ React6.createElement(Status, {
798
- indeterminate: true,
799
- "aria-label": "Initializing"
800
- }));
801
- };
802
-
803
762
  // packages/plugins/plugin-space/src/components/PersistenceStatus.tsx
804
763
  import { ArrowsCounterClockwise, CheckCircle as CheckCircle2, Warning } from "@phosphor-icons/react";
805
- import React7, { useEffect as useEffect3, useState as useState3 } from "react";
764
+ import React6, { useEffect as useEffect2, useState as useState2 } from "react";
806
765
  import { debounce } from "@dxos/async";
807
- import { Tooltip, useTranslation as useTranslation7 } from "@dxos/react-ui";
808
- import { getSize as getSize2, mx as mx4, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
809
- var Status2;
810
- (function(Status3) {
811
- Status3[Status3["PERSISTED_LOCALLY"] = 0] = "PERSISTED_LOCALLY";
812
- Status3[Status3["PENDING"] = 1] = "PENDING";
813
- Status3[Status3["ERROR"] = 2] = "ERROR";
814
- })(Status2 || (Status2 = {}));
766
+ import { Tooltip, useTranslation as useTranslation6 } from "@dxos/react-ui";
767
+ import { getSize as getSize2, mx as mx3, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
768
+ var Status;
769
+ (function(Status2) {
770
+ Status2[Status2["PERSISTED_LOCALLY"] = 0] = "PERSISTED_LOCALLY";
771
+ Status2[Status2["PENDING"] = 1] = "PENDING";
772
+ Status2[Status2["ERROR"] = 2] = "ERROR";
773
+ })(Status || (Status = {}));
815
774
  var PersistenceStatus = ({ db }) => {
816
- const { t } = useTranslation7(SPACE_PLUGIN);
817
- const [displayMessage, setDisplayMessage] = useState3(false);
818
- const [status, naturalSetStatus] = useState3(0);
819
- const [prevStatus, setPrevStatus] = useState3(0);
775
+ const { t } = useTranslation6(SPACE_PLUGIN);
776
+ const [displayMessage, setDisplayMessage] = useState2(false);
777
+ const [status, naturalSetStatus] = useState2(0);
778
+ const [prevStatus, setPrevStatus] = useState2(0);
820
779
  const _setStatus = debounce(naturalSetStatus, 500);
821
- useEffect3(() => {
780
+ useEffect2(() => {
822
781
  setPrevStatus(status);
823
782
  if (prevStatus !== status && status === 0) {
824
783
  setDisplayMessage(true);
@@ -830,48 +789,48 @@ var PersistenceStatus = ({ db }) => {
830
789
  ]);
831
790
  switch (status) {
832
791
  case 2:
833
- return /* @__PURE__ */ React7.createElement("div", {
792
+ return /* @__PURE__ */ React6.createElement("div", {
834
793
  className: "flex items-center"
835
- }, /* @__PURE__ */ React7.createElement(Warning, {
836
- className: mx4(getSize2(4), "me-1")
837
- }), /* @__PURE__ */ React7.createElement("span", {
838
- className: mx4("text-sm", warningText)
794
+ }, /* @__PURE__ */ React6.createElement(Warning, {
795
+ className: mx3(getSize2(4), "me-1")
796
+ }), /* @__PURE__ */ React6.createElement("span", {
797
+ className: mx3("text-sm", warningText)
839
798
  }, t("persistence error label")));
840
799
  case 1:
841
- return /* @__PURE__ */ React7.createElement("div", {
800
+ return /* @__PURE__ */ React6.createElement("div", {
842
801
  className: "flex items-center"
843
- }, /* @__PURE__ */ React7.createElement(ArrowsCounterClockwise, {
844
- className: mx4(getSize2(4), "me-1")
845
- }), /* @__PURE__ */ React7.createElement("span", {
846
- className: mx4("text-sm", staticPlaceholderText)
802
+ }, /* @__PURE__ */ React6.createElement(ArrowsCounterClockwise, {
803
+ className: mx3(getSize2(4), "me-1")
804
+ }), /* @__PURE__ */ React6.createElement("span", {
805
+ className: mx3("text-sm", staticPlaceholderText)
847
806
  }, t("persistence pending label")));
848
807
  case 0:
849
808
  default:
850
- return /* @__PURE__ */ React7.createElement(Tooltip.Root, {
809
+ return /* @__PURE__ */ React6.createElement(Tooltip.Root, {
851
810
  delayDuration: 400
852
- }, /* @__PURE__ */ React7.createElement(Tooltip.Trigger, {
811
+ }, /* @__PURE__ */ React6.createElement(Tooltip.Trigger, {
853
812
  role: "status",
854
813
  className: "flex items-center"
855
- }, /* @__PURE__ */ React7.createElement(CheckCircle2, {
856
- className: mx4(getSize2(4), "me-1")
857
- }), displayMessage && /* @__PURE__ */ React7.createElement("span", {
858
- className: mx4("text-sm", staticPlaceholderText)
859
- }, t("persisted locally label"))), /* @__PURE__ */ React7.createElement(Tooltip.Portal, null, /* @__PURE__ */ React7.createElement(Tooltip.Content, {
814
+ }, /* @__PURE__ */ React6.createElement(CheckCircle2, {
815
+ className: mx3(getSize2(4), "me-1")
816
+ }), displayMessage && /* @__PURE__ */ React6.createElement("span", {
817
+ className: mx3("text-sm", staticPlaceholderText)
818
+ }, t("persisted locally label"))), /* @__PURE__ */ React6.createElement(Tooltip.Portal, null, /* @__PURE__ */ React6.createElement(Tooltip.Content, {
860
819
  classNames: "z-10"
861
- }, t("persisted locally message"), /* @__PURE__ */ React7.createElement(Tooltip.Arrow, null))));
820
+ }, t("persisted locally message"), /* @__PURE__ */ React6.createElement(Tooltip.Arrow, null))));
862
821
  }
863
822
  };
864
823
 
865
824
  // packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx
866
- import React8, { useCallback, useRef, useState as useState4 } from "react";
825
+ import React7, { useCallback, useRef, useState as useState3 } from "react";
867
826
  import { log } from "@dxos/log";
868
- import { Button as Button2, Input as Input2, Popover, useTranslation as useTranslation8 } from "@dxos/react-ui";
827
+ import { Button as Button2, Input as Input2, Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
869
828
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx";
870
829
  var PopoverRenameObject = ({ object: obj }) => {
871
- const { t } = useTranslation8(SPACE_PLUGIN);
830
+ const { t } = useTranslation7(SPACE_PLUGIN);
872
831
  const doneButton = useRef(null);
873
832
  const object = obj;
874
- const [name, setName] = useState4(object.name || object.title || "");
833
+ const [name, setName] = useState3(object.name || object.title || "");
875
834
  const handleDone = useCallback(() => {
876
835
  try {
877
836
  object.name = name;
@@ -893,23 +852,23 @@ var PopoverRenameObject = ({ object: obj }) => {
893
852
  object,
894
853
  name
895
854
  ]);
896
- return /* @__PURE__ */ React8.createElement("div", {
855
+ return /* @__PURE__ */ React7.createElement("div", {
897
856
  role: "none",
898
857
  className: "p-1 flex gap-2"
899
- }, /* @__PURE__ */ React8.createElement("div", {
858
+ }, /* @__PURE__ */ React7.createElement("div", {
900
859
  role: "none",
901
860
  className: "flex-1"
902
- }, /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Label, {
861
+ }, /* @__PURE__ */ React7.createElement(Input2.Root, null, /* @__PURE__ */ React7.createElement(Input2.Label, {
903
862
  srOnly: true
904
- }, t("object name label")), /* @__PURE__ */ React8.createElement(Input2.TextInput, {
863
+ }, t("object name label")), /* @__PURE__ */ React7.createElement(Input2.TextInput, {
905
864
  placeholder: t("object title placeholder"),
906
865
  value: name,
907
866
  "data-testid": "spacePlugin.renameObject.input",
908
867
  onChange: ({ target: { value } }) => setName(value),
909
868
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
910
- }))), /* @__PURE__ */ React8.createElement(Popover.Close, {
869
+ }))), /* @__PURE__ */ React7.createElement(Popover.Close, {
911
870
  asChild: true
912
- }, /* @__PURE__ */ React8.createElement(Button2, {
871
+ }, /* @__PURE__ */ React7.createElement(Button2, {
913
872
  ref: doneButton,
914
873
  classNames: "self-stretch",
915
874
  onClick: handleDone
@@ -919,36 +878,36 @@ var PopoverRenameObject = ({ object: obj }) => {
919
878
  };
920
879
 
921
880
  // packages/plugins/plugin-space/src/components/PopoverRenameSpace.tsx
922
- import React9, { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
923
- import { Button as Button3, Input as Input3, Popover as Popover2, useTranslation as useTranslation9 } from "@dxos/react-ui";
881
+ import React8, { useCallback as useCallback2, useRef as useRef2, useState as useState4 } from "react";
882
+ import { Button as Button3, Input as Input3, Popover as Popover2, useTranslation as useTranslation8 } from "@dxos/react-ui";
924
883
  var PopoverRenameSpace = ({ space }) => {
925
- const { t } = useTranslation9(SPACE_PLUGIN);
884
+ const { t } = useTranslation8(SPACE_PLUGIN);
926
885
  const doneButton = useRef2(null);
927
- const [name, setName] = useState5(space.properties.name ?? "");
886
+ const [name, setName] = useState4(space.properties.name ?? "");
928
887
  const handleDone = useCallback2(() => {
929
888
  space.properties.name = name;
930
889
  }, [
931
890
  space,
932
891
  name
933
892
  ]);
934
- return /* @__PURE__ */ React9.createElement("div", {
893
+ return /* @__PURE__ */ React8.createElement("div", {
935
894
  role: "none",
936
895
  className: "p-1 flex gap-2"
937
- }, /* @__PURE__ */ React9.createElement("div", {
896
+ }, /* @__PURE__ */ React8.createElement("div", {
938
897
  role: "none",
939
898
  className: "flex-1"
940
- }, /* @__PURE__ */ React9.createElement(Input3.Root, null, /* @__PURE__ */ React9.createElement(Input3.Label, {
899
+ }, /* @__PURE__ */ React8.createElement(Input3.Root, null, /* @__PURE__ */ React8.createElement(Input3.Label, {
941
900
  srOnly: true
942
- }, t("space name label")), /* @__PURE__ */ React9.createElement(Input3.TextInput, {
901
+ }, t("space name label")), /* @__PURE__ */ React8.createElement(Input3.TextInput, {
943
902
  defaultValue: space.properties.name ?? "",
944
903
  placeholder: t("unnamed space label"),
945
904
  onChange: ({ target: { value } }) => setName(value),
946
905
  // TODO(wittjosiah): Ideally this should access the popover context to close the popover.
947
906
  // Currently this is not possible because Radix does not expose the popover context.
948
907
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
949
- }))), /* @__PURE__ */ React9.createElement(Popover2.Close, {
908
+ }))), /* @__PURE__ */ React8.createElement(Popover2.Close, {
950
909
  asChild: true
951
- }, /* @__PURE__ */ React9.createElement(Button3, {
910
+ }, /* @__PURE__ */ React8.createElement(Button3, {
952
911
  ref: doneButton,
953
912
  classNames: "self-stretch",
954
913
  onClick: handleDone
@@ -958,12 +917,12 @@ var PopoverRenameSpace = ({ space }) => {
958
917
  };
959
918
 
960
919
  // packages/plugins/plugin-space/src/components/ShareSpaceButton.tsx
961
- import React10 from "react";
920
+ import React9 from "react";
962
921
  import { useIntentDispatcher } from "@dxos/app-framework";
963
- import { Button as Button4, useTranslation as useTranslation10 } from "@dxos/react-ui";
922
+ import { Button as Button4, useTranslation as useTranslation9 } from "@dxos/react-ui";
964
923
  var ShareSpaceButton = ({ spaceId }) => {
965
924
  const dispatch = useIntentDispatcher();
966
- return /* @__PURE__ */ React10.createElement(ShareSpaceButtonImpl, {
925
+ return /* @__PURE__ */ React9.createElement(ShareSpaceButtonImpl, {
967
926
  onClick: () => dispatch({
968
927
  action: SpaceAction.SHARE,
969
928
  data: {
@@ -973,8 +932,8 @@ var ShareSpaceButton = ({ spaceId }) => {
973
932
  });
974
933
  };
975
934
  var ShareSpaceButtonImpl = ({ onClick }) => {
976
- const { t } = useTranslation10(SPACE_PLUGIN);
977
- return /* @__PURE__ */ React10.createElement(Button4, {
935
+ const { t } = useTranslation9(SPACE_PLUGIN);
936
+ return /* @__PURE__ */ React9.createElement(Button4, {
978
937
  "data-testid": "spacePlugin.shareSpaceButton",
979
938
  onClick,
980
939
  classNames: "mli-1"
@@ -983,30 +942,30 @@ var ShareSpaceButtonImpl = ({ onClick }) => {
983
942
 
984
943
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
985
944
  import { Command } from "@phosphor-icons/react";
986
- import React12 from "react";
945
+ import React11 from "react";
987
946
  import { Surface } from "@dxos/app-framework";
988
947
  import { SpaceState as SpaceState2 } from "@dxos/react-client/echo";
989
- import { Main, useTranslation as useTranslation12 } from "@dxos/react-ui";
990
- import { getSize as getSize4, mx as mx6, topbarBlockPaddingStart } from "@dxos/react-ui-theme";
948
+ import { Main, useTranslation as useTranslation11 } from "@dxos/react-ui";
949
+ import { getSize as getSize4, mx as mx5, topbarBlockPaddingStart } from "@dxos/react-ui-theme";
991
950
  import { ClipboardProvider } from "@dxos/shell/react";
992
951
 
993
952
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMembersSection.tsx
994
953
  import { CaretDown, Check, UserPlus, UsersThree } from "@phosphor-icons/react";
995
- import React11, { useCallback as useCallback3, useState as useState6 } from "react";
954
+ import React10, { useCallback as useCallback3, useState as useState5 } from "react";
996
955
  import { LayoutAction, useIntent } from "@dxos/app-framework";
997
956
  import { useMembers, SpaceMember, useSpaceInvitations } from "@dxos/react-client/echo";
998
957
  import { InvitationEncoder } from "@dxos/react-client/invitations";
999
958
  import { Invitation } from "@dxos/react-client/invitations";
1000
- import { Button as Button5, ButtonGroup, DropdownMenu as DropdownMenu2, List, useTranslation as useTranslation11 } from "@dxos/react-ui";
1001
- import { descriptionText as descriptionText3, getSize as getSize3, mx as mx5 } from "@dxos/react-ui-theme";
959
+ import { Button as Button5, ButtonGroup, DropdownMenu as DropdownMenu2, List, useTranslation as useTranslation10 } from "@dxos/react-ui";
960
+ import { descriptionText as descriptionText2, getSize as getSize3, mx as mx4 } from "@dxos/react-ui-theme";
1002
961
  import { InvitationListItem, IdentityListItem } from "@dxos/shell/react";
1003
962
  var activeActionKeyStorageKey = "dxos:react-shell/space-manager/active-action";
1004
963
  var Presence = SpaceMember.PresenceState;
1005
964
  var handleCreateInvitationUrl = (invitationCode) => `${origin}?spaceInvitationCode=${invitationCode}`;
1006
965
  var SpaceMemberList = ({ members }) => {
1007
- return members.length > 0 ? /* @__PURE__ */ React11.createElement(List, {
966
+ return members.length > 0 ? /* @__PURE__ */ React10.createElement(List, {
1008
967
  classNames: "col-start-2 col-end-5 gap-y-1 grid grid-cols-subgrid items-center"
1009
- }, members.map((member) => /* @__PURE__ */ React11.createElement(IdentityListItem, {
968
+ }, members.map((member) => /* @__PURE__ */ React10.createElement(IdentityListItem, {
1010
969
  classNames: "contents",
1011
970
  key: member.identity.identityKey.toHex(),
1012
971
  identity: member.identity,
@@ -1014,7 +973,7 @@ var SpaceMemberList = ({ members }) => {
1014
973
  }))) : null;
1015
974
  };
1016
975
  var SpaceMembersSection = ({ space }) => {
1017
- const { t } = useTranslation11(SPACE_PLUGIN);
976
+ const { t } = useTranslation10(SPACE_PLUGIN);
1018
977
  const invitations = useSpaceInvitations(space.key);
1019
978
  const { dispatch } = useIntent();
1020
979
  const handleCloseDialog = () => dispatch({
@@ -1079,7 +1038,7 @@ var SpaceMembersSection = ({ space }) => {
1079
1038
  ])
1080
1039
  }
1081
1040
  };
1082
- const [activeActionKey, setInternalActiveActionKey] = useState6(localStorage.getItem(activeActionKeyStorageKey) ?? "inviteOne");
1041
+ const [activeActionKey, setInternalActiveActionKey] = useState5(localStorage.getItem(activeActionKeyStorageKey) ?? "inviteOne");
1083
1042
  const setActiveActionKey = (nextKey) => {
1084
1043
  setInternalActiveActionKey(nextKey);
1085
1044
  localStorage.setItem(activeActionKeyStorageKey, nextKey);
@@ -1092,103 +1051,103 @@ var SpaceMembersSection = ({ space }) => {
1092
1051
  [Presence.ONLINE]: [],
1093
1052
  [Presence.OFFLINE]: []
1094
1053
  });
1095
- return /* @__PURE__ */ React11.createElement("section", {
1054
+ return /* @__PURE__ */ React10.createElement("section", {
1096
1055
  className: "mbe-4 col-span-3 grid gap-y-2 grid-cols-subgrid auto-rows-min"
1097
- }, /* @__PURE__ */ React11.createElement("h2", {
1056
+ }, /* @__PURE__ */ React10.createElement("h2", {
1098
1057
  className: "contents"
1099
- }, /* @__PURE__ */ React11.createElement(UsersThree, {
1058
+ }, /* @__PURE__ */ React10.createElement(UsersThree, {
1100
1059
  weight: "duotone",
1101
- className: mx5(getSize3(5), "place-self-center")
1102
- }), /* @__PURE__ */ React11.createElement("span", {
1060
+ className: mx4(getSize3(5), "place-self-center")
1061
+ }), /* @__PURE__ */ React10.createElement("span", {
1103
1062
  className: "text-lg col-span-2"
1104
- }, t("space members label"))), /* @__PURE__ */ React11.createElement("h3", {
1063
+ }, t("space members label"))), /* @__PURE__ */ React10.createElement("h3", {
1105
1064
  className: "col-start-2 col-span-3 text-sm italic text-description"
1106
- }, t("invitations heading")), invitations.length > 0 && /* @__PURE__ */ React11.createElement(List, {
1065
+ }, t("invitations heading")), invitations.length > 0 && /* @__PURE__ */ React10.createElement(List, {
1107
1066
  classNames: "col-start-2 col-span-2 gap-y-2 grid grid-cols-[var(--rail-size)_1fr_var(--rail-action)_var(--rail-action)]"
1108
- }, invitations.map((invitation) => /* @__PURE__ */ React11.createElement(InvitationListItem, {
1067
+ }, invitations.map((invitation) => /* @__PURE__ */ React10.createElement(InvitationListItem, {
1109
1068
  reverseEffects: true,
1110
1069
  classNames: "pis-0 pie-0 gap-0 col-span-4 grid grid-cols-subgrid",
1111
1070
  key: invitation.get().invitationId,
1112
1071
  invitation,
1113
1072
  send: handleInvitationSelect,
1114
1073
  createInvitationUrl: handleCreateInvitationUrl
1115
- }))), /* @__PURE__ */ React11.createElement(ButtonGroup, {
1074
+ }))), /* @__PURE__ */ React10.createElement(ButtonGroup, {
1116
1075
  classNames: "col-start-2 col-end-4 grid grid-cols-[1fr_var(--rail-action)] place-self-grow gap-px"
1117
- }, /* @__PURE__ */ React11.createElement(Button5, {
1076
+ }, /* @__PURE__ */ React10.createElement(Button5, {
1118
1077
  classNames: "gap-2",
1119
1078
  onClick: activeAction.onClick
1120
- }, /* @__PURE__ */ React11.createElement(activeAction.icon, {
1079
+ }, /* @__PURE__ */ React10.createElement(activeAction.icon, {
1121
1080
  className: getSize3(5)
1122
- }), /* @__PURE__ */ React11.createElement("span", null, t(activeAction.label, {
1081
+ }), /* @__PURE__ */ React10.createElement("span", null, t(activeAction.label, {
1123
1082
  ns: "os"
1124
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Trigger, {
1083
+ }))), /* @__PURE__ */ React10.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React10.createElement(DropdownMenu2.Trigger, {
1125
1084
  asChild: true
1126
- }, /* @__PURE__ */ React11.createElement(Button5, {
1085
+ }, /* @__PURE__ */ React10.createElement(Button5, {
1127
1086
  classNames: "pli-0"
1128
- }, /* @__PURE__ */ React11.createElement(CaretDown, {
1087
+ }, /* @__PURE__ */ React10.createElement(CaretDown, {
1129
1088
  className: getSize3(4)
1130
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Viewport, null, Object.entries(inviteActions).map(([id, action]) => {
1131
- return /* @__PURE__ */ React11.createElement(DropdownMenu2.CheckboxItem, {
1089
+ }))), /* @__PURE__ */ React10.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React10.createElement(DropdownMenu2.Viewport, null, Object.entries(inviteActions).map(([id, action]) => {
1090
+ return /* @__PURE__ */ React10.createElement(DropdownMenu2.CheckboxItem, {
1132
1091
  key: id,
1133
1092
  "aria-labelledby": `${id}__label`,
1134
1093
  "aria-describedby": `${id}__description`,
1135
1094
  checked: activeActionKey === id,
1136
1095
  onCheckedChange: (checked) => checked && setActiveActionKey(id),
1137
1096
  classNames: "gap-2"
1138
- }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
1097
+ }, action.icon && /* @__PURE__ */ React10.createElement(action.icon, {
1139
1098
  className: getSize3(5)
1140
- }), /* @__PURE__ */ React11.createElement("div", {
1099
+ }), /* @__PURE__ */ React10.createElement("div", {
1141
1100
  role: "none",
1142
1101
  className: "flex-1 min-is-0 space-b-1"
1143
- }, /* @__PURE__ */ React11.createElement("p", {
1102
+ }, /* @__PURE__ */ React10.createElement("p", {
1144
1103
  id: `${id}__label`
1145
1104
  }, t(action.label, {
1146
1105
  ns: "os"
1147
- })), action.description && /* @__PURE__ */ React11.createElement("p", {
1106
+ })), action.description && /* @__PURE__ */ React10.createElement("p", {
1148
1107
  id: `${id}__description`,
1149
- className: descriptionText3
1108
+ className: descriptionText2
1150
1109
  }, t(action.description, {
1151
1110
  ns: "os"
1152
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.ItemIndicator, {
1111
+ }))), /* @__PURE__ */ React10.createElement(DropdownMenu2.ItemIndicator, {
1153
1112
  asChild: true
1154
- }, /* @__PURE__ */ React11.createElement(Check, {
1113
+ }, /* @__PURE__ */ React10.createElement(Check, {
1155
1114
  className: getSize3(4)
1156
1115
  })));
1157
- })), /* @__PURE__ */ React11.createElement(DropdownMenu2.Arrow, null)))), members[Presence.ONLINE].length + members[Presence.OFFLINE].length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1158
- className: mx5(descriptionText3, "text-center is-full mlb-2")
1116
+ })), /* @__PURE__ */ React10.createElement(DropdownMenu2.Arrow, null)))), members[Presence.ONLINE].length + members[Presence.OFFLINE].length < 1 ? /* @__PURE__ */ React10.createElement("p", {
1117
+ className: mx4(descriptionText2, "text-center is-full mlb-2")
1159
1118
  }, t("empty space members message", {
1160
1119
  ns: "os"
1161
- })) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("h3", {
1120
+ })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("h3", {
1162
1121
  className: "col-start-2 col-end-5 text-sm italic text-description"
1163
1122
  }, t("active space members heading", {
1164
1123
  count: members[Presence.ONLINE].length
1165
- })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1124
+ })), /* @__PURE__ */ React10.createElement(SpaceMemberList, {
1166
1125
  members: members[Presence.ONLINE]
1167
- }), /* @__PURE__ */ React11.createElement("h3", {
1126
+ }), /* @__PURE__ */ React10.createElement("h3", {
1168
1127
  className: "col-start-2 col-end-5 text-sm italic text-description"
1169
1128
  }, t("inactive space members heading", {
1170
1129
  count: members[Presence.OFFLINE].length
1171
- })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1130
+ })), /* @__PURE__ */ React10.createElement(SpaceMemberList, {
1172
1131
  members: members[Presence.OFFLINE]
1173
1132
  })));
1174
1133
  };
1175
1134
 
1176
1135
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
1177
1136
  var KeyShortcuts = () => {
1178
- const { t } = useTranslation12(SPACE_PLUGIN);
1179
- return /* @__PURE__ */ React12.createElement("section", {
1137
+ const { t } = useTranslation11(SPACE_PLUGIN);
1138
+ return /* @__PURE__ */ React11.createElement("section", {
1180
1139
  className: "mbe-4 col-span-4 md:col-start-5 md:col-end-7 grid grid-cols-subgrid gap-y-2 auto-rows-min"
1181
- }, /* @__PURE__ */ React12.createElement("h2", {
1140
+ }, /* @__PURE__ */ React11.createElement("h2", {
1182
1141
  className: "contents"
1183
- }, /* @__PURE__ */ React12.createElement(Command, {
1142
+ }, /* @__PURE__ */ React11.createElement(Command, {
1184
1143
  weight: "duotone",
1185
- className: mx6(getSize4(5), "place-self-center")
1186
- }), /* @__PURE__ */ React12.createElement("span", {
1144
+ className: mx5(getSize4(5), "place-self-center")
1145
+ }), /* @__PURE__ */ React11.createElement("span", {
1187
1146
  className: "text-lg col-span-2 md:col-span-1"
1188
- }, t("keyshortcuts label"))), /* @__PURE__ */ React12.createElement("div", {
1147
+ }, t("keyshortcuts label"))), /* @__PURE__ */ React11.createElement("div", {
1189
1148
  role: "none",
1190
1149
  className: "col-start-2 col-end-4 md:col-end-5 pie-2"
1191
- }, /* @__PURE__ */ React12.createElement(Surface, {
1150
+ }, /* @__PURE__ */ React11.createElement(Surface, {
1192
1151
  role: "keyshortcuts"
1193
1152
  })));
1194
1153
  };
@@ -1197,7 +1156,7 @@ var SpaceMain = ({ space, role }) => {
1197
1156
  const state = space.state.get();
1198
1157
  const ready = state === SpaceState2.SPACE_READY;
1199
1158
  const Root = role === "main" ? Main.Content : "div";
1200
- return /* @__PURE__ */ React12.createElement(ClipboardProvider, null, /* @__PURE__ */ React12.createElement(Root, {
1159
+ return /* @__PURE__ */ React11.createElement(ClipboardProvider, null, /* @__PURE__ */ React11.createElement(Root, {
1201
1160
  ...role === "main" ? {
1202
1161
  classNames: [
1203
1162
  topbarBlockPaddingStart,
@@ -1206,23 +1165,23 @@ var SpaceMain = ({ space, role }) => {
1206
1165
  ]
1207
1166
  } : {
1208
1167
  role: "none",
1209
- className: mx6(topbarBlockPaddingStart, "row-span-2", spaceMainLayout)
1168
+ className: mx5(topbarBlockPaddingStart, "row-span-2", spaceMainLayout)
1210
1169
  },
1211
1170
  "data-testid": `spacePlugin.${role}`,
1212
1171
  "data-isready": ready ? "true" : "false"
1213
- }, ready && /* @__PURE__ */ React12.createElement(SpaceMembersSection, {
1172
+ }, ready && /* @__PURE__ */ React11.createElement(SpaceMembersSection, {
1214
1173
  space
1215
- }), /* @__PURE__ */ React12.createElement(KeyShortcuts, null)));
1174
+ }), /* @__PURE__ */ React11.createElement(KeyShortcuts, null)));
1216
1175
  };
1217
1176
 
1218
1177
  // packages/plugins/plugin-space/src/components/SpacePresence.tsx
1219
- import React13, { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
1178
+ import React12, { useCallback as useCallback4, useEffect as useEffect3, useState as useState6 } from "react";
1220
1179
  import { usePlugin } from "@dxos/app-framework";
1221
1180
  import { generateName } from "@dxos/display-name";
1222
1181
  import { PublicKey, useClient as useClient3 } from "@dxos/react-client";
1223
1182
  import { getSpace as getSpace3, useMembers as useMembers2, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1224
1183
  import { useIdentity } from "@dxos/react-client/halo";
1225
- import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation13, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1184
+ import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation12, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1226
1185
  import { AttentionGlyph, useAttention } from "@dxos/react-ui-attention";
1227
1186
  import { ComplexMap, keyToFallback } from "@dxos/util";
1228
1187
  var REFRESH_INTERVAL = 5e3;
@@ -1235,8 +1194,8 @@ var SpacePresence = ({ object, spaceKey }) => {
1235
1194
  const identity = useIdentity();
1236
1195
  const space = spaceKey ? client.spaces.get(spaceKey) : getSpace3(object);
1237
1196
  const spaceMembers = useMembers2(space?.key);
1238
- const [_moment, setMoment] = useState7(Date.now());
1239
- useEffect4(() => {
1197
+ const [_moment, setMoment] = useState6(Date.now());
1198
+ useEffect3(() => {
1240
1199
  const interval = setInterval(() => setMoment(Date.now()), REFRESH_INTERVAL);
1241
1200
  return () => clearInterval(interval);
1242
1201
  }, []);
@@ -1259,7 +1218,7 @@ var SpacePresence = ({ object, spaceKey }) => {
1259
1218
  lastSeen
1260
1219
  };
1261
1220
  }).toSorted((a, b) => a.lastSeen - b.lastSeen);
1262
- return /* @__PURE__ */ React13.createElement(FullPresence, {
1221
+ return /* @__PURE__ */ React12.createElement(FullPresence, {
1263
1222
  members: membersForObject
1264
1223
  });
1265
1224
  };
@@ -1269,38 +1228,38 @@ var FullPresence = (props) => {
1269
1228
  if (members.length === 0) {
1270
1229
  return null;
1271
1230
  }
1272
- return /* @__PURE__ */ React13.createElement(AvatarGroup.Root, {
1231
+ return /* @__PURE__ */ React12.createElement(AvatarGroup.Root, {
1273
1232
  size,
1274
1233
  classNames: "mbs-2 mie-4",
1275
1234
  "data-testid": "spacePlugin.presence"
1276
- }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React13.createElement(Tooltip2.Root, {
1235
+ }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React12.createElement(Tooltip2.Root, {
1277
1236
  key: member.identity.identityKey.toHex()
1278
- }, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1237
+ }, /* @__PURE__ */ React12.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React12.createElement(PrensenceAvatar, {
1279
1238
  identity: member.identity,
1280
1239
  group: true,
1281
1240
  match: member.currentlyAttended,
1282
1241
  index: members.length - i,
1283
1242
  onClick: () => onMemberClick?.(member)
1284
- })), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1243
+ })), /* @__PURE__ */ React12.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React12.createElement(Tooltip2.Content, {
1285
1244
  side: "bottom"
1286
- }, /* @__PURE__ */ React13.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(AvatarGroupItem.Root, {
1245
+ }, /* @__PURE__ */ React12.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React12.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React12.createElement(Tooltip2.Root, null, /* @__PURE__ */ React12.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React12.createElement(AvatarGroupItem.Root, {
1287
1246
  status: "inactive"
1288
- }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1247
+ }, /* @__PURE__ */ React12.createElement(Avatar.Frame, {
1289
1248
  style: {
1290
1249
  zIndex: members.length - 4
1291
1250
  }
1292
- }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1251
+ }, /* @__PURE__ */ React12.createElement(Avatar.Fallback, {
1293
1252
  text: `+${members.length - 3}`
1294
- })))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1253
+ })))), /* @__PURE__ */ React12.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React12.createElement(Tooltip2.Content, {
1295
1254
  side: "bottom"
1296
- }, /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React13.createElement(List2, {
1255
+ }, /* @__PURE__ */ React12.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React12.createElement(List2, {
1297
1256
  classNames: "max-h-56 overflow-y-auto"
1298
- }, members.map((member) => /* @__PURE__ */ React13.createElement(ListItem.Root, {
1257
+ }, members.map((member) => /* @__PURE__ */ React12.createElement(ListItem.Root, {
1299
1258
  key: member.identity.identityKey.toHex(),
1300
1259
  classNames: "flex gap-2 items-center cursor-pointer mbe-2",
1301
1260
  onClick: () => onMemberClick?.(member),
1302
1261
  "data-testid": "identity-list-item"
1303
- }, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1262
+ }, /* @__PURE__ */ React12.createElement(PrensenceAvatar, {
1304
1263
  identity: member.identity,
1305
1264
  showName: true,
1306
1265
  match: member.currentlyAttended
@@ -1310,10 +1269,10 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1310
1269
  const Root = group ? AvatarGroupItem.Root : Avatar.Root;
1311
1270
  const status = match ? "current" : "active";
1312
1271
  const fallbackValue = keyToFallback(identity.identityKey);
1313
- return /* @__PURE__ */ React13.createElement(Root, {
1272
+ return /* @__PURE__ */ React12.createElement(Root, {
1314
1273
  status,
1315
1274
  hue: identity.profile?.data?.hue || fallbackValue.hue
1316
- }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1275
+ }, /* @__PURE__ */ React12.createElement(Avatar.Frame, {
1317
1276
  "data-testid": "spacePlugin.presence.member",
1318
1277
  "data-status": status,
1319
1278
  ...index ? {
@@ -1322,9 +1281,9 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1322
1281
  }
1323
1282
  } : {},
1324
1283
  onClick: () => onClick?.()
1325
- }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1284
+ }, /* @__PURE__ */ React12.createElement(Avatar.Fallback, {
1326
1285
  text: identity.profile?.data?.emoji || fallbackValue.emoji
1327
- })), showName && /* @__PURE__ */ React13.createElement(Avatar.Label, {
1286
+ })), showName && /* @__PURE__ */ React12.createElement(Avatar.Label, {
1328
1287
  classNames: "text-sm truncate pli-2"
1329
1288
  }, getName(identity)));
1330
1289
  };
@@ -1333,8 +1292,8 @@ var SmallPresenceLive = ({ id, viewers }) => {
1333
1292
  const moment = Date.now();
1334
1293
  return Array.from(viewers2.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION);
1335
1294
  };
1336
- const [activeViewers, setActiveViewers] = useState7(viewers ? getActiveViewers(viewers) : []);
1337
- useEffect4(() => {
1295
+ const [activeViewers, setActiveViewers] = useState6(viewers ? getActiveViewers(viewers) : []);
1296
+ useEffect3(() => {
1338
1297
  if (viewers) {
1339
1298
  setActiveViewers(getActiveViewers(viewers));
1340
1299
  const interval = setInterval(() => {
@@ -1345,44 +1304,44 @@ var SmallPresenceLive = ({ id, viewers }) => {
1345
1304
  }, [
1346
1305
  viewers
1347
1306
  ]);
1348
- return /* @__PURE__ */ React13.createElement(SmallPresence, {
1307
+ return /* @__PURE__ */ React12.createElement(SmallPresence, {
1349
1308
  id,
1350
1309
  count: activeViewers.length
1351
1310
  });
1352
1311
  };
1353
1312
  var SmallPresence = ({ id, count }) => {
1354
- const { t } = useTranslation13(SPACE_PLUGIN);
1313
+ const { t } = useTranslation12(SPACE_PLUGIN);
1355
1314
  const { hasAttention, isAncestor, isRelated } = useAttention(id);
1356
1315
  const attention = hasAttention || isAncestor || isRelated;
1357
- return /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, {
1316
+ return /* @__PURE__ */ React12.createElement(Tooltip2.Root, null, /* @__PURE__ */ React12.createElement(Tooltip2.Trigger, {
1358
1317
  asChild: true
1359
- }, /* @__PURE__ */ React13.createElement("div", {
1318
+ }, /* @__PURE__ */ React12.createElement("div", {
1360
1319
  role: "none",
1361
1320
  className: "flex",
1362
1321
  "data-attention": attention
1363
- }, /* @__PURE__ */ React13.createElement(AttentionGlyph, {
1322
+ }, /* @__PURE__ */ React12.createElement(AttentionGlyph, {
1364
1323
  presence: count > 1 ? "many" : count === 1 ? "one" : "none",
1365
1324
  classNames: "self-center mie-1"
1366
- }))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1325
+ }))), /* @__PURE__ */ React12.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React12.createElement(Tooltip2.Content, {
1367
1326
  side: "bottom",
1368
1327
  classNames: "z-[70]"
1369
- }, /* @__PURE__ */ React13.createElement("span", null, t("presence label", {
1328
+ }, /* @__PURE__ */ React12.createElement("span", null, t("presence label", {
1370
1329
  count
1371
- })), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))));
1330
+ })), /* @__PURE__ */ React12.createElement(Tooltip2.Arrow, null))));
1372
1331
  };
1373
1332
 
1374
1333
  // packages/plugins/plugin-space/src/components/SpaceSettings.tsx
1375
- import React14 from "react";
1334
+ import React13 from "react";
1376
1335
  import { useIntentDispatcher as useIntentDispatcher2, useResolvePlugins } from "@dxos/app-framework";
1377
- import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation14 } from "@dxos/react-ui";
1378
- import { FormInput } from "@dxos/react-ui-data";
1336
+ import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation13 } from "@dxos/react-ui";
1337
+ import { DeprecatedFormInput } from "@dxos/react-ui-data";
1379
1338
  var SpaceSettings = ({ settings }) => {
1380
- const { t } = useTranslation14(SPACE_PLUGIN);
1339
+ const { t } = useTranslation13(SPACE_PLUGIN);
1381
1340
  const dispatch = useIntentDispatcher2();
1382
1341
  const plugins = useResolvePlugins(parseSpaceInitPlugin);
1383
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(FormInput, {
1342
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(DeprecatedFormInput, {
1384
1343
  label: t("show hidden spaces label")
1385
- }, /* @__PURE__ */ React14.createElement(Input4.Switch, {
1344
+ }, /* @__PURE__ */ React13.createElement(Input4.Switch, {
1386
1345
  checked: settings.showHidden,
1387
1346
  onCheckedChange: (checked) => dispatch({
1388
1347
  plugin: SPACE_PLUGIN,
@@ -1391,34 +1350,41 @@ var SpaceSettings = ({ settings }) => {
1391
1350
  state: !!checked
1392
1351
  }
1393
1352
  })
1394
- })), /* @__PURE__ */ React14.createElement(FormInput, {
1353
+ })), /* @__PURE__ */ React13.createElement(DeprecatedFormInput, {
1395
1354
  label: t("default on space create label")
1396
- }, /* @__PURE__ */ React14.createElement(Select.Root, {
1355
+ }, /* @__PURE__ */ React13.createElement(Select.Root, {
1397
1356
  value: settings.onSpaceCreate,
1398
1357
  onValueChange: (value) => {
1399
1358
  settings.onSpaceCreate = value;
1400
1359
  }
1401
- }, /* @__PURE__ */ React14.createElement(Select.TriggerButton, null), /* @__PURE__ */ React14.createElement(Select.Portal, null, /* @__PURE__ */ React14.createElement(Select.Content, null, /* @__PURE__ */ React14.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React14.createElement(Select.Option, {
1360
+ }, /* @__PURE__ */ React13.createElement(Select.TriggerButton, null), /* @__PURE__ */ React13.createElement(Select.Portal, null, /* @__PURE__ */ React13.createElement(Select.Content, null, /* @__PURE__ */ React13.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React13.createElement(Select.Option, {
1402
1361
  key: onSpaceCreate.action,
1403
1362
  value: onSpaceCreate.action
1404
1363
  }, toLocalizedString2(onSpaceCreate.label, t)))))))));
1405
1364
  };
1406
1365
 
1407
1366
  // packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx
1408
- import React15, { useCallback as useCallback5, useState as useState8 } from "react";
1367
+ import React14, { useCallback as useCallback5, useState as useState7 } from "react";
1409
1368
  import { log as log2 } from "@dxos/log";
1410
1369
  import { EdgeReplicationSetting } from "@dxos/protocols/proto/dxos/echo/metadata";
1411
- import { Input as Input5, useTranslation as useTranslation15 } from "@dxos/react-ui";
1370
+ import { useClient as useClient4 } from "@dxos/react-client";
1371
+ import { DeviceType, useDevices } from "@dxos/react-client/halo";
1372
+ import { Input as Input5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1412
1373
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx";
1413
1374
  var SpaceSettingsPanel = ({ space }) => {
1414
- const { t } = useTranslation15(SPACE_PLUGIN);
1415
- const [edgeReplication, setEdgeReplication] = useState8(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1375
+ const { t } = useTranslation14(SPACE_PLUGIN);
1376
+ const client = useClient4();
1377
+ const devices = useDevices();
1378
+ const managedDeviceAvailable = devices.find((device) => device.profile?.type === DeviceType.AGENT_MANAGED);
1379
+ const edgeAgents = Boolean(client.config.values.runtime?.client?.edgeFeatures?.agents);
1380
+ const edgeReplicationAvailable = edgeAgents && managedDeviceAvailable;
1381
+ const [edgeReplication, setEdgeReplication] = useState7(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1416
1382
  const toggleEdgeReplication = useCallback5(async (next) => {
1417
1383
  setEdgeReplication(next);
1418
1384
  await space?.internal.setEdgeReplicationPreference(next ? EdgeReplicationSetting.ENABLED : EdgeReplicationSetting.DISABLED).catch((err) => {
1419
1385
  log2.catch(err, void 0, {
1420
1386
  F: __dxlog_file3,
1421
- L: 30,
1387
+ L: 38,
1422
1388
  S: void 0,
1423
1389
  C: (f, a) => f(...a)
1424
1390
  });
@@ -1427,50 +1393,129 @@ var SpaceSettingsPanel = ({ space }) => {
1427
1393
  }, [
1428
1394
  space
1429
1395
  ]);
1430
- return /* @__PURE__ */ React15.createElement("div", {
1396
+ return /* @__PURE__ */ React14.createElement("div", {
1431
1397
  role: "form",
1432
1398
  className: "flex flex-col w-full p-2 gap-4"
1433
- }, /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1399
+ }, /* @__PURE__ */ React14.createElement(Input5.Root, null, /* @__PURE__ */ React14.createElement("div", {
1434
1400
  role: "none",
1435
1401
  className: "flex flex-col gap-1"
1436
- }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("name label")), /* @__PURE__ */ React15.createElement(Input5.TextInput, {
1402
+ }, /* @__PURE__ */ React14.createElement(Input5.Label, null, t("name label")), /* @__PURE__ */ React14.createElement(Input5.TextInput, {
1437
1403
  placeholder: t("name placeholder"),
1438
- value: space.properties.name,
1404
+ value: space.properties.name ?? "",
1439
1405
  onChange: (event) => {
1440
1406
  space.properties.name = event.target.value;
1441
1407
  }
1442
- }))), /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1408
+ }))), edgeReplicationAvailable && /* @__PURE__ */ React14.createElement(Input5.Root, null, /* @__PURE__ */ React14.createElement("div", {
1443
1409
  role: "none",
1444
1410
  className: "flex justify-between"
1445
- }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("edge replication label")), /* @__PURE__ */ React15.createElement(Input5.Switch, {
1411
+ }, /* @__PURE__ */ React14.createElement(Input5.Label, null, t("edge replication label")), /* @__PURE__ */ React14.createElement(Input5.Switch, {
1446
1412
  checked: edgeReplication,
1447
1413
  onCheckedChange: toggleEdgeReplication
1448
1414
  }))));
1449
1415
  };
1450
1416
 
1451
- // packages/plugins/plugin-space/src/components/SaveStatus.tsx
1452
- import React16, { useEffect as useEffect5, useState as useState9 } from "react";
1453
- import { Context } from "@dxos/context";
1417
+ // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1418
+ import React16, { useEffect as useEffect6, useState as useState10 } from "react";
1454
1419
  import { StatusBar } from "@dxos/plugin-status-bar";
1455
- import { useClient as useClient4 } from "@dxos/react-client";
1456
- import { Icon, useTranslation as useTranslation16 } from "@dxos/react-ui";
1457
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SaveStatus.tsx";
1458
- var SaveStatus = () => {
1459
- const { t } = useTranslation16(SPACE_PLUGIN);
1460
- const client = useClient4();
1461
- const [state, setState] = useState9("saved");
1462
- useEffect5(() => {
1463
- return createClientSaveTracker(client, (state2) => {
1464
- setState(state2);
1465
- });
1466
- }, []);
1467
- return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1468
- title: state === "saving" ? t("saving label") : t("saved label")
1469
- }, /* @__PURE__ */ React16.createElement(Icon, {
1470
- icon: state === "saving" ? "ph--arrows-clockwise--regular" : "ph--check-circle--regular",
1471
- size: 4
1420
+ import { useClient as useClient6 } from "@dxos/react-client";
1421
+ import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation15 } from "@dxos/react-ui";
1422
+ import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1423
+ import { mx as mx7 } from "@dxos/react-ui-theme";
1424
+
1425
+ // packages/plugins/plugin-space/src/components/SyncStatus/Space.tsx
1426
+ import React15, { useEffect as useEffect4, useState as useState8 } from "react";
1427
+ import { Icon } from "@dxos/react-ui";
1428
+ import { mx as mx6 } from "@dxos/react-ui-theme";
1429
+ var SYNC_STALLED_TIMEOUT = 5e3;
1430
+ var styles = {
1431
+ barBg: "bg-neutral-50 dark:bg-green-900 text-black",
1432
+ barFg: "bg-neutral-100 bg-green-500",
1433
+ barHover: "dark:hover:bg-green-500"
1434
+ };
1435
+ var useActive = (count) => {
1436
+ const [current, setCurrent] = useState8(count);
1437
+ const [active, setActive] = useState8(false);
1438
+ useEffect4(() => {
1439
+ let t;
1440
+ if (count !== current) {
1441
+ setActive(true);
1442
+ setCurrent(count);
1443
+ t && clearTimeout(t);
1444
+ t = setTimeout(() => {
1445
+ setActive(false);
1446
+ }, SYNC_STALLED_TIMEOUT);
1447
+ }
1448
+ return () => {
1449
+ setActive(false);
1450
+ clearTimeout(t);
1451
+ };
1452
+ }, [
1453
+ count,
1454
+ current
1455
+ ]);
1456
+ return active;
1457
+ };
1458
+ var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1459
+ const downActive = useActive(localDocumentCount);
1460
+ const upActive = useActive(remoteDocumentCount);
1461
+ return /* @__PURE__ */ React15.createElement("div", {
1462
+ className: mx6("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1463
+ title: spaceId,
1464
+ onClick: () => {
1465
+ void navigator.clipboard.writeText(spaceId);
1466
+ }
1467
+ }, /* @__PURE__ */ React15.createElement(Icon, {
1468
+ icon: "ph--arrow-fat-line-left--regular",
1469
+ size: 3,
1470
+ classNames: mx6(downActive && "animate-[pulse_1s_infinite]")
1471
+ }), /* @__PURE__ */ React15.createElement(Candle, {
1472
+ up: {
1473
+ count: remoteDocumentCount,
1474
+ total: remoteDocumentCount + missingOnRemote
1475
+ },
1476
+ down: {
1477
+ count: localDocumentCount,
1478
+ total: localDocumentCount + missingOnLocal
1479
+ },
1480
+ title: spaceId
1481
+ }), /* @__PURE__ */ React15.createElement(Icon, {
1482
+ icon: "ph--arrow-fat-line-right--regular",
1483
+ size: 3,
1484
+ classNames: mx6(upActive && "animate-[pulse_1s_step-start_infinite]")
1472
1485
  }));
1473
1486
  };
1487
+ var Candle = ({ classNames, up, down }) => {
1488
+ return /* @__PURE__ */ React15.createElement("div", {
1489
+ className: mx6("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1490
+ }, /* @__PURE__ */ React15.createElement(Bar, {
1491
+ classNames: "justify-end",
1492
+ ...up
1493
+ }), /* @__PURE__ */ React15.createElement("div", {
1494
+ className: "relative"
1495
+ }, /* @__PURE__ */ React15.createElement("div", {
1496
+ className: mx6("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1497
+ }, up.total)), /* @__PURE__ */ React15.createElement(Bar, down));
1498
+ };
1499
+ var Bar = ({ classNames, count, total }) => {
1500
+ let p = count / total * 100;
1501
+ if (count < total) {
1502
+ p = Math.min(p, 95);
1503
+ }
1504
+ return /* @__PURE__ */ React15.createElement("div", {
1505
+ className: mx6("relative flex w-full", styles.barBg, classNames)
1506
+ }, /* @__PURE__ */ React15.createElement("div", {
1507
+ className: mx6("shrink-0", styles.barFg),
1508
+ style: {
1509
+ width: `${p}%`
1510
+ }
1511
+ }), count !== total && /* @__PURE__ */ React15.createElement("div", {
1512
+ className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1513
+ }, count));
1514
+ };
1515
+
1516
+ // packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts
1517
+ import { Context } from "@dxos/context";
1518
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts";
1474
1519
  var createClientSaveTracker = (client, cb) => {
1475
1520
  const unsubscribeCallbacks = {};
1476
1521
  const state = {};
@@ -1499,7 +1544,7 @@ var createClientSaveTracker = (client, cb) => {
1499
1544
  var createSpaceSaveTracker = (space, cb) => {
1500
1545
  const ctx = new Context(void 0, {
1501
1546
  F: __dxlog_file4,
1502
- L: 64
1547
+ L: 40
1503
1548
  });
1504
1549
  void space.waitUntilReady().then(() => {
1505
1550
  if (ctx.disposed) {
@@ -1530,19 +1575,41 @@ var createSpaceSaveTracker = (space, cb) => {
1530
1575
  };
1531
1576
  };
1532
1577
 
1533
- // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1534
- import React17, { useEffect as useEffect7, useState as useState11 } from "react";
1535
- import { StatusBar as StatusBar2 } from "@dxos/plugin-status-bar";
1536
- import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation17 } from "@dxos/react-ui";
1537
- import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1538
- import { mx as mx7 } from "@dxos/react-ui-theme";
1578
+ // packages/plugins/plugin-space/src/components/SyncStatus/status.ts
1579
+ var getStatus = ({ offline, saved, needsToUpload, needsToDownload }) => {
1580
+ if (!saved) {
1581
+ return "saving locally";
1582
+ } else if (!offline && needsToDownload) {
1583
+ return "downloading";
1584
+ } else if (!offline && needsToUpload) {
1585
+ return "uploading";
1586
+ } else if (offline && !needsToUpload && !needsToDownload) {
1587
+ return "offline persisted";
1588
+ } else {
1589
+ return "remote synced";
1590
+ }
1591
+ };
1592
+ var getIcon = (status) => {
1593
+ switch (status) {
1594
+ case "saving locally":
1595
+ return "ph--download--regular";
1596
+ case "downloading":
1597
+ return "ph--cloud-arrow-down--regular";
1598
+ case "uploading":
1599
+ return "ph--cloud-arrow-up--regular";
1600
+ case "offline persisted":
1601
+ return "ph--check-circle--regular";
1602
+ case "remote synced":
1603
+ return "ph--cloud-check--regular";
1604
+ }
1605
+ };
1539
1606
 
1540
- // packages/plugins/plugin-space/src/components/SyncStatus/types.ts
1541
- import { useEffect as useEffect6, useState as useState10 } from "react";
1607
+ // packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts
1608
+ import { useEffect as useEffect5, useState as useState9 } from "react";
1542
1609
  import { Context as Context2 } from "@dxos/context";
1543
1610
  import { EdgeService } from "@dxos/protocols";
1544
1611
  import { useClient as useClient5 } from "@dxos/react-client";
1545
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/types.ts";
1612
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts";
1546
1613
  var createEmptyEdgeSyncState = () => ({
1547
1614
  missingOnLocal: 0,
1548
1615
  missingOnRemote: 0,
@@ -1563,8 +1630,8 @@ var getSyncSummary = (syncMap) => {
1563
1630
  var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1564
1631
  var useSyncState = () => {
1565
1632
  const client = useClient5();
1566
- const [spaceState, setSpaceState] = useState10({});
1567
- useEffect6(() => {
1633
+ const [spaceState, setSpaceState] = useState9({});
1634
+ useEffect5(() => {
1568
1635
  const ctx = new Context2(void 0, {
1569
1636
  F: __dxlog_file5,
1570
1637
  L: 48
@@ -1599,146 +1666,86 @@ var useSyncState = () => {
1599
1666
  };
1600
1667
 
1601
1668
  // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1602
- var SYNC_STALLED_TIMEOUT = 5e3;
1603
- var styles = {
1604
- barBg: "bg-neutral-50 dark:bg-green-900 text-black",
1605
- barFg: "bg-neutral-100 bg-green-500",
1606
- barHover: "dark:hover:bg-green-500"
1607
- };
1608
1669
  var SyncStatus = () => {
1670
+ const client = useClient6();
1609
1671
  const state = useSyncState();
1610
- return /* @__PURE__ */ React17.createElement(SyncStatusIndicator, {
1611
- state
1672
+ const [saved, setSaved] = useState10(true);
1673
+ useEffect6(() => {
1674
+ return createClientSaveTracker(client, (state2) => {
1675
+ setSaved(state2 === "saved");
1676
+ });
1677
+ }, []);
1678
+ return /* @__PURE__ */ React16.createElement(SyncStatusIndicator, {
1679
+ state,
1680
+ saved
1612
1681
  });
1613
1682
  };
1614
- var SyncStatusIndicator = ({ state }) => {
1683
+ var SyncStatusIndicator = ({ state, saved }) => {
1684
+ const { t } = useTranslation15(SPACE_PLUGIN);
1615
1685
  const summary = getSyncSummary(state);
1616
- const offline = false;
1686
+ const offline = Object.values(state).length === 0;
1617
1687
  const needsToUpload = summary.differentDocuments > 0 || summary.missingOnRemote > 0;
1618
1688
  const needsToDownload = summary.differentDocuments > 0 || summary.missingOnLocal > 0;
1619
- const [classNames, setClassNames] = useState11();
1620
- useEffect7(() => {
1689
+ const status = getStatus({
1690
+ offline,
1691
+ saved,
1692
+ needsToUpload,
1693
+ needsToDownload
1694
+ });
1695
+ const [classNames, setClassNames] = useState10();
1696
+ useEffect6(() => {
1621
1697
  setClassNames(void 0);
1622
- if (!needsToUpload && !needsToDownload) {
1698
+ if (offline || !needsToUpload && !needsToDownload) {
1623
1699
  return;
1624
1700
  }
1625
- const t = setTimeout(() => {
1701
+ const t2 = setTimeout(() => {
1626
1702
  setClassNames("text-orange-500");
1627
1703
  }, SYNC_STALLED_TIMEOUT);
1628
- return () => clearTimeout(t);
1704
+ return () => clearTimeout(t2);
1629
1705
  }, [
1706
+ offline,
1630
1707
  needsToUpload,
1631
1708
  needsToDownload
1632
1709
  ]);
1633
- return /* @__PURE__ */ React17.createElement(StatusBar2.Item, null, /* @__PURE__ */ React17.createElement(Popover3.Root, null, /* @__PURE__ */ React17.createElement(Popover3.Trigger, null, /* @__PURE__ */ React17.createElement(Icon2, {
1634
- icon: offline ? "ph--cloud-x--regular" : needsToUpload ? "ph--cloud-arrow-up--regular" : needsToDownload ? "ph--cloud-arrow-down--regular" : "ph--cloud-check--regular",
1710
+ const title = t(`${status} label`);
1711
+ const icon = /* @__PURE__ */ React16.createElement(Icon2, {
1712
+ icon: getIcon(status),
1635
1713
  size: 4,
1636
1714
  classNames
1637
- })), /* @__PURE__ */ React17.createElement(Popover3.Content, {
1638
- sideOffset: 16
1639
- }, /* @__PURE__ */ React17.createElement(SyncStatusDetail, {
1640
- state,
1641
- summary,
1642
- debug: false
1643
- }))));
1715
+ });
1716
+ if (offline) {
1717
+ return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1718
+ title
1719
+ }, icon);
1720
+ } else {
1721
+ return /* @__PURE__ */ React16.createElement(Popover3.Root, null, /* @__PURE__ */ React16.createElement(Popover3.Trigger, {
1722
+ asChild: true
1723
+ }, /* @__PURE__ */ React16.createElement(StatusBar.Button, {
1724
+ title
1725
+ }, icon)), /* @__PURE__ */ React16.createElement(Popover3.Portal, null, /* @__PURE__ */ React16.createElement(Popover3.Content, {
1726
+ sideOffset: 16
1727
+ }, /* @__PURE__ */ React16.createElement(SyncStatusDetail, {
1728
+ state,
1729
+ summary,
1730
+ debug: false
1731
+ }))));
1732
+ }
1644
1733
  };
1645
1734
  var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1646
- const { t } = useTranslation17(SPACE_PLUGIN);
1735
+ const { t } = useTranslation15(SPACE_PLUGIN);
1647
1736
  const entries = Object.entries(state).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1648
- return /* @__PURE__ */ React17.createElement("div", {
1649
- className: mx7("flex flex-col text-xs min-w-[16rem]", classNames)
1650
- }, /* @__PURE__ */ React17.createElement("h1", {
1651
- className: "p-2"
1652
- }, t("sync status title")), /* @__PURE__ */ React17.createElement("div", {
1653
- className: "flex flex-col gap-[2px] my-[2px]"
1654
- }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React17.createElement(SpaceRow, {
1737
+ return /* @__PURE__ */ React16.createElement("div", {
1738
+ className: mx7("flex flex-col gap-3 p-2 text-xs min-w-[16rem]", classNames)
1739
+ }, /* @__PURE__ */ React16.createElement("h1", null, t("sync status title")), /* @__PURE__ */ React16.createElement("div", {
1740
+ className: "flex flex-col gap-2"
1741
+ }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React16.createElement(SpaceRow, {
1655
1742
  key: spaceId,
1656
1743
  spaceId,
1657
1744
  state: state2
1658
- }))), debug && /* @__PURE__ */ React17.createElement(SyntaxHighlighter, {
1745
+ }))), debug && /* @__PURE__ */ React16.createElement(SyntaxHighlighter, {
1659
1746
  language: "json"
1660
1747
  }, JSON.stringify(summary, null, 2)));
1661
1748
  };
1662
- var useActive = (count) => {
1663
- const [current, setCurrent] = useState11(count);
1664
- const [active, setActive] = useState11(false);
1665
- useEffect7(() => {
1666
- let t;
1667
- if (count !== current) {
1668
- setActive(true);
1669
- setCurrent(count);
1670
- t && clearTimeout(t);
1671
- t = setTimeout(() => {
1672
- setActive(false);
1673
- }, SYNC_STALLED_TIMEOUT);
1674
- }
1675
- return () => {
1676
- setActive(false);
1677
- clearTimeout(t);
1678
- };
1679
- }, [
1680
- count,
1681
- current
1682
- ]);
1683
- return active;
1684
- };
1685
- var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1686
- const downActive = useActive(localDocumentCount);
1687
- const upActive = useActive(remoteDocumentCount);
1688
- return /* @__PURE__ */ React17.createElement("div", {
1689
- className: mx7("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1690
- title: spaceId,
1691
- onClick: () => {
1692
- void navigator.clipboard.writeText(spaceId);
1693
- }
1694
- }, /* @__PURE__ */ React17.createElement(Icon2, {
1695
- icon: "ph--arrow-fat-line-left--regular",
1696
- size: 3,
1697
- classNames: mx7(downActive && "animate-[pulse_1s_infinite]")
1698
- }), /* @__PURE__ */ React17.createElement(Candle, {
1699
- up: {
1700
- count: remoteDocumentCount,
1701
- total: remoteDocumentCount + missingOnRemote
1702
- },
1703
- down: {
1704
- count: localDocumentCount,
1705
- total: localDocumentCount + missingOnLocal
1706
- },
1707
- title: spaceId
1708
- }), /* @__PURE__ */ React17.createElement(Icon2, {
1709
- icon: "ph--arrow-fat-line-right--regular",
1710
- size: 3,
1711
- classNames: mx7(upActive && "animate-[pulse_1s_step-start_infinite]")
1712
- }));
1713
- };
1714
- var Candle = ({ classNames, up, down }) => {
1715
- return /* @__PURE__ */ React17.createElement("div", {
1716
- className: mx7("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1717
- }, /* @__PURE__ */ React17.createElement(Bar, {
1718
- classNames: "justify-end",
1719
- ...up
1720
- }), /* @__PURE__ */ React17.createElement("div", {
1721
- className: "relative"
1722
- }, /* @__PURE__ */ React17.createElement("div", {
1723
- className: mx7("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1724
- }, up.total)), /* @__PURE__ */ React17.createElement(Bar, down));
1725
- };
1726
- var Bar = ({ classNames, count, total }) => {
1727
- let p = count / total * 100;
1728
- if (count < total) {
1729
- p = Math.min(p, 95);
1730
- }
1731
- return /* @__PURE__ */ React17.createElement("div", {
1732
- className: mx7("relative flex w-full", styles.barBg, classNames)
1733
- }, /* @__PURE__ */ React17.createElement("div", {
1734
- className: mx7("shrink-0", styles.barFg),
1735
- style: {
1736
- width: `${p}%`
1737
- }
1738
- }), count !== total && /* @__PURE__ */ React17.createElement("div", {
1739
- className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1740
- }, count));
1741
- };
1742
1749
 
1743
1750
  // packages/plugins/plugin-space/src/translations.ts
1744
1751
  var translations_default = [
@@ -1827,7 +1834,13 @@ var translations_default = [
1827
1834
  "name label": "Name",
1828
1835
  "name placeholder": "Name",
1829
1836
  "unnamed object settings label": "Settings",
1830
- "edge replication label": "Enable EDGE Replication"
1837
+ "edge replication label": "Enable EDGE Replication",
1838
+ "saving locally label": "Writing to disk",
1839
+ "downloading label": "Replicating from peers",
1840
+ "uploading label": "Replicating to peers",
1841
+ "offline persisted label": "Saved to disk (offline)",
1842
+ "remote synced label": "Synced with peers",
1843
+ "open settings panel label": "Show Settings"
1831
1844
  }
1832
1845
  }
1833
1846
  }
@@ -1836,7 +1849,6 @@ var translations_default = [
1836
1849
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
1837
1850
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/SpacePlugin.tsx";
1838
1851
  var ACTIVE_NODE_BROADCAST_INTERVAL = 3e4;
1839
- var OBJECT_ID_LENGTH = 60;
1840
1852
  var SPACE_MAX_OBJECTS = 500;
1841
1853
  var DIRECTORY_TYPE = "text/directory";
1842
1854
  var parseSpacePlugin = (plugin) => Array.isArray(plugin?.provides.space?.enabled) ? plugin : void 0;
@@ -1856,15 +1868,20 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1856
1868
  const spaceSubscriptions = new EventSubscriptions();
1857
1869
  const graphSubscriptions = /* @__PURE__ */ new Map();
1858
1870
  let clientPlugin;
1871
+ let graphPlugin;
1859
1872
  let intentPlugin;
1873
+ let layoutPlugin;
1860
1874
  let navigationPlugin;
1861
1875
  let attentionPlugin;
1862
1876
  const onSpaceReady = async () => {
1863
- if (!clientPlugin || !navigationPlugin || !attentionPlugin) {
1877
+ if (!clientPlugin || !intentPlugin || !graphPlugin || !navigationPlugin || !layoutPlugin || !attentionPlugin) {
1864
1878
  return;
1865
1879
  }
1866
1880
  const client = clientPlugin.provides.client;
1881
+ const dispatch = intentPlugin.provides.intent.dispatch;
1882
+ const graph = graphPlugin.provides.graph;
1867
1883
  const location = navigationPlugin.provides.location;
1884
+ const layout = layoutPlugin.provides.layout;
1868
1885
  const attention = attentionPlugin.provides.attention;
1869
1886
  const defaultSpace = client.spaces.default;
1870
1887
  if (typeof defaultSpace.properties[COMPOSER_SPACE_LOCK] !== "boolean") {
@@ -1879,6 +1896,24 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1879
1896
  order: []
1880
1897
  }));
1881
1898
  }
1899
+ subscriptions.add(scheduledEffect(() => ({
1900
+ layoutMode: layout.layoutMode,
1901
+ soloPart: location.active.solo?.[0]
1902
+ }), ({ layoutMode, soloPart }) => {
1903
+ if (layoutMode !== "solo" || !soloPart) {
1904
+ return;
1905
+ }
1906
+ const node = graph.findNode(soloPart.id);
1907
+ if (!node && soloPart.id.length === FQ_ID_LENGTH) {
1908
+ void dispatch({
1909
+ plugin: SPACE_PLUGIN,
1910
+ action: SpaceAction.WAIT_FOR_OBJECT,
1911
+ data: {
1912
+ id: soloPart.id
1913
+ }
1914
+ });
1915
+ }
1916
+ }));
1882
1917
  subscriptions.add(client.spaces.subscribe(async (spaces) => {
1883
1918
  if (defaultSpace.state.get() === SpaceState3.SPACE_REQUIRES_MIGRATION) {
1884
1919
  await defaultSpace.internal.migrate();
@@ -1926,7 +1961,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1926
1961
  err: err.message
1927
1962
  }, {
1928
1963
  F: __dxlog_file6,
1929
- L: 231,
1964
+ L: 257,
1930
1965
  S: void 0,
1931
1966
  C: (f, a) => f(...a)
1932
1967
  });
@@ -1984,10 +2019,12 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1984
2019
  key: "spaceNames",
1985
2020
  type: LocalStorageStore.json()
1986
2021
  });
2022
+ graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
2023
+ layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
1987
2024
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin2);
1988
2025
  attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
1989
2026
  clientPlugin = resolvePlugin(plugins, parseClientPlugin);
1990
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin3);
2027
+ intentPlugin = resolvePlugin(plugins, parseIntentPlugin2);
1991
2028
  if (!clientPlugin || !intentPlugin) {
1992
2029
  return;
1993
2030
  }
@@ -2007,7 +2044,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2007
2044
  dispatch
2008
2045
  });
2009
2046
  };
2010
- client.spaces.isReady.subscribe(async (ready) => {
2047
+ subscriptions.add(client.spaces.isReady.subscribe(async (ready) => {
2011
2048
  if (ready) {
2012
2049
  await clientPlugin?.provides.client.spaces.default.waitUntilReady();
2013
2050
  if (firstRun) {
@@ -2017,7 +2054,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2017
2054
  }
2018
2055
  await onSpaceReady();
2019
2056
  }
2020
- });
2057
+ }).unsubscribe);
2021
2058
  },
2022
2059
  unload: async () => {
2023
2060
  settings.close();
@@ -2033,7 +2070,21 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2033
2070
  ...translations_default,
2034
2071
  osTranslations
2035
2072
  ],
2036
- root: () => state.values.awaiting ? /* @__PURE__ */ React18.createElement(AwaitingObject, {
2073
+ complementary: {
2074
+ panels: [
2075
+ {
2076
+ id: "settings",
2077
+ label: [
2078
+ "open settings panel label",
2079
+ {
2080
+ ns: SPACE_PLUGIN
2081
+ }
2082
+ ],
2083
+ icon: "ph--gear--regular"
2084
+ }
2085
+ ]
2086
+ },
2087
+ root: () => state.values.awaiting ? /* @__PURE__ */ React17.createElement(AwaitingObject, {
2037
2088
  id: state.values.awaiting
2038
2089
  }) : null,
2039
2090
  metadata: {
@@ -2061,37 +2112,33 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2061
2112
  },
2062
2113
  surface: {
2063
2114
  component: ({ data, role, ...rest }) => {
2064
- const primary = data.active ?? data.object;
2065
2115
  switch (role) {
2066
2116
  case "article":
2067
- case "main":
2068
- return isSpace2(primary) && primary.state.get() === SpaceState3.SPACE_READY ? /* @__PURE__ */ React18.createElement(Surface2, {
2117
+ return isSpace2(data.object) && data.object.state.get() === SpaceState3.SPACE_READY ? /* @__PURE__ */ React17.createElement(Surface2, {
2069
2118
  data: {
2070
- active: primary.properties[CollectionType.typename],
2071
- id: primary.id
2119
+ object: data.object.properties[CollectionType.typename],
2120
+ id: data.object.id
2072
2121
  },
2073
2122
  role,
2074
2123
  ...rest
2075
- }) : primary instanceof CollectionType ? {
2076
- node: /* @__PURE__ */ React18.createElement(CollectionMain, {
2077
- collection: primary
2124
+ }) : data.object instanceof CollectionType ? {
2125
+ node: /* @__PURE__ */ React17.createElement(CollectionMain, {
2126
+ collection: data.object
2078
2127
  }),
2079
2128
  disposition: "fallback"
2080
- } : typeof primary === "string" && primary.length === OBJECT_ID_LENGTH ? /* @__PURE__ */ React18.createElement(MissingObject, {
2081
- id: primary
2082
- }) : null;
2129
+ } : null;
2083
2130
  case "complementary--settings":
2084
- return isSpace2(data.subject) ? /* @__PURE__ */ React18.createElement(SpaceSettingsPanel, {
2131
+ return isSpace2(data.subject) ? /* @__PURE__ */ React17.createElement(SpaceSettingsPanel, {
2085
2132
  space: data.subject
2086
2133
  }) : isEchoObject2(data.subject) ? {
2087
- node: /* @__PURE__ */ React18.createElement(DefaultObjectSettings, {
2134
+ node: /* @__PURE__ */ React17.createElement(DefaultObjectSettings, {
2088
2135
  object: data.subject
2089
2136
  }),
2090
2137
  disposition: "fallback"
2091
2138
  } : null;
2092
2139
  case "dialog":
2093
2140
  if (data.component === "dxos.org/plugin/space/InvitationManagerDialog") {
2094
- return /* @__PURE__ */ React18.createElement(Dialog.Content, null, /* @__PURE__ */ React18.createElement(ClipboardProvider2, null, /* @__PURE__ */ React18.createElement(InvitationManager, {
2141
+ return /* @__PURE__ */ React17.createElement(Dialog.Content, null, /* @__PURE__ */ React17.createElement(ClipboardProvider2, null, /* @__PURE__ */ React17.createElement(InvitationManager, {
2095
2142
  active: true,
2096
2143
  ...data.subject
2097
2144
  })));
@@ -2099,12 +2146,12 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2099
2146
  return null;
2100
2147
  case "popover": {
2101
2148
  if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace2(data.subject)) {
2102
- return /* @__PURE__ */ React18.createElement(PopoverRenameSpace, {
2149
+ return /* @__PURE__ */ React17.createElement(PopoverRenameSpace, {
2103
2150
  space: data.subject
2104
2151
  });
2105
2152
  }
2106
2153
  if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject2(data.subject)) {
2107
- return /* @__PURE__ */ React18.createElement(PopoverRenameObject, {
2154
+ return /* @__PURE__ */ React17.createElement(PopoverRenameObject, {
2108
2155
  object: data.subject
2109
2156
  });
2110
2157
  }
@@ -2112,10 +2159,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2112
2159
  }
2113
2160
  // TODO(burdon): Add role name syntax to minimal plugin docs.
2114
2161
  case "presence--glyph": {
2115
- return isReactiveObject2(data.object) ? /* @__PURE__ */ React18.createElement(SmallPresenceLive, {
2162
+ return isReactiveObject2(data.object) ? /* @__PURE__ */ React17.createElement(SmallPresenceLive, {
2116
2163
  id: data.id,
2117
2164
  viewers: state.values.viewersByObject[fullyQualifiedId4(data.object)]
2118
- }) : /* @__PURE__ */ React18.createElement(SmallPresence, {
2165
+ }) : /* @__PURE__ */ React17.createElement(SmallPresence, {
2119
2166
  id: data.id,
2120
2167
  count: 0
2121
2168
  });
@@ -2130,32 +2177,32 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2130
2177
  const space = isSpace2(data.object) ? data.object : getSpace4(data.object);
2131
2178
  const object = isSpace2(data.object) ? data.object.state.get() === SpaceState3.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2132
2179
  return space && object ? {
2133
- node: /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SpacePresence, {
2180
+ node: /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SpacePresence, {
2134
2181
  object
2135
- }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React18.createElement(ShareSpaceButton, {
2182
+ }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React17.createElement(ShareSpaceButton, {
2136
2183
  spaceId: space.id
2137
2184
  })),
2138
2185
  disposition: "hoist"
2139
2186
  } : null;
2140
2187
  }
2141
2188
  case "section":
2142
- return data.object instanceof CollectionType ? /* @__PURE__ */ React18.createElement(CollectionSection, {
2189
+ return data.object instanceof CollectionType ? /* @__PURE__ */ React17.createElement(CollectionSection, {
2143
2190
  collection: data.object
2144
2191
  }) : null;
2145
2192
  case "settings":
2146
- return data.plugin === meta_default.id ? /* @__PURE__ */ React18.createElement(SpaceSettings, {
2193
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React17.createElement(SpaceSettings, {
2147
2194
  settings: settings.values
2148
2195
  }) : null;
2149
2196
  case "menu-footer":
2150
2197
  if (isEchoObject2(data.object)) {
2151
- return /* @__PURE__ */ React18.createElement(MenuFooter, {
2198
+ return /* @__PURE__ */ React17.createElement(MenuFooter, {
2152
2199
  object: data.object
2153
2200
  });
2154
2201
  } else {
2155
2202
  return null;
2156
2203
  }
2157
2204
  case "status": {
2158
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SyncStatus, null), /* @__PURE__ */ React18.createElement(SaveStatus, null));
2205
+ return /* @__PURE__ */ React17.createElement(SyncStatus, null);
2159
2206
  }
2160
2207
  default:
2161
2208
  return null;
@@ -2166,11 +2213,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2166
2213
  builder: (plugins) => {
2167
2214
  const clientPlugin2 = resolvePlugin(plugins, parseClientPlugin);
2168
2215
  const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
2169
- const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
2216
+ const graphPlugin2 = resolvePlugin(plugins, parseGraphPlugin);
2170
2217
  const client = clientPlugin2?.provides.client;
2171
2218
  const dispatch = intentPlugin?.provides.intent.dispatch;
2172
2219
  const resolve = metadataPlugin?.provides.metadata.resolver;
2173
- const graph = graphPlugin?.provides.graph;
2220
+ const graph = graphPlugin2?.provides.graph;
2174
2221
  if (!client || !dispatch || !resolve || !graph) {
2175
2222
  return [];
2176
2223
  }
@@ -2216,7 +2263,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2216
2263
  } else {
2217
2264
  log3.warn("spaces order object not found", void 0, {
2218
2265
  F: __dxlog_file6,
2219
- L: 528,
2266
+ L: 553,
2220
2267
  S: void 0,
2221
2268
  C: (f, a) => f(...a)
2222
2269
  });
@@ -2478,7 +2525,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2478
2525
  ];
2479
2526
  },
2480
2527
  serializer: (plugins) => {
2481
- const dispatch = resolvePlugin(plugins, parseIntentPlugin3)?.provides.intent.dispatch;
2528
+ const dispatch = resolvePlugin(plugins, parseIntentPlugin2)?.provides.intent.dispatch;
2482
2529
  if (!dispatch) {
2483
2530
  return [];
2484
2531
  }
@@ -3055,7 +3102,6 @@ export {
3055
3102
  MenuFooter,
3056
3103
  MessageState,
3057
3104
  MessageType,
3058
- MissingObject,
3059
3105
  PersistenceStatus,
3060
3106
  PopoverRenameObject,
3061
3107
  PopoverRenameSpace,
@@ -3065,7 +3111,6 @@ export {
3065
3111
  SPACE_PLUGIN,
3066
3112
  SPACE_PLUGIN_SHORT_ID,
3067
3113
  SPACE_TYPE,
3068
- SaveStatus,
3069
3114
  ShareSpaceButton,
3070
3115
  ShareSpaceButtonImpl,
3071
3116
  SmallPresence,