2026-10-02 23:49:39 +02:00
<!doctype html>
< html >
< head > < meta charset = "utf-8" >
< style >
:root {
color-scheme: light dark;
--bg:#0e131c; --ink:#e7eaf1; --mut:#8b98a9; --line2:rgba(255,255,255,.13);
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
--acid:#d6ff3d; --acid-tint: rgb(from var(--acid) r g b / .14);
2026-10-02 23:49:39 +02:00
}
@media (prefers-color-scheme: light) {
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
:root { --bg:#eceff3; --ink:#1a1f28; --mut:#5c6676; --line2:rgba(0,0,0,.10); --acid:#0AC18E; --acid-tint: rgb(from var(--acid) r g b / .14); }
2026-10-02 23:49:39 +02:00
}
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; overflow: hidden;
user-select: none; }
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
/* Icons sit in a vertically-centered column: the two spacers split the
remaining space above and below so the stack reads as "quick access"
centered in the strip, Opera-style. */
2026-10-02 23:49:39 +02:00
.strip { display: flex; flex-direction: column; align-items: center;
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
padding: 6px 0; height: 100%; box-sizing: border-box;
2026-10-02 23:49:39 +02:00
border-right: 1px solid var(--line2); }
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
.icons { display: flex; flex-direction: column; align-items: center; gap: 4px;
flex: none; }
.spacer { flex: 1 1 auto; min-height: 10px; }
.icon { width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center;
cursor: pointer; background: transparent; border: none; padding: 0; color: var(--ink);
2026-10-02 23:49:39 +02:00
position: relative; }
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
.icon:hover { background: var(--line2); }
2026-10-02 23:49:39 +02:00
.icon:active { transform: scale(0.94); }
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
.icon.on { background: var(--acid-tint); box-shadow: inset 2px 0 0 var(--acid); }
2026-10-08 01:30:33 +02:00
.icon.dragging { opacity: .4; }
.icon.dropbefore { box-shadow: inset 0 2px 0 var(--acid); }
.icon.dropafter { box-shadow: inset 0 -2px 0 var(--acid); }
2026-10-21 23:02:32 +03:00
.icon svg, .icon img { width: 26px; height: 26px; display: block; }
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
.icon.letter { font: 600 13px/1 system-ui, sans-serif; color: var(--mut); }
2026-10-02 23:49:39 +02:00
.icon .tt { position: absolute; left: 44px; top: 50%; transform: translateY(-50%);
background: var(--bg); color: var(--ink); padding: 4px 8px; border-radius: 6px;
border: 1px solid var(--line2); white-space: nowrap; font-size: 12px;
pointer-events: none; opacity: 0; transition: opacity .1s; z-index: 10; }
.icon:hover .tt { opacity: 1; transition-delay: .4s; }
.add { color: var(--mut); font: 500 20px/1 system-ui, sans-serif; }
2026-10-03 20:48:55 +02:00
.sep { width: 22px; height: 1px; background: var(--line2); margin: 4px 0; }
.icon.emoji { font-size: 18px; }
2026-10-02 23:49:39 +02:00
.add:hover { color: var(--acid); }
2026-10-21 20:10:11 +03:00
/* Gear + LLM button sit at the bottom of the strip. The LLM button grows
a small chevron badge in the bottom-right that opens the "pick AI"
menu; the main area of the button opens the current default LLM in
the left panel. Right-click on the button is equivalent to the chevron. */
2026-10-07 23:28:01 +02:00
.gear { color: var(--mut); margin-bottom: 2px; }
.gear:hover { color: var(--ink); }
.gear svg { width: 17px; height: 17px; }
2026-10-21 20:10:11 +03:00
.llm { color: var(--mut); margin-bottom: 2px; position: relative; }
.llm:hover { color: var(--ink); }
.llm.on { background: var(--acid-tint); box-shadow: inset 2px 0 0 var(--acid); color: var(--ink); }
.llm .glyph { font-size: 16px; line-height: 1; }
.llm img { width: 18px; height: 18px; display: block; }
.llm .chev { position: absolute; right: 1px; bottom: 1px; width: 10px; height: 10px;
display: grid; place-items: center; color: var(--mut); background: var(--bg);
border: 1px solid var(--line2); border-radius: 3px; font-size: 7px; line-height: 1; padding: 0; cursor: pointer; }
.llm .chev:hover { color: var(--ink); }
2026-10-02 23:49:39 +02:00
< / style > < / head >
< body >
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
< div class = "strip" >
< div class = "spacer" > < / div >
< div class = "icons" id = "icons" > < / div >
< div class = "spacer" > < / div >
2026-10-24 14:20:20 +03:00
< button class = "icon llm" id = "llmBtn" hidden > < span class = "glyph" id = "llmGlyph" > ✨< / span > < span class = "tt" id = "llmTip" > AI< / span > < span class = "chev" id = "llmChev" role = "button" tabindex = "0" aria-label = "Pick AI engine" title = "Pick AI engine" > ▾< / span > < / button >
Theseus 0.3.101: Grok + Gemini + ChatGPT, sidebar polish
Three more LLM engines land in the catalog and in DEFAULT_ENABLED, so the
sparkle button's picker lists five AI engines out of the box: Perplexity,
Phind, ChatGPT, Grok, Gemini. The first two answer a URL query without any
login, the latter three need a free-tier account; all three accept the
chat URL as the "open the home" target, which is what the sidebar button
needs. A one-time offer migration adds them to any existing profile's
enabledEngines (users who disable one keep it off across restarts via a
new `enginesOffered` field).
Sidebar strip polish. The gear button now opens Settings › Sidebar on a
single click instead of popping a one-item native menu first. The "+"
add button under the gear is removed — adding a web app goes through
Settings › Sidebar anyway, which the gear opens. The quicklinks-add IPC
is kept but repointed to Settings › Sidebar (it used to open General,
which was the wrong page for the add-a-web-app flow).
2026-10-21 21:55:10 +03:00
< button class = "icon gear" id = "gearBtn" title = "Sidebar settings" > < svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" > < circle cx = "12" cy = "12" r = "3" / > < path d = "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" / > < / svg > < span class = "tt" > Sidebar settings< / span > < / button >
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
< / div >
2026-10-08 01:38:53 +02:00
< script src = "strip-icons.js" > < / script >
2026-10-02 23:49:39 +02:00
< script >
const Q = window.quicklinks;
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
const icons = document.getElementById("icons");
Theseus 0.3.101: Grok + Gemini + ChatGPT, sidebar polish
Three more LLM engines land in the catalog and in DEFAULT_ENABLED, so the
sparkle button's picker lists five AI engines out of the box: Perplexity,
Phind, ChatGPT, Grok, Gemini. The first two answer a URL query without any
login, the latter three need a free-tier account; all three accept the
chat URL as the "open the home" target, which is what the sidebar button
needs. A one-time offer migration adds them to any existing profile's
enabledEngines (users who disable one keep it off across restarts via a
new `enginesOffered` field).
Sidebar strip polish. The gear button now opens Settings › Sidebar on a
single click instead of popping a one-item native menu first. The "+"
add button under the gear is removed — adding a web app goes through
Settings › Sidebar anyway, which the gear opens. The quicklinks-add IPC
is kept but repointed to Settings › Sidebar (it used to open General,
which was the wrong page for the add-a-web-app flow).
2026-10-21 21:55:10 +03:00
// Gear: click opens Settings › Sidebar directly (no popover). The "+" add
// button that used to live below the gear is gone — adding a web app goes
// through Settings › Sidebar now, which the gear opens anyway.
2026-10-07 23:28:01 +02:00
const gearBtn = document.getElementById("gearBtn");
Theseus 0.3.101: Grok + Gemini + ChatGPT, sidebar polish
Three more LLM engines land in the catalog and in DEFAULT_ENABLED, so the
sparkle button's picker lists five AI engines out of the box: Perplexity,
Phind, ChatGPT, Grok, Gemini. The first two answer a URL query without any
login, the latter three need a free-tier account; all three accept the
chat URL as the "open the home" target, which is what the sidebar button
needs. A one-time offer migration adds them to any existing profile's
enabledEngines (users who disable one keep it off across restarts via a
new `enginesOffered` field).
Sidebar strip polish. The gear button now opens Settings › Sidebar on a
single click instead of popping a one-item native menu first. The "+"
add button under the gear is removed — adding a web app goes through
Settings › Sidebar anyway, which the gear opens. The quicklinks-add IPC
is kept but repointed to Settings › Sidebar (it used to open General,
which was the wrong page for the add-a-web-app flow).
2026-10-21 21:55:10 +03:00
gearBtn.onclick = () => Q & & Q.add & & Q.add();
2026-10-21 20:10:11 +03:00
// LLM button: click opens the current default LLM in the left panel.
// Right-click (or the small chevron badge) opens the AI picker menu.
const llmBtn = document.getElementById("llmBtn");
const llmGlyph = document.getElementById("llmGlyph");
const llmTip = document.getElementById("llmTip");
const llmChev = document.getElementById("llmChev");
llmBtn.addEventListener("click", (e) => {
if (e.target === llmChev) return; // chevron handles its own click
Q & & Q.open & & Q.open("llm");
});
llmBtn.addEventListener("contextmenu", (e) => {
e.preventDefault();
const r = llmBtn.getBoundingClientRect();
Q & & Q.llmMenu & & Q.llmMenu({ x: r.left, y: r.top, width: r.width, height: r.height });
});
2026-10-24 14:20:20 +03:00
llmChev.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); e.stopPropagation(); const r = llmBtn.getBoundingClientRect(); Q & & Q.llmMenu & & Q.llmMenu({ x: r.left, y: r.top, width: r.width, height: r.height }); }
});
2026-10-21 20:10:11 +03:00
llmChev.addEventListener("click", (e) => {
e.stopPropagation();
const r = llmBtn.getBoundingClientRect();
Q & & Q.llmMenu & & Q.llmMenu({ x: r.left, y: r.top, width: r.width, height: r.height });
});
2026-10-08 01:38:53 +02:00
const { BRAND, svgFor: brandForLink, hostOf } = window.StripIcons;
2026-10-08 01:28:31 +02:00
function letterIcon(b, L) { b.classList.add("letter"); b.prepend(document.createTextNode((L.title || "?").slice(0, 1).toUpperCase())); }
2026-10-08 01:30:33 +02:00
// One order for web apps and extension panels (main keeps it); drag an
// icon up or down the strip to move it.
let order = [];
let dragKey = null;
function wireDrag(b, key) {
b.draggable = true;
b.dataset.key = key;
b.addEventListener("dragstart", (e) => { dragKey = key; b.classList.add("dragging"); try { e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("application/x-theseus-strip", key); } catch {} });
b.addEventListener("dragend", () => { dragKey = null; b.classList.remove("dragging"); icons.querySelectorAll(".icon").forEach((x) => x.classList.remove("dropbefore", "dropafter")); });
b.addEventListener("dragover", (e) => {
if (!dragKey || dragKey === key) return;
e.preventDefault(); e.dataTransfer.dropEffect = "move";
const r = b.getBoundingClientRect(); const before = (e.clientY - r.top) < r.height / 2 ;
b.classList.toggle("dropbefore", before); b.classList.toggle("dropafter", !before);
});
b.addEventListener("dragleave", () => b.classList.remove("dropbefore", "dropafter"));
b.addEventListener("drop", (e) => {
e.preventDefault();
if (!dragKey || dragKey === key) return;
const r = b.getBoundingClientRect(); const before = (e.clientY - r.top) < r.height / 2 ;
const next = order.filter((k) => k !== dragKey);
next.splice(next.indexOf(key) + (before ? 0 : 1), 0, dragKey);
dragKey = null;
Q & & Q.reorder & & Q.reorder(next);
});
}
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
function render(data) {
const links = (data & & data.links) || [];
const openId = (data & & data.openId) || null;
icons.innerHTML = "";
2026-10-03 20:48:55 +02:00
const panels = (data & & data.panels) || [];
2026-10-08 01:30:33 +02:00
order = Array.isArray(data & & data.order) ? data.order : [...panels.map((P) => P.id), ...links.map((L) => "q:" + L.id)];
const made = new Map();
2026-10-03 20:48:55 +02:00
for (const P of panels) {
const b = document.createElement("button");
b.className = "icon";
if (openId === P.id) b.classList.add("on");
b.title = P.title;
if (/^data:image\//.test(P.icon)) {
const img = document.createElement("img");
img.src = P.icon;
img.alt = "";
b.appendChild(img);
} else {
b.classList.add(P.icon ? "emoji" : "letter");
b.textContent = P.icon || (P.title || "?").slice(0, 1).toUpperCase();
}
const tt = document.createElement("span");
tt.className = "tt"; tt.textContent = P.title;
b.appendChild(tt);
b.onclick = () => Q & & Q.open(P.id);
2026-10-08 01:30:33 +02:00
wireDrag(b, P.id);
made.set(P.id, b);
2026-10-03 20:48:55 +02:00
}
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
for (const L of links) {
2026-10-02 23:49:39 +02:00
const b = document.createElement("button");
b.className = "icon";
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
if (openId & & L.id === openId) b.classList.add("on");
2026-10-02 23:49:39 +02:00
b.title = L.title || L.url;
2026-10-08 01:28:31 +02:00
const svg = brandForLink(L);
const host = hostOf(L.url);
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
if (svg) {
b.innerHTML = svg;
2026-10-08 01:28:31 +02:00
} else if (host & & /^https?:/.test(L.url)) {
const img = document.createElement("img");
img.alt = "";
img.onerror = () => { img.remove(); letterIcon(b, L); };
img.src = new URL("/favicon.ico", L.url).href;
b.appendChild(img);
2026-10-02 23:49:39 +02:00
} else {
2026-10-08 01:28:31 +02:00
letterIcon(b, L);
2026-10-02 23:49:39 +02:00
}
const tt = document.createElement("span");
tt.className = "tt"; tt.textContent = L.title || L.url;
b.appendChild(tt);
b.onclick = () => Q & & Q.open(L.id);
2026-10-08 01:30:33 +02:00
wireDrag(b, "q:" + L.id);
made.set("q:" + L.id, b);
2026-10-02 23:49:39 +02:00
}
2026-10-08 01:30:33 +02:00
for (const k of order) { const b = made.get(k); if (b) { icons.appendChild(b); made.delete(k); } }
for (const b of made.values()) icons.appendChild(b);
2026-10-21 20:10:11 +03:00
// LLM button — visible only when at least one LLM engine is enabled.
const llm = (data & & data.llm) || null;
const engines = (llm & & llm.engines) || [];
if (engines.length) {
llmBtn.hidden = false;
llmBtn.classList.toggle("on", !!(llm & & llm.open));
const curId = (llm & & llm.current) || engines[0].id;
const cur = engines.find((e) => e.id === curId) || engines[0];
llmTip.textContent = cur.name;
// Prefer the engine's bundled favicon; fall back to the symbol emoji.
llmGlyph.textContent = "";
llmGlyph.innerHTML = "";
if (cur.favicon) {
const img = document.createElement("img");
img.src = cur.favicon; img.alt = "";
img.onerror = () => { llmGlyph.innerHTML = ""; llmGlyph.textContent = cur.sym || "✨"; };
llmGlyph.appendChild(img);
} else {
llmGlyph.textContent = cur.sym || "✨";
}
} else {
llmBtn.hidden = true;
}
2026-10-02 23:49:39 +02:00
}
Theseus 0.3.68: quick-links strip opens services in a dedicated side panel
Clicking an icon on the left strip now opens the service inside a dedicated
380-px mini-view (quickPanel) next to the strip, Opera-style, instead of a
new full-sized tab. Click the active icon again to close the panel; click a
different one to switch. If the panel is already pointed at the same host,
we skip the loadURL so scroll position, open chat and login state survive
a close+reopen round-trip.
Icons now paint as real brand SVGs (Messenger, WhatsApp, Telegram, X,
YouTube, Spotify) with their official colours, bundled inside quicklinks.html
so no external favicon fetch leaks the fact that the strip is loaded.
Unknown ids fall back to a letter chip. The strip vertically centres the
icons between two flex spacers to match Opera's layout.
Defaults ship Messenger, WhatsApp, Telegram, X, YouTube and Spotify. The
Settings › General › Quick links section still lists / adds / removes
entries and toggles the strip.
2026-10-03 00:09:44 +02:00
Q & & Q.getState & & Q.getState().then(render).catch(() => render(null));
Q & & Q.onState & & Q.onState(render);
2026-10-02 23:49:39 +02:00
< / script >
< / body >
< / html >