Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 1 | // The Runner window's work: the runner on its own, live. What it is |
| 2 | // doing, each kind of job and the job each is running, how jobs run and for | |
| 3 | // which workspace, its updates and its log, from the app's status | |
| 4 | // (src/runner/mod.rs View, in diagnosis.rs's words), and each change kept | |
| 5 | // the moment it is made. Everything it asks is a command in src/bridge.rs. | |
| 6 | (function () { | |
| 7 | function byId(id) { | |
| 8 | return document.getElementById(id); | |
| 9 | } | |
| 10 | ||
| 11 | function invoke(command, args) { | |
| 12 | var core = window.__TAURI__ && window.__TAURI__.core; | |
| 13 | if (core && typeof core.invoke === "function") return core.invoke(command, args || {}); | |
| 14 | return Promise.reject(new Error("This page belongs inside the g1t desktop app.")); | |
| 15 | } | |
| 16 | ||
| 17 | function fail(error) { | |
| 18 | var box = byId("error"); | |
| 19 | box.textContent = typeof error === "string" ? error : (error && error.message) || "That could not be changed."; | |
| 20 | box.hidden = false; | |
| 21 | } | |
| 22 | ||
| 23 | // What each way of running jobs can reach, said plainly (src/runner/backend.rs). | |
| 24 | var BACKENDS = { | |
| 25 | sandboxed: { text: "The runner and every job run in a sandbox of their own. Nothing a job does reaches this computer.", warn: false }, | |
| 26 | docker: { | |
| 27 | text: "Each job runs in a container of its own, but the runner controls this computer's Docker, which can reach your files. Not a sandbox.", | |
| 28 | warn: true, | |
| 29 | }, | |
| 30 | host: { | |
| 31 | text: "Jobs run directly on this computer, as you: they can read, change and delete anything your account can. For jobs that need this system itself, such as building a Windows installer.", | |
| 32 | warn: true, | |
| 33 | }, | |
| 34 | }; | |
| 35 | var current = null; | |
| 36 | ||
| 37 | // ── The runner ────────────────────────────────────────────────────── | |
| 38 | // Its diagnosis, from src/runner/diagnosis.rs, as the tray and the | |
| 39 | // site's Runners page show it; its buttons are the fixes. | |
| 40 | function option(value, text) { | |
| 41 | var item = document.createElement("option"); | |
| 42 | item.value = value; | |
| 43 | item.textContent = text; | |
| 44 | return item; | |
| 45 | } | |
| 46 | ||
| Merge branch 'main' into rm-agents | 47 | var busy = window.g1tBusy; |
| 48 | ||
| 49 | // The whole runner's status, as far as a button waits on it: a press is | |
| 50 | // done when any of this changes (busy.js). | |
| 51 | function runnerStatus(runner) { | |
| 52 | var d = runner.diagnosis; | |
| 53 | var update = d.update || {}; | |
| 54 | return JSON.stringify([d.code, d.tone, d.title, d.cause, runner.chip.label, runner.enabled, runner.paused, update.checking, update.checked_at, update.ready]); | |
| 55 | } | |
| 56 | ||
| 57 | // One kind of job's, with the whole runner's. | |
| 58 | function kindStatus(kind, runner) { | |
| 59 | return JSON.stringify([runnerStatus(runner), kind.state, kind.enabled, kind.tone, kind.title, kind.cause]); | |
| 60 | } | |
| 61 | ||
| 62 | // A fix's button. Choosing is done here, in this window; a copy says it | |
| 63 | // was copied. One that changes the runner (the catalogue says which: | |
| 64 | // `waits`) stays busy until the status that follows; one the catalogue | |
| 65 | // asks about first (`confirm`) asks. | |
| 66 | function actionButton(action, primary, key, status) { | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 67 | var button = document.createElement("button"); |
| 68 | button.type = "button"; | |
| 69 | button.textContent = action.label; | |
| 70 | if (primary) button.className = "primary"; | |
| Merge branch 'main' into rm-agents | 71 | key = key + ":" + action.id; |
| 72 | if (busy.pressed(key, status)) busy.start(button); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 73 | button.addEventListener("click", function () { |
| 74 | if (action.id === "choose_workspace") return byId("runnerWorkspace").focus(); | |
| 75 | if (action.id === "choose_backend") return byId("runnerBackend").focus(); | |
| Merge branch 'main' into rm-agents | 76 | if (action.confirm && !window.confirm(action.confirm)) return; |
| 77 | busy.run(button, key, status, !!action.waits, function () { | |
| 78 | return invoke("runner_control", { action: action.id }); | |
| 79 | }, fail).then(function (done) { | |
| 80 | if (!done || action.id.indexOf("copy_") !== 0) return; | |
| 81 | button.textContent = "Copied"; | |
| 82 | setTimeout(function () { | |
| 83 | button.textContent = action.label; | |
| 84 | }, 2000); | |
| 85 | }); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 86 | }); |
| 87 | return button; | |
| 88 | } | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 89 | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 90 | function element(tag, className, text) { |
| 91 | var item = document.createElement(tag); | |
| 92 | if (className) item.className = className; | |
| 93 | if (text != null) item.textContent = text; | |
| 94 | return item; | |
| 95 | } | |
| 96 | ||
| 97 | // The catalogue's sentences name commands in backticks: `wsl --install`. | |
| 98 | // Said here as code, which can be selected and copied. | |
| 99 | function prose(into, text) { | |
| 100 | into.textContent = ""; | |
| 101 | String(text || "") | |
| 102 | .split("`") | |
| 103 | .forEach(function (part, at) { | |
| 104 | if (!part) return; | |
| 105 | into.appendChild(at % 2 ? element("code", null, part) : document.createTextNode(part)); | |
| 106 | }); | |
| 107 | return into; | |
| 108 | } | |
| 109 | ||
| 110 | // ── Each kind of job, a card of its own ─────────────────────────────── | |
| 111 | // Linux jobs and Windows jobs (macOS jobs once they are released): what | |
| 112 | // each is doing, why one isn't running and its fix, and its own Start or | |
| 113 | // Stop, which leaves the other as it is. The words are the app's | |
| 114 | // (CapabilityLine in src/runner/diagnosis.rs); the card only lays them out. | |
| 115 | var SVG = "http://www.w3.org/2000/svg"; | |
| 116 | // Plain line icons, 16px on a 24px grid: a terminal for Linux jobs, a | |
| 117 | // window for Windows jobs, a laptop for macOS jobs. | |
| 118 | var ICONS = { | |
| 119 | linux: ["M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1z", "M7 10l3 2.5L7 15", "M12.5 15h4"], | |
| 120 | windows: ["M4 4h16a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z", "M3 9h18", "M6.5 6.5h.01", "M9 6.5h.01"], | |
| 121 | macos: ["M5 6a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v9H5z", "M2.5 18.5h19", "M3.5 18.5L5 15h14l1.5 3.5"], | |
| 122 | }; | |
| 123 | // How each runner keeps a job from this computer, said plainly. | |
| 124 | var ISOLATION = { "nested-container": "A fresh container in the VM", vm: "A VM of its own", container: "A container of its own", host: "None" }; | |
| 125 | var BUSY = { busy: true, starting: true, downloading: true, updating: true }; | |
| 126 | var cards = {}; | |
| 127 | ||
| 128 | // A small arrow: the link goes out to g1t. | |
| 129 | function outward() { | |
| 130 | var svg = document.createElementNS(SVG, "svg"); | |
| 131 | svg.setAttribute("viewBox", "0 0 24 24"); | |
| 132 | svg.setAttribute("width", "11"); | |
| 133 | svg.setAttribute("height", "11"); | |
| 134 | svg.setAttribute("fill", "none"); | |
| 135 | svg.setAttribute("stroke", "currentColor"); | |
| 136 | svg.setAttribute("stroke-width", "2"); | |
| 137 | svg.setAttribute("stroke-linecap", "round"); | |
| 138 | svg.setAttribute("aria-hidden", "true"); | |
| 139 | var path = document.createElementNS(SVG, "path"); | |
| 140 | path.setAttribute("d", "M7 17L17 7M9 7h8v8"); | |
| 141 | svg.appendChild(path); | |
| 142 | return svg; | |
| 143 | } | |
| 144 | ||
| 145 | function icon(id) { | |
| 146 | var svg = document.createElementNS(SVG, "svg"); | |
| 147 | svg.setAttribute("viewBox", "0 0 24 24"); | |
| 148 | svg.setAttribute("width", "16"); | |
| 149 | svg.setAttribute("height", "16"); | |
| 150 | svg.setAttribute("fill", "none"); | |
| 151 | svg.setAttribute("stroke", "currentColor"); | |
| 152 | svg.setAttribute("stroke-width", "1.75"); | |
| 153 | svg.setAttribute("stroke-linecap", "round"); | |
| 154 | svg.setAttribute("stroke-linejoin", "round"); | |
| 155 | svg.setAttribute("aria-hidden", "true"); | |
| 156 | (ICONS[id] || ICONS.linux).forEach(function (d) { | |
| 157 | var path = document.createElementNS(SVG, "path"); | |
| 158 | path.setAttribute("d", d); | |
| 159 | svg.appendChild(path); | |
| 160 | }); | |
| 161 | return svg; | |
| 162 | } | |
| 163 | ||
| 164 | // A card's parts, made once and filled in on every status. | |
| 165 | function makeCard(kind) { | |
| 166 | var card = element("article", "kind"); | |
| 167 | card.setAttribute("role", "listitem"); | |
| 168 | card.setAttribute("aria-labelledby", "kind-" + kind.id + "-title"); | |
| 169 | var head = element("header", "kind-head"); | |
| 170 | var badge = element("span", "kind-icon"); | |
| 171 | badge.appendChild(icon(kind.id)); | |
| 172 | var name = element("span", "kind-name"); | |
| 173 | var title = element("h3", null, kind.label); | |
| 174 | title.id = "kind-" + kind.id + "-title"; | |
| 175 | name.appendChild(title); | |
| 176 | var pill = element("span", "pill"); | |
| 177 | // Its state is said when it changes, as "Linux jobs: Waiting for jobs". | |
| 178 | pill.setAttribute("role", "status"); | |
| 179 | pill.setAttribute("aria-live", "polite"); | |
| 180 | pill.setAttribute("aria-atomic", "true"); | |
| 181 | var said = element("span", "visually-hidden", kind.label + ": "); | |
| 182 | pill.appendChild(said); | |
| 183 | pill.appendChild(element("span", "pill-dot")); | |
| 184 | pill.appendChild(element("span", "pill-text")); | |
| 185 | name.appendChild(pill); | |
| 186 | head.appendChild(badge); | |
| 187 | head.appendChild(name); | |
| 188 | card.appendChild(head); | |
| 189 | card.appendChild(element("p", "kind-about")); | |
| 190 | var body = element("div", "kind-body"); | |
| 191 | card.appendChild(body); | |
| 192 | var details = element("dl", "kind-details"); | |
| 193 | card.appendChild(details); | |
| 194 | var actions = element("div", "kind-actions"); | |
| 195 | card.appendChild(actions); | |
| 196 | return { root: card, pill: pill, about: card.querySelector(".kind-about"), body: body, details: details, actions: actions, signature: "" }; | |
| 197 | } | |
| 198 | ||
| 199 | // What it is running, with where to see it on g1t. | |
| 200 | function jobRow(job) { | |
| 201 | var row = element("div", "kind-job"); | |
| 202 | row.appendChild(element("span", "kind-job-label", job.kind === "agent" ? "Agent work" : "Running")); | |
| 203 | var what = element("span", "kind-job-what"); | |
| 204 | if (job.link) { | |
| 205 | var link = element("a", null, job.name); | |
| 206 | link.href = job.link; | |
| 207 | what.appendChild(link); | |
| 208 | } else { | |
| 209 | what.appendChild(element("strong", null, job.name)); | |
| 210 | } | |
| 211 | if (job.repo) what.appendChild(element("span", "muted", " in " + job.repo)); | |
| 212 | row.appendChild(what); | |
| 213 | return row; | |
| 214 | } | |
| 215 | ||
| 216 | function progressRow(kind) { | |
| 217 | var row = element("div", "kind-progress"); | |
| 218 | var bar = element("div", "bar"); | |
| 219 | bar.setAttribute("role", "progressbar"); | |
| 220 | bar.setAttribute("aria-valuemin", "0"); | |
| 221 | bar.setAttribute("aria-valuemax", "100"); | |
| 222 | bar.setAttribute("aria-valuenow", String(kind.progress)); | |
| 223 | bar.setAttribute("aria-label", kind.label + ": the sandbox's image"); | |
| 224 | var fill = element("span"); | |
| 225 | fill.style.width = Math.max(2, Math.min(100, kind.progress)) + "%"; | |
| 226 | bar.appendChild(fill); | |
| 227 | row.appendChild(bar); | |
| 228 | row.appendChild(element("span", "muted small", kind.progress + "%")); | |
| 229 | return row; | |
| 230 | } | |
| 231 | ||
| 232 | function detail(list, term, value, given) { | |
| 233 | if (!value) return; | |
| 234 | var row = element("div"); | |
| 235 | row.appendChild(element("dt", null, term)); | |
| 236 | var dd = element("dd", null, given ? null : value); | |
| 237 | if (given) dd.appendChild(given); | |
| 238 | row.appendChild(dd); | |
| 239 | list.appendChild(row); | |
| 240 | } | |
| 241 | ||
| Merge branch 'main' into rm-agents | 242 | // Start or Stop for one kind of job, said for which: busy from the click |
| 243 | // until the status that follows says it started or stopped. | |
| 244 | function toggleButton(kind, onFirst, runner) { | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 245 | var on = kind.enabled; |
| 246 | var button = element("button", on ? "quiet" : onFirst ? "primary" : null); | |
| 247 | button.type = "button"; | |
| Merge branch 'main' into rm-agents | 248 | button.textContent = on ? "Stop" : "Start"; |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 249 | button.setAttribute("aria-label", (on ? "Stop " : "Start ") + kind.label); |
| Merge branch 'main' into rm-agents | 250 | var key = "toggle:" + kind.id; |
| 251 | var status = kindStatus(kind, runner); | |
| 252 | if (busy.pressed(key, status)) busy.start(button); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 253 | button.addEventListener("click", function () { |
| Merge branch 'main' into rm-agents | 254 | busy.run(button, key, status, true, function () { |
| 255 | return invoke("runner_control", { action: on ? "stop" : "start", capability: kind.id }); | |
| 256 | }, fail); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 257 | }); |
| 258 | return button; | |
| 259 | } | |
| 260 | ||
| 261 | function fillCard(card, kind, runner) { | |
| 262 | var root = card.root; | |
| 263 | root.dataset.state = kind.state; | |
| 264 | root.dataset.tone = kind.tone; | |
| 265 | root.classList.toggle("off", !kind.enabled); | |
| 266 | card.pill.dataset.tone = kind.tone; | |
| 267 | card.pill.classList.toggle("live", !!BUSY[kind.state]); | |
| 268 | // Said again only when it changes, so a screen reader hears each change once. | |
| 269 | var text = card.pill.querySelector(".pill-text"); | |
| 270 | if (text.textContent !== kind.title) text.textContent = kind.title; | |
| 271 | if (card.about.textContent !== kind.about) card.about.textContent = kind.about; | |
| 272 | ||
| 273 | // What changes the buttons and the words is drawn again only when it changes, | |
| 274 | // so a button keeps its focus while the status ticks. | |
| 275 | var update = runner.diagnosis.update || null; | |
| Merge branch 'main' into rm-agents | 276 | var signature = JSON.stringify([kind, runner.link, update && update.checked]); |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 277 | if (signature === card.signature) return; |
| 278 | card.signature = signature; | |
| 279 | ||
| 280 | var body = card.body; | |
| 281 | body.textContent = ""; | |
| 282 | if (kind.job) body.appendChild(jobRow(kind.job)); | |
| 283 | if (kind.state === "downloading" && kind.progress != null) body.appendChild(progressRow(kind)); | |
| 284 | if (kind.headline) body.appendChild(element("p", "kind-headline", kind.headline)); | |
| 285 | if (kind.cause) body.appendChild(prose(element("p", "kind-cause"), kind.cause)); | |
| 286 | if (kind.fix) body.appendChild(prose(element("p", "kind-fix"), kind.fix)); | |
| 287 | body.hidden = !body.firstChild; | |
| 288 | ||
| 289 | var details = card.details; | |
| 290 | details.textContent = ""; | |
| 291 | // Its name on g1t opens the workspace's Runners page, where it is listed. | |
| 292 | var named = null; | |
| 293 | if (kind.runner && runner.link) { | |
| 294 | named = element("button", "link", kind.runner); | |
| 295 | named.type = "button"; | |
| 296 | named.setAttribute("aria-label", "View " + kind.runner + " on g1t"); | |
| 297 | named.appendChild(outward()); | |
| 298 | named.addEventListener("click", function () { | |
| 299 | invoke("runner_control", { action: "view_runners" }).catch(fail); | |
| 300 | }); | |
| 301 | } | |
| 302 | detail(details, "On g1t", kind.runner, named); | |
| 303 | detail(details, "Version", kind.version ? "g1t-runner " + kind.version : null); | |
| 304 | // A newer version waiting for this kind of job, and when g1t last looked. | |
| 305 | if (update && (kind.update || kind.version)) { | |
| 306 | var updates = element("span", "kind-update"); | |
| 307 | if (kind.update) updates.appendChild(element("span", "kind-update-ready", kind.update)); | |
| 308 | updates.appendChild(element("span", "muted", update.checked)); | |
| 309 | detail(details, "Updates", true, updates); | |
| 310 | } | |
| 311 | detail(details, "Isolation", ISOLATION[kind.isolation] || kind.isolation); | |
| 312 | details.hidden = !details.firstChild; | |
| 313 | ||
| 314 | var actions = card.actions; | |
| 315 | actions.textContent = ""; | |
| 316 | // Its first fix stands out when it is the person's to do; while g1t | |
| 317 | // sees to it (waiting for the release's images), none does. | |
| 318 | var urgent = kind.tone === "problem" || kind.tone === "warning"; | |
| 319 | kind.actions.forEach(function (action, at) { | |
| Merge branch 'main' into rm-agents | 320 | actions.appendChild(actionButton(action, at === 0 && urgent && kind.state !== "waiting", kind.id, kindStatus(kind, runner))); |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 321 | }); |
| 322 | if (kind.can_toggle) { | |
| Merge branch 'main' into rm-agents | 323 | var toggle = toggleButton(kind, kind.actions.length === 0, runner); |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 324 | toggle.classList.add("end"); |
| 325 | actions.appendChild(toggle); | |
| 326 | } | |
| 327 | actions.hidden = !actions.firstChild; | |
| 328 | } | |
| 329 | ||
| 330 | function renderKinds(runner) { | |
| 331 | var list = byId("runner-kinds"); | |
| 332 | var kinds = (runner && runner.diagnosis.capabilities) || []; | |
| 333 | list.hidden = kinds.length === 0; | |
| 334 | var seen = {}; | |
| 335 | kinds.forEach(function (kind, at) { | |
| 336 | seen[kind.id] = true; | |
| 337 | var card = cards[kind.id] || (cards[kind.id] = makeCard(kind)); | |
| 338 | if (list.children[at] !== card.root) list.insertBefore(card.root, list.children[at] || null); | |
| 339 | fillCard(card, kind, runner); | |
| 340 | }); | |
| 341 | Object.keys(cards).forEach(function (id) { | |
| 342 | if (seen[id]) return; | |
| 343 | cards[id].root.remove(); | |
| 344 | delete cards[id]; | |
| 345 | }); | |
| 346 | list.classList.toggle("single", kinds.length === 1); | |
| 347 | } | |
| 348 | ||
| 349 | function renderRunner(runner) { | |
| 350 | if (!runner) return; | |
| 351 | var diagnosis = runner.diagnosis; | |
| 352 | renderEngine(runner); | |
| 353 | // The whole runner's line, when the cards don't already say it. | |
| 354 | var cardsSayIt = diagnosis.in_capabilities && diagnosis.capabilities && diagnosis.capabilities.length > 0; | |
| 355 | byId("runner-diagnosis").hidden = !!cardsSayIt; | |
| 356 | byId("runner-dot").className = "dot " + diagnosis.tone; | |
| 357 | byId("runner-title").textContent = diagnosis.title; | |
| 358 | prose(byId("runner-cause"), diagnosis.cause); | |
| 359 | prose(byId("runner-fix"), diagnosis.fix); | |
| 360 | var actions = byId("runner-actions"); | |
| 361 | actions.textContent = ""; | |
| 362 | diagnosis.actions.forEach(function (action, at) { | |
| Merge branch 'main' into rm-agents | 363 | actions.appendChild(actionButton(action, at === 0, "runner", runnerStatus(runner))); |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 364 | }); |
| 365 | renderKinds(runner); | |
| 366 | byId("runner").checked = !!runner.enabled; | |
| 367 | ||
| 368 | var backend = byId("runnerBackend"); | |
| 369 | backend.value = runner.backend; | |
| 370 | var about = BACKENDS[runner.backend] || BACKENDS.sandboxed; | |
| 371 | byId("runner-backend-note").textContent = about.text; | |
| 372 | byId("runner-backend-note").className = about.warn ? "warning-note" : "muted"; | |
| 373 | ||
| 374 | var workspaces = byId("runnerWorkspace"); | |
| 375 | workspaces.textContent = ""; | |
| 376 | var known = runner.workspaces.slice(); | |
| 377 | var listed = known.some(function (w) { | |
| 378 | return w.slug === runner.workspace; | |
| 379 | }); | |
| 380 | if (runner.workspace && !listed) known.unshift({ slug: runner.workspace, name: null }); | |
| 381 | known.forEach(function (w) { | |
| 382 | workspaces.appendChild(option(w.slug, w.name ? w.name + " (" + w.slug + ")" : w.slug)); | |
| 383 | }); | |
| 384 | if (known.length === 0) workspaces.appendChild(option("", "Open g1t, signed in, to choose")); | |
| 385 | workspaces.value = runner.workspace || ""; | |
| 386 | workspaces.disabled = known.length === 0; | |
| 387 | ||
| 388 | byId("runner-machine").textContent = "This computer: " + runner.machine; | |
| 389 | // The runner's version, when g1t last looked for a newer one, and, with | |
| 390 | // no cards to say it, what becomes of one waiting. | |
| 391 | var update = diagnosis.update; | |
| 392 | var about = [runner.version ? "g1t-runner " + runner.version : null, update ? update.checked : null, update && update.note].filter(Boolean); | |
| 393 | byId("runner-version").textContent = about.length ? about.join(" · ") : " "; | |
| 394 | var check = byId("runner-check"); | |
| 395 | check.hidden = !update; | |
| 396 | if (update) { | |
| 397 | check.textContent = update.check.label; | |
| Merge branch 'main' into rm-agents | 398 | // Busy while the app looks, whoever asked, and from a click until it says it is looking. |
| 399 | if (update.checking || busy.pressed("check", runnerStatus(runner))) busy.start(check); | |
| 400 | else busy.stop(check); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 401 | } |
| Merge branch 'main' into rm-agents | 402 | // A Start or Stop pressed is done once the status says so. |
| 403 | if (!busy.pressed("engine", runnerStatus(runner))) busy.stop(byId("engine-toggle")); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 404 | byId("runner-view").hidden = !runner.link; |
| 405 | // The log follows along, unless it was scrolled back to read. | |
| 406 | var log = byId("runner-log"); | |
| 407 | var following = log.scrollTop + log.clientHeight >= log.scrollHeight - 8; | |
| 408 | log.textContent = runner.log.length ? runner.log.join("\n") : "Nothing yet."; | |
| 409 | if (following) log.scrollTop = log.scrollHeight; | |
| 410 | } | |
| 411 | ||
| 412 | byId("runnerBackend").addEventListener("change", save); | |
| 413 | byId("runnerWorkspace").addEventListener("change", save); | |
| Merge branch 'main' into rm-agents | 414 | // A button that asks the runner for something: busy until the status |
| 415 | // that follows when it `waits`, or until the app has it. | |
| 416 | function control(id, key, action, waits) { | |
| 417 | var button = byId(id); | |
| 418 | button.addEventListener("click", function () { | |
| 419 | var status = current && current.runnerView ? runnerStatus(current.runnerView) : ""; | |
| 420 | busy.run(button, key, status, waits, function () { | |
| 421 | return invoke("runner_control", { action: typeof action === "function" ? action() : action }); | |
| 422 | }, fail); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 423 | }); |
| Merge branch 'main' into rm-agents | 424 | } |
| 425 | control("runner-view", "view", "view_runners", false); | |
| 426 | control("runner-open-log", "log", "view_log", false); | |
| 427 | // Looks now; what it finds installs as each kind of job is idle, and the status that follows says so. | |
| 428 | control("runner-check", "check", "check_updates", true); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 429 | |
| 430 | // ── The whole runner, at the top ───────────────────────────────────── | |
| 431 | // As the title bar's chip says it, with what it is doing in a line and | |
| 432 | // its Start or Stop; the cards below say each kind of job. | |
| 433 | function renderEngine(runner) { | |
| 434 | byId("engine-dot").className = "dot " + runner.chip.tone; | |
| 435 | var label = byId("engine-label"); | |
| 436 | if (label.textContent !== runner.chip.label) label.textContent = runner.chip.label; | |
| 437 | var about = [runner.diagnosis.title, runner.version ? "g1t-runner " + runner.version : null, runner.workspace ? "for " + runner.workspace : null].filter(Boolean); | |
| 438 | byId("engine-sub").textContent = about.join(" · "); | |
| 439 | var toggle = byId("engine-toggle"); | |
| 440 | var on = runner.enabled && !runner.paused; | |
| 441 | toggle.hidden = false; | |
| 442 | toggle.textContent = on ? "Stop" : "Start"; | |
| 443 | toggle.className = on ? "quiet" : "primary"; | |
| 444 | toggle.dataset.action = on ? "stop" : "start"; | |
| 445 | } | |
| 446 | ||
| Merge branch 'main' into rm-agents | 447 | control("engine-toggle", "engine", function () { |
| 448 | return byId("engine-toggle").dataset.action; | |
| 449 | }, true); | |
| The desktop app is 0.3.4, and the runner has a window of its own. Beside the title bar's Settings button a chip says what the runner is doing, live, with a dot in its colour (Runner running, Running a job, Running 2 jobs, Runner starting, Runner updating, Runner stopped, Runner offline, Runner needs you), as Docker Desktop shows its engine; in a narrow window only the dot shows. It opens the Runner window, as the tray's runner row now does: at its top what the whole runner is doing, with what it is running, its version and workspace, and its own Stop or Start; then each kind of job's card as before; then its setup (running jobs here at all, how jobs run, the workspace, the computer with Check for runner updates and View on g1t); and its log, open and following along as it is written. Settings keeps the runner as one line, what it is doing with Open runner, and each window saves only its own settings over what the app has now, so neither undoes the other's. The chip's words are diagnosis.rs's, the Runner window is made off the main thread as Settings now is, and it has a capability of its own with only the commands it uses; the title bar may now ask the runner's status. Two things fixed on the way: a settings row hidden until it applies, Restart to change the title bar, showed all the time, since its row's display beat the hidden attribute; and in a narrow window the title bar's buttons ran over the search, which now shrinks instead. The desktop guide describes the chip, the Runner window and where each runner setting now is. | 450 | |
| 451 | // Every setting, as the app has it now (the settings window changes the | |
| 452 | // rest), with the runner's own as they are on the page. | |
| 453 | var KEPT = ["startHidden", "closeToTray", "notifications", "flash", "badge", "systemTitleBar", "autoUpdate", "zoom", "runner", "runnerBackend", "runnerWorkspace", "runnerCapabilities"]; | |
| 454 | function save() { | |
| 455 | invoke("get_settings") | |
| 456 | .then(function (fresh) { | |
| 457 | var settings = {}; | |
| 458 | KEPT.forEach(function (key) { | |
| 459 | if (key in fresh) settings[key] = fresh[key]; | |
| 460 | }); | |
| 461 | settings.runner = byId("runner").checked; | |
| 462 | settings.runnerBackend = byId("runnerBackend").value || "sandboxed"; | |
| 463 | settings.runnerWorkspace = byId("runnerWorkspace").value || null; | |
| 464 | return invoke("save_settings", { settings: settings }); | |
| 465 | }) | |
| 466 | .then( | |
| 467 | function (view) { | |
| 468 | current = view; | |
| 469 | renderRunner(view.runnerView); | |
| 470 | }, | |
| 471 | function (error) { | |
| 472 | fail(error); | |
| 473 | if (current) renderRunner(current.runnerView); | |
| 474 | }, | |
| 475 | ); | |
| 476 | } | |
| 477 | byId("runner").addEventListener("change", save); | |
| 478 | ||
| 479 | var events = window.__TAURI__ && window.__TAURI__.event; | |
| 480 | if (events && typeof events.listen === "function") { | |
| 481 | events | |
| 482 | .listen("g1t-runner-status", function (event) { | |
| 483 | if (current) current.runnerView = event.payload; | |
| 484 | renderRunner(event.payload); | |
| 485 | }) | |
| 486 | .catch(function () {}); | |
| 487 | } | |
| 488 | ||
| 489 | // Links out, in the system's browser (src/bridge.js does the same on the site). | |
| 490 | document.addEventListener("click", function (event) { | |
| 491 | var anchor = event.target && event.target.closest ? event.target.closest("a[href]") : null; | |
| 492 | if (!anchor) return; | |
| 493 | event.preventDefault(); | |
| 494 | invoke("open_url", { url: anchor.href }).catch(function () {}); | |
| 495 | }); | |
| 496 | ||
| 497 | // g1t's own title bar, when the window has no system frame. | |
| 498 | function frame(view) { | |
| 499 | if (!view.customFrame) return; | |
| 500 | if (view.platform === "macos") document.documentElement.classList.add("mac"); | |
| 501 | var bar = byId("titlebar"); | |
| 502 | bar.hidden = false; | |
| 503 | document.body.classList.add("framed"); | |
| 504 | bar.addEventListener("mousedown", function (event) { | |
| 505 | if (event.button !== 0 || event.target.closest("button")) return; | |
| 506 | invoke("window_control", { action: "drag" }).catch(function () {}); | |
| 507 | }); | |
| 508 | byId("close-window").addEventListener("click", function () { | |
| 509 | invoke("window_control", { action: "close" }).catch(function () {}); | |
| 510 | }); | |
| 511 | } | |
| 512 | ||
| 513 | invoke("get_settings") | |
| 514 | .then(function (view) { | |
| 515 | current = view; | |
| 516 | frame(view); | |
| 517 | renderRunner(view.runnerView); | |
| 518 | var log = byId("runner-log"); | |
| 519 | log.scrollTop = log.scrollHeight; | |
| 520 | }) | |
| 521 | .catch(fail); | |
| 522 | })(); |
This file's history is long; its oldest lines are credited to the oldest commit read.