openvibers/openvibe.live Commits

A channel on a phone: the channel line in about 100 px, the sheet just under it, the grip centred (#814)

OP OpenVibers committed 2 days ago · ab43d47c80 · 2 files, +41 −2

Ask 366 ("the top bar needs to be a little more compact so that we get a little more space"):
- The channel line on a phone, live: who on the first line; live, watching and the title on one line; the actions in
  one slim row with Share as its icon (108 px, was 137 to 149).
- A sheet kept just under the line measures what the line holds (not its stretched box), and follows it as the page
  fills in (a ResizeObserver), so the chat gets the room (462 px, was 421) and the line is never cut.
- The sheet's grip is centred again (#807 left it at the left edge).

Changes

ddiff --git a/public/css/features/channel.css b/public/css/features/channel.css
iindex f8492dcc..ca656f92 100644
---- a/public/css/features/channel.css
++++ b/public/css/features/channel.css
@@@ -2226,7 +2226,7 @@ html[data-ov-motion="off"] #page-channel.ch-tabbed .ch-tab-panel.is-entering { a
#page-channel.ch-is-live:not(.chat-collapsed) .channel-below-fold { display: none; }
body:has(#page-channel.active.ch-is-live:not(.chat-collapsed)) #ov-footer { display: none; }
#page-channel.ch-is-live.chat-collapsed #ch-bot-section { display: none !important; }
-- #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) > .chat-sidebar > .chat-grip { position: absolute; top: 0; left: 0; right: 0; height: 14px; z-index: 4; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) > .chat-sidebar > .chat-grip { position: absolute; top: 0; height: 16px; z-index: 4; }
#page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) > .chat-sidebar .chat-header { padding-top: 8px; min-height: 46px; }
#page-channel.ch-is-live .chat-sidebar .ch-goal-widget { padding: 3px 6px 0; }
#page-channel.ch-is-live .chat-sidebar .cgw-goal { height: 30px; }
@@@ -2244,3 +2244,20 @@ html[data-ov-motion="off"] #page-channel.ch-tabbed .ch-tab-panel.is-entering { a
html.chat-compact #page-channel.ch-is-live .chat-sidebar .cgw-goal * { font-size: .66rem; }
html.chat-compact #page-channel.ch-is-live .chat-sidebar .chat-input-area { padding-top: 4px; }
}
++
++/* ── The channel line on a phone, live, compact (ask 366: "the top bar needs to be a little more compact so that we
++ get a little more space out of it"): who on the first line, then live, watching and the title on one line, then the
++ actions in one slim row with Share as its icon. About a hundred pixels instead of a hundred and fifty. ─── */
++@media (max-width: 768px) and (orientation: portrait) {
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar { padding: 8px 12px 10px; row-gap: 8px; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar .ch-avatar { width: 40px; height: 40px; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) .ch-info-bar-text { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 6px; row-gap: 1px; min-width: 0; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) .ch-info-bar-top { flex: 0 0 100%; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) :is(.ch-presence, .ch-stream-title) { margin: 0; font-size: .82rem; line-height: 1.35; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) .ch-stream-title { min-width: 0; color: var(--text-secondary); overflow-wrap: anywhere; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) .ch-presence:not(:empty) + .ch-meta + .ch-social-pills + .ch-stream-title::before,
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar:not(.ch-info-open) .ch-presence:not(:empty) ~ .ch-stream-title::before { content: "·"; margin-right: 6px; color: var(--text-muted); }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar-right :is(.ch-action, .ovk-ask) { height: 38px; min-height: 38px; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar-right #ch-btn-share { width: 38px; padding: 0; justify-content: center; }
++ #page-channel.ch-is-live .stream-layout:not(:has(.video-container.is-vertical)) .ch-info-bar-right #ch-btn-share > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
++}
ddiff --git a/public/js/channel-chat-resize.js b/public/js/channel-chat-resize.js
iindex 9b259269..8cc75bdf 100644
---- a/public/js/channel-chat-resize.js
++++ b/public/js/channel-chat-resize.js
@@@ -43,9 +43,16 @@
function lineSize() {
const p = page();
const info = p && p.querySelector('.stream-main > .ch-info-bar');
-- const h = info && info.offsetParent !== null ? info.scrollHeight : 0;
++ const h = info && info.offsetParent !== null ? lineHeight(info) : 0;
return Math.max(180, Math.round(dockRoom() - (h || 150)));
}
++ /** What the channel line holds, top to its last shown child plus its padding (its box may be taller: it fills). */
++ function lineHeight(info) {
++ const top = info.getBoundingClientRect().top;
++ let bottom = top;
++ for (const k of info.children) { const r = k.getBoundingClientRect(); if (r.height) bottom = Math.max(bottom, r.bottom); }
++ return Math.ceil(bottom - top + (parseFloat(getComputedStyle(info).paddingBottom) || 0));
++ }
const MODES = {
side: { key: 'openvibe_chat_width', prop: '--chat-w', axis: 'x', min: 260, max: () => Math.min(window.innerWidth * 0.5, 760) },
overlay: { key: 'openvibe_chat_overlay_w', prop: '--chat-ow', axis: 'x', min: 260, max: () => window.innerWidth * 0.7 },
@@@ -196,6 +203,21 @@
new MutationObserver(() => { const now = p.classList.contains('ch-is-live'); if (now !== was) { was = now; applySaved(); syncAll(); } })
.observe(p, { attributes: true, attributeFilter: ['class'] });
}
++ // The channel line fills in after the page (the title, the live line, the actions): a sheet kept just under it
++ // follows its height as it settles, so the line is never cut and never leaves a gap.
++ const info = p && p.querySelector('.stream-main > .ch-info-bar');
++ if (info && !info._ovLineWatch && typeof ResizeObserver === 'function') {
++ info._ovLineWatch = true;
++ let last = 0;
++ new ResizeObserver(() => {
++ const saved = read(MODES.sheet.key);
++ if (!docked() || !(saved === LINE || saved > 0)) return;
++ const h = lineHeight(info);
++ if (Math.abs(h - last) < 2) return;
++ last = h;
++ setSize('sheet', LINE);
++ }).observe(info);
++ }
}
init();
document.addEventListener('ov:fragment', init);