Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: AD4M integration #3

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5110902
Persist profile in AD4M's public agent perspective
lucksus Jan 29, 2022
31608a5
Merge branch 'main' into ad4m
lucksus Jan 29, 2022
c00a802
Boilerplate ad4m language wired-up to clutter DNA
lucksus Jan 29, 2022
0f60e4c
gitignore
lucksus Jan 29, 2022
b5f3e74
Merge branch 'main' into ad4m
lucksus Jan 29, 2022
41ce213
Compiling Mew components for ad4m language icons
lucksus Jan 29, 2022
09fc569
Merge branch 'main' into ad4m
lucksus Jan 29, 2022
b0a3f91
Merge branch 'main' into ad4m
lucksus Jan 31, 2022
933bb00
WIP: Clutter AD4M Language integration
lucksus Feb 1, 2022
724378a
route to ad4m profile page for test
weswalla Feb 17, 2022
3e0ae42
Merge branch 'mew-interaction-feature' into ad4m
weswalla Feb 17, 2022
b2a8d18
use ad4m mew language when creating mews and viewing mews feed
weswalla Feb 17, 2022
dcbd544
initial icon and added script to visually test icon
weswalla Feb 17, 2022
df6f49b
WIP: basic mew icon (still needs to interact with ad4m
weswalla Feb 18, 2022
d76935c
Merge branch 'mew-interaction-feature' into ad4m
weswalla Feb 22, 2022
51cdc66
mew expression icon complete and works in perspect3ve
weswalla Mar 2, 2022
e11b178
use entry header data for ad4m expression author and timestamp
weswalla Mar 2, 2022
c1bff41
add agent key and timestamp from mew header to ad4m expression metadata
weswalla Mar 10, 2022
e496aae
added interaction for licking mew
weswalla Mar 11, 2022
7284da8
use interaction in icon for licking mew, added unlick mew interaction
weswalla Mar 11, 2022
d684453
added basic follow feature (by DID) and show mews of following
weswalla Mar 11, 2022
b3a292d
bumped clutter dna to hdk 0.0.123
weswalla Mar 23, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ad4m-language/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.js
*.js.map
node_modules
build
dist-mew
dist-mew-constructor
!main.js
!rollup.config.icons.dev.js
!rollup.config.icons.js
42 changes: 42 additions & 0 deletions ad4m-language/ConstructorIcon.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<svelte:options tag={null}/>

<script lang="ts">
export let commitExpression
export let mewType
export let discard

let text = ""
if (!mewType) {
mewType = {
original: null
}
}
function createMewInput(text) {
let createMewInput = {
mewType: mewType,
mew: text
}
return createMewInput
}

</script>

<div class="container">
<input bind:value={text}>
<button on:click={()=>commitExpression(createMewInput(text))}>Publish Mew</button>
<button on:click={discard}>Discard</button>
</div>


<style>
.container {
color: burlywood;
width: 400px;
height: 300px;
}

input {
width: 100%;
height: 200px;
}
</style>
96 changes: 96 additions & 0 deletions ad4m-language/Icon.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<svelte:options tag={null}/>

<script lang="ts">
import type Expression from "@perspect3vism/ad4m/Expression";
import type ExpressionClient from "@perspect3vism/ad4m/ExpressionClient";
import { InteractionCall } from "@perspect3vism/ad4m"

export let expression: Expression
export let createExpression
export let expressionClient: ExpressionClient
let feedMewWithContext
$: if(expression && expression.data) {
console.log('expression from icon:', expression)
feedMewWithContext = JSON.parse(expression.data)
}

let text = ""
let isReplying = false
let isMewMewing = false
async function togglelickMew() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this look @lucksus ?

console.log(feedMewWithContext.mewEntryHash)
const interactionCall = new InteractionCall('lick-mew', { entryHash: feedMewWithContext.mewEntryHash })
const exprAddr = `${expression.language.address}://${feedMewWithContext.mewEntryHash}`
await expressionClient.interact(exprAddr, interactionCall)
// TODO: first check if agent key is in the list of liked mews, then lick or unlick accordingly
}
function replyToMew() {
if (isMewMewing) {
isMewMewing = !isMewMewing
}
isReplying = !isReplying
}
function shareMew() {
const createMewInput = {
mewType: {
reMew: feedMewWithContext.mewEntryHash
},
mew: null
}
createExpression(createMewInput)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could also get replaced with expressionClient.create()

}
function mewMew() {
if (isReplying) {
isReplying = !isReplying
}
isMewMewing = !isMewMewing
}
function createMewInput(text) {
let mewType = isReplying ? { reply: feedMewWithContext.mewEntryHash } : { mewMew: feedMewWithContext.mewEntryHash }
let createMewInput = {
mewType: mewType,
mew: text
}
return createMewInput
}
</script>

<div class="container">
{#if expression}
<div class="avatar-box"></div>
<div class="mew-meta">
{expression.author} {expression.timestamp}
</div>
<div class="mew-content">
<p>{feedMewWithContext.feedMew.mew.mew.mew}</p>
</div>
<div class="mew-interactions">
<button on:click={async () => togglelickMew()}>lick ({feedMewWithContext.licks.length})</button>
<button on:click={() => replyToMew()}>reply ({feedMewWithContext.comments.length})</button>
<button on:click={() => shareMew()}>share ({feedMewWithContext.shares.length})</button>
<button on:click={() => mewMew()}>mewmew ({feedMewWithContext.shares.length})</button>
</div>
{#if isReplying}
<input bind:value={text}>
<button on:click={()=>createExpression(createMewInput(text))}>Publish Mew</button>
{:else if isMewMewing}
<input bind:value={text}>
<button on:click={()=>createExpression(createMewInput(text))}>Publish Mew</button>
{/if}
{/if}
</div>


<style>
.container {
width: 400px;
height: 300px;
background-color: lightblue;
}
.avatar-box {
width: 50px;
height: 50px;
border-radius: 50px;
background: blue;
}
</style>
88 changes: 88 additions & 0 deletions ad4m-language/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import type { Address, Agent, Expression, PublicSharing, LanguageContext, HolochainLanguageDelegate, ExpressionAdapter, AgentService, Interaction } from "@perspect3vism/ad4m";
import { DNA_NICK } from "./dna";
import { serializeHash } from "@holochain-open-dev/core-types";
import { Base64 } from 'js-base64';

export default class ExpressionAdapterImpl implements ExpressionAdapter {
#DNA: HolochainLanguageDelegate;
#agent: AgentService;
putAdapter: PublicSharing

constructor(context: LanguageContext) {
this.#DNA = context.Holochain as HolochainLanguageDelegate;
this.#agent = context.agent;
this.putAdapter = new Sharing(context)
}

async get(mewAddress: Address): Promise<Expression> {
const fullMewWithContext = await this.#DNA.call(
DNA_NICK,
"mews",
"get_feed_mew_and_context",
mewAddress
);
const author = serializeHash(new Uint8Array(fullMewWithContext.feedMew.header.author.data))
const timestamp = fullMewWithContext.feedMew.header.timestamp
return {
author: author,
timestamp: timestamp,
data: fullMewWithContext,
proof: {
key: 'none',
signature: 'none'
}
}
};

async interactions(expressionAddress: Address): Promise<Interaction[]> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the right idea @lucksus

return [{
label: 'lick a mew',
name: 'lick-mew',
parameters: [['entryHash','object']],
execute: async (parameters: object) => {
const mewAddress = parameters['entryHash']
await this.#DNA.call(
DNA_NICK,
"mews",
"lick_mew",
mewAddress
)
}
},
{
label: 'unlick a mew',
name: 'unlick-mew',
parameters: [['entryHash','object']],
execute: async (parameters: object) => {
const mewAddress = parameters['entryHash']
await this.#DNA.call(
DNA_NICK,
"mews",
"unlick_mew",
mewAddress
)
}
}]
}
}

class Sharing implements PublicSharing {
#DNA: HolochainLanguageDelegate;
#agent: AgentService;

constructor(context: LanguageContext) {
this.#DNA = context.Holochain as HolochainLanguageDelegate;
this.#agent = context.agent;
}

async createPublic(mewObject: object): Promise<Address> {
const address = await this.#DNA.call(
DNA_NICK,
"mews",
"create_mew",
mewObject
);

return address
}
}
4 changes: 4 additions & 0 deletions ad4m-language/dna.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dna from "../dnas/clutter/workdir/clutter.dna";

export const DNA = Buffer.from(dna, "base64");
export const DNA_NICK = "clutter";
13 changes: 13 additions & 0 deletions ad4m-language/expressionUI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { ExpressionUI } from "@perspect3vism/ad4m";
import Icon from './build/Icon.js'
import ConstructorIcon from './build/ConstructorIcon.js'

export class UI implements ExpressionUI {
icon(): string {
return Icon
}

constructorIcon(): string {
return ConstructorIcon
}
}
11 changes: 11 additions & 0 deletions ad4m-language/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Svelte App</title>
<script defer src="build/icon-bundle.js"></script>
</head>
<body></body>
</html>
28 changes: 28 additions & 0 deletions ad4m-language/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Address, Agent, Language, LanguageContext, HolochainLanguageDelegate, Interaction } from "@perspect3vism/ad4m";
import ExpressionAdapter from "./adapter";

import { UI } from "./expressionUI";
import { DNA, DNA_NICK } from "./dna";



function interactions(expression: Address): Interaction[] {
return [];
}

export const name = "clutter";

export default async function create(context: LanguageContext): Promise<Language> {
const Holochain = context.Holochain as HolochainLanguageDelegate;
await Holochain.registerDNAs([{ file: DNA, nick: DNA_NICK }]);

const expressionAdapter = new ExpressionAdapter(context);
const expressionUI = new UI();

return {
name,
expressionAdapter,
interactions,
expressionUI,
} as Language;
}
17 changes: 17 additions & 0 deletions ad4m-language/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import App from './Icon.svelte';

const expression = {
author: 'unknown',
timestamp: 'unknown',
data: '{"feedMew":{"mew":{"mewType":{"original":null},"mew":{"mew":"creating a mew!"}},"header":{"type":"Create","author":{"type":"Buffer","data":[132,32,36,186,86,176,212,167,6,145,108,225,172,236,229,46,72,224,134,148,218,129,184,207,70,245,63,201,156,56,148,167,21,134,59,226,20,60,70]},"timestamp":1645074844495627,"header_seq":5,"prev_header":{"type":"Buffer","data":[132,41,36,235,154,154,117,54,170,234,91,126,69,140,99,147,170,115,238,38,123,240,254,76,113,233,53,148,148,150,27,128,199,247,194,230,243,127,204]},"entry_type":{"App":{"id":2,"zome_id":1,"visibility":{"Public":null}}},"entry_hash":{"type":"Buffer","data":[132,33,36,116,50,17,86,115,69,106,23,117,208,110,61,50,111,49,35,64,147,83,148,74,241,30,61,230,188,103,37,224,29,196,36,127,138,174,48]}}},"mewEntryHash":"uhCEkdDIRVnNFahd10G49Mm8xI0CTU5RK8R495rxnJeAdxCR_iq4w","comments":[],"shares":[],"licks":[]}',
language: { address: 'QmcWWYnz494S2yucuZb3f1TczqfuAWjvNgRC3wZkB3mPqW' },
proof: { valid: null, invalid: true }
}
const app = new App({
target: document.body,
props: {
expression: expression,
},
});

export default app;
Loading