@dxos/shell 0.4.10-main.ec8b427 → 0.4.10-main.ef6fbc2
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.
- package/dist/bundle/shell.mjs +40192 -24641
- package/dist/bundle/shell.mjs.map +1 -1
- package/dist/bundle/shell.umd.js +156 -85
- package/dist/bundle/shell.umd.js.map +1 -1
- package/dist/bundle/style.css +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react.mjs +1147 -1006
- package/dist/lib/browser/react.mjs.map +4 -4
- package/dist/lib/browser/testing/index.mjs +8 -8
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/types/src/components/AgentConfig.d.ts +3 -0
- package/dist/types/src/components/AgentConfig.d.ts.map +1 -0
- package/dist/types/src/components/AgentConfig.js +37 -0
- package/dist/types/src/components/AgentConfig.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceList.d.ts +3 -0
- package/dist/types/src/components/DeviceList/DeviceList.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceList.js +29 -0
- package/dist/types/src/components/DeviceList/DeviceList.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.d.ts +6 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.js +72 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.d.ts +27 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.js +6 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.js.map +1 -0
- package/dist/types/src/components/DeviceList/index.d.ts +3 -0
- package/dist/types/src/components/DeviceList/index.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/index.js +22 -0
- package/dist/types/src/components/DeviceList/index.js.map +1 -0
- package/dist/types/src/components/EmojiPicker.d.ts +9 -2
- package/dist/types/src/components/EmojiPicker.d.ts.map +1 -1
- package/dist/types/src/components/EmojiPicker.js +59 -4
- package/dist/types/src/components/EmojiPicker.js.map +1 -1
- package/dist/types/src/components/HuePicker.d.ts +9 -2
- package/dist/types/src/components/HuePicker.d.ts.map +1 -1
- package/dist/types/src/components/HuePicker.js +75 -6
- package/dist/types/src/components/HuePicker.js.map +1 -1
- package/dist/types/src/components/IdentityList/index.d.ts +0 -1
- package/dist/types/src/components/IdentityList/index.d.ts.map +1 -1
- package/dist/types/src/components/IdentityList/index.js +0 -1
- package/dist/types/src/components/IdentityList/index.js.map +1 -1
- package/dist/types/src/components/Panel/Action.d.ts +2 -2
- package/dist/types/src/components/Viewport/Viewport.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/index.js +2 -0
- package/dist/types/src/components/index.js.map +1 -1
- package/dist/types/src/composites/IdentityDialog/IdentityDialog.js +1 -1
- package/dist/types/src/composites/IdentityDialog/IdentityDialog.js.map +1 -1
- package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/Shell.js +14 -6
- package/dist/types/src/composites/Shell/Shell.js.map +1 -1
- package/dist/types/src/composites/StatusDialog/StatusDialog.d.ts +2 -0
- package/dist/types/src/composites/StatusDialog/StatusDialog.d.ts.map +1 -0
- package/dist/types/src/composites/StatusDialog/StatusDialog.js +22 -0
- package/dist/types/src/composites/StatusDialog/StatusDialog.js.map +1 -0
- package/dist/types/src/composites/StatusDialog/index.d.ts +2 -0
- package/dist/types/src/composites/StatusDialog/index.d.ts.map +1 -0
- package/dist/types/src/composites/StatusDialog/index.js +21 -0
- package/dist/types/src/composites/StatusDialog/index.js.map +1 -0
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +89 -42
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +0 -3
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +1 -43
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +11 -12
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +3 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.js +13 -24
- package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts +4 -4
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +9 -39
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +6 -3
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +0 -3
- package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/index.js +0 -3
- package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.js +12 -5
- package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js +2 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +8 -3
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/joinMachine.d.ts +3 -2
- package/dist/types/src/panels/JoinPanel/joinMachine.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/joinMachine.js +7 -0
- package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/index.d.ts +0 -1
- package/dist/types/src/panels/JoinPanel/steps/index.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/index.js +0 -1
- package/dist/types/src/panels/JoinPanel/steps/index.js.map +1 -1
- package/dist/types/src/panels/StatusPanel/StatusPanel.d.ts +4 -0
- package/dist/types/src/panels/StatusPanel/StatusPanel.d.ts.map +1 -0
- package/dist/types/src/panels/StatusPanel/StatusPanel.js +19 -0
- package/dist/types/src/panels/StatusPanel/StatusPanel.js.map +1 -0
- package/dist/types/src/panels/StatusPanel/index.d.ts +2 -0
- package/dist/types/src/panels/StatusPanel/index.d.ts.map +1 -0
- package/dist/types/src/panels/StatusPanel/index.js +21 -0
- package/dist/types/src/panels/StatusPanel/index.js.map +1 -0
- package/dist/types/src/panels/index.d.ts +1 -0
- package/dist/types/src/panels/index.d.ts.map +1 -1
- package/dist/types/src/panels/index.js +1 -0
- package/dist/types/src/panels/index.js.map +1 -1
- package/dist/types/src/steps/ConfirmReset.d.ts +16 -0
- package/dist/types/src/steps/ConfirmReset.d.ts.map +1 -0
- package/dist/types/src/steps/ConfirmReset.js +71 -0
- package/dist/types/src/steps/ConfirmReset.js.map +1 -0
- package/dist/types/src/steps/StepProps.d.ts +4 -1
- package/dist/types/src/steps/StepProps.d.ts.map +1 -1
- package/dist/types/src/steps/index.d.ts +1 -0
- package/dist/types/src/steps/index.d.ts.map +1 -1
- package/dist/types/src/steps/index.js +1 -0
- package/dist/types/src/steps/index.js.map +1 -1
- package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
- package/dist/types/src/testing/shell-manager.js +8 -8
- package/dist/types/src/testing/shell-manager.js.map +1 -1
- package/dist/types/src/translations/locales/en-US.d.ts +16 -3
- package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
- package/dist/types/src/translations/locales/en-US.js +20 -7
- package/dist/types/src/translations/locales/en-US.js.map +1 -1
- package/dist/types/src/types/index.js +1 -0
- package/dist/types/src/types/index.js.map +1 -1
- package/package.json +20 -20
- package/src/components/AgentConfig.tsx +66 -0
- package/src/components/DeviceList/DeviceList.tsx +54 -0
- package/src/components/DeviceList/DeviceListItem.tsx +120 -0
- package/src/components/DeviceList/DeviceListProps.ts +33 -0
- package/src/components/DeviceList/index.ts +6 -0
- package/src/components/EmojiPicker.tsx +103 -4
- package/src/components/HuePicker.tsx +99 -5
- package/src/components/IdentityList/index.ts +0 -1
- package/src/components/index.ts +2 -0
- package/src/composites/IdentityDialog/IdentityDialog.tsx +1 -1
- package/src/composites/Shell/Shell.tsx +17 -4
- package/src/composites/StatusDialog/StatusDialog.tsx +24 -0
- package/src/composites/StatusDialog/index.ts +5 -0
- package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +0 -63
- package/src/panels/IdentityPanel/IdentityPanel.tsx +149 -43
- package/src/panels/IdentityPanel/IdentityPanelProps.ts +15 -15
- package/src/panels/IdentityPanel/identityMachine.ts +17 -25
- package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +23 -67
- package/src/panels/IdentityPanel/steps/ProfileForm.tsx +18 -5
- package/src/panels/IdentityPanel/steps/index.ts +0 -3
- package/src/panels/JoinPanel/JoinPanel.stories.tsx +3 -2
- package/src/panels/JoinPanel/JoinPanel.tsx +21 -5
- package/src/panels/JoinPanel/JoinPanelProps.ts +9 -3
- package/src/panels/JoinPanel/joinMachine.ts +12 -2
- package/src/panels/JoinPanel/steps/index.ts +0 -1
- package/src/panels/StatusPanel/StatusPanel.tsx +19 -0
- package/src/panels/StatusPanel/index.ts +5 -0
- package/src/panels/index.ts +1 -0
- package/src/steps/ConfirmReset.tsx +112 -0
- package/src/steps/StepProps.ts +2 -1
- package/src/steps/index.ts +1 -0
- package/src/testing/shell-manager.ts +8 -8
- package/src/translations/locales/en-US.ts +22 -7
- package/src/types/index.ts +2 -0
- package/dist/types/src/components/IdentityList/DeviceList.d.ts +0 -7
- package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +0 -1
- package/dist/types/src/components/IdentityList/DeviceList.js +0 -34
- package/dist/types/src/components/IdentityList/DeviceList.js.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +0 -3
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js +0 -26
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts +0 -10
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js +0 -23
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +0 -16
- package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js +0 -40
- package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +0 -1
- package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts +0 -13
- package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts.map +0 -1
- package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js +0 -66
- package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js.map +0 -1
- package/src/components/IdentityList/DeviceList.tsx +0 -49
- package/src/panels/IdentityPanel/steps/AgentForm.tsx +0 -61
- package/src/panels/IdentityPanel/steps/DeviceManager.tsx +0 -41
- package/src/panels/IdentityPanel/steps/SignOutChooser.tsx +0 -84
- package/src/panels/JoinPanel/steps/ResetIdentity.tsx +0 -80
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
import
|
|
4
|
+
import { CopySimple, Plugs, PlugsConnected } from '@phosphor-icons/react';
|
|
5
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
5
6
|
|
|
6
7
|
import { generateName } from '@dxos/display-name';
|
|
7
8
|
import { log } from '@dxos/log';
|
|
@@ -9,8 +10,10 @@ import { useClient } from '@dxos/react-client';
|
|
|
9
10
|
import { type Identity, useIdentity, useDevices, useHaloInvitations } from '@dxos/react-client/halo';
|
|
10
11
|
import { useInvitationStatus } from '@dxos/react-client/invitations';
|
|
11
12
|
import type { CancellableInvitationObservable } from '@dxos/react-client/invitations';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
13
|
+
import { useNetworkStatus, ConnectionState } from '@dxos/react-client/mesh';
|
|
14
|
+
import { Avatar, DensityProvider, Input, Toolbar, Tooltip, useId, useTranslation } from '@dxos/react-ui';
|
|
15
|
+
import { getSize } from '@dxos/react-ui-theme';
|
|
16
|
+
import { hexToEmoji, hexToHue, keyToFallback } from '@dxos/util';
|
|
14
17
|
|
|
15
18
|
import {
|
|
16
19
|
type IdentityPanelHeadingProps,
|
|
@@ -18,24 +21,122 @@ import {
|
|
|
18
21
|
type IdentityPanelProps,
|
|
19
22
|
} from './IdentityPanelProps';
|
|
20
23
|
import { useIdentityMachine } from './identityMachine';
|
|
21
|
-
import {
|
|
24
|
+
import { IdentityActionChooser } from './steps';
|
|
22
25
|
import { useAgentHandlers } from './useAgentHandlers';
|
|
23
|
-
import {
|
|
24
|
-
|
|
26
|
+
import {
|
|
27
|
+
Viewport,
|
|
28
|
+
Heading,
|
|
29
|
+
CloseButton,
|
|
30
|
+
EmojiPickerToolbarButton,
|
|
31
|
+
useClipboardContext,
|
|
32
|
+
HuePickerToolbarButton,
|
|
33
|
+
} from '../../components';
|
|
34
|
+
import { ConfirmReset, InvitationManager } from '../../steps';
|
|
25
35
|
|
|
26
36
|
const viewStyles = 'pbs-1 pbe-3 pli-3';
|
|
27
37
|
|
|
28
|
-
|
|
38
|
+
// TODO(thure): Factor out?
|
|
39
|
+
const getHueValue = (identity?: Identity) =>
|
|
40
|
+
identity?.profile?.data?.hue || hexToHue(identity?.identityKey.toHex() ?? '0');
|
|
41
|
+
const getEmojiValue = (identity?: Identity) =>
|
|
42
|
+
identity?.profile?.data?.emoji || hexToEmoji(identity?.identityKey.toHex() ?? '0');
|
|
43
|
+
|
|
44
|
+
const IdentityHeading = ({
|
|
45
|
+
titleId,
|
|
46
|
+
title,
|
|
47
|
+
identity,
|
|
48
|
+
onDone,
|
|
49
|
+
onUpdateProfile,
|
|
50
|
+
connectionState,
|
|
51
|
+
onChangeConnectionState,
|
|
52
|
+
}: IdentityPanelHeadingProps) => {
|
|
29
53
|
const fallbackValue = keyToFallback(identity.identityKey);
|
|
54
|
+
const { t } = useTranslation('os');
|
|
55
|
+
const [displayName, setDisplayName] = useState(identity.profile?.displayName ?? '');
|
|
56
|
+
const [emoji, setEmoji] = useState<string>(getEmojiValue(identity));
|
|
57
|
+
const [hue, setHue] = useState<string>(getHueValue(identity));
|
|
58
|
+
const { textValue, setTextValue } = useClipboardContext();
|
|
59
|
+
const identityHex = identity.identityKey.toHex();
|
|
60
|
+
const copied = textValue === identityHex;
|
|
61
|
+
|
|
62
|
+
const handleUpdateProfile = async () => {
|
|
63
|
+
const nextProfile = {
|
|
64
|
+
...(displayName && { displayName }),
|
|
65
|
+
...((emoji || hue) && { data: { ...(emoji && { emoji }), ...(hue && { hue }) } }),
|
|
66
|
+
};
|
|
67
|
+
return onUpdateProfile?.(nextProfile);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
void handleUpdateProfile();
|
|
72
|
+
}, [emoji, hue]);
|
|
73
|
+
|
|
74
|
+
const isConnected = connectionState === ConnectionState.ONLINE;
|
|
75
|
+
|
|
30
76
|
return (
|
|
31
77
|
<Heading titleId={titleId} title={title} corner={<CloseButton onDone={onDone} />}>
|
|
32
|
-
<Avatar.Root size={
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
78
|
+
<Avatar.Root size={16} variant='circle' status={isConnected ? 'active' : 'error'} hue={hue || fallbackValue.hue}>
|
|
79
|
+
<Toolbar.Root classNames='grid grid-cols-[1fr_var(--rail-action)_min-content_var(--rail-action)_1fr] items-center gap-2'>
|
|
80
|
+
<Tooltip.Root>
|
|
81
|
+
<Tooltip.Trigger asChild>
|
|
82
|
+
<Toolbar.Button
|
|
83
|
+
classNames='bs-[--rail-action] is-[--rail-action] justify-self-end'
|
|
84
|
+
onClick={() =>
|
|
85
|
+
onChangeConnectionState?.(isConnected ? ConnectionState.OFFLINE : ConnectionState.ONLINE)
|
|
86
|
+
}
|
|
87
|
+
>
|
|
88
|
+
<span className='sr-only'>{t(isConnected ? 'disconnect label' : 'connect label')}</span>
|
|
89
|
+
{isConnected ? <PlugsConnected className={getSize(5)} /> : <Plugs className={getSize(5)} />}
|
|
90
|
+
</Toolbar.Button>
|
|
91
|
+
</Tooltip.Trigger>
|
|
92
|
+
<Tooltip.Portal>
|
|
93
|
+
<Tooltip.Content side='bottom' classNames='z-50'>
|
|
94
|
+
{t(isConnected ? 'disconnect label' : 'connect label')}
|
|
95
|
+
<Tooltip.Arrow />
|
|
96
|
+
</Tooltip.Content>
|
|
97
|
+
</Tooltip.Portal>
|
|
98
|
+
</Tooltip.Root>
|
|
99
|
+
<EmojiPickerToolbarButton emoji={emoji} onChangeEmoji={setEmoji} classNames='bs-[--rail-action]' />
|
|
100
|
+
<Avatar.Frame classNames='relative z-[2] -mli-4 chromatic-ignore'>
|
|
101
|
+
<Avatar.Fallback text={emoji || fallbackValue.emoji} />
|
|
102
|
+
</Avatar.Frame>
|
|
103
|
+
<HuePickerToolbarButton hue={hue} onChangeHue={setHue} classNames='bs-[--rail-action]' />
|
|
104
|
+
<Tooltip.Root>
|
|
105
|
+
<Tooltip.Trigger asChild>
|
|
106
|
+
<Toolbar.Button
|
|
107
|
+
classNames='bs-[--rail-action] justify-self-start'
|
|
108
|
+
data-testid='update-profile-form-copy-key'
|
|
109
|
+
onClick={() => setTextValue(identityHex)}
|
|
110
|
+
>
|
|
111
|
+
<span className='sr-only'>{t(copied ? 'copy success label' : 'copy self public key label')}</span>
|
|
112
|
+
<CopySimple className={getSize(5)} />
|
|
113
|
+
</Toolbar.Button>
|
|
114
|
+
</Tooltip.Trigger>
|
|
115
|
+
<Tooltip.Portal>
|
|
116
|
+
<Tooltip.Content side='bottom' classNames='z-50'>
|
|
117
|
+
{t(copied ? 'copy success label' : 'copy self public key label')}
|
|
118
|
+
<Tooltip.Arrow />
|
|
119
|
+
</Tooltip.Content>
|
|
120
|
+
</Tooltip.Portal>
|
|
121
|
+
</Tooltip.Root>
|
|
122
|
+
</Toolbar.Root>
|
|
123
|
+
<Avatar.Label classNames='sr-only' data-testid='identityHeading.displayName'>
|
|
37
124
|
{identity.profile?.displayName ?? generateName(identity.identityKey.toHex())}
|
|
38
125
|
</Avatar.Label>
|
|
126
|
+
<Input.Root>
|
|
127
|
+
<Input.Label srOnly>{t('display name input label')}</Input.Label>
|
|
128
|
+
<Input.TextInput
|
|
129
|
+
variant='subdued'
|
|
130
|
+
data-testid='display-name-input'
|
|
131
|
+
placeholder={t('display name input placeholder')}
|
|
132
|
+
classNames='mbs-2 text-center font-light text-xl'
|
|
133
|
+
value={displayName}
|
|
134
|
+
onChange={({ target: { value } }) => {
|
|
135
|
+
setDisplayName(value);
|
|
136
|
+
}}
|
|
137
|
+
onBlur={handleUpdateProfile}
|
|
138
|
+
/>
|
|
139
|
+
</Input.Root>
|
|
39
140
|
</Avatar.Root>
|
|
40
141
|
</Heading>
|
|
41
142
|
);
|
|
@@ -47,18 +148,18 @@ export const IdentityPanelImpl = (props: IdentityPanelImplProps) => {
|
|
|
47
148
|
titleId,
|
|
48
149
|
activeView,
|
|
49
150
|
onUpdateProfile,
|
|
50
|
-
|
|
151
|
+
onResetStorage,
|
|
51
152
|
onJoinNewIdentity,
|
|
52
153
|
IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser,
|
|
53
154
|
InvitationManager: InvitationManagerComponent = InvitationManager,
|
|
155
|
+
connectionState,
|
|
156
|
+
onChangeConnectionState,
|
|
54
157
|
onDone,
|
|
55
158
|
...rest
|
|
56
159
|
} = props;
|
|
57
160
|
const { t } = useTranslation('os');
|
|
58
161
|
const title = useMemo(() => {
|
|
59
162
|
switch (activeView) {
|
|
60
|
-
case 'agent manager':
|
|
61
|
-
return 'Manage Agent';
|
|
62
163
|
case 'device invitation manager':
|
|
63
164
|
return t('choose add device label');
|
|
64
165
|
default:
|
|
@@ -66,9 +167,13 @@ export const IdentityPanelImpl = (props: IdentityPanelImplProps) => {
|
|
|
66
167
|
}
|
|
67
168
|
}, [activeView, t]);
|
|
68
169
|
|
|
170
|
+
const onCancelReset = () => rest.send?.('unchooseAction');
|
|
171
|
+
|
|
69
172
|
return (
|
|
70
173
|
<DensityProvider density='fine'>
|
|
71
|
-
<IdentityHeading
|
|
174
|
+
<IdentityHeading
|
|
175
|
+
{...{ identity, titleId, title, onDone, onUpdateProfile, connectionState, onChangeConnectionState }}
|
|
176
|
+
/>
|
|
72
177
|
<Viewport.Root activeView={activeView}>
|
|
73
178
|
<Viewport.Views>
|
|
74
179
|
<Viewport.View id='identity action chooser' classNames={viewStyles}>
|
|
@@ -81,28 +186,24 @@ export const IdentityPanelImpl = (props: IdentityPanelImplProps) => {
|
|
|
81
186
|
invitationUrl={rest.createInvitationUrl(rest.invitationCode!)}
|
|
82
187
|
/>
|
|
83
188
|
</Viewport.View>
|
|
84
|
-
<Viewport.View id='
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
identity={identity}
|
|
92
|
-
onUpdateProfile={onUpdateProfile}
|
|
189
|
+
<Viewport.View classNames={viewStyles} id='confirm join new identity'>
|
|
190
|
+
<ConfirmReset
|
|
191
|
+
active={activeView === 'confirm join new identity'}
|
|
192
|
+
{...rest}
|
|
193
|
+
mode='join new identity'
|
|
194
|
+
onConfirm={onJoinNewIdentity}
|
|
195
|
+
onCancel={onCancelReset}
|
|
93
196
|
/>
|
|
94
197
|
</Viewport.View>
|
|
95
|
-
<Viewport.View classNames={viewStyles} id='
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
198
|
+
<Viewport.View classNames={viewStyles} id='confirm reset storage'>
|
|
199
|
+
<ConfirmReset
|
|
200
|
+
active={activeView === 'confirm reset storage'}
|
|
201
|
+
{...rest}
|
|
202
|
+
mode='reset storage'
|
|
203
|
+
onConfirm={onResetStorage}
|
|
204
|
+
onCancel={onCancelReset}
|
|
101
205
|
/>
|
|
102
206
|
</Viewport.View>
|
|
103
|
-
<Viewport.View classNames={viewStyles} id='agent manager'>
|
|
104
|
-
<AgentForm send={rest.send} active={activeView === 'agent manager'} {...rest} />
|
|
105
|
-
</Viewport.View>
|
|
106
207
|
</Viewport.Views>
|
|
107
208
|
</Viewport.Root>
|
|
108
209
|
</DensityProvider>
|
|
@@ -120,6 +221,7 @@ const IdentityPanelWithInvitationImpl = ({
|
|
|
120
221
|
export const IdentityPanel = ({
|
|
121
222
|
titleId: propsTitleId,
|
|
122
223
|
createInvitationUrl = (code) => code,
|
|
224
|
+
initialDisposition = 'default',
|
|
123
225
|
...props
|
|
124
226
|
}: IdentityPanelProps) => {
|
|
125
227
|
const titleId = useId('identityPanel__heading', propsTitleId);
|
|
@@ -132,7 +234,13 @@ export const IdentityPanel = ({
|
|
|
132
234
|
log.error('IdentityPanel rendered with no active identity.');
|
|
133
235
|
return null;
|
|
134
236
|
}
|
|
135
|
-
const [identityState, identitySend, identityService] = useIdentityMachine(client
|
|
237
|
+
const [identityState, identitySend, identityService] = useIdentityMachine(client, {
|
|
238
|
+
context: { initialDisposition },
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const { swarm: connectionState } = useNetworkStatus();
|
|
242
|
+
|
|
243
|
+
const handleChangeConnectionState = async (nextState: ConnectionState) => client?.mesh.updateConfig(nextState);
|
|
136
244
|
|
|
137
245
|
useEffect(() => {
|
|
138
246
|
const subscription = identityService.subscribe((state) => {
|
|
@@ -148,14 +256,10 @@ export const IdentityPanel = ({
|
|
|
148
256
|
return 'identity action chooser';
|
|
149
257
|
case identityState.matches('managingDeviceInvitation'):
|
|
150
258
|
return 'device invitation manager';
|
|
151
|
-
case identityState.matches('
|
|
152
|
-
return '
|
|
153
|
-
case
|
|
154
|
-
return '
|
|
155
|
-
case identityState.matches('signingOut'):
|
|
156
|
-
return 'signing out';
|
|
157
|
-
case [{ managingAgent: 'idle' }, { managingAgent: 'pending' }].some(identityState.matches):
|
|
158
|
-
return 'agent manager';
|
|
259
|
+
case identityState.matches('confirmingResetStorage'):
|
|
260
|
+
return 'confirm reset storage';
|
|
261
|
+
case identityState.matches('confirmingJoinNewIdentity'):
|
|
262
|
+
return 'confirm join new identity';
|
|
159
263
|
default:
|
|
160
264
|
return 'identity action chooser';
|
|
161
265
|
}
|
|
@@ -175,6 +279,8 @@ export const IdentityPanel = ({
|
|
|
175
279
|
titleId,
|
|
176
280
|
createInvitationUrl,
|
|
177
281
|
onUpdateProfile,
|
|
282
|
+
connectionState,
|
|
283
|
+
onChangeConnectionState: handleChangeConnectionState,
|
|
178
284
|
...agentProps,
|
|
179
285
|
} satisfies IdentityPanelImplProps;
|
|
180
286
|
|
|
@@ -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
|
|
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
|
-
| '
|
|
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
|
-
|
|
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<
|
|
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: '
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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 {
|
|
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 = (
|
|
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={
|
|
41
|
+
onCreateInvitationClick={createInvitation}
|
|
48
42
|
agentHostingEnabled={!!agentHostingProviderClient}
|
|
49
43
|
/>
|
|
50
44
|
);
|
|
51
45
|
};
|
|
52
46
|
|
|
53
|
-
export type IdentityActionChooserImplProps = IdentityActionChooserProps &
|
|
54
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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 {
|
|
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
|
-
<
|
|
79
|
+
<EmojiPickerBlock
|
|
72
80
|
emoji={emoji}
|
|
73
81
|
onChangeEmoji={setEmoji}
|
|
74
82
|
disabled={disabled}
|
|
75
83
|
onClickClear={() => setEmoji(getEmojiValue(identity))}
|
|
76
84
|
/>
|
|
77
|
-
<
|
|
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={() =>
|
|
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')}
|
|
@@ -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
|
|
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:
|
|
38
|
+
ResetIdentity: ConfirmResetImpl,
|
|
38
39
|
},
|
|
39
40
|
};
|
|
40
41
|
|