@dxos/shell 0.4.7-main.7b31910 → 0.4.7-main.83fe62c

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