diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-04-01 17:54:07 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-04-01 17:54:07 -0400 |
| commit | 06070a820f5a92c2671242b044cec5f6b3dacff5 (patch) | |
| tree | 257be786bee080c0eb76941df827680eec9912f0 /src/frontend/components | |
| parent | c78d291679a0b054e20ad35784dd5a8f9238f0a9 (diff) | |
| download | xesite-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.tsx | 56 | ||||
| -rw-r--r-- | src/frontend/components/MastodonShareButton.tsx | 76 | ||||
| -rw-r--r-- | src/frontend/components/WASITerm.tsx | 83 |
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"> - <<a href={`/characters#${nameLower}`}><b>{name}</b></a>> {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"> + <<a href={`/characters#${nameLower}`}> + <b>{name}</b> + </a>> {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> + ); +} |
