Files
bare-operating-system/examples/tui-dashboard/index.js
T
Raven Scott ddebf42f1c
Release rolling / release (push) Successful in 9m38s
TUI Updates p2
2026-08-12 22:55:38 -04:00

116 lines
3.1 KiB
JavaScript

/** Guest TUI dashboard. Raw JS: list + detail, resize-aware. */
async function run(ctx) {
if (!ctx.tui || !ctx.tui.isTTY()) {
ctx.console.error('tui-dashboard: needs a TTY')
ctx.exitCode = 1
return
}
const items = [
{
title: 'corestore',
desc: 'A namespaced collection of hypercores. Corestore manages many cores under one storage root.'
},
{
title: 'hyperswarm',
desc: 'Find and connect to peers by topic. Hole-punching and connection management.'
},
{
title: 'hypercore',
desc: 'A secure append-only log — the primitive everything is built on.'
},
{
title: 'hyperdrive',
desc: 'A distributed filesystem on hypercore and hyperbee. Replicated peer to peer.'
},
{
title: 'ctx.tui',
desc: 'Bare OS guest TUI on ctx. Raw JS, session streams, Fish suspend, VFS filepicker.'
}
]
function wrap(text, w) {
const out = []
for (const para of String(text).split('\n')) {
let line = ''
for (const word of para.split(' ')) {
if (line && line.length + 1 + word.length > w) {
out.push(line)
line = word
} else {
line = line ? line + ' ' + word : word
}
}
out.push(line)
}
return out.join('\n')
}
const LIST_W = 18
const app = {
list: ctx.tui.list.create({ items: items, height: 10, width: LIST_W }),
detail: ctx.tui.viewport.create({ width: 40, height: 10 }),
width: 80,
height: 24,
init: function () {
this._sync()
return null
},
_sync: function () {
const item = this.list.selectedItem()
this.detail.setContent(
item ? wrap(item.desc, this.detail.width || 40) : ''
)
this.detail.gotoTop()
},
_layout: function () {
const bodyH = Math.max(3, this.height - 5)
this.list.height = bodyH
this.detail.height = bodyH
this.detail.width = Math.max(10, this.width - LIST_W - 8)
this._sync()
},
update: function (msg) {
if (ctx.tui.key.matches(msg, 'q', 'ctrl+c')) return [this, ctx.tui.quit]
if (msg && msg.type === 'resize') {
this.width = msg.width
this.height = msg.height
this._layout()
}
const [list, lcmd] = this.list.update(msg)
this.list = list
this._sync()
const [detail, dcmd] = this.detail.update(msg)
this.detail = detail
return [this, lcmd || dcmd]
},
view: function () {
const left = ctx.tui
.style()
.border(ctx.tui.style.borders.rounded)
.width(LIST_W + 2)
.render(this.list.view())
const right = ctx.tui
.style()
.border(ctx.tui.style.borders.rounded)
.width(this.detail.width || 40)
.render(this.detail.view())
const body = ctx.tui.style.joinHorizontal(
ctx.tui.style.position.top,
left,
' ',
right
)
return (
ctx.tui.style().bold(true).render('dashboard') +
'\n' +
body +
'\n↑/↓ select · pgup/pgdn scroll · / filter · q quit'
)
}
}
await ctx.tui.run(app)
}