works for now :)

This commit is contained in:
tsukino
2023-12-25 22:18:52 -08:00
parent 9a26776f0a
commit f1fb298827
4 changed files with 95 additions and 78 deletions

View File

@@ -14,7 +14,6 @@ export class CustomElement extends HTMLElement implements ICustomElement {
css: string;
html: string;
#tree?: VNode;
#approot?: any;
#lastAttrUpdated = 0;
#attrUpdateTimeout: any;
@@ -34,14 +33,14 @@ export class CustomElement extends HTMLElement implements ICustomElement {
return h('div');
}
refresh() {
if (this.shadowRoot) {
this.#tree = this.render();
this.shadowRoot.innerHTML = '';
this.shadowRoot.appendChild(html(`<style>${this.css}</style>`));
this.#tree.append(this.shadowRoot);
}
}
create = () => {
if (!this.shadowRoot) return;
this.#tree = this.render();
this.shadowRoot.innerHTML = '';
this.shadowRoot.appendChild(html(`<style>${this.css}</style>`));
this.#tree.append(this.shadowRoot);
};
get state() {
return Array.from(this.attributes).reduce(
@@ -55,8 +54,8 @@ export class CustomElement extends HTMLElement implements ICustomElement {
async connectedCallback() {
this.attachShadow({ mode: 'open' });
this.refresh();
await this.onmount();
this.create();
}
attributeChangedCallback(key: string, ov: string, nv: string) {
@@ -73,7 +72,7 @@ export class CustomElement extends HTMLElement implements ICustomElement {
this.#attrUpdateTimeout = null;
}
this.#lastAttrUpdated = now;
this.refresh();
await this.update();
};
if (timeSince > wait) {
@@ -95,10 +94,13 @@ export class CustomElement extends HTMLElement implements ICustomElement {
if (!this.shadowRoot) return;
if (!this.#tree) {
this.refresh();
this.create();
} else if (this.#tree) {
await this.onupdate();
this.#tree.update();
const oldTree = this.#tree;
const newTree = this.render();
newTree.patch(oldTree.el);
this.onupdated();
}
};
@@ -134,8 +136,6 @@ export class VNode {
style?: CSSStyleDeclaration;
parentNode?: VNode;
content?: string;
#patches: (() => any)[] = [];
#updates: (() => any)[] = [];
#el?: any;
constructor(options: VNodeProps) {
@@ -146,7 +146,6 @@ export class VNode {
this.style = options.style;
this.content = options.content;
this.children = options.children || [];
this.#updates = [];
for (const node of this.children) {
node.parentNode = this;
@@ -165,21 +164,67 @@ export class VNode {
return this;
}
addPatch(patchFn: () => void) {
this.#patches.push(patchFn);
}
append(root: ShadowRoot) {
return new Promise(() => {
const frag = this.createElement();
root.append(frag);
return frag;
});
const frag = this.createElement();
root.append(frag);
return frag;
}
update() {
for (const update of this.#updates) {
update();
patch(rootElement: Element) {
const frag = this.createElement();
const lastEl = rootElement;
const newEl = frag.children[0];
this._patchOne(lastEl, newEl);
}
_patchOne(lastEl: Element, newEl: Element) {
if (lastEl.tagName !== newEl.tagName) {
lastEl.replaceWith(newEl);
return;
}
if (newEl.attributes.length) {
for (const attr of Array.from(newEl.attributes)) {
if (lastEl.getAttribute(attr.name) !== attr.value) {
lastEl?.setAttribute(attr.name, attr.value);
}
}
}
if (newEl.classList.length) {
for (const name of Array.from(newEl.classList)) {
if (!lastEl.classList.contains(name)) {
lastEl?.classList.add(name);
}
}
}
if (lastEl.classList.length) {
for (const name of Array.from(newEl.classList)) {
if (!newEl.classList.contains(name)) {
lastEl?.classList.remove(name);
}
}
}
if (lastEl.tagName === 'TEXT' && lastEl.textContent !== newEl.textContent) {
lastEl.textContent = newEl.textContent;
}
const maxlength = Math.max(newEl.children.length, lastEl.children.length);
for (let i = 0; i < maxlength; i++) {
const lastChild = lastEl.children[i];
const newChild = newEl.children[i];
if (lastChild && newChild) {
this._patchOne(lastChild, newChild);
} else if (!lastChild && newChild) {
lastEl.append(newChild);
} else if (lastChild && !newChild) {
lastEl.removeChild(lastChild);
}
}
}
@@ -216,16 +261,6 @@ export class VNode {
el.appendChild(childFrag);
}
if (this.#patches.length) {
const patch = () => {
this.#patches.forEach((fn) => {
fn();
});
};
this.rootNode.#updates.push(patch);
}
this.#el = el;
return frag;
@@ -252,8 +287,6 @@ export const h = (
const id = name.match(/(?<=[#*])([^.#\[\]]*)+?(?=[(#.\s\[)*])?/g);
const attributes = name.match(/(?<=[\[])([^.#\[\]]*)+?(?=[\]*])?/g) || [];
const patches: (() => { from: VNode | VNode[]; to: VNode | VNode[] })[] = [];
let options: VNodeProps = {
tagName: tagName![0],
classList: classList || [],
@@ -286,20 +319,6 @@ export const h = (
...options,
});
for (const patch of patches) {
vnode.addPatch(() => {
if (!vnode.el) return;
const { from, to } = patch();
if (Array.isArray(to)) {
vnode.el.append(...to.map((n) => n.createElement()));
} else if (!Array.isArray(from)) {
from.el.replaceWith(to.createElement());
}
});
}
return vnode;
function reduceChildren(
@@ -342,16 +361,6 @@ export const h = (
retNodes = [nodes];
}
const oldNodes = nodes;
patches.push(() => {
const newNodes = nodeOrText();
return {
from: oldNodes,
to: newNodes,
};
});
return retNodes as VNode[];
}

View File

@@ -19,25 +19,26 @@ export default class ProfileImage extends CustomElement {
attributeChangedCallback(key: string, ov: string, nv: string) {
super.attributeChangedCallback(key, ov, nv);
// console.log('changing profile-image attr', key, nv);
this.update();
}
async onmount() {
const { creator } = this.state;
const store = getStore();
const node: NodeStore = store.get('node');
const user = await node.node.db.db.getProfile(creator || '');
const user = await node.getUser(this.state.creator || '');
let url =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAABNZJREFUeF7tnFmW6jAMRJP975Ut0CcNnc5gR6XRcmL+HtFQqitDMzzm1+v1nsbN1oF5nqa3zNZ5ALFlUao2T9OE4ukXCGdKynNOLU4s0bdUigZSE2AojPIr+3VLK1YglkWzG5hZH31CMquvaku4XqAkNZD1DwqwoZ4v2AgM0+vRVDiLVANZ5HQxO+ib7yx0dRMg66x0P9AWfljD1nyxFxm2QEylIcW0GLT5lEZ+fRAIvzAl9enXq68moFfqFA/qemL3s0m/PCHZxCbmei2NYST4kAVawWgMVgTCbJqqq5AF/gOuQm2BCN67ARz3DyHNpCUYlPhtEgqEHksasdix3ND3VKV9/PPcgGAbU48qXcFq+pvm2cENCCb6CRZjTvxFNQbCE9t1NLh7sUBAUWmN3+j3GsUByDzN0/vw9OolPyE65qjHcDUQZn9jB9t2Nx6mzz97QxGENvvgLZwQZxVG5Y3KeCy5qmbxIQsaFgpSacub7DX7fJtX6nnZkcoOcNVP6mTDEcByYABh2aULRh7p3IBcN0ekgcMblgI74mECbW5ASNWnV0R+b9ZyfeHGk7MyAphAFFIVqYx5DEIpodR13feimEAM5tWWAPwgW1jUIJvIAkRA/OfRdEBz0biNsVTK9joVW+H1BSLMli0BkQVoAUJcpAUUFZ2QAF2PbWEE5MYrG7waRkBiVMPY4UCmbq+626cp6JuLTN2PCC/CqRNDWXZ1Qp4A+jZA0A1EoFrWQvptYxoAaTku1574+HggCXhIJEhyJP+1LB7IcekEkwpS4lcd6bgb5PMPGsiaJLChkCKogox2mxgayG1GLQ9iuiCaYsvn6e/xmXrQuuGkHnJCcEP4hGxr3wAIaEjhCZRvvjIDkEoAOVQACtKSTYrQbTqNAE/IMDGKLwjERk7XWIPEhwKxwdp3FYrrAJKM7wYIxa6knJfDi07m1EmOzzTjhDTgfvWjpWcgbPDsBDsLGra2G2JfiTwhN5zZy0tR3aO/JJC1yyCj+44oiAsHon9OByUlCGu4fDogCby7k4RlD3yBWGyaRY2OqPkCuTCi7PNy73LL96s+UXvRDEgfS2uFAa/jCAQX0QccnUrUDR4QtKpOO/uBzq1dg8JlIFfGN4fi6ZLzcED5IpDLPKCoh2WN2tZHcRJ08ZDF6ciJ9cDlVPM7VuR0vOcQzdyRU2l0Vt+RiBkgDoi1Sc3qlcBs76uAA3kOIJ5gQQhbCQOIJxBB7fZABFskmLObFCEQwkVjk5FySMyJiijJl+0eSEKBvuPnqy48IT6DxO9DfEfKuVRAKLF3vv63Gu5A8u1gbqyOQAYKCfpfICfr1jsiTV0PbcpPDCXmSnLMT0gkQsnAa06EUEEPcyAqk0ay37dOBMvRLQ75rOfMfCdEPp3rh0n/sgoCDTXnA9LtOQGFb776Xnwjv/R7WYbAaZVOzZzK0vNUIlA96hOCNhJPok1ML3A/oBqI1q+m+QlhNQWS0A96P5xFxwNxHoh29CpCKa6ajtVdotyBYFJ0Nt4pmwckm7vZ9BQ3gyeSB6TBKvLGaSDQuGV6IMbzfsq5U5Y3UAGRt3Wx+VzUU6CoNp2kAhJkq28b2iNGf30xBZBK8+/d+6t6oQxXug5VADnObW+6fcX8rPhAnuhSIEc+kEBxT2z1A58ObwvXw1MMAAAAAElFTkSuQmCC';
if (user.profileImageUrl) {
url = user.profileImageUrl;
} else if (creator) {
url = 'data:image/svg+xml;utf8,' + minidenticon(creator, 50, 50);
}
user?.subscribe((u) => {
let url =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAABNZJREFUeF7tnFmW6jAMRJP975Ut0CcNnc5gR6XRcmL+HtFQqitDMzzm1+v1nsbN1oF5nqa3zNZ5ALFlUao2T9OE4ukXCGdKynNOLU4s0bdUigZSE2AojPIr+3VLK1YglkWzG5hZH31CMquvaku4XqAkNZD1DwqwoZ4v2AgM0+vRVDiLVANZ5HQxO+ib7yx0dRMg66x0P9AWfljD1nyxFxm2QEylIcW0GLT5lEZ+fRAIvzAl9enXq68moFfqFA/qemL3s0m/PCHZxCbmei2NYST4kAVawWgMVgTCbJqqq5AF/gOuQm2BCN67ARz3DyHNpCUYlPhtEgqEHksasdix3ND3VKV9/PPcgGAbU48qXcFq+pvm2cENCCb6CRZjTvxFNQbCE9t1NLh7sUBAUWmN3+j3GsUByDzN0/vw9OolPyE65qjHcDUQZn9jB9t2Nx6mzz97QxGENvvgLZwQZxVG5Y3KeCy5qmbxIQsaFgpSacub7DX7fJtX6nnZkcoOcNVP6mTDEcByYABh2aULRh7p3IBcN0ekgcMblgI74mECbW5ASNWnV0R+b9ZyfeHGk7MyAphAFFIVqYx5DEIpodR13feimEAM5tWWAPwgW1jUIJvIAkRA/OfRdEBz0biNsVTK9joVW+H1BSLMli0BkQVoAUJcpAUUFZ2QAF2PbWEE5MYrG7waRkBiVMPY4UCmbq+626cp6JuLTN2PCC/CqRNDWXZ1Qp4A+jZA0A1EoFrWQvptYxoAaTku1574+HggCXhIJEhyJP+1LB7IcekEkwpS4lcd6bgb5PMPGsiaJLChkCKogox2mxgayG1GLQ9iuiCaYsvn6e/xmXrQuuGkHnJCcEP4hGxr3wAIaEjhCZRvvjIDkEoAOVQACtKSTYrQbTqNAE/IMDGKLwjERk7XWIPEhwKxwdp3FYrrAJKM7wYIxa6knJfDi07m1EmOzzTjhDTgfvWjpWcgbPDsBDsLGra2G2JfiTwhN5zZy0tR3aO/JJC1yyCj+44oiAsHon9OByUlCGu4fDogCby7k4RlD3yBWGyaRY2OqPkCuTCi7PNy73LL96s+UXvRDEgfS2uFAa/jCAQX0QccnUrUDR4QtKpOO/uBzq1dg8JlIFfGN4fi6ZLzcED5IpDLPKCoh2WN2tZHcRJ08ZDF6ciJ9cDlVPM7VuR0vOcQzdyRU2l0Vt+RiBkgDoi1Sc3qlcBs76uAA3kOIJ5gQQhbCQOIJxBB7fZABFskmLObFCEQwkVjk5FySMyJiijJl+0eSEKBvuPnqy48IT6DxO9DfEfKuVRAKLF3vv63Gu5A8u1gbqyOQAYKCfpfICfr1jsiTV0PbcpPDCXmSnLMT0gkQsnAa06EUEEPcyAqk0ay37dOBMvRLQ75rOfMfCdEPp3rh0n/sgoCDTXnA9LtOQGFb776Xnwjv/R7WYbAaZVOzZzK0vNUIlA96hOCNhJPok1ML3A/oBqI1q+m+QlhNQWS0A96P5xFxwNxHoh29CpCKa6ajtVdotyBYFJ0Nt4pmwckm7vZ9BQ3gyeSB6TBKvLGaSDQuGV6IMbzfsq5U5Y3UAGRt3Wx+VzUU6CoNp2kAhJkq28b2iNGf30xBZBK8+/d+6t6oQxXug5VADnObW+6fcX8rPhAnuhSIEc+kEBxT2z1A58ObwvXw1MMAAAAAElFTkSuQmCC';
if (u.profileImageUrl) {
url = u.profileImageUrl;
} else if (this.state.creator) {
url =
'data:image/svg+xml;utf8,' + minidenticon(this.state.creator, 50, 50);
}
// console.log('setting src', url);
this.setAttribute('src', url);
this.setAttribute('src', url);
});
}
}

View File

@@ -1,4 +1,4 @@
import { CustomElement, h, register, xh } from '../../../lib/ui.ts';
import { CustomElement, h, register } from '../../../lib/ui.ts';
import { getStore } from '../../state';
import { default as NodeState } from '../../state/node.ts';
import '../../components/Post';

View File

@@ -12,6 +12,7 @@ export default class Node extends Store {
$globalPosts = new Observable<string[]>([]);
$posts = new ObservableMap<string, Post>();
$users = new ObservableMap<string, any>();
constructor(options?: StateOptions) {
super(options);
@@ -20,7 +21,7 @@ export default class Node extends Store {
bootstrap: [
'/ip4/127.0.0.1/tcp/64029/ws/p2p/12D3KooWG1yjigfXNQtfkLC8TbzoSreeDx8User1Q5wo49MUK1NB',
'/ip4/192.168.86.30/tcp/64029/ws/p2p/12D3KooWG1yjigfXNQtfkLC8TbzoSreeDx8User1Q5wo49MUK1NB',
'/ip4/192.168.86.24/tcp/64029/ws/p2p/12D3KooWG1yjigfXNQtfkLC8TbzoSreeDx8User1Q5wo49MUK1NB'
'/ip4/192.168.86.24/tcp/64029/ws/p2p/12D3KooWG1yjigfXNQtfkLC8TbzoSreeDx8User1Q5wo49MUK1NB',
],
});
this.node = node;
@@ -63,4 +64,10 @@ export default class Node extends Store {
getPost = async (hash: string): Promise<Post | null> => {
return this.node.db.db.getMessage(hash) as Promise<Post | null>;
};
getUser = async (creator = '') => {
const profile = await this.node.db.db.getProfile(creator);
this.$users.set(creator, profile);
return this.$users.get(creator);
};
}