@dxos/plugin-client 0.8.4-main.2e9d522 → 0.8.4-main.3c1ae3b
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/lib/browser/{app-graph-builder-JNIES5L4.mjs → app-graph-builder-7LBCMPIW.mjs} +26 -25
- package/dist/lib/browser/app-graph-builder-7LBCMPIW.mjs.map +7 -0
- package/dist/lib/browser/chunk-4LRO3Y2O.mjs +19 -0
- package/dist/lib/browser/chunk-4LRO3Y2O.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SV3MHIKI.mjs → chunk-HZSIIWH5.mjs} +76 -82
- package/dist/lib/browser/chunk-HZSIIWH5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-RMHBOY3Y.mjs → chunk-RDIG75CA.mjs} +3 -3
- package/dist/lib/browser/chunk-RDIG75CA.mjs.map +7 -0
- package/dist/lib/browser/chunk-UZTC5O5A.mjs +17 -0
- package/dist/lib/browser/chunk-UZTC5O5A.mjs.map +7 -0
- package/dist/lib/browser/chunk-ZRVMXLDR.mjs +15 -0
- package/dist/lib/browser/chunk-ZRVMXLDR.mjs.map +7 -0
- package/dist/lib/browser/{client-SKVKXPLY.mjs → client-KIPUUVWJ.mjs} +14 -8
- package/dist/lib/browser/client-KIPUUVWJ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +23 -19
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/{intent-resolver-LNPLD5CA.mjs → intent-resolver-N4J2B5KF.mjs} +18 -18
- package/dist/lib/browser/intent-resolver-N4J2B5KF.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{migrations-D76RCG72.mjs → migrations-RCNZRP3I.mjs} +6 -6
- package/dist/lib/browser/migrations-RCNZRP3I.mjs.map +7 -0
- package/dist/lib/browser/{react-context-YWVPZUMU.mjs → react-context-JYJ63L5S.mjs} +9 -8
- package/dist/lib/browser/react-context-JYJ63L5S.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-QFZTDNLS.mjs → react-surface-X6YMVGZZ.mjs} +8 -8
- package/dist/lib/browser/react-surface-X6YMVGZZ.mjs.map +7 -0
- package/dist/lib/browser/{schema-defs-HKW6VNZB.mjs → schema-defs-DKGLMWWM.mjs} +8 -8
- package/dist/lib/browser/schema-defs-DKGLMWWM.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/lib/node-esm/{app-graph-builder-SWFB4FID.mjs → app-graph-builder-4CVWKYZ6.mjs} +26 -25
- package/dist/lib/node-esm/app-graph-builder-4CVWKYZ6.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7M7VWQJW.mjs +20 -0
- package/dist/lib/node-esm/chunk-7M7VWQJW.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-DQDFIOXV.mjs +18 -0
- package/dist/lib/node-esm/chunk-DQDFIOXV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QT3EQXDU.mjs +17 -0
- package/dist/lib/node-esm/chunk-QT3EQXDU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FBYODKEL.mjs → chunk-RGCZX67B.mjs} +76 -82
- package/dist/lib/node-esm/chunk-RGCZX67B.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-5V3RCXZV.mjs → chunk-VENKFPBC.mjs} +3 -3
- package/dist/lib/node-esm/chunk-VENKFPBC.mjs.map +7 -0
- package/dist/lib/node-esm/{client-SLL6GDC2.mjs → client-W5DQW2E7.mjs} +14 -8
- package/dist/lib/node-esm/client-W5DQW2E7.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +23 -19
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/{intent-resolver-L7C6YRWV.mjs → intent-resolver-F2ZP2UQJ.mjs} +18 -18
- package/dist/lib/node-esm/intent-resolver-F2ZP2UQJ.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{migrations-YISDI7LF.mjs → migrations-TZFOPRPE.mjs} +6 -6
- package/dist/lib/node-esm/migrations-TZFOPRPE.mjs.map +7 -0
- package/dist/lib/node-esm/{react-context-EEHS4S3L.mjs → react-context-7BJGZI5D.mjs} +9 -8
- package/dist/lib/node-esm/react-context-7BJGZI5D.mjs.map +7 -0
- package/dist/lib/node-esm/{react-surface-2K6W37R4.mjs → react-surface-BWX37JGM.mjs} +8 -8
- package/dist/lib/node-esm/react-surface-BWX37JGM.mjs.map +7 -0
- package/dist/lib/node-esm/{schema-defs-5ZNI63RW.mjs → schema-defs-SLSDRMGM.mjs} +8 -8
- package/dist/lib/node-esm/schema-defs-SLSDRMGM.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +2 -2
- package/dist/types/src/ClientPlugin.d.ts +1 -1
- package/dist/types/src/ClientPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +2 -2
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/client.d.ts +1 -1
- package/dist/types/src/capabilities/client.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +10 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/migrations.d.ts +1 -1
- package/dist/types/src/capabilities/migrations.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-context.d.ts +2 -2
- package/dist/types/src/capabilities/react-context.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/schema-defs.d.ts +1 -1
- package/dist/types/src/capabilities/schema-defs.d.ts.map +1 -1
- package/dist/types/src/components/DevicesContainer.d.ts.map +1 -1
- package/dist/types/src/components/DevicesContainer.stories.d.ts +224 -5
- package/dist/types/src/components/DevicesContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/JoinDialog.d.ts +1 -1
- package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
- package/dist/types/src/components/ProfileContainer.d.ts.map +1 -1
- package/dist/types/src/components/ProfileContainer.stories.d.ts +57 -5
- package/dist/types/src/components/ProfileContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/RecoveryCodeDialog.d.ts +1 -1
- package/dist/types/src/components/RecoveryCodeDialog.d.ts.map +1 -1
- package/dist/types/src/components/RecoveryCodeDialog.stories.d.ts +59 -5
- package/dist/types/src/components/RecoveryCodeDialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/RecoveryCredentialsContainer.d.ts +1 -1
- package/dist/types/src/components/RecoveryCredentialsContainer.d.ts.map +1 -1
- package/dist/types/src/components/RecoveryCredentialsContainer.stories.d.ts +57 -5
- package/dist/types/src/components/RecoveryCredentialsContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/ResetDialog.d.ts +1 -1
- package/dist/types/src/components/ResetDialog.d.ts.map +1 -1
- package/dist/types/src/components/ResetDialog.stories.d.ts +59 -4
- package/dist/types/src/components/ResetDialog.stories.d.ts.map +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +10 -4
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -36
- package/src/ClientPlugin.ts +57 -59
- package/src/capabilities/app-graph-builder.ts +25 -23
- package/src/capabilities/capabilities.ts +4 -6
- package/src/capabilities/client.ts +6 -4
- package/src/capabilities/intent-resolver.ts +7 -6
- package/src/capabilities/migrations.ts +2 -2
- package/src/capabilities/react-context.tsx +5 -3
- package/src/capabilities/react-surface.tsx +4 -4
- package/src/capabilities/schema-defs.ts +6 -5
- package/src/components/DevicesContainer.stories.tsx +9 -11
- package/src/components/DevicesContainer.tsx +56 -69
- package/src/components/JoinDialog.tsx +5 -4
- package/src/components/ProfileContainer.stories.tsx +8 -9
- package/src/components/ProfileContainer.tsx +40 -45
- package/src/components/RecoveryCodeDialog.stories.tsx +9 -10
- package/src/components/RecoveryCodeDialog.tsx +6 -6
- package/src/components/RecoveryCredentialsContainer.stories.tsx +9 -11
- package/src/components/RecoveryCredentialsContainer.tsx +47 -51
- package/src/components/ResetDialog.stories.tsx +10 -11
- package/src/components/ResetDialog.tsx +5 -4
- package/src/events.ts +6 -6
- package/src/index.ts +4 -3
- package/src/meta.ts +6 -3
- package/src/types/schema.ts +4 -4
- package/dist/lib/browser/app-graph-builder-JNIES5L4.mjs.map +0 -7
- package/dist/lib/browser/chunk-3F2Q2RKC.mjs +0 -18
- package/dist/lib/browser/chunk-3F2Q2RKC.mjs.map +0 -7
- package/dist/lib/browser/chunk-CAF2COXW.mjs +0 -19
- package/dist/lib/browser/chunk-CAF2COXW.mjs.map +0 -7
- package/dist/lib/browser/chunk-GS3LDHYD.mjs +0 -12
- package/dist/lib/browser/chunk-GS3LDHYD.mjs.map +0 -7
- package/dist/lib/browser/chunk-RMHBOY3Y.mjs.map +0 -7
- package/dist/lib/browser/chunk-SV3MHIKI.mjs.map +0 -7
- package/dist/lib/browser/client-SKVKXPLY.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-LNPLD5CA.mjs.map +0 -7
- package/dist/lib/browser/migrations-D76RCG72.mjs.map +0 -7
- package/dist/lib/browser/react-context-YWVPZUMU.mjs.map +0 -7
- package/dist/lib/browser/react-surface-QFZTDNLS.mjs.map +0 -7
- package/dist/lib/browser/schema-defs-HKW6VNZB.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-SWFB4FID.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-5V3RCXZV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FBYODKEL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-IOGTQFLM.mjs +0 -19
- package/dist/lib/node-esm/chunk-IOGTQFLM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SZLX4BVJ.mjs +0 -14
- package/dist/lib/node-esm/chunk-SZLX4BVJ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UMO3ETDV.mjs +0 -20
- package/dist/lib/node-esm/chunk-UMO3ETDV.mjs.map +0 -7
- package/dist/lib/node-esm/client-SLL6GDC2.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-L7C6YRWV.mjs.map +0 -7
- package/dist/lib/node-esm/migrations-YISDI7LF.mjs.map +0 -7
- package/dist/lib/node-esm/react-context-EEHS4S3L.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-2K6W37R4.mjs.map +0 -7
- package/dist/lib/node-esm/schema-defs-5ZNI63RW.mjs.map +0 -7
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
6
6
|
import { QR } from 'react-qr-rounded';
|
|
7
7
|
|
|
8
|
-
import { createIntent
|
|
8
|
+
import { createIntent } from '@dxos/app-framework';
|
|
9
|
+
import { useIntentDispatcher } from '@dxos/app-framework/react';
|
|
9
10
|
import { log } from '@dxos/log';
|
|
10
11
|
import { useClient, useMulticastObservable } from '@dxos/react-client';
|
|
11
12
|
import { type Device, useDevices } from '@dxos/react-client/halo';
|
|
12
13
|
import { type CancellableInvitationObservable, Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
|
|
13
14
|
import { useNetworkStatus } from '@dxos/react-client/mesh';
|
|
14
|
-
import { Button, Clipboard, IconButton, List, useId, useTranslation
|
|
15
|
+
import { Button, Clipboard, Icon, IconButton, List, useId, useTranslation } from '@dxos/react-ui';
|
|
15
16
|
import {
|
|
16
17
|
ControlFrame,
|
|
17
18
|
ControlFrameItem,
|
|
@@ -20,11 +21,10 @@ import {
|
|
|
20
21
|
ControlPage,
|
|
21
22
|
ControlSection,
|
|
22
23
|
} from '@dxos/react-ui-form';
|
|
23
|
-
import { StackItem } from '@dxos/react-ui-stack';
|
|
24
24
|
import { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from '@dxos/shell/react';
|
|
25
25
|
import { hexToEmoji } from '@dxos/util';
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import { meta } from '../meta';
|
|
28
28
|
import { ClientAction } from '../types';
|
|
29
29
|
|
|
30
30
|
export type DevicesContainerProps = {
|
|
@@ -51,70 +51,57 @@ export const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps)
|
|
|
51
51
|
|
|
52
52
|
return (
|
|
53
53
|
<Clipboard.Provider>
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
>
|
|
60
|
-
<
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
</List>
|
|
54
|
+
<ControlPage>
|
|
55
|
+
<ControlSection
|
|
56
|
+
title={t('devices verbose label', { ns: meta.id })}
|
|
57
|
+
description={t('devices description', { ns: meta.id })}
|
|
58
|
+
>
|
|
59
|
+
<ControlFrame>
|
|
60
|
+
<ControlFrameItem title={t('devices label', { ns: meta.id })}>
|
|
61
|
+
<List>
|
|
62
|
+
{devices.map((device: Device) => {
|
|
63
|
+
return (
|
|
64
|
+
<DeviceListItem key={device.deviceKey.toHex()} device={device} connectionState={connectionState} />
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
</List>
|
|
68
|
+
</ControlFrameItem>
|
|
69
|
+
{createInvitationUrl && (
|
|
70
|
+
<ControlFrameItem title='Add device'>
|
|
71
|
+
<DeviceInvitation createInvitationUrl={createInvitationUrl} />
|
|
73
72
|
</ControlFrameItem>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<
|
|
82
|
-
title={t('
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
</
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<Button
|
|
107
|
-
variant='destructive'
|
|
108
|
-
onClick={handleJoinNewIdentity}
|
|
109
|
-
data-testid='devicesContainer.joinExisting'
|
|
110
|
-
>
|
|
111
|
-
{t('join new identity label')}
|
|
112
|
-
</Button>
|
|
113
|
-
</ControlItem>
|
|
114
|
-
</ControlGroup>
|
|
115
|
-
</ControlSection>
|
|
116
|
-
</ControlPage>
|
|
117
|
-
</StackItem.Content>
|
|
73
|
+
)}
|
|
74
|
+
</ControlFrame>
|
|
75
|
+
</ControlSection>
|
|
76
|
+
<ControlSection
|
|
77
|
+
title={t('danger zone title', { ns: meta.id })}
|
|
78
|
+
description={t('danger zone description', { ns: meta.id })}
|
|
79
|
+
>
|
|
80
|
+
<ControlGroup>
|
|
81
|
+
<ControlItem title={t('reset device label')} description={t('reset device description', { ns: meta.id })}>
|
|
82
|
+
<Button variant='destructive' onClick={handleResetStorage} data-testid='devicesContainer.reset'>
|
|
83
|
+
{t('reset device label')}
|
|
84
|
+
</Button>
|
|
85
|
+
</ControlItem>
|
|
86
|
+
<ControlItem
|
|
87
|
+
title={t('recover identity label')}
|
|
88
|
+
description={t('recover identity description', { ns: meta.id })}
|
|
89
|
+
>
|
|
90
|
+
<Button variant='destructive' onClick={handleRecover} data-testid='devicesContainer.recover'>
|
|
91
|
+
{t('recover identity label')}
|
|
92
|
+
</Button>
|
|
93
|
+
</ControlItem>
|
|
94
|
+
<ControlItem
|
|
95
|
+
title={t('join new identity label')}
|
|
96
|
+
description={t('join new identity description', { ns: meta.id })}
|
|
97
|
+
>
|
|
98
|
+
<Button variant='destructive' onClick={handleJoinNewIdentity} data-testid='devicesContainer.joinExisting'>
|
|
99
|
+
{t('join new identity label')}
|
|
100
|
+
</Button>
|
|
101
|
+
</ControlItem>
|
|
102
|
+
</ControlGroup>
|
|
103
|
+
</ControlSection>
|
|
104
|
+
</ControlPage>
|
|
118
105
|
</Clipboard.Provider>
|
|
119
106
|
);
|
|
120
107
|
};
|
|
@@ -189,7 +176,7 @@ const InvitationSection = ({
|
|
|
189
176
|
onInvitationDone = () => {},
|
|
190
177
|
onInvitationCreate = () => {},
|
|
191
178
|
}: InvitationComponentProps) => {
|
|
192
|
-
const { t } = useTranslation(
|
|
179
|
+
const { t } = useTranslation(meta.id);
|
|
193
180
|
const activeView =
|
|
194
181
|
state < 0
|
|
195
182
|
? 'init'
|
|
@@ -236,7 +223,7 @@ const InvitationQR = ({ id, url, onCancel }: { id: string; url: string; onCancel
|
|
|
236
223
|
const emoji = hexToEmoji(id);
|
|
237
224
|
return (
|
|
238
225
|
<>
|
|
239
|
-
<p className='text-description'>{t('qr code description', { ns:
|
|
226
|
+
<p className='text-description'>{t('qr code description', { ns: meta.id })}</p>
|
|
240
227
|
<div role='group' className='grid grid-cols-[1fr_min-content] mlb-2 gap-2'>
|
|
241
228
|
<div role='none' className='is-full aspect-square relative text-description'>
|
|
242
229
|
<QR
|
|
@@ -4,20 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { LayoutAction, createIntent } from '@dxos/app-framework';
|
|
8
|
+
import { useIntentDispatcher } from '@dxos/app-framework/react';
|
|
8
9
|
import { ObservabilityAction } from '@dxos/plugin-observability/types';
|
|
9
10
|
import { type InvitationResult } from '@dxos/react-client/invitations';
|
|
10
11
|
import { Dialog, useTranslation } from '@dxos/react-ui';
|
|
11
12
|
import { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';
|
|
12
13
|
|
|
13
|
-
import {
|
|
14
|
+
import { meta } from '../meta';
|
|
14
15
|
import { ClientAction } from '../types';
|
|
15
16
|
|
|
16
|
-
export const JOIN_DIALOG = `${
|
|
17
|
+
export const JOIN_DIALOG = `${meta.id}/JoinDialog`;
|
|
17
18
|
|
|
18
19
|
export const JoinDialog = (props: JoinPanelProps) => {
|
|
19
20
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
20
|
-
const { t } = useTranslation(
|
|
21
|
+
const { t } = useTranslation(meta.id);
|
|
21
22
|
|
|
22
23
|
const handleCancelResetStorage = useCallback(() => dispatch(createIntent(ClientAction.ShareIdentity)), [dispatch]);
|
|
23
24
|
|
|
@@ -2,28 +2,27 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
|
|
9
7
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
10
|
-
import { withTheme
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
|
-
import { ProfileContainer } from './ProfileContainer';
|
|
13
10
|
import { translations } from '../translations';
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
import { ProfileContainer } from './ProfileContainer';
|
|
13
|
+
|
|
14
|
+
const meta = {
|
|
16
15
|
title: 'plugins/plugin-client/ProfileContainer',
|
|
17
16
|
component: ProfileContainer,
|
|
18
|
-
decorators: [withClientProvider({ createIdentity: true })
|
|
17
|
+
decorators: [withTheme, withClientProvider({ createIdentity: true })],
|
|
19
18
|
parameters: {
|
|
20
19
|
layout: 'fullscreen',
|
|
21
20
|
translations,
|
|
22
21
|
},
|
|
23
|
-
}
|
|
22
|
+
} satisfies Meta<typeof ProfileContainer>;
|
|
24
23
|
|
|
25
24
|
export default meta;
|
|
26
25
|
|
|
27
|
-
type Story = StoryObj<typeof
|
|
26
|
+
type Story = StoryObj<typeof meta>;
|
|
28
27
|
|
|
29
28
|
export const Default: Story = {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { type ChangeEvent, useCallback, useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { debounce } from '@dxos/async';
|
|
@@ -10,27 +10,37 @@ import { useClient } from '@dxos/react-client';
|
|
|
10
10
|
import { type Identity, useIdentity } from '@dxos/react-client/halo';
|
|
11
11
|
import { ButtonGroup, Clipboard, Input, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
import {
|
|
13
|
-
Form,
|
|
14
|
-
type InputComponent,
|
|
15
13
|
ControlItem,
|
|
16
14
|
ControlItemInput,
|
|
17
|
-
ControlSection,
|
|
18
15
|
ControlPage,
|
|
16
|
+
ControlSection,
|
|
17
|
+
Form,
|
|
18
|
+
type FormFieldMap,
|
|
19
19
|
} from '@dxos/react-ui-form';
|
|
20
20
|
import { EmojiPickerBlock, HuePicker } from '@dxos/react-ui-pickers';
|
|
21
|
-
import {
|
|
22
|
-
import { hexToHue, hexToEmoji } from '@dxos/util';
|
|
21
|
+
import { hexToEmoji, hexToHue } from '@dxos/util';
|
|
23
22
|
|
|
24
|
-
import {
|
|
23
|
+
import { meta } from '../meta';
|
|
24
|
+
|
|
25
|
+
// TOOD(burdon): Factor out?
|
|
26
|
+
// TODO(wittjosiah): Integrate annotations with translations.
|
|
27
|
+
const UserProfile = Schema.Struct({
|
|
28
|
+
did: Schema.String.annotations({ title: 'DID' }),
|
|
29
|
+
displayName: Schema.String.annotations({ title: 'Display name' }),
|
|
30
|
+
emoji: Schema.String.annotations({ title: 'Avatar' }),
|
|
31
|
+
hue: Schema.String.annotations({ title: 'Color' }),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
type UserProfile = Schema.Schema.Type<typeof UserProfile>;
|
|
25
35
|
|
|
26
36
|
// TODO(thure): Factor out?
|
|
27
37
|
const getDefaultHueValue = (identity: Identity | null) => hexToHue(identity?.identityKey.toHex() ?? '0');
|
|
28
|
-
const getDefaultEmojiValue = (identity: Identity | null) => hexToEmoji(identity?.identityKey.toHex() ?? '0');
|
|
29
38
|
const getHueValue = (identity: Identity | null) => identity?.profile?.data?.hue || getDefaultHueValue(identity);
|
|
39
|
+
const getDefaultEmojiValue = (identity: Identity | null) => hexToEmoji(identity?.identityKey.toHex() ?? '0');
|
|
30
40
|
const getEmojiValue = (identity: Identity | null) => identity?.profile?.data?.emoji || getDefaultEmojiValue(identity);
|
|
31
41
|
|
|
32
42
|
export const ProfileContainer = () => {
|
|
33
|
-
const { t } = useTranslation(
|
|
43
|
+
const { t } = useTranslation(meta.id);
|
|
34
44
|
const client = useClient();
|
|
35
45
|
const identity = useIdentity();
|
|
36
46
|
const [displayName, setDisplayNameDirectly] = useState(identity?.profile?.displayName ?? '');
|
|
@@ -40,7 +50,7 @@ export const ProfileContainer = () => {
|
|
|
40
50
|
const updateProfile = useMemo(
|
|
41
51
|
() =>
|
|
42
52
|
debounce(
|
|
43
|
-
(profile: Partial<
|
|
53
|
+
(profile: Partial<UserProfile>) =>
|
|
44
54
|
client.halo.updateProfile({
|
|
45
55
|
displayName: profile.displayName,
|
|
46
56
|
data: {
|
|
@@ -54,7 +64,7 @@ export const ProfileContainer = () => {
|
|
|
54
64
|
);
|
|
55
65
|
|
|
56
66
|
const handleSave = useCallback(
|
|
57
|
-
(profile:
|
|
67
|
+
(profile: UserProfile) => {
|
|
58
68
|
setDisplayNameDirectly(profile.displayName);
|
|
59
69
|
setEmojiDirectly(profile.emoji);
|
|
60
70
|
setHueDirectly(profile.hue);
|
|
@@ -65,22 +75,23 @@ export const ProfileContainer = () => {
|
|
|
65
75
|
|
|
66
76
|
const values = useMemo(
|
|
67
77
|
() => ({
|
|
78
|
+
did: identity?.did,
|
|
68
79
|
displayName,
|
|
69
80
|
emoji,
|
|
70
81
|
hue,
|
|
71
|
-
did: identity?.did,
|
|
72
82
|
}),
|
|
73
83
|
[identity, displayName, emoji, hue],
|
|
74
84
|
);
|
|
75
85
|
|
|
76
86
|
// TODO(wittjosiah): Integrate descriptions with the form schema.
|
|
77
|
-
const
|
|
87
|
+
const fieldMap = useMemo<FormFieldMap>(
|
|
78
88
|
() => ({
|
|
79
89
|
displayName: ({ type, label, getValue, onValueChange }) => {
|
|
80
90
|
const handleChange = useCallback(
|
|
81
91
|
({ target: { value } }: ChangeEvent<HTMLInputElement>) => onValueChange(type, value),
|
|
82
92
|
[onValueChange, type],
|
|
83
93
|
);
|
|
94
|
+
|
|
84
95
|
return (
|
|
85
96
|
<ControlItemInput title={label} description={t('display name description')}>
|
|
86
97
|
<Input.TextInput
|
|
@@ -98,6 +109,7 @@ export const ProfileContainer = () => {
|
|
|
98
109
|
() => onValueChange(type, getDefaultEmojiValue(identity)),
|
|
99
110
|
[onValueChange, type],
|
|
100
111
|
);
|
|
112
|
+
|
|
101
113
|
return (
|
|
102
114
|
<ControlItem title={label} description={t('icon description')}>
|
|
103
115
|
<EmojiPickerBlock
|
|
@@ -116,14 +128,12 @@ export const ProfileContainer = () => {
|
|
|
116
128
|
() => onValueChange(type, getDefaultHueValue(identity)),
|
|
117
129
|
[onValueChange, type],
|
|
118
130
|
);
|
|
131
|
+
|
|
119
132
|
return (
|
|
120
133
|
<ControlItem title={label} description={t('hue description')}>
|
|
121
|
-
<
|
|
122
|
-
value={getValue()}
|
|
123
|
-
|
|
124
|
-
onReset={handleHueReset}
|
|
125
|
-
classNames='[--hue-preview-size:1.5rem] justify-self-end'
|
|
126
|
-
/>
|
|
134
|
+
<div role='none' className='flex justify-self-end'>
|
|
135
|
+
<HuePicker value={getValue()} onChange={handleChange} onReset={handleHueReset} />
|
|
136
|
+
</div>
|
|
127
137
|
</ControlItem>
|
|
128
138
|
);
|
|
129
139
|
},
|
|
@@ -143,31 +153,16 @@ export const ProfileContainer = () => {
|
|
|
143
153
|
);
|
|
144
154
|
|
|
145
155
|
return (
|
|
146
|
-
<
|
|
147
|
-
<
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
<Form
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
outerSpacing={false}
|
|
158
|
-
/>
|
|
159
|
-
</ControlSection>
|
|
160
|
-
</Clipboard.Provider>
|
|
161
|
-
</ControlPage>
|
|
162
|
-
</StackItem.Content>
|
|
156
|
+
<ControlPage>
|
|
157
|
+
<Clipboard.Provider>
|
|
158
|
+
<ControlSection title={t('profile label')} description={t('profile description')}>
|
|
159
|
+
<Form.Root schema={UserProfile} values={values} fieldMap={fieldMap} autoSave onSave={handleSave}>
|
|
160
|
+
<Form.Content>
|
|
161
|
+
<Form.FieldSet classNames='container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content]' />
|
|
162
|
+
</Form.Content>
|
|
163
|
+
</Form.Root>
|
|
164
|
+
</ControlSection>
|
|
165
|
+
</Clipboard.Provider>
|
|
166
|
+
</ControlPage>
|
|
163
167
|
);
|
|
164
168
|
};
|
|
165
|
-
|
|
166
|
-
// TODO(wittjosiah): Integrate annotations with translations.
|
|
167
|
-
const ProfileSchema = Schema.Struct({
|
|
168
|
-
displayName: Schema.String.annotations({ title: 'Display name' }),
|
|
169
|
-
emoji: Schema.String.annotations({ title: 'Avatar' }),
|
|
170
|
-
hue: Schema.String.annotations({ title: 'Color' }),
|
|
171
|
-
did: Schema.String.annotations({ title: 'DID' }),
|
|
172
|
-
});
|
|
173
|
-
type Profile = Schema.Schema.Type<typeof ProfileSchema>;
|
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { useClient } from '@dxos/react-client';
|
|
11
9
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
12
10
|
import { AlertDialog, useAsyncEffect } from '@dxos/react-ui';
|
|
13
|
-
import { withTheme
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
12
|
|
|
15
|
-
import { RecoveryCodeDialog, type RecoveryCodeDialogProps } from './RecoveryCodeDialog';
|
|
16
13
|
import { translations } from '../translations';
|
|
17
14
|
|
|
15
|
+
import { RecoveryCodeDialog } from './RecoveryCodeDialog';
|
|
16
|
+
|
|
18
17
|
const DefaultStory = () => {
|
|
19
18
|
const client = useClient();
|
|
20
19
|
const [recoveryCode, setRecoveryCode] = useState<string>();
|
|
@@ -32,19 +31,19 @@ const DefaultStory = () => {
|
|
|
32
31
|
);
|
|
33
32
|
};
|
|
34
33
|
|
|
35
|
-
const meta
|
|
34
|
+
const meta = {
|
|
36
35
|
title: 'plugins/plugin-client/RecoveryCodeDialog',
|
|
37
|
-
component: RecoveryCodeDialog,
|
|
36
|
+
component: RecoveryCodeDialog as any,
|
|
38
37
|
render: DefaultStory,
|
|
39
|
-
decorators: [withClientProvider({ createIdentity: true })
|
|
38
|
+
decorators: [withTheme, withClientProvider({ createIdentity: true })],
|
|
40
39
|
parameters: {
|
|
41
40
|
layout: 'fullscreen',
|
|
42
41
|
translations,
|
|
43
42
|
},
|
|
44
|
-
}
|
|
43
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
45
44
|
|
|
46
45
|
export default meta;
|
|
47
46
|
|
|
48
|
-
type Story = StoryObj<
|
|
47
|
+
type Story = StoryObj<typeof meta>;
|
|
49
48
|
|
|
50
49
|
export const Default: Story = {};
|
|
@@ -6,16 +6,16 @@ import React, { useCallback, useState } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { AlertDialog, Button, Clipboard, Input, useTranslation } from '@dxos/react-ui';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { meta } from '../meta';
|
|
10
10
|
|
|
11
|
-
export const RECOVERY_CODE_DIALOG = `${
|
|
11
|
+
export const RECOVERY_CODE_DIALOG = `${meta.id}/RecoveryCodeDialog`;
|
|
12
12
|
|
|
13
13
|
export type RecoveryCodeDialogProps = {
|
|
14
14
|
code: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export const RecoveryCodeDialog = ({ code }: RecoveryCodeDialogProps) => {
|
|
18
|
-
const { t } = useTranslation(
|
|
18
|
+
const { t } = useTranslation(meta.id);
|
|
19
19
|
const [confirmation, setConfirmation] = useState(false);
|
|
20
20
|
|
|
21
21
|
const handleConfirmation = useCallback((checked: boolean) => setConfirmation(checked), []);
|
|
@@ -23,11 +23,11 @@ export const RecoveryCodeDialog = ({ code }: RecoveryCodeDialogProps) => {
|
|
|
23
23
|
return (
|
|
24
24
|
<AlertDialog.Content classNames='bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden'>
|
|
25
25
|
<AlertDialog.Title>{t('recovery code dialog title')}</AlertDialog.Title>
|
|
26
|
-
<p className='
|
|
26
|
+
<p className='plb-4'>{t('recovery code dialog description')}</p>
|
|
27
27
|
<Clipboard.Provider>
|
|
28
28
|
<Code code={code} />
|
|
29
29
|
</Clipboard.Provider>
|
|
30
|
-
<div className='flex flex-col
|
|
30
|
+
<div className='flex flex-col plb-4 gap-2'>
|
|
31
31
|
<p>{t('recovery code dialog warning 1')}</p>
|
|
32
32
|
<p>{t('recovery code dialog warning 2')}</p>
|
|
33
33
|
</div>
|
|
@@ -60,7 +60,7 @@ const Code = ({ code }: { code: string }) => {
|
|
|
60
60
|
<div className='grid grid-cols-4'>
|
|
61
61
|
{words.map((word, i) => (
|
|
62
62
|
<div key={i} className='flex items-center p-2 gap-2'>
|
|
63
|
-
<div className='
|
|
63
|
+
<div className='is-4 text-xs text-center text-subdued'>{i + 1}</div>
|
|
64
64
|
<div className='text-sm'>{word}</div>
|
|
65
65
|
</div>
|
|
66
66
|
))}
|
|
@@ -2,43 +2,41 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
|
|
9
7
|
import { IntentPlugin } from '@dxos/app-framework';
|
|
10
8
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
11
|
-
import { withTheme
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
10
|
|
|
13
|
-
import { RecoveryCredentialsContainer } from './RecoveryCredentialsContainer';
|
|
14
11
|
import { ClientPlugin } from '../ClientPlugin';
|
|
15
12
|
import { translations } from '../translations';
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
import { RecoveryCredentialsContainer } from './RecoveryCredentialsContainer';
|
|
15
|
+
|
|
16
|
+
const meta = {
|
|
18
17
|
title: 'plugins/plugin-client/RecoveryCredentialsContainer',
|
|
19
18
|
component: RecoveryCredentialsContainer,
|
|
20
19
|
decorators: [
|
|
20
|
+
withTheme,
|
|
21
21
|
withPluginManager({
|
|
22
22
|
plugins: [
|
|
23
23
|
ClientPlugin({
|
|
24
|
-
onClientInitialized: async (
|
|
24
|
+
onClientInitialized: async ({ client }) => {
|
|
25
25
|
await client.halo.createIdentity();
|
|
26
26
|
},
|
|
27
27
|
}),
|
|
28
28
|
IntentPlugin(),
|
|
29
29
|
],
|
|
30
30
|
}),
|
|
31
|
-
withTheme,
|
|
32
|
-
withLayout(),
|
|
33
31
|
],
|
|
34
32
|
parameters: {
|
|
35
33
|
layout: 'fullscreen',
|
|
36
34
|
translations,
|
|
37
35
|
},
|
|
38
|
-
}
|
|
36
|
+
} satisfies Meta<typeof RecoveryCredentialsContainer>;
|
|
39
37
|
|
|
40
38
|
export default meta;
|
|
41
39
|
|
|
42
|
-
type Story = StoryObj<typeof
|
|
40
|
+
type Story = StoryObj<typeof meta>;
|
|
43
41
|
|
|
44
42
|
export const Default: Story = {};
|