From 5973191f96f73953ea82bcabebf2601840f10608 Mon Sep 17 00:00:00 2001 From: Eric Harris-Braun Date: Tue, 16 Jan 2024 16:16:07 -0500 Subject: [PATCH] add we attachments compatibility --- ui/src/elements/how-document.ts | 50 +++++++++++++++++++ ui/src/elements/how-unit.ts | 3 -- ui/src/elements/svg-icons.ts | 6 ++- ui/src/holochain-app.ts | 87 ++++++++++++++++++++++++++++----- ui/src/how.store.ts | 19 ++++--- ui/src/types.ts | 1 + 6 files changed, 143 insertions(+), 23 deletions(-) diff --git a/ui/src/elements/how-document.ts b/ui/src/elements/how-document.ts index 5949a66..aa4e594 100644 --- a/ui/src/elements/how-document.ts +++ b/ui/src/elements/how-document.ts @@ -23,6 +23,7 @@ import { ActionHash } from "@holochain/client"; import { HowConfirm } from "./how-confirm"; import { CommentControl, Control } from "../controls"; import {until} from 'lit-html/directives/until.js'; +import { hrlB64WithContextToRaw, hrlWithContextToB64 } from "../util"; /** * @element how-document @@ -397,6 +398,15 @@ import {until} from 'lit-html/directives/until.js'; return false } + private async addAttachment() { + if (this._store.weClient) { + const hrl = await this._store.weClient.userSelectHrl() + if (hrl) { + const doc : Document = this._documents.value[this.currentDocumentEh] + await this._store.markDocument(this.path, [{hash: doc.documentHash!, mark: JSON.stringify(hrlWithContextToB64(hrl)), markType: MarkTypes.Attachment}]) } + } + } + private sectionRow(doc:Document, section: Section, index: number, comments:Array, isSteward: boolean) : TemplateResult { let commentsHTML if (this.canSeeComments(doc, section)) { @@ -543,6 +553,46 @@ import {until} from 'lit-html/directives/until.js'; > `) } + if (this._store.weClient) { + const isSteward = unit.stewards.includes(this._store.myAgentPubKey) + if (isSteward) { + affordancesHTML.push(html` +
this.addAttachment()} + > +
`) + } + for (const mark of doc.marks.filter(m=>m.markType==MarkTypes.Attachment)) { + const attachment = JSON.parse(`${mark.mark}`) + affordancesHTML.push(html` +
+ ${until(this._store.weClient.entryInfo(hrlB64WithContextToRaw(attachment).hrl) + .then(res=> { + if (res) { + const entryInfo = res.entryInfo + return html` + ${entryInfo.name} + + { + const hrl = hrlB64WithContextToRaw(attachment) + // @ts-ignore + this._store.weClient.openHrl(hrl.hrl, hrl.context) + }} + > + ` + }} + ), + html`...` + )} +
+ `) + } + } } let tasksHTML: Array = [] if (docStats.emptySections > 0) { diff --git a/ui/src/elements/how-unit.ts b/ui/src/elements/how-unit.ts index f1dc0f0..6547115 100644 --- a/ui/src/elements/how-unit.ts +++ b/ui/src/elements/how-unit.ts @@ -307,9 +307,6 @@ export class HowUnit extends ScopedElementsMixin(LitElement) { ` } - else { - collectionsHTML = html`collections: ${collections.length}` - } return html`
diff --git a/ui/src/elements/svg-icons.ts b/ui/src/elements/svg-icons.ts index da0f4c4..403d4bd 100644 --- a/ui/src/elements/svg-icons.ts +++ b/ui/src/elements/svg-icons.ts @@ -74,6 +74,8 @@ export const SVG = { `, collect: ``, - chevron: `` + chevron: ``, + clip: `` - } \ No newline at end of file + } + diff --git a/ui/src/holochain-app.ts b/ui/src/holochain-app.ts index 9ffc0d2..dacb504 100644 --- a/ui/src/holochain-app.ts +++ b/ui/src/holochain-app.ts @@ -16,6 +16,7 @@ import { AdminWebsocket, AppAgentClient, AppAgentWebsocket, + encodeHashToBase64, } from '@holochain/client'; import { provide } from '@lit/context'; import { LitElement, css, html } from 'lit'; @@ -28,10 +29,17 @@ import {howContext} from "./types" import { localized, msg } from '@lit/localize'; import { ScopedElementsMixin } from "@open-wc/scoped-elements"; -import { WeClient, isWeContext, initializeHotReload } from '@lightningrodlabs/we-applet'; +import { WeClient, isWeContext, initializeHotReload, HrlWithContext, Hrl } from '@lightningrodlabs/we-applet'; +import { appletServices } from './we'; +import { HowUnit } from './elements/how-unit'; const appId = 'how' +enum RenderType { + App, + Unit, +} + @localized() @customElement('holochain-app') export class HolochainApp extends ScopedElementsMixin(LitElement) { @@ -50,6 +58,9 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) { @property() _profilesStore!: ProfilesStore; + renderType = RenderType.App + hrl: Hrl| undefined + async firstUpdated() { const config:ProfilesConfig = { @@ -78,23 +89,73 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) { } const appAgentClient = await AppAgentWebsocket.connect(new URL(url), appId) - this._howStore = new HowStore(appAgentClient, "how") + this._howStore = new HowStore(undefined, appAgentClient, "how") this._profilesStore = new ProfilesStore( new ProfilesClient(appAgentClient, 'how'), config ); } else { - const weClient = await WeClient.connect(); - - if ( - !(weClient.renderInfo.type === "applet-view") - && !(weClient.renderInfo.view.type === "main") - ) throw new Error("This Applet only implements the applet main view."); + const weClient = await WeClient.connect(appletServices); + + switch (weClient.renderInfo.type) { + case "applet-view": + switch (weClient.renderInfo.view.type) { + case "main": + // default is allready App + break; + case "block": + switch(weClient.renderInfo.view.block) { + default: + throw new Error("Unknown applet-view block type:"+weClient.renderInfo.view.block); + } + break; + case "entry": + console.log("render", weClient.renderInfo) + switch (weClient.renderInfo.view.roleName) { + case "how": + switch (weClient.renderInfo.view.integrityZomeName) { + case "how_integrity": + switch (weClient.renderInfo.view.entryType) { + case "unitx": + this.renderType = RenderType.Unit + this.hrl = weClient.renderInfo.view.hrl + break; + default: + throw new Error("Unknown entry type:"+weClient.renderInfo.view.entryType); + } + break; + default: + throw new Error("Unknown integrity zome:"+weClient.renderInfo.view.integrityZomeName); + } + break; + default: + throw new Error("Unknown role name:"+weClient.renderInfo.view.roleName); + } + break; + default: + throw new Error("Unsupported applet-view type"); + } + break; + case "cross-applet-view": + switch (weClient.renderInfo.view.type) { + case "main": + // here comes your rendering logic for the cross-applet main view + //break; + case "block": + // + //break; + default: + throw new Error("Unknown cross-applet-view render type.") + } + break; + default: + throw new Error("Unknown render view type"); + } //@ts-ignore const client = weClient.renderInfo.appletClient; - this._howStore = new HowStore(client, "how") - + this._howStore = new HowStore(weClient, client, "how") + if (this.renderType == RenderType.Unit) this._howStore.pullUnits() //@ts-ignore const profilesClient = weClient.renderInfo.profilesClient; @@ -109,7 +170,10 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) { if (!this.loaded) return html`Loading...`; return html` - + ${this.renderType == RenderType.App ? html` + `:""} + ${this.renderType == RenderType.Unit && this.hrl ? html` + `:""} @@ -119,6 +183,7 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) { static get scopedElements() { return { "how-controller": HowController, + "how-unit": HowUnit, }; } } diff --git a/ui/src/how.store.ts b/ui/src/how.store.ts index 71f4572..fb1dedd 100644 --- a/ui/src/how.store.ts +++ b/ui/src/how.store.ts @@ -24,6 +24,7 @@ import { Progress, } from './types'; import { Action, ActionHash } from '@holochain/client'; +import { WeClient } from '@lightningrodlabs/we-applet'; export type HowConfig = { processRoot: string @@ -70,9 +71,11 @@ export class HowStore { ) constructor( + public weClient: WeClient|undefined, protected client: AppAgentClient, roleName: RoleName, - zomeName = 'how' + zomeName = 'how', + ) { this.myAgentPubKey = encodeHashToBase64(client.myPubKey); this.service = new HowService(client, roleName, zomeName); @@ -241,12 +244,14 @@ export class HowStore { async pullMeta() { const docs = await this.pullDocuments("") - const meta = docs.find(d=>d.content.documentType == DocType.TreeMeta) - if (meta) { - this.treeName = meta.content.content[0].name - this.config = JSON.parse(meta.content.content[0].content) as HowConfig - this.processRootPath = this.config.processRoot.split(".") - Document.processRoot = this.config.processRoot + if (docs) { + const meta = docs.find(d=>d.content.documentType == DocType.TreeMeta) + if (meta) { + this.treeName = meta.content.content[0].name + this.config = JSON.parse(meta.content.content[0].content) as HowConfig + this.processRootPath = this.config.processRoot.split(".") + Document.processRoot = this.config.processRoot + } } // await this.pullDocuments("soc_proto.process.define.declaration") diff --git a/ui/src/types.ts b/ui/src/types.ts index 3430a13..9a4dbf0 100644 --- a/ui/src/types.ts +++ b/ui/src/types.ts @@ -386,6 +386,7 @@ export enum MarkTypes { CommentStatus = 1, Vote = 2, Approval = 3, + Attachment = 4, } export type Offsets = {