fix(livetv): navigate guide rows in displayed source-group order

Vertical D-pad/arrow navigation stepped through the flat channel list,
which is number-sorted across servers. With overlapping channel numbers
from multiple DVRs, focus interleaved source groups and could dead-end
before the last displayed row. Derive the up/down order from the same
grouped rows the guide renders.

close #1843
This commit is contained in:
edde746
2026-08-09 11:12:09 +02:00
parent ff461d9f71
commit 63f2bedf2c
2 changed files with 159 additions and 27 deletions
+17 -14
View File
@@ -585,6 +585,14 @@ class GuideTabState extends State<GuideTab>
];
}
/// Flat [GuideTab.channels] indexes in displayed row order. Differs from
/// ascending index order when multiple source groups exist: the flat list is
/// number-sorted across sources, while rows are grouped by source.
List<int> get _displayOrderChannelIndexes => [
for (final row in _guideRows)
if (row is _GuideChannelRow) row.channelIndex,
];
double _guideRowHeight(_GuideRow row) {
return switch (row) {
_GuideSourceHeaderRow() => _sourceHeaderRowHeight,
@@ -791,25 +799,20 @@ class GuideTabState extends State<GuideTab>
}
KeyEventResult _handleGridKey(LogicalKeyboardKey key) {
if (key.isUpKey) {
if (_gridChannelIndex > 0) {
_updateFocus(() {
_gridChannelIndex--;
if (_gridColumn == 1) _focusedProgram = _findCurrentProgram(_gridChannelIndex);
});
_scrollToChannel(_gridChannelIndex);
} else {
if (key.isUpKey || key.isDownKey) {
// Move through rows in displayed (source-grouped) order. Stepping the
// flat channel index would interleave sources whose channel numbers
// overlap and could dead-end before the last displayed row.
final order = _displayOrderChannelIndexes;
final position = order.indexOf(_gridChannelIndex);
if (key.isUpKey && position <= 0) {
_updateFocus(() {
_focusZone = _GuideZone.timeNav;
_timeNavIndex = 1;
});
}
return KeyEventResult.handled;
}
if (key.isDownKey) {
if (_gridChannelIndex < widget.channels.length - 1) {
} else if (key.isUpKey || (position != -1 && position < order.length - 1)) {
_updateFocus(() {
_gridChannelIndex++;
_gridChannelIndex = order[key.isUpKey ? position - 1 : position + 1];
if (_gridColumn == 1) _focusedProgram = _findCurrentProgram(_gridChannelIndex);
});
_scrollToChannel(_gridChannelIndex);