aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/components
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2023-04-01 17:54:07 -0400
committerXe Iaso <me@xeiaso.net>2023-04-01 17:54:07 -0400
commit06070a820f5a92c2671242b044cec5f6b3dacff5 (patch)
tree257be786bee080c0eb76941df827680eec9912f0 /src/frontend/components
parentc78d291679a0b054e20ad35784dd5a8f9238f0a9 (diff)
downloadxesite-06070a820f5a92c2671242b044cec5f6b3dacff5.tar.xz
xesite-06070a820f5a92c2671242b044cec5f6b3dacff5.zip
build javascript files with esbuild
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'src/frontend/components')
-rw-r--r--src/frontend/components/ConvSnippet.tsx56
-rw-r--r--src/frontend/components/MastodonShareButton.tsx76
-rw-r--r--src/frontend/components/WASITerm.tsx83
3 files changed, 195 insertions, 20 deletions
diff --git a/src/frontend/components/ConvSnippet.tsx b/src/frontend/components/ConvSnippet.tsx
index 02b2121..375ed9a 100644
--- a/src/frontend/components/ConvSnippet.tsx
+++ b/src/frontend/components/ConvSnippet.tsx
@@ -1,27 +1,43 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
export interface ConvSnippetProps {
- name: string;
- mood: string;
- children: HTMLElement[];
+ name: string;
+ mood: string;
+ children: HTMLElement[];
}
-const ConvSnippet = ({name, mood, children}: ConvSnippetProps) => {
- const nameLower = name.toLowerCase();
- name = name.replace(" ", "_");
+const ConvSnippet = ({ name, mood, children }: ConvSnippetProps) => {
+ const nameLower = name.toLowerCase();
+ name = name.replace(" ", "_");
- return (
- <div className="conversation">
- <div className="conversation-standalone">
- <picture>
- <source type="image/avif" srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.avif`} />
- <source type="image/webp" srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.webp`} />
- <img style="max-height:4.5rem" alt={`${name} is ${mood}`} loading="lazy" src={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.png`} />
- </picture>
- </div>
- <div className="conversation-chat">
- &lt;<a href={`/characters#${nameLower}`}><b>{name}</b></a>&gt; {children}
- </div>
- </div>
- );
+ return (
+ <div className="conversation">
+ <div className="conversation-standalone">
+ <picture>
+ <source
+ type="image/avif"
+ srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.avif`}
+ />
+ <source
+ type="image/webp"
+ srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.webp`}
+ />
+ <img
+ style="max-height:4.5rem"
+ alt={`${name} is ${mood}`}
+ loading="lazy"
+ src={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.png`}
+ />
+ </picture>
+ </div>
+ <div className="conversation-chat">
+ &lt;<a href={`/characters#${nameLower}`}>
+ <b>{name}</b>
+ </a>&gt; {children}
+ </div>
+ </div>
+ );
};
export default ConvSnippet;
diff --git a/src/frontend/components/MastodonShareButton.tsx b/src/frontend/components/MastodonShareButton.tsx
new file mode 100644
index 0000000..03fe596
--- /dev/null
+++ b/src/frontend/components/MastodonShareButton.tsx
@@ -0,0 +1,76 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
+import { u } from "xeact";
+
+export interface MastodonShareButtonProps {
+ title: string;
+ url: string;
+ series?: string;
+ tags: string;
+}
+
+export default function MastodonShareButton(
+ { title, url = u(), series, tags }: MastodonShareButtonProps,
+) {
+ let defaultURL = localStorage["mastodon_instance"];
+
+ if (defaultURL == undefined) {
+ defaultURL = "";
+ }
+
+ const tootTemplate = `${title}
+
+${url}
+
+${series ? "#" + series + " " : ""}${
+ tags ? tags.map((x) => "#" + x).join(" ") : ""
+ } @cadey@pony.social`;
+
+ const instanceBox = (
+ <input
+ type="text"
+ placeholder="https://pony.social"
+ value={defaultURL}
+ />
+ );
+ const tootBox = (
+ <textarea rows={6} cols={40}>
+ {tootTemplate}
+ </textarea>
+ );
+
+ return (
+ <div>
+ <details>
+ <summary>Share on Mastodon</summary>
+ <span>{"Instance URL (https://mastodon.example)"}</span>
+ <br />
+ {instanceBox}
+ <br />
+ {tootBox}
+ <br />
+ <button
+ onClick={() => {
+ let instanceURL = instanceBox.value;
+
+ if (!instanceURL.startsWith("https://")) {
+ instanceURL = `https://${instanceURL}`;
+ }
+
+ localStorage["mastodon_instance"] = instanceURL;
+ const text = tootBox.value;
+ const mastodonURL = u(instanceURL + "/share", {
+ text,
+ visibility: "public",
+ });
+ console.log({ text, mastodonURL });
+ window.open(mastodonURL, "_blank");
+ }}
+ >
+ Share
+ </button>
+ </details>
+ </div>
+ );
+}
diff --git a/src/frontend/components/WASITerm.tsx b/src/frontend/components/WASITerm.tsx
new file mode 100644
index 0000000..5f7e7f9
--- /dev/null
+++ b/src/frontend/components/WASITerm.tsx
@@ -0,0 +1,83 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
+import { t, x } from "xeact";
+import Terminal from "@xterm";
+import * as fitAdd from "@xterm/addon-fit";
+import { Fd, File, PreopenDirectory, WASI } from "@bjorn3/browser_wasi_shim";
+
+class XtermStdio extends Fd {
+ term: Terminal;
+
+ constructor(term: Terminal) {
+ super();
+ this.term = term;
+ }
+
+ fd_write(view8: Uint8Array, iovs: any) {
+ let nwritten = 0;
+ for (let iovec of iovs) {
+ console.log(
+ iovec.buf_len,
+ iovec.buf_len,
+ view8.slice(iovec.buf, iovec.buf + iovec.buf_len),
+ );
+ let buffer = view8.slice(iovec.buf, iovec.buf + iovec.buf_len);
+ this.term.write(buffer);
+ nwritten += iovec.buf_len;
+ }
+ return { ret: 0, nwritten };
+ }
+}
+
+const loadExternalFile = async (path: string) => {
+ return new File(await (await (await fetch(path)).blob()).arrayBuffer());
+};
+
+export interface WASITermProps {
+ href: string;
+ env: string[];
+ args: string[];
+}
+
+export default function WASITerm({ href, env, args }: WASITermProps) {
+ const root = <div style="max-width:80ch;max-height:20ch"></div>;
+
+ const term = new Terminal({
+ convertEol: true,
+ fontFamily: "Iosevka Curly Iaso",
+ });
+
+ const fit = new fitAdd.default();
+ term.loadAddon(fit);
+ fit.fit();
+
+ return (
+ <div>
+ {root}
+ <button
+ onClick={async () => {
+ term.writeln(`\x1B[93mfetching ${href}...\x1B[0m`);
+ const wasm = await WebAssembly.compileStreaming(fetch(href));
+ term.writeln("\x1B[93mdone, instantiating\x1B[0m");
+
+ const fds = [
+ new XtermStdio(term),
+ new XtermStdio(term),
+ new XtermStdio(term),
+ new PreopenDirectory("/tmp", {}),
+ ];
+
+ let wasi = new WASI(args, env, fds);
+ term.clear();
+ // let inst = await WebAssembly.instantiate(wasm, {
+ // "wasi_snapshot_preview1": wasi.wasiImport,
+ // });
+ // wasi.start(inst);
+ }}
+ >
+ Run
+ </button>
+ </div>
+ );
+}