Shell: tooltips at once, one or two words; text-size buttons are drawn − and +
Every header and top-bar button's title becomes a tip the shell shows the moment the pointer arrives (the browser's own waits a second and looks different everywhere); it moves from `title` to data-tip so the native one never appears, and a module that sets `title` again is picked up on the next hover. The shell's own labels are "Settings" and "Remove"; the top bar's are "Fullscreen", "Add tile", "Layouts", "Admin"; Slack, PCO Plan, ProdCom and Timers shorten theirs to match. A− / A+ are a drawn − and + in Slack, PCO Plan and ProdCom, sized like every other header icon. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
1930fb142d
commit
818def822d
@@ -10,6 +10,10 @@
|
||||
|
||||
const REFRESH_SVG = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-2.64-6.36"/><path d="M21 3v6h-6"/></svg>';
|
||||
|
||||
/* the text-size buttons: a drawn − and + at the icon size, like every other header icon */
|
||||
const MINUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/></svg>';
|
||||
const PLUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>';
|
||||
|
||||
export default function create({ root, moduleApi }) {
|
||||
let state = null;
|
||||
let skew = 0; // server clock − local clock, ms
|
||||
@@ -55,7 +59,7 @@ export default function create({ root, moduleApi }) {
|
||||
|
||||
const refreshBtn = moduleApi.header.addButton({
|
||||
icon: REFRESH_SVG,
|
||||
title: 'Re-read the plan from Planning Center now',
|
||||
title: 'Refresh',
|
||||
onClick() {
|
||||
refreshBtn.classList.add('active');
|
||||
moduleApi.fetch('/refresh', { method: 'POST' })
|
||||
@@ -69,8 +73,8 @@ export default function create({ root, moduleApi }) {
|
||||
moduleApi.saveInstanceSettings({ textSize: Math.min(40, Math.max(9, size + delta)) });
|
||||
applyPrefs();
|
||||
}
|
||||
moduleApi.header.addButton({ label: 'A−', title: 'Smaller text', onClick: () => bumpTextSize(-1) });
|
||||
moduleApi.header.addButton({ label: 'A+', title: 'Larger text', onClick: () => bumpTextSize(1) });
|
||||
moduleApi.header.addButton({ icon: MINUS_SVG, title: 'Smaller text', onClick: () => bumpTextSize(-1) });
|
||||
moduleApi.header.addButton({ icon: PLUS_SVG, title: 'Larger text', onClick: () => bumpTextSize(1) });
|
||||
|
||||
/* ── formatting ─────────────────────────────────────────────────── */
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
persists in instance settings, and all network traffic goes through
|
||||
moduleApi (the module's server proxy at /prodcom/*). */
|
||||
|
||||
/* the text-size buttons: a drawn − and + at the icon size, like every other header icon */
|
||||
const MINUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/></svg>';
|
||||
const PLUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>';
|
||||
|
||||
export default function create({ root, moduleApi }) {
|
||||
/* ── per-instance state ─────────────────────────────────────────── */
|
||||
|
||||
@@ -48,7 +52,7 @@ export default function create({ root, moduleApi }) {
|
||||
let channelMenuEl = null; // the open menu's element (filled on each open)
|
||||
const channelsMenu = moduleApi.header.addMenu({
|
||||
icon: CHANNELS_SVG,
|
||||
title: 'Choose visible channels',
|
||||
title: 'Channels',
|
||||
build(menu) {
|
||||
menu.classList.add('pt-menu');
|
||||
channelMenuEl = menu;
|
||||
@@ -65,7 +69,7 @@ export default function create({ root, moduleApi }) {
|
||||
let timeBtn = null;
|
||||
timeBtn = moduleApi.header.addButton({
|
||||
icon: CLOCK_SVG,
|
||||
title: 'Show / hide timestamps',
|
||||
title: 'Timestamps',
|
||||
onClick() {
|
||||
moduleApi.saveInstanceSettings({ showTimes: !moduleApi.instanceSettings.showTimes });
|
||||
applyInstanceSettings();
|
||||
@@ -77,8 +81,8 @@ export default function create({ root, moduleApi }) {
|
||||
moduleApi.saveInstanceSettings({ textSize: Math.min(48, Math.max(10, current + delta)) });
|
||||
applyInstanceSettings();
|
||||
}
|
||||
moduleApi.header.addButton({ label: 'A−', title: 'Smaller text', onClick: () => bumpTextSize(-2) });
|
||||
moduleApi.header.addButton({ label: 'A+', title: 'Larger text', onClick: () => bumpTextSize(2) });
|
||||
moduleApi.header.addButton({ icon: MINUS_SVG, title: 'Smaller text', onClick: () => bumpTextSize(-2) });
|
||||
moduleApi.header.addButton({ icon: PLUS_SVG, title: 'Larger text', onClick: () => bumpTextSize(2) });
|
||||
|
||||
// icon and tooltip track the current direction — applyInstanceSettings sets both
|
||||
const flowBtn = moduleApi.header.addButton({
|
||||
@@ -93,7 +97,7 @@ export default function create({ root, moduleApi }) {
|
||||
|
||||
moduleApi.header.addButton({
|
||||
icon: JUMP_SVG,
|
||||
title: 'Jump to latest',
|
||||
title: 'Latest',
|
||||
onClick() {
|
||||
pinnedToLatest = true;
|
||||
jumpBtn.hidden = true;
|
||||
@@ -103,7 +107,7 @@ export default function create({ root, moduleApi }) {
|
||||
|
||||
const clearBtn = moduleApi.header.addButton({
|
||||
icon: CLEAR_SVG,
|
||||
title: 'Clear this tile (does not affect ProdCom)',
|
||||
title: 'Clear',
|
||||
onClick: clearView,
|
||||
});
|
||||
clearBtn.classList.add('pt-clear');
|
||||
@@ -120,9 +124,7 @@ export default function create({ root, moduleApi }) {
|
||||
wrap.classList.toggle('newest-first', up);
|
||||
flowBtn.innerHTML = up ? FLOW_UP_SVG : FLOW_DOWN_SVG;
|
||||
flowBtn.classList.toggle('active', up);
|
||||
flowBtn.title = up
|
||||
? 'Newest at top — click for newest at bottom'
|
||||
: 'Newest at bottom — click for newest at top';
|
||||
flowBtn.title = up ? 'Newest first' : 'Oldest first';
|
||||
jumpBtn.textContent = (up ? '↑' : '↓') + ' New messages';
|
||||
}
|
||||
applyInstanceSettings();
|
||||
@@ -174,9 +176,7 @@ export default function create({ root, moduleApi }) {
|
||||
channelCountEl.textContent = filtering ? `${visibleCount}/${channels.size}` : '';
|
||||
channelCountEl.hidden = !filtering;
|
||||
channelsMenu.button.classList.toggle('active', filtering);
|
||||
channelsMenu.button.title = filtering
|
||||
? `Channels — showing ${visibleCount} of ${channels.size}`
|
||||
: 'Choose visible channels';
|
||||
channelsMenu.button.title = filtering ? `Channels ${visibleCount}/${channels.size}` : 'Channels';
|
||||
}
|
||||
|
||||
function rebuildChannelMenu() {
|
||||
|
||||
@@ -283,7 +283,7 @@ export default function create({ root, moduleApi }) {
|
||||
let menuEl = null; // the open menu's element (filled on each open)
|
||||
const itemsMenu = solo ? null : moduleApi.header.addMenu({
|
||||
label: 'Timers ▾',
|
||||
title: 'Choose which timers this tile shows',
|
||||
title: 'Choose timers',
|
||||
build(menu) {
|
||||
// the shell hands over an emptied element on every open
|
||||
menu.classList.add('tm-menu');
|
||||
|
||||
@@ -635,6 +635,10 @@ const emojiMenu = (() => {
|
||||
|
||||
/* ── the factory ────────────────────────────────────────────────────── */
|
||||
|
||||
/* the text-size buttons: a drawn − and + at the icon size, like every other header icon */
|
||||
const MINUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/></svg>';
|
||||
const PLUS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>';
|
||||
|
||||
export default function create({ root, moduleApi }) {
|
||||
const variant = String(moduleApi.variant || '');
|
||||
// The entry's preset `view` is authoritative; a tile added under 1.0.0 has
|
||||
@@ -680,11 +684,11 @@ function createTranscriptTile({ root, moduleApi }) {
|
||||
moduleApi.saveInstanceSettings({ textSize: Math.min(48, Math.max(10, textSizePx(moduleApi) + delta)) });
|
||||
applyInstanceSettings();
|
||||
}
|
||||
moduleApi.header.addButton({ label: 'A−', title: 'Smaller text', onClick: () => bumpTextSize(-1) });
|
||||
moduleApi.header.addButton({ label: 'A+', title: 'Larger text', onClick: () => bumpTextSize(1) });
|
||||
moduleApi.header.addButton({ icon: MINUS_SVG, title: 'Smaller text', onClick: () => bumpTextSize(-1) });
|
||||
moduleApi.header.addButton({ icon: PLUS_SVG, title: 'Larger text', onClick: () => bumpTextSize(1) });
|
||||
moduleApi.header.addButton({
|
||||
icon: JUMP_SVG,
|
||||
title: 'Jump to latest',
|
||||
title: 'Latest',
|
||||
onClick() {
|
||||
pinnedToLatest = true;
|
||||
jumpBtn.hidden = true;
|
||||
@@ -1056,7 +1060,7 @@ function createSendTile({ root, moduleApi, mode }) {
|
||||
const gate = root.querySelector('.sl-gate');
|
||||
const compose = root.querySelector('.sl-compose');
|
||||
|
||||
const lockBtn = moduleApi.header.addButton({ icon: LOCK_SVG, title: 'Lock now', onClick: () => lock('Locked') });
|
||||
const lockBtn = moduleApi.header.addButton({ icon: LOCK_SVG, title: 'Lock', onClick: () => lock('Locked') });
|
||||
lockBtn.style.display = 'none';
|
||||
|
||||
function applyInstanceSettings() {
|
||||
|
||||
Reference in New Issue
Block a user