Skip to content

Commit

Permalink
add we attachments compatibility
Browse files Browse the repository at this point in the history
adds attachments support for we
  • Loading branch information
zippy committed Jan 16, 2024
1 parent 41a42b7 commit e43583f
Show file tree
Hide file tree
Showing 10 changed files with 312 additions and 29 deletions.
16 changes: 16 additions & 0 deletions dnas/how/zomes/coordinator/how/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ fn get_documents_inner(base: EntryHash) -> HowResult<Vec<DocumentOutput>> {
get_input.push(GetInput::new(hash, GetOptions::default()))
}
}
_get_docs(get_input)
}

#[hdk_extern]
pub fn get_document(hash: EntryHash) -> ExternResult<DocumentOutput> {
let mut get_input= vec!();
let x = GetInput::new(hash.try_into().map_err(|_e| wasm_error!("hash error"))?, GetOptions::default());
get_input.push(x);
let result = _get_docs(get_input)?;
if result.len() != 1 {
return Err(wasm_error!(WasmErrorInner::Guest(String::from("could not find document"))));
}
Ok(result[0].clone())
}

fn _get_docs(get_input: Vec<GetInput>) -> HowResult<Vec<DocumentOutput>> {

let document_elements = HDK.with(|hdk| hdk.borrow().get_details(get_input))?;

Expand Down
63 changes: 62 additions & 1 deletion ui/src/elements/how-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { consume } from '@lit/context';
import { StoreSubscriber } from "@holochain-open-dev/stores";

import {sharedStyles} from "../sharedStyles";
import {EntryHashB64, encodeHashToBase64} from "@holochain/client";
import {EntryHashB64, decodeHashFromBase64, encodeHashToBase64} from "@holochain/client";
import {howContext, Section, SectionType, SourceManual, Document, DocType, HilightRange, CommentInfo, Comment, CommentStatus, MarkTypes, MarkDocumentInput, CommentAction, applyApprovedComments, CommentStats, DocumentStats, DocumentAction, VoteAction, ApprovalAction, Dictionary, Unit} from "../types";
import {HowStore} from "../how.store";
import {ScopedElementsMixin} from "@open-wc/scoped-elements";
Expand All @@ -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
Expand Down Expand Up @@ -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<Comment>, isSteward: boolean) : TemplateResult {
let commentsHTML
if (this.canSeeComments(doc, section)) {
Expand Down Expand Up @@ -543,6 +553,57 @@ import {until} from 'lit-html/directives/until.js';
></svg-button>
</div>`)
}
if (this._store.weClient) {
const isSteward = unit.stewards.includes(this._store.myAgentPubKey)
if (isSteward) {
affordancesHTML.push(html`
<div>
<svg-button
button="clipboard"
info="hrl to clipboard"
infoPosition="right"
.click=${() => {
const attachment = { hrl: [this._store.dnaHash, decodeHashFromBase64(this.currentDocumentEh)], context: {} }
// @ts-ignore
this._store.weClient?.hrlToClipboard(attachment)
}}
></svg-button>
<svg-button
button="plus"
info="add attachment"
infoPosition="right"
.click=${() => this.addAttachment()}
></svg-button>
</div>`)
}
for (const mark of doc.marks.filter(m=>m.markType==MarkTypes.Attachment)) {
const attachment = JSON.parse(`${mark.mark}`)
affordancesHTML.push(html`
<div style="display:flex; align-items:center">
${until(this._store.weClient.entryInfo(hrlB64WithContextToRaw(attachment).hrl)
.then(res=> {
if (res) {
const entryInfo = res.entryInfo
return html`
${entryInfo.name}
<svg-button
button="paperclip"
.click=${()=>{
const hrl = hrlB64WithContextToRaw(attachment)
// @ts-ignore
this._store.weClient.openHrl(hrl.hrl, hrl.context)
}}
>
</svg-button>`
}}
),
html`...`
)}
</div>
`)
}
}
}
let tasksHTML: Array<TemplateResult> = []
if (docStats.emptySections > 0) {
Expand Down
3 changes: 0 additions & 3 deletions ui/src/elements/how-unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,6 @@ export class HowUnit extends ScopedElementsMixin(LitElement) {
</mwc-select>
</div>`
}
else {
collectionsHTML = html`collections: ${collections.length}`
}

return html`
<div class="unit row">
Expand Down
8 changes: 5 additions & 3 deletions ui/src/elements/svg-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ export const SVG = {
</svg>
`,
collect: `<svg xmlns="http://www.w3.org/2000/svg" height="26" width="24" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg>`,
chevron: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>`

}
chevron: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>`,
paperclip: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M364.2 83.8c-24.4-24.4-64-24.4-88.4 0l-184 184c-42.1 42.1-42.1 110.3 0 152.4s110.3 42.1 152.4 0l152-152c10.9-10.9 28.7-10.9 39.6 0s10.9 28.7 0 39.6l-152 152c-64 64-167.6 64-231.6 0s-64-167.6 0-231.6l184-184c46.3-46.3 121.3-46.3 167.6 0s46.3 121.3 0 167.6l-176 176c-28.6 28.6-75 28.6-103.6 0s-28.6-75 0-103.6l144-144c10.9-10.9 28.7-10.9 39.6 0s10.9 28.7 0 39.6l-144 144c-6.7 6.7-6.7 17.7 0 24.4s17.7 6.7 24.4 0l176-176c24.4-24.4 24.4-64 0-88.4z"/></svg>`,
clipboard: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z"/></svg>`
}

100 changes: 89 additions & 11 deletions ui/src/holochain-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
AdminWebsocket,
AppAgentClient,
AppAgentWebsocket,
encodeHashToBase64,
} from '@holochain/client';
import { provide } from '@lit/context';
import { LitElement, css, html } from 'lit';
Expand All @@ -28,10 +29,19 @@ 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';
import { HowDocument } from './elements/how-document';

const appId = 'how'

enum RenderType {
App,
Unit,
Document,
}

@localized()
@customElement('holochain-app')
export class HolochainApp extends ScopedElementsMixin(LitElement) {
Expand All @@ -50,6 +60,9 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) {
@property()
_profilesStore!: ProfilesStore;

renderType = RenderType.App
hrl: Hrl| undefined

async firstUpdated() {

const config:ProfilesConfig = {
Expand Down Expand Up @@ -78,23 +91,81 @@ 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":
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;
case "document":
this.renderType = RenderType.Document
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()
else if (this.renderType == RenderType.Document) {
await this._howStore.pullUnits()
// @ts-ignore
await this._howStore.pullDocument(this.hrl[1])
}

//@ts-ignore
const profilesClient = weClient.renderInfo.profilesClient;
Expand All @@ -109,7 +180,12 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) {
if (!this.loaded) return html`<span>Loading...</span>`;
return html`
<profile-prompt>
<how-controller></how-controller>
${this.renderType == RenderType.App ? html`
<how-controller></how-controller>`:""}
${this.renderType == RenderType.Unit && this.hrl ? html`
<how-unit .currentUnitEh=${encodeHashToBase64(this.hrl[1])}></how-unit>`:""}
${this.renderType == RenderType.Document && this.hrl ? html`
<how-document .currentDocumentEh=${encodeHashToBase64(this.hrl[1])}></how-document>`:""}
</profile-prompt>
<!-- <how-controller id="controller" dummy="{true}""></how-controller> -->
Expand All @@ -119,6 +195,8 @@ export class HolochainApp extends ScopedElementsMixin(LitElement) {
static get scopedElements() {
return {
"how-controller": HowController,
"how-unit": HowUnit,
"how-document": HowDocument,
};
}
}
8 changes: 6 additions & 2 deletions ui/src/how.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppAgentClient, EntryHashB64, AgentPubKeyB64, AppAgentCallZomeRequest, RoleName, encodeHashToBase64, decodeHashFromBase64 } from '@holochain/client';
import { AppAgentClient, EntryHashB64, AgentPubKeyB64, AppAgentCallZomeRequest, RoleName, encodeHashToBase64, decodeHashFromBase64, EntryHash } from '@holochain/client';
import { UnitInput, RustNode, RustTree, Initialization, DocumentOutput, DocumentInput, UpdateDocumentInput, AdvanceStateInput, UnitOutput, MarkDocumentInput, HowSignal, Unit, UpdateUnitInput} from './types';
import { ActionHash } from '@holochain/client';

Expand Down Expand Up @@ -35,6 +35,10 @@ export class HowService {
return await this.callZome('get_units', null)
}

async getDocument(input: EntryHash): Promise<DocumentOutput> {
return this.callZome('get_document', input);
}

async createDocument(input: DocumentInput): Promise<EntryHashB64> {
return this.callZome('create_document', input);
}
Expand Down Expand Up @@ -63,7 +67,7 @@ export class HowService {
let tree:RustTree = await this.callZome('get_tree', null);
return tree.tree
}

async notify(signal: HowSignal, folks: Array<AgentPubKeyB64>): Promise<void> {
return this.callZome('notify', {signal, folks});
}
Expand Down
Loading

0 comments on commit e43583f

Please sign in to comment.