@dxos/shell 0.4.10-main.fa5a270 → 0.4.10-main.fe71b4c

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 (220) hide show
  1. package/dist/bundle/index-BjPIerZ_.mjs +110 -0
  2. package/dist/bundle/index-BjPIerZ_.mjs.map +1 -0
  3. package/dist/bundle/index-BnojJ-lm.mjs +96615 -0
  4. package/dist/bundle/index-BnojJ-lm.mjs.map +1 -0
  5. package/dist/bundle/shell.mjs +9 -80814
  6. package/dist/bundle/shell.mjs.map +1 -1
  7. package/dist/bundle/shell.umd.js +156 -85
  8. package/dist/bundle/shell.umd.js.map +1 -1
  9. package/dist/bundle/style.css +1 -1
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/browser/react.mjs +1177 -1034
  12. package/dist/lib/browser/react.mjs.map +4 -4
  13. package/dist/lib/browser/testing/index.mjs +8 -8
  14. package/dist/lib/browser/testing/index.mjs.map +3 -3
  15. package/dist/types/src/components/AgentConfig.d.ts +3 -0
  16. package/dist/types/src/components/AgentConfig.d.ts.map +1 -0
  17. package/dist/types/src/components/AgentConfig.js +37 -0
  18. package/dist/types/src/components/AgentConfig.js.map +1 -0
  19. package/dist/types/src/components/DeviceList/DeviceList.d.ts +3 -0
  20. package/dist/types/src/components/DeviceList/DeviceList.d.ts.map +1 -0
  21. package/dist/types/src/components/DeviceList/DeviceList.js +29 -0
  22. package/dist/types/src/components/DeviceList/DeviceList.js.map +1 -0
  23. package/dist/types/src/components/DeviceList/DeviceListItem.d.ts +6 -0
  24. package/dist/types/src/components/DeviceList/DeviceListItem.d.ts.map +1 -0
  25. package/dist/types/src/components/DeviceList/DeviceListItem.js +72 -0
  26. package/dist/types/src/components/DeviceList/DeviceListItem.js.map +1 -0
  27. package/dist/types/src/components/DeviceList/DeviceListProps.d.ts +27 -0
  28. package/dist/types/src/components/DeviceList/DeviceListProps.d.ts.map +1 -0
  29. package/dist/types/src/components/DeviceList/DeviceListProps.js +6 -0
  30. package/dist/types/src/components/DeviceList/DeviceListProps.js.map +1 -0
  31. package/dist/types/src/components/DeviceList/index.d.ts +3 -0
  32. package/dist/types/src/components/DeviceList/index.d.ts.map +1 -0
  33. package/dist/types/src/components/DeviceList/index.js +22 -0
  34. package/dist/types/src/components/DeviceList/index.js.map +1 -0
  35. package/dist/types/src/components/EmojiPicker.d.ts +9 -2
  36. package/dist/types/src/components/EmojiPicker.d.ts.map +1 -1
  37. package/dist/types/src/components/EmojiPicker.js +59 -4
  38. package/dist/types/src/components/EmojiPicker.js.map +1 -1
  39. package/dist/types/src/components/HuePicker.d.ts +9 -2
  40. package/dist/types/src/components/HuePicker.d.ts.map +1 -1
  41. package/dist/types/src/components/HuePicker.js +75 -6
  42. package/dist/types/src/components/HuePicker.js.map +1 -1
  43. package/dist/types/src/components/IdentityList/index.d.ts +0 -1
  44. package/dist/types/src/components/IdentityList/index.d.ts.map +1 -1
  45. package/dist/types/src/components/IdentityList/index.js +0 -1
  46. package/dist/types/src/components/IdentityList/index.js.map +1 -1
  47. package/dist/types/src/components/InvitationList/InvitationListItem.js +5 -5
  48. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  49. package/dist/types/src/components/Panel/Action.d.ts +2 -2
  50. package/dist/types/src/components/Viewport/Viewport.d.ts +1 -1
  51. package/dist/types/src/components/index.d.ts +2 -0
  52. package/dist/types/src/components/index.d.ts.map +1 -1
  53. package/dist/types/src/components/index.js +2 -0
  54. package/dist/types/src/components/index.js.map +1 -1
  55. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js +1 -1
  56. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js.map +1 -1
  57. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  58. package/dist/types/src/composites/Shell/Shell.js +14 -6
  59. package/dist/types/src/composites/Shell/Shell.js.map +1 -1
  60. package/dist/types/src/composites/StatusDialog/StatusDialog.d.ts +2 -0
  61. package/dist/types/src/composites/StatusDialog/StatusDialog.d.ts.map +1 -0
  62. package/dist/types/src/composites/StatusDialog/StatusDialog.js +22 -0
  63. package/dist/types/src/composites/StatusDialog/StatusDialog.js.map +1 -0
  64. package/dist/types/src/composites/StatusDialog/index.d.ts +2 -0
  65. package/dist/types/src/composites/StatusDialog/index.d.ts.map +1 -0
  66. package/dist/types/src/composites/StatusDialog/index.js +21 -0
  67. package/dist/types/src/composites/StatusDialog/index.js.map +1 -0
  68. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts +1 -1
  69. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  70. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +89 -42
  71. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  72. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +0 -3
  73. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
  74. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +1 -43
  75. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -1
  76. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +11 -12
  77. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
  78. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +3 -1
  79. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
  80. package/dist/types/src/panels/IdentityPanel/identityMachine.js +13 -24
  81. package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
  82. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts +4 -4
  83. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
  84. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +9 -39
  85. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
  86. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +1 -1
  87. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  88. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +6 -3
  89. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  90. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +0 -3
  91. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
  92. package/dist/types/src/panels/IdentityPanel/steps/index.js +0 -3
  93. package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
  94. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -1
  95. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +5 -1
  96. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -1
  97. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +1 -1
  98. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -1
  99. package/dist/types/src/panels/JoinPanel/JoinPanel.js +12 -5
  100. package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
  101. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts +1 -1
  102. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts.map +1 -1
  103. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js +2 -1
  104. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js.map +1 -1
  105. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +8 -3
  106. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -1
  107. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts +3 -2
  108. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts.map +1 -1
  109. package/dist/types/src/panels/JoinPanel/joinMachine.js +7 -0
  110. package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
  111. package/dist/types/src/panels/JoinPanel/steps/index.d.ts +0 -1
  112. package/dist/types/src/panels/JoinPanel/steps/index.d.ts.map +1 -1
  113. package/dist/types/src/panels/JoinPanel/steps/index.js +0 -1
  114. package/dist/types/src/panels/JoinPanel/steps/index.js.map +1 -1
  115. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
  116. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +3 -1
  117. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
  118. package/dist/types/src/panels/StatusPanel/StatusPanel.d.ts +4 -0
  119. package/dist/types/src/panels/StatusPanel/StatusPanel.d.ts.map +1 -0
  120. package/dist/types/src/panels/StatusPanel/StatusPanel.js +19 -0
  121. package/dist/types/src/panels/StatusPanel/StatusPanel.js.map +1 -0
  122. package/dist/types/src/panels/StatusPanel/index.d.ts +2 -0
  123. package/dist/types/src/panels/StatusPanel/index.d.ts.map +1 -0
  124. package/dist/types/src/panels/StatusPanel/index.js +21 -0
  125. package/dist/types/src/panels/StatusPanel/index.js.map +1 -0
  126. package/dist/types/src/panels/index.d.ts +1 -0
  127. package/dist/types/src/panels/index.d.ts.map +1 -1
  128. package/dist/types/src/panels/index.js +1 -0
  129. package/dist/types/src/panels/index.js.map +1 -1
  130. package/dist/types/src/steps/ConfirmReset.d.ts +16 -0
  131. package/dist/types/src/steps/ConfirmReset.d.ts.map +1 -0
  132. package/dist/types/src/steps/ConfirmReset.js +71 -0
  133. package/dist/types/src/steps/ConfirmReset.js.map +1 -0
  134. package/dist/types/src/steps/InvitationManager.d.ts +1 -1
  135. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  136. package/dist/types/src/steps/InvitationManager.js +3 -4
  137. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  138. package/dist/types/src/steps/StepProps.d.ts +4 -1
  139. package/dist/types/src/steps/StepProps.d.ts.map +1 -1
  140. package/dist/types/src/steps/index.d.ts +1 -0
  141. package/dist/types/src/steps/index.d.ts.map +1 -1
  142. package/dist/types/src/steps/index.js +1 -0
  143. package/dist/types/src/steps/index.js.map +1 -1
  144. package/dist/types/src/stories/Invitations.e2e-stories.d.ts.map +1 -1
  145. package/dist/types/src/stories/Invitations.e2e-stories.js +2 -2
  146. package/dist/types/src/stories/Invitations.e2e-stories.js.map +1 -1
  147. package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
  148. package/dist/types/src/testing/shell-manager.js +8 -8
  149. package/dist/types/src/testing/shell-manager.js.map +1 -1
  150. package/dist/types/src/translations/locales/en-US.d.ts +16 -3
  151. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  152. package/dist/types/src/translations/locales/en-US.js +20 -7
  153. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  154. package/dist/types/src/types/index.js +1 -0
  155. package/dist/types/src/types/index.js.map +1 -1
  156. package/package.json +22 -21
  157. package/src/components/AgentConfig.tsx +66 -0
  158. package/src/components/DeviceList/DeviceList.tsx +54 -0
  159. package/src/components/DeviceList/DeviceListItem.tsx +120 -0
  160. package/src/components/DeviceList/DeviceListProps.ts +33 -0
  161. package/src/components/DeviceList/index.ts +6 -0
  162. package/src/components/EmojiPicker.tsx +103 -4
  163. package/src/components/HuePicker.tsx +99 -5
  164. package/src/components/IdentityList/index.ts +0 -1
  165. package/src/components/InvitationList/InvitationListItem.tsx +5 -5
  166. package/src/components/index.ts +2 -0
  167. package/src/composites/IdentityDialog/IdentityDialog.tsx +1 -1
  168. package/src/composites/Shell/Shell.tsx +17 -4
  169. package/src/composites/StatusDialog/StatusDialog.tsx +24 -0
  170. package/src/composites/StatusDialog/index.ts +5 -0
  171. package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +0 -63
  172. package/src/panels/IdentityPanel/IdentityPanel.tsx +149 -43
  173. package/src/panels/IdentityPanel/IdentityPanelProps.ts +15 -15
  174. package/src/panels/IdentityPanel/identityMachine.ts +17 -25
  175. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +23 -67
  176. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +18 -5
  177. package/src/panels/IdentityPanel/steps/index.ts +0 -3
  178. package/src/panels/IdentityPanel/useAgentHandlers.ts +5 -1
  179. package/src/panels/JoinPanel/JoinPanel.stories.tsx +3 -2
  180. package/src/panels/JoinPanel/JoinPanel.tsx +21 -5
  181. package/src/panels/JoinPanel/JoinPanelProps.ts +9 -3
  182. package/src/panels/JoinPanel/joinMachine.ts +12 -2
  183. package/src/panels/JoinPanel/steps/index.ts +0 -1
  184. package/src/panels/SpacePanel/steps/SpaceManager.tsx +3 -1
  185. package/src/panels/StatusPanel/StatusPanel.tsx +19 -0
  186. package/src/panels/StatusPanel/index.ts +5 -0
  187. package/src/panels/index.ts +1 -0
  188. package/src/steps/ConfirmReset.tsx +112 -0
  189. package/src/steps/InvitationManager.tsx +4 -4
  190. package/src/steps/StepProps.ts +2 -1
  191. package/src/steps/index.ts +1 -0
  192. package/src/stories/Invitations.e2e-stories.tsx +3 -3
  193. package/src/testing/shell-manager.ts +8 -8
  194. package/src/translations/locales/en-US.ts +22 -7
  195. package/src/types/index.ts +2 -0
  196. package/dist/types/src/components/IdentityList/DeviceList.d.ts +0 -7
  197. package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +0 -1
  198. package/dist/types/src/components/IdentityList/DeviceList.js +0 -34
  199. package/dist/types/src/components/IdentityList/DeviceList.js.map +0 -1
  200. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +0 -3
  201. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +0 -1
  202. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js +0 -26
  203. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js.map +0 -1
  204. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts +0 -10
  205. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts.map +0 -1
  206. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js +0 -23
  207. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js.map +0 -1
  208. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +0 -16
  209. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +0 -1
  210. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js +0 -40
  211. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +0 -1
  212. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts +0 -13
  213. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts.map +0 -1
  214. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js +0 -66
  215. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js.map +0 -1
  216. package/src/components/IdentityList/DeviceList.tsx +0 -49
  217. package/src/panels/IdentityPanel/steps/AgentForm.tsx +0 -61
  218. package/src/panels/IdentityPanel/steps/DeviceManager.tsx +0 -41
  219. package/src/panels/IdentityPanel/steps/SignOutChooser.tsx +0 -84
  220. package/src/panels/JoinPanel/steps/ResetIdentity.tsx +0 -80
@@ -7,33 +7,29 @@ import type { Event, SingleOrArray } from 'xstate';
7
7
 
8
8
  import type { Device, Identity } from '@dxos/react-client/halo';
9
9
  import type { InvitationStatus } from '@dxos/react-client/invitations';
10
+ import type { ConnectionState } from '@dxos/react-client/mesh';
10
11
 
11
12
  import type { IdentityEvent } from './identityMachine';
13
+ import { type AgentFormProps } from '../../components';
12
14
  import type { InvitationManagerProps } from '../../steps';
13
15
 
14
- export type AgentFormProps = {
15
- onAgentCreate?: () => Promise<void>;
16
- onAgentDestroy?: () => Promise<void>;
17
- agentStatus?: string;
18
- agentActive?: boolean;
19
- agentProviderDisabled?: boolean;
20
- validationMessage?: string;
21
- };
16
+ export type IdentityPanelInitialDisposition = 'default' | 'manage-device-invitation';
22
17
 
23
18
  export type IdentityPanelImplProps = {
24
19
  titleId: string;
25
20
  activeView:
26
- | 'device manager'
27
- | 'agent manager'
28
- | 'update profile form'
29
21
  | 'device invitation manager'
30
22
  | 'identity action chooser'
31
- | 'signing out';
23
+ | 'confirm join new identity'
24
+ | 'confirm reset storage';
25
+ initialDisposition?: IdentityPanelInitialDisposition;
32
26
  identity: Identity;
33
27
  devices: Device[];
28
+ connectionState?: ConnectionState;
29
+ onChangeConnectionState?: (nextState: ConnectionState) => Promise<void>;
34
30
  onUpdateProfile?: (profile: NonNullable<Identity['profile']>) => Promise<void>;
35
- onResetDevice?: () => Promise<void>;
36
- onJoinNewIdentity?: () => void;
31
+ onResetStorage?: () => Promise<void>;
32
+ onJoinNewIdentity?: () => Promise<void>;
37
33
  createInvitationUrl: (invitationCode: string) => string;
38
34
  send?: (event: SingleOrArray<Event<IdentityEvent>>) => void;
39
35
  onDone?: () => void;
@@ -46,11 +42,15 @@ export type IdentityPanelImplProps = {
46
42
 
47
43
  export type IdentityPanelProps = Partial<Omit<IdentityPanelImplProps, 'send' | 'activeView' | 'identity'>>;
48
44
 
49
- export type IdentityPanelHeadingProps = Pick<IdentityPanelImplProps, 'titleId' | 'identity' | 'onDone'> & {
45
+ export type IdentityPanelHeadingProps = Pick<
46
+ IdentityPanelImplProps,
47
+ 'titleId' | 'identity' | 'onDone' | 'onUpdateProfile' | 'connectionState' | 'onChangeConnectionState'
48
+ > & {
50
49
  title: string;
51
50
  };
52
51
 
53
52
  export type IdentityPanelStepProps = Pick<IdentityPanelImplProps, 'send' | 'onDone' | 'doneActionParent'> & {
54
53
  active?: boolean;
55
54
  agentHostingEnabled?: boolean;
55
+ devices: Device[];
56
56
  };
@@ -10,16 +10,18 @@ import { type Client } from '@dxos/react-client';
10
10
  import { type Identity } from '@dxos/react-client/halo';
11
11
  import { type CancellableInvitationObservable } from '@dxos/react-client/invitations';
12
12
 
13
+ import { type IdentityPanelInitialDisposition } from './IdentityPanelProps';
13
14
  import { type StepEvent } from '../../steps';
14
15
 
15
16
  type IdentityMachineContext = {
17
+ initialDisposition?: IdentityPanelInitialDisposition;
16
18
  invitation?: CancellableInvitationObservable;
17
19
  identity: Identity | null;
18
20
  identitySubscribable: Subscribable<SetIdentityEvent> | null;
19
21
  };
20
22
 
21
23
  type IdentityChooseActionEvent = {
22
- type: 'chooseDevices' | 'chooseAgent' | 'chooseProfile' | 'chooseSignOut' | 'sigingOut' | 'unchooseAction';
24
+ type: 'chooseResetStorage' | 'chooseJoinNewIdentity' | 'unchooseAction';
23
25
  };
24
26
 
25
27
  type IdentitySelectDeviceInvitationEvent = {
@@ -56,40 +58,30 @@ const identityMachine = createMachine<IdentityMachineContext, IdentityEvent>(
56
58
  src: (context) => context.identitySubscribable!,
57
59
  },
58
60
  states: {
61
+ unknown: {
62
+ always: [
63
+ { cond: 'initiallyManagingDeviceInvitation', target: 'managingDeviceInvitation', actions: 'log' },
64
+ { target: 'choosingAction', actions: 'log' },
65
+ ],
66
+ },
59
67
  choosingAction: {},
60
68
  managingDeviceInvitation: {},
61
- managingAgent: {
62
- initial: 'idle',
63
- states: {
64
- idle: {},
65
- pending: {},
66
- },
67
- },
68
- managingDevices: {},
69
- managingProfile: {
70
- initial: 'idle',
71
- states: {
72
- idle: {},
73
- pending: {},
74
- },
75
- on: {
76
- setIdentity: { target: 'choosingAction', actions: ['setIdentity', 'log'] },
77
- updateProfile: { target: '.pending', actions: 'log' },
78
- },
79
- },
80
- signingOut: {},
69
+ confirmingResetStorage: {},
70
+ confirmingJoinNewIdentity: {},
81
71
  },
82
72
  on: {
83
73
  unchooseAction: { target: '.choosingAction', actions: ['unsetInvitation', 'log'] },
84
74
  deselectInvitation: { target: '.choosingAction', actions: ['unsetInvitation', 'log'] },
85
75
  selectInvitation: { target: '.managingDeviceInvitation', actions: ['setInvitation', 'log'] },
86
- chooseDevices: { target: '.managingDevices', actions: 'log' },
87
- chooseProfile: { target: '.managingProfile', actions: 'log' },
88
- chooseSignOut: { target: '.signingOut', actions: 'log' },
89
- chooseAgent: { target: '.managingAgent', actions: 'log' },
76
+ chooseJoinNewIdentity: { target: '.confirmingJoinNewIdentity', actions: 'log' },
77
+ chooseResetStorage: { target: '.confirmingResetStorage', actions: 'log' },
90
78
  },
91
79
  },
92
80
  {
81
+ guards: {
82
+ initiallyManagingDeviceInvitation: ({ initialDisposition }, _event) =>
83
+ initialDisposition === 'manage-device-invitation',
84
+ },
93
85
  actions: {
94
86
  setIdentity: assign<IdentityMachineContext, IdentityEvent>({
95
87
  identity: (context, event) => (event as SetIdentityEvent)?.identity ?? null,
@@ -2,17 +2,14 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from '@phosphor-icons/react';
6
5
  import React, { useCallback } from 'react';
7
6
 
8
7
  import { log } from '@dxos/log';
9
8
  import { useAgentHostingProviderClient, useClient } from '@dxos/react-client';
10
9
  import { useHaloInvitations } from '@dxos/react-client/halo';
11
10
  import { Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
12
- import { DensityProvider, useTranslation } from '@dxos/react-ui';
13
- import { getSize } from '@dxos/react-ui-theme';
14
11
 
15
- import { Action } from '../../../components';
12
+ import { AgentConfig, type AgentFormProps, DeviceList } from '../../../components';
16
13
  import { type IdentityPanelStepProps } from '../IdentityPanelProps';
17
14
 
18
15
  export type IdentityActionChooserProps = IdentityPanelStepProps;
@@ -28,13 +25,10 @@ export const IdentityActionChooser = (props: IdentityPanelStepProps) => {
28
25
  log.info(JSON.stringify({ invitationCode, authCode: invitation.authCode }));
29
26
  }
30
27
  }, []);
31
- const createInvitation = (e: React.MouseEvent) => {
32
- const testing = e.altKey && e.shiftKey;
28
+ const createInvitation = () => {
33
29
  invitations.forEach((invitation) => invitation.cancel());
34
30
  // TODO(nf): allow user to make invitations non-persistent?
35
- const invitation = client.halo.share(
36
- testing ? { type: Invitation.Type.MULTIUSE, authMethod: Invitation.AuthMethod.NONE } : undefined,
37
- );
31
+ const invitation = client.halo.share();
38
32
  // TODO(wittjosiah): Don't depend on NODE_ENV.
39
33
  if (process.env.NODE_ENV !== 'production') {
40
34
  invitation.subscribe(onInvitationEvent);
@@ -44,74 +38,36 @@ export const IdentityActionChooser = (props: IdentityPanelStepProps) => {
44
38
  return (
45
39
  <IdentityActionChooserImpl
46
40
  {...props}
47
- onCreateInvitationClick={(e) => createInvitation(e)}
41
+ onCreateInvitationClick={createInvitation}
48
42
  agentHostingEnabled={!!agentHostingProviderClient}
49
43
  />
50
44
  );
51
45
  };
52
46
 
53
- export type IdentityActionChooserImplProps = IdentityActionChooserProps & {
54
- onCreateInvitationClick?: (e: React.MouseEvent) => void;
55
- };
47
+ export type IdentityActionChooserImplProps = IdentityActionChooserProps &
48
+ Partial<AgentFormProps> & {
49
+ onCreateInvitationClick?: () => void;
50
+ };
56
51
 
57
52
  export const IdentityActionChooserImpl = ({
58
- onCreateInvitationClick,
59
- active,
60
53
  send,
61
- onDone,
62
- doneActionParent,
54
+ onCreateInvitationClick,
55
+ devices,
56
+ onAgentDestroy,
57
+ onAgentCreate,
58
+ agentStatus,
59
+ agentActive,
63
60
  agentHostingEnabled,
64
61
  }: IdentityActionChooserImplProps) => {
65
- const { t } = useTranslation('os');
66
-
67
- // const doneAction = (
68
- // <PanelAction aria-label={t('done label')} onClick={onDone} disabled={!active} data-testid='identity-panel-done'>
69
- // <Check weight='light' className={getSize(6)} />
70
- // </PanelAction>
71
- // );
72
62
  return (
73
- <div role='none' className='grow flex flex-col gap-1'>
74
- <DensityProvider density='coarse'>
75
- <div className='grow justify-center flex flex-col gap-1'>
76
- {agentHostingEnabled && (
77
- <Action data-testid='manage-agent' onClick={() => send?.({ type: 'chooseAgent' })} classNames='plb-4'>
78
- <HardDrive className={getSize(6)} />
79
- <span className='grow mli-3'>Manage Agent</span>
80
- <CaretRight weight='bold' className={getSize(4)} />
81
- </Action>
82
- )}
83
- <Action
84
- disabled={!active}
85
- data-testid='devices-panel.create-invitation'
86
- onClick={onCreateInvitationClick}
87
- classNames='plb-4'
88
- >
89
- <Plus className={getSize(6)} />
90
- <span className='grow mli-3'>{t('choose add device label')}</span>
91
- <CaretRight weight='bold' className={getSize(4)} />
92
- </Action>
93
- <Action data-testid='manage-devices' onClick={() => send?.({ type: 'chooseDevices' })} classNames='plb-4'>
94
- <Devices className={getSize(6)} />
95
- <span className='grow mli-3'>{t('choose devices label')}</span>
96
- <CaretRight weight='bold' className={getSize(4)} />
97
- </Action>
98
- <Action data-testid='manage-profile' onClick={() => send?.({ type: 'chooseProfile' })} classNames='plb-4'>
99
- <UserGear className={getSize(6)} />
100
- <span className='grow mli-3'>{t('choose profile label')}</span>
101
- <CaretRight weight='bold' className={getSize(4)} />
102
- </Action>
103
- <Action
104
- data-testid='devices-panel.sign-out'
105
- onClick={() => send?.({ type: 'chooseSignOut' })}
106
- classNames='plb-4'
107
- >
108
- <Power className={getSize(6)} />
109
- <span className='grow mli-3'>{t('choose sign out label')}</span>
110
- <CaretRight weight='bold' className={getSize(4)} />
111
- </Action>
112
- </div>
113
- </DensityProvider>
114
- {/* <PanelActions>{doneActionParent ? cloneElement(doneActionParent, {}, doneAction) : doneAction}</PanelActions> */}
115
- </div>
63
+ <>
64
+ <DeviceList
65
+ devices={devices}
66
+ onClickAdd={onCreateInvitationClick}
67
+ onClickJoinExisting={() => send?.({ type: 'chooseJoinNewIdentity' })}
68
+ onClickReset={() => send?.({ type: 'chooseResetStorage' })}
69
+ />
70
+ {agentHostingEnabled && <AgentConfig {...{ agentActive, agentStatus, onAgentDestroy, onAgentCreate }} />}
71
+ </>
116
72
  );
117
73
  };
@@ -10,11 +10,19 @@ import { type Identity } from '@dxos/react-client/halo';
10
10
  import { useTranslation } from '@dxos/react-ui';
11
11
  import { hexToEmoji, hexToHue } from '@dxos/util';
12
12
 
13
- import { Action, Actions, StepHeading, Input, useClipboardContext, EmojiPicker, HuePicker } from '../../../components';
13
+ import {
14
+ Action,
15
+ Actions,
16
+ StepHeading,
17
+ Input,
18
+ useClipboardContext,
19
+ EmojiPickerBlock,
20
+ HuePickerBlock,
21
+ } from '../../../components';
14
22
  import { type IdentityPanelStepProps } from '../IdentityPanelProps';
15
23
  import { type IdentityEvent } from '../identityMachine';
16
24
 
17
- export interface ProfileFormProps extends Omit<IdentityPanelStepProps, 'send'> {
25
+ export interface ProfileFormProps extends Omit<IdentityPanelStepProps, 'send' | 'devices'> {
18
26
  send?: (event: SingleOrArray<Event<IdentityEvent>>) => void;
19
27
  onUpdateProfile?: (profile: NonNullable<Identity['profile']>) => Promise<void>;
20
28
  identity?: Identity;
@@ -68,13 +76,13 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
68
76
  />
69
77
  <StepHeading className='mbe-2'>{t('emoji and color label')}</StepHeading>
70
78
  <div role='none' className='grid grid-cols-[1fr_min-content] gap-y-2'>
71
- <EmojiPicker
79
+ <EmojiPickerBlock
72
80
  emoji={emoji}
73
81
  onChangeEmoji={setEmoji}
74
82
  disabled={disabled}
75
83
  onClickClear={() => setEmoji(getEmojiValue(identity))}
76
84
  />
77
- <HuePicker
85
+ <HuePickerBlock
78
86
  hue={hue}
79
87
  onChangeHue={setHue}
80
88
  disabled={disabled}
@@ -106,7 +114,12 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
106
114
  <Action
107
115
  variant='primary'
108
116
  disabled={disabled}
109
- onClick={() => onUpdateProfile?.({ displayName, data: { emoji, hue } })}
117
+ onClick={() =>
118
+ onUpdateProfile?.({
119
+ ...(displayName && { displayName }),
120
+ ...((emoji || hue) && { data: { ...(emoji && { emoji }), ...(hue && { hue }) } }),
121
+ })
122
+ }
110
123
  data-testid='update-profile-form-continue'
111
124
  >
112
125
  {t('done label')}
@@ -2,8 +2,5 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './AgentForm';
6
- export * from './DeviceManager';
7
5
  export * from './IdentityActionChooser';
8
6
  export * from './ProfileForm';
9
- export * from './SignOutChooser';
@@ -67,7 +67,11 @@ export const useAgentHandlers = ({
67
67
  invitations.forEach((invitation) => invitation.cancel());
68
68
 
69
69
  // TODO(nf): do this work in the hosting provider client?
70
- const invitation = client.halo.share({ type: Invitation.Type.MULTIUSE, authMethod: Invitation.AuthMethod.NONE });
70
+ const invitation = client.halo.share({
71
+ type: Invitation.Type.INTERACTIVE,
72
+ authMethod: Invitation.AuthMethod.NONE,
73
+ multiUse: true,
74
+ });
71
75
 
72
76
  invitation.subscribe(handleAgentCreate);
73
77
  };
@@ -10,8 +10,9 @@ import { withTheme } from '@dxos/storybook-utils';
10
10
 
11
11
  import { JoinPanelImpl } from './JoinPanel';
12
12
  import { type JoinPanelImplProps } from './JoinPanelProps';
13
- import { IdentityInputImpl, ResetIdentityImpl } from './steps';
13
+ import { IdentityInputImpl } from './steps';
14
14
  import { StorybookDialog } from '../../components/StorybookDialog';
15
+ import { ConfirmResetImpl } from '../../steps';
15
16
 
16
17
  const noOpProps: JoinPanelImplProps = {
17
18
  titleId: 'storybookJoinPanel__title',
@@ -34,7 +35,7 @@ export default {
34
35
  parameters: { chromatic: { disableSnapshot: false } },
35
36
  args: {
36
37
  IdentityInput: IdentityInputImpl,
37
- ResetIdentity: ResetIdentityImpl,
38
+ ResetIdentity: ConfirmResetImpl,
38
39
  },
39
40
  };
40
41
 
@@ -19,9 +19,9 @@ import {
19
19
  InvitationRescuer,
20
20
  InvitationInput,
21
21
  InvitationAccepted,
22
- ResetIdentity,
23
22
  } from './steps';
24
23
  import { Viewport } from '../../components';
24
+ import { ConfirmReset } from '../../steps';
25
25
  import { stepStyles } from '../../styles';
26
26
 
27
27
  export const JoinPanelImpl = (props: JoinPanelImplProps) => {
@@ -44,8 +44,10 @@ export const JoinPanelImpl = (props: JoinPanelImplProps) => {
44
44
  onSpaceInvitationCancel,
45
45
  onHaloInvitationAuthenticate,
46
46
  onSpaceInvitationAuthenticate,
47
+ onCancelResetStorage,
48
+ onConfirmResetStorage,
47
49
  IdentityInput: IdentityInputComponent = IdentityInput,
48
- ResetIdentity: ResetIdentityComponent = ResetIdentity,
50
+ ConfirmReset: ConfirmResetComponent = ConfirmReset,
49
51
  } = props;
50
52
  return (
51
53
  <DensityProvider density='fine'>
@@ -55,11 +57,12 @@ export const JoinPanelImpl = (props: JoinPanelImplProps) => {
55
57
  <Viewport.View classNames={stepStyles} id='addition method chooser'>
56
58
  <AdditionMethodChooser send={send} active={activeView === 'addition method chooser'} />
57
59
  </Viewport.View>
58
- <Viewport.View classNames={stepStyles} id='reset identity confirmation'>
59
- <ResetIdentityComponent
60
+ <Viewport.View classNames={stepStyles} id='reset storage confirmation'>
61
+ <ConfirmResetComponent
60
62
  send={send}
61
- method='reset identity'
62
63
  active={activeView === 'reset identity confirmation'}
64
+ onCancel={onCancelResetStorage}
65
+ onConfirm={onConfirmResetStorage}
63
66
  />
64
67
  </Viewport.View>
65
68
  <Viewport.View classNames={stepStyles} id='create identity input'>
@@ -172,11 +175,13 @@ export const JoinPanelImpl = (props: JoinPanelImplProps) => {
172
175
  export const JoinPanel = ({
173
176
  titleId: propsTitleId,
174
177
  mode = 'default',
178
+ initialDisposition = 'default',
175
179
  initialInvitationCode,
176
180
  exitActionParent,
177
181
  onExit,
178
182
  doneActionParent,
179
183
  onDone: propsOnDone,
184
+ onCancelResetStorage,
180
185
  }: JoinPanelProps) => {
181
186
  const client = useClient();
182
187
  const identity = useIdentity();
@@ -186,6 +191,7 @@ export const JoinPanel = ({
186
191
  const [joinState, joinSend, joinService] = useJoinMachine(client, {
187
192
  context: {
188
193
  mode,
194
+ initialDisposition,
189
195
  identity,
190
196
  ...(initialInvitationCode && {
191
197
  [mode === 'halo-only' ? 'halo' : 'space']: { unredeemedCode: initialInvitationCode },
@@ -379,6 +385,14 @@ export const JoinPanel = ({
379
385
  });
380
386
  }, [joinState, propsOnDone]);
381
387
 
388
+ const onConfirmResetStorage = useCallback(
389
+ () =>
390
+ client.reset().then(() => {
391
+ joinSend({ type: 'resetIdentity' });
392
+ }),
393
+ [client, joinSend],
394
+ );
395
+
382
396
  return (
383
397
  <JoinPanelImpl
384
398
  {...{
@@ -409,6 +423,8 @@ export const JoinPanel = ({
409
423
  joinSend({ type: 'authenticateSpaceVerificationCode' });
410
424
  return joinState.context.space.invitationObservable?.authenticate(authCode);
411
425
  },
426
+ onConfirmResetStorage,
427
+ onCancelResetStorage,
412
428
  }}
413
429
  />
414
430
  );
@@ -8,12 +8,14 @@ import type { Identity } from '@dxos/react-client/halo';
8
8
  import type { Invitation, AuthenticatingInvitationObservable, InvitationResult } from '@dxos/react-client/invitations';
9
9
 
10
10
  import { type JoinSend } from './joinMachine';
11
- import { type ResetIdentityProps, type IdentityInputProps } from './steps';
12
- import { type StepProps } from '../../steps';
11
+ import { type IdentityInputProps } from './steps';
12
+ import { type ConfirmResetProps, type StepProps } from '../../steps';
13
13
  import { type FailReason } from '../../types';
14
14
 
15
15
  export type JoinPanelMode = 'default' | 'halo-only';
16
16
 
17
+ export type JoinPanelInitialDisposition = 'default' | 'accept-halo-invitation';
18
+
17
19
  export type JoinStepProps = Omit<StepProps, 'send' | 'onDone'> & {
18
20
  send: JoinSend;
19
21
  onDone?: (result: InvitationResult | null) => void;
@@ -21,6 +23,7 @@ export type JoinStepProps = Omit<StepProps, 'send' | 'onDone'> & {
21
23
 
22
24
  export interface JoinPanelProps {
23
25
  mode?: JoinPanelMode;
26
+ initialDisposition?: JoinPanelInitialDisposition;
24
27
  initialInvitationCode?: string;
25
28
  titleId?: string;
26
29
  exitActionParent?: Parameters<typeof cloneElement>[0];
@@ -28,6 +31,7 @@ export interface JoinPanelProps {
28
31
  onExit?: () => void;
29
32
  onDone?: (result: InvitationResult | null) => void;
30
33
  parseInvitationCodeInput?: (invitationCodeInput: string) => string;
34
+ onCancelResetStorage?: () => void;
31
35
  }
32
36
 
33
37
  export type JoinPanelImplProps = Pick<
@@ -61,8 +65,10 @@ export type JoinPanelImplProps = Pick<
61
65
  onSpaceInvitationCancel?: () => Promise<void> | undefined;
62
66
  onHaloInvitationAuthenticate?: (authCode: string) => Promise<void> | undefined;
63
67
  onSpaceInvitationAuthenticate?: (authCode: string) => Promise<void> | undefined;
68
+ onConfirmResetStorage?: () => Promise<void>;
69
+ onCancelResetStorage?: () => void;
64
70
  IdentityInput?: React.FC<IdentityInputProps>;
65
- ResetIdentity?: React.FC<ResetIdentityProps>;
71
+ ConfirmReset?: React.FC<ConfirmResetProps>;
66
72
  };
67
73
 
68
74
  export interface IdentityAction {
@@ -19,7 +19,7 @@ import { type Client, AlreadyJoinedError } from '@dxos/react-client';
19
19
  import { type Identity } from '@dxos/react-client/halo';
20
20
  import { type AuthenticatingInvitationObservable, Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
21
21
 
22
- import { type JoinPanelMode } from './JoinPanelProps';
22
+ import { type JoinPanelInitialDisposition, type JoinPanelMode } from './JoinPanelProps';
23
23
  import { type FailReason } from '../../types';
24
24
 
25
25
  type InvitationKindContext = Partial<{
@@ -33,6 +33,7 @@ type InvitationKindContext = Partial<{
33
33
 
34
34
  type JoinMachineContext = {
35
35
  mode: JoinPanelMode;
36
+ initialDisposition: JoinPanelInitialDisposition;
36
37
  identity: Identity | null;
37
38
  halo: InvitationKindContext;
38
39
  space: InvitationKindContext;
@@ -74,7 +75,8 @@ type EmptyInvitationEvent = {
74
75
  | 'authenticateHaloVerificationCode'
75
76
  | 'authenticateSpaceVerificationCode'
76
77
  | 'resetHaloInvitation'
77
- | 'resetSpaceInvitation';
78
+ | 'resetSpaceInvitation'
79
+ | 'deselectInvitation';
78
80
  };
79
81
 
80
82
  type InvitationEvent = FailInvitationEvent | SetInvitationCodeEvent | SetInvitationEvent | EmptyInvitationEvent;
@@ -294,6 +296,7 @@ const joinMachine = createMachine<JoinMachineContext, JoinEvent>(
294
296
  id: 'join',
295
297
  predictableActionArguments: true,
296
298
  context: {
299
+ initialDisposition: 'default',
297
300
  mode: 'default',
298
301
  identity: null,
299
302
  halo: {},
@@ -304,6 +307,11 @@ const joinMachine = createMachine<JoinMachineContext, JoinEvent>(
304
307
  unknown: {
305
308
  always: [
306
309
  { cond: 'existingIdentity', target: 'resettingIdentity', actions: 'log' },
310
+ {
311
+ cond: 'initiallyAcceptingHaloInvitation',
312
+ target: '#join.choosingIdentity.acceptingHaloInvitation',
313
+ actions: 'log',
314
+ },
307
315
  { cond: 'noSelectedIdentity', target: 'choosingIdentity', actions: 'log' },
308
316
  { target: 'acceptingSpaceInvitation', actions: 'log' },
309
317
  ],
@@ -352,6 +360,8 @@ const joinMachine = createMachine<JoinMachineContext, JoinEvent>(
352
360
  guards: {
353
361
  existingIdentity: ({ identity, mode }, _event) => mode === 'halo-only' && !!identity,
354
362
  noSelectedIdentity: ({ identity }, _event) => !identity,
363
+ initiallyAcceptingHaloInvitation: ({ identity, initialDisposition }, _event) =>
364
+ !identity && initialDisposition === 'accept-halo-invitation',
355
365
  hasHaloUnredeemedCode: ({ halo }, _event) => !!halo.unredeemedCode,
356
366
  noSpaceInvitation: ({ space }, _event) => !space.invitation && !space.unredeemedCode,
357
367
  },
@@ -9,4 +9,3 @@ export * from './InvitationAccepted';
9
9
  export * from './InvitationInput';
10
10
  export * from './InvitationRescuer';
11
11
  export * from './InvitationAuthenticator';
12
- export * from './ResetIdentity';
@@ -59,6 +59,7 @@ export const SpaceManager = (props: SpaceManagerProps) => {
59
59
  const invitation = space.share?.({
60
60
  type: Invitation.Type.INTERACTIVE,
61
61
  authMethod: Invitation.AuthMethod.SHARED_SECRET,
62
+ multiUse: false,
62
63
  target,
63
64
  });
64
65
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== 'production') {
@@ -72,8 +73,9 @@ export const SpaceManager = (props: SpaceManagerProps) => {
72
73
  icon: UsersThree,
73
74
  onClick: useCallback(() => {
74
75
  const invitation = space.share?.({
75
- type: Invitation.Type.MULTIUSE,
76
+ type: Invitation.Type.INTERACTIVE,
76
77
  authMethod: Invitation.AuthMethod.NONE,
78
+ multiUse: true,
77
79
  target,
78
80
  });
79
81
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== 'production') {
@@ -0,0 +1,19 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { Status, useTranslation } from '@dxos/react-ui';
8
+
9
+ export const StatusPanel = ({ titleId }: { titleId?: string }) => {
10
+ const { t } = useTranslation('os');
11
+ return (
12
+ <div className='grid place-items-center p-2 gap-2'>
13
+ <p id={titleId} className='font-medium text-center'>
14
+ {t('resetting message')}
15
+ </p>
16
+ <Status indeterminate>{t('resetting message')}</Status>
17
+ </div>
18
+ );
19
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './StatusPanel';
@@ -5,3 +5,4 @@
5
5
  export * from './IdentityPanel';
6
6
  export * from './JoinPanel';
7
7
  export * from './SpacePanel';
8
+ export * from './StatusPanel';