@dxos/plugin-client 0.10.0 → 0.11.1
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/ClientPlugin.mjs +65 -0
- package/dist/lib/ClientPlugin.mjs.map +1 -0
- package/dist/lib/ClientPlugin.node.mjs +904 -0
- package/dist/lib/ClientPlugin.node.mjs.map +1 -0
- package/dist/lib/ClientPlugin.workerd.mjs +10 -0
- package/dist/lib/ClientPlugin.workerd.mjs.map +1 -0
- package/dist/lib/capabilities/node.mjs +13 -0
- package/dist/lib/capabilities/node.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +23 -0
- package/dist/lib/capabilities.mjs.map +1 -0
- package/dist/lib/chunk-AccountContainer.mjs +190 -0
- package/dist/lib/chunk-AccountContainer.mjs.map +1 -0
- package/dist/lib/chunk-DevicesContainer.mjs +275 -0
- package/dist/lib/chunk-DevicesContainer.mjs.map +1 -0
- package/dist/lib/chunk-InvitationsContainer.mjs +149 -0
- package/dist/lib/chunk-InvitationsContainer.mjs.map +1 -0
- package/dist/lib/chunk-JoinDialog.mjs +35 -0
- package/dist/lib/chunk-JoinDialog.mjs.map +1 -0
- package/dist/lib/chunk-ProfileContainer.mjs +145 -0
- package/dist/lib/chunk-ProfileContainer.mjs.map +1 -0
- package/dist/lib/chunk-RecoveryCodeDialog.mjs +72 -0
- package/dist/lib/chunk-RecoveryCodeDialog.mjs.map +1 -0
- package/dist/lib/chunk-RecoveryCredentialsContainer.mjs +65 -0
- package/dist/lib/chunk-RecoveryCredentialsContainer.mjs.map +1 -0
- package/dist/lib/chunk-ResetDialog.mjs +47 -0
- package/dist/lib/chunk-ResetDialog.mjs.map +1 -0
- package/dist/lib/chunk-UsageContainer.mjs +217 -0
- package/dist/lib/chunk-UsageContainer.mjs.map +1 -0
- package/dist/lib/{neutral/account-cache-YVQKLNV2.mjs → chunk-account-cache.mjs} +10 -12
- package/dist/lib/chunk-account-cache.mjs.map +1 -0
- package/dist/lib/chunk-app-graph-builder.mjs +111 -0
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
- package/dist/lib/chunk-client.mjs +90 -0
- package/dist/lib/chunk-client.mjs.map +1 -0
- package/dist/lib/{neutral/chunk-GSKMAS3S.mjs → chunk-constants.mjs} +5 -8
- package/dist/lib/chunk-constants.mjs.map +1 -0
- package/dist/lib/chunk-create-agent.mjs +23 -0
- package/dist/lib/chunk-create-agent.mjs.map +1 -0
- package/dist/lib/chunk-create-identity.mjs +28 -0
- package/dist/lib/chunk-create-identity.mjs.map +1 -0
- package/dist/lib/chunk-create-passkey.mjs +85 -0
- package/dist/lib/chunk-create-passkey.mjs.map +1 -0
- package/dist/lib/chunk-create-recovery-code.mjs +31 -0
- package/dist/lib/chunk-create-recovery-code.mjs.map +1 -0
- package/dist/lib/chunk-hooks.mjs +29 -0
- package/dist/lib/chunk-hooks.mjs.map +1 -0
- package/dist/lib/chunk-hub-http-client.mjs +14 -0
- package/dist/lib/chunk-hub-http-client.mjs.map +1 -0
- package/dist/lib/chunk-join-identity.mjs +20 -0
- package/dist/lib/chunk-join-identity.mjs.map +1 -0
- package/dist/lib/chunk-layer-specs.mjs +107 -0
- package/dist/lib/chunk-layer-specs.mjs.map +1 -0
- package/dist/lib/{neutral/chunk-6G4KZLBG.mjs → chunk-meta.mjs} +13 -20
- package/dist/lib/chunk-meta.mjs.map +1 -0
- package/dist/lib/chunk-migrations.mjs +29 -0
- package/dist/lib/chunk-migrations.mjs.map +1 -0
- package/dist/lib/chunk-navigation-handler.mjs +71 -0
- package/dist/lib/chunk-navigation-handler.mjs.map +1 -0
- package/dist/lib/chunk-navigation-target-loader.mjs +46 -0
- package/dist/lib/chunk-navigation-target-loader.mjs.map +1 -0
- package/dist/lib/chunk-open-usage.mjs +14 -0
- package/dist/lib/chunk-open-usage.mjs.map +1 -0
- package/dist/lib/chunk-operation-handler.mjs +11 -0
- package/dist/lib/chunk-operation-handler.mjs.map +1 -0
- package/dist/lib/chunk-operations.mjs +212 -0
- package/dist/lib/chunk-operations.mjs.map +1 -0
- package/dist/lib/chunk-progress.mjs +10 -0
- package/dist/lib/chunk-progress.mjs.map +1 -0
- package/dist/lib/chunk-react-context.mjs +30 -0
- package/dist/lib/chunk-react-context.mjs.map +1 -0
- package/dist/lib/chunk-react-surface.mjs +70 -0
- package/dist/lib/chunk-react-surface.mjs.map +1 -0
- package/dist/lib/chunk-recover-identity.mjs +17 -0
- package/dist/lib/chunk-recover-identity.mjs.map +1 -0
- package/dist/lib/chunk-redeem-passkey.mjs +72 -0
- package/dist/lib/chunk-redeem-passkey.mjs.map +1 -0
- package/dist/lib/chunk-redeem-token.mjs +24 -0
- package/dist/lib/chunk-redeem-token.mjs.map +1 -0
- package/dist/lib/chunk-remote-trace-monitor.mjs +37 -0
- package/dist/lib/chunk-remote-trace-monitor.mjs.map +1 -0
- package/dist/lib/chunk-reset-storage.mjs +17 -0
- package/dist/lib/chunk-reset-storage.mjs.map +1 -0
- package/dist/lib/chunk-resolve-navigation-targets.mjs +32 -0
- package/dist/lib/chunk-resolve-navigation-targets.mjs.map +1 -0
- package/dist/lib/chunk-schema-defs.mjs +53 -0
- package/dist/lib/chunk-schema-defs.mjs.map +1 -0
- package/dist/lib/chunk-share-identity.mjs +16 -0
- package/dist/lib/chunk-share-identity.mjs.map +1 -0
- package/dist/lib/chunk-space-replication-progress.mjs +94 -0
- package/dist/lib/chunk-space-replication-progress.mjs.map +1 -0
- package/dist/lib/chunk-trace-progress.mjs +69 -0
- package/dist/lib/chunk-trace-progress.mjs.map +1 -0
- package/dist/lib/chunk-update-profile.mjs +15 -0
- package/dist/lib/chunk-update-profile.mjs.map +1 -0
- package/dist/lib/components.mjs +0 -0
- package/dist/lib/containers.mjs +15 -0
- package/dist/lib/containers.mjs.map +1 -0
- package/dist/lib/index.mjs +27 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/meta.mjs +2 -0
- package/dist/lib/operations.mjs +2 -0
- package/dist/lib/plugin.mjs +9 -0
- package/dist/lib/plugin.mjs.map +1 -0
- package/dist/lib/testing.mjs +21 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/lib/translations.mjs +111 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/lib/types.mjs +139 -0
- package/dist/lib/types.mjs.map +1 -0
- package/dist/types/src/ClientPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/account-cache.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +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/hub-http-client.d.ts +1 -1
- package/dist/types/src/capabilities/index.d.ts +6 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/layer-specs.d.ts +1 -1
- package/dist/types/src/capabilities/migrations.d.ts +1 -1
- package/dist/types/src/capabilities/navigation-handler/navigation-handler.d.ts +3 -1
- package/dist/types/src/capabilities/navigation-handler/navigation-handler.d.ts.map +1 -1
- package/dist/types/src/capabilities/navigation-target-loader.d.ts +11 -0
- package/dist/types/src/capabilities/navigation-target-loader.d.ts.map +1 -0
- package/dist/types/src/capabilities/node.d.ts +2 -1
- package/dist/types/src/capabilities/node.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
- package/dist/types/src/capabilities/react-context.d.ts +1 -1
- 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/remote-trace-monitor.d.ts +15 -0
- package/dist/types/src/capabilities/remote-trace-monitor.d.ts.map +1 -0
- package/dist/types/src/capabilities/schema-defs.d.ts +1 -1
- package/dist/types/src/capabilities/space-replication-progress.d.ts +11 -0
- package/dist/types/src/capabilities/space-replication-progress.d.ts.map +1 -0
- package/dist/types/src/capabilities/trace-progress.d.ts +17 -0
- package/dist/types/src/capabilities/trace-progress.d.ts.map +1 -0
- package/dist/types/src/commands/account/login/login.d.ts +2 -1
- package/dist/types/src/commands/account/login/login.d.ts.map +1 -1
- package/dist/types/src/commands/account/logout/logout.d.ts +1 -1
- package/dist/types/src/commands/account/logout/logout.d.ts.map +1 -1
- package/dist/types/src/commands/halo/index.d.ts.map +1 -1
- package/dist/types/src/commands/halo/share/share.d.ts.map +1 -1
- package/dist/types/src/commands/profile/create.d.ts.map +1 -1
- package/dist/types/src/containers/AccountContainer/AccountContainer.d.ts +4 -1
- package/dist/types/src/containers/AccountContainer/AccountContainer.d.ts.map +1 -1
- package/dist/types/src/containers/AccountContainer/AccountContainer.stories.d.ts +4 -1
- package/dist/types/src/containers/AccountContainer/AccountContainer.stories.d.ts.map +1 -1
- package/dist/types/src/containers/DevicesContainer/DevicesContainer.d.ts +4 -1
- package/dist/types/src/containers/DevicesContainer/DevicesContainer.d.ts.map +1 -1
- package/dist/types/src/containers/DevicesContainer/DevicesContainer.stories.d.ts +4 -1
- package/dist/types/src/containers/DevicesContainer/DevicesContainer.stories.d.ts.map +1 -1
- package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.d.ts +4 -1
- package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.d.ts.map +1 -1
- package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.stories.d.ts +4 -1
- package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.stories.d.ts.map +1 -1
- package/dist/types/src/containers/JoinDialog/JoinDialog.d.ts +4 -1
- package/dist/types/src/containers/JoinDialog/JoinDialog.d.ts.map +1 -1
- package/dist/types/src/containers/JoinDialog/JoinDialog.stories.d.ts +4 -1
- package/dist/types/src/containers/JoinDialog/JoinDialog.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ProfileContainer/ProfileContainer.d.ts +4 -1
- package/dist/types/src/containers/ProfileContainer/ProfileContainer.d.ts.map +1 -1
- package/dist/types/src/containers/ProfileContainer/ProfileContainer.stories.d.ts +4 -1
- package/dist/types/src/containers/ProfileContainer/ProfileContainer.stories.d.ts.map +1 -1
- package/dist/types/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.d.ts +4 -1
- package/dist/types/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.d.ts.map +1 -1
- package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.d.ts +4 -1
- package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.d.ts.map +1 -1
- package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.stories.d.ts +4 -1
- package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ResetDialog/ResetDialog.d.ts +4 -1
- package/dist/types/src/containers/ResetDialog/ResetDialog.d.ts.map +1 -1
- package/dist/types/src/containers/ResetDialog/ResetDialog.stories.d.ts +4 -1
- package/dist/types/src/containers/ResetDialog/ResetDialog.stories.d.ts.map +1 -1
- package/dist/types/src/containers/UsageContainer/UsageContainer.d.ts +4 -5
- package/dist/types/src/containers/UsageContainer/UsageContainer.d.ts.map +1 -1
- package/dist/types/src/containers/UsageContainer/UsageView.d.ts +4 -7
- package/dist/types/src/containers/UsageContainer/UsageView.d.ts.map +1 -1
- package/dist/types/src/containers/UsageContainer/UsageView.stories.d.ts +4 -2
- package/dist/types/src/containers/UsageContainer/UsageView.stories.d.ts.map +1 -1
- package/dist/types/src/halo-services-layer.d.ts +19 -0
- package/dist/types/src/halo-services-layer.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/operations/definitions.d.ts +9 -1
- package/dist/types/src/operations/definitions.d.ts.map +1 -1
- package/dist/types/src/operations/errors.d.ts +109 -0
- package/dist/types/src/operations/errors.d.ts.map +1 -0
- package/dist/types/src/operations/errors.test.d.ts +2 -0
- package/dist/types/src/operations/errors.test.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +1 -0
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/operations/redeem-passkey.d.ts.map +1 -1
- package/dist/types/src/operations/resolve-navigation-targets.d.ts +5 -0
- package/dist/types/src/operations/resolve-navigation-targets.d.ts.map +1 -0
- package/dist/types/src/operations/update-profile.d.ts +5 -0
- package/dist/types/src/operations/update-profile.d.ts.map +1 -0
- package/dist/types/src/progress/index.d.ts +2 -0
- package/dist/types/src/progress/index.d.ts.map +1 -0
- package/dist/types/src/progress/progress-keys.d.ts +6 -0
- package/dist/types/src/progress/progress-keys.d.ts.map +1 -0
- package/dist/types/src/testing/initializeIdentity.d.ts +5 -1
- package/dist/types/src/testing/initializeIdentity.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +10 -1
- package/dist/types/src/types/capabilities.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +6 -0
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +60 -55
- package/src/ClientPlugin.ts +25 -2
- package/src/capabilities/app-graph-builder.ts +1 -1
- package/src/capabilities/client.ts +26 -0
- package/src/capabilities/index.ts +10 -0
- package/src/capabilities/layer-specs.ts +64 -2
- package/src/capabilities/migrations.ts +9 -1
- package/src/capabilities/navigation-handler/navigation-handler.ts +20 -3
- package/src/capabilities/navigation-target-loader.ts +70 -0
- package/src/capabilities/react-context.tsx +20 -2
- package/src/capabilities/{react-surface.tsx → react-surface.ts} +14 -12
- package/src/capabilities/remote-trace-monitor.ts +62 -0
- package/src/capabilities/space-replication-progress.ts +143 -0
- package/src/capabilities/trace-progress.ts +84 -0
- package/src/commands/account/login/login.ts +48 -6
- package/src/commands/account/logout/logout.ts +4 -0
- package/src/commands/halo/index.ts +6 -2
- package/src/commands/halo/share/share.ts +16 -5
- package/src/commands/profile/create.ts +23 -40
- package/src/containers/AccountContainer/AccountContainer.tsx +6 -5
- package/src/containers/DevicesContainer/DevicesContainer.tsx +2 -0
- package/src/containers/InvitationsContainer/InvitationsContainer.tsx +2 -0
- package/src/containers/JoinDialog/JoinDialog.tsx +2 -0
- package/src/containers/ProfileContainer/ProfileContainer.tsx +19 -13
- package/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.tsx +2 -0
- package/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.tsx +7 -9
- package/src/containers/ResetDialog/ResetDialog.tsx +2 -0
- package/src/containers/UsageContainer/UsageContainer.tsx +10 -1
- package/src/containers/UsageContainer/UsageView.stories.tsx +0 -12
- package/src/containers/UsageContainer/UsageView.tsx +9 -10
- package/src/halo-services-layer.ts +29 -0
- package/src/index.ts +9 -0
- package/src/operations/definitions.ts +9 -1
- package/src/operations/errors.test.ts +27 -0
- package/src/operations/errors.ts +47 -0
- package/src/operations/index.ts +3 -0
- package/src/operations/open-usage.ts +3 -3
- package/src/operations/redeem-passkey.ts +85 -55
- package/src/operations/resolve-navigation-targets.ts +71 -0
- package/src/operations/share-identity.ts +3 -3
- package/src/operations/update-profile.ts +20 -0
- package/src/progress/index.ts +5 -0
- package/src/progress/progress-keys.ts +15 -0
- package/src/testing/initializeIdentity.ts +10 -2
- package/src/translations.ts +2 -0
- package/src/types/capabilities.ts +15 -1
- package/src/types/schema.ts +7 -0
- package/dist/lib/neutral/AccountContainer-7SF53UON.mjs +0 -186
- package/dist/lib/neutral/AccountContainer-7SF53UON.mjs.map +0 -7
- package/dist/lib/neutral/ClientPlugin.mjs +0 -72
- package/dist/lib/neutral/ClientPlugin.mjs.map +0 -7
- package/dist/lib/neutral/ClientPlugin.node.mjs +0 -1156
- package/dist/lib/neutral/ClientPlugin.node.mjs.map +0 -7
- package/dist/lib/neutral/ClientPlugin.workerd.mjs +0 -16
- package/dist/lib/neutral/ClientPlugin.workerd.mjs.map +0 -7
- package/dist/lib/neutral/DevicesContainer-PRWIN36N.mjs +0 -271
- package/dist/lib/neutral/DevicesContainer-PRWIN36N.mjs.map +0 -7
- package/dist/lib/neutral/InvitationsContainer-BI5RAWET.mjs +0 -143
- package/dist/lib/neutral/InvitationsContainer-BI5RAWET.mjs.map +0 -7
- package/dist/lib/neutral/JoinDialog-4BWV4CYB.mjs +0 -53
- package/dist/lib/neutral/JoinDialog-4BWV4CYB.mjs.map +0 -7
- package/dist/lib/neutral/ProfileContainer-YEAYOTX5.mjs +0 -169
- package/dist/lib/neutral/ProfileContainer-YEAYOTX5.mjs.map +0 -7
- package/dist/lib/neutral/RecoveryCodeDialog-7EPNKCLB.mjs +0 -59
- package/dist/lib/neutral/RecoveryCodeDialog-7EPNKCLB.mjs.map +0 -7
- package/dist/lib/neutral/RecoveryCredentialsContainer-6BZ2IWX7.mjs +0 -60
- package/dist/lib/neutral/RecoveryCredentialsContainer-6BZ2IWX7.mjs.map +0 -7
- package/dist/lib/neutral/ResetDialog-KUWX45JY.mjs +0 -57
- package/dist/lib/neutral/ResetDialog-KUWX45JY.mjs.map +0 -7
- package/dist/lib/neutral/UsageContainer-2DWCVVE4.mjs +0 -241
- package/dist/lib/neutral/UsageContainer-2DWCVVE4.mjs.map +0 -7
- package/dist/lib/neutral/account-cache-YVQKLNV2.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-RVXTD6OE.mjs +0 -159
- package/dist/lib/neutral/app-graph-builder-RVXTD6OE.mjs.map +0 -7
- package/dist/lib/neutral/capabilities/index.mjs +0 -34
- package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
- package/dist/lib/neutral/capabilities/node.mjs +0 -21
- package/dist/lib/neutral/capabilities/node.mjs.map +0 -7
- package/dist/lib/neutral/chunk-6G4KZLBG.mjs.map +0 -7
- package/dist/lib/neutral/chunk-7DEIKHB7.mjs +0 -199
- package/dist/lib/neutral/chunk-7DEIKHB7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-A7WDDIWY.mjs +0 -162
- package/dist/lib/neutral/chunk-A7WDDIWY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GSKMAS3S.mjs.map +0 -7
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-JY35S2CN.mjs +0 -27
- package/dist/lib/neutral/chunk-JY35S2CN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ZFABGG2E.mjs +0 -8
- package/dist/lib/neutral/chunk-ZFABGG2E.mjs.map +0 -7
- package/dist/lib/neutral/client-7I5Y5SOA.mjs +0 -62
- package/dist/lib/neutral/client-7I5Y5SOA.mjs.map +0 -7
- package/dist/lib/neutral/components/index.mjs +0 -1
- package/dist/lib/neutral/components/index.mjs.map +0 -7
- package/dist/lib/neutral/containers/index.mjs +0 -25
- package/dist/lib/neutral/containers/index.mjs.map +0 -7
- package/dist/lib/neutral/create-agent-6UKJMZS5.mjs +0 -26
- package/dist/lib/neutral/create-agent-6UKJMZS5.mjs.map +0 -7
- package/dist/lib/neutral/create-identity-ULCRB3YH.mjs +0 -42
- package/dist/lib/neutral/create-identity-ULCRB3YH.mjs.map +0 -7
- package/dist/lib/neutral/create-passkey-I7VDS3AC.mjs +0 -81
- package/dist/lib/neutral/create-passkey-I7VDS3AC.mjs.map +0 -7
- package/dist/lib/neutral/create-recovery-code-DH2B6EGP.mjs +0 -36
- package/dist/lib/neutral/create-recovery-code-DH2B6EGP.mjs.map +0 -7
- package/dist/lib/neutral/hub-http-client-WOJUCDKV.mjs +0 -19
- package/dist/lib/neutral/hub-http-client-WOJUCDKV.mjs.map +0 -7
- package/dist/lib/neutral/index.mjs +0 -25
- package/dist/lib/neutral/index.mjs.map +0 -7
- package/dist/lib/neutral/join-identity-PJCHDNLH.mjs +0 -27
- package/dist/lib/neutral/join-identity-PJCHDNLH.mjs.map +0 -7
- package/dist/lib/neutral/layer-specs-YI7BVWKZ.mjs +0 -59
- package/dist/lib/neutral/layer-specs-YI7BVWKZ.mjs.map +0 -7
- package/dist/lib/neutral/meta.json +0 -1
- package/dist/lib/neutral/meta.mjs +0 -8
- package/dist/lib/neutral/meta.mjs.map +0 -7
- package/dist/lib/neutral/migrations-7FTW55ER.mjs +0 -23
- package/dist/lib/neutral/migrations-7FTW55ER.mjs.map +0 -7
- package/dist/lib/neutral/navigation-handler-MQ6MZXLX.mjs +0 -46
- package/dist/lib/neutral/navigation-handler-MQ6MZXLX.mjs.map +0 -7
- package/dist/lib/neutral/open-usage-OJVTPGOY.mjs +0 -27
- package/dist/lib/neutral/open-usage-OJVTPGOY.mjs.map +0 -7
- package/dist/lib/neutral/operation-handler-E3HB7E2T.mjs +0 -13
- package/dist/lib/neutral/operation-handler-E3HB7E2T.mjs.map +0 -7
- package/dist/lib/neutral/operations/index.mjs +0 -12
- package/dist/lib/neutral/operations/index.mjs.map +0 -7
- package/dist/lib/neutral/plugin.mjs +0 -17
- package/dist/lib/neutral/plugin.mjs.map +0 -7
- package/dist/lib/neutral/react-context-V74T6JOJ.mjs +0 -23
- package/dist/lib/neutral/react-context-V74T6JOJ.mjs.map +0 -7
- package/dist/lib/neutral/react-surface-HPXRA65U.mjs +0 -75
- package/dist/lib/neutral/react-surface-HPXRA65U.mjs.map +0 -7
- package/dist/lib/neutral/recover-identity-B7YM2BR4.mjs +0 -26
- package/dist/lib/neutral/recover-identity-B7YM2BR4.mjs.map +0 -7
- package/dist/lib/neutral/redeem-passkey-TYP4XLHO.mjs +0 -66
- package/dist/lib/neutral/redeem-passkey-TYP4XLHO.mjs.map +0 -7
- package/dist/lib/neutral/redeem-token-2J33R3PV.mjs +0 -29
- package/dist/lib/neutral/redeem-token-2J33R3PV.mjs.map +0 -7
- package/dist/lib/neutral/reset-storage-K47HZTGP.mjs +0 -26
- package/dist/lib/neutral/reset-storage-K47HZTGP.mjs.map +0 -7
- package/dist/lib/neutral/schema-defs-IHBCKTMM.mjs +0 -51
- package/dist/lib/neutral/schema-defs-IHBCKTMM.mjs.map +0 -7
- package/dist/lib/neutral/share-identity-TOROBLWL.mjs +0 -31
- package/dist/lib/neutral/share-identity-TOROBLWL.mjs.map +0 -7
- package/dist/lib/neutral/testing/index.mjs +0 -25
- package/dist/lib/neutral/testing/index.mjs.map +0 -7
- package/dist/lib/neutral/translations.mjs +0 -124
- package/dist/lib/neutral/translations.mjs.map +0 -7
- package/dist/lib/neutral/types/index.mjs +0 -16
- package/dist/lib/neutral/types/index.mjs.map +0 -7
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { hexToEmoji } from "@dxos/util";
|
|
2
|
+
import { meta } from "#meta";
|
|
3
|
+
import { ClientOperation } from "#operations";
|
|
4
|
+
import { log } from "@dxos/log";
|
|
5
|
+
import { useCallback, useEffect, useState } from "react";
|
|
6
|
+
import { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from "@dxos/shell/react";
|
|
7
|
+
import { useOperationInvoker } from "@dxos/app-framework/ui";
|
|
8
|
+
import { useClient, useMulticastObservable } from "@dxos/react-client";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { Button, Clipboard, Icon, IconButton, useId, useTranslation } from "@dxos/react-ui";
|
|
11
|
+
import { Form } from "@dxos/react-ui-form";
|
|
12
|
+
import { useDevices } from "@dxos/react-client/halo";
|
|
13
|
+
import { QR } from "react-qr-rounded";
|
|
14
|
+
import { Invitation, InvitationEncoder } from "@dxos/react-client/invitations";
|
|
15
|
+
import { useNetworkStatus } from "@dxos/react-client/mesh";
|
|
16
|
+
import { Listbox } from "@dxos/react-ui-list";
|
|
17
|
+
import { osTranslations } from "@dxos/ui-theme";
|
|
18
|
+
//#region src/containers/DevicesContainer/DevicesContainer.tsx
|
|
19
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-client/src/containers/DevicesContainer/DevicesContainer.tsx";
|
|
20
|
+
var DevicesContainer = ({ createInvitationUrl }) => {
|
|
21
|
+
const { t } = useTranslation(meta.profile.key);
|
|
22
|
+
const { invokePromise } = useOperationInvoker();
|
|
23
|
+
const devices = useDevices();
|
|
24
|
+
const { swarm: connectionState } = useNetworkStatus();
|
|
25
|
+
const handleResetStorage = useCallback(() => invokePromise(ClientOperation.ResetStorage, {}), [invokePromise]);
|
|
26
|
+
const handleRecover = useCallback(() => invokePromise(ClientOperation.ResetStorage, { mode: "recover" }), [invokePromise]);
|
|
27
|
+
const handleJoinNewIdentity = useCallback(() => invokePromise(ClientOperation.ResetStorage, { mode: "join-new-identity" }), [invokePromise]);
|
|
28
|
+
return /* @__PURE__ */ jsx(Clipboard.Provider, { children: /* @__PURE__ */ jsx(Form.Root, {
|
|
29
|
+
variant: "settings",
|
|
30
|
+
children: /* @__PURE__ */ jsx(Form.Viewport, {
|
|
31
|
+
scroll: true,
|
|
32
|
+
children: /* @__PURE__ */ jsxs(Form.Content, { children: [/* @__PURE__ */ jsx(Form.Section, {
|
|
33
|
+
title: t("devices-verbose.label", { ns: meta.profile.key }),
|
|
34
|
+
description: t("devices.description", { ns: meta.profile.key }),
|
|
35
|
+
children: /* @__PURE__ */ jsxs(Form.Group, { children: [/* @__PURE__ */ jsxs("div", {
|
|
36
|
+
role: "group",
|
|
37
|
+
className: "min-w-0",
|
|
38
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
39
|
+
className: "text-lg mb-2",
|
|
40
|
+
children: t("devices.label", { ns: meta.profile.key })
|
|
41
|
+
}), /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
|
|
42
|
+
"aria-label": t("devices.label", { ns: meta.profile.key }),
|
|
43
|
+
children: devices.map((device) => /* @__PURE__ */ jsx(DeviceListItem, {
|
|
44
|
+
device,
|
|
45
|
+
connectionState
|
|
46
|
+
}, device.deviceKey.toHex()))
|
|
47
|
+
}) })]
|
|
48
|
+
}), createInvitationUrl && /* @__PURE__ */ jsxs("div", {
|
|
49
|
+
role: "group",
|
|
50
|
+
className: "min-w-0",
|
|
51
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
52
|
+
className: "text-lg mb-2",
|
|
53
|
+
children: t("add-device.label")
|
|
54
|
+
}), /* @__PURE__ */ jsx(DeviceInvitation, { createInvitationUrl })]
|
|
55
|
+
})] })
|
|
56
|
+
}), /* @__PURE__ */ jsxs(Form.Section, {
|
|
57
|
+
title: t("danger-zone.title", { ns: meta.profile.key }),
|
|
58
|
+
description: t("danger-zone.description", { ns: meta.profile.key }),
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsx(Form.Row, {
|
|
61
|
+
label: t("reset-device.label"),
|
|
62
|
+
description: t("reset-device.description", { ns: meta.profile.key }),
|
|
63
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
64
|
+
variant: "destructive",
|
|
65
|
+
onClick: handleResetStorage,
|
|
66
|
+
"data-testid": "devicesContainer.reset",
|
|
67
|
+
children: t("reset-device.label")
|
|
68
|
+
})
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ jsx(Form.Row, {
|
|
71
|
+
label: t("recover-identity.label"),
|
|
72
|
+
description: t("recover-identity.description", { ns: meta.profile.key }),
|
|
73
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
74
|
+
variant: "destructive",
|
|
75
|
+
onClick: handleRecover,
|
|
76
|
+
"data-testid": "devicesContainer.recover",
|
|
77
|
+
children: t("recover-identity.label")
|
|
78
|
+
})
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ jsx(Form.Row, {
|
|
81
|
+
label: t("join-new-identity.label"),
|
|
82
|
+
description: t("join-new-identity.description", { ns: meta.profile.key }),
|
|
83
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
84
|
+
variant: "destructive",
|
|
85
|
+
onClick: handleJoinNewIdentity,
|
|
86
|
+
"data-testid": "devicesContainer.joinExisting",
|
|
87
|
+
children: t("join-new-identity.label")
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
})] })
|
|
92
|
+
})
|
|
93
|
+
}) });
|
|
94
|
+
};
|
|
95
|
+
var DeviceInvitation = (props) => {
|
|
96
|
+
const client = useClient();
|
|
97
|
+
const [invitation, setInvitation] = useState();
|
|
98
|
+
const onInvitationCreate = useCallback(() => {
|
|
99
|
+
const invitation = client.halo.share();
|
|
100
|
+
if (client.config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
|
|
101
|
+
const subscription = invitation.subscribe((invitation) => {
|
|
102
|
+
const invitationCode = InvitationEncoder.encode(invitation);
|
|
103
|
+
if (invitation.state === Invitation.State.CONNECTING) {
|
|
104
|
+
log.info(JSON.stringify({
|
|
105
|
+
invitationCode,
|
|
106
|
+
authCode: invitation.authCode
|
|
107
|
+
}), void 0, {
|
|
108
|
+
"~LogMeta": "~LogMeta",
|
|
109
|
+
F: __dxlog_file,
|
|
110
|
+
L: 135,
|
|
111
|
+
S: void 0
|
|
112
|
+
});
|
|
113
|
+
subscription.unsubscribe();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
setInvitation(invitation);
|
|
118
|
+
}, [client]);
|
|
119
|
+
const onInvitationDone = useCallback(() => {
|
|
120
|
+
setInvitation(void 0);
|
|
121
|
+
}, []);
|
|
122
|
+
if (invitation) return /* @__PURE__ */ jsx(DeviceInvitationImpl, {
|
|
123
|
+
...props,
|
|
124
|
+
invitation,
|
|
125
|
+
onInvitationCreate,
|
|
126
|
+
onInvitationDone
|
|
127
|
+
});
|
|
128
|
+
else return /* @__PURE__ */ jsx(InvitationSection, {
|
|
129
|
+
...props,
|
|
130
|
+
onInvitationCreate,
|
|
131
|
+
onInvitationDone
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
var DeviceInvitationImpl = ({ invitation: invitationObservable, createInvitationUrl, onInvitationDone, onInvitationCreate }) => {
|
|
135
|
+
const invitation = useMulticastObservable(invitationObservable);
|
|
136
|
+
const url = createInvitationUrl(InvitationEncoder.encode(invitation));
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (invitation.state >= Invitation.State.SUCCESS) onInvitationDone();
|
|
139
|
+
}, [invitation.state]);
|
|
140
|
+
return /* @__PURE__ */ jsx(InvitationSection, {
|
|
141
|
+
...invitation,
|
|
142
|
+
url,
|
|
143
|
+
onInvitationDone,
|
|
144
|
+
onInvitationCreate
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
var InvitationSection = ({ state = -1, authCode, invitationId = "never", url = "never", onInvitationDone = () => {}, onInvitationCreate = () => {} }) => {
|
|
148
|
+
const { t } = useTranslation(meta.profile.key);
|
|
149
|
+
const activeView = state < 0 ? "init" : state >= Invitation.State.CANCELLED ? "complete" : state >= Invitation.State.READY_FOR_AUTHENTICATION && authCode ? "auth-code" : "qr-code";
|
|
150
|
+
return activeView === "init" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
|
|
151
|
+
className: "text-description mb-2",
|
|
152
|
+
children: t("add-device.description")
|
|
153
|
+
}), /* @__PURE__ */ jsx(IconButton, {
|
|
154
|
+
icon: "ph--plus--regular",
|
|
155
|
+
label: t("create-device-invitation.label"),
|
|
156
|
+
disabled: state >= 0,
|
|
157
|
+
classNames: "w-full",
|
|
158
|
+
"data-testid": "devicesContainer.createInvitation",
|
|
159
|
+
onClick: onInvitationCreate
|
|
160
|
+
})] }) : /* @__PURE__ */ jsx(Viewport.Root, {
|
|
161
|
+
activeView,
|
|
162
|
+
children: /* @__PURE__ */ jsxs(Viewport.Views, { children: [
|
|
163
|
+
/* @__PURE__ */ jsx(Viewport.View, { id: "init" }),
|
|
164
|
+
/* @__PURE__ */ jsx(Viewport.View, {
|
|
165
|
+
id: "complete",
|
|
166
|
+
children: /* @__PURE__ */ jsx(InvitationComplete, { statusValue: state })
|
|
167
|
+
}),
|
|
168
|
+
/* @__PURE__ */ jsx(Viewport.View, {
|
|
169
|
+
id: "auth-code",
|
|
170
|
+
children: /* @__PURE__ */ jsx(InvitationAuthCode, {
|
|
171
|
+
id: invitationId,
|
|
172
|
+
code: authCode ?? "never",
|
|
173
|
+
onCancel: onInvitationDone
|
|
174
|
+
})
|
|
175
|
+
}),
|
|
176
|
+
/* @__PURE__ */ jsx(Viewport.View, {
|
|
177
|
+
id: "qr-code",
|
|
178
|
+
children: /* @__PURE__ */ jsx(InvitationQR, {
|
|
179
|
+
id: invitationId,
|
|
180
|
+
url,
|
|
181
|
+
onCancel: onInvitationDone
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
] })
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
var InvitationQR = ({ id, url, onCancel }) => {
|
|
188
|
+
const { t } = useTranslation(osTranslations);
|
|
189
|
+
const qrLabel = useId("devices-container__qr-code");
|
|
190
|
+
const emoji = hexToEmoji(id);
|
|
191
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
192
|
+
/* @__PURE__ */ jsx("p", {
|
|
193
|
+
className: "text-description",
|
|
194
|
+
children: t("qr-code.description", { ns: meta.profile.key })
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ jsxs("div", {
|
|
197
|
+
role: "group",
|
|
198
|
+
className: "grid grid-cols-[1fr_min-content]",
|
|
199
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
200
|
+
className: "flex justify-center py-4",
|
|
201
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
202
|
+
className: "w-full md:max-w-80 aspect-square relative text-description",
|
|
203
|
+
children: [/* @__PURE__ */ jsx(QR, {
|
|
204
|
+
rounding: 100,
|
|
205
|
+
backgroundColor: "transparent",
|
|
206
|
+
color: "currentColor",
|
|
207
|
+
"aria-labelledby": qrLabel,
|
|
208
|
+
errorCorrectionLevel: "Q",
|
|
209
|
+
cutout: true,
|
|
210
|
+
children: url ?? "never"
|
|
211
|
+
}), /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(Emoji, { text: emoji }) })]
|
|
212
|
+
})
|
|
213
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
214
|
+
id: qrLabel,
|
|
215
|
+
className: "sr-only",
|
|
216
|
+
children: t("qr.label")
|
|
217
|
+
})]
|
|
218
|
+
}),
|
|
219
|
+
/* @__PURE__ */ jsx("div", {
|
|
220
|
+
className: "flex justify-center",
|
|
221
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
222
|
+
className: "flex gap-2",
|
|
223
|
+
children: [/* @__PURE__ */ jsx(Clipboard.Button, { value: url ?? "never" }), /* @__PURE__ */ jsx(Button, {
|
|
224
|
+
variant: "ghost",
|
|
225
|
+
onClick: onCancel,
|
|
226
|
+
children: t("cancel.label")
|
|
227
|
+
})]
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
] });
|
|
231
|
+
};
|
|
232
|
+
var InvitationAuthCode = ({ id, code, onCancel }) => {
|
|
233
|
+
const { t } = useTranslation(osTranslations);
|
|
234
|
+
const emoji = hexToEmoji(id);
|
|
235
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
236
|
+
/* @__PURE__ */ jsx("p", {
|
|
237
|
+
className: "text-description",
|
|
238
|
+
children: t("auth-other-device-emoji.message")
|
|
239
|
+
}),
|
|
240
|
+
emoji && /* @__PURE__ */ jsx(Emoji, {
|
|
241
|
+
text: emoji,
|
|
242
|
+
className: "mx-auto my-2 text-center"
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ jsx("p", {
|
|
245
|
+
className: "text-description",
|
|
246
|
+
children: t("auth-code.message")
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ jsx(AuthCode, {
|
|
249
|
+
code,
|
|
250
|
+
large: true,
|
|
251
|
+
classNames: "mx-auto my-2 text-center grow"
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ jsx(Button, {
|
|
254
|
+
variant: "ghost",
|
|
255
|
+
onClick: onCancel,
|
|
256
|
+
children: t("cancel.label")
|
|
257
|
+
})
|
|
258
|
+
] });
|
|
259
|
+
};
|
|
260
|
+
var InvitationComplete = ({ statusValue }) => {
|
|
261
|
+
return statusValue > 0 ? /* @__PURE__ */ jsx(Icon, {
|
|
262
|
+
icon: "ph--check--regular",
|
|
263
|
+
size: 6,
|
|
264
|
+
classNames: "m-1.5"
|
|
265
|
+
}) : /* @__PURE__ */ jsx(Icon, {
|
|
266
|
+
icon: "ph--x--regular",
|
|
267
|
+
size: 6,
|
|
268
|
+
classNames: "m-1.5"
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
DevicesContainer.displayName = "DevicesContainer";
|
|
272
|
+
//#endregion
|
|
273
|
+
export { DevicesContainer as default };
|
|
274
|
+
|
|
275
|
+
//# sourceMappingURL=chunk-DevicesContainer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-DevicesContainer.mjs","names":[],"sources":["../../src/containers/DevicesContainer/DevicesContainer.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { QR } from 'react-qr-rounded';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { log } from '@dxos/log';\nimport { useClient, useMulticastObservable } from '@dxos/react-client';\nimport { type Device, useDevices } from '@dxos/react-client/halo';\nimport { type CancellableInvitationObservable, Invitation, InvitationEncoder } from '@dxos/react-client/invitations';\nimport { useNetworkStatus } from '@dxos/react-client/mesh';\nimport { Button, Clipboard, Icon, IconButton, useId, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\nimport { Listbox } from '@dxos/react-ui-list';\nimport { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from '@dxos/shell/react';\nimport { osTranslations } from '@dxos/ui-theme';\nimport { hexToEmoji } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { ClientOperation } from '#operations';\n\nexport type DevicesContainerProps = {\n createInvitationUrl?: (invitationCode: string) => string;\n};\n\nexport const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps) => {\n const { t } = useTranslation(meta.profile.key);\n const { invokePromise } = useOperationInvoker();\n const devices = useDevices();\n const { swarm: connectionState } = useNetworkStatus();\n\n const handleResetStorage = useCallback(() => invokePromise(ClientOperation.ResetStorage, {}), [invokePromise]);\n\n const handleRecover = useCallback(\n () => invokePromise(ClientOperation.ResetStorage, { mode: 'recover' }),\n [invokePromise],\n );\n\n const handleJoinNewIdentity = useCallback(\n () => invokePromise(ClientOperation.ResetStorage, { mode: 'join-new-identity' }),\n [invokePromise],\n );\n\n return (\n <Clipboard.Provider>\n <Form.Root variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section\n title={t('devices-verbose.label', { ns: meta.profile.key })}\n description={t('devices.description', { ns: meta.profile.key })}\n >\n <Form.Group>\n <div role='group' className='min-w-0'>\n <h3 className='text-lg mb-2'>{t('devices.label', { ns: meta.profile.key })}</h3>\n <Listbox.Root>\n <Listbox.Content aria-label={t('devices.label', { ns: meta.profile.key })}>\n {devices.map((device: Device) => (\n <DeviceListItem\n key={device.deviceKey.toHex()}\n device={device}\n connectionState={connectionState}\n />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </div>\n {createInvitationUrl && (\n <div role='group' className='min-w-0'>\n <h3 className='text-lg mb-2'>{t('add-device.label')}</h3>\n <DeviceInvitation createInvitationUrl={createInvitationUrl} />\n </div>\n )}\n </Form.Group>\n </Form.Section>\n <Form.Section\n title={t('danger-zone.title', { ns: meta.profile.key })}\n description={t('danger-zone.description', { ns: meta.profile.key })}\n >\n <Form.Row\n label={t('reset-device.label')}\n description={t('reset-device.description', { ns: meta.profile.key })}\n >\n <Button variant='destructive' onClick={handleResetStorage} data-testid='devicesContainer.reset'>\n {t('reset-device.label')}\n </Button>\n </Form.Row>\n <Form.Row\n label={t('recover-identity.label')}\n description={t('recover-identity.description', { ns: meta.profile.key })}\n >\n <Button variant='destructive' onClick={handleRecover} data-testid='devicesContainer.recover'>\n {t('recover-identity.label')}\n </Button>\n </Form.Row>\n <Form.Row\n label={t('join-new-identity.label')}\n description={t('join-new-identity.description', { ns: meta.profile.key })}\n >\n <Button\n variant='destructive'\n onClick={handleJoinNewIdentity}\n data-testid='devicesContainer.joinExisting'\n >\n {t('join-new-identity.label')}\n </Button>\n </Form.Row>\n </Form.Section>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n </Clipboard.Provider>\n );\n};\n\ntype DeviceInvitationProps = {\n invitation?: CancellableInvitationObservable;\n createInvitationUrl: (invitationCode: string) => string;\n onInvitationDone: () => void;\n onInvitationCreate: () => void;\n};\n\nconst DeviceInvitation = (props: Pick<DeviceInvitationProps, 'createInvitationUrl'>) => {\n const client = useClient();\n const [invitation, setInvitation] = useState<CancellableInvitationObservable>();\n\n const onInvitationCreate = useCallback(() => {\n const invitation = client.halo.share();\n if (client.config.values.runtime?.app?.env?.DX_ENVIRONMENT !== 'production') {\n const subscription = invitation.subscribe((invitation: Invitation) => {\n const invitationCode = InvitationEncoder.encode(invitation);\n if (invitation.state === Invitation.State.CONNECTING) {\n log.info(JSON.stringify({ invitationCode, authCode: invitation.authCode }));\n subscription.unsubscribe();\n }\n });\n }\n setInvitation(invitation);\n }, [client]);\n\n const onInvitationDone = useCallback(() => {\n setInvitation(undefined);\n }, []);\n\n if (invitation) {\n return <DeviceInvitationImpl {...props} {...{ invitation, onInvitationCreate, onInvitationDone }} />;\n } else {\n return <InvitationSection {...props} {...{ onInvitationCreate, onInvitationDone }} />;\n }\n};\n\nconst DeviceInvitationImpl = ({\n invitation: invitationObservable,\n createInvitationUrl,\n onInvitationDone,\n onInvitationCreate,\n}: DeviceInvitationProps) => {\n const invitation = useMulticastObservable(invitationObservable!);\n const url = createInvitationUrl(InvitationEncoder.encode(invitation));\n\n useEffect(() => {\n if (invitation.state >= Invitation.State.SUCCESS) {\n onInvitationDone();\n }\n }, [invitation.state]);\n\n return <InvitationSection {...invitation} {...{ url, onInvitationDone, onInvitationCreate }} />;\n};\n\ntype InvitationComponentProps = Partial<\n Pick<Invitation, 'authCode' | 'invitationId'> &\n Pick<DeviceInvitationProps, 'onInvitationDone' | 'onInvitationCreate'> & {\n state: number;\n url: string;\n }\n>;\n\nconst InvitationSection = ({\n state = -1,\n authCode,\n invitationId = 'never',\n url = 'never',\n onInvitationDone = () => {},\n onInvitationCreate = () => {},\n}: InvitationComponentProps) => {\n const { t } = useTranslation(meta.profile.key);\n const activeView =\n state < 0\n ? 'init'\n : state >= Invitation.State.CANCELLED\n ? 'complete'\n : state >= Invitation.State.READY_FOR_AUTHENTICATION && authCode\n ? 'auth-code'\n : 'qr-code';\n\n return activeView === 'init' ? (\n <>\n <p className='text-description mb-2'>{t('add-device.description')}</p>\n <IconButton\n icon='ph--plus--regular'\n label={t('create-device-invitation.label')}\n disabled={state >= 0}\n classNames='w-full'\n data-testid='devicesContainer.createInvitation'\n onClick={onInvitationCreate}\n />\n </>\n ) : (\n <Viewport.Root activeView={activeView}>\n <Viewport.Views>\n <Viewport.View id='init'>\n {/* This view intentionally left blank while conditionally rendering the viewport. */}\n </Viewport.View>\n <Viewport.View id='complete'>\n <InvitationComplete statusValue={state} />\n </Viewport.View>\n <Viewport.View id='auth-code'>\n <InvitationAuthCode id={invitationId} code={authCode ?? 'never'} onCancel={onInvitationDone} />\n </Viewport.View>\n <Viewport.View id='qr-code'>\n <InvitationQR id={invitationId} url={url} onCancel={onInvitationDone} />\n </Viewport.View>\n </Viewport.Views>\n </Viewport.Root>\n );\n};\n\nconst InvitationQR = ({ id, url, onCancel }: { id: string; url: string; onCancel: () => void }) => {\n const { t } = useTranslation(osTranslations);\n const qrLabel = useId('devices-container__qr-code');\n const emoji = hexToEmoji(id);\n return (\n <>\n <p className='text-description'>{t('qr-code.description', { ns: meta.profile.key })}</p>\n <div role='group' className='grid grid-cols-[1fr_min-content]'>\n <div className='flex justify-center py-4'>\n <div className='w-full md:max-w-80 aspect-square relative text-description'>\n <QR\n rounding={100}\n backgroundColor='transparent'\n color='currentColor'\n aria-labelledby={qrLabel}\n errorCorrectionLevel='Q'\n cutout={true}\n >\n {url ?? 'never'}\n </QR>\n <Centered>\n <Emoji text={emoji} />\n </Centered>\n </div>\n </div>\n <span id={qrLabel} className='sr-only'>\n {t('qr.label')}\n </span>\n </div>\n {/* TODO(burdon): Factor out button bar */}\n <div className='flex justify-center'>\n <div className='flex gap-2'>\n <Clipboard.Button value={url ?? 'never'} />\n <Button variant='ghost' onClick={onCancel}>\n {t('cancel.label')}\n </Button>\n </div>\n </div>\n </>\n );\n};\n\nconst InvitationAuthCode = ({ id, code, onCancel }: { id: string; code: string; onCancel: () => void }) => {\n const { t } = useTranslation(osTranslations);\n const emoji = hexToEmoji(id);\n\n return (\n <>\n <p className='text-description'>{t('auth-other-device-emoji.message')}</p>\n {emoji && <Emoji text={emoji} className='mx-auto my-2 text-center' />}\n <p className='text-description'>{t('auth-code.message')}</p>\n <AuthCode code={code} large classNames='mx-auto my-2 text-center grow' />\n <Button variant='ghost' onClick={onCancel}>\n {t('cancel.label')}\n </Button>\n </>\n );\n};\n\nconst InvitationComplete = ({ statusValue }: { statusValue: number }) => {\n return statusValue > 0 ? (\n <Icon icon='ph--check--regular' size={6} classNames='m-1.5' />\n ) : (\n <Icon icon='ph--x--regular' size={6} classNames='m-1.5' />\n );\n};\n\nDevicesContainer.displayName = 'DevicesContainer';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { t as useHubHttpClient } from "./chunk-hooks.mjs";
|
|
2
|
+
import { meta } from "#meta";
|
|
3
|
+
import { ClientCapabilities } from "#types";
|
|
4
|
+
import { Context } from "@dxos/context";
|
|
5
|
+
import { useCallback, useState } from "react";
|
|
6
|
+
import { useCapability } from "@dxos/app-framework/ui";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { useAtom, useAtomSet } from "@effect-atom/atom-react";
|
|
9
|
+
import { Clipboard, Icon, IconButton, useAsyncEffect, useTranslation } from "@dxos/react-ui";
|
|
10
|
+
import { Form } from "@dxos/react-ui-form";
|
|
11
|
+
import { Listbox } from "@dxos/react-ui-list";
|
|
12
|
+
//#region src/containers/InvitationsContainer/InvitationsContainer.tsx
|
|
13
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-client/src/containers/InvitationsContainer/InvitationsContainer.tsx";
|
|
14
|
+
var InvitationsContainer = () => {
|
|
15
|
+
const { t } = useTranslation(meta.profile.key);
|
|
16
|
+
const accountCacheAtom = useCapability(ClientCapabilities.AccountCache);
|
|
17
|
+
const [cache] = useAtom(accountCacheAtom);
|
|
18
|
+
const setCache = useAtomSet(accountCacheAtom);
|
|
19
|
+
const [pending, setPending] = useState(false);
|
|
20
|
+
const hubClient = useHubHttpClient();
|
|
21
|
+
useAsyncEffect(async () => {
|
|
22
|
+
if (!hubClient) return;
|
|
23
|
+
try {
|
|
24
|
+
const result = await hubClient.listAccountInvitations(new Context(void 0, {
|
|
25
|
+
"~LogMeta": "~LogMeta",
|
|
26
|
+
F: __dxlog_file,
|
|
27
|
+
L: 35
|
|
28
|
+
}));
|
|
29
|
+
setCache((prev) => ({
|
|
30
|
+
...prev,
|
|
31
|
+
invitations: result.invitations,
|
|
32
|
+
fetchedAt: Date.now()
|
|
33
|
+
}));
|
|
34
|
+
} catch {}
|
|
35
|
+
}, [hubClient, setCache]);
|
|
36
|
+
const handleIssue = useCallback(async () => {
|
|
37
|
+
if (!hubClient) return;
|
|
38
|
+
setPending(true);
|
|
39
|
+
try {
|
|
40
|
+
const result = await hubClient.issueAccountInvitation(new Context(void 0, {
|
|
41
|
+
"~LogMeta": "~LogMeta",
|
|
42
|
+
F: __dxlog_file,
|
|
43
|
+
L: 48
|
|
44
|
+
}));
|
|
45
|
+
setCache((prev) => ({
|
|
46
|
+
...prev,
|
|
47
|
+
account: prev.account ? {
|
|
48
|
+
...prev.account,
|
|
49
|
+
invitationsRemaining: Math.max(0, prev.account.invitationsRemaining - 1)
|
|
50
|
+
} : prev.account,
|
|
51
|
+
invitations: [{
|
|
52
|
+
code: result.code,
|
|
53
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54
|
+
}, ...prev.invitations ?? []]
|
|
55
|
+
}));
|
|
56
|
+
} finally {
|
|
57
|
+
setPending(false);
|
|
58
|
+
}
|
|
59
|
+
}, [hubClient, setCache]);
|
|
60
|
+
const remaining = cache.account?.invitationsRemaining ?? 0;
|
|
61
|
+
const list = cache.invitations ?? [];
|
|
62
|
+
const available = list.filter((row) => !row.redeemedByIdentityDid);
|
|
63
|
+
const redeemed = list.filter((row) => Boolean(row.redeemedByIdentityDid));
|
|
64
|
+
return /* @__PURE__ */ jsx(Clipboard.Provider, { children: /* @__PURE__ */ jsx(Form.Root, {
|
|
65
|
+
variant: "settings",
|
|
66
|
+
children: /* @__PURE__ */ jsx(Form.Viewport, {
|
|
67
|
+
scroll: true,
|
|
68
|
+
children: /* @__PURE__ */ jsxs(Form.Content, { children: [
|
|
69
|
+
/* @__PURE__ */ jsx(Form.Section, {
|
|
70
|
+
title: t("invitations-section.title"),
|
|
71
|
+
description: t("invitations-section.description"),
|
|
72
|
+
children: /* @__PURE__ */ jsx(Form.Row, {
|
|
73
|
+
label: t("generate-invitation.label"),
|
|
74
|
+
description: t("generate-invitation.description", { count: remaining }),
|
|
75
|
+
children: /* @__PURE__ */ jsx(IconButton, {
|
|
76
|
+
icon: "ph--plus--regular",
|
|
77
|
+
label: t("generate-invitation.label"),
|
|
78
|
+
variant: "primary",
|
|
79
|
+
onClick: handleIssue,
|
|
80
|
+
disabled: pending || remaining <= 0
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
available.length > 0 ? /* @__PURE__ */ jsx(Form.Section, {
|
|
85
|
+
title: t("available-invitations.title"),
|
|
86
|
+
children: /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
|
|
87
|
+
classNames: "gap-1",
|
|
88
|
+
children: available.map((row) => /* @__PURE__ */ jsx(AvailableInvitationItem, { row }, row.code))
|
|
89
|
+
}) })
|
|
90
|
+
}) : null,
|
|
91
|
+
redeemed.length > 0 ? /* @__PURE__ */ jsx(Form.Section, {
|
|
92
|
+
title: t("redeemed-invitations.title"),
|
|
93
|
+
children: /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
|
|
94
|
+
classNames: "gap-1",
|
|
95
|
+
children: redeemed.map((row) => /* @__PURE__ */ jsx(RedeemedInvitationItem, { row }, row.code))
|
|
96
|
+
}) })
|
|
97
|
+
}) : null
|
|
98
|
+
] })
|
|
99
|
+
})
|
|
100
|
+
}) });
|
|
101
|
+
};
|
|
102
|
+
var AvailableInvitationItem = ({ row }) => /* @__PURE__ */ jsxs(Listbox.Item, {
|
|
103
|
+
id: row.code,
|
|
104
|
+
classNames: "grid grid-cols-[min-content_1fr_min-content] items-center gap-2",
|
|
105
|
+
children: [
|
|
106
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
107
|
+
icon: "ph--paper-plane-tilt--duotone",
|
|
108
|
+
size: 5,
|
|
109
|
+
classNames: "text-description"
|
|
110
|
+
}),
|
|
111
|
+
/* @__PURE__ */ jsxs("div", {
|
|
112
|
+
className: "flex flex-col min-w-0",
|
|
113
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
114
|
+
className: "font-mono truncate",
|
|
115
|
+
children: row.code
|
|
116
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
117
|
+
className: "text-description text-xs",
|
|
118
|
+
children: new Date(row.createdAt).toLocaleString()
|
|
119
|
+
})]
|
|
120
|
+
}),
|
|
121
|
+
/* @__PURE__ */ jsx(Clipboard.IconButton, { value: row.code })
|
|
122
|
+
]
|
|
123
|
+
});
|
|
124
|
+
var RedeemedInvitationItem = ({ row }) => {
|
|
125
|
+
const date = row.redeemedAt ?? row.createdAt;
|
|
126
|
+
return /* @__PURE__ */ jsxs(Listbox.Item, {
|
|
127
|
+
id: row.code,
|
|
128
|
+
classNames: "grid grid-cols-[min-content_1fr] items-center gap-2",
|
|
129
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
130
|
+
icon: "ph--check-circle--duotone",
|
|
131
|
+
size: 5,
|
|
132
|
+
classNames: "text-success-text"
|
|
133
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
134
|
+
className: "flex flex-col min-w-0",
|
|
135
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
136
|
+
className: "font-mono truncate",
|
|
137
|
+
children: row.code
|
|
138
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
139
|
+
className: "text-description text-xs",
|
|
140
|
+
children: new Date(date).toLocaleString()
|
|
141
|
+
})]
|
|
142
|
+
})]
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
InvitationsContainer.displayName = "InvitationsContainer";
|
|
146
|
+
//#endregion
|
|
147
|
+
export { InvitationsContainer as default };
|
|
148
|
+
|
|
149
|
+
//# sourceMappingURL=chunk-InvitationsContainer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-InvitationsContainer.mjs","names":[],"sources":["../../src/containers/InvitationsContainer/InvitationsContainer.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtom, useAtomSet } from '@effect-atom/atom-react';\nimport React, { useCallback, useState } from 'react';\n\nimport { useCapability } from '@dxos/app-framework/ui';\nimport { Context } from '@dxos/context';\nimport { Clipboard, Icon, IconButton, useAsyncEffect, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\nimport { Listbox } from '@dxos/react-ui-list';\n\nimport { meta } from '#meta';\nimport { type AccountCacheInvitation, ClientCapabilities } from '#types';\n\nimport { useHubHttpClient } from '../../hooks';\n\nexport const InvitationsContainer = () => {\n const { t } = useTranslation(meta.profile.key);\n const accountCacheAtom = useCapability(ClientCapabilities.AccountCache);\n const [cache] = useAtom(accountCacheAtom);\n const setCache = useAtomSet(accountCacheAtom);\n const [pending, setPending] = useState(false);\n\n // Account/invitation routes live on hub-service, not the edge worker.\n const hubClient = useHubHttpClient();\n\n useAsyncEffect(async () => {\n if (!hubClient) {\n return;\n }\n\n try {\n const result = await hubClient.listAccountInvitations(new Context());\n setCache((prev) => ({ ...prev, invitations: result.invitations, fetchedAt: Date.now() }));\n } catch {\n // Offline: keep cache.\n }\n }, [hubClient, setCache]);\n\n const handleIssue = useCallback(async () => {\n if (!hubClient) {\n return;\n }\n setPending(true);\n try {\n const result = await hubClient.issueAccountInvitation(new Context());\n // Optimistically push the new code and decrement the remaining quota; the\n // server consumes one slot at issue time. Next refresh reconciles.\n setCache((prev) => ({\n ...prev,\n account: prev.account\n ? { ...prev.account, invitationsRemaining: Math.max(0, prev.account.invitationsRemaining - 1) }\n : prev.account,\n invitations: [{ code: result.code, createdAt: new Date().toISOString() }, ...(prev.invitations ?? [])],\n }));\n } finally {\n setPending(false);\n }\n }, [hubClient, setCache]);\n\n const remaining = cache.account?.invitationsRemaining ?? 0;\n const list = cache.invitations ?? [];\n const available = list.filter((row) => !row.redeemedByIdentityDid);\n const redeemed = list.filter((row) => Boolean(row.redeemedByIdentityDid));\n\n return (\n <Clipboard.Provider>\n <Form.Root variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section title={t('invitations-section.title')} description={t('invitations-section.description')}>\n <Form.Row\n label={t('generate-invitation.label')}\n description={t('generate-invitation.description', { count: remaining })}\n >\n <IconButton\n icon='ph--plus--regular'\n label={t('generate-invitation.label')}\n variant='primary'\n onClick={handleIssue}\n disabled={pending || remaining <= 0}\n />\n </Form.Row>\n </Form.Section>\n\n {available.length > 0 ? (\n <Form.Section title={t('available-invitations.title')}>\n <Listbox.Root>\n <Listbox.Content classNames='gap-1'>\n {available.map((row) => (\n <AvailableInvitationItem key={row.code} row={row} />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </Form.Section>\n ) : null}\n\n {redeemed.length > 0 ? (\n <Form.Section title={t('redeemed-invitations.title')}>\n <Listbox.Root>\n <Listbox.Content classNames='gap-1'>\n {redeemed.map((row) => (\n <RedeemedInvitationItem key={row.code} row={row} />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </Form.Section>\n ) : null}\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n </Clipboard.Provider>\n );\n};\n\nconst AvailableInvitationItem = ({ row }: { row: AccountCacheInvitation }) => (\n <Listbox.Item id={row.code} classNames='grid grid-cols-[min-content_1fr_min-content] items-center gap-2'>\n <Icon icon='ph--paper-plane-tilt--duotone' size={5} classNames='text-description' />\n <div className='flex flex-col min-w-0'>\n <div className='font-mono truncate'>{row.code}</div>\n <p className='text-description text-xs'>{new Date(row.createdAt).toLocaleString()}</p>\n </div>\n <Clipboard.IconButton value={row.code} />\n </Listbox.Item>\n);\n\nconst RedeemedInvitationItem = ({ row }: { row: AccountCacheInvitation }) => {\n const date = row.redeemedAt ?? row.createdAt;\n return (\n <Listbox.Item id={row.code} classNames='grid grid-cols-[min-content_1fr] items-center gap-2'>\n <Icon icon='ph--check-circle--duotone' size={5} classNames='text-success-text' />\n <div className='flex flex-col min-w-0'>\n <div className='font-mono truncate'>{row.code}</div>\n <p className='text-description text-xs'>{new Date(date).toLocaleString()}</p>\n </div>\n </Listbox.Item>\n );\n};\n\nInvitationsContainer.displayName = 'InvitationsContainer';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { meta } from "#meta";
|
|
2
|
+
import { LayoutOperation } from "@dxos/app-toolkit";
|
|
3
|
+
import { ClientOperation } from "#operations";
|
|
4
|
+
import { useCallback } from "react";
|
|
5
|
+
import { JoinPanel } from "@dxos/shell/react";
|
|
6
|
+
import { useOperationInvoker } from "@dxos/app-framework/ui";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { Dialog, useTranslation } from "@dxos/react-ui";
|
|
9
|
+
import { osTranslations } from "@dxos/ui-theme";
|
|
10
|
+
import { ObservabilityOperation } from "@dxos/plugin-observability";
|
|
11
|
+
//#region src/containers/JoinDialog/JoinDialog.tsx
|
|
12
|
+
var JoinDialog = (props) => {
|
|
13
|
+
const { invokePromise } = useOperationInvoker();
|
|
14
|
+
const { t } = useTranslation(meta.profile.key);
|
|
15
|
+
const handleCancelResetStorage = useCallback(() => invokePromise(ClientOperation.ShareIdentity), [invokePromise]);
|
|
16
|
+
const handleDone = useCallback(async (result) => {
|
|
17
|
+
if (result?.identityKey) await Promise.all([invokePromise(LayoutOperation.UpdateDialog, { state: false }), invokePromise(ObservabilityOperation.SendEvent, { name: props.initialDisposition === "recover-identity" ? "identity.recover" : "identity.join" })]);
|
|
18
|
+
}, [invokePromise]);
|
|
19
|
+
return /* @__PURE__ */ jsxs(Dialog.Content, { children: [/* @__PURE__ */ jsx(Dialog.Header, { children: /* @__PURE__ */ jsx(Dialog.Title, {
|
|
20
|
+
classNames: "sr-only",
|
|
21
|
+
children: t("join-space.label", { ns: osTranslations })
|
|
22
|
+
}) }), /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsx(JoinPanel, {
|
|
23
|
+
...props,
|
|
24
|
+
mode: "halo-only",
|
|
25
|
+
exitActionParent: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true }),
|
|
26
|
+
doneActionParent: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true }),
|
|
27
|
+
onCancelResetStorage: handleCancelResetStorage,
|
|
28
|
+
onDone: handleDone
|
|
29
|
+
}) })] });
|
|
30
|
+
};
|
|
31
|
+
JoinDialog.displayName = "JoinDialog";
|
|
32
|
+
//#endregion
|
|
33
|
+
export { JoinDialog as default };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=chunk-JoinDialog.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-JoinDialog.mjs","names":[],"sources":["../../src/containers/JoinDialog/JoinDialog.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { LayoutOperation } from '@dxos/app-toolkit';\nimport { ObservabilityOperation } from '@dxos/plugin-observability';\nimport { type InvitationResult } from '@dxos/react-client/invitations';\nimport { Dialog, useTranslation } from '@dxos/react-ui';\nimport { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';\nimport { osTranslations } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\nimport { ClientOperation } from '#operations';\n\nexport const JoinDialog = (props: JoinPanelProps) => {\n const { invokePromise } = useOperationInvoker();\n const { t } = useTranslation(meta.profile.key);\n\n const handleCancelResetStorage = useCallback(() => invokePromise(ClientOperation.ShareIdentity), [invokePromise]);\n\n const handleDone = useCallback(\n async (result: InvitationResult | null) => {\n if (result?.identityKey) {\n await Promise.all([\n invokePromise(LayoutOperation.UpdateDialog, { state: false }),\n invokePromise(ObservabilityOperation.SendEvent, {\n name: props.initialDisposition === 'recover-identity' ? 'identity.recover' : 'identity.join',\n }),\n ]);\n }\n },\n [invokePromise],\n );\n\n // TODO(burdon): Move JoinHeading into Dialog.Heading.\n return (\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title classNames='sr-only'>{t('join-space.label', { ns: osTranslations })}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <JoinPanel\n {...props}\n mode='halo-only'\n exitActionParent={<Dialog.Close asChild />}\n doneActionParent={<Dialog.Close asChild />}\n onCancelResetStorage={handleCancelResetStorage}\n onDone={handleDone}\n />\n </Dialog.Body>\n </Dialog.Content>\n );\n};\n\nJoinDialog.displayName = 'JoinDialog';\n"],"mappings":";;;;;;;;;;;AAiBA,IAAa,cAAc,UAA0B;CACnD,MAAM,EAAE,kBAAkB,oBAAoB;CAC9C,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAE7C,MAAM,2BAA2B,kBAAkB,cAAc,gBAAgB,aAAa,GAAG,CAAC,aAAa,CAAC;CAEhH,MAAM,aAAa,YACjB,OAAO,WAAoC;EACzC,IAAI,QAAQ,aACV,MAAM,QAAQ,IAAI,CAChB,cAAc,gBAAgB,cAAc,EAAE,OAAO,MAAM,CAAC,GAC5D,cAAc,uBAAuB,WAAW,EAC9C,MAAM,MAAM,uBAAuB,qBAAqB,qBAAqB,gBAC/E,CAAC,CACH,CAAC;CAEL,GACA,CAAC,aAAa,CAChB;CAGA,OACE,qBAAC,OAAO,SAAR,EAAA,UAAA,CACE,oBAAC,OAAO,QAAR,EAAA,UACE,oBAAC,OAAO,OAAR;EAAc,YAAW;YAAW,EAAE,oBAAoB,EAAE,IAAI,eAAe,CAAC;CAAgB,CAAA,EACnF,CAAA,GACf,oBAAC,OAAO,MAAR,EAAA,UACE,oBAAC,WAAD;EACE,GAAI;EACJ,MAAK;EACL,kBAAkB,oBAAC,OAAO,OAAR,EAAc,SAAA,KAAS,CAAA;EACzC,kBAAkB,oBAAC,OAAO,OAAR,EAAc,SAAA,KAAS,CAAA;EACzC,sBAAsB;EACtB,QAAQ;CACT,CAAA,EACU,CAAA,CACC,EAAA,CAAA;AAEpB;AAEA,WAAW,cAAc"}
|