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