From 21820b88d0dc10f2b72e3b9417827f70457cac9c Mon Sep 17 00:00:00 2001 From: Andre <200930841+Andre-Bzk@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:02:14 +0200 Subject: [PATCH] feat: add search access to the crumbs bar for logged-in users The mobile view hides the whole original body behind replaceBody(), which removed every path back to phpBB's search: the header icon and, inside a thread, the per-topic "Search this topic..." form. Without this there was no way to search at all from the rebuilt view. The crumbs bar has no room for a third element next to the breadcrumb trail and the login pill, so the new search button only shows once a session exists and shares the pill's existing right-aligned group instead of claiming separate space. On viewtopic it reveals a second bar that reuses the original per-topic search form in place, keeping its hidden topic-id and scope fields intact rather than reconstructing them and risking a silently broken query. --- rin-mobile.user.js | 108 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/rin-mobile.user.js b/rin-mobile.user.js index 3d3c0cf..507577a 100644 --- a/rin-mobile.user.js +++ b/rin-mobile.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name RIN Mobile // @description Mobile Ansicht fuer cs.rin.ru: Themenlisten als Karten, Threads als Beitragsstrom -// @version 3.8 +// @version 3.9 // @match *://cs.rin.ru/forum/* // @run-at document-start // ==/UserScript== @@ -86,10 +86,21 @@ color:#eee !important; text-decoration:none !important; } .rm-crumbs a:last-of-type { font-weight:650; } .rm-crumbs .rm-sep { flex:none; font-size:13px; color:#eee; opacity:.45; } - .rm-crumbs a.rm-auth { flex:none; margin-left:auto; padding:6px 12px !important; + /* Traegt die Lupe und die Login/Logout-Pille zusammen als eine Einheit + rechts β€” nur eine gemeinsame margin-left:auto, statt jedes Element + einzeln an den Rand zu schieben, sonst klafft zwischen beiden eine + Luecke statt "direkt links neben der Pille". */ + .rm-crumbs .rm-auth-group { flex:none; margin-left:auto; + display:flex; align-items:center; gap:6px; } + .rm-crumbs a.rm-auth { flex:none; padding:6px 12px !important; font-size:13px !important; border-radius:99px; background:rgba(128,128,128,.18); border:1px solid rgba(160,160,160,.4); } + .rm-crumbs a.rm-search { flex:none; min-width:44px; height:29px; + display:flex; align-items:center; justify-content:center; + padding:0 16px !important; font-size:14px; border-radius:99px; + background:rgba(128,128,128,.18); + border:1px solid rgba(160,160,160,.4); } /* Nur gesetzt, wenn die Leiste wirklich gebaut wurde β€” ohne Brotkrumen im Original-DOM bleibt der Platz sonst leer reserviert. */ body.rm-crumbed .rm-root { @@ -97,6 +108,34 @@ body.rm-crumbed .rm-dbg { margin-top:calc(45px + env(safe-area-inset-top)); } + /* Zweite Leiste unter den Brotkrumen, nur im Thread: Ersatz fuer + "Search this topic..." der Originalseite. Das dortige Formular wird + unveraendert hierher verschoben statt neu gebaut, wie das + Login-Formular in .rm-login form. */ + .rm-search-bar { box-sizing:border-box; + position:fixed; left:0; right:0; z-index:9997; + top:calc(44px + env(safe-area-inset-top)); + display:flex; align-items:center; + padding:8px 12px; + background:rgba(28,28,30,.96); + -webkit-backdrop-filter:blur(12px); + backdrop-filter:blur(12px); + border-bottom:1px solid rgba(128,128,128,.3); + transform:translateY(-110%); + transition:transform .18s ease; } + .rm-search-bar.rm-open { transform:translateY(0); } + .rm-search-bar form { flex:1; min-width:0; + display:flex; align-items:center; gap:8px; } + .rm-search-bar input[type="text"] { + flex:1; min-width:0; box-sizing:border-box; + font-size:16px; padding:9px 12px; border-radius:10px; + color:#eee; background:rgba(120,120,120,.18); + border:1px solid rgba(160,160,160,.35); } + .rm-search-bar input[type="submit"] { + flex:none; font-size:14px; font-weight:650; padding:9px 16px; + border-radius:10px; color:#fff; border:0; + background:rgba(120,170,255,.85); } + /* === Themen- und Forenliste === */ .rm-sec { padding:18px 14px 6px; font-size:12px; font-weight:700; @@ -388,11 +427,31 @@ if (!n) return; var st = loginState(); + var group = document.createElement('div'); + group.className = 'rm-auth-group'; + + // Lupe nur bei bestehender Sitzung. Ausserhalb von viewtopic fuehrt sie + // direkt auf search.php, im Thread blendet sie stattdessen die zweite + // Leiste ein β€” Ersatz fuer "Search this topic...", das mit dem + // Original-DOM ausgeblendet wurde. + if (st.in) { + var search = document.createElement('a'); + search.className = 'rm-search'; + search.href = 'https://cs.rin.ru/forum/search.php'; + search.textContent = 'πŸ”'; + search.setAttribute('aria-label', 'Suche'); + search.addEventListener('click', function (e) { + if (view === 'thread') { e.preventDefault(); toggleThreadSearch(); } + }); + group.appendChild(search); + } + var auth = document.createElement('a'); auth.className = 'rm-auth'; auth.href = st.href; auth.textContent = st.in ? (st.name || 'Logout') : 'Login'; - bar.appendChild(auth); + group.appendChild(auth); + bar.appendChild(group); document.body.appendChild(bar); document.body.classList.add('rm-crumbed'); @@ -1032,6 +1091,47 @@ // Thread // ========================================================================== + // "Search this topic..." steht dreifach identisch im Original-DOM (Kopf, + // Fuss, ueber der Beitragsliste), samt versteckter Felder fuer Themen-Id + // und Scope (sf=msgonly). replaceBody() versteckt das nur per Klasse, das + // erste Formular bleibt im DOM erreichbar und wird beim ersten Antippen + // der Lupe unveraendert in die zweite Leiste verschoben statt neu gebaut β€” + // wie das Login-Formular in buildLogin(). + var threadSearchBar = null; + + function buildThreadSearch() { + var form = document.querySelector('#topic-search'); + if (!form) return null; + + // Die Originalseite emuliert einen Platzhalter per onclick/onblur statt + // per placeholder-Attribut. + var inp = form.querySelector('input[name="keywords"]'); + if (inp) { + inp.removeAttribute('onclick'); + inp.removeAttribute('onblur'); + if (inp.value === 'Search this topic…') inp.value = ''; + inp.placeholder = 'In diesem Thema suchen'; + } + var submit = form.querySelector('input[type="submit"]'); + if (submit) submit.value = 'Suchen'; + + var bar = document.createElement('div'); + bar.className = 'rm-search-bar'; + bar.appendChild(form); + document.body.appendChild(bar); + return bar; + } + + function toggleThreadSearch() { + if (!threadSearchBar) threadSearchBar = buildThreadSearch(); + if (!threadSearchBar) return; + var open = threadSearchBar.classList.toggle('rm-open'); + if (open) { + var inp = threadSearchBar.querySelector('input[type="text"]'); + if (inp) inp.focus(); + } + } + // Der Beitragstext liegt in einer verschachtelten Tabelle. closest('tr') // trifft deshalb die innere Zeile, der Autor- und Profilspalte fehlen. // Aufsteigen, bis die Zeile eine Profil- oder Autorenspalte enthaelt. @@ -1287,7 +1387,7 @@ if (DEBUG) { var d = document.createElement('div'); d.className = 'rm-dbg'; - d.textContent = 'RIN Mobile v3.8\n' + log.join('\n'); + d.textContent = 'RIN Mobile v3.9\n' + log.join('\n'); document.body.insertBefore(d, document.body.firstChild); } }