relay-companion 0.1.91 → 0.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/overlay/inbox.html +14 -2
  2. package/package.json +1 -1
@@ -2945,6 +2945,7 @@
2945
2945
  // relays plus the live Sent list. Local data only — the pill shows the
2946
2946
  // user's own exchanges; the API's /v1/threads serves web and agents.
2947
2947
  let threadDetailId = null; // threadId while a thread's history is open
2948
+ let threadDetailScrolledFor = null; // thread already auto-scrolled to newest (reset on leave)
2948
2949
  let threadDetailPartyHint = ""; // who it's with, for the header while messages load
2949
2950
  function threadMessages() {
2950
2951
  const msgs = [];
@@ -3044,7 +3045,11 @@
3044
3045
  const threadNote = threadOpenTarget
3045
3046
  ? `<div class="row-err${rowNotes.get(threadOpenTarget.id)?.cls === "ok" ? " ok" : ""}" data-err="${esc(threadOpenTarget.id)}" data-stop="1">${esc(rowNotes.get(threadOpenTarget.id)?.text || "")}</div>`
3046
3047
  : "";
3047
- thHistoryEl.innerHTML = threadActions + threadNote + thread.msgs.map((m) => `
3048
+ // Chat-shaped, like every messaging app (and Claude itself — Sven's field
3049
+ // note): messages read oldest -> newest downward, the open actions sit at
3050
+ // the BOTTOM next to the newest message, and entering the thread lands you
3051
+ // at the newest message, not the stalest.
3052
+ thHistoryEl.innerHTML = thread.msgs.map((m) => `
3048
3053
  <button class="th-msg${m.unread ? " unread" : ""}" type="button" data-msg="${esc(m.id)}" data-dir="${m.direction}">
3049
3054
  <span class="th-msg-top">
3050
3055
  <span class="th-dir${m.direction === "out" ? " out" : ""}">${m.direction === "out" ? "←" : "→"}</span>
@@ -3052,7 +3057,13 @@
3052
3057
  <span class="th-time">${esc(timeAgo(m.at))}</span>
3053
3058
  </span>
3054
3059
  <span class="th-msg-title">${esc(m.title)}</span>
3055
- </button>`).join("");
3060
+ </button>`).join("") + threadActions + threadNote;
3061
+ // Land at the newest message when ENTERING the thread; rebuilds of the same
3062
+ // open thread (payload pushes) keep the user's scroll position untouched.
3063
+ if (threadDetailScrolledFor !== thread.threadId) {
3064
+ threadDetailScrolledFor = thread.threadId;
3065
+ requestAnimationFrame(() => { scrollEl.scrollTop = scrollEl.scrollHeight; });
3066
+ }
3056
3067
  for (const el of thHistoryEl.querySelectorAll(".th-msg")) {
3057
3068
  el.addEventListener("click", () => {
3058
3069
  const id = el.getAttribute("data-msg");
@@ -3068,6 +3079,7 @@
3068
3079
  }
3069
3080
  thBackEl.addEventListener("click", () => {
3070
3081
  threadDetailId = null;
3082
+ threadDetailScrolledFor = null;
3071
3083
  activeView = "relays";
3072
3084
  syncTabs();
3073
3085
  applyView();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relay-companion",
3
- "version": "0.1.91",
3
+ "version": "0.1.92",
4
4
  "description": "Relay companion for ordinary messages, with dormant coordination features available only by explicit opt-in.",
5
5
  "type": "module",
6
6
  "bin": {