The guide's actions had three record buttons side by side. One Record now opens, in its place, to the three choices, the first focused; Esc or another program folds them back. A program without series information keeps the plain Record. R, Shift R and N are as before.
- commit
- 9633ca2e7b6a5c1e87223a037d485fc6a0029978
- parent
- b1832427144bb0a1813f8fc378b73fa1c9b6e867
- author
- FelineStateMachine <226808055+FelineStateMachine@users.noreply.github.com>
- kind
- feat risk score 1.8 of 3, Jev's estimate
| M | README.md | 2 | +- |
| M | frontend/ | 35 | ++++++++++++++++++++++++++---- |
@@ -158,7 +158,7 @@ had.
158158 159159 | Key | Elsewhere |160160 | --- | --- |161-| G | Guide: arrows move, and Up and Down wrap round the channels. The filters (Favorites, Sports...; also `[` `]`) are Down from the top bar, which is Left from the earliest program. Enter watches what's on, or shows a program to come's actions; hold Enter, or I, for any program's: watch, record, series, new episodes only, favorite, hide. Home jumps to now, R / Shift R / N record, Shift F favorite, H hide (U undoes) |161+| G | Guide: arrows move, and Up and Down wrap round the channels. The filters (Favorites, Sports...; also `[` `]`) are Down from the top bar, which is Left from the earliest program. Enter watches what's on, or shows a program to come's actions; hold Enter, or I, for any program's: watch, record (which opens to this one, every episode or new only), favorite, hide. Home jumps to now, R / Shift R / N record, Shift F favorite, H hide (U undoes) |162162 | D | Recordings: Left (or `[` `]`) for Library, Coming up, Series. Enter shows a recording's actions: resume, from the start, watched, delete (press twice); for one recording now, watch from the start, 30 more minutes, stop (keeping it) and delete; Shift Enter starts over, W marks watched, Delete twice removes; on a series K sets how many to keep, N new episodes only |163163 | A | Reception: what the tuners measured, by RF channel (the ones the scan found first), with the transmitters licensed on each. Up and Down pick one, Enter watches its first channel; Left for the tuner, Measure now, which reads every RF channel on a free tuner and shows its progress, and Scan for channels (press twice) |164164 | W | Weather: current conditions, alerts, the next 24 hours, 7-day, radar loop and satellite; Up and Down move through them, Left to watch the weather channel |@@ -161,6 +161,7 @@ const state = {
161161 config: null, // location the lineup is built for162162 dvr: null, // recording state from the server163163 dvrKeys: new Map(), // "7.1@1791058239" -> upcoming item164+ recPick: '', // the airing whose Record is open to its choices164165 recording: null, // recording being played instead of live TV165166 captionsFor: null, // captions turned off or on for one program: { key, on }166167 recTab: 'library',@@ -1556,6 +1557,7 @@ function restoreFocus() {
15561557 // recording's actions, the guide's filters): it goes to the view's main15571558 // part, and reports whether it did.15581559 function viewBack() {1560+ if (state.view === 'guide' && state.recPick) { closeRecordPick(); return true; }15591561 if (state.view === 'guide' && guideUI.zone !== 'grid') { guideZone('grid'); return true; }15601562 if (state.view === 'recordings' && recUI.zone === 'actions') { recZone('list'); return true; }15611563 return false;@@ -1877,9 +1879,10 @@ function wireGuide() {
18771879 const ch = list[state.gRow];18781880 switch (b.dataset.act) {18791881 case 'watch': return watchChannel(ch);1880- case 'once': return recordSelected('once');1881- case 'series': return recordSelected('series', false);1882- case 'new': return recordSelected('series', true);1882+ case 'record': return openRecordPick(ch, selectedProgram(list));1883+ case 'once': state.recPick = ''; return recordSelected('once');1884+ case 'series': state.recPick = ''; return recordSelected('series', false);1885+ case 'new': state.recPick = ''; return recordSelected('series', true);18831886 case 'fav': return toggleFavorite(ch);18841887 case 'hide': guideZone('grid'); return hideChannel(ch);18851888 default: return null;@@ -2180,13 +2183,18 @@ function renderGuideActions(ch, p) {
21802183 const label = { recording: 'Recording now', unavailable: 'Channel not available', conflict: 'Conflict: every tuner records then' }[it.status] || 'Recording scheduled';21812184 parts.push(`<span class="chip ${it.status === 'unavailable' || it.status === 'conflict' ? 'warn' : 'live'}">${label}</span>`);21822185 parts.push(act('once', it.status === 'recording' ? 'Stop recording' : 'Cancel'));2186+ } else if (!rule && p.seriesId) {2187+ // One Record, which opens to this airing, every episode or new ones;2188+ // another program closes it.2189+ if (state.recPick !== airingKey(ch, p)) state.recPick = '';2190+ parts.push(state.recPick === airingKey(ch, p)2191+ ? act('once', '<i></i>This one', 'rec') + act('series', 'Every episode') + act('new', 'New only')2192+ : act('record', '<i></i>Record', 'rec'));21832193 } else {21842194 parts.push(act('once', '<i></i>Record', 'rec'));21852195 }21862196 if (rule) {21872197 parts.push(`<span class="chip new">Series${rule.newOnly ? ', new only' : ''}</span>${act('series', 'Stop series')}`);2188- } else if (p.seriesId) {2189- parts.push(act('series', 'Record series') + act('new', 'New episodes only'));21902198 }21912199 }21922200 if (!airing) parts.push(act('watch', `Watch ${esc(ch.number)}`));@@ -2219,6 +2227,23 @@ function fitGuideDetail() {
22192227 if (box.offsetHeight > room) box.classList.add('one-row');22202228 }22212229 2230+// openRecordPick opens Record into its three choices, the first focused.2231+function openRecordPick(ch, p) {2232+ if (!ch || !p) return;2233+ state.recPick = airingKey(ch, p);2234+ renderGuideActions(ch, p);2235+ focusEl(f($('#guide'), 'actions').querySelector('[data-act="once"]'));2236+}2237+2238+// closeRecordPick folds the choices back into Record, focused.2239+function closeRecordPick() {2240+ state.recPick = '';2241+ const list = guideChannels();2242+ renderGuideActions(list[state.gRow], selectedProgram(list));2243+ const rec = f($('#guide'), 'actions').querySelector('[data-act="record"]');2244+ if (rec && guideUI.zone === 'actions') focusEl(rec);2245+}2246+22222247 function recordSelected(kind, newOnly) {22232248 const list = guideChannels();22242249 return recordAiring(list[state.gRow], selectedProgram(list), kind, newOnly);