@dxos/shell 0.4.7-main.f9d3866 → 0.4.7-next.76c1dea

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 (169) hide show
  1. package/dist/bundle/shell.mjs +69806 -27240
  2. package/dist/bundle/shell.mjs.map +1 -1
  3. package/dist/bundle/shell.umd.js +796 -80
  4. package/dist/bundle/shell.umd.js.map +1 -1
  5. package/dist/bundle/style.css +1 -1
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +871 -669
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -0
  10. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  11. package/dist/types/src/components/CompoundButton/CompoundButton.stories.d.ts +1 -0
  12. package/dist/types/src/components/CompoundButton/CompoundButton.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/EmojiPicker.d.ts +11 -0
  14. package/dist/types/src/components/EmojiPicker.d.ts.map +1 -0
  15. package/dist/types/src/components/EmojiPicker.js +79 -0
  16. package/dist/types/src/components/EmojiPicker.js.map +1 -0
  17. package/dist/types/src/components/HuePicker.d.ts +11 -0
  18. package/dist/types/src/components/HuePicker.d.ts.map +1 -0
  19. package/dist/types/src/components/HuePicker.js +56 -0
  20. package/dist/types/src/components/HuePicker.js.map +1 -0
  21. package/dist/types/src/components/IdentityList/DeviceList.d.ts +1 -0
  22. package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +1 -1
  23. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -1
  24. package/dist/types/src/components/IdentityList/IdentityListItem.js +5 -5
  25. package/dist/types/src/components/IdentityList/IdentityListItem.js.map +1 -1
  26. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts +1 -0
  27. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts.map +1 -1
  28. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts +1 -0
  29. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts +1 -0
  31. package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts +1 -0
  33. package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts.map +1 -1
  34. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -1
  35. package/dist/types/src/components/InvitationList/InvitationListItem.js +2 -2
  36. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  37. package/dist/types/src/components/Panel/CloseButton.d.ts +1 -0
  38. package/dist/types/src/components/Panel/CloseButton.d.ts.map +1 -1
  39. package/dist/types/src/components/Panel/Panel.stories.d.ts +1 -0
  40. package/dist/types/src/components/Panel/Panel.stories.d.ts.map +1 -1
  41. package/dist/types/src/components/SpaceListItem.d.ts.map +1 -1
  42. package/dist/types/src/components/SpaceListItem.js +2 -3
  43. package/dist/types/src/components/SpaceListItem.js.map +1 -1
  44. package/dist/types/src/components/Viewport/Viewport.js.map +1 -1
  45. package/dist/types/src/components/Viewport/Viewport.stories.d.ts +1 -0
  46. package/dist/types/src/components/Viewport/Viewport.stories.d.ts.map +1 -1
  47. package/dist/types/src/components/index.d.ts +2 -0
  48. package/dist/types/src/components/index.d.ts.map +1 -1
  49. package/dist/types/src/components/index.js +2 -0
  50. package/dist/types/src/components/index.js.map +1 -1
  51. package/dist/types/src/composites/IdentityDialog/IdentityDialog.d.ts +1 -0
  52. package/dist/types/src/composites/IdentityDialog/IdentityDialog.d.ts.map +1 -1
  53. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js +1 -1
  54. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js.map +1 -1
  55. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts +1 -0
  56. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts.map +1 -1
  57. package/dist/types/src/composites/JoinDialog/JoinDialog.js +2 -2
  58. package/dist/types/src/composites/JoinDialog/JoinDialog.js.map +1 -1
  59. package/dist/types/src/composites/Shell/Shell.d.ts +1 -0
  60. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  61. package/dist/types/src/composites/Shell/Shell.js.map +1 -1
  62. package/dist/types/src/composites/Shell/ShellContext.js.map +1 -1
  63. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts +1 -0
  64. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts.map +1 -1
  65. package/dist/types/src/composites/SpaceDialog/SpaceDialog.js +1 -1
  66. package/dist/types/src/composites/SpaceDialog/SpaceDialog.js.map +1 -1
  67. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts +1 -0
  68. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  69. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +7 -6
  70. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  71. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +1 -0
  72. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
  73. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +1 -0
  74. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +1 -1
  75. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts +1 -0
  76. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts.map +1 -1
  77. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
  78. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +2 -1
  79. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
  80. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +1 -0
  81. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  82. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +12 -3
  83. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  84. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +1 -0
  85. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +1 -1
  86. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +1 -1
  87. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -1
  88. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +2 -1
  89. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -1
  90. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +1 -0
  91. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -1
  92. package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
  93. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts +1 -0
  94. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts.map +1 -1
  95. package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
  96. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.d.ts +1 -0
  97. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.d.ts.map +1 -1
  98. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts +1 -0
  99. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts.map +1 -1
  100. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js +8 -7
  101. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js.map +1 -1
  102. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.d.ts +1 -0
  103. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.d.ts.map +1 -1
  104. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts +1 -0
  105. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts.map +1 -1
  106. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +2 -2
  107. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -1
  108. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts +1 -0
  109. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts.map +1 -1
  110. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js.map +1 -1
  111. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.d.ts +1 -0
  112. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.d.ts.map +1 -1
  113. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.js.map +1 -1
  114. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts +1 -0
  115. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts.map +1 -1
  116. package/dist/types/src/panels/Panels.stories.d.ts.map +1 -1
  117. package/dist/types/src/panels/Panels.stories.js +1 -3
  118. package/dist/types/src/panels/Panels.stories.js.map +1 -1
  119. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts +1 -0
  120. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -1
  121. package/dist/types/src/panels/SpacePanel/SpacePanel.js.map +1 -1
  122. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts +1 -0
  123. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -1
  124. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
  125. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +2 -1
  126. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
  127. package/dist/types/src/playwright/invitations-manager.js.map +1 -1
  128. package/dist/types/src/steps/InvitationManager.d.ts +1 -0
  129. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  130. package/dist/types/src/steps/InvitationManager.js +5 -4
  131. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  132. package/dist/types/src/stories/Invitations.e2e-stories.d.ts +1 -0
  133. package/dist/types/src/stories/Invitations.e2e-stories.d.ts.map +1 -1
  134. package/dist/types/src/stories/Invitations.e2e-stories.js +3 -2
  135. package/dist/types/src/stories/Invitations.e2e-stories.js.map +1 -1
  136. package/dist/types/src/testing/scoped-shell-manager.js.map +1 -1
  137. package/dist/types/src/testing/shell-manager.js.map +1 -1
  138. package/dist/types/src/translations/locales/en-US.d.ts +21 -0
  139. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  140. package/dist/types/src/translations/locales/en-US.js +21 -0
  141. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  142. package/dist/types/src/util/index.d.ts +0 -1
  143. package/dist/types/src/util/index.d.ts.map +1 -1
  144. package/dist/types/src/util/index.js +0 -1
  145. package/dist/types/src/util/index.js.map +1 -1
  146. package/package.json +23 -22
  147. package/src/components/EmojiPicker.tsx +82 -0
  148. package/src/components/HuePicker.tsx +87 -0
  149. package/src/components/IdentityList/IdentityListItem.tsx +9 -5
  150. package/src/components/InvitationList/InvitationListItem.tsx +2 -2
  151. package/src/components/SpaceListItem.tsx +4 -5
  152. package/src/components/index.ts +2 -0
  153. package/src/panels/IdentityPanel/IdentityPanel.tsx +6 -5
  154. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +2 -1
  155. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +29 -7
  156. package/src/panels/IdentityPanel/useAgentHandlers.ts +2 -1
  157. package/src/panels/JoinPanel/steps/IdentityAdded.tsx +7 -7
  158. package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +2 -2
  159. package/src/panels/Panels.stories.tsx +1 -3
  160. package/src/panels/SpacePanel/steps/SpaceManager.tsx +2 -1
  161. package/src/steps/InvitationManager.tsx +4 -3
  162. package/src/stories/Invitations.e2e-stories.tsx +3 -2
  163. package/src/translations/locales/en-US.ts +21 -0
  164. package/src/util/index.ts +0 -1
  165. package/dist/types/src/util/toEmoji.d.ts +0 -2
  166. package/dist/types/src/util/toEmoji.d.ts.map +0 -1
  167. package/dist/types/src/util/toEmoji.js +0 -26
  168. package/dist/types/src/util/toEmoji.js.map +0 -1
  169. package/src/util/toEmoji.ts +0 -22
@@ -139,47 +139,188 @@ var CompoundButton = ({ children, description, before, after, variant = "default
139
139
  }, after));
140
140
  };
141
141
 
142
- // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
142
+ // packages/sdk/shell/src/components/EmojiPicker.tsx
143
+ import emojiData from "@emoji-mart/data";
144
+ import EmojiMart from "@emoji-mart/react";
145
+ import { ArrowCounterClockwise, CaretDown } from "@phosphor-icons/react";
146
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
147
+ import React4, { useState as useState3 } from "react";
148
+ import { Button as Button2, Popover, useTranslation as useTranslation2, Tooltip as Tooltip2 } from "@dxos/react-ui";
149
+ import { getSize as getSize2 } from "@dxos/react-ui-theme";
150
+ var EmojiPicker = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }) => {
151
+ const { t } = useTranslation2("os");
152
+ const [emojiValue, setEmojiValue] = useControllableState({
153
+ prop: emoji,
154
+ onChange: onChangeEmoji,
155
+ defaultProp: defaultEmoji
156
+ });
157
+ const [emojiPickerOpen, setEmojiPickerOpen] = useState3(false);
158
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(Popover.Root, {
159
+ open: emojiPickerOpen,
160
+ onOpenChange: setEmojiPickerOpen
161
+ }, /* @__PURE__ */ React4.createElement(Popover.Trigger, {
162
+ asChild: true
163
+ }, /* @__PURE__ */ React4.createElement(Button2, {
164
+ variant: "ghost",
165
+ classNames: "gap-2 text-2xl plb-1",
166
+ disabled
167
+ }, /* @__PURE__ */ React4.createElement("span", {
168
+ className: "sr-only"
169
+ }, t("select emoji label")), /* @__PURE__ */ React4.createElement("span", {
170
+ className: "grow pis-14"
171
+ }, emojiValue), /* @__PURE__ */ React4.createElement(CaretDown, {
172
+ className: getSize2(4)
173
+ }))), /* @__PURE__ */ React4.createElement(Popover.Content, {
174
+ side: "right",
175
+ onKeyDownCapture: (event) => {
176
+ if (event.key === "Escape") {
177
+ event.stopPropagation();
178
+ setEmojiPickerOpen(false);
179
+ }
180
+ }
181
+ }, /* @__PURE__ */ React4.createElement(EmojiMart, {
182
+ data: emojiData,
183
+ onEmojiSelect: ({ native }) => {
184
+ if (native) {
185
+ setEmojiValue(native);
186
+ setEmojiPickerOpen(false);
187
+ }
188
+ },
189
+ autoFocus: true,
190
+ maxFrequentRows: 0,
191
+ noCountryFlags: true
192
+ }), /* @__PURE__ */ React4.createElement(Popover.Arrow, null))), /* @__PURE__ */ React4.createElement(Tooltip2.Root, null, /* @__PURE__ */ React4.createElement(Tooltip2.Trigger, {
193
+ asChild: true
194
+ }, /* @__PURE__ */ React4.createElement(Button2, {
195
+ variant: "ghost",
196
+ onClick: onClickClear,
197
+ disabled
198
+ }, /* @__PURE__ */ React4.createElement("span", {
199
+ className: "sr-only"
200
+ }, t("clear label")), /* @__PURE__ */ React4.createElement(ArrowCounterClockwise, null))), /* @__PURE__ */ React4.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React4.createElement(Tooltip2.Content, {
201
+ style: {
202
+ zIndex: 70
203
+ },
204
+ side: "right"
205
+ }, t("clear label"), /* @__PURE__ */ React4.createElement(Tooltip2.Arrow, null)))));
206
+ };
207
+
208
+ // packages/sdk/shell/src/components/HuePicker.tsx
209
+ import { ArrowCounterClockwise as ArrowCounterClockwise2, CaretDown as CaretDown2, Check as Check2 } from "@phosphor-icons/react";
210
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
143
211
  import React5 from "react";
212
+ import { Button as Button3, useTranslation as useTranslation3, Tooltip as Tooltip3, DropdownMenu, useThemeContext as useThemeContext2 } from "@dxos/react-ui";
213
+ import { getSize as getSize3, hueTokenThemes } from "@dxos/react-ui-theme";
214
+ var HuePreview = ({ hue }) => {
215
+ const { tx } = useThemeContext2();
216
+ return /* @__PURE__ */ React5.createElement("svg", {
217
+ width: 12,
218
+ height: 12,
219
+ viewBox: "0 0 12 12"
220
+ }, /* @__PURE__ */ React5.createElement("rect", {
221
+ x: 0,
222
+ y: 0,
223
+ width: 12,
224
+ height: 12,
225
+ className: tx("hue.fill", "select--hue__preview", {
226
+ hue
227
+ })
228
+ }));
229
+ };
230
+ var HuePicker = ({ disabled, hue, onChangeHue, defaultHue, onClickClear }) => {
231
+ const { t } = useTranslation3("os");
232
+ const [hueValue, setHueValue] = useControllableState2({
233
+ prop: hue,
234
+ onChange: onChangeHue,
235
+ defaultProp: defaultHue
236
+ });
237
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(DropdownMenu.Root, {
238
+ modal: false
239
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu.Trigger, {
240
+ asChild: true
241
+ }, /* @__PURE__ */ React5.createElement(Button3, {
242
+ variant: "ghost",
243
+ classNames: "gap-2 plb-1",
244
+ disabled
245
+ }, /* @__PURE__ */ React5.createElement("span", {
246
+ className: "sr-only"
247
+ }, t("select hue label")), /* @__PURE__ */ React5.createElement("div", {
248
+ role: "none",
249
+ className: "pis-14 grow flex items-center justify-center gap-2"
250
+ }, /* @__PURE__ */ React5.createElement(HuePreview, {
251
+ hue: hueValue
252
+ }), /* @__PURE__ */ React5.createElement("span", null, t(`${hueValue} label`))), /* @__PURE__ */ React5.createElement(CaretDown2, {
253
+ className: getSize3(4)
254
+ }))), /* @__PURE__ */ React5.createElement(DropdownMenu.Content, {
255
+ side: "right"
256
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu.Viewport, null, Object.keys(hueTokenThemes).map((hue2) => {
257
+ return /* @__PURE__ */ React5.createElement(DropdownMenu.CheckboxItem, {
258
+ key: hue2,
259
+ checked: hue2 === hueValue,
260
+ onCheckedChange: () => setHueValue(hue2)
261
+ }, /* @__PURE__ */ React5.createElement(HuePreview, {
262
+ hue: hue2
263
+ }), /* @__PURE__ */ React5.createElement("span", {
264
+ className: "grow"
265
+ }, t(`${hue2} label`)), /* @__PURE__ */ React5.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React5.createElement(Check2, null)));
266
+ })), /* @__PURE__ */ React5.createElement(DropdownMenu.Arrow, null))), /* @__PURE__ */ React5.createElement(Tooltip3.Root, null, /* @__PURE__ */ React5.createElement(Tooltip3.Trigger, {
267
+ asChild: true
268
+ }, /* @__PURE__ */ React5.createElement(Button3, {
269
+ variant: "ghost",
270
+ onClick: onClickClear,
271
+ disabled
272
+ }, /* @__PURE__ */ React5.createElement("span", {
273
+ className: "sr-only"
274
+ }, t("clear label")), /* @__PURE__ */ React5.createElement(ArrowCounterClockwise2, null))), /* @__PURE__ */ React5.createElement(Tooltip3.Portal, null, /* @__PURE__ */ React5.createElement(Tooltip3.Content, {
275
+ style: {
276
+ zIndex: 70
277
+ },
278
+ side: "right"
279
+ }, t("clear label"), /* @__PURE__ */ React5.createElement(Tooltip3.Arrow, null)))));
280
+ };
281
+
282
+ // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
283
+ import React7 from "react";
144
284
  import { generateName as generateName2 } from "@dxos/display-name";
145
285
  import { DeviceType } from "@dxos/react-client/halo";
146
- import { List, useTranslation as useTranslation2 } from "@dxos/react-ui";
286
+ import { List, useTranslation as useTranslation4 } from "@dxos/react-ui";
147
287
  import { descriptionText as descriptionText2, mx as mx4 } from "@dxos/react-ui-theme";
148
288
 
149
289
  // packages/sdk/shell/src/components/IdentityList/IdentityListItem.tsx
150
- import React4, { forwardRef } from "react";
290
+ import React6, { forwardRef } from "react";
151
291
  import { generateName } from "@dxos/display-name";
152
292
  import { SpaceMember } from "@dxos/react-client/echo";
153
- import { ListItem, Avatar, useJdenticonHref, useId as useId2 } from "@dxos/react-ui";
293
+ import { ListItem, Avatar, useId as useId2 } from "@dxos/react-ui";
154
294
  import { mx as mx3 } from "@dxos/react-ui-theme";
295
+ import { keyToFallback } from "@dxos/util";
155
296
  var IdentityListItem = /* @__PURE__ */ forwardRef(({ identity, presence, onClick, classNames, ...props }, forwardedRef) => {
156
- const fallbackValue = identity.identityKey.toHex();
297
+ const fallbackValue = keyToFallback(identity.identityKey);
157
298
  const labelId = useId2("identityListItem__label");
158
- const jdenticon = useJdenticonHref(fallbackValue ?? "", 12);
159
299
  const displayName = identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
160
- return /* @__PURE__ */ React4.createElement(ListItem.Root, {
300
+ return /* @__PURE__ */ React6.createElement(ListItem.Root, {
161
301
  ...props,
162
302
  classNames: mx3("flex gap-2 pis-3 pie-1 items-center", onClick && "cursor-pointer", classNames),
163
303
  onClick: () => onClick?.(),
164
304
  "data-testid": "identity-list-item",
165
305
  labelId,
166
306
  ref: forwardedRef
167
- }, /* @__PURE__ */ React4.createElement(Avatar.Root, {
307
+ }, /* @__PURE__ */ React6.createElement(Avatar.Root, {
168
308
  status: presence === SpaceMember.PresenceState.ONLINE ? "active" : "inactive",
169
- labelId
170
- }, /* @__PURE__ */ React4.createElement(Avatar.Frame, {
309
+ labelId,
310
+ hue: identity.profile?.data?.hue || fallbackValue.hue
311
+ }, /* @__PURE__ */ React6.createElement(Avatar.Frame, {
171
312
  classNames: "place-self-center"
172
- }, /* @__PURE__ */ React4.createElement(Avatar.Fallback, {
173
- href: jdenticon
174
- })), /* @__PURE__ */ React4.createElement(Avatar.Label, {
313
+ }, /* @__PURE__ */ React6.createElement(Avatar.Fallback, {
314
+ text: identity.profile?.data?.emoji || fallbackValue.emoji
315
+ })), /* @__PURE__ */ React6.createElement(Avatar.Label, {
175
316
  classNames: "text-sm truncate pli-2"
176
317
  }, displayName)));
177
318
  });
178
319
 
179
320
  // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
180
321
  var DeviceList = ({ devices, onSelect }) => {
181
- const { t } = useTranslation2("os");
182
- return devices.length > 0 ? /* @__PURE__ */ React5.createElement(List, {
322
+ const { t } = useTranslation4("os");
323
+ return devices.length > 0 ? /* @__PURE__ */ React7.createElement(List, {
183
324
  classNames: "flex flex-col gap-2"
184
325
  }, devices.map((device) => {
185
326
  const deviceType = device.profile?.type || DeviceType.UNKNOWN;
@@ -190,25 +331,25 @@ var DeviceList = ({ devices, onSelect }) => {
190
331
  displayName
191
332
  }
192
333
  };
193
- return /* @__PURE__ */ React5.createElement(IdentityListItem, {
334
+ return /* @__PURE__ */ React7.createElement(IdentityListItem, {
194
335
  key: device.deviceKey.toHex(),
195
336
  identity,
196
337
  presence: device.presence,
197
338
  onClick: onSelect && (() => onSelect(device))
198
339
  });
199
- })) : /* @__PURE__ */ React5.createElement("div", {
340
+ })) : /* @__PURE__ */ React7.createElement("div", {
200
341
  role: "none",
201
342
  className: "grow flex items-center p-2"
202
- }, /* @__PURE__ */ React5.createElement("p", {
343
+ }, /* @__PURE__ */ React7.createElement("p", {
203
344
  className: mx4(descriptionText2, "text-center is-full")
204
345
  }, t("empty device list message")));
205
346
  };
206
347
 
207
348
  // packages/sdk/shell/src/components/IdentityList/SpaceMemberList.tsx
208
- import React6, { useMemo } from "react";
349
+ import React8, { useMemo } from "react";
209
350
  import { useClient } from "@dxos/react-client";
210
351
  import { useMembers } from "@dxos/react-client/echo";
211
- import { useTranslation as useTranslation3, List as List2 } from "@dxos/react-ui";
352
+ import { useTranslation as useTranslation5, List as List2 } from "@dxos/react-ui";
212
353
  import { descriptionText as descriptionText3, mx as mx5 } from "@dxos/react-ui-theme";
213
354
  var SpaceMemberList = ({ spaceKey, includeSelf, onSelect }) => {
214
355
  const client = useClient();
@@ -216,100 +357,42 @@ var SpaceMemberList = ({ spaceKey, includeSelf, onSelect }) => {
216
357
  const members = useMemo(() => includeSelf ? allUnsortedMembers.sort((member) => member.identity.identityKey.equals(client.halo.identity.get().identityKey) ? -1 : 1) : allUnsortedMembers.filter((member) => !member.identity.identityKey.equals(client.halo.identity.get().identityKey)), [
217
358
  allUnsortedMembers
218
359
  ]);
219
- return /* @__PURE__ */ React6.createElement(SpaceMemberListImpl, {
360
+ return /* @__PURE__ */ React8.createElement(SpaceMemberListImpl, {
220
361
  members,
221
362
  onSelect
222
363
  });
223
364
  };
224
365
  var SpaceMemberListImpl = ({ members, onSelect }) => {
225
- const { t } = useTranslation3("os");
366
+ const { t } = useTranslation5("os");
226
367
  const visibleMembers = members.filter((member) => member.identity);
227
- return visibleMembers.length > 0 ? /* @__PURE__ */ React6.createElement(List2, {
368
+ return visibleMembers.length > 0 ? /* @__PURE__ */ React8.createElement(List2, {
228
369
  classNames: "flex flex-col gap-2",
229
370
  "data-testid": "space-members-list"
230
371
  }, visibleMembers.map((member) => {
231
- return /* @__PURE__ */ React6.createElement(IdentityListItem, {
372
+ return /* @__PURE__ */ React8.createElement(IdentityListItem, {
232
373
  key: member.identity.identityKey.toHex(),
233
374
  identity: member.identity,
234
375
  presence: member.presence,
235
376
  onClick: onSelect && (() => onSelect(member))
236
377
  });
237
- })) : /* @__PURE__ */ React6.createElement("div", {
378
+ })) : /* @__PURE__ */ React8.createElement("div", {
238
379
  role: "none",
239
380
  className: "grow flex items-center p-2"
240
- }, /* @__PURE__ */ React6.createElement("p", {
381
+ }, /* @__PURE__ */ React8.createElement("p", {
241
382
  className: mx5(descriptionText3, "text-center is-full mlb-2")
242
383
  }, t("empty space members message")));
243
384
  };
244
385
 
245
386
  // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
246
387
  import { X } from "@phosphor-icons/react";
247
- import React8, { useCallback as useCallback2 } from "react";
248
- import { Invitation as Invitation2, useInvitationStatus } from "@dxos/react-client/invitations";
249
- import { Button as Button2, ListItem as ListItem2, useTranslation as useTranslation4, Avatar as Avatar2, useThemeContext as useThemeContext2, Tooltip as Tooltip2 } from "@dxos/react-ui";
250
- import { focusRing, getSize as getSize2, mx as mx7 } from "@dxos/react-ui-theme";
251
-
252
- // packages/sdk/shell/src/util/invitationStatusValue.ts
253
- import { Invitation } from "@dxos/react-client/invitations";
254
- var invitationStatusValue = /* @__PURE__ */ new Map([
255
- [
256
- Invitation.State.ERROR,
257
- -3
258
- ],
259
- [
260
- Invitation.State.TIMEOUT,
261
- -2
262
- ],
263
- [
264
- Invitation.State.CANCELLED,
265
- -1
266
- ],
267
- [
268
- Invitation.State.INIT,
269
- 0
270
- ],
271
- [
272
- Invitation.State.CONNECTING,
273
- 1
274
- ],
275
- [
276
- Invitation.State.CONNECTED,
277
- 2
278
- ],
279
- [
280
- Invitation.State.READY_FOR_AUTHENTICATION,
281
- 3
282
- ],
283
- [
284
- Invitation.State.AUTHENTICATING,
285
- 4
286
- ],
287
- [
288
- Invitation.State.SUCCESS,
289
- 5
290
- ]
291
- ]);
292
-
293
- // packages/sdk/shell/src/util/toEmoji.ts
294
- import toArray from "lodash.toarray";
295
- var emoji = toArray(
296
- // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
297
- // Emoji sometimes use a combination of code points, and some code points aren't visible on their own, so by adding or deleting you may unintentionally create non-visible items.
298
- // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
299
- // – not people or isolated anthropomorphic faces
300
- // – not flags
301
- // – more concrete than abstract
302
- // – less culturally specific
303
- // – less easily confused with another emoji in the set
304
- // – requires less special knowledge to identify
305
- // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
306
- // – less common as a signifier in UX
307
- "\u{1F479}\u{1F47B}\u{1F47D}\u{1F916}\u{1F383}\u{1F9BE}\u{1F9BF}\u{1F9B7}\u{1F463}\u{1F441}\uFE0F\u{1F9F6}\u{1F451}\u{1F412}\u{1F986}\u{1F989}\u{1F434}\u{1F984}\u{1F41D}\u{1F98B}\u{1F41E}\u{1FAB2}\u{1F422}\u{1F98E}\u{1F995}\u{1F991}\u{1F980}\u{1F420}\u{1F42C}\u{1F40B}\u{1F9AD}\u{1F405}\u{1F406}\u{1F993}\u{1F98D}\u{1F9A7}\u{1F418}\u{1F42B}\u{1F992}\u{1F998}\u{1F9AC}\u{1F416}\u{1F40F}\u{1F98C}\u{1F415}\u{1F408}\u{1F413}\u{1F99A}\u{1F99C}\u{1F9A2}\u{1F9A9}\u{1F9A6}\u{1F401}\u{1F43F}\uFE0F\u{1F335}\u{1F332}\u{1F333}\u{1FAB5}\u{1F331}\u{1F341}\u{1FABA}\u{1F344}\u{1F41A}\u{1FAB8}\u{1FAA8}\u{1F33E}\u{1F337}\u{1F33B}\u2600\uFE0F\u{1F319}\u{1FA90}\u2B50\uFE0F\u26A1\uFE0F\u2604\uFE0F\u{1F525}\u{1F308}\u2601\uFE0F\u{1F4A7}\u26F1\uFE0F\u{1F30A}\u{1F34E}\u{1F34B}\u{1F349}\u{1F347}\u{1FAD0}\u{1F348}\u{1F352}\u{1F351}\u{1F96D}\u{1F34D}\u{1F965}\u{1F95D}\u{1F951}\u{1F336}\uFE0F\u{1F33D}\u{1F955}\u{1F36C}\u{1F95C}\u{1FAD6}\u2615\uFE0F\u{1F375}\u{1F9CA}\u{1F9C2}\u{1F3D4}\uFE0F\u2693\uFE0F\u{1F6DF}\u{1F3DD}\uFE0F\u{1F6F6}\u{1F680}\u{1F6F0}\uFE0F\u26F2\uFE0F\u{1F3F0}\u{1F6B2}\u26FA\uFE0F\u{1F399}\uFE0F\u{1F9F2}\u2699\uFE0F\u{1F529}\u{1F52E}\u{1F52D}\u{1F52C}\u{1F9EC}\u{1F321}\uFE0F\u{1F9FA}\u{1F6CE}\uFE0F\u{1F511}\u{1FA91}\u{1F9F8}\u{1F388}\u{1F380}\u{1F38A}\u267B\uFE0F\u{1F3B5}"
308
- );
309
- var toEmoji = (keyAsHex) => emoji[parseInt(keyAsHex, 16) % emoji.length];
388
+ import React10, { useCallback as useCallback2 } from "react";
389
+ import { Invitation, useInvitationStatus } from "@dxos/react-client/invitations";
390
+ import { Button as Button4, ListItem as ListItem2, useTranslation as useTranslation6, Avatar as Avatar2, useThemeContext as useThemeContext3, Tooltip as Tooltip4 } from "@dxos/react-ui";
391
+ import { focusRing, getSize as getSize4, mx as mx7 } from "@dxos/react-ui-theme";
392
+ import { hexToEmoji } from "@dxos/util";
310
393
 
311
394
  // packages/sdk/shell/src/components/AuthCode.tsx
312
- import React7 from "react";
395
+ import React9 from "react";
313
396
  import { mx as mx6 } from "@dxos/react-ui-theme";
314
397
  var AuthCode = (props) => {
315
398
  const { code, large, classNames } = props;
@@ -319,17 +402,17 @@ var AuthCode = (props) => {
319
402
  const handleCopy = () => {
320
403
  void navigator.clipboard.writeText(code ?? "");
321
404
  };
322
- return /* @__PURE__ */ React7.createElement("span", {
405
+ return /* @__PURE__ */ React9.createElement("span", {
323
406
  className: mx6(large ? "text-6xl" : "text-2xl", "font-mono pli-2.5 flex gap-1.5 rounded cursor-pointer", classNames),
324
407
  onClick: handleCopy
325
- }, /* @__PURE__ */ React7.createElement("span", null, left), /* @__PURE__ */ React7.createElement("span", null, right));
408
+ }, /* @__PURE__ */ React9.createElement("span", null, left), /* @__PURE__ */ React9.createElement("span", null, right));
326
409
  };
327
410
 
328
411
  // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
329
412
  var InvitationListItem = (props) => {
330
413
  const { invitation } = props;
331
414
  const invitationStatus = useInvitationStatus(invitation);
332
- return /* @__PURE__ */ React8.createElement(InvitationListItemImpl, {
415
+ return /* @__PURE__ */ React10.createElement(InvitationListItemImpl, {
333
416
  ...props,
334
417
  invitationStatus
335
418
  });
@@ -339,11 +422,11 @@ var avatarProps = {
339
422
  variant: "circle"
340
423
  };
341
424
  var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
342
- const { tx } = useThemeContext2();
343
- return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("span", {
425
+ const { tx } = useThemeContext3();
426
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("span", {
344
427
  role: "none",
345
- className: mx7("absolute inline-end-auto opacity-20", reverseEffects ? "inline-start-3" : "inline-start-1", getSize2(avatarProps.size))
346
- }, /* @__PURE__ */ React8.createElement("span", {
428
+ className: mx7("absolute inline-end-auto opacity-20", reverseEffects ? "inline-start-3" : "inline-start-1", getSize4(avatarProps.size))
429
+ }, /* @__PURE__ */ React10.createElement("span", {
347
430
  role: "none",
348
431
  className: tx("avatar.ring", "avatar__ring", {
349
432
  ...avatarProps,
@@ -353,10 +436,10 @@ var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
353
436
  style: {
354
437
  animationDelay: "400ms"
355
438
  }
356
- })), /* @__PURE__ */ React8.createElement("span", {
439
+ })), /* @__PURE__ */ React10.createElement("span", {
357
440
  role: "none",
358
- className: mx7("absolute inline-end-auto opacity-50", reverseEffects ? "inline-start-2" : "inline-start-2", getSize2(avatarProps.size))
359
- }, /* @__PURE__ */ React8.createElement("span", {
441
+ className: mx7("absolute inline-end-auto opacity-50", reverseEffects ? "inline-start-2" : "inline-start-2", getSize4(avatarProps.size))
442
+ }, /* @__PURE__ */ React10.createElement("span", {
360
443
  role: "none",
361
444
  className: tx("avatar.ring", "avatar__ring", {
362
445
  ...avatarProps,
@@ -369,19 +452,19 @@ var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
369
452
  })));
370
453
  };
371
454
  var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationStatus, send, onClickRemove, createInvitationUrl, reverseEffects, ...props }) => {
372
- const { t } = useTranslation4("os");
455
+ const { t } = useTranslation6("os");
373
456
  const { cancel, status: invitationStatus, invitationCode, authCode, type } = propsInvitationStatus;
374
457
  const isCancellable = !([
375
- Invitation2.State.ERROR,
376
- Invitation2.State.TIMEOUT,
377
- Invitation2.State.CANCELLED
458
+ Invitation.State.ERROR,
459
+ Invitation.State.TIMEOUT,
460
+ Invitation.State.CANCELLED
378
461
  ].indexOf(invitationStatus) >= 0);
379
- const showShare = type === Invitation2.Type.MULTIUSE || [
380
- Invitation2.State.INIT,
381
- Invitation2.State.CONNECTING,
382
- Invitation2.State.CONNECTED
462
+ const showShare = type === Invitation.Type.MULTIUSE || [
463
+ Invitation.State.INIT,
464
+ Invitation.State.CONNECTING,
465
+ Invitation.State.CONNECTED
383
466
  ].indexOf(invitationStatus) >= 0;
384
- const showAuthCode = invitationStatus === Invitation2.State.READY_FOR_AUTHENTICATION;
467
+ const showAuthCode = invitationStatus === Invitation.State.READY_FOR_AUTHENTICATION;
385
468
  const handleClickRemove = useCallback2(() => onClickRemove?.(invitation), [
386
469
  invitation,
387
470
  onClickRemove
@@ -389,55 +472,55 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
389
472
  const invitationUrl = invitationCode && createInvitationUrl(invitationCode);
390
473
  const invitationId = invitation?.get().invitationId;
391
474
  const avatarAnimation = [
392
- Invitation2.State.INIT,
393
- Invitation2.State.CONNECTING,
394
- Invitation2.State.CONNECTED,
395
- Invitation2.State.READY_FOR_AUTHENTICATION,
396
- Invitation2.State.AUTHENTICATING
475
+ Invitation.State.INIT,
476
+ Invitation.State.CONNECTING,
477
+ Invitation.State.CONNECTED,
478
+ Invitation.State.READY_FOR_AUTHENTICATION,
479
+ Invitation.State.AUTHENTICATING
397
480
  ].includes(invitationStatus) ? "pulse" : "none";
398
481
  const avatarError = [
399
- Invitation2.State.ERROR,
400
- Invitation2.State.TIMEOUT,
401
- Invitation2.State.CANCELLED
482
+ Invitation.State.ERROR,
483
+ Invitation.State.TIMEOUT,
484
+ Invitation.State.CANCELLED
402
485
  ].includes(invitationStatus);
403
486
  const avatarGreen = [
404
- Invitation2.State.CONNECTED,
405
- Invitation2.State.READY_FOR_AUTHENTICATION,
406
- Invitation2.State.AUTHENTICATING,
407
- Invitation2.State.SUCCESS
487
+ Invitation.State.CONNECTED,
488
+ Invitation.State.READY_FOR_AUTHENTICATION,
489
+ Invitation.State.AUTHENTICATING,
490
+ Invitation.State.SUCCESS
408
491
  ].includes(invitationStatus);
409
492
  const avatarStatus = avatarError ? "error" : avatarGreen ? "active" : "inactive";
410
- return /* @__PURE__ */ React8.createElement(ListItem2.Root, {
493
+ return /* @__PURE__ */ React10.createElement(ListItem2.Root, {
411
494
  id: invitationCode,
412
495
  ...props,
413
496
  classNames: [
414
497
  "flex gap-2 pis-3 pie-1 items-center relative",
415
498
  props.classNames
416
499
  ]
417
- }, /* @__PURE__ */ React8.createElement(ListItem2.Heading, {
500
+ }, /* @__PURE__ */ React10.createElement(ListItem2.Heading, {
418
501
  classNames: "sr-only"
419
- }, t(type === Invitation2.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation2.Type.MULTIUSE && /* @__PURE__ */ React8.createElement(AvatarStackEffect, {
502
+ }, t(type === Invitation.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation.Type.MULTIUSE && /* @__PURE__ */ React10.createElement(AvatarStackEffect, {
420
503
  status: avatarStatus,
421
504
  animation: avatarAnimation,
422
505
  reverseEffects
423
- }), /* @__PURE__ */ React8.createElement(Tooltip2.Root, null, /* @__PURE__ */ React8.createElement(Avatar2.Root, {
506
+ }), /* @__PURE__ */ React10.createElement(Tooltip4.Root, null, /* @__PURE__ */ React10.createElement(Avatar2.Root, {
424
507
  ...avatarProps,
425
508
  animation: avatarAnimation,
426
509
  status: avatarStatus
427
- }, /* @__PURE__ */ React8.createElement(Tooltip2.Trigger, {
510
+ }, /* @__PURE__ */ React10.createElement(Tooltip4.Trigger, {
428
511
  asChild: true
429
- }, /* @__PURE__ */ React8.createElement(Avatar2.Frame, {
512
+ }, /* @__PURE__ */ React10.createElement(Avatar2.Frame, {
430
513
  tabIndex: 0,
431
514
  classNames: [
432
515
  focusRing,
433
516
  "relative rounded-full place-self-center"
434
517
  ]
435
- }, /* @__PURE__ */ React8.createElement(Avatar2.Fallback, {
436
- text: toEmoji(invitationId)
437
- })))), /* @__PURE__ */ React8.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip2.Content, {
518
+ }, /* @__PURE__ */ React10.createElement(Avatar2.Fallback, {
519
+ text: hexToEmoji(invitationId)
520
+ })))), /* @__PURE__ */ React10.createElement(Tooltip4.Portal, null, /* @__PURE__ */ React10.createElement(Tooltip4.Content, {
438
521
  side: "left",
439
522
  classNames: "z-[70]"
440
- }, t(type === Invitation2.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React8.createElement(Tooltip2.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Button2, {
523
+ }, t(type === Invitation.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React10.createElement(Tooltip4.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Button4, {
441
524
  variant: "ghost",
442
525
  classNames: "grow justify-start font-medium",
443
526
  onClick: () => send({
@@ -445,60 +528,60 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
445
528
  invitation
446
529
  }),
447
530
  "data-testid": "show-qrcode"
448
- }, /* @__PURE__ */ React8.createElement("span", null, t("open share panel label"))), /* @__PURE__ */ React8.createElement(CopyButtonIconOnly, {
531
+ }, /* @__PURE__ */ React10.createElement("span", null, t("open share panel label"))), /* @__PURE__ */ React10.createElement(CopyButtonIconOnly, {
449
532
  variant: "ghost",
450
533
  value: invitationUrl
451
- })) : showAuthCode ? /* @__PURE__ */ React8.createElement(AuthCode, {
534
+ })) : showAuthCode ? /* @__PURE__ */ React10.createElement(AuthCode, {
452
535
  code: authCode,
453
536
  classNames: "grow"
454
- }) : invitationStatus === Invitation2.State.CONNECTING ? /* @__PURE__ */ React8.createElement("span", {
537
+ }) : invitationStatus === Invitation.State.CONNECTING ? /* @__PURE__ */ React10.createElement("span", {
455
538
  className: "pli-2 grow text-neutral-500"
456
- }, "Connecting...") : invitationStatus === Invitation2.State.AUTHENTICATING ? /* @__PURE__ */ React8.createElement("span", {
539
+ }, "Connecting...") : invitationStatus === Invitation.State.AUTHENTICATING ? /* @__PURE__ */ React10.createElement("span", {
457
540
  className: "pli-2 grow text-neutral-500"
458
- }, "Authenticating...") : invitationStatus === Invitation2.State.ERROR || invitationStatus === Invitation2.State.TIMEOUT ? /* @__PURE__ */ React8.createElement("span", {
541
+ }, "Authenticating...") : invitationStatus === Invitation.State.ERROR || invitationStatus === Invitation.State.TIMEOUT ? /* @__PURE__ */ React10.createElement("span", {
459
542
  className: "pli-2 grow text-neutral-500"
460
- }, "Failed") : invitationStatus === Invitation2.State.CANCELLED ? /* @__PURE__ */ React8.createElement("span", {
543
+ }, "Failed") : invitationStatus === Invitation.State.CANCELLED ? /* @__PURE__ */ React10.createElement("span", {
461
544
  className: "pli-2 grow text-neutral-500"
462
- }, "Cancelled") : invitationStatus === Invitation2.State.SUCCESS ? /* @__PURE__ */ React8.createElement("span", {
545
+ }, "Cancelled") : invitationStatus === Invitation.State.SUCCESS ? /* @__PURE__ */ React10.createElement("span", {
463
546
  className: "pli-2 grow truncate"
464
- }, "User joined") : /* @__PURE__ */ React8.createElement("span", {
547
+ }, "User joined") : /* @__PURE__ */ React10.createElement("span", {
465
548
  className: "grow"
466
- }, " "), isCancellable ? /* @__PURE__ */ React8.createElement(Button2, {
549
+ }, " "), isCancellable ? /* @__PURE__ */ React10.createElement(Button4, {
467
550
  variant: "ghost",
468
551
  classNames: "flex gap-1 pli-0",
469
552
  onClick: cancel,
470
553
  "data-testid": "cancel-invitation"
471
- }, /* @__PURE__ */ React8.createElement("span", {
554
+ }, /* @__PURE__ */ React10.createElement("span", {
472
555
  className: "sr-only"
473
- }, t("cancel invitation label")), /* @__PURE__ */ React8.createElement(X, {
474
- className: getSize2(4)
475
- })) : /* @__PURE__ */ React8.createElement(Button2, {
556
+ }, t("cancel invitation label")), /* @__PURE__ */ React10.createElement(X, {
557
+ className: getSize4(4)
558
+ })) : /* @__PURE__ */ React10.createElement(Button4, {
476
559
  variant: "ghost",
477
560
  classNames: "flex gap-1 pli-0",
478
561
  onClick: handleClickRemove,
479
562
  "data-testid": "remove-invitation"
480
- }, /* @__PURE__ */ React8.createElement("span", {
563
+ }, /* @__PURE__ */ React10.createElement("span", {
481
564
  className: "sr-only"
482
- }, t("remove invitation label")), /* @__PURE__ */ React8.createElement(X, {
483
- className: getSize2(4)
565
+ }, t("remove invitation label")), /* @__PURE__ */ React10.createElement(X, {
566
+ className: getSize4(4)
484
567
  })));
485
568
  };
486
569
 
487
570
  // packages/sdk/shell/src/components/InvitationList/InvitationListContainer.tsx
488
- import React10, { useCallback as useCallback3 } from "react";
571
+ import React12, { useCallback as useCallback3 } from "react";
489
572
  import { useSpace, useSpaceInvitations } from "@dxos/react-client/echo";
490
573
 
491
574
  // packages/sdk/shell/src/components/InvitationList/InvitationList.tsx
492
- import React9 from "react";
575
+ import React11 from "react";
493
576
  import { List as List3 } from "@dxos/react-ui";
494
577
  import { mx as mx8 } from "@dxos/react-ui-theme";
495
578
  var InvitationList = ({ invitations, send, ...invitationProps }) => {
496
579
  const { className, InvitationListItem: Item = InvitationListItem } = invitationProps;
497
- return /* @__PURE__ */ React9.createElement(List3, {
580
+ return /* @__PURE__ */ React11.createElement(List3, {
498
581
  classNames: mx8("flex flex-col gap-2", className)
499
582
  }, invitations.map((invitation) => {
500
583
  const value = invitation.get().invitationId;
501
- return /* @__PURE__ */ React9.createElement(Item, {
584
+ return /* @__PURE__ */ React11.createElement(Item, {
502
585
  key: value,
503
586
  send,
504
587
  invitation,
@@ -516,7 +599,7 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl, send }) => {
516
599
  }, [
517
600
  space
518
601
  ]);
519
- return /* @__PURE__ */ React10.createElement(InvitationList, {
602
+ return /* @__PURE__ */ React12.createElement(InvitationList, {
520
603
  invitations,
521
604
  onClickRemove,
522
605
  createInvitationUrl,
@@ -525,11 +608,11 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl, send }) => {
525
608
  };
526
609
 
527
610
  // packages/sdk/shell/src/components/Panel/Action.tsx
528
- import { CaretDown, Check as Check2, Placeholder } from "@phosphor-icons/react";
529
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
530
- import React11, { forwardRef as forwardRef2 } from "react";
531
- import { Button as Button3, DropdownMenu, useTranslation as useTranslation5 } from "@dxos/react-ui";
532
- import { descriptionText as descriptionText4, getSize as getSize3, mx as mx9 } from "@dxos/react-ui-theme";
611
+ import { CaretDown as CaretDown3, Check as Check3, Placeholder } from "@phosphor-icons/react";
612
+ import { useControllableState as useControllableState3 } from "@radix-ui/react-use-controllable-state";
613
+ import React13, { forwardRef as forwardRef2 } from "react";
614
+ import { Button as Button5, DropdownMenu as DropdownMenu2, useTranslation as useTranslation7 } from "@dxos/react-ui";
615
+ import { descriptionText as descriptionText4, getSize as getSize5, mx as mx9 } from "@dxos/react-ui-theme";
533
616
  var defaultActions = {
534
617
  noopAction: {
535
618
  label: "No-op",
@@ -541,17 +624,17 @@ var defaultActions = {
541
624
  };
542
625
  var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
543
626
  const { classNames, variant, isFull = true, actions = defaultActions, activeAction: propsActiveAction, onChangeActiveAction, defaultActiveAction, ...rest } = props;
544
- const [activeActionKey2 = Object.keys(actions)[0], setActiveAction] = useControllableState({
627
+ const [activeActionKey2 = Object.keys(actions)[0], setActiveAction] = useControllableState3({
545
628
  prop: propsActiveAction,
546
629
  onChange: onChangeActiveAction,
547
630
  defaultProp: defaultActiveAction
548
631
  });
549
632
  const activeAction = actions[activeActionKey2] ?? {};
550
- const { t } = useTranslation5("os");
551
- return /* @__PURE__ */ React11.createElement("div", {
633
+ const { t } = useTranslation7("os");
634
+ return /* @__PURE__ */ React13.createElement("div", {
552
635
  role: "none",
553
636
  className: mx9("mbs-2 flex gap-px items-center", isFull && "is-full")
554
- }, /* @__PURE__ */ React11.createElement(Button3, {
637
+ }, /* @__PURE__ */ React13.createElement(Button5, {
555
638
  ...rest,
556
639
  classNames: [
557
640
  "bs-11 flex-1 min-is-0 flex gap-2 rounded-ie-none",
@@ -560,48 +643,48 @@ var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
560
643
  ref: forwardedRef,
561
644
  variant,
562
645
  onClick: activeAction.onClick
563
- }, activeAction.icon && /* @__PURE__ */ React11.createElement(activeAction.icon, {
564
- className: getSize3(5)
565
- }), /* @__PURE__ */ React11.createElement("span", null, activeAction.label)), /* @__PURE__ */ React11.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Trigger, {
646
+ }, activeAction.icon && /* @__PURE__ */ React13.createElement(activeAction.icon, {
647
+ className: getSize5(5)
648
+ }), /* @__PURE__ */ React13.createElement("span", null, activeAction.label)), /* @__PURE__ */ React13.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Trigger, {
566
649
  asChild: true
567
- }, /* @__PURE__ */ React11.createElement(Button3, {
650
+ }, /* @__PURE__ */ React13.createElement(Button5, {
568
651
  classNames: [
569
652
  "bs-11 flex-none rounded-is-none",
570
653
  classNames
571
654
  ]
572
- }, /* @__PURE__ */ React11.createElement("span", {
655
+ }, /* @__PURE__ */ React13.createElement("span", {
573
656
  className: "sr-only"
574
- }, t("invite options label")), /* @__PURE__ */ React11.createElement(CaretDown, {
575
- className: getSize3(4)
576
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Viewport, null, Object.entries(actions).map(([id, action]) => {
577
- return /* @__PURE__ */ React11.createElement(DropdownMenu.CheckboxItem, {
657
+ }, t("invite options label")), /* @__PURE__ */ React13.createElement(CaretDown3, {
658
+ className: getSize5(4)
659
+ }))), /* @__PURE__ */ React13.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Viewport, null, Object.entries(actions).map(([id, action]) => {
660
+ return /* @__PURE__ */ React13.createElement(DropdownMenu2.CheckboxItem, {
578
661
  key: id,
579
662
  "aria-labelledby": `${id}__label`,
580
663
  "aria-describedby": `${id}__description`,
581
664
  checked: activeActionKey2 === id,
582
665
  onCheckedChange: (checked) => checked && setActiveAction(id),
583
666
  classNames: "gap-2"
584
- }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
585
- className: getSize3(5)
586
- }), /* @__PURE__ */ React11.createElement("div", {
667
+ }, action.icon && /* @__PURE__ */ React13.createElement(action.icon, {
668
+ className: getSize5(5)
669
+ }), /* @__PURE__ */ React13.createElement("div", {
587
670
  role: "none",
588
671
  className: "flex-1 min-is-0 space-b-1"
589
- }, /* @__PURE__ */ React11.createElement("p", {
672
+ }, /* @__PURE__ */ React13.createElement("p", {
590
673
  id: `${id}__label`
591
- }, action.label), action.description && /* @__PURE__ */ React11.createElement("p", {
674
+ }, action.label), action.description && /* @__PURE__ */ React13.createElement("p", {
592
675
  id: `${id}__description`,
593
676
  className: descriptionText4
594
- }, action.description)), /* @__PURE__ */ React11.createElement(DropdownMenu.ItemIndicator, {
677
+ }, action.description)), /* @__PURE__ */ React13.createElement(DropdownMenu2.ItemIndicator, {
595
678
  asChild: true
596
- }, /* @__PURE__ */ React11.createElement(Check2, {
679
+ }, /* @__PURE__ */ React13.createElement(Check3, {
597
680
  weight: "bold",
598
- className: getSize3(4)
681
+ className: getSize5(4)
599
682
  })));
600
- })), /* @__PURE__ */ React11.createElement(DropdownMenu.Arrow, null))));
683
+ })), /* @__PURE__ */ React13.createElement(DropdownMenu2.Arrow, null))));
601
684
  });
602
685
  var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
603
686
  const { children, classNames, variant, isFull = true, ...rest } = props;
604
- return /* @__PURE__ */ React11.createElement(Button3, {
687
+ return /* @__PURE__ */ React13.createElement(Button5, {
605
688
  ...rest,
606
689
  classNames: [
607
690
  isFull && "is-full",
@@ -614,10 +697,10 @@ var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
614
697
  });
615
698
 
616
699
  // packages/sdk/shell/src/components/Panel/Actions.tsx
617
- import React12, { forwardRef as forwardRef3 } from "react";
700
+ import React14, { forwardRef as forwardRef3 } from "react";
618
701
  import { mx as mx10 } from "@dxos/react-ui-theme";
619
702
  var Actions = /* @__PURE__ */ forwardRef3(({ classNames, children, ...props }, forwardedRef) => {
620
- return /* @__PURE__ */ React12.createElement("div", {
703
+ return /* @__PURE__ */ React14.createElement("div", {
621
704
  ...props,
622
705
  className: mx10("flex flex-col gap-2 mbs-2", Array.isArray(children) && children.length > 1 ? "justify-between" : "justify-center", classNames),
623
706
  ref: forwardedRef
@@ -626,37 +709,37 @@ var Actions = /* @__PURE__ */ forwardRef3(({ classNames, children, ...props }, f
626
709
 
627
710
  // packages/sdk/shell/src/components/Panel/CloseButton.tsx
628
711
  import { X as X2 } from "@phosphor-icons/react";
629
- import React13 from "react";
630
- import { Button as Button4, useTranslation as useTranslation6 } from "@dxos/react-ui";
631
- import { getSize as getSize4, mx as mx11 } from "@dxos/react-ui-theme";
712
+ import React15 from "react";
713
+ import { Button as Button6, useTranslation as useTranslation8 } from "@dxos/react-ui";
714
+ import { getSize as getSize6, mx as mx11 } from "@dxos/react-ui-theme";
632
715
  var CloseButton = ({ onDone, ...props }) => {
633
- const { t } = useTranslation6("os");
634
- return /* @__PURE__ */ React13.createElement(Button4, {
716
+ const { t } = useTranslation8("os");
717
+ return /* @__PURE__ */ React15.createElement(Button6, {
635
718
  variant: "ghost",
636
719
  classNames: mx11("plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
637
720
  onClick: () => onDone?.(),
638
721
  ...props
639
- }, /* @__PURE__ */ React13.createElement(X2, {
722
+ }, /* @__PURE__ */ React15.createElement(X2, {
640
723
  weight: "bold",
641
- className: getSize4(4)
642
- }), /* @__PURE__ */ React13.createElement("span", {
724
+ className: getSize6(4)
725
+ }), /* @__PURE__ */ React15.createElement("span", {
643
726
  className: "sr-only"
644
727
  }, t("exit label")));
645
728
  };
646
729
 
647
730
  // packages/sdk/shell/src/components/Panel/Emoji.tsx
648
- import React14 from "react";
649
- import { mx as mx12, getSize as getSize5 } from "@dxos/react-ui-theme";
731
+ import React16 from "react";
732
+ import { mx as mx12, getSize as getSize7 } from "@dxos/react-ui-theme";
650
733
  var Emoji = ({ text, className }) => {
651
734
  const size = 14;
652
- return /* @__PURE__ */ React14.createElement("div", {
735
+ return /* @__PURE__ */ React16.createElement("div", {
653
736
  role: "none",
654
- className: mx12(getSize5(size), "rounded relative pointer-events-none", className)
655
- }, /* @__PURE__ */ React14.createElement("svg", {
737
+ className: mx12(getSize7(size), "rounded relative pointer-events-none", className)
738
+ }, /* @__PURE__ */ React16.createElement("svg", {
656
739
  viewBox: `0 0 ${size * 4} ${size * 4}`,
657
740
  width: size * 4,
658
741
  height: size * 4
659
- }, /* @__PURE__ */ React14.createElement("text", {
742
+ }, /* @__PURE__ */ React16.createElement("text", {
660
743
  x: "50%",
661
744
  y: "50%",
662
745
  textAnchor: "middle",
@@ -667,55 +750,55 @@ var Emoji = ({ text, className }) => {
667
750
  };
668
751
  var Centered = (props) => {
669
752
  const { children } = props;
670
- return /* @__PURE__ */ React14.createElement("div", {
753
+ return /* @__PURE__ */ React16.createElement("div", {
671
754
  role: "none",
672
755
  className: "absolute inset-0 flex items-center justify-center"
673
756
  }, children);
674
757
  };
675
758
 
676
759
  // packages/sdk/shell/src/components/Panel/Heading.tsx
677
- import React15, { forwardRef as forwardRef4 } from "react";
760
+ import React17, { forwardRef as forwardRef4 } from "react";
678
761
  import { descriptionText as descriptionText5, mx as mx13 } from "@dxos/react-ui-theme";
679
762
  var Heading = /* @__PURE__ */ forwardRef4(({ titleId, title, titleSrOnly, children, corner }, forwardedRef) => {
680
- return /* @__PURE__ */ React15.createElement("div", {
763
+ return /* @__PURE__ */ React17.createElement("div", {
681
764
  role: "none",
682
765
  className: "pbe-2 relative",
683
766
  ref: forwardedRef
684
- }, corner, /* @__PURE__ */ React15.createElement("h1", {
767
+ }, corner, /* @__PURE__ */ React17.createElement("h1", {
685
768
  ...!titleSrOnly && {
686
769
  id: titleId
687
770
  },
688
771
  className: mx13(descriptionText5, "text-center mlb-2", titleSrOnly && "invisible")
689
- }, title), titleSrOnly && /* @__PURE__ */ React15.createElement("span", {
772
+ }, title), titleSrOnly && /* @__PURE__ */ React17.createElement("span", {
690
773
  id: titleId
691
774
  }, title), children);
692
775
  });
693
776
 
694
777
  // packages/sdk/shell/src/components/Panel/Label.tsx
695
- import React16 from "react";
778
+ import React18 from "react";
696
779
  import { descriptionText as descriptionText6, mx as mx14 } from "@dxos/react-ui-theme";
697
780
  var Label = (props) => {
698
781
  const { children } = props;
699
- return /* @__PURE__ */ React16.createElement("span", {
782
+ return /* @__PURE__ */ React18.createElement("span", {
700
783
  className: mx14(descriptionText6, "text-center mli-6 whitespace-normal")
701
784
  }, children);
702
785
  };
703
786
 
704
787
  // packages/sdk/shell/src/components/Panel/Input.tsx
705
- import React17 from "react";
788
+ import React19 from "react";
706
789
  import { Input as UiInput } from "@dxos/react-ui";
707
790
  var Input = ({ validationMessage, label, ...props }) => {
708
- return /* @__PURE__ */ React17.createElement(UiInput.Root, null, /* @__PURE__ */ React17.createElement(UiInput.Label, null, label), /* @__PURE__ */ React17.createElement(UiInput.TextInput, {
791
+ return /* @__PURE__ */ React19.createElement(UiInput.Root, null, /* @__PURE__ */ React19.createElement(UiInput.Label, null, label), /* @__PURE__ */ React19.createElement(UiInput.TextInput, {
709
792
  ...props,
710
793
  classNames: "plb-3 mbs-2 text-center"
711
- }), /* @__PURE__ */ React17.createElement(UiInput.DescriptionAndValidation, null, validationMessage && /* @__PURE__ */ React17.createElement(UiInput.Validation, null, validationMessage)));
794
+ }), /* @__PURE__ */ React19.createElement(UiInput.DescriptionAndValidation, null, validationMessage && /* @__PURE__ */ React19.createElement(UiInput.Validation, null, validationMessage)));
712
795
  };
713
796
 
714
797
  // packages/sdk/shell/src/components/Panel/StepHeading.tsx
715
- import React18, { forwardRef as forwardRef5 } from "react";
798
+ import React20, { forwardRef as forwardRef5 } from "react";
716
799
  import { mx as mx15 } from "@dxos/react-ui-theme";
717
800
  var StepHeading = /* @__PURE__ */ forwardRef5(({ children, className, ...props }, forwardedRef) => {
718
- return /* @__PURE__ */ React18.createElement("h2", {
801
+ return /* @__PURE__ */ React20.createElement("h2", {
719
802
  ...props,
720
803
  className: mx15("font-normal text-sm mbe-4 mli-1 text-center", className),
721
804
  ref: forwardedRef
@@ -725,8 +808,8 @@ var StepHeading = /* @__PURE__ */ forwardRef5(({ children, className, ...props }
725
808
  // packages/sdk/shell/src/components/Viewport/Viewport.tsx
726
809
  import { useFocusFinders } from "@fluentui/react-tabster";
727
810
  import { createContextScope } from "@radix-ui/react-context";
728
- import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
729
- import React19, { forwardRef as forwardRef6, useEffect } from "react";
811
+ import { useControllableState as useControllableState4 } from "@radix-ui/react-use-controllable-state";
812
+ import React21, { forwardRef as forwardRef6, useEffect } from "react";
730
813
  import { useForwardedRef } from "@dxos/react-ui";
731
814
  import { mx as mx16 } from "@dxos/react-ui-theme";
732
815
  var VIEWPORT_NAME = "Viewport";
@@ -735,17 +818,17 @@ var VIEW_NAME = "ViewportView";
735
818
  var [createViewportContext, createViewportScope] = createContextScope(VIEWPORT_NAME, []);
736
819
  var [ViewportProvider, useViewportContext] = createViewportContext(VIEWPORT_NAME);
737
820
  var ViewportRoot = ({ __viewportScope, classNames, children, defaultActiveView, activeView: propsActiveView, focusManaged = false, onActiveViewChange, ...props }) => {
738
- const [activeView = "never", setActiveView] = useControllableState2({
821
+ const [activeView = "never", setActiveView] = useControllableState4({
739
822
  prop: propsActiveView,
740
823
  defaultProp: defaultActiveView,
741
824
  onChange: onActiveViewChange
742
825
  });
743
- return /* @__PURE__ */ React19.createElement(ViewportProvider, {
826
+ return /* @__PURE__ */ React21.createElement(ViewportProvider, {
744
827
  focusManaged,
745
828
  activeView,
746
829
  setActiveView,
747
830
  scope: __viewportScope
748
- }, /* @__PURE__ */ React19.createElement("div", {
831
+ }, /* @__PURE__ */ React21.createElement("div", {
749
832
  role: "region",
750
833
  "aria-live": "polite",
751
834
  ...props,
@@ -757,7 +840,7 @@ var ViewportViews = ({ classNames, children, ...props }) => {
757
840
  const size = {
758
841
  inlineSize: `${Math.ceil(children.length) * 100}%`
759
842
  };
760
- return /* @__PURE__ */ React19.createElement("div", {
843
+ return /* @__PURE__ */ React21.createElement("div", {
761
844
  role: "none",
762
845
  style: size,
763
846
  ...props,
@@ -779,7 +862,7 @@ var ViewportView = /* @__PURE__ */ forwardRef6(({ __viewportScope, classNames, c
779
862
  ref.current,
780
863
  isActive
781
864
  ]);
782
- return /* @__PURE__ */ React19.createElement("section", {
865
+ return /* @__PURE__ */ React21.createElement("section", {
783
866
  ...props,
784
867
  ...!isActive && {
785
868
  "aria-hidden": true
@@ -796,41 +879,41 @@ var Viewport = {
796
879
  };
797
880
 
798
881
  // packages/sdk/shell/src/components/SpaceListItem.tsx
799
- import React20, { forwardRef as forwardRef7 } from "react";
800
- import { Avatar as Avatar3, useId as useId3, useJdenticonHref as useJdenticonHref2 } from "@dxos/react-ui";
882
+ import React22, { forwardRef as forwardRef7 } from "react";
883
+ import { Avatar as Avatar3, useId as useId3 } from "@dxos/react-ui";
801
884
  import { mx as mx17 } from "@dxos/react-ui-theme";
802
- import { humanize } from "@dxos/util";
885
+ import { humanize, keyToEmoji } from "@dxos/util";
803
886
  var SpaceListItem = /* @__PURE__ */ forwardRef7(({ space, onClick }, ref) => {
804
- const fallbackValue = space.key.toHex();
887
+ const fallbackValue = keyToEmoji(space.key);
805
888
  const labelId = useId3("identityListItem__label");
806
- const jdenticon = useJdenticonHref2(fallbackValue ?? "", 12);
807
889
  const displayName = space.properties.name ?? humanize(space.key.toHex());
808
- return /* @__PURE__ */ React20.createElement("li", {
890
+ return /* @__PURE__ */ React22.createElement("li", {
809
891
  className: mx17("flex gap-2 items-center mbe-2", onClick && "cursor-pointer"),
810
892
  onClick: () => onClick?.(),
811
893
  ref,
812
894
  "data-testid": "space-list-item"
813
- }, /* @__PURE__ */ React20.createElement(Avatar3.Root, {
895
+ }, /* @__PURE__ */ React22.createElement(Avatar3.Root, {
814
896
  labelId
815
- }, /* @__PURE__ */ React20.createElement(Avatar3.Frame, null, /* @__PURE__ */ React20.createElement(Avatar3.Fallback, {
816
- href: jdenticon
817
- })), /* @__PURE__ */ React20.createElement(Avatar3.Label, {
897
+ }, /* @__PURE__ */ React22.createElement(Avatar3.Frame, null, /* @__PURE__ */ React22.createElement(Avatar3.Fallback, {
898
+ text: fallbackValue
899
+ })), /* @__PURE__ */ React22.createElement(Avatar3.Label, {
818
900
  classNames: "text-sm truncate"
819
901
  }, displayName)));
820
902
  });
821
903
 
822
904
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
823
- import React40 from "react";
905
+ import React42 from "react";
824
906
  import { Dialog, useId as useId9 } from "@dxos/react-ui";
825
907
 
826
908
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
827
- import React27, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
909
+ import React29, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
828
910
  import { generateName as generateName3 } from "@dxos/display-name";
829
- import { log as log3 } from "@dxos/log";
911
+ import { log as log5 } from "@dxos/log";
830
912
  import { useClient as useClient3 } from "@dxos/react-client";
831
913
  import { useIdentity, useDevices, useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
832
914
  import { useInvitationStatus as useInvitationStatus2 } from "@dxos/react-client/invitations";
833
- import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation13 } from "@dxos/react-ui";
915
+ import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useTranslation as useTranslation15 } from "@dxos/react-ui";
916
+ import { keyToFallback as keyToFallback2 } from "@dxos/util";
834
917
 
835
918
  // packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts
836
919
  import { useMachine } from "@xstate/react";
@@ -959,30 +1042,30 @@ var useIdentityMachine = (client, options) => {
959
1042
  };
960
1043
 
961
1044
  // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentForm.tsx
962
- import React21 from "react";
963
- import { useTranslation as useTranslation7 } from "@dxos/react-ui";
1045
+ import React23 from "react";
1046
+ import { useTranslation as useTranslation9 } from "@dxos/react-ui";
964
1047
  var AgentForm = (props) => {
965
1048
  const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
966
1049
  const disabled = !active;
967
- const { t } = useTranslation7("os");
968
- return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
1050
+ const { t } = useTranslation9("os");
1051
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", {
969
1052
  role: "none",
970
1053
  className: "grow flex flex-col justify-center"
971
- }, /* @__PURE__ */ React21.createElement(Input, {
1054
+ }, /* @__PURE__ */ React23.createElement(Input, {
972
1055
  validationMessage,
973
- label: /* @__PURE__ */ React21.createElement(StepHeading, null, "Agent Status"),
1056
+ label: /* @__PURE__ */ React23.createElement(StepHeading, null, "Agent Status"),
974
1057
  disabled,
975
1058
  "data-testid": "agent-status",
976
1059
  value: agentStatus
977
- })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
1060
+ })), /* @__PURE__ */ React23.createElement(Actions, null, /* @__PURE__ */ React23.createElement(Action, {
978
1061
  disabled: agentActive || agentProviderDisabled,
979
1062
  onClick: () => onAgentCreate?.(),
980
1063
  "data-testid": "create-agent"
981
- }, "Create Agent"), /* @__PURE__ */ React21.createElement(Action, {
1064
+ }, "Create Agent"), /* @__PURE__ */ React23.createElement(Action, {
982
1065
  disabled: !agentActive || agentProviderDisabled,
983
1066
  onClick: () => onAgentDestroy?.(),
984
1067
  "data-testid": "destroy-agent"
985
- }, "Destroy Agent"), /* @__PURE__ */ React21.createElement(Action, {
1068
+ }, "Destroy Agent"), /* @__PURE__ */ React23.createElement(Action, {
986
1069
  disabled,
987
1070
  onClick: () => send?.({
988
1071
  type: "unchooseAction"
@@ -992,17 +1075,17 @@ var AgentForm = (props) => {
992
1075
  };
993
1076
 
994
1077
  // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
995
- import React22 from "react";
996
- import { useTranslation as useTranslation8 } from "@dxos/react-ui";
1078
+ import React24 from "react";
1079
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
997
1080
  var DeviceManager = ({ devices, active, send }) => {
998
- const { t } = useTranslation8("os");
1081
+ const { t } = useTranslation10("os");
999
1082
  const disabled = !active;
1000
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
1083
+ return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1001
1084
  role: "none",
1002
1085
  className: "grow"
1003
- }, /* @__PURE__ */ React22.createElement(DeviceList, {
1086
+ }, /* @__PURE__ */ React24.createElement(DeviceList, {
1004
1087
  devices
1005
- })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
1088
+ })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1006
1089
  variant: "ghost",
1007
1090
  disabled,
1008
1091
  onClick: () => send?.({
@@ -1014,12 +1097,14 @@ var DeviceManager = ({ devices, active, send }) => {
1014
1097
 
1015
1098
  // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
1016
1099
  import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from "@phosphor-icons/react";
1017
- import React23, { useCallback as useCallback4 } from "react";
1100
+ import React25, { useCallback as useCallback4 } from "react";
1101
+ import { log as log2 } from "@dxos/log";
1018
1102
  import { useAgentHostingProviderClient, useClient as useClient2 } from "@dxos/react-client";
1019
1103
  import { useHaloInvitations } from "@dxos/react-client/halo";
1020
- import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
1021
- import { DensityProvider, useTranslation as useTranslation9 } from "@dxos/react-ui";
1022
- import { getSize as getSize6 } from "@dxos/react-ui-theme";
1104
+ import { Invitation as Invitation2, InvitationEncoder } from "@dxos/react-client/invitations";
1105
+ import { DensityProvider, useTranslation as useTranslation11 } from "@dxos/react-ui";
1106
+ import { getSize as getSize8 } from "@dxos/react-ui-theme";
1107
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx";
1023
1108
  var IdentityActionChooser = (props) => {
1024
1109
  const { send } = props;
1025
1110
  const client = useClient2();
@@ -1027,19 +1112,24 @@ var IdentityActionChooser = (props) => {
1027
1112
  const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
1028
1113
  const onInvitationEvent = useCallback4((invitation) => {
1029
1114
  const invitationCode = InvitationEncoder.encode(invitation);
1030
- if (invitation.state === Invitation3.State.CONNECTING) {
1031
- console.log(JSON.stringify({
1115
+ if (invitation.state === Invitation2.State.CONNECTING) {
1116
+ log2.info(JSON.stringify({
1032
1117
  invitationCode,
1033
1118
  authCode: invitation.authCode
1034
- }));
1119
+ }), void 0, {
1120
+ F: __dxlog_file2,
1121
+ L: 28,
1122
+ S: void 0,
1123
+ C: (f, a) => f(...a)
1124
+ });
1035
1125
  }
1036
1126
  }, []);
1037
1127
  const createInvitation = (e) => {
1038
1128
  const testing = e.altKey && e.shiftKey;
1039
1129
  invitations.forEach((invitation2) => invitation2.cancel());
1040
1130
  const invitation = client.halo.share(testing ? {
1041
- type: Invitation3.Type.MULTIUSE,
1042
- authMethod: Invitation3.AuthMethod.NONE
1131
+ type: Invitation2.Type.MULTIUSE,
1132
+ authMethod: Invitation2.AuthMethod.NONE
1043
1133
  } : void 0);
1044
1134
  if (true) {
1045
1135
  invitation.subscribe(onInvitationEvent);
@@ -1049,138 +1139,157 @@ var IdentityActionChooser = (props) => {
1049
1139
  invitation
1050
1140
  });
1051
1141
  };
1052
- return /* @__PURE__ */ React23.createElement(IdentityActionChooserImpl, {
1142
+ return /* @__PURE__ */ React25.createElement(IdentityActionChooserImpl, {
1053
1143
  ...props,
1054
1144
  onCreateInvitationClick: (e) => createInvitation(e),
1055
1145
  agentHostingEnabled: !!agentHostingProviderClient
1056
1146
  });
1057
1147
  };
1058
1148
  var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent, agentHostingEnabled }) => {
1059
- const { t } = useTranslation9("os");
1060
- return /* @__PURE__ */ React23.createElement("div", {
1149
+ const { t } = useTranslation11("os");
1150
+ return /* @__PURE__ */ React25.createElement("div", {
1061
1151
  role: "none",
1062
1152
  className: "grow flex flex-col gap-1"
1063
- }, /* @__PURE__ */ React23.createElement(DensityProvider, {
1153
+ }, /* @__PURE__ */ React25.createElement(DensityProvider, {
1064
1154
  density: "coarse"
1065
- }, /* @__PURE__ */ React23.createElement("div", {
1155
+ }, /* @__PURE__ */ React25.createElement("div", {
1066
1156
  className: "grow justify-center flex flex-col gap-1"
1067
- }, agentHostingEnabled && /* @__PURE__ */ React23.createElement(Action, {
1157
+ }, agentHostingEnabled && /* @__PURE__ */ React25.createElement(Action, {
1068
1158
  "data-testid": "manage-agent",
1069
1159
  onClick: () => send?.({
1070
1160
  type: "chooseAgent"
1071
1161
  }),
1072
1162
  classNames: "plb-4"
1073
- }, /* @__PURE__ */ React23.createElement(HardDrive, {
1074
- className: getSize6(6)
1075
- }), /* @__PURE__ */ React23.createElement("span", {
1163
+ }, /* @__PURE__ */ React25.createElement(HardDrive, {
1164
+ className: getSize8(6)
1165
+ }), /* @__PURE__ */ React25.createElement("span", {
1076
1166
  className: "grow mli-3"
1077
- }, "Manage Agent"), /* @__PURE__ */ React23.createElement(CaretRight, {
1167
+ }, "Manage Agent"), /* @__PURE__ */ React25.createElement(CaretRight, {
1078
1168
  weight: "bold",
1079
- className: getSize6(4)
1080
- })), /* @__PURE__ */ React23.createElement(Action, {
1169
+ className: getSize8(4)
1170
+ })), /* @__PURE__ */ React25.createElement(Action, {
1081
1171
  disabled: !active,
1082
1172
  "data-testid": "devices-panel.create-invitation",
1083
1173
  onClick: onCreateInvitationClick,
1084
1174
  classNames: "plb-4"
1085
- }, /* @__PURE__ */ React23.createElement(Plus, {
1086
- className: getSize6(6)
1087
- }), /* @__PURE__ */ React23.createElement("span", {
1175
+ }, /* @__PURE__ */ React25.createElement(Plus, {
1176
+ className: getSize8(6)
1177
+ }), /* @__PURE__ */ React25.createElement("span", {
1088
1178
  className: "grow mli-3"
1089
- }, t("choose add device label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1179
+ }, t("choose add device label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1090
1180
  weight: "bold",
1091
- className: getSize6(4)
1092
- })), /* @__PURE__ */ React23.createElement(Action, {
1181
+ className: getSize8(4)
1182
+ })), /* @__PURE__ */ React25.createElement(Action, {
1093
1183
  "data-testid": "manage-devices",
1094
1184
  onClick: () => send?.({
1095
1185
  type: "chooseDevices"
1096
1186
  }),
1097
1187
  classNames: "plb-4"
1098
- }, /* @__PURE__ */ React23.createElement(Devices, {
1099
- className: getSize6(6)
1100
- }), /* @__PURE__ */ React23.createElement("span", {
1188
+ }, /* @__PURE__ */ React25.createElement(Devices, {
1189
+ className: getSize8(6)
1190
+ }), /* @__PURE__ */ React25.createElement("span", {
1101
1191
  className: "grow mli-3"
1102
- }, t("choose devices label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1192
+ }, t("choose devices label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1103
1193
  weight: "bold",
1104
- className: getSize6(4)
1105
- })), /* @__PURE__ */ React23.createElement(Action, {
1194
+ className: getSize8(4)
1195
+ })), /* @__PURE__ */ React25.createElement(Action, {
1106
1196
  "data-testid": "manage-profile",
1107
1197
  onClick: () => send?.({
1108
1198
  type: "chooseProfile"
1109
1199
  }),
1110
1200
  classNames: "plb-4"
1111
- }, /* @__PURE__ */ React23.createElement(UserGear, {
1112
- className: getSize6(6)
1113
- }), /* @__PURE__ */ React23.createElement("span", {
1201
+ }, /* @__PURE__ */ React25.createElement(UserGear, {
1202
+ className: getSize8(6)
1203
+ }), /* @__PURE__ */ React25.createElement("span", {
1114
1204
  className: "grow mli-3"
1115
- }, t("choose profile label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1205
+ }, t("choose profile label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1116
1206
  weight: "bold",
1117
- className: getSize6(4)
1118
- })), /* @__PURE__ */ React23.createElement(Action, {
1207
+ className: getSize8(4)
1208
+ })), /* @__PURE__ */ React25.createElement(Action, {
1119
1209
  "data-testid": "devices-panel.sign-out",
1120
1210
  onClick: () => send?.({
1121
1211
  type: "chooseSignOut"
1122
1212
  }),
1123
1213
  classNames: "plb-4"
1124
- }, /* @__PURE__ */ React23.createElement(Power, {
1125
- className: getSize6(6)
1126
- }), /* @__PURE__ */ React23.createElement("span", {
1214
+ }, /* @__PURE__ */ React25.createElement(Power, {
1215
+ className: getSize8(6)
1216
+ }), /* @__PURE__ */ React25.createElement("span", {
1127
1217
  className: "grow mli-3"
1128
- }, t("choose sign out label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1218
+ }, t("choose sign out label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1129
1219
  weight: "bold",
1130
- className: getSize6(4)
1220
+ className: getSize8(4)
1131
1221
  })))));
1132
1222
  };
1133
1223
 
1134
1224
  // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1135
- import React24, { useState as useState3 } from "react";
1136
- import { log as log2 } from "@dxos/log";
1137
- import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1138
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1225
+ import React26, { useState as useState4 } from "react";
1226
+ import { log as log3 } from "@dxos/log";
1227
+ import { useTranslation as useTranslation12 } from "@dxos/react-ui";
1228
+ import { hexToEmoji as hexToEmoji2, hexToHue } from "@dxos/util";
1229
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1139
1230
  var ProfileForm = (props) => {
1140
1231
  const { onUpdateProfile } = props;
1141
- const { t } = useTranslation10("os");
1142
- const [validationMessage, setValidationMessage] = useState3("");
1232
+ const { t } = useTranslation12("os");
1233
+ const [validationMessage, setValidationMessage] = useState4("");
1143
1234
  const handleUpdateProfile = async (profile) => {
1144
1235
  await onUpdateProfile?.(profile).catch((error) => {
1145
- log2.catch(error, void 0, {
1146
- F: __dxlog_file2,
1147
- L: 32,
1236
+ log3.catch(error, void 0, {
1237
+ F: __dxlog_file3,
1238
+ L: 33,
1148
1239
  S: void 0,
1149
1240
  C: (f, a) => f(...a)
1150
1241
  });
1151
1242
  setValidationMessage(t("failed to update profile message"));
1152
1243
  });
1153
1244
  };
1154
- return /* @__PURE__ */ React24.createElement(ProfileFormImpl, {
1245
+ return /* @__PURE__ */ React26.createElement(ProfileFormImpl, {
1155
1246
  ...props,
1156
1247
  onUpdateProfile: handleUpdateProfile,
1157
1248
  validationMessage
1158
1249
  });
1159
1250
  };
1251
+ var getHueValue = (identity) => identity?.profile?.data?.hue || hexToHue(identity?.identityKey.toHex() ?? "0");
1252
+ var getEmojiValue = (identity) => identity?.profile?.data?.emoji || hexToEmoji2(identity?.identityKey.toHex() ?? "0");
1160
1253
  var ProfileFormImpl = (props) => {
1161
1254
  const { active, identity, send, onUpdateProfile, validationMessage } = props;
1162
1255
  const profile = identity?.profile;
1163
1256
  const disabled = !active;
1164
- const { t } = useTranslation10("os");
1165
- const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1257
+ const { t } = useTranslation12("os");
1258
+ const [displayName, setDisplayName] = useState4(profile?.displayName ?? "");
1259
+ const [hue, setHue] = useState4(getHueValue(identity));
1260
+ const [emoji, setEmoji] = useState4(getEmojiValue(identity));
1166
1261
  const { textValue, setTextValue } = useClipboardContext();
1167
1262
  const identityHex = identity?.identityKey.toHex();
1168
1263
  const copied = textValue === identityHex;
1169
- return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1264
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("div", {
1170
1265
  role: "none",
1171
1266
  className: "grow flex flex-col justify-center"
1172
- }, /* @__PURE__ */ React24.createElement(Input, {
1267
+ }, /* @__PURE__ */ React26.createElement(Input, {
1173
1268
  validationMessage,
1174
- label: /* @__PURE__ */ React24.createElement(StepHeading, null, t("display name input label")),
1269
+ label: /* @__PURE__ */ React26.createElement(StepHeading, {
1270
+ className: "m-0"
1271
+ }, t("display name input label")),
1175
1272
  disabled,
1176
1273
  "data-testid": "display-name-input",
1177
1274
  placeholder: t("display name input placeholder"),
1178
- value: inputValue,
1179
- onChange: ({ target: { value } }) => setInputValue(value),
1180
- onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1181
- displayName: inputValue
1182
- })
1183
- })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1275
+ value: displayName,
1276
+ onChange: ({ target: { value } }) => setDisplayName(value)
1277
+ }), /* @__PURE__ */ React26.createElement(StepHeading, {
1278
+ className: "mbe-2"
1279
+ }, t("emoji and color label")), /* @__PURE__ */ React26.createElement("div", {
1280
+ role: "none",
1281
+ className: "grid grid-cols-[1fr_min-content] gap-y-2"
1282
+ }, /* @__PURE__ */ React26.createElement(EmojiPicker, {
1283
+ emoji,
1284
+ onChangeEmoji: setEmoji,
1285
+ disabled,
1286
+ onClickClear: () => setEmoji(getEmojiValue(identity))
1287
+ }), /* @__PURE__ */ React26.createElement(HuePicker, {
1288
+ hue,
1289
+ onChangeHue: setHue,
1290
+ disabled,
1291
+ onClickClear: () => setHue(getHueValue(identity))
1292
+ }))), /* @__PURE__ */ React26.createElement(Actions, null, /* @__PURE__ */ React26.createElement(Action, {
1184
1293
  variant: "ghost",
1185
1294
  disabled,
1186
1295
  onClick: () => {
@@ -1189,18 +1298,22 @@ var ProfileFormImpl = (props) => {
1189
1298
  }
1190
1299
  },
1191
1300
  "data-testid": "update-profile-form-copy-key"
1192
- }, t(copied ? "copy success label" : "copy self public key label")), /* @__PURE__ */ React24.createElement(Action, {
1301
+ }, t(copied ? "copy success label" : "copy self public key label")), /* @__PURE__ */ React26.createElement(Action, {
1193
1302
  variant: "ghost",
1194
1303
  disabled,
1195
1304
  onClick: () => send?.({
1196
1305
  type: "unchooseAction"
1197
1306
  }),
1198
1307
  "data-testid": "update-profile-form-back"
1199
- }, t("back label")), /* @__PURE__ */ React24.createElement(Action, {
1308
+ }, t("back label")), /* @__PURE__ */ React26.createElement(Action, {
1200
1309
  variant: "primary",
1201
1310
  disabled,
1202
1311
  onClick: () => onUpdateProfile?.({
1203
- displayName: inputValue
1312
+ displayName,
1313
+ data: {
1314
+ emoji,
1315
+ hue
1316
+ }
1204
1317
  }),
1205
1318
  "data-testid": "update-profile-form-continue"
1206
1319
  }, t("done label"))));
@@ -1208,17 +1321,17 @@ var ProfileFormImpl = (props) => {
1208
1321
 
1209
1322
  // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1210
1323
  import { Warning } from "@phosphor-icons/react";
1211
- import React25 from "react";
1212
- import { Message, useTranslation as useTranslation11 } from "@dxos/react-ui";
1213
- import { getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1324
+ import React27 from "react";
1325
+ import { Message, useTranslation as useTranslation13 } from "@dxos/react-ui";
1326
+ import { getSize as getSize9, mx as mx18 } from "@dxos/react-ui-theme";
1214
1327
  var SignOutChooser = (props) => {
1215
- const { t } = useTranslation11("os");
1328
+ const { t } = useTranslation13("os");
1216
1329
  const onResetDevice = () => {
1217
1330
  if (window.confirm(t("reset device confirm message"))) {
1218
1331
  void props.onResetDevice?.();
1219
1332
  }
1220
1333
  };
1221
- return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1334
+ return /* @__PURE__ */ React27.createElement(SignOutChooserImpl, {
1222
1335
  disabled: !props.active,
1223
1336
  onBack: () => props.send?.({
1224
1337
  type: "unchooseAction"
@@ -1228,24 +1341,24 @@ var SignOutChooser = (props) => {
1228
1341
  });
1229
1342
  };
1230
1343
  var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1231
- const { t } = useTranslation11("os");
1232
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1344
+ const { t } = useTranslation13("os");
1345
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement("div", {
1233
1346
  role: "none",
1234
1347
  className: "grow flex flex-col justify-center"
1235
- }, /* @__PURE__ */ React25.createElement(Message.Root, {
1348
+ }, /* @__PURE__ */ React27.createElement(Message.Root, {
1236
1349
  valence: "error"
1237
- }, /* @__PURE__ */ React25.createElement(Message.Title, null, /* @__PURE__ */ React25.createElement(Warning, {
1238
- className: mx18(getSize7(6), "inline mie-2")
1239
- }), t("sign out chooser title")), /* @__PURE__ */ React25.createElement(Message.Body, null, t("sign out chooser message")))), /* @__PURE__ */ React25.createElement(Actions, null, /* @__PURE__ */ React25.createElement(Action, {
1350
+ }, /* @__PURE__ */ React27.createElement(Message.Title, null, /* @__PURE__ */ React27.createElement(Warning, {
1351
+ className: mx18(getSize9(6), "inline mie-2")
1352
+ }), t("sign out chooser title")), /* @__PURE__ */ React27.createElement(Message.Body, null, t("sign out chooser message")))), /* @__PURE__ */ React27.createElement(Actions, null, /* @__PURE__ */ React27.createElement(Action, {
1240
1353
  disabled,
1241
1354
  onClick: onBack
1242
- }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1355
+ }, t("back label")), /* @__PURE__ */ React27.createElement(Action, {
1243
1356
  variant: "primary",
1244
1357
  "data-testid": "sign-out.join-new-identity",
1245
1358
  classNames: "!bg-error-500 hover:!bg-error-550",
1246
1359
  disabled,
1247
1360
  onClick: onJoinNewIdentity
1248
- }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1361
+ }, t("join new identity label")), /* @__PURE__ */ React27.createElement(Action, {
1249
1362
  variant: "primary",
1250
1363
  "data-testid": "sign-out.reset-device",
1251
1364
  classNames: "!bg-error-500 hover:!bg-error-550",
@@ -1255,15 +1368,16 @@ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }
1255
1368
  };
1256
1369
 
1257
1370
  // packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts
1258
- import { useCallback as useCallback5, useEffect as useEffect2, useState as useState4 } from "react";
1371
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState5 } from "react";
1259
1372
  import { invariant } from "@dxos/invariant";
1373
+ import { log as log4 } from "@dxos/log";
1260
1374
  import { useAgentHostingProviderClient as useAgentHostingProviderClient2 } from "@dxos/react-client";
1261
- import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1262
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1375
+ import { Invitation as Invitation3, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1376
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1263
1377
  var useAgentHandlers = ({ client, invitations, identity }) => {
1264
- const [validationMessage, setValidationMessage] = useState4("");
1265
- const [agentStatus, setAgentStatus] = useState4("");
1266
- const [agentActive, setAgentActive] = useState4(false);
1378
+ const [validationMessage, setValidationMessage] = useState5("");
1379
+ const [agentStatus, setAgentStatus] = useState5("");
1380
+ const [agentActive, setAgentActive] = useState5(false);
1267
1381
  const agentHostingProviderClient = useAgentHostingProviderClient2(client.config);
1268
1382
  useEffect2(() => {
1269
1383
  const fetchAgentStatus = async () => {
@@ -1284,15 +1398,20 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1284
1398
  }, []);
1285
1399
  const handleAgentCreate = useCallback5(async (invitation) => {
1286
1400
  const invitationCode = InvitationEncoder2.encode(invitation);
1287
- if (invitation.state === Invitation4.State.CONNECTING) {
1288
- console.log(JSON.stringify({
1401
+ if (invitation.state === Invitation3.State.CONNECTING) {
1402
+ log4.info(JSON.stringify({
1289
1403
  invitationCode,
1290
1404
  authCode: invitation.authCode
1291
- }));
1292
- invariant(identity, "Identity not found", {
1293
- F: __dxlog_file3,
1405
+ }), void 0, {
1406
+ F: __dxlog_file4,
1294
1407
  L: 50,
1295
1408
  S: void 0,
1409
+ C: (f, a) => f(...a)
1410
+ });
1411
+ invariant(identity, "Identity not found", {
1412
+ F: __dxlog_file4,
1413
+ L: 51,
1414
+ S: void 0,
1296
1415
  A: [
1297
1416
  "identity",
1298
1417
  "'Identity not found'"
@@ -1313,16 +1432,16 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1313
1432
  const onAgentCreate = async () => {
1314
1433
  invitations.forEach((invitation2) => invitation2.cancel());
1315
1434
  const invitation = client.halo.share({
1316
- type: Invitation4.Type.MULTIUSE,
1317
- authMethod: Invitation4.AuthMethod.NONE
1435
+ type: Invitation3.Type.MULTIUSE,
1436
+ authMethod: Invitation3.AuthMethod.NONE
1318
1437
  });
1319
1438
  invitation.subscribe(handleAgentCreate);
1320
1439
  };
1321
1440
  const onAgentDestroy = async () => {
1322
1441
  const identity2 = client.halo.identity.get();
1323
1442
  invariant(identity2, "Identity not found", {
1324
- F: __dxlog_file3,
1325
- L: 76,
1443
+ F: __dxlog_file4,
1444
+ L: 77,
1326
1445
  S: void 0,
1327
1446
  A: [
1328
1447
  "identity",
@@ -1348,24 +1467,68 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1348
1467
  };
1349
1468
 
1350
1469
  // packages/sdk/shell/src/steps/InvitationManager.tsx
1351
- import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1352
- import React26, { useMemo as useMemo2 } from "react";
1470
+ import { Check as Check4, X as X3 } from "@phosphor-icons/react";
1471
+ import React28, { useMemo as useMemo2 } from "react";
1353
1472
  import { QR } from "react-qr-rounded";
1354
1473
  import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1355
- import { useId as useId4, useTranslation as useTranslation12 } from "@dxos/react-ui";
1356
- import { descriptionText as descriptionText7, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1474
+ import { useId as useId4, useTranslation as useTranslation14 } from "@dxos/react-ui";
1475
+ import { descriptionText as descriptionText7, getSize as getSize10, mx as mx19 } from "@dxos/react-ui-theme";
1476
+ import { hexToEmoji as hexToEmoji3 } from "@dxos/util";
1477
+
1478
+ // packages/sdk/shell/src/util/invitationStatusValue.ts
1479
+ import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1480
+ var invitationStatusValue = /* @__PURE__ */ new Map([
1481
+ [
1482
+ Invitation4.State.ERROR,
1483
+ -3
1484
+ ],
1485
+ [
1486
+ Invitation4.State.TIMEOUT,
1487
+ -2
1488
+ ],
1489
+ [
1490
+ Invitation4.State.CANCELLED,
1491
+ -1
1492
+ ],
1493
+ [
1494
+ Invitation4.State.INIT,
1495
+ 0
1496
+ ],
1497
+ [
1498
+ Invitation4.State.CONNECTING,
1499
+ 1
1500
+ ],
1501
+ [
1502
+ Invitation4.State.CONNECTED,
1503
+ 2
1504
+ ],
1505
+ [
1506
+ Invitation4.State.READY_FOR_AUTHENTICATION,
1507
+ 3
1508
+ ],
1509
+ [
1510
+ Invitation4.State.AUTHENTICATING,
1511
+ 4
1512
+ ],
1513
+ [
1514
+ Invitation4.State.SUCCESS,
1515
+ 5
1516
+ ]
1517
+ ]);
1518
+
1519
+ // packages/sdk/shell/src/steps/InvitationManager.tsx
1357
1520
  var InvitationManagerView = ({ children, ...props }) => {
1358
- return /* @__PURE__ */ React26.createElement(Viewport.View, {
1521
+ return /* @__PURE__ */ React28.createElement(Viewport.View, {
1359
1522
  ...props,
1360
1523
  classNames: "grow flex flex-col justify-around items-center"
1361
1524
  }, children);
1362
1525
  };
1363
- var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1364
- const { t } = useTranslation12("os");
1526
+ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id = "0" }) => {
1527
+ const { t } = useTranslation14("os");
1365
1528
  const qrLabel = useId4("invitation-manager__qr-code");
1366
1529
  const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1367
1530
  const showAuthCode = statusValue === 3;
1368
- const emoji2 = toEmoji(id ?? "");
1531
+ const emoji = hexToEmoji3(id);
1369
1532
  const activeView = useMemo2(() => {
1370
1533
  switch (true) {
1371
1534
  case statusValue === 5:
@@ -1379,18 +1542,18 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1379
1542
  }, [
1380
1543
  statusValue
1381
1544
  ]);
1382
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1545
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(Viewport.Root, {
1383
1546
  activeView,
1384
1547
  classNames: "grow plb-1"
1385
- }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1548
+ }, /* @__PURE__ */ React28.createElement(Viewport.Views, null, /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1386
1549
  id: "showing qr",
1387
- emoji: emoji2
1388
- }, /* @__PURE__ */ React26.createElement("p", {
1550
+ emoji
1551
+ }, /* @__PURE__ */ React28.createElement("p", {
1389
1552
  className: "text-sm mlb-1 font-normal text-center"
1390
- }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React26.createElement("div", {
1553
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React28.createElement("div", {
1391
1554
  role: "none",
1392
1555
  className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1393
- }, /* @__PURE__ */ React26.createElement(QR, {
1556
+ }, /* @__PURE__ */ React28.createElement(QR, {
1394
1557
  rounding: 100,
1395
1558
  backgroundColor: "transparent",
1396
1559
  color: "currentColor",
@@ -1398,31 +1561,31 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1398
1561
  "aria-labelledby": qrLabel,
1399
1562
  errorCorrectionLevel: "Q",
1400
1563
  cutout: true
1401
- }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1402
- text: emoji2
1403
- }))), /* @__PURE__ */ React26.createElement("span", {
1564
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React28.createElement(Centered, null, /* @__PURE__ */ React28.createElement(Emoji, {
1565
+ text: emoji
1566
+ }))), /* @__PURE__ */ React28.createElement("span", {
1404
1567
  id: qrLabel,
1405
1568
  className: "sr-only"
1406
- }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1569
+ }, t("qr label")), /* @__PURE__ */ React28.createElement(CopyButton, {
1407
1570
  variant: "ghost",
1408
1571
  value: invitationUrl ?? "never"
1409
- })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1572
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1410
1573
  id: "showing auth code"
1411
- }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1574
+ }, /* @__PURE__ */ React28.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React28.createElement(AuthCode, {
1412
1575
  code: authCode,
1413
1576
  large: true,
1414
1577
  classNames: "text-black dark:text-white"
1415
- }), /* @__PURE__ */ React26.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React26.createElement(Emoji, {
1416
- text: emoji2
1417
- })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1578
+ }), /* @__PURE__ */ React28.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji && /* @__PURE__ */ React28.createElement(Emoji, {
1579
+ text: emoji
1580
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1418
1581
  id: "showing final"
1419
- }, statusValue > 0 ? /* @__PURE__ */ React26.createElement(Check3, {
1420
- className: mx19("m-1.5", getSize8(6))
1421
- }) : /* @__PURE__ */ React26.createElement(X3, {
1422
- className: mx19("m-1.5", getSize8(6))
1423
- })))), /* @__PURE__ */ React26.createElement(Actions, {
1582
+ }, statusValue > 0 ? /* @__PURE__ */ React28.createElement(Check4, {
1583
+ className: mx19("m-1.5", getSize10(6))
1584
+ }) : /* @__PURE__ */ React28.createElement(X3, {
1585
+ className: mx19("m-1.5", getSize10(6))
1586
+ })))), /* @__PURE__ */ React28.createElement(Actions, {
1424
1587
  classNames: "mbs-4"
1425
- }, /* @__PURE__ */ React26.createElement(Action, {
1588
+ }, /* @__PURE__ */ React28.createElement(Action, {
1426
1589
  disabled: !active,
1427
1590
  onClick: () => send?.({
1428
1591
  type: "deselectInvitation"
@@ -1431,32 +1594,33 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1431
1594
  };
1432
1595
 
1433
1596
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
1434
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1597
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1435
1598
  var viewStyles = "pbs-1 pbe-3 pli-3";
1436
1599
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1437
- const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1438
- return /* @__PURE__ */ React27.createElement(Heading, {
1600
+ const fallbackValue = keyToFallback2(identity.identityKey);
1601
+ return /* @__PURE__ */ React29.createElement(Heading, {
1439
1602
  titleId,
1440
1603
  title,
1441
- corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1604
+ corner: /* @__PURE__ */ React29.createElement(CloseButton, {
1442
1605
  onDone
1443
1606
  })
1444
- }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1607
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Root, {
1445
1608
  size: 12,
1446
1609
  variant: "circle",
1447
- status: "active"
1448
- }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1610
+ status: "active",
1611
+ hue: identity.profile?.data?.hue || fallbackValue.hue
1612
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Frame, {
1449
1613
  classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1450
- }, /* @__PURE__ */ React27.createElement(Avatar4.Fallback, {
1451
- href: fallbackHref
1452
- })), /* @__PURE__ */ React27.createElement(Avatar4.Label, {
1614
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Fallback, {
1615
+ text: identity.profile?.data?.emoji || fallbackValue.emoji
1616
+ })), /* @__PURE__ */ React29.createElement(Avatar4.Label, {
1453
1617
  classNames: "block text-center font-light text-xl",
1454
1618
  "data-testid": "identityHeading.displayName"
1455
1619
  }, identity.profile?.displayName ?? generateName3(identity.identityKey.toHex()))));
1456
1620
  };
1457
1621
  var IdentityPanelImpl = (props) => {
1458
1622
  const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1459
- const { t } = useTranslation13("os");
1623
+ const { t } = useTranslation15("os");
1460
1624
  const title = useMemo3(() => {
1461
1625
  switch (activeView) {
1462
1626
  case "agent manager":
@@ -1470,54 +1634,54 @@ var IdentityPanelImpl = (props) => {
1470
1634
  activeView,
1471
1635
  t
1472
1636
  ]);
1473
- return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1637
+ return /* @__PURE__ */ React29.createElement(DensityProvider2, {
1474
1638
  density: "fine"
1475
- }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1639
+ }, /* @__PURE__ */ React29.createElement(IdentityHeading, {
1476
1640
  identity,
1477
1641
  titleId,
1478
1642
  title,
1479
1643
  onDone
1480
- }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1644
+ }), /* @__PURE__ */ React29.createElement(Viewport.Root, {
1481
1645
  activeView
1482
- }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1646
+ }, /* @__PURE__ */ React29.createElement(Viewport.Views, null, /* @__PURE__ */ React29.createElement(Viewport.View, {
1483
1647
  id: "identity action chooser",
1484
1648
  classNames: viewStyles
1485
- }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1649
+ }, /* @__PURE__ */ React29.createElement(IdentityActionChooserComponent, {
1486
1650
  active: activeView === "identity action chooser",
1487
1651
  ...rest
1488
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1652
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1489
1653
  id: "device invitation manager",
1490
1654
  classNames: viewStyles
1491
- }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1655
+ }, /* @__PURE__ */ React29.createElement(InvitationManagerComponent, {
1492
1656
  active: activeView === "device invitation manager",
1493
1657
  ...rest,
1494
1658
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1495
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1659
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1496
1660
  id: "device manager",
1497
1661
  classNames: viewStyles
1498
- }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1662
+ }, /* @__PURE__ */ React29.createElement(DeviceManager, {
1499
1663
  active: activeView === "device manager",
1500
1664
  ...rest
1501
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1665
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1502
1666
  classNames: viewStyles,
1503
1667
  id: "update profile form"
1504
- }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1668
+ }, /* @__PURE__ */ React29.createElement(ProfileForm, {
1505
1669
  send: rest.send,
1506
1670
  active: activeView === "update profile form",
1507
1671
  identity,
1508
1672
  onUpdateProfile
1509
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1673
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1510
1674
  classNames: viewStyles,
1511
1675
  id: "signing out"
1512
- }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1676
+ }, /* @__PURE__ */ React29.createElement(SignOutChooser, {
1513
1677
  send: rest.send,
1514
1678
  active: activeView === "signing out",
1515
1679
  onResetDevice,
1516
1680
  onJoinNewIdentity
1517
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1681
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1518
1682
  classNames: viewStyles,
1519
1683
  id: "agent manager"
1520
- }, /* @__PURE__ */ React27.createElement(AgentForm, {
1684
+ }, /* @__PURE__ */ React29.createElement(AgentForm, {
1521
1685
  send: rest.send,
1522
1686
  active: activeView === "agent manager",
1523
1687
  ...rest
@@ -1525,7 +1689,7 @@ var IdentityPanelImpl = (props) => {
1525
1689
  };
1526
1690
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1527
1691
  const invitationStatus = useInvitationStatus2(invitation);
1528
- return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1692
+ return /* @__PURE__ */ React29.createElement(IdentityPanelImpl, {
1529
1693
  ...props,
1530
1694
  ...invitationStatus
1531
1695
  });
@@ -1542,15 +1706,20 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1542
1706
  invitations
1543
1707
  });
1544
1708
  if (!identity) {
1545
- console.error("IdentityPanel rendered with no active identity.");
1709
+ log5.error("IdentityPanel rendered with no active identity.", void 0, {
1710
+ F: __dxlog_file5,
1711
+ L: 132,
1712
+ S: void 0,
1713
+ C: (f, a) => f(...a)
1714
+ });
1546
1715
  return null;
1547
1716
  }
1548
1717
  const [identityState, identitySend, identityService] = useIdentityMachine(client);
1549
1718
  useEffect3(() => {
1550
1719
  const subscription = identityService.subscribe((state) => {
1551
- log3("[state]", state, {
1552
- F: __dxlog_file4,
1553
- L: 138,
1720
+ log5("[state]", state, {
1721
+ F: __dxlog_file5,
1722
+ L: 139,
1554
1723
  S: void 0,
1555
1724
  C: (f, a) => f(...a)
1556
1725
  });
@@ -1610,40 +1779,40 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1610
1779
  onUpdateProfile,
1611
1780
  ...agentProps
1612
1781
  };
1613
- return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1782
+ return identityState.context.invitation ? /* @__PURE__ */ React29.createElement(IdentityPanelWithInvitationImpl, {
1614
1783
  ...implProps,
1615
1784
  invitation: identityState.context.invitation
1616
- }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1785
+ }) : /* @__PURE__ */ React29.createElement(IdentityPanelImpl, implProps);
1617
1786
  };
1618
1787
 
1619
1788
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1620
- import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1621
- import { log as log8 } from "@dxos/log";
1789
+ import React39, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1790
+ import { log as log10 } from "@dxos/log";
1622
1791
  import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1623
1792
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
1624
- import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext3 } from "@dxos/react-ui";
1793
+ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext4 } from "@dxos/react-ui";
1625
1794
 
1626
1795
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1627
1796
  import { X as X4 } from "@phosphor-icons/react";
1628
- import React28, { cloneElement, forwardRef as forwardRef8 } from "react";
1629
- import { Button as Button5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1630
- import { descriptionText as descriptionText8, getSize as getSize9, mx as mx20 } from "@dxos/react-ui-theme";
1797
+ import React30, { cloneElement, forwardRef as forwardRef8 } from "react";
1798
+ import { Button as Button7, useTranslation as useTranslation16 } from "@dxos/react-ui";
1799
+ import { descriptionText as descriptionText8, getSize as getSize11, mx as mx20 } from "@dxos/react-ui-theme";
1631
1800
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1632
- const { t } = useTranslation14("os");
1633
- const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1801
+ const { t } = useTranslation16("os");
1802
+ const exitButton = /* @__PURE__ */ React30.createElement(Button7, {
1634
1803
  variant: "ghost",
1635
1804
  ...onExit && {
1636
1805
  onClick: onExit
1637
1806
  },
1638
1807
  classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1639
1808
  "data-testid": "join-exit"
1640
- }, /* @__PURE__ */ React28.createElement(X4, {
1809
+ }, /* @__PURE__ */ React30.createElement(X4, {
1641
1810
  weight: "bold",
1642
- className: getSize9(4)
1643
- }), /* @__PURE__ */ React28.createElement("span", {
1811
+ className: getSize11(4)
1812
+ }), /* @__PURE__ */ React30.createElement("span", {
1644
1813
  className: "sr-only"
1645
1814
  }, t("exit label")));
1646
- return /* @__PURE__ */ React28.createElement(Heading, {
1815
+ return /* @__PURE__ */ React30.createElement(Heading, {
1647
1816
  ref: forwardedRef,
1648
1817
  titleId,
1649
1818
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -1660,13 +1829,13 @@ var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActi
1660
1829
  import { useMachine as useMachine2 } from "@xstate/react";
1661
1830
  import { useCallback as useCallback6 } from "react";
1662
1831
  import { assign as assign2, createMachine as createMachine2 } from "xstate";
1663
- import { log as log4 } from "@dxos/log";
1832
+ import { log as log6 } from "@dxos/log";
1664
1833
  import { AlreadyJoinedError } from "@dxos/react-client";
1665
1834
  import { Invitation as Invitation6, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
1666
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1835
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1667
1836
  var getInvitationSubscribable = (Kind, invitation) => {
1668
- log4("[subscribing to invitation]", invitation, {
1669
- F: __dxlog_file5,
1837
+ log6("[subscribing to invitation]", invitation, {
1838
+ F: __dxlog_file6,
1670
1839
  L: 88,
1671
1840
  S: void 0,
1672
1841
  C: (f, a) => f(...a)
@@ -1675,11 +1844,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1675
1844
  subscribe: (next, onError, complete) => invitation.subscribe((invitation2) => {
1676
1845
  switch (invitation2.state) {
1677
1846
  case Invitation6.State.CONNECTING: {
1678
- log4("[invitation connecting]", {
1847
+ log6("[invitation connecting]", {
1679
1848
  Kind,
1680
1849
  invitation: invitation2
1681
1850
  }, {
1682
- F: __dxlog_file5,
1851
+ F: __dxlog_file6,
1683
1852
  L: 99,
1684
1853
  S: void 0,
1685
1854
  C: (f, a) => f(...a)
@@ -1690,11 +1859,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1690
1859
  });
1691
1860
  }
1692
1861
  case Invitation6.State.CONNECTED: {
1693
- log4("[invitation connected]", {
1862
+ log6("[invitation connected]", {
1694
1863
  Kind,
1695
1864
  invitation: invitation2
1696
1865
  }, {
1697
- F: __dxlog_file5,
1866
+ F: __dxlog_file6,
1698
1867
  L: 104,
1699
1868
  S: void 0,
1700
1869
  C: (f, a) => f(...a)
@@ -1705,11 +1874,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1705
1874
  });
1706
1875
  }
1707
1876
  case Invitation6.State.READY_FOR_AUTHENTICATION: {
1708
- log4("[invitation ready for authentication]", {
1877
+ log6("[invitation ready for authentication]", {
1709
1878
  Kind,
1710
1879
  invitation: invitation2
1711
1880
  }, {
1712
- F: __dxlog_file5,
1881
+ F: __dxlog_file6,
1713
1882
  L: 109,
1714
1883
  S: void 0,
1715
1884
  C: (f, a) => f(...a)
@@ -1720,11 +1889,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1720
1889
  });
1721
1890
  }
1722
1891
  case Invitation6.State.AUTHENTICATING: {
1723
- log4("[invitation authenticating]", {
1892
+ log6("[invitation authenticating]", {
1724
1893
  Kind,
1725
1894
  invitation: invitation2
1726
1895
  }, {
1727
- F: __dxlog_file5,
1896
+ F: __dxlog_file6,
1728
1897
  L: 114,
1729
1898
  S: void 0,
1730
1899
  C: (f, a) => f(...a)
@@ -1735,11 +1904,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1735
1904
  });
1736
1905
  }
1737
1906
  case Invitation6.State.SUCCESS: {
1738
- log4("[invitation success]", {
1907
+ log6("[invitation success]", {
1739
1908
  Kind,
1740
1909
  invitation: invitation2
1741
1910
  }, {
1742
- F: __dxlog_file5,
1911
+ F: __dxlog_file6,
1743
1912
  L: 119,
1744
1913
  S: void 0,
1745
1914
  C: (f, a) => f(...a)
@@ -1751,10 +1920,10 @@ var getInvitationSubscribable = (Kind, invitation) => {
1751
1920
  return complete?.();
1752
1921
  }
1753
1922
  case Invitation6.State.CANCELLED: {
1754
- log4.warn("[invitation cancelled]", {
1923
+ log6.warn("[invitation cancelled]", {
1755
1924
  Kind
1756
1925
  }, {
1757
- F: __dxlog_file5,
1926
+ F: __dxlog_file6,
1758
1927
  L: 125,
1759
1928
  S: void 0,
1760
1929
  C: (f, a) => f(...a)
@@ -1765,10 +1934,10 @@ var getInvitationSubscribable = (Kind, invitation) => {
1765
1934
  });
1766
1935
  }
1767
1936
  case Invitation6.State.TIMEOUT: {
1768
- log4.error("[invitation timeout]", {
1937
+ log6.error("[invitation timeout]", {
1769
1938
  Kind
1770
1939
  }, {
1771
- F: __dxlog_file5,
1940
+ F: __dxlog_file6,
1772
1941
  L: 130,
1773
1942
  S: void 0,
1774
1943
  C: (f, a) => f(...a)
@@ -1781,11 +1950,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1781
1950
  }
1782
1951
  }, (error) => {
1783
1952
  if (error instanceof AlreadyJoinedError) {
1784
- log4("[already joined]", {
1953
+ log6("[already joined]", {
1785
1954
  Kind,
1786
1955
  error
1787
1956
  }, {
1788
- F: __dxlog_file5,
1957
+ F: __dxlog_file6,
1789
1958
  L: 137,
1790
1959
  S: void 0,
1791
1960
  C: (f, a) => f(...a)
@@ -1796,11 +1965,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1796
1965
  });
1797
1966
  return complete?.();
1798
1967
  }
1799
- log4.error("[invitation errored]", {
1968
+ log6.error("[invitation errored]", {
1800
1969
  Kind,
1801
1970
  error
1802
1971
  }, {
1803
- F: __dxlog_file5,
1972
+ F: __dxlog_file6,
1804
1973
  L: 142,
1805
1974
  S: void 0,
1806
1975
  C: (f, a) => f(...a)
@@ -2120,12 +2289,12 @@ var joinMachine = createMachine2({
2120
2289
  } : context.space
2121
2290
  }),
2122
2291
  log: (context, event) => {
2123
- log4("[transition]", {
2292
+ log6("[transition]", {
2124
2293
  event,
2125
2294
  haloInvitation: context.halo.invitation,
2126
2295
  spaceInvitation: context.space.invitation
2127
2296
  }, {
2128
- F: __dxlog_file5,
2297
+ F: __dxlog_file6,
2129
2298
  L: 406,
2130
2299
  S: void 0,
2131
2300
  C: (f, a) => f(...a)
@@ -2138,8 +2307,8 @@ var defaultCodeFromUrl = (invitationType, text) => {
2138
2307
  const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
2139
2308
  return searchParams.get(`${invitationType}InvitationCode`) ?? searchParams.get(`${invitationType}Invitation`) ?? searchParams.get("invitationCode") ?? searchParams.get("invitation") ?? text;
2140
2309
  } catch (err) {
2141
- log4.catch(err, void 0, {
2142
- F: __dxlog_file5,
2310
+ log6.catch(err, void 0, {
2311
+ F: __dxlog_file6,
2143
2312
  L: 433,
2144
2313
  S: void 0,
2145
2314
  C: (f, a) => f(...a)
@@ -2159,8 +2328,8 @@ var useJoinMachine = (client, options) => {
2159
2328
  invitationSubscribable: getInvitationSubscribable("Halo", invitationObservable)
2160
2329
  };
2161
2330
  } catch (err) {
2162
- log4.error("Could not redeem device invitation code", err, {
2163
- F: __dxlog_file5,
2331
+ log6.error("Could not redeem device invitation code", err, {
2332
+ F: __dxlog_file6,
2164
2333
  L: 454,
2165
2334
  S: void 0,
2166
2335
  C: (f, a) => f(...a)
@@ -2184,8 +2353,8 @@ var useJoinMachine = (client, options) => {
2184
2353
  invitationSubscribable: getInvitationSubscribable("Space", invitationObservable)
2185
2354
  };
2186
2355
  } catch (err) {
2187
- log4.error("Could not redeem space invitation code", err, {
2188
- F: __dxlog_file5,
2356
+ log6.error("Could not redeem space invitation code", err, {
2357
+ F: __dxlog_file6,
2189
2358
  L: 476,
2190
2359
  S: void 0,
2191
2360
  C: (f, a) => f(...a)
@@ -2246,17 +2415,17 @@ var useJoinMachine = (client, options) => {
2246
2415
 
2247
2416
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
2248
2417
  import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
2249
- import React29 from "react";
2250
- import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2251
- import { getSize as getSize10 } from "@dxos/react-ui-theme";
2418
+ import React31 from "react";
2419
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2420
+ import { getSize as getSize12 } from "@dxos/react-ui-theme";
2252
2421
  var AdditionMethodChooser = (viewStateProps) => {
2253
2422
  const disabled = !viewStateProps.active;
2254
2423
  const { send } = viewStateProps;
2255
- const { t } = useTranslation15("os");
2424
+ const { t } = useTranslation17("os");
2256
2425
  const sharedButtonProps = {
2257
2426
  disabled,
2258
- after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2259
- className: getSize10(4),
2427
+ after: /* @__PURE__ */ React31.createElement(CaretRight2, {
2428
+ className: getSize12(4),
2260
2429
  weight: "bold"
2261
2430
  }),
2262
2431
  slots: {
@@ -2265,37 +2434,37 @@ var AdditionMethodChooser = (viewStateProps) => {
2265
2434
  }
2266
2435
  }
2267
2436
  };
2268
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
2437
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React31.createElement("div", {
2269
2438
  role: "none",
2270
2439
  className: "flex flex-col gap-1 grow"
2271
- }, /* @__PURE__ */ React29.createElement(CompoundButton, {
2440
+ }, /* @__PURE__ */ React31.createElement(CompoundButton, {
2272
2441
  ...sharedButtonProps,
2273
2442
  description: t("create identity description"),
2274
- before: /* @__PURE__ */ React29.createElement(Plus2, {
2275
- className: getSize10(6)
2443
+ before: /* @__PURE__ */ React31.createElement(Plus2, {
2444
+ className: getSize12(6)
2276
2445
  }),
2277
2446
  onClick: () => send({
2278
2447
  type: "createIdentity"
2279
2448
  }),
2280
2449
  "data-autofocus": "choosingAuthMethod",
2281
2450
  "data-testid": "identity-chooser.create-identity"
2282
- }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2451
+ }, t("create identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2283
2452
  ...sharedButtonProps,
2284
2453
  description: t("join identity description"),
2285
- before: /* @__PURE__ */ React29.createElement(QrCode, {
2286
- className: getSize10(6)
2454
+ before: /* @__PURE__ */ React31.createElement(QrCode, {
2455
+ className: getSize12(6)
2287
2456
  }),
2288
2457
  onClick: () => send({
2289
2458
  type: "acceptHaloInvitation"
2290
2459
  }),
2291
2460
  "data-testid": "identity-chooser.join-identity"
2292
- }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2461
+ }, t("join identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2293
2462
  ...sharedButtonProps,
2294
2463
  // TODO(mykola): Implement recover.
2295
2464
  disabled: true,
2296
2465
  description: t("recover identity description"),
2297
- before: /* @__PURE__ */ React29.createElement(Textbox, {
2298
- className: getSize10(6)
2466
+ before: /* @__PURE__ */ React31.createElement(Textbox, {
2467
+ className: getSize12(6)
2299
2468
  }),
2300
2469
  onClick: () => send({
2301
2470
  type: "recoverIdentity"
@@ -2305,37 +2474,39 @@ var AdditionMethodChooser = (viewStateProps) => {
2305
2474
  };
2306
2475
 
2307
2476
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
2308
- import React30, { cloneElement as cloneElement2 } from "react";
2477
+ import React32, { cloneElement as cloneElement2 } from "react";
2309
2478
  import { generateName as generateName4 } from "@dxos/display-name";
2310
- import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation16 } from "@dxos/react-ui";
2479
+ import { Avatar as Avatar5, useId as useId6, useTranslation as useTranslation18 } from "@dxos/react-ui";
2311
2480
  import { mx as mx21 } from "@dxos/react-ui-theme";
2481
+ import { hexToFallback } from "@dxos/util";
2312
2482
  var IdentityAdded = (props) => {
2313
2483
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2314
2484
  const disabled = !active;
2315
- const { t } = useTranslation16("os");
2316
- const fallbackValue = addedIdentity?.identityKey.toHex();
2485
+ const { t } = useTranslation18("os");
2486
+ const addedIdentityHex = addedIdentity?.identityKey.toHex() ?? "0";
2487
+ const fallbackValue = hexToFallback(addedIdentityHex);
2317
2488
  const labelId = useId6("identityListItem__label");
2318
- const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2319
- const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName4(addedIdentity?.identityKey.toHex()));
2320
- const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2489
+ const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName4(addedIdentityHex));
2490
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2321
2491
  ...onDone && {
2322
2492
  onClick: () => onDone(null)
2323
2493
  },
2324
2494
  disabled,
2325
2495
  "data-autofocus": "confirmingAddedIdentity",
2326
2496
  "data-testid": "identity-added-done"
2327
- }, /* @__PURE__ */ React30.createElement("span", null, t("done label")));
2328
- return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React30.createElement("div", {
2497
+ }, /* @__PURE__ */ React32.createElement("span", null, t("done label")));
2498
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React32.createElement("div", {
2329
2499
  role: "none",
2330
2500
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2331
- }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2501
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Root, {
2332
2502
  status: "active",
2333
- labelId
2334
- }, /* @__PURE__ */ React30.createElement(Avatar5.Frame, null, /* @__PURE__ */ React30.createElement(Avatar5.Fallback, {
2335
- href: jdenticon
2336
- })), /* @__PURE__ */ React30.createElement(Avatar5.Label, {
2503
+ labelId,
2504
+ hue: addedIdentity?.profile?.data?.hue || fallbackValue.hue
2505
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Frame, null, /* @__PURE__ */ React32.createElement(Avatar5.Fallback, {
2506
+ text: addedIdentity?.profile?.data?.emoji || fallbackValue.emoji
2507
+ })), /* @__PURE__ */ React32.createElement(Avatar5.Label, {
2337
2508
  classNames: mx21("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2338
- }, displayName))), /* @__PURE__ */ React30.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React30.createElement(Action, {
2509
+ }, displayName))), /* @__PURE__ */ React32.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React32.createElement(Action, {
2339
2510
  variant: "primary",
2340
2511
  disabled: disabled || !addedIdentity,
2341
2512
  onClick: () => addedIdentity && send({
@@ -2347,17 +2518,17 @@ var IdentityAdded = (props) => {
2347
2518
  };
2348
2519
 
2349
2520
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2350
- import React31, { useState as useState5 } from "react";
2351
- import { log as log5 } from "@dxos/log";
2521
+ import React33, { useState as useState6 } from "react";
2522
+ import { log as log7 } from "@dxos/log";
2352
2523
  import { useClient as useClient4 } from "@dxos/react-client";
2353
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2354
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2524
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2525
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2355
2526
  var IdentityInput = (props) => {
2356
2527
  const { send, method } = props;
2357
2528
  const isRecover = method === "recover identity";
2358
2529
  const client = useClient4();
2359
- const { t } = useTranslation17("os");
2360
- const [validationMessage, setValidationMessage] = useState5("");
2530
+ const { t } = useTranslation19("os");
2531
+ const [validationMessage, setValidationMessage] = useState6("");
2361
2532
  const createIdentity = (displayName) => {
2362
2533
  void client.halo.createIdentity({
2363
2534
  [isRecover ? "seedphrase" : "displayName"]: displayName
@@ -2367,8 +2538,8 @@ var IdentityInput = (props) => {
2367
2538
  identity
2368
2539
  });
2369
2540
  }, (error) => {
2370
- log5.catch(error, void 0, {
2371
- F: __dxlog_file6,
2541
+ log7.catch(error, void 0, {
2542
+ F: __dxlog_file7,
2372
2543
  L: 37,
2373
2544
  S: void 0,
2374
2545
  C: (f, a) => f(...a)
@@ -2376,7 +2547,7 @@ var IdentityInput = (props) => {
2376
2547
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2377
2548
  });
2378
2549
  };
2379
- return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2550
+ return /* @__PURE__ */ React33.createElement(IdentityInputImpl, {
2380
2551
  ...props,
2381
2552
  onDisplayNameConfirm: createIdentity,
2382
2553
  validationMessage
@@ -2385,27 +2556,27 @@ var IdentityInput = (props) => {
2385
2556
  var IdentityInputImpl = (props) => {
2386
2557
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2387
2558
  const disabled = !active;
2388
- const { t } = useTranslation17("os");
2389
- const [inputValue, setInputValue] = useState5("");
2559
+ const { t } = useTranslation19("os");
2560
+ const [inputValue, setInputValue] = useState6("");
2390
2561
  const isRecover = method === "recover identity";
2391
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2562
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2392
2563
  role: "none",
2393
2564
  className: "grow flex flex-col justify-center"
2394
- }, /* @__PURE__ */ React31.createElement(Input, {
2565
+ }, /* @__PURE__ */ React33.createElement(Input, {
2395
2566
  validationMessage,
2396
- label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2567
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2397
2568
  disabled,
2398
2569
  "data-testid": "identity-input",
2399
2570
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2400
2571
  onChange: ({ target: { value } }) => setInputValue(value)
2401
- })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2572
+ })), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2402
2573
  variant: "ghost",
2403
2574
  disabled,
2404
2575
  onClick: () => send?.({
2405
2576
  type: "deselectAuthMethod"
2406
2577
  }),
2407
2578
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2408
- }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2579
+ }, t("back label")), /* @__PURE__ */ React33.createElement(Action, {
2409
2580
  variant: "primary",
2410
2581
  disabled,
2411
2582
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2414,40 +2585,40 @@ var IdentityInputImpl = (props) => {
2414
2585
  };
2415
2586
 
2416
2587
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2417
- import React32, { cloneElement as cloneElement3 } from "react";
2418
- import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2588
+ import React34, { cloneElement as cloneElement3 } from "react";
2589
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2419
2590
  var InvitationAccepted = (props) => {
2420
2591
  const { active, Kind, doneActionParent, onDone } = props;
2421
2592
  const disabled = !active;
2422
- const { t } = useTranslation18("os");
2423
- const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2593
+ const { t } = useTranslation20("os");
2594
+ const doneAction = /* @__PURE__ */ React34.createElement(Action, {
2424
2595
  variant: "primary",
2425
2596
  onClick: onDone,
2426
2597
  disabled,
2427
2598
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2428
2599
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2429
2600
  }, t("done label"));
2430
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2601
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2431
2602
  role: "none",
2432
2603
  className: "grow flex flex-col justify-center"
2433
- }, /* @__PURE__ */ React32.createElement("p", {
2604
+ }, /* @__PURE__ */ React34.createElement("p", {
2434
2605
  className: "text-center text-sm font-normal"
2435
- }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2606
+ }, t("welcome message"))), /* @__PURE__ */ React34.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2436
2607
  };
2437
2608
 
2438
2609
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2439
- import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2440
- import { log as log6 } from "@dxos/log";
2441
- import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2442
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2610
+ import React35, { useState as useState7, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2611
+ import { log as log8 } from "@dxos/log";
2612
+ import { useTranslation as useTranslation21 } from "@dxos/react-ui";
2613
+ var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2443
2614
  var invitationCodeFromUrl = (text) => {
2444
2615
  try {
2445
2616
  const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
2446
2617
  const invitation = searchParams.get("spaceInvitationCode") ?? searchParams.get("deviceInvitationCode");
2447
2618
  return invitation ?? text;
2448
2619
  } catch (err) {
2449
- log6.catch(err, void 0, {
2450
- F: __dxlog_file7,
2620
+ log8.catch(err, void 0, {
2621
+ F: __dxlog_file8,
2451
2622
  L: 25,
2452
2623
  S: void 0,
2453
2624
  C: (f, a) => f(...a)
@@ -2458,8 +2629,8 @@ var invitationCodeFromUrl = (text) => {
2458
2629
  var InvitationInput = (props) => {
2459
2630
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2460
2631
  const disabled = !active;
2461
- const { t } = useTranslation19("os");
2462
- const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2632
+ const { t } = useTranslation21("os");
2633
+ const [inputValue, setInputValue] = useState7(unredeemedCode ?? "");
2463
2634
  useEffect4(() => {
2464
2635
  unredeemedCode && setInputValue(unredeemedCode ?? "");
2465
2636
  }, [
@@ -2477,7 +2648,7 @@ var InvitationInput = (props) => {
2477
2648
  }
2478
2649
  });
2479
2650
  };
2480
- const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2651
+ const exitAction = /* @__PURE__ */ React35.createElement(Action, {
2481
2652
  variant: "ghost",
2482
2653
  disabled,
2483
2654
  ...onExit ? {
@@ -2487,11 +2658,11 @@ var InvitationInput = (props) => {
2487
2658
  },
2488
2659
  "data-testid": "join-exit"
2489
2660
  }, t("cancel label"));
2490
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2661
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2491
2662
  role: "none",
2492
2663
  className: "grow flex flex-col justify-center"
2493
- }, /* @__PURE__ */ React33.createElement(Input, {
2494
- label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2664
+ }, /* @__PURE__ */ React35.createElement(Input, {
2665
+ label: /* @__PURE__ */ React35.createElement(StepHeading, null, t("invitation input label")),
2495
2666
  // TODO(burdon): Translation.
2496
2667
  placeholder: "Type an invitation code",
2497
2668
  disabled,
@@ -2500,14 +2671,14 @@ var InvitationInput = (props) => {
2500
2671
  "data-autofocus": `inputting${Kind}InvitationCode`,
2501
2672
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2502
2673
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2503
- })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2674
+ })), /* @__PURE__ */ React35.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React35.createElement(Action, {
2504
2675
  variant: "ghost",
2505
2676
  disabled,
2506
2677
  onClick: () => send({
2507
2678
  type: "deselectAuthMethod"
2508
2679
  }),
2509
2680
  "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2510
- }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React33.createElement(Action, {
2681
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React35.createElement(Action, {
2511
2682
  variant: "primary",
2512
2683
  disabled,
2513
2684
  onClick: handleNext,
@@ -2516,8 +2687,8 @@ var InvitationInput = (props) => {
2516
2687
  };
2517
2688
 
2518
2689
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2519
- import React34 from "react";
2520
- import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2690
+ import React36 from "react";
2691
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2521
2692
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2522
2693
  var InvitationActions = ({
2523
2694
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2529,14 +2700,14 @@ var InvitationActions = ({
2529
2700
  Kind,
2530
2701
  failReason
2531
2702
  }) => {
2532
- const { t } = useTranslation20("os");
2703
+ const { t } = useTranslation22("os");
2533
2704
  if (failReason) {
2534
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2705
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2535
2706
  className: descriptionText9
2536
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2707
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React36.createElement("div", {
2537
2708
  role: "none",
2538
2709
  className: "grow"
2539
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2710
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2540
2711
  disabled: !active,
2541
2712
  onClick: () => send({
2542
2713
  type: `reset${Kind}Invitation`
@@ -2544,16 +2715,16 @@ var InvitationActions = ({
2544
2715
  "data-testid": "invitation-rescuer-reset"
2545
2716
  }, t("reset label"))));
2546
2717
  } else {
2547
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2718
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2548
2719
  className: descriptionText9
2549
- }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2720
+ }, t("connecting status label")), /* @__PURE__ */ React36.createElement("div", {
2550
2721
  role: "none",
2551
2722
  className: "grow"
2552
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2723
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2553
2724
  disabled: true,
2554
2725
  classNames: "order-2",
2555
2726
  "data-testid": "next"
2556
- }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2727
+ }, t("next label")), /* @__PURE__ */ React36.createElement(Action, {
2557
2728
  disabled: !active,
2558
2729
  onClick: onInvitationCancel,
2559
2730
  "data-testid": "invitation-rescuer-cancel"
@@ -2562,46 +2733,47 @@ var InvitationActions = ({
2562
2733
  };
2563
2734
  var InvitationRescuer = (props) => {
2564
2735
  const { Kind, invitationState, active, send } = props;
2565
- const { t } = useTranslation20("os");
2566
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2736
+ const { t } = useTranslation22("os");
2737
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2567
2738
  role: "none",
2568
2739
  className: "grow flex flex-col justify-center"
2569
- }, /* @__PURE__ */ React34.createElement(StepHeading, {
2740
+ }, /* @__PURE__ */ React36.createElement(StepHeading, {
2570
2741
  className: descriptionText9
2571
- }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2742
+ }, "There was a problem joining the space")), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2572
2743
  disabled: !active,
2573
2744
  "data-testid": "invitation-rescuer-blank-reset",
2574
2745
  onClick: () => send({
2575
2746
  type: `reset${Kind}Invitation`
2576
2747
  })
2577
- }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2748
+ }, t("reset label")))) : /* @__PURE__ */ React36.createElement(InvitationActions, props));
2578
2749
  };
2579
2750
 
2580
2751
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2581
- import React35, { useState as useState7 } from "react";
2582
- import { Input as Input2, useTranslation as useTranslation21 } from "@dxos/react-ui";
2752
+ import React37, { useState as useState8 } from "react";
2753
+ import { Input as Input2, useTranslation as useTranslation23 } from "@dxos/react-ui";
2754
+ import { hexToEmoji as hexToEmoji4 } from "@dxos/util";
2583
2755
  var pinLength = 6;
2584
2756
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2585
2757
  const disabled = !active || pending;
2586
- const { t } = useTranslation21("os");
2758
+ const { t } = useTranslation23("os");
2587
2759
  const invitationType = Kind.toLowerCase();
2588
- const [authCode, setAuthCode] = useState7("");
2760
+ const [authCode, setAuthCode] = useState8("");
2589
2761
  const onChange = ({ target: { value } }) => {
2590
2762
  setAuthCode(value);
2591
2763
  if (value.length === pinLength) {
2592
2764
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2593
2765
  }
2594
2766
  };
2595
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2767
+ return /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement("div", {
2596
2768
  role: "none",
2597
2769
  className: "grow flex flex-col justify-center"
2598
- }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2599
- text: toEmoji(invitationId)
2600
- }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2770
+ }, invitationId && /* @__PURE__ */ React37.createElement(Emoji, {
2771
+ text: hexToEmoji4(invitationId)
2772
+ }), /* @__PURE__ */ React37.createElement(Input2.Root, failed && {
2601
2773
  validationValence: "error"
2602
- }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2774
+ }, /* @__PURE__ */ React37.createElement(Input2.Label, {
2603
2775
  asChild: true
2604
- }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2776
+ }, /* @__PURE__ */ React37.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React37.createElement(Input2.PinInput, {
2605
2777
  disabled,
2606
2778
  length: pinLength,
2607
2779
  onChange,
@@ -2612,14 +2784,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2612
2784
  "data-prevent-ios-autofocus": true,
2613
2785
  "data-testid": `${invitationType}-auth-code-input`,
2614
2786
  "data-1p-ignore": true
2615
- }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2787
+ }), failed && /* @__PURE__ */ React37.createElement(Input2.DescriptionAndValidation, {
2616
2788
  classNames: "text-center"
2617
- }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2789
+ }, /* @__PURE__ */ React37.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React37.createElement(Actions, null, /* @__PURE__ */ React37.createElement(Action, {
2618
2790
  variant: "ghost",
2619
2791
  disabled,
2620
2792
  onClick: () => onInvitationCancel?.(),
2621
2793
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2622
- }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2794
+ }, t("cancel label")), /* @__PURE__ */ React37.createElement(Action, {
2623
2795
  variant: "primary",
2624
2796
  disabled,
2625
2797
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2629,23 +2801,23 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2629
2801
  };
2630
2802
 
2631
2803
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2632
- import React36, { useState as useState8 } from "react";
2633
- import { log as log7 } from "@dxos/log";
2804
+ import React38, { useState as useState9 } from "react";
2805
+ import { log as log9 } from "@dxos/log";
2634
2806
  import { useClient as useClient5 } from "@dxos/react-client";
2635
- import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2636
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2807
+ import { useTranslation as useTranslation24 } from "@dxos/react-ui";
2808
+ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2637
2809
  var ResetIdentity = ({ send, active }) => {
2638
2810
  const client = useClient5();
2639
- const { t } = useTranslation22("os");
2640
- const [validationMessage, setValidationMessage] = useState8("");
2641
- const [pending, setPending] = useState8(false);
2811
+ const { t } = useTranslation24("os");
2812
+ const [validationMessage, setValidationMessage] = useState9("");
2813
+ const [pending, setPending] = useState9(false);
2642
2814
  const resetIdentity = () => {
2643
2815
  setPending(true);
2644
2816
  void client.reset().then(() => send?.({
2645
2817
  type: "resetIdentity"
2646
2818
  }), (error) => {
2647
- log7.catch(error, void 0, {
2648
- F: __dxlog_file8,
2819
+ log9.catch(error, void 0, {
2820
+ F: __dxlog_file9,
2649
2821
  L: 35,
2650
2822
  S: void 0,
2651
2823
  C: (f, a) => f(...a)
@@ -2654,7 +2826,7 @@ var ResetIdentity = ({ send, active }) => {
2654
2826
  setPending(false);
2655
2827
  });
2656
2828
  };
2657
- return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2829
+ return /* @__PURE__ */ React38.createElement(ResetIdentityImpl, {
2658
2830
  disabled: !active,
2659
2831
  pending,
2660
2832
  validationMessage,
@@ -2662,22 +2834,22 @@ var ResetIdentity = ({ send, active }) => {
2662
2834
  });
2663
2835
  };
2664
2836
  var ResetIdentityImpl = ({ disabled, pending, validationMessage, onConfirm }) => {
2665
- const { t } = useTranslation22("os");
2837
+ const { t } = useTranslation24("os");
2666
2838
  const confirmationValue = t("confirmation value");
2667
- const [inputValue, setInputValue] = useState8("");
2668
- return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2839
+ const [inputValue, setInputValue] = useState9("");
2840
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("div", {
2669
2841
  role: "none",
2670
2842
  className: "grow flex flex-col justify-center"
2671
- }, /* @__PURE__ */ React36.createElement(Input, {
2843
+ }, /* @__PURE__ */ React38.createElement(Input, {
2672
2844
  validationMessage,
2673
- label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2845
+ label: /* @__PURE__ */ React38.createElement(StepHeading, null, t("reset identity input label", {
2674
2846
  confirmationValue
2675
2847
  })),
2676
2848
  disabled,
2677
2849
  "data-testid": "reset-identity-input",
2678
2850
  placeholder: confirmationValue,
2679
2851
  onChange: ({ target: { value } }) => setInputValue(value)
2680
- })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2852
+ })), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(Action, {
2681
2853
  // TODO(wittjosiah): Probably make this red?
2682
2854
  variant: "primary",
2683
2855
  disabled: disabled || pending || inputValue !== confirmationValue,
@@ -2711,50 +2883,50 @@ var resolvedBgColor = (status) => status === Invitation7.State.ERROR ? errorBgCo
2711
2883
  var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTextColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledTextColor : successTextColor;
2712
2884
 
2713
2885
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
2714
- var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2886
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2715
2887
  var JoinPanelImpl = (props) => {
2716
2888
  const { titleId, send, activeView, failed, mode, unredeemedCodes, invitationStates, succeededKeys, failReasons, onExit, onHaloDone, onSpaceDone, exitActionParent, doneActionParent, onHaloInvitationCancel, onSpaceInvitationCancel, onHaloInvitationAuthenticate, onSpaceInvitationAuthenticate, IdentityInput: IdentityInputComponent = IdentityInput, ResetIdentity: ResetIdentityComponent = ResetIdentity } = props;
2717
- return /* @__PURE__ */ React37.createElement(DensityProvider3, {
2889
+ return /* @__PURE__ */ React39.createElement(DensityProvider3, {
2718
2890
  density: "fine"
2719
- }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2891
+ }, mode !== "halo-only" && /* @__PURE__ */ React39.createElement(JoinHeading, {
2720
2892
  titleId,
2721
2893
  mode,
2722
2894
  onExit,
2723
2895
  exitActionParent
2724
- }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2896
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
2725
2897
  focusManaged: true,
2726
2898
  activeView
2727
- }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2899
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
2728
2900
  classNames: stepStyles,
2729
2901
  id: "addition method chooser"
2730
- }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2902
+ }, /* @__PURE__ */ React39.createElement(AdditionMethodChooser, {
2731
2903
  send,
2732
2904
  active: activeView === "addition method chooser"
2733
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2905
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2734
2906
  classNames: stepStyles,
2735
2907
  id: "reset identity confirmation"
2736
- }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2908
+ }, /* @__PURE__ */ React39.createElement(ResetIdentityComponent, {
2737
2909
  send,
2738
2910
  method: "reset identity",
2739
2911
  active: activeView === "reset identity confirmation"
2740
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2912
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2741
2913
  classNames: stepStyles,
2742
2914
  id: "create identity input"
2743
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2915
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2744
2916
  send,
2745
2917
  method: "create identity",
2746
2918
  active: activeView === "create identity input"
2747
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2919
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2748
2920
  classNames: stepStyles,
2749
2921
  id: "recover identity input"
2750
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2922
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2751
2923
  send,
2752
2924
  method: "recover identity",
2753
2925
  active: activeView === "recover identity input"
2754
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2926
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2755
2927
  classNames: stepStyles,
2756
2928
  id: "halo invitation input"
2757
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2929
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2758
2930
  send,
2759
2931
  Kind: "Halo",
2760
2932
  active: activeView === "halo invitation input",
@@ -2764,20 +2936,20 @@ var JoinPanelImpl = (props) => {
2764
2936
  ...succeededKeys?.Halo && {
2765
2937
  succeededKeys: succeededKeys.Halo
2766
2938
  }
2767
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2939
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2768
2940
  classNames: stepStyles,
2769
2941
  id: "halo invitation rescuer"
2770
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2942
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2771
2943
  send,
2772
2944
  Kind: "Halo",
2773
2945
  active: activeView === "halo invitation rescuer",
2774
2946
  invitationState: invitationStates?.Halo,
2775
2947
  onInvitationCancel: onHaloInvitationCancel,
2776
2948
  failReason: failReasons?.Halo
2777
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2949
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2778
2950
  classNames: stepStyles,
2779
2951
  id: "halo invitation authenticator"
2780
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2952
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2781
2953
  send,
2782
2954
  Kind: "Halo",
2783
2955
  active: activeView === "halo invitation authenticator",
@@ -2786,28 +2958,28 @@ var JoinPanelImpl = (props) => {
2786
2958
  ...failed.has("Halo") && {
2787
2959
  failed: true
2788
2960
  }
2789
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2961
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2790
2962
  classNames: stepStyles,
2791
2963
  id: "halo invitation accepted"
2792
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2964
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2793
2965
  send,
2794
2966
  Kind: "Halo",
2795
2967
  active: activeView === "halo invitation accepted",
2796
2968
  doneActionParent,
2797
2969
  onDone: onHaloDone
2798
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2970
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2799
2971
  classNames: stepStyles,
2800
2972
  id: "identity added"
2801
- }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2973
+ }, /* @__PURE__ */ React39.createElement(IdentityAdded, {
2802
2974
  send,
2803
2975
  mode,
2804
2976
  active: activeView === "identity added",
2805
2977
  doneActionParent,
2806
2978
  onDone: onHaloDone
2807
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2979
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2808
2980
  classNames: stepStyles,
2809
2981
  id: "space invitation input"
2810
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2982
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2811
2983
  send,
2812
2984
  Kind: "Space",
2813
2985
  active: activeView === "space invitation input",
@@ -2819,20 +2991,20 @@ var JoinPanelImpl = (props) => {
2819
2991
  },
2820
2992
  onExit,
2821
2993
  exitActionParent
2822
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2994
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2823
2995
  classNames: stepStyles,
2824
2996
  id: "space invitation rescuer"
2825
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2997
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2826
2998
  send,
2827
2999
  Kind: "Space",
2828
3000
  active: activeView === "space invitation rescuer",
2829
3001
  invitationState: invitationStates?.Space,
2830
3002
  onInvitationCancel: onSpaceInvitationCancel,
2831
3003
  failReason: failReasons?.Space
2832
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
3004
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2833
3005
  classNames: stepStyles,
2834
3006
  id: "space invitation authenticator"
2835
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
3007
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2836
3008
  send,
2837
3009
  Kind: "Space",
2838
3010
  active: activeView === "space invitation authenticator",
@@ -2841,10 +3013,10 @@ var JoinPanelImpl = (props) => {
2841
3013
  ...failed.has("Space") && {
2842
3014
  failed: true
2843
3015
  }
2844
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
3016
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2845
3017
  classNames: stepStyles,
2846
3018
  id: "space invitation accepted"
2847
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
3019
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2848
3020
  send,
2849
3021
  Kind: "Space",
2850
3022
  active: activeView === "space invitation accepted",
@@ -2855,7 +3027,7 @@ var JoinPanelImpl = (props) => {
2855
3027
  var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCode, exitActionParent, onExit, doneActionParent, onDone: propsOnDone }) => {
2856
3028
  const client = useClient6();
2857
3029
  const identity = useIdentity2();
2858
- const { hasIosKeyboard } = useThemeContext3();
3030
+ const { hasIosKeyboard } = useThemeContext4();
2859
3031
  const titleId = useId7("joinPanel__heading", propsTitleId);
2860
3032
  const [joinState, joinSend, joinService] = useJoinMachine(client, {
2861
3033
  context: {
@@ -2870,8 +3042,8 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2870
3042
  });
2871
3043
  useEffect5(() => {
2872
3044
  const subscription = joinService.subscribe((state) => {
2873
- log8("[state]", state, {
2874
- F: __dxlog_file9,
3045
+ log10("[state]", state, {
3046
+ F: __dxlog_file10,
2875
3047
  L: 198,
2876
3048
  S: void 0,
2877
3049
  C: (f, a) => f(...a)
@@ -3084,7 +3256,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3084
3256
  joinState,
3085
3257
  propsOnDone
3086
3258
  ]);
3087
- return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
3259
+ return /* @__PURE__ */ React39.createElement(JoinPanelImpl, {
3088
3260
  titleId,
3089
3261
  mode,
3090
3262
  send: joinSend,
@@ -3123,16 +3295,16 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3123
3295
 
3124
3296
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3125
3297
  import { Planet } from "@phosphor-icons/react";
3126
- import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3127
- import { log as log10 } from "@dxos/log";
3298
+ import React41, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3299
+ import { log as log13 } from "@dxos/log";
3128
3300
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
3129
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
3301
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation26 } from "@dxos/react-ui";
3130
3302
 
3131
3303
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
3132
3304
  import { useMachine as useMachine3 } from "@xstate/react";
3133
3305
  import { assign as assign3, createMachine as createMachine3 } from "xstate";
3134
- import { log as log9 } from "@dxos/log";
3135
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
3306
+ import { log as log11 } from "@dxos/log";
3307
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
3136
3308
  var spaceMachine = createMachine3({
3137
3309
  id: "space",
3138
3310
  predictableActionArguments: true,
@@ -3169,11 +3341,11 @@ var spaceMachine = createMachine3({
3169
3341
  invitation: () => void 0
3170
3342
  }),
3171
3343
  log: (context, event) => {
3172
- log9("[transition]", {
3344
+ log11("[transition]", {
3173
3345
  event,
3174
3346
  context
3175
3347
  }, {
3176
- F: __dxlog_file10,
3348
+ F: __dxlog_file11,
3177
3349
  L: 53,
3178
3350
  S: void 0,
3179
3351
  C: (f, a) => f(...a)
@@ -3192,25 +3364,32 @@ var useSpaceMachine = (options) => {
3192
3364
 
3193
3365
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
3194
3366
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
3195
- import React38, { useCallback as useCallback8, useState as useState9 } from "react";
3367
+ import React40, { useCallback as useCallback8, useState as useState10 } from "react";
3368
+ import { log as log12 } from "@dxos/log";
3196
3369
  import { useConfig } from "@dxos/react-client";
3197
3370
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
3198
3371
  import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3199
- import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3372
+ import { ScrollArea, useTranslation as useTranslation25 } from "@dxos/react-ui";
3200
3373
  import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
3374
+ var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx";
3201
3375
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
3202
3376
  var SpaceManager = (props) => {
3203
3377
  const { space, target } = props;
3204
- const { t } = useTranslation23("os");
3378
+ const { t } = useTranslation25("os");
3205
3379
  const config = useConfig();
3206
3380
  const invitations = useSpaceInvitations2(space?.key);
3207
3381
  const onInvitationEvent = useCallback8((invitation) => {
3208
3382
  const invitationCode = InvitationEncoder4.encode(invitation);
3209
3383
  if (invitation.state === Invitation8.State.CONNECTING) {
3210
- console.log(JSON.stringify({
3384
+ log12.info(JSON.stringify({
3211
3385
  invitationCode,
3212
3386
  authCode: invitation.authCode
3213
- }));
3387
+ }), void 0, {
3388
+ F: __dxlog_file12,
3389
+ L: 49,
3390
+ S: void 0,
3391
+ C: (f, a) => f(...a)
3392
+ });
3214
3393
  }
3215
3394
  }, []);
3216
3395
  const inviteActions = {
@@ -3249,7 +3428,7 @@ var SpaceManager = (props) => {
3249
3428
  ])
3250
3429
  }
3251
3430
  };
3252
- return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
3431
+ return /* @__PURE__ */ React40.createElement(SpaceManagerImpl, {
3253
3432
  ...props,
3254
3433
  invitations,
3255
3434
  inviteActions
@@ -3258,7 +3437,7 @@ var SpaceManager = (props) => {
3258
3437
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
3259
3438
  var SpaceManagerImpl = (props) => {
3260
3439
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
3261
- const { t } = useTranslation23("os");
3440
+ const { t } = useTranslation25("os");
3262
3441
  const inviteActions = propsInviteActions ?? {
3263
3442
  noopInvite: {
3264
3443
  label: t("create space invitation label"),
@@ -3268,7 +3447,7 @@ var SpaceManagerImpl = (props) => {
3268
3447
  }
3269
3448
  }
3270
3449
  };
3271
- const [activeAction, setInternalActiveAction] = useState9(localStorage.getItem(activeActionKey) ?? "inviteOne");
3450
+ const [activeAction, setInternalActiveAction] = useState10(localStorage.getItem(activeActionKey) ?? "inviteOne");
3272
3451
  const setActiveAction = (nextAction) => {
3273
3452
  setInternalActiveAction(nextAction);
3274
3453
  localStorage.setItem(activeActionKey, nextAction);
@@ -3276,26 +3455,26 @@ var SpaceManagerImpl = (props) => {
3276
3455
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3277
3456
  Invitation8.State.CANCELLED
3278
3457
  ].includes(invitation.get().state));
3279
- return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
3458
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(ScrollArea.Root, {
3280
3459
  classNames: "grow shrink basis-28 -mli-2"
3281
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
3460
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Viewport, {
3282
3461
  classNames: "is-full pie-2"
3283
- }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3462
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement("h3", {
3284
3463
  className: mx22(headingFragment, descriptionText10)
3285
- }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
3464
+ }, t("invitation list heading")), /* @__PURE__ */ React40.createElement(InvitationListComponent, {
3286
3465
  className: "mb-2",
3287
3466
  send,
3288
3467
  invitations: visibleInvitations ?? [],
3289
3468
  onClickRemove: (invitation) => invitation.cancel(),
3290
3469
  createInvitationUrl
3291
- }), /* @__PURE__ */ React38.createElement("h3", {
3470
+ }), /* @__PURE__ */ React40.createElement("h3", {
3292
3471
  className: mx22(headingFragment, descriptionText10, "mbs-2")
3293
- }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
3472
+ }, t("space member list heading"))), /* @__PURE__ */ React40.createElement(SpaceMemberListComponent, {
3294
3473
  spaceKey: space.key,
3295
3474
  includeSelf: true
3296
- })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
3475
+ })), /* @__PURE__ */ React40.createElement(ScrollArea.Scrollbar, {
3297
3476
  orientation: "vertical"
3298
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
3477
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React40.createElement(Actions, null, /* @__PURE__ */ React40.createElement(BifurcatedAction, {
3299
3478
  disabled: !active,
3300
3479
  actions: inviteActions,
3301
3480
  activeAction,
@@ -3305,49 +3484,49 @@ var SpaceManagerImpl = (props) => {
3305
3484
  };
3306
3485
 
3307
3486
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3308
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3487
+ var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3309
3488
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
3310
- const { t } = useTranslation24("os");
3489
+ const { t } = useTranslation26("os");
3311
3490
  const name = space.properties.name;
3312
- return /* @__PURE__ */ React39.createElement(Heading, {
3491
+ return /* @__PURE__ */ React41.createElement(Heading, {
3313
3492
  titleId,
3314
3493
  title: t("space panel heading"),
3315
- corner: /* @__PURE__ */ React39.createElement(CloseButton, {
3494
+ corner: /* @__PURE__ */ React41.createElement(CloseButton, {
3316
3495
  "data-testid": "identity-panel-done",
3317
3496
  onDone
3318
3497
  })
3319
- }, /* @__PURE__ */ React39.createElement("div", {
3498
+ }, /* @__PURE__ */ React41.createElement("div", {
3320
3499
  role: "none",
3321
3500
  className: "flex gap-4 items-center justify-center mlb-4"
3322
- }, /* @__PURE__ */ React39.createElement(Planet, {
3501
+ }, /* @__PURE__ */ React41.createElement(Planet, {
3323
3502
  size: 32,
3324
3503
  weight: "light"
3325
- }), /* @__PURE__ */ React39.createElement("div", {
3504
+ }), /* @__PURE__ */ React41.createElement("div", {
3326
3505
  className: "block text-start font-light text-xl"
3327
3506
  }, name ?? space.key.truncate())));
3328
3507
  };
3329
3508
  var SpacePanelImpl = (props) => {
3330
3509
  const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3331
- return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3510
+ return /* @__PURE__ */ React41.createElement(DensityProvider4, {
3332
3511
  density: "fine"
3333
- }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3512
+ }, /* @__PURE__ */ React41.createElement(SpacePanelHeading, {
3334
3513
  ...rest,
3335
3514
  titleId,
3336
3515
  space
3337
- }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3516
+ }), /* @__PURE__ */ React41.createElement(Viewport.Root, {
3338
3517
  activeView
3339
- }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3518
+ }, /* @__PURE__ */ React41.createElement(Viewport.Views, null, /* @__PURE__ */ React41.createElement(Viewport.View, {
3340
3519
  id: "space manager",
3341
3520
  classNames: stepStyles
3342
- }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3521
+ }, /* @__PURE__ */ React41.createElement(SpaceManagerComponent, {
3343
3522
  active: activeView === "space manager",
3344
3523
  space,
3345
3524
  target,
3346
3525
  ...rest
3347
- })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3526
+ })), /* @__PURE__ */ React41.createElement(Viewport.View, {
3348
3527
  id: "space invitation manager",
3349
3528
  classNames: stepStyles
3350
- }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3529
+ }, /* @__PURE__ */ React41.createElement(InvitationManagerComponent, {
3351
3530
  active: activeView === "space invitation manager",
3352
3531
  ...rest,
3353
3532
  invitationUrl: props.invitationUrl
@@ -3355,7 +3534,7 @@ var SpacePanelImpl = (props) => {
3355
3534
  };
3356
3535
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3357
3536
  const invitationStatus = useInvitationStatus3(invitation);
3358
- return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3537
+ return /* @__PURE__ */ React41.createElement(SpacePanelImpl, {
3359
3538
  ...props,
3360
3539
  ...invitationStatus,
3361
3540
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3370,8 +3549,8 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3370
3549
  });
3371
3550
  useEffect6(() => {
3372
3551
  const subscription = spaceService.subscribe((state) => {
3373
- log10("[state]", state, {
3374
- F: __dxlog_file11,
3552
+ log13("[state]", state, {
3553
+ F: __dxlog_file13,
3375
3554
  L: 94,
3376
3555
  S: void 0,
3377
3556
  C: (f, a) => f(...a)
@@ -3402,100 +3581,100 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3402
3581
  };
3403
3582
  return spaceState.context.invitation ? (
3404
3583
  // TODO(wittjosiah): Unused? Remove?
3405
- /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3584
+ /* @__PURE__ */ React41.createElement(SpacePanelWithInvitationImpl, {
3406
3585
  ...implProps,
3407
3586
  invitation: spaceState.context.invitation
3408
3587
  })
3409
- ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3588
+ ) : /* @__PURE__ */ React41.createElement(SpacePanelImpl, implProps);
3410
3589
  };
3411
3590
 
3412
3591
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3413
3592
  var IdentityDialog = (props) => {
3414
3593
  const titleId = useId9("spaceDialog__title");
3415
- return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3594
+ return /* @__PURE__ */ React42.createElement(Dialog.Root, {
3416
3595
  defaultOpen: true,
3417
3596
  onOpenChange: (open) => open || props.onDone?.()
3418
- }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3597
+ }, /* @__PURE__ */ React42.createElement(Dialog.Portal, null, /* @__PURE__ */ React42.createElement(Dialog.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog.Content, {
3419
3598
  "aria-labelledby": titleId,
3420
3599
  onOpenAutoFocus: (e) => e.preventDefault()
3421
- }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3600
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(IdentityPanel, {
3422
3601
  ...props,
3423
3602
  titleId,
3424
- doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3603
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog.Close, {
3425
3604
  asChild: true
3426
3605
  })
3427
3606
  }))))));
3428
3607
  };
3429
3608
 
3430
3609
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3431
- import React41 from "react";
3610
+ import React43 from "react";
3432
3611
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3433
3612
  var JoinDialog = (joinPanelProps) => {
3434
3613
  const titleId = useId10("joinDialog__title");
3435
3614
  const { height } = useVisualViewport();
3436
- return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3615
+ return /* @__PURE__ */ React43.createElement(AlertDialog.Root, {
3437
3616
  defaultOpen: true,
3438
3617
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3439
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3618
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React43.createElement(AlertDialog.Overlay, {
3440
3619
  classNames: "backdrop-blur",
3441
3620
  ...height && {
3442
3621
  style: {
3443
3622
  blockSize: `${height}px`
3444
3623
  }
3445
3624
  }
3446
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3625
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Content, {
3447
3626
  "aria-labelledby": titleId
3448
- }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3627
+ }, /* @__PURE__ */ React43.createElement(JoinPanel, {
3449
3628
  ...joinPanelProps,
3450
3629
  titleId,
3451
- exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3630
+ exitActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Cancel, {
3452
3631
  asChild: true
3453
3632
  }),
3454
- doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3633
+ doneActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Action, {
3455
3634
  asChild: true
3456
3635
  })
3457
3636
  })))));
3458
3637
  };
3459
3638
 
3460
3639
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3461
- import React44, { StrictMode } from "react";
3640
+ import React46, { StrictMode } from "react";
3462
3641
  import { createRoot } from "react-dom/client";
3463
3642
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3464
3643
  import { ShellRuntimeImpl } from "@dxos/client-services";
3465
3644
  import { Client, ClientContext, ClientServicesProxy, Config, SystemStatus } from "@dxos/react-client";
3466
- import { ThemeProvider, Tooltip as Tooltip3 } from "@dxos/react-ui";
3645
+ import { ThemeProvider, Tooltip as Tooltip5 } from "@dxos/react-ui";
3467
3646
  import { defaultTx } from "@dxos/react-ui-theme";
3468
3647
  import { createIFramePort } from "@dxos/rpc-tunnel";
3469
3648
 
3470
3649
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3471
- import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3472
- import { log as log11 } from "@dxos/log";
3650
+ import React45, { useEffect as useEffect7, useState as useState11 } from "react";
3651
+ import { log as log14 } from "@dxos/log";
3473
3652
  import { ShellDisplay, ShellLayout, useClient as useClient7 } from "@dxos/react-client";
3474
3653
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3475
3654
 
3476
3655
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3477
- import React42 from "react";
3656
+ import React44 from "react";
3478
3657
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3479
3658
  var SpaceDialog = (spacePanelProps) => {
3480
3659
  const titleId = useId11("spaceDialog__title");
3481
- return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3660
+ return /* @__PURE__ */ React44.createElement(Dialog2.Root, {
3482
3661
  defaultOpen: true,
3483
3662
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3484
- }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3663
+ }, /* @__PURE__ */ React44.createElement(Dialog2.Portal, null, /* @__PURE__ */ React44.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React44.createElement(Dialog2.Content, {
3485
3664
  "aria-labelledby": titleId
3486
- }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3665
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(SpacePanel, {
3487
3666
  ...spacePanelProps,
3488
3667
  titleId,
3489
- doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3668
+ doneActionParent: /* @__PURE__ */ React44.createElement(Dialog2.Close, {
3490
3669
  asChild: true
3491
3670
  })
3492
3671
  }))))));
3493
3672
  };
3494
3673
 
3495
3674
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3496
- var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3675
+ var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3497
3676
  var Shell = ({ runtime, origin }) => {
3498
- const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState10({
3677
+ const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState11({
3499
3678
  layout: runtime.layout,
3500
3679
  invitationCode: runtime.invitationCode,
3501
3680
  spaceKey: runtime.spaceKey,
@@ -3510,8 +3689,8 @@ var Shell = ({ runtime, origin }) => {
3510
3689
  ]);
3511
3690
  useEffect7(() => {
3512
3691
  if (layout === ShellLayout.SPACE && !space) {
3513
- log11.warn("No space found for shell space invitations.", void 0, {
3514
- F: __dxlog_file12,
3692
+ log14.warn("No space found for shell space invitations.", void 0, {
3693
+ F: __dxlog_file14,
3515
3694
  L: 32,
3516
3695
  S: void 0,
3517
3696
  C: (f, a) => f(...a)
@@ -3533,7 +3712,7 @@ var Shell = ({ runtime, origin }) => {
3533
3712
  ]);
3534
3713
  switch (layout) {
3535
3714
  case ShellLayout.INITIALIZE_IDENTITY:
3536
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3715
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3537
3716
  mode: "halo-only",
3538
3717
  initialInvitationCode: invitationCode,
3539
3718
  onDone: () => {
@@ -3548,7 +3727,7 @@ var Shell = ({ runtime, origin }) => {
3548
3727
  case ShellLayout.IDENTITY:
3549
3728
  case ShellLayout.SHARE_IDENTITY:
3550
3729
  case ShellLayout.EDIT_PROFILE:
3551
- return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3730
+ return /* @__PURE__ */ React45.createElement(IdentityDialog, {
3552
3731
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3553
3732
  onResetDevice: async () => {
3554
3733
  await client.reset();
@@ -3570,7 +3749,7 @@ var Shell = ({ runtime, origin }) => {
3570
3749
  }
3571
3750
  });
3572
3751
  case ShellLayout.SPACE:
3573
- return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3752
+ return space ? /* @__PURE__ */ React45.createElement(SpaceDialog, {
3574
3753
  space,
3575
3754
  target,
3576
3755
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
@@ -3584,7 +3763,7 @@ var Shell = ({ runtime, origin }) => {
3584
3763
  }
3585
3764
  }) : null;
3586
3765
  case ShellLayout.JOIN_SPACE:
3587
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3766
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3588
3767
  initialInvitationCode: invitationCode,
3589
3768
  onDone: async (result) => {
3590
3769
  const target2 = result?.target ?? void 0;
@@ -3718,7 +3897,28 @@ var os = {
3718
3897
  "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3719
3898
  "join new identity label": "Join a new identity",
3720
3899
  "reset device label": "Reset device",
3721
- "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3900
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost.",
3901
+ "emoji and color label": "Emoji and color",
3902
+ "clear label": "Use default",
3903
+ "select emoji label": "Choose an emoji to use in your avatar",
3904
+ "select hue label": "Choose a hue to use in your avatar",
3905
+ "red label": "Red",
3906
+ "orange label": "Orange",
3907
+ "amber label": "Amber",
3908
+ "yellow label": "Yellow",
3909
+ "lime label": "Lime",
3910
+ "green label": "Green",
3911
+ "emerald label": "Emerald",
3912
+ "teal label": "Teal",
3913
+ "cyan label": "Cyan",
3914
+ "sky label": "Sky",
3915
+ "blue label": "Blue",
3916
+ "indigo label": "Indigo",
3917
+ "violet label": "Violet",
3918
+ "purple label": "Purple",
3919
+ "fuchsia label": "Fuchsia",
3920
+ "pink label": "Pink",
3921
+ "rose label": "Rose"
3722
3922
  };
3723
3923
 
3724
3924
  // packages/sdk/shell/src/translations/index.ts
@@ -3742,24 +3942,24 @@ var runShell = async (config = new Config()) => {
3742
3942
  runtime.open(),
3743
3943
  client.initialize()
3744
3944
  ]);
3745
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3945
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React46.createElement(StrictMode, null, /* @__PURE__ */ React46.createElement(ThemeProvider, {
3746
3946
  tx: defaultTx,
3747
3947
  resourceExtensions: [
3748
3948
  osTranslations
3749
3949
  ]
3750
- }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3950
+ }, /* @__PURE__ */ React46.createElement(ClientContext.Provider, {
3751
3951
  value: {
3752
3952
  client,
3753
3953
  status: SystemStatus.ACTIVE
3754
3954
  }
3755
- }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3955
+ }, /* @__PURE__ */ React46.createElement(ClipboardProvider, null, /* @__PURE__ */ React46.createElement(Tooltip5.Provider, null, /* @__PURE__ */ React46.createElement(Shell, {
3756
3956
  runtime,
3757
3957
  origin: location.origin
3758
3958
  })))))));
3759
3959
  };
3760
3960
 
3761
3961
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3762
- import React45, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3962
+ import React47, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState12 } from "react";
3763
3963
  import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3764
3964
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3765
3965
  import { mx as mx23 } from "@dxos/react-ui-theme";
@@ -3821,7 +4021,7 @@ var useShell = () => {
3821
4021
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3822
4022
  const client = useClient8();
3823
4023
  const identity = useIdentity3();
3824
- const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
4024
+ const [display, setDisplay] = useState12(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3825
4025
  const shellRuntime = useMemo6(() => {
3826
4026
  if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3827
4027
  return;
@@ -3891,12 +4091,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3891
4091
  }, [
3892
4092
  shellRuntime
3893
4093
  ]);
3894
- return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
4094
+ return /* @__PURE__ */ React47.createElement(React47.Fragment, null, shellRuntime && /* @__PURE__ */ React47.createElement("div", {
3895
4095
  className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3896
- }, /* @__PURE__ */ React45.createElement(Shell, {
4096
+ }, /* @__PURE__ */ React47.createElement(Shell, {
3897
4097
  runtime: shellRuntime,
3898
4098
  origin: window.location.origin
3899
- })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
4099
+ })), /* @__PURE__ */ React47.createElement(ShellContext.Provider, {
3900
4100
  value: {
3901
4101
  runtime: shellRuntime,
3902
4102
  setDisplay
@@ -3917,7 +4117,9 @@ export {
3917
4117
  CopyButtonIconOnly,
3918
4118
  DeviceList,
3919
4119
  Emoji,
4120
+ EmojiPicker,
3920
4121
  Heading,
4122
+ HuePicker,
3921
4123
  IdentityDialog,
3922
4124
  IdentityListItem,
3923
4125
  IdentityPanel,