|
73 | 73 | m.loadFirstEpisodeTask = CreateObject("roSGNode", "LoadItemsTask") |
74 | 74 | m.loadFirstEpisodeTask.itemsToLoad = "seriesFirstEpisode" |
75 | 75 |
|
| 76 | + ' Series: fetch the resume/next-up episode in the background for the Resume button |
| 77 | + m.loadSeriesResumeTask = CreateObject("roSGNode", "LoadItemsTask") |
| 78 | + m.loadSeriesResumeTask.itemsToLoad = "seriesResume" |
| 79 | + |
76 | 80 | ' Season: fetch parent series metadata in the background for ratings/runtime/genres/logo |
77 | 81 | m.loadSeasonSeriesTask = CreateObject("roSGNode", "LoadItemsTask") |
78 | 82 | m.loadSeasonSeriesTask.itemsToLoad = "metaDataDetails" |
|
175 | 179 | else |
176 | 180 | m.buttonGrp.buttonFocused = 0 |
177 | 181 | end if |
178 | | - focusButtonGroupChild() |
| 182 | + ' Only move actual focus when the button group already owns it — avoid stealing |
| 183 | + ' focus from the extras row or description when the button arrives asynchronously. |
| 184 | + if m.buttonGrp.isInFocusChain() |
| 185 | + focusButtonGroupChild() |
| 186 | + end if |
179 | 187 | else |
180 | 188 | ' Resume button already present — update text and tick values |
181 | 189 | resumeButton.text = resumeText |
|
829 | 837 | manageGoToSeriesButton(item.type) |
830 | 838 | manageDeleteButton() |
831 | 839 |
|
832 | | - ' Season: kick off background fetch of parent series data for ratings/runtime/genres/logo |
| 840 | + ' Series: kick off background fetch of resume/next-up episode for the Resume button |
| 841 | + if item.type = "Series" |
| 842 | + ' Unobserve before re-observing to prevent callbacks stacking on repeated content changes. |
| 843 | + m.loadSeriesResumeTask.unobserveField("content") |
| 844 | + m.loadSeriesResumeTask.control = "STOP" |
| 845 | + m.top.nextUpEpisode = invalid |
| 846 | + m.loadSeriesResumeTask.itemId = item.id |
| 847 | + m.loadSeriesResumeTask.observeField("content", "onSeriesResumeLoaded") |
| 848 | + m.loadSeriesResumeTask.control = "RUN" |
| 849 | + end if |
| 850 | + |
| 851 | + ' Season: kick off background fetch of parent series metadata for ratings/runtime/genres/logo |
833 | 852 | if item.type = "Season" and isValidAndNotEmpty(item.seriesId) |
834 | 853 | ' Unobserve before re-observing to prevent callbacks stacking on repeated content changes. |
835 | 854 | m.loadSeasonSeriesTask.unobserveField("content") |
|
1481 | 1500 | end if |
1482 | 1501 | end sub |
1483 | 1502 |
|
| 1503 | +' onSeriesResumeLoaded: Set nextUpEpisode from seriesResume task result to show/hide the Resume button |
| 1504 | +sub onSeriesResumeLoaded() |
| 1505 | + m.loadSeriesResumeTask.unobserveField("content") |
| 1506 | + content = m.loadSeriesResumeTask.content |
| 1507 | + m.loadSeriesResumeTask.content = [] |
| 1508 | + |
| 1509 | + if isValid(content) and content.count() > 0 |
| 1510 | + m.top.nextUpEpisode = content[0] |
| 1511 | + else |
| 1512 | + m.top.nextUpEpisode = invalid |
| 1513 | + end if |
| 1514 | +end sub |
| 1515 | + |
1484 | 1516 | ' onShuffleEpisodeDataLoaded: Play shuffled episodes for Series |
1485 | 1517 | sub onShuffleEpisodeDataLoaded() |
1486 | 1518 | m.getShuffleEpisodesTask.unobserveField("data") |
|
0 commit comments