@dxos/shell 0.5.1-main.f02b2c7 → 0.5.1-main.f2d5836
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 +7059 -7017
- package/dist/bundle/shell.mjs.map +1 -1
- package/dist/bundle/shell.umd.js +64 -64
- package/dist/bundle/shell.umd.js.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react.mjs +148 -80
- package/dist/lib/browser/react.mjs.map +3 -3
- package/dist/lib/browser/testing/index.mjs +3 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/types/src/components/DeviceList/DeviceListItem.js +1 -1
- package/dist/types/src/components/DeviceList/DeviceListItem.js.map +1 -1
- package/dist/types/src/composites/Shell/Shell.d.ts +1 -2
- package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/Shell.js +24 -4
- package/dist/types/src/composites/Shell/Shell.js.map +1 -1
- package/dist/types/src/composites/Shell/ShellContext.js +1 -1
- package/dist/types/src/composites/Shell/ShellContext.js.map +1 -1
- package/dist/types/src/composites/Shell/memory-shell-runtime.d.ts +10 -2
- package/dist/types/src/composites/Shell/memory-shell-runtime.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/memory-shell-runtime.js +20 -1
- package/dist/types/src/composites/Shell/memory-shell-runtime.js.map +1 -1
- package/dist/types/src/composites/Shell/run-shell.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/run-shell.js +29 -9
- package/dist/types/src/composites/Shell/run-shell.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts +1 -3
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +3 -2
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.js +2 -2
- package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
- package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
- package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +2 -18
- package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
- package/dist/types/src/steps/ConfirmReset.js +1 -1
- package/dist/types/src/steps/ConfirmReset.js.map +1 -1
- package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
- package/dist/types/src/steps/InvitationManager.js +3 -0
- package/dist/types/src/steps/InvitationManager.js.map +1 -1
- package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
- package/dist/types/src/testing/shell-manager.js +3 -2
- package/dist/types/src/testing/shell-manager.js.map +1 -1
- package/dist/types/src/translations/locales/en-US.d.ts +2 -0
- package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
- package/dist/types/src/translations/locales/en-US.js +11 -9
- package/dist/types/src/translations/locales/en-US.js.map +1 -1
- package/package.json +21 -21
- package/src/components/DeviceList/DeviceListItem.tsx +1 -1
- package/src/composites/Shell/Shell.tsx +36 -5
- package/src/composites/Shell/ShellContext.tsx +1 -1
- package/src/composites/Shell/memory-shell-runtime.ts +36 -2
- package/src/composites/Shell/run-shell.tsx +59 -18
- package/src/panels/IdentityPanel/IdentityPanel.tsx +1 -1
- package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +2 -2
- package/src/panels/IdentityPanel/useAgentHandlers.ts +3 -4
- package/src/panels/JoinPanel/JoinPanel.tsx +2 -2
- package/src/panels/SpacePanel/steps/SpaceManager.tsx +2 -18
- package/src/steps/ConfirmReset.tsx +1 -1
- package/src/steps/InvitationManager.tsx +3 -0
- package/src/testing/shell-manager.ts +4 -2
- package/src/translations/locales/en-US.ts +11 -9
|
@@ -7,8 +7,16 @@ import { createRoot } from 'react-dom/client';
|
|
|
7
7
|
|
|
8
8
|
import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from '@dxos/client-protocol';
|
|
9
9
|
import { ShellRuntimeImpl } from '@dxos/client-services';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
AgentHostingProvider,
|
|
12
|
+
Client,
|
|
13
|
+
ClientContext,
|
|
14
|
+
ClientServicesProxy,
|
|
15
|
+
Config,
|
|
16
|
+
ShellDisplay,
|
|
17
|
+
SystemStatus,
|
|
18
|
+
} from '@dxos/react-client';
|
|
19
|
+
import { Button, Dialog, ThemeProvider, Tooltip, useTranslation } from '@dxos/react-ui';
|
|
12
20
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
13
21
|
import { createIFramePort } from '@dxos/rpc-tunnel';
|
|
14
22
|
|
|
@@ -17,22 +25,55 @@ import { ClipboardProvider } from '../../components';
|
|
|
17
25
|
import { osTranslations } from '../../translations';
|
|
18
26
|
|
|
19
27
|
export const runShell = async (config: Config = new Config()) => {
|
|
20
|
-
|
|
21
|
-
const client = new Client({ config, services });
|
|
28
|
+
// If runtime fails to open then the shell will not be openable.
|
|
22
29
|
const runtime = new ShellRuntimeImpl(createIFramePort({ channel: DEFAULT_SHELL_CHANNEL }));
|
|
23
|
-
await
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
await runtime.open();
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const services = new ClientServicesProxy(createIFramePort({ channel: DEFAULT_CLIENT_CHANNEL }));
|
|
34
|
+
const client = new Client({ config, services });
|
|
35
|
+
await client.initialize();
|
|
36
|
+
|
|
37
|
+
createRoot(document.getElementById('root')!).render(
|
|
38
|
+
<StrictMode>
|
|
39
|
+
<ThemeProvider tx={defaultTx} resourceExtensions={[osTranslations]}>
|
|
40
|
+
<ClientContext.Provider value={{ client, status: SystemStatus.ACTIVE }}>
|
|
41
|
+
<ClipboardProvider>
|
|
42
|
+
<Tooltip.Provider>
|
|
43
|
+
<AgentHostingProvider>
|
|
44
|
+
<Shell runtime={runtime} />
|
|
45
|
+
</AgentHostingProvider>
|
|
46
|
+
</Tooltip.Provider>
|
|
47
|
+
</ClipboardProvider>
|
|
48
|
+
</ClientContext.Provider>
|
|
49
|
+
</ThemeProvider>
|
|
50
|
+
</StrictMode>,
|
|
51
|
+
);
|
|
52
|
+
} catch {
|
|
53
|
+
// If shell's client fails to initialize, ensure that the shell is still closeable.
|
|
54
|
+
createRoot(document.getElementById('root')!).render(
|
|
55
|
+
<StrictMode>
|
|
56
|
+
<ThemeProvider tx={defaultTx} resourceExtensions={[osTranslations]}>
|
|
57
|
+
<Fallback onClose={() => runtime.setAppContext({ display: ShellDisplay.NONE })} />
|
|
58
|
+
</ThemeProvider>
|
|
59
|
+
</StrictMode>,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const Fallback = ({ onClose }: { onClose?: () => void }) => {
|
|
65
|
+
const { t } = useTranslation('os');
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Dialog.Root modal open onOpenChange={() => onClose?.()}>
|
|
69
|
+
<Dialog.Overlay>
|
|
70
|
+
<Dialog.Content>
|
|
71
|
+
<Dialog.Title>{t('shell fallback title')}</Dialog.Title>
|
|
72
|
+
<Dialog.Close asChild onClick={() => onClose?.()}>
|
|
73
|
+
<Button variant='primary'>{t('close label')}</Button>
|
|
74
|
+
</Dialog.Close>
|
|
75
|
+
</Dialog.Content>
|
|
76
|
+
</Dialog.Overlay>
|
|
77
|
+
</Dialog.Root>
|
|
37
78
|
);
|
|
38
79
|
};
|
|
@@ -235,7 +235,7 @@ export const IdentityPanel = ({
|
|
|
235
235
|
const devices = useDevices();
|
|
236
236
|
const identity = useIdentity();
|
|
237
237
|
const invitations = useHaloInvitations();
|
|
238
|
-
const agentProps = useAgentHandlers({
|
|
238
|
+
const agentProps = useAgentHandlers({ identity, invitations });
|
|
239
239
|
if (!identity) {
|
|
240
240
|
log.error('IdentityPanel rendered with no active identity.');
|
|
241
241
|
return null;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
7
|
import { log } from '@dxos/log';
|
|
8
|
-
import {
|
|
8
|
+
import { useAgentHostingClient, useClient } from '@dxos/react-client';
|
|
9
9
|
import { useHaloInvitations } from '@dxos/react-client/halo';
|
|
10
10
|
import { Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ export const IdentityActionChooser = (props: IdentityPanelStepProps) => {
|
|
|
18
18
|
const { send } = props;
|
|
19
19
|
const client = useClient();
|
|
20
20
|
const invitations = useHaloInvitations();
|
|
21
|
-
const agentHostingProviderClient =
|
|
21
|
+
const agentHostingProviderClient = useAgentHostingClient();
|
|
22
22
|
const onInvitationEvent = useCallback((invitation: Invitation) => {
|
|
23
23
|
const invitationCode = InvitationEncoder.encode(invitation);
|
|
24
24
|
if (invitation.state === Invitation.State.CONNECTING) {
|
|
@@ -7,23 +7,22 @@ import { useCallback, useEffect, useState } from 'react';
|
|
|
7
7
|
import { type CancellableInvitation } from '@dxos/client-protocol';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
|
-
import {
|
|
10
|
+
import { useAgentHostingClient, useClient } from '@dxos/react-client';
|
|
11
11
|
import { type Identity } from '@dxos/react-client/halo';
|
|
12
12
|
import { Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
|
|
13
13
|
|
|
14
14
|
export const useAgentHandlers = ({
|
|
15
|
-
client,
|
|
16
15
|
invitations,
|
|
17
16
|
identity,
|
|
18
17
|
}: {
|
|
19
|
-
client: Client;
|
|
20
18
|
invitations: CancellableInvitation[];
|
|
21
19
|
identity: Identity | null;
|
|
22
20
|
}) => {
|
|
23
21
|
const [validationMessage, setValidationMessage] = useState('');
|
|
24
22
|
const [agentStatus, setAgentStatus] = useState('');
|
|
25
23
|
const [agentActive, setAgentActive] = useState(false);
|
|
26
|
-
const agentHostingProviderClient =
|
|
24
|
+
const agentHostingProviderClient = useAgentHostingClient();
|
|
25
|
+
const client = useClient();
|
|
27
26
|
|
|
28
27
|
useEffect(() => {
|
|
29
28
|
const fetchAgentStatus = async () => {
|
|
@@ -60,7 +60,7 @@ export const JoinPanelImpl = (props: JoinPanelImplProps) => {
|
|
|
60
60
|
<Viewport.View classNames={stepStyles} id='reset storage confirmation'>
|
|
61
61
|
<ConfirmResetComponent
|
|
62
62
|
send={send}
|
|
63
|
-
active={activeView === 'reset
|
|
63
|
+
active={activeView === 'reset storage confirmation'}
|
|
64
64
|
onCancel={onCancelResetStorage}
|
|
65
65
|
onConfirm={onConfirmResetStorage}
|
|
66
66
|
/>
|
|
@@ -222,7 +222,7 @@ export const JoinPanel = ({
|
|
|
222
222
|
case joinState.matches({ choosingIdentity: 'choosingAuthMethod' }):
|
|
223
223
|
return 'addition method chooser';
|
|
224
224
|
case joinState.matches('resettingIdentity'):
|
|
225
|
-
return 'reset
|
|
225
|
+
return 'reset storage confirmation';
|
|
226
226
|
case joinState.matches({ choosingIdentity: 'creatingIdentity' }):
|
|
227
227
|
return 'create identity input';
|
|
228
228
|
case joinState.matches({ choosingIdentity: 'recoveringIdentity' }):
|
|
@@ -73,8 +73,8 @@ export const SpaceManager = (props: SpaceManagerProps) => {
|
|
|
73
73
|
icon: UsersThree,
|
|
74
74
|
onClick: useCallback(() => {
|
|
75
75
|
const invitation = space.share?.({
|
|
76
|
-
type: Invitation.Type.
|
|
77
|
-
authMethod: Invitation.AuthMethod.
|
|
76
|
+
type: Invitation.Type.DELEGATED,
|
|
77
|
+
authMethod: Invitation.AuthMethod.KNOWN_PUBLIC_KEY,
|
|
78
78
|
multiUse: true,
|
|
79
79
|
target,
|
|
80
80
|
});
|
|
@@ -83,22 +83,6 @@ export const SpaceManager = (props: SpaceManagerProps) => {
|
|
|
83
83
|
}
|
|
84
84
|
}, [space]),
|
|
85
85
|
},
|
|
86
|
-
// inviteNonPersistent: {
|
|
87
|
-
// label: 'Invite one (nonpersistent)',
|
|
88
|
-
// description: 'Only one user may join. Invitation does not resume if client is restarted.',
|
|
89
|
-
// icon: UserPlus,
|
|
90
|
-
// onClick: useCallback(() => {
|
|
91
|
-
// const invitation = space.share?.({
|
|
92
|
-
// type: Invitation.Type.INTERACTIVE,
|
|
93
|
-
// authMethod: Invitation.AuthMethod.SHARED_SECRET,
|
|
94
|
-
// persistent: false,
|
|
95
|
-
// target,
|
|
96
|
-
// });
|
|
97
|
-
// if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== 'production') {
|
|
98
|
-
// invitation.subscribe(onInvitationEvent);
|
|
99
|
-
// }
|
|
100
|
-
// }, [space]),
|
|
101
|
-
// },
|
|
102
86
|
};
|
|
103
87
|
|
|
104
88
|
return <SpaceManagerImpl {...props} invitations={invitations} inviteActions={inviteActions} />;
|
|
@@ -86,7 +86,7 @@ export const ConfirmResetImpl = ({
|
|
|
86
86
|
}
|
|
87
87
|
disabled={disabled}
|
|
88
88
|
data-testid={`${testIdAffix}.reset-identity-input`}
|
|
89
|
-
placeholder={confirmationValue}
|
|
89
|
+
placeholder={t('confirmation placeholder', { confirmationValue })}
|
|
90
90
|
onChange={({ target: { value } }) => setInputValue(value)}
|
|
91
91
|
/>
|
|
92
92
|
</div>
|
|
@@ -53,6 +53,9 @@ export const InvitationManager = ({
|
|
|
53
53
|
const showAuthCode = statusValue === 3;
|
|
54
54
|
const emoji = hexToEmoji(id);
|
|
55
55
|
const activeView = useMemo(() => {
|
|
56
|
+
if (multiUse) {
|
|
57
|
+
return 'showing qr';
|
|
58
|
+
}
|
|
56
59
|
switch (true) {
|
|
57
60
|
case statusValue === 5:
|
|
58
61
|
case statusValue < 0:
|
|
@@ -10,6 +10,8 @@ import { ScopedShellManager } from './scoped-shell-manager';
|
|
|
10
10
|
|
|
11
11
|
// TODO(wittjosiah): Normalize data-testids between snake and camel case.
|
|
12
12
|
|
|
13
|
+
const CONFIRM_INPUT = 'RESET';
|
|
14
|
+
|
|
13
15
|
export class ShellManager extends ScopedShellManager {
|
|
14
16
|
private _invitationCode = new Trigger<string>();
|
|
15
17
|
private _authCode = new Trigger<string>();
|
|
@@ -67,14 +69,14 @@ export class ShellManager extends ScopedShellManager {
|
|
|
67
69
|
this.page.on('dialog', handleDialog);
|
|
68
70
|
await this.shell.getByTestId('device-list-item-current.options').click();
|
|
69
71
|
await this.shell.getByTestId('device-list-item-current.reset').click();
|
|
70
|
-
await this.shell.getByTestId('reset-storage.reset-identity-input').fill(
|
|
72
|
+
await this.shell.getByTestId('reset-storage.reset-identity-input').fill(CONFIRM_INPUT);
|
|
71
73
|
await this.shell.getByTestId('reset-storage.reset-identity-confirm').click();
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
async joinNewIdentity(invitationCode: string) {
|
|
75
77
|
await this.shell.getByTestId('device-list-item-current.options').click();
|
|
76
78
|
await this.shell.getByTestId('device-list-item-current.join-existing').click();
|
|
77
|
-
await this.shell.getByTestId('join-new-identity.reset-identity-input').fill(
|
|
79
|
+
await this.shell.getByTestId('join-new-identity.reset-identity-input').fill(CONFIRM_INPUT);
|
|
78
80
|
await this.shell.getByTestId('join-new-identity.reset-identity-confirm').click();
|
|
79
81
|
await this.inputInvitation('device', invitationCode, this.shell);
|
|
80
82
|
}
|
|
@@ -85,23 +85,24 @@ export const os = {
|
|
|
85
85
|
'auth code message': 'Enter the following auth code on the joining device.',
|
|
86
86
|
'display name input label': 'Display name',
|
|
87
87
|
'display name input placeholder': 'Enter a display name',
|
|
88
|
-
'invite one label': '
|
|
88
|
+
'invite one label': 'Single-use invitation',
|
|
89
89
|
'invite one description': 'Only one user may join.',
|
|
90
|
-
'invite one qr label': 'Single-use',
|
|
90
|
+
'invite one qr label': 'Single-use invitation',
|
|
91
91
|
'invite one list item label': 'Active single-use invitation',
|
|
92
|
-
'invite many label': '
|
|
92
|
+
'invite many label': 'Standing invitation',
|
|
93
93
|
'invite many description': 'Anyone with the link can join.',
|
|
94
|
-
'invite many qr label': '
|
|
95
|
-
'invite many list item label': 'Active
|
|
94
|
+
'invite many qr label': 'Standing invitation',
|
|
95
|
+
'invite many list item label': 'Active standing invitation',
|
|
96
96
|
'invite options label': 'Change the active invite option.',
|
|
97
97
|
'reset in progress label': 'Resetting...',
|
|
98
98
|
'confirm label': 'Confirm',
|
|
99
99
|
'reset storage input label':
|
|
100
|
-
'This will
|
|
100
|
+
'WARNING: This will delete all data on this device. Type {{confirmationValue}} to continue.',
|
|
101
101
|
'join new identity input label':
|
|
102
|
-
'
|
|
102
|
+
'WARNING: To join an existing device all data on this device will be deleted. Type {{confirmationValue}} to continue.',
|
|
103
103
|
'failed to reset identity message': 'Failed to reset identity.',
|
|
104
|
-
'confirmation value': '
|
|
104
|
+
'confirmation value': 'RESET',
|
|
105
|
+
'confirmation placeholder': 'Enter {{confirmationValue}} to continue.',
|
|
105
106
|
'sign out chooser title': 'Danger zone',
|
|
106
107
|
'sign out chooser message': 'Proceeding with the action below will erase all data on this device.',
|
|
107
108
|
'join new identity label': 'Join a new identity',
|
|
@@ -111,7 +112,7 @@ export const os = {
|
|
|
111
112
|
'clear label': 'Use default',
|
|
112
113
|
'select emoji label': 'Choose an emoji to use in your avatar',
|
|
113
114
|
'select hue label': 'Choose a hue to use in your avatar',
|
|
114
|
-
'resetting message': 'One moment while
|
|
115
|
+
'resetting message': 'One moment while the device is reset…',
|
|
115
116
|
'red label': 'Red',
|
|
116
117
|
'orange label': 'Orange',
|
|
117
118
|
'amber label': 'Amber',
|
|
@@ -142,4 +143,5 @@ export const os = {
|
|
|
142
143
|
'create agent label': 'Start an agent',
|
|
143
144
|
'destroy agent label': 'Shut down agent',
|
|
144
145
|
'agent device label': 'Your agent',
|
|
146
|
+
'shell fallback title': 'Shell failed to connect',
|
|
145
147
|
};
|