ScratchIndexPage
uses node:fs
The scratch files: the work not saved to the codebase yet, newest first, each with the namespace it saves to, and a button starting another.
import { ago, at, servedCodebase, shareNow } from "#codebase/tcmts/share"; import { keptFile, NewScratchButton, scratchDir, scratchFiles, StudioFrame, studioShare } from "#codebase/tcmts/studio"; import fs from "node:fs"; import path from "node:path"; export async function ScratchIndexPage() { studioShare(); const s = shareNow(); if (!s.signedIn) return ( <StudioFrame tab="scratch" title="Sign in"> {null} </StudioFrame> ); const own = servedCodebase().cb; const files = scratchFiles(own).map((f) => { const text = fs.readFileSync(path.join(scratchDir(own), f.file), "utf8"); const abs = path.join(scratchDir(own), f.file); const kept = /\.tsx?$/.test(f.file) ? undefined : keptFile(own, abs, text); return { ...f, ns: kept ? undefined : /^\/\/ tcm: namespace (\S+)/m.exec(text)?.[1], kept, empty: !text.trim(), }; }); return ( <StudioFrame tab="scratch" title="Scratch files"> <div className="pagehead"> <h2 className="title">Scratch files</h2> {s.cb === own && ( <div className="right"> <NewScratchButton /> </div> )} </div> <div className="box"> {files.length ? ( files.map((f) => ( <a className="lrow tracerow" key={f.file} href={at(`/scratch/${encodeURIComponent(f.file)}`)} > <div> <span className="mono">{f.file}</span>{" "} <span className="muted"> {f.kept ? `goes back to ${f.kept}` : f.empty ? "empty" : f.ns ? `in ${f.ns}` : ""} </span> </div> <span className="muted">{`changed ${ago(f.at)}`}</span> </a> )) ) : ( <div className="empty"> None: a scratch file holds code on its way into the codebase. Edit on a definition's page writes it into one. </div> )} </div> </StudioFrame> ); }
uses
- tcmts.share.ago
- tcmts.share.at
- tcmts.share.servedCodebase
- tcmts.share.shareNow
- tcmts.studio.NewScratchButton
- tcmts.studio.StudioFrame
- tcmts.studio.keptFile
- tcmts.studio.scratchDir
- tcmts.studio.scratchFiles
- tcmts.studio.studioShare