Skip to content

Commit

Permalink
UI working
Browse files Browse the repository at this point in the history
  • Loading branch information
guillemcordoba committed Oct 29, 2024
1 parent a61340b commit df513c8
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 46 deletions.
55 changes: 43 additions & 12 deletions ui/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,21 @@
import { SignalWatcher } from '@holochain-open-dev/signals';
import { AppWebsocket } from '@holochain/client';
import { ContextProvider } from '@lit/context';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/spinner/spinner.js';
import '@shoelace-style/shoelace/dist/themes/light.css';
import { LitElement, css, html } from 'lit';

import '../src/elements/link-devices-recipient.ts';
import '../src/elements/link-devices-requestor.ts';
import '../src/elements/linked-devices-context.ts';
import { LinkedDevicesClient, LinkedDevicesStore } from '../src/index.ts';

export class DemoApp extends SignalWatcher(LitElement) {
constructor() {
super();
this._loading = true;
this._view = { view: 'main' };
this._view = 'main';
}

async firstUpdated() {
Expand All @@ -63,20 +66,46 @@
this._linkedDevicesStore = new LinkedDevicesStore(
new LinkedDevicesClient(appClient, 'linked_devices_test'),
);
this._exampleStore = new ContextProvider(
this,
exampleStoreContext,
new ExampleStore(
new ExampleClient(appClient, 'linked_devices_test'),
),
);
}

renderContent() {
if (this.linkingDeviceRecipient) {
return html`
<link-devices-recipient
@device-linked=${() => {
this.linkingDeviceRecipient = false;
this.requestUpdate();
}}
>
</link-devices-recipient>
`;
}
if (this.linkingDeviceRequestor) {
return html`
<link-devices-requestor
@device-linked=${() => {
this.linkingDeviceRequestor = false;
this.requestUpdate();
}}
>
</link-devices-requestor>
`;
}
return html`
<linked-devices-context .store=${this._linkedDevicesStore}>
<!-- TODO: add here the content of your application -->
</linked-devices-context>
<sl-button
@click=${() => {
this.linkingDeviceRequestor = true;
this.requestUpdate();
}}
>Link Device as requestor</sl-button
>
<sl-button
@click=${() => {
this.linkingDeviceRecipient = true;
this.requestUpdate();
}}
>Link Device as recipient</sl-button
>
`;
}

Expand All @@ -91,7 +120,9 @@

return html`
<div class="fill row" style="width: 100vw; height: 100%;">
${this.renderContent()}
<linked-devices-context .store=${this._linkedDevicesStore}>
${this.renderContent()}
</linked-devices-context>
</div>
`;
}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export interface LinkedDevicesConfig {
export const defaultLinkedDevicesConfig: LinkedDevicesConfig = {
linkDevicePasscodeLength: 4,
};

export const TTL_CAP_GRANT = 60 * 1000; // 1 minute
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import {
sharedStyles,
} from '@holochain-open-dev/elements';
import { SignalWatcher } from '@holochain-open-dev/signals';
import { encodeHashToBase64 } from '@holochain/client';
import { AgentPubKey, encodeHashToBase64 } from '@holochain/client';
import { consume } from '@lit/context';
import { msg } from '@lit/localize';
import { SlInput } from '@shoelace-style/shoelace';
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
import { LitElement, css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';

import { TTL_CAP_GRANT } from '../config.js';
import { linkedDevicesStoreContext, profilesStoreContext } from '../context.js';
import { linkedDevicesStoreContext } from '../context.js';
import { LinkedDevicesStore } from '../linked-devices-store.js';
import { RequestLinkAgentSignal } from '../types.js';
import { LinkDevicesSignal, LinkedDevicesSignal } from '../types.js';
import './passcode-input.js';
import { PasscodeInput } from './passcode-input.js';

Expand All @@ -31,10 +32,10 @@ export function randomPasscode(length: number) {
return passcode;
}

@customElement('link-device-recipient')
export class LinkDeviceRecipient extends SignalWatcher(LitElement) {
@customElement('link-devices-recipient')
export class LinkDevicesRecipient extends SignalWatcher(LitElement) {
/**
* Profiles store for this element, not required if you embed this element inside a <profiles-context>
* LinkedDevicesStore for this element, not required if you embed this element inside a <linked-devices-context>
*/
@consume({ context: linkedDevicesStoreContext, subscribe: true })
@property()
Expand All @@ -44,7 +45,7 @@ export class LinkDeviceRecipient extends SignalWatcher(LitElement) {
recipientPasscode: number[] = [];

@state()
requestLinkAgentSignal: RequestLinkAgentSignal | undefined;
initializedLinkDevicesByRequestor: AgentPubKey | undefined;

interval: any;

Expand All @@ -56,48 +57,54 @@ export class LinkDeviceRecipient extends SignalWatcher(LitElement) {
this.recipientPasscode = randomPasscode(
this.store.config.linkDevicePasscodeLength,
);
await this.store.client.clearLinkAgent();
await this.store.client.prepareLinkAgent(this.recipientPasscode);
await this.store.client.clearLinkDevices();
await this.store.client.prepareLinkDevices(this.recipientPasscode);
}, TTL_CAP_GRANT);
await this.store.client.prepareLinkAgent(this.recipientPasscode);
await this.store.client.prepareLinkDevices(this.recipientPasscode);

this.store.client.onSignal(signal => {
if ('type' in signal) return;
this.requestLinkAgentSignal = signal as RequestLinkAgentSignal;
if (
!('type' in signal && (signal as any).type === 'LinkDevicesInitialized')
)
return;
this.initializedLinkDevicesByRequestor = (
signal as any as LinkDevicesSignal
).requestor;
});
}
disconnectedCallback(): void {
super.disconnectedCallback();
clearInterval(this.interval);
this.store.client.clearLinkAgent();
this.store.client.clearLinkDevices();
}

async attemptLinkAgent(
requestLinkAgentSignal: RequestLinkAgentSignal,
requestor: AgentPubKey,
inputtedRequestorPasscode: Array<number>,
) {
if (
!areEqual(
requestLinkAgentSignal.requestor_passcode,
inputtedRequestorPasscode,
)
) {
notifyError(msg('Incorrect pass code'));
(
this.shadowRoot!.querySelector('passcode-input') as PasscodeInput
).clearPasscode();
return;
}
// if (
// !areEqual(
// requestLinkAgentSignal.requestor_passcode,
// inputtedRequestorPasscode,
// )
// ) {
// notifyError(msg('Incorrect pass code'));
// (
// this.shadowRoot!.querySelector('passcode-input') as PasscodeInput
// ).clearPasscode();
// return;
// }
try {
await this.store.client.linkAgentWithMyProfile(
requestLinkAgentSignal.from,
await this.store.client.requestLinkDevices(
requestor,
inputtedRequestorPasscode,
);
this.dispatchEvent(
new CustomEvent('agent-linked', {
new CustomEvent('device-linked', {
bubbles: true,
composed: true,
detail: {
agentPubKey: requestLinkAgentSignal.from,
agentPubKey: requestor,
},
}),
);
Expand All @@ -111,7 +118,7 @@ export class LinkDeviceRecipient extends SignalWatcher(LitElement) {
).clearPasscode();
}

renderRequestLinkAgent(requestLinkAgentSignal: RequestLinkAgentSignal) {
renderRequestLinkAgent(initializedLinkDevicesByRequestor: AgentPubKey) {
return html`
<div
class="column"
Expand All @@ -122,16 +129,21 @@ export class LinkDeviceRecipient extends SignalWatcher(LitElement) {
<passcode-input
.passcodeLength=${this.store.config.linkDevicePasscodeLength}
@passcode-change=${(e: CustomEvent) =>
this.attemptLinkAgent(requestLinkAgentSignal, e.detail.passcode)}
this.attemptLinkAgent(
initializedLinkDevicesByRequestor,
e.detail.passcode,
)}
>
</passcode-input>
</div>
`;
}

render() {
if (this.requestLinkAgentSignal)
return this.renderRequestLinkAgent(this.requestLinkAgentSignal);
if (this.initializedLinkDevicesByRequestor)
return this.renderRequestLinkAgent(
this.initializedLinkDevicesByRequestor,
);

return html`<div
class="column"
Expand Down
Loading

0 comments on commit df513c8

Please sign in to comment.