diff --git a/components/home/LoadItemsTask.bs b/components/home/LoadItemsTask.bs index 730ef4898..b5705dde0 100644 --- a/components/home/LoadItemsTask.bs +++ b/components/home/LoadItemsTask.bs @@ -314,20 +314,123 @@ function loadMergedContinueWatching() as object end for end if + recentPlayedParams = { + includeItemTypes: "Episode", + filters: "IsPlayed", + recursive: true, + sortBy: "DatePlayed", + sortOrder: "Descending", + limit: 100, + fields: "UserData,SeriesId", + UserId: m.global.session.user.id + } + recentPlayedResponse = api.items.get(recentPlayedParams) + + ' Create a lookup map of series LastPlayedDate to populate nextup + seriesLastPlayedMap = {} + if isChainValid(recentPlayedResponse, "Items") + for each item in recentPlayedResponse.Items + sId = item.LookupCI("SeriesId") + userData = item.LookupCI("UserData") + if isValid(sId) and isValid(userData) and seriesLastPlayedMap[sId] = invalid + seriesLastPlayedMap[sId] = userData["LastPlayedDate"] + end if + end for + end if ' Add Next Up items that aren't already in Continue Watching if isChainValid(nextUpData, "Items") for each item in nextUpData.Items itemId = item.LookupCI("Id") + seriesId = item.LookupCI("SeriesId") + userData = item.LookupCI("UserData") + if not isValid(userData) then userData = {} + if userData["LastPlayedDate"] = invalid and isValid(seriesId) + userData["LastPlayedDate"] = seriesLastPlayedMap[seriesId] + end if ' Only add if not already in resume items if not resumeItemIds.DoesExist(itemId) tmp = createSGNode("HomeData") - tmp.json = item + tmp.json = { + Id: itemId, + name: item.LookupCI("name"), + Type: item.LookupCI("Type"), + SeriesName: item.LookupCI("SeriesName"), + SeriesId: seriesId, + SeasonId: item.LookupCI("SeasonId"), + ProductionYear: item.LookupCI("ProductionYear"), + Status: item.LookupCI("Status"), + EndDate: item.LookupCI("EndDate"), + ParentIndexNumber: item.LookupCI("ParentIndexNumber"), + IndexNumber: item.LookupCI("IndexNumber"), + IndexNumberEnd: item.LookupCI("IndexNumberEnd"), + OfficialRating: item.LookupCI("OfficialRating"), + CollectionType: item.LookupCI("CollectionType"), + ImageTags: item.LookupCI("ImageTags"), + UserData: userData, + ParentThumbItemId: item.LookupCI("ParentThumbItemId"), + ParentThumbImageTag: item.LookupCI("ParentThumbImageTag"), + ParentBackdropImageTags: item.LookupCI("ParentBackdropImageTags"), + ParentBackdropItemId: item.LookupCI("ParentBackdropItemId"), + SeriesPrimaryImageTag: item.LookupCI("SeriesPrimaryImageTag"), + BackdropImageTags: item.LookupCI("BackdropImageTags") + } results.push(tmp) end if end for end if - return results + sortedResults = sortServerResultsByDate(results) + return sortedResults +end function + +' sortServerResultsByDate: Sorts multi-server results by a date field (descending) +' +' @param {array} results - Array of items from multiple servers +' @return {array} Sorted array +function sortServerResultsByDate(results as object) as object + if not isValidAndNotEmpty(results) then return [] + + ' Convert to array with sortable date values + sortableItems = [] + for each item in results + dateValue = invalid + if isValid(item.json) and isValid(item.json.UserData) + dateValue = item.json.UserData.LastPlayedDate + end if + sortableItems.push({ + item: item, + sortDate: dateValue + }) + end for + + ' Simple bubble sort (sufficient for small arrays) + n = sortableItems.count() + for i = 0 to n - 2 + for j = 0 to n - i - 2 + ' Compare dates (ISO strings compare correctly alphabetically for descending) + date1 = sortableItems[j].sortDate + date2 = sortableItems[j + 1].sortDate + + ' Handle invalid dates + if not isValid(date1) then date1 = "" + if not isValid(date2) then date2 = "" + + ' Swap if date1 < date2 (we want descending order) + if date1 < date2 + temp = sortableItems[j] + sortableItems[j] = sortableItems[j + 1] + sortableItems[j + 1] = temp + end if + end for + end for + + ' Extract sorted items + sortedResults = [] + for each sortable in sortableItems + sortedResults.push(sortable.item) + end for + + return sortedResults end function function loadSeasonOfEpisodes() as object