thunderbird-patch-review
Easy-to-use patch review interface for Thunderbird
Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht
git clone git://mccd.space/thunderbird-patch-review
| Log | Files | Refs | README | LICENSE |
commit 893b7a0be9f0f09f676f66ca9a3d530f17291e75 parent 0a3e906c666337b0a51a6b16f1391c300e41a127 Author: Pi Agent <agent@pi.local> Date: Sat, 18 Jul 2026 12:52:11 +0200 review: group the patch list and commit message into one box Merge the series selector and the commit-message block into a single bordered box: <nav id="series-nav"> is removed from the page and rendered inside renderPatch, with the commit message (and any general patch comment) as siblings beneath it. The pills now live in a .series-nav footer-row inside the shared .patch-box, and the commit message drops its own border/background since the box provides them. Diffstat:
| M | extension/review/review.css | | | 31 | +++++++++++++++++++++---------- |
| M | extension/review/review.html | | | 2 | -- |
| M | extension/review/review.js | | | 22 | ++++++++++++++++------ |
3 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/extension/review/review.css b/extension/review/review.css
@@ -157,14 +157,25 @@ button.primary:hover { color: #fff; opacity: 0.9; }
color: var(--fg);
}
-#series-nav {
+.patch-box {
+ margin: 0.6rem 0 1rem;
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ background: var(--surface);
+ overflow: hidden;
+}
+
+.series-nav {
display: flex;
- gap: 0.4rem;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
flex-wrap: wrap;
- padding: 0.6rem 1rem;
+ padding: 0.4rem 0.6rem;
+ border-bottom: 1px solid var(--border);
}
-#series-nav .pill {
+.series-nav .pill {
padding: 0.2rem 0.7rem;
border: 1px solid var(--border);
border-radius: 999px;
@@ -172,13 +183,13 @@ button.primary:hover { color: #fff; opacity: 0.9; }
color: var(--muted);
}
-#series-nav .pill.active {
+.series-nav .pill.active {
border-color: var(--accent);
color: var(--accent);
font-weight: 600;
}
-#series-nav .pill .badge {
+.series-nav .pill .badge {
display: inline-block;
min-width: 1.2em;
margin-left: 0.35em;
@@ -193,11 +204,11 @@ button.primary:hover { color: #fff; opacity: 0.9; }
.commit-message {
position: relative;
- margin: 0.5rem 0 1rem;
+ margin: 0;
padding: 0.8rem 1rem;
- border: 1px solid var(--border);
- border-radius: 6px;
- background: var(--surface);
+ border: 0;
+ border-radius: 0;
+ background: transparent;
white-space: pre-wrap;
font-family: ui-monospace, monospace;
}
diff --git a/extension/review/review.html b/extension/review/review.html
@@ -37,8 +37,6 @@
</div>
</header>
- <nav id="series-nav"></nav>
-
<main id="content"></main>
<div id="status" hidden>
diff --git a/extension/review/review.js b/extension/review/review.js
@@ -64,7 +64,6 @@ async function init() {
$("#srht-status").hidden = false;
}
- renderNav();
renderPatch();
updateCount();
}
@@ -73,7 +72,8 @@ async function init() {
// Rendering
function renderNav() {
- const nav = $("#series-nav");
+ const nav = state.navEl;
+ if (!nav) return;
nav.textContent = "";
state.series.forEach((patch, i) => {
const pill = document.createElement("span");
@@ -93,7 +93,6 @@ function renderNav() {
pill.title = patch.subject;
pill.addEventListener("click", () => {
state.current = i;
- renderNav();
renderPatch();
});
nav.appendChild(pill);
@@ -107,6 +106,17 @@ function renderPatch() {
const patch = state.series[i];
const parsed = state.parsed[i];
+ // The patch list and the commit message share one box so the series
+ // selector reads as a header to the message it selects.
+ const box = document.createElement("div");
+ box.className = "patch-box";
+
+ const nav = document.createElement("nav");
+ nav.className = "series-nav";
+ box.appendChild(nav);
+ state.navEl = nav;
+ renderNav();
+
// Commit message (or cover letter text) with a whole-patch comment. Never
// fall back to the raw body for a patch — that would print the whole diff
// above the interactive one (common case: single-line commit messages,
@@ -121,12 +131,13 @@ function renderPatch() {
generalBtn.textContent = state.comments[i][store.GENERAL] ? "Edit comment" : "Comment on patch";
generalBtn.addEventListener("click", () => openGeneralEditor(msg));
msg.appendChild(generalBtn);
- content.appendChild(msg);
+ box.appendChild(msg);
const existingGeneral = state.comments[i][store.GENERAL];
if (existingGeneral) {
- content.appendChild(commentCard(existingGeneral.text, () => openGeneralEditor(msg)));
+ box.appendChild(commentCard(existingGeneral.text, () => openGeneralEditor(msg)));
}
+ content.appendChild(box);
parsed.files.forEach((file, fileIndex) => {
const details = document.createElement("details");
@@ -299,7 +310,6 @@ function editorBox(initial, loc, close) {
textarea.value
);
close();
- renderNav();
renderPatch();
updateCount();
};