Add deck tabs, uniform action buttons, lyric reports in the player panel and a song list in the lyrics studio
This commit is contained in:
@@ -2770,6 +2770,9 @@ const Notes = (() => {
|
||||
}).join('');
|
||||
if (st.sync) renderSyncPointer();
|
||||
else tick(now(), true);
|
||||
paintFlags();
|
||||
loadFlags();
|
||||
setPanelFlagMode(sv.panelFlag && flagsEnabled());
|
||||
}
|
||||
|
||||
function renderOffset() {
|
||||
@@ -3306,7 +3309,7 @@ const Notes = (() => {
|
||||
// The sung line sits in the middle of the screen at the largest size that
|
||||
// still fits on ONE row (measured per line with a canvas), highlighted; its
|
||||
// neighbours shrink and fade with distance. Auto-scroll keeps it centred.
|
||||
const sv = { key: '', idx: -2, timer: null, flags: new Map(), flagsKey: '', flagMode: false, pressed: 0 };
|
||||
const sv = { key: '', idx: -2, timer: null, flags: new Map(), flagsKey: '', flagMode: false, panelFlag: false, pressed: 0 };
|
||||
const flagsEnabled = () => data.settings.lyricFlags !== false && !!window.FlagUI;
|
||||
const serviceOn = () => isServiceModeOpen() && !!data.settings.serviceLyrics;
|
||||
const serviceAuto = () => data.settings.serviceLyricsAutoscroll !== false;
|
||||
@@ -3374,9 +3377,7 @@ const Notes = (() => {
|
||||
|
||||
// ---- reporting wrong lines (per-profile setting: settings.lyricFlags) ----
|
||||
function paintFlags() {
|
||||
const list = $('serviceLyricsList');
|
||||
if (!list) return;
|
||||
list.querySelectorAll('.sl-line').forEach((el) => {
|
||||
document.querySelectorAll('#serviceLyricsList .sl-line, #lyricsList .lyr-line').forEach((el) => {
|
||||
const l = lines()[Number(el.dataset.i)];
|
||||
const f = flagsEnabled() && l ? sv.flags.get(l.text) : null;
|
||||
el.classList.toggle('flagged', !!f);
|
||||
@@ -3405,7 +3406,7 @@ const Notes = (() => {
|
||||
sv.flagsKey = ''; // force a refresh from the server (counts, ids)
|
||||
if (vid === st.videoId) await loadFlags();
|
||||
toast(res.action === 'withdrawn' ? 'Report withdrawn' : 'Thanks — reported ✓');
|
||||
if (res.action === 'saved') { sv.flagMode = false; renderServiceButtons(); }
|
||||
if (res.action === 'saved') { sv.flagMode = false; renderServiceButtons(); setPanelFlagMode(false); }
|
||||
}
|
||||
|
||||
function centreOn(list, el) {
|
||||
@@ -3677,6 +3678,31 @@ const Notes = (() => {
|
||||
renderOffset();
|
||||
tick(now(), true);
|
||||
};
|
||||
function setPanelFlagMode(on) {
|
||||
sv.panelFlag = !!on;
|
||||
const b = $('lyricsFlagBtn');
|
||||
if (b) {
|
||||
b.setAttribute('aria-pressed', String(sv.panelFlag));
|
||||
b.classList.toggle('hidden', !flagsEnabled());
|
||||
b.querySelector('span').textContent = sv.panelFlag ? 'Tap the line that is wrong…' : 'Report a wrong line';
|
||||
}
|
||||
$('lyricsList').classList.toggle('flagging', sv.panelFlag);
|
||||
}
|
||||
if ($('lyricsFlagBtn')) $('lyricsFlagBtn').addEventListener('click', () => setPanelFlagMode(!sv.panelFlag));
|
||||
{
|
||||
// Hold a lyric line to report it without switching modes.
|
||||
const pl = $('lyricsList');
|
||||
let timer = null, sx = 0, sy = 0;
|
||||
const cancel = () => { clearTimeout(timer); timer = null; };
|
||||
pl.addEventListener('pointerdown', (e) => {
|
||||
const row = e.target.closest('.lyr-line');
|
||||
if (!row || !flagsEnabled() || st.sync) return;
|
||||
sx = e.clientX; sy = e.clientY; cancel();
|
||||
timer = setTimeout(() => { timer = null; sv.pressed = Date.now(); if (navigator.vibrate) navigator.vibrate(12); openFlag(row); }, 550);
|
||||
});
|
||||
pl.addEventListener('pointermove', (e) => { if (timer && Math.hypot(e.clientX - sx, e.clientY - sy) > 8) cancel(); });
|
||||
['pointerup', 'pointercancel', 'pointerleave', 'scroll'].forEach((t) => pl.addEventListener(t, cancel, { passive: true }));
|
||||
}
|
||||
$('lyrOffMinus').addEventListener('click', () => nudge(-0.5));
|
||||
$('lyrOffPlus').addEventListener('click', () => nudge(0.5));
|
||||
$('lyrAutoscroll').addEventListener('change', (e) => {
|
||||
@@ -3697,8 +3723,10 @@ const Notes = (() => {
|
||||
}
|
||||
const row = e.target.closest('[data-i]');
|
||||
if (!row) return;
|
||||
if (Date.now() - sv.pressed < 700) return; // that was the long-press
|
||||
const i = Number(row.dataset.i);
|
||||
if (st.sync) { st.sync.ptr = i; renderSyncPointer(); return; }
|
||||
if (sv.panelFlag && row.classList.contains('lyr-line')) { openFlag(row); return; }
|
||||
const l = lines()[i];
|
||||
if (l && l.t !== null && l.t !== undefined) {
|
||||
st.lastUserScroll = 0;
|
||||
@@ -3726,11 +3754,26 @@ const Notes = (() => {
|
||||
});
|
||||
|
||||
return {
|
||||
load, tick, addBookmark, addNote, handleSyncKey, serviceRefresh, refreshFlags: () => { sv.flagsKey = ''; renderServiceButtons(); paintFlags(); loadFlags(); },
|
||||
load, tick, addBookmark, addNote, handleSyncKey, serviceRefresh, refreshFlags: () => { sv.flagsKey = ''; renderServiceButtons(); setPanelFlagMode(sv.panelFlag && flagsEnabled()); paintFlags(); loadFlags(); },
|
||||
stageLyrics: { render: renderStage, set: setStageLyrics, on: stageOn },
|
||||
};
|
||||
})();
|
||||
|
||||
// ---- Player deck tabs: Sound & view (default) / Practice ----
|
||||
(function deckTabs() {
|
||||
const tabs = document.querySelectorAll('.dk-tab');
|
||||
if (!tabs.length) return;
|
||||
let cur = 'sound';
|
||||
try { cur = localStorage.getItem('ytpDeckTab') === 'practice' ? 'practice' : 'sound'; } catch { /* default */ }
|
||||
const show = (name) => {
|
||||
tabs.forEach((t) => { const on = t.dataset.dk === name; t.classList.toggle('active', on); t.setAttribute('aria-selected', String(on)); });
|
||||
document.querySelectorAll('.dk-group').forEach((g) => g.classList.toggle('hidden', g.dataset.dk !== name));
|
||||
try { localStorage.setItem('ytpDeckTab', name); } catch { /* private mode */ }
|
||||
};
|
||||
tabs.forEach((t) => t.addEventListener('click', () => show(t.dataset.dk)));
|
||||
show(cur);
|
||||
})();
|
||||
|
||||
// ============================================================================
|
||||
// Phone remote (server/remote.js relays both ends over /ws/remote)
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user