Tucker McKnight <tucker@pangolin.lan> | Sun Jan 25 2026
Convert commit.ts to a mithril template
0 1
i
mport {NavHelper} from './helpers/nav.ts'
export default async (0 1 2 3
import m from 'mithril'
import render from 'mithril-node-render'
import {NavHelper} from './helpers/nav.ts'
export default async (9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
const lineNumbers = eleventyConfig.getFilter("lineNumbers")
const languageExtension = eleventyConfig.getFilter("languageExtension")
return `
<div class="row">
<div class="col-auto">
<div class="bezel-secondary px-3 py-2">
<h1 class="fs-2">${data.patchInfo.commit.message.split('\n')[0]}</h2>
<div class="input-group mb-2 flex-nowrap">
<span class="font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll">${data.patchInfo.commit.hash}</span>
<button data-copy-text='${data.patchInfo.commit.hash}' class="btn btn-info shadow-none copy-button">Copy</button>
</div>
<p>${data.patchInfo.commit.author} | ${date(data.patchInfo.commit.date)}</p>
<pre class="mb-0">${data.patchInfo.commit.message}</pre>
</div>
</div>
</div>
<div class="row my-4">
<div class="col-auto">
<div class="form-check">
<input class="form-check-input" type="radio" name="unified" id="splitModeSwitch" value="split" onchange="toggleUnifiedMode(this)" checked>
<label class="form-check-label" for="splitModeSwitch">
Side-by-side
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="unified" id="unifiedModeSwitch" value="unified" onchange="toggleUnifiedMode(this)">
<label class="form-check-label" for="unifiedModeSwitch">
Stacked
</label>
</div>
</div>
</div>
<div class="row" id="diffs">
${data.patchInfo.commit.diffs.map((hunk) => {
return `
<div class=hunk>
<span class="font-monospace fw-bold"><a href="${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${hunk.fileName.split('/').map((filePart) => { return filePart.split('.').map((subpart) => { return slugify(subpart)}).join('.')}).join('/')}.html">${hunk.fileName}:${hunk.lineNumber}</a></span>
<div class="diff d-flex">
<div class="flex-grow-1 diff-left pe-2">
<span class='font-monospace text-secondary'>Before</span>
<div class="row">
<div class="col-auto border-end"><pre class="mb-0">
${lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n')}</pre></div>
<div class="col overflow-scroll">
<pre class="mb-0" data-start="${hunk.lineNumber}"><code data-type="before" class="line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}">${hunk.beforeText}</code></pre>
</div>
</div>
</div>
<div class="diff-right flex-grow-1">
<span class='font-monospace text-secondary'>After</span>
<div class="row">
<div class="col-auto border-end"><pre class="mb-0">
${lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n')}</pre></div>
<div class="col overflow-scroll">
<pre class="mb-0" data-start="${hunk.lineNumber}"><code data-type="after" class="line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}">${hunk.afterText}</code></pre>
</div>
</div>
</div>
</div>
</div>
`
}).join('')}
</div>
<script>
const toggleUnifiedMode = (e) => {
const diffs = document.getElementById('diffs')
const afterDiffs = document.querySelectorAll('.diff-right')
if (e.value == "unified") {
diffs.classList.add("unified")
}
else {
diffs.classList.remove("unified")
}
}
</script>
`
}9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
const lineNumbers = eleventyConfig.getFilter("lineNumbers")
const languageExtension = eleventyConfig.getFilter("languageExtension")
return render([
m('div', {class: "row"},
m('div', {class: "col-auto"},
m('div', {class: "bezel-secondary px-3 py-2"}, [
m('h1', {class: "fs-2"}, data.patchInfo.commit.message.split('\n')[0]),
m('div', {class: "input-group mb-2 flex-nowrap"}, [
m('span', {class: "font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll"}, data.patchInfo.commit.hash),
m('button', {'data-copy-text': data.patchInfo.commit.hash, class: "btn btn-info shadow-none copy-button"}, 'Copy')
]),
m('p', `${data.patchInfo.commit.author} | ${date(data.patchInfo.commit.date)}`),
m('pre', {class: "mb-0"}, data.patchInfo.commit.message)
])
)
),
m('div', {class: "row my-4"},
m('div', {class: "col-auto"}, [
m('div', {class: "form-check"}, [
m('input', {
class: "form-check-input",
type: "radio",
name: "unified",
id: "splitModeSwitch",
value: "split",
onchange: "toggleUnifiedMode(this)",
checked: true,
}),
m('label', {class: "form-check-label", for: "splitModeSwitch"}, 'Side-by-side'),
]),
m('div', {class: "form-check"}, [
m('input', {
class: "form-check-input",
type: "radio",
name: "unified",
id: "unifiedModeSwitch",
value: "unified",
onchange: "toggleUnifiedMode(this)",
}),
m('label', {class: "form-check-label", for: "unifiedModeSwitch"}, 'Stacked')
])
])
),
m('div', {class: "row", id: "diffs"}, data.patchInfo.commit.diffs.map((hunk) => {
return m('div', {class: 'hunk'}, [
m('span', {class: "font-monospace fw-bold"},
m('a', {
href: `${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${hunk.fileName.split('/').map((filePart) => { return filePart.split('.').map((subpart) => { return slugify(subpart)}).join('.')}).join('/')}.html`
}, `${hunk.fileName}:${hunk.lineNumber}`)
),
m('div', {class: "diff d-flex"}, [
m('div', {class: "flex-grow-1 diff-left pe-2"}, [
m('span', {class: 'font-monospace text-secondary'}, 'Before'),
m('div', {class: "row"}, [
m('div', {class: "col-auto border-end"}, m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}))),
m('div', {class: "col overflow-scroll"},
m('pre', {class: "mb-0", 'data-start': hunk.lineNumber}, m('code', {'data-type': 'before', class: `line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, hunk.beforeText))
)
])
]),
m('div', {class: "diff-right flex-grow-1"}, [
m('span', {class: 'font-monospace text-secondary'}, 'After'),
m('div', {class: "row"},
m('div', {class: "col-auto border-end"}, m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}))),
m('div', {class: "col overflow-scroll"},
m('pre', {class: "mb-0", 'data-start': hunk.lineNumber},
m('code', {'data-type': "after", class: `line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, hunk.afterText)
)
)
)
])
])
])
})),
m('script', m.trust(`
const toggleUnifiedMode = (e) => {
const diffs = document.getElementById('diffs')
const afterDiffs = document.querySelectorAll('.diff-right')
if (e.value == "unified") {
diffs.classList.add("unified")
}
else {
diffs.classList.remove("unified")
}
}
`)
)
])
}