Wednesday, 30 July 2026
Local filesystem access, remote projects proxy, file tree custom elements + icons, project-list-default tab UI.
The navigation in project-list-default now uses proper custom elements:
<pld-tabs> and <pld-tab> (previously
<div class="pld-tabs"> / <button class="pld-tab">).
The tabs are centred in the nav bar via
position: absolute; left: 50%; transform: translateX(-50%)
without interfering with the logo.
The This PC tab row was rewritten to use the same style as online project rows:
pld-name class, Barlow 5em weight, and a seeded hue via
hueFromId(folder) so each local folder gets a deterministic colour.
The subtitle / path line was removed for visual consistency.
The Electron app can now open any host directory as an editor workspace.
The This PC tab lets the user browse and select a local folder;
clicking opens the editor with a localRoot URL param.
Editor.ts gained a localRoot field and private
_readUrl / _writeUrl helpers that branch on
localRoot → remoteProject → projectId.
editor-shell.ts reads the localRoot URL param and sets it
on the Editor singleton. file-tree-panel.ts branches on
localRoot for all tree, read, write, rename, and delete operations,
routing through the /api/local/ routes (Node.js fs).
Root cause of the prior /api/files//tree 404 error: projectId
was '' when only localRoot was set, producing a double slash
in the URL. Fixed by the three-branch URL helper.
Online projects from roject.rokojori.com are now accessible in the
Electron app via a server-side reverse proxy. source/server/routes/remoteProxy.ts
is a catch-all router mounted at /api/remote: it strips the prefix,
prepends /api, and forwards the request to
roject.rokojori.com over HTTPS.
Authentication is automatic: the Electron onBeforeSendHeaders interceptor
already injects Authorization: Bearer <token> into every
localhost:3000 request, so the proxy receives the header and forwards it
upstream with no new IPC channel needed.
project-list-default gained an _isRemoteOnline flag and a
_projectUrl() helper that routes all API calls to /api/remote/projects
when the Online tab is active. Row clicks open the editor with a remoteProject
URL param; Editor.ts / editor-shell.ts read and apply it
the same way as localRoot.
All structural HTML in the file tree was converted to hyphenated custom elements:
<ftp-header>, <ftp-tree>, <ftp-list>,
<ftp-dir>, <ftp-dir-label>,
<ftp-file>, <ftp-inline-create>,
<ftp-inline-label>, <ftp-type-error>,
<ftp-empty>, <ftp-up>.
CSS selectors, DOM queries, and closest() calls updated throughout
(e.g. el.closest('ftp-dir') instead of el.closest('li')).
Directories now start closed. A CSS triangle indicator (border trick,
no character) on ftp-dir-label::before points right when closed and
rotates 90° on .open. Directories are sorted before files in
renderNodes. Files and directories get SVG icons via
<img src="/icons/...">; the same icons appear in
tab-container header tabs. SVG sources live in source/icons/
and are copied to build/app/icons/ by scripts/copy-pages.js.
Server-side proxy over dual-window approach for remote projects.
Option A (opening a second BrowserWindow pointed at the live site) would have
introduced version skew risk when the local Electron build diverges from the server.
Option B (proxy at /api/remote/**) keeps a single frontend, single
server, and lets onBeforeSendHeaders handle auth automatically.
Three-branch URL helper instead of hardcoded paths.
_readUrl / _writeUrl check localRoot first,
then remoteProject, then fall back to projectId. This keeps
all routing in one place and prevents the double-slash /api/files//tree
error that occurred when projectId was empty.
Hyphenated custom element names for all structural markup.
No <div class="name"> pattern anywhere in the file tree or
project list. CSS uses the element tag as the root selector, keeping selectors
short and scoped without class name collisions.