From 311b2051b0aeab11e1fd62fc28acc086dd35d4b9 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 26 May 2023 16:34:49 -0400 Subject: [PATCH] Implementing WeApplet --- we-applet/demo/index.html | 2 +- we-applet/src/applet-view.ts | 134 ++++++++++++++++++ we-applet/src/attachment-types.ts | 32 +++++ we-applet/src/cross-applet-view.ts | 27 ++++ we-applet/src/index.ts | 70 +-------- we-applet/src/mock.ts | 25 ++++ we-applet/src/we-utils.ts | 32 +++++ .../src/elements/comment-thread-view.ts | 3 +- 8 files changed, 257 insertions(+), 68 deletions(-) create mode 100644 we-applet/src/applet-view.ts create mode 100644 we-applet/src/attachment-types.ts create mode 100644 we-applet/src/cross-applet-view.ts create mode 100644 we-applet/src/mock.ts create mode 100644 we-applet/src/we-utils.ts diff --git a/we-applet/demo/index.html b/we-applet/demo/index.html index 1c79eb7b..fc8d28f4 100644 --- a/we-applet/demo/index.html +++ b/we-applet/demo/index.html @@ -20,7 +20,7 @@ import { ProfilesClient } from '@holochain-open-dev/profiles'; import { ProfilesZomeMock } from "@holochain-open-dev/profiles/dist/mocks.js"; import { weServicesMock } from "@lightningrodlabs/we-applet/dist/mocks.js"; - + import Applet from "../dist"; /** Define setup function */ diff --git a/we-applet/src/applet-view.ts b/we-applet/src/applet-view.ts new file mode 100644 index 00000000..62df30c8 --- /dev/null +++ b/we-applet/src/applet-view.ts @@ -0,0 +1,134 @@ +import {AppAgentClient, AppAgentWebsocket, encodeHashToBase64, EntryHash} from "@holochain/client"; +import {ProfilesClient} from "@holochain-open-dev/profiles"; +import {AppletViews, WeServices} from "@lightningrodlabs/we-applet"; +import {ThreadsApp} from "@threads/app"; +import { + AppAgentClient, AppAgentWebsocket, + EntryHash, +} from "@holochain/client"; +import { html, render} from "lit"; +import { msg } from "@lit/localize"; + +import { + Hrl, + AppletViews, + CrossAppletViews, + WeApplet, + WeServices, +} from "@lightningrodlabs/we-applet"; + +import "@holochain-open-dev/profiles/dist/elements/profiles-context.js"; +import "@lightningrodlabs/we-applet/dist/elements/we-services-context.js"; +import "@lightningrodlabs/we-applet/dist/elements/hrl-link.js"; + +import {ProfilesClient, ProfilesStore} from "@holochain-open-dev/profiles"; +import {ThreadsApp} from "@threads/app"; +import {asCellProxy} from "./we-utils"; +import {ThreadsProxy} from "@threads/elements/dist/bindings/threads.proxy"; + + +// FIXME: Add threads-context in some way + +/** */ +export function appletViews( + client: AppAgentClient, + _appletId: EntryHash, + profilesClient: ProfilesClient, + weServices: WeServices +): AppletViews { + return { + main: (element) => { + const agentWs = client as AppAgentWebsocket; + console.log("ThreadsApplet.main()", client, agentWs.appWebsocket) + /** Link to styles */ + const cssLink = document.createElement('link'); + cssLink.href = "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.4.0/dist/themes/light.css"; + cssLink.rel = "stylesheet"; + cssLink.media="(prefers-color-scheme:light)" + element.appendChild(cssLink); + /** Create and append */ + const app = new ThreadsApp(agentWs.appWebsocket, undefined, true, "threads-applet"); + element.appendChild(app); + }, + blocks: {}, + entries: { + rThreads: { + threads_integrity: { + + /** Thread */ + participation_protocol: { + info: async (hrl: Hrl) => { + const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + const pp = await proxy.getPp(hrl[1]); + return { + icon_src: "", + name: pp[0].purpose, + }; + }, + view: async (element, hrl: Hrl, context) => { + //const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + //const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + const spaceElem = html` +
Before custom element
+ +
After custom element
+ `; + render(spaceElem, element); + }, + }, + + + /** TextMessage */ + text_message: { + info: async (hrl: Hrl) => { + const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + const tuple = await proxy.getTextMessage(hrl[1]); + return { + icon_src: "", + name: tuple[2].value, + }; + }, + view: async (element, hrl: Hrl, context) => { + //const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + //const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + const spaceElem = html` +
Before custom element
+ +
After custom element
+ `; + render(spaceElem, element); + }, + }, + + + // /** Path entry type */ + // path: { + // info: async (hrl: Hrl) => { + // const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + // const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + // const tuple = await proxy.getSubjectsByType(hrl[1]); + // return { + // icon_src: "", + // name: tuple[2].value, + // }; + // }, + // view: async (element, hrl: Hrl, context: any) => { + // //const cellProxy = await asCellProxy(client, hrl, "threads-applet", "rThreads"); + // //const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + // const spaceElem = html` + //
Before custom element
+ // + //
After custom element
+ // `; + // render(spaceElem, element); + // }, + // }, + + + } + } + }, + }; +} diff --git a/we-applet/src/attachment-types.ts b/we-applet/src/attachment-types.ts new file mode 100644 index 00000000..94743b32 --- /dev/null +++ b/we-applet/src/attachment-types.ts @@ -0,0 +1,32 @@ +import {AppAgentClient, decodeHashFromBase64, DnaHash} from "@holochain/client"; +import {AttachmentType, Hrl} from "@lightningrodlabs/we-applet"; +import {asCellProxy} from "./we-utils"; +import {ThreadsProxy} from "@threads/elements/dist/bindings/threads.proxy"; +import {CreatePpInput} from "@threads/elements/dist/bindings/threads.types"; + + +/** */ +export async function attachmentTypes(client: AppAgentClient): Promise> { + return { + thread: { + label: "Thread", + icon_src: "", + async create(attachToHrl: Hrl) { + const cellProxy = await asCellProxy(client, attachToHrl, "threads-applet", "rThreads"); + const proxy: ThreadsProxy = new ThreadsProxy(cellProxy); + const input: CreatePpInput = { + purpose: "comment", + rules: "FFA", + dnaHash: attachToHrl[0], + subjectHash: attachToHrl[1], + subjectType: "unknown", + }; + const ppPair = await proxy.createParticipationProtocol(input); + return { + hrl: [decodeHashFromBase64(cellProxy.cell.dnaHash), ppPair[0]], + context: {}, + }; + } + } + }; +} diff --git a/we-applet/src/cross-applet-view.ts b/we-applet/src/cross-applet-view.ts new file mode 100644 index 00000000..d76769e2 --- /dev/null +++ b/we-applet/src/cross-applet-view.ts @@ -0,0 +1,27 @@ +import {AppAgentClient, EntryHash} from "@holochain/client"; +import {ProfilesClient} from "@holochain-open-dev/profiles"; +import {CrossAppletViews, WeServices} from "@lightningrodlabs/we-applet"; +import {html, render} from "lit"; + + +/** */ +export function crossAppletViews( + applets: ReadonlyMap, // Segmented by groupId + weServices: WeServices, +): CrossAppletViews { + // .store=${new ProfilesStore(applets[random].profilesClient)} + return { + main: (element) => + render( + html` + + + + + + `, + element + ), + blocks: {}, + }; +} diff --git a/we-applet/src/index.ts b/we-applet/src/index.ts index e30188dc..5caf357d 100644 --- a/we-applet/src/index.ts +++ b/we-applet/src/index.ts @@ -1,27 +1,19 @@ import { - AppAgentClient, AppAgentWebsocket, - EntryHash, + AppAgentClient } from "@holochain/client"; -import { html, render} from "lit"; -import { msg } from "@lit/localize"; import { - Hrl, - AppletViews, - CrossAppletViews, WeApplet, - WeServices, } from "@lightningrodlabs/we-applet"; import "@holochain-open-dev/profiles/dist/elements/profiles-context.js"; import "@lightningrodlabs/we-applet/dist/elements/we-services-context.js"; import "@lightningrodlabs/we-applet/dist/elements/hrl-link.js"; -import {ProfilesClient, ProfilesStore} from "@holochain-open-dev/profiles"; -import {ThreadsApp} from "@threads/app"; +import {appletViews} from "./applet-view"; +import {crossAppletViews} from "./cross-applet-view"; +import {attachmentTypes} from "./attachment-types"; -// import "./applet-main"; -// import "./cross-applet-main"; /** */ @@ -34,58 +26,4 @@ const applet: WeApplet = { export default applet; -/** */ -async function attachmentTypes(appletClient: AppAgentClient) { - return {} -} - - -/** */ -function appletViews( - client: AppAgentClient, - _appletId: EntryHash, - profilesClient: ProfilesClient, - weServices: WeServices -): AppletViews { - return { - main: (element) => { - const agentWs = client as AppAgentWebsocket; - console.log("ThreadsApplet.main()", client, agentWs.appWebsocket) - /** Link to styles */ - const cssLink = document.createElement('link'); - cssLink.href = "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.4.0/dist/themes/light.css"; - cssLink.rel = "stylesheet"; - cssLink.media="(prefers-color-scheme:light)" - element.appendChild(cssLink); - /** Create and append */ - const app = new ThreadsApp(agentWs.appWebsocket, undefined, true, "threads-applet"); - element.appendChild(app); - }, - blocks: {}, - entries: {}, - }; -} - - -function crossAppletViews( - applets: ReadonlyMap, // Segmented by groupId - weServices: WeServices, -): CrossAppletViews { - // .store=${new ProfilesStore(applets[random].profilesClient)} - return { - main: (element) => - render( - html` - - - - - - `, - element - ), - blocks: {}, - }; -} - diff --git a/we-applet/src/mock.ts b/we-applet/src/mock.ts new file mode 100644 index 00000000..28d33376 --- /dev/null +++ b/we-applet/src/mock.ts @@ -0,0 +1,25 @@ + +// export const weServicesMock: WeServices = { +// openViews: OpenViews; +// attachmentTypes: ReadonlyMap>; // Segmented by groupId +// +// groupProfile(groupId: DnaHash): Promise; +// appletInfo(appletId: EntryHash): Promise; +// entryInfo(hrl: Hrl): Promise; +// search(filter: string): Promise>; +// }; +// +// +// export const weServicesMock: WeServices = { +// appletInfo: async () => undefined, +// attachmentTypes: new HoloHashMap>(), +// entryInfo: async () => undefined, +// groupProfile: async () => +// openViews: { +// openAppletBlock: () => {}, +// openCrossAppletBlock: () => {}, +// openHrl: () => {}, +// }, +// search: async () => [], +// }; + diff --git a/we-applet/src/we-utils.ts b/we-applet/src/we-utils.ts new file mode 100644 index 00000000..3fa80b4a --- /dev/null +++ b/we-applet/src/we-utils.ts @@ -0,0 +1,32 @@ +import {asCell, BaseRoleName, Cell, CellProxy, ConductorAppProxy} from "@ddd-qc/cell-proxy"; +import {AppAgentClient, AppAgentWebsocket, CellInfo, encodeHashToBase64, InstalledAppId} from "@holochain/client"; +import {Hrl} from "@lightningrodlabs/we-applet"; + + +/** */ +export async function getCellInfo(client: AppAgentClient, hrl: Hrl, baseRoleName: BaseRoleName): Promise { + const appInfo = await client.appInfo(); + const cells = appInfo.cell_info[baseRoleName]; + for (const cellInfo of cells) { + const cell = asCell(cellInfo); + if (!cell) { + continue; + } + const cellId = cell.cell_id; + if (encodeHashToBase64(cellId[0]) == encodeHashToBase64(hrl[0])) { + return cellInfo; + } + } + return null; +} + + +/** */ +export async function asCellProxy(client: AppAgentClient, hrl: Hrl, appId: InstalledAppId, baseRoleName: BaseRoleName): Promise { + const agentWs = client as AppAgentWebsocket; + const appProxy = await ConductorAppProxy.new(agentWs.appWebsocket); + const cellInfo = await getCellInfo(client, hrl, baseRoleName); + const cell = Cell.from(cellInfo, appId, baseRoleName) + const cellProxy = new CellProxy(appProxy, cell); + return cellProxy; +} diff --git a/webcomponents/src/elements/comment-thread-view.ts b/webcomponents/src/elements/comment-thread-view.ts index b35aa844..a15a52fa 100644 --- a/webcomponents/src/elements/comment-thread-view.ts +++ b/webcomponents/src/elements/comment-thread-view.ts @@ -9,6 +9,7 @@ import "@ui5/webcomponents/dist/Avatar.js" import List from "@ui5/webcomponents/dist/List" import "@ui5/webcomponents/dist/StandardListItem.js"; import {ThreadsProfile} from "../viewModels/profiles.proxy"; +import {ActionHashB64} from "@holochain/client"; // import "@ui5/webcomponents/dist/CustomListItem.js"; // import "@ui5/webcomponents/dist/GroupHeaderListItem.js" @@ -28,7 +29,7 @@ export class CommentThreadView extends DnaElement { /** -- Properties -- */ /** Hash of Thread to display */ - @property() threadHash: string = '' + @property() threadHash: ActionHashB64 = '' /** View beads in chronological order, otherwise use timeReference as end-time and display older beads only. */ @property() startFromBeginning: boolean = false;