musora-content-services 2.22.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/ContentOrganization.html +2 -2
  3. package/docs/Gamification.html +2 -2
  4. package/docs/UserManagementSystem.html +2 -2
  5. package/docs/api_types.js.html +2 -2
  6. package/docs/config.js.html +2 -2
  7. package/docs/content-org_content-org.js.html +2 -2
  8. package/docs/content-org_playlists-types.js.html +2 -2
  9. package/docs/content-org_playlists.js.html +2 -2
  10. package/docs/content.js.html +44 -27
  11. package/docs/gamification_awards.js.html +2 -2
  12. package/docs/gamification_gamification.js.html +2 -2
  13. package/docs/gamification_types.js.html +2 -2
  14. package/docs/global.html +2 -2
  15. package/docs/index.html +2 -2
  16. package/docs/module-Awards.html +2 -2
  17. package/docs/module-Config.html +2 -2
  18. package/docs/module-Content-Services-V2.html +14 -47
  19. package/docs/module-Interests.html +2 -2
  20. package/docs/module-Permissions.html +2 -2
  21. package/docs/module-Playlists.html +2 -2
  22. package/docs/module-Railcontent-Services.html +2 -2
  23. package/docs/module-Sanity-Services.html +30 -30
  24. package/docs/module-Sessions.html +2 -2
  25. package/docs/module-UserActivity.html +23 -47
  26. package/docs/module-UserChat.html +2 -2
  27. package/docs/module-UserManagement.html +178 -7
  28. package/docs/module-UserNotifications.html +2 -2
  29. package/docs/module-UserProfile.html +2 -2
  30. package/docs/railcontent.js.html +2 -2
  31. package/docs/sanity.js.html +23 -6
  32. package/docs/userActivity.js.html +143 -57
  33. package/docs/user_chat.js.html +2 -2
  34. package/docs/user_interests.js.html +2 -2
  35. package/docs/user_management.js.html +12 -2
  36. package/docs/user_notifications.js.html +4 -4
  37. package/docs/user_permissions.js.html +2 -2
  38. package/docs/user_profile.js.html +2 -2
  39. package/docs/user_sessions.js.html +2 -2
  40. package/docs/user_types.js.html +2 -2
  41. package/docs/user_user-management-system.js.html +2 -2
  42. package/package.json +1 -1
  43. package/src/index.d.ts +2 -0
  44. package/src/index.js +2 -0
  45. package/src/services/imageSRCVerify.js +0 -0
  46. package/src/services/user/management.js +10 -0
  47. package/src/services/userActivity.js +2 -0
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Awards.html">Awards</a><ul class='methods'><li data-type='method'><a href="module-Awards.html#.fetchAwardsForUser">fetchAwardsForUser</a></li></ul></li><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Content-Services-V2.html">Content-Services-V2</a><ul class='methods'><li data-type='method'><a href="module-Content-Services-V2.html#.getContentRows">getContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getNewAndUpcoming">getNewAndUpcoming</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecent">getRecent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecommendedForYou">getRecommendedForYou</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getScheduleContentRows">getScheduleContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getTabResults">getTabResults</a></li></ul></li><li><a href="module-Interests.html">Interests</a><ul class='methods'><li data-type='method'><a href="module-Interests.html#.fetchInterests">fetchInterests</a></li><li data-type='method'><a href="module-Interests.html#.fetchUninterests">fetchUninterests</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsInterested">markContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsNotInterested">markContentAsNotInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsInterested">removeContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsNotInterested">removeContentAsNotInterested</a></li></ul></li><li><a href="module-Permissions.html">Permissions</a><ul class='methods'><li data-type='method'><a href="module-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-Permissions.html#.reset">reset</a></li></ul></li><li><a href="module-Playlists.html">Playlists</a><ul class='methods'><li data-type='method'><a href="module-Playlists.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Playlists.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Playlists.html#.togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#.undeletePlaylist">undeletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~deleteItemsFromPlaylist">deleteItemsFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~restoreItemFromPlaylist">restoreItemFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~unlikePlaylist">unlikePlaylist</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.assignModeratorToComment">assignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.closeComment">closeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createComment">createComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deleteComment">deleteComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.editComment">editComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeIndexMetadata">fetchChallengeIndexMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeLessonData">fetchChallengeLessonData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeMetadata">fetchChallengeMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeUserActiveChallenges">fetchChallengeUserActiveChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComment">fetchComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCommentRelies">fetchCommentRelies</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComments">fetchComments</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedChallenges">fetchCompletedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchOwnedChallenges">fetchOwnedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchRecentUserActivities">fetchRecentUserActivities</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchTopComment">fetchTopComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserChallengeProgress">fetchUserChallengeProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPracticeNotes">fetchUserPracticeNotes</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likeComment">likeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.openComment">openComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnroll">postChallengesEnroll</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnrollmentNotification">postChallengesEnrollmentNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesHideCompletedBanner">postChallengesHideCompletedBanner</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesLeave">postChallengesLeave</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSetStartDate">postChallengesSetStartDate</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSoloNotification">postChallengesSoloNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesUnlock">postChallengesUnlock</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.replyToComment">replyToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportComment">reportComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.restoreComment">restoreComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unassignModeratorToComment">unassignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unlikeComment">unlikeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#~fetchLastInteractedChild">fetchLastInteractedChild</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCoachLessons">fetchCoachLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonsFeaturingThisContent">fetchLessonsFeaturingThisContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchOtherSongVersions">fetchOtherSongVersions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentForDownload">fetchParentForDownload</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedRecommendedContent">fetchRelatedRecommendedContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~fetchRelatedByLicense">fetchRelatedByLicense</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getNextAndPreviousQuarterDates">getNextAndPreviousQuarterDates</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li><li data-type='method'><a href="module-Sanity-Services.html#~handleCustomFetchAll">handleCustomFetchAll</a></li></ul></li><li><a href="module-Sessions.html">Sessions</a><ul class='methods'><li data-type='method'><a href="module-Sessions.html#.login">login</a></li><li data-type='method'><a href="module-Sessions.html#.logout">logout</a></li></ul></li><li><a href="module-UserActivity.html">UserActivity</a><ul class='methods'><li data-type='method'><a href="module-UserActivity.html#.calculateLongestStreaks">calculateLongestStreaks</a></li><li data-type='method'><a href="module-UserActivity.html#.createPracticeNotes">createPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.deletePracticeSession">deletePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.deleteUserActivity">deleteUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeNotes">getPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeSessions">getPracticeSessions</a></li><li data-type='method'><a href="module-UserActivity.html#.getProgressRows">getProgressRows</a></li><li data-type='method'><a href="module-UserActivity.html#.getRecentActivity">getRecentActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserMonthlyStats">getUserMonthlyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserWeeklyStats">getUserWeeklyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.pinProgressRow">pinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserActivity">recordUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserPractice">recordUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.removeUserPractice">removeUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.restorePracticeSession">restorePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserPractice">restoreUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.unpinProgressRow">unpinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.updatePracticeNotes">updatePracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.updateUserPractice">updateUserPractice</a></li></ul></li><li><a href="module-UserChat.html">UserChat</a><ul class='methods'><li data-type='method'><a href="module-UserChat.html#.fetchChatSettings">fetchChatSettings</a></li></ul></li><li><a href="module-UserManagement.html">UserManagement</a><ul class='methods'><li data-type='method'><a href="module-UserManagement.html#.blockUser">blockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.deletePicture">deletePicture</a></li><li data-type='method'><a href="module-UserManagement.html#.unblockUser">unblockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPicture">uploadPicture</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPictureFromS3">uploadPictureFromS3</a></li></ul></li><li><a href="module-UserNotifications.html">UserNotifications</a><ul class='methods'><li data-type='method'><a href="module-UserNotifications.html#.deleteNotification">deleteNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotificationSettings">fetchNotificationSettings</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotifications">fetchNotifications</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchUnreadCount">fetchUnreadCount</a></li><li data-type='method'><a href="module-UserNotifications.html#.markAllNotificationsAsRead">markAllNotificationsAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsRead">markNotificationAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsUnread">markNotificationAsUnread</a></li><li data-type='method'><a href="module-UserNotifications.html#.updateNotificationSetting">updateNotificationSetting</a></li></ul></li><li><a href="module-UserProfile.html">UserProfile</a><ul class='methods'><li data-type='method'><a href="module-UserProfile.html#.otherStats">otherStats</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="ContentOrganization.html">ContentOrganization</a></li><li><a href="Gamification.html">Gamification</a></li><li><a href="UserManagementSystem.html">UserManagementSystem</a></li></ul><h3><a href="global.html">Global</a></h3>
32
+ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Awards.html">Awards</a><ul class='methods'><li data-type='method'><a href="module-Awards.html#.fetchAwardsForUser">fetchAwardsForUser</a></li></ul></li><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Content-Services-V2.html">Content-Services-V2</a><ul class='methods'><li data-type='method'><a href="module-Content-Services-V2.html#.getContentRows">getContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getNewAndUpcoming">getNewAndUpcoming</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecent">getRecent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecommendedForYou">getRecommendedForYou</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getScheduleContentRows">getScheduleContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getTabResults">getTabResults</a></li></ul></li><li><a href="module-Interests.html">Interests</a><ul class='methods'><li data-type='method'><a href="module-Interests.html#.fetchInterests">fetchInterests</a></li><li data-type='method'><a href="module-Interests.html#.fetchUninterests">fetchUninterests</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsInterested">markContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsNotInterested">markContentAsNotInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsInterested">removeContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsNotInterested">removeContentAsNotInterested</a></li></ul></li><li><a href="module-Permissions.html">Permissions</a><ul class='methods'><li data-type='method'><a href="module-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-Permissions.html#.reset">reset</a></li></ul></li><li><a href="module-Playlists.html">Playlists</a><ul class='methods'><li data-type='method'><a href="module-Playlists.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Playlists.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Playlists.html#.togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#.undeletePlaylist">undeletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~deleteItemsFromPlaylist">deleteItemsFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~restoreItemFromPlaylist">restoreItemFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~unlikePlaylist">unlikePlaylist</a></li></ul></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.assignModeratorToComment">assignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.closeComment">closeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createComment">createComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deleteComment">deleteComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.editComment">editComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeIndexMetadata">fetchChallengeIndexMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeLessonData">fetchChallengeLessonData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeMetadata">fetchChallengeMetadata</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchChallengeUserActiveChallenges">fetchChallengeUserActiveChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComment">fetchComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCommentRelies">fetchCommentRelies</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComments">fetchComments</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedChallenges">fetchCompletedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchOwnedChallenges">fetchOwnedChallenges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchRecentUserActivities">fetchRecentUserActivities</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchTopComment">fetchTopComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserChallengeProgress">fetchUserChallengeProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPracticeNotes">fetchUserPracticeNotes</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likeComment">likeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.openComment">openComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesCommunityNotification">postChallengesCommunityNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnroll">postChallengesEnroll</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesEnrollmentNotification">postChallengesEnrollmentNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesHideCompletedBanner">postChallengesHideCompletedBanner</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesLeave">postChallengesLeave</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSetStartDate">postChallengesSetStartDate</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesSoloNotification">postChallengesSoloNotification</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postChallengesUnlock">postChallengesUnlock</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.replyToComment">replyToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportComment">reportComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.restoreComment">restoreComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unassignModeratorToComment">unassignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unlikeComment">unlikeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#~fetchLastInteractedChild">fetchLastInteractedChild</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchArtists">fetchArtists</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCoachLessons">fetchCoachLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonsFeaturingThisContent">fetchLessonsFeaturingThisContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchOtherSongVersions">fetchOtherSongVersions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchParentForDownload">fetchParentForDownload</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedRecommendedContent">fetchRelatedRecommendedContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~fetchRelatedByLicense">fetchRelatedByLicense</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getNextAndPreviousQuarterDates">getNextAndPreviousQuarterDates</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li><li data-type='method'><a href="module-Sanity-Services.html#~handleCustomFetchAll">handleCustomFetchAll</a></li></ul></li><li><a href="module-Sessions.html">Sessions</a><ul class='methods'><li data-type='method'><a href="module-Sessions.html#.login">login</a></li><li data-type='method'><a href="module-Sessions.html#.logout">logout</a></li></ul></li><li><a href="module-UserActivity.html">UserActivity</a><ul class='methods'><li data-type='method'><a href="module-UserActivity.html#.calculateLongestStreaks">calculateLongestStreaks</a></li><li data-type='method'><a href="module-UserActivity.html#.createPracticeNotes">createPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.deletePracticeSession">deletePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.deleteUserActivity">deleteUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeNotes">getPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeSessions">getPracticeSessions</a></li><li data-type='method'><a href="module-UserActivity.html#.getProgressRows">getProgressRows</a></li><li data-type='method'><a href="module-UserActivity.html#.getRecentActivity">getRecentActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserMonthlyStats">getUserMonthlyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserWeeklyStats">getUserWeeklyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.pinProgressRow">pinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserActivity">recordUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserPractice">recordUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.removeUserPractice">removeUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.restorePracticeSession">restorePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserPractice">restoreUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.unpinProgressRow">unpinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.updatePracticeNotes">updatePracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.updateUserPractice">updateUserPractice</a></li></ul></li><li><a href="module-UserChat.html">UserChat</a><ul class='methods'><li data-type='method'><a href="module-UserChat.html#.fetchChatSettings">fetchChatSettings</a></li></ul></li><li><a href="module-UserManagement.html">UserManagement</a><ul class='methods'><li data-type='method'><a href="module-UserManagement.html#.blockUser">blockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.deletePicture">deletePicture</a></li><li data-type='method'><a href="module-UserManagement.html#.getUserData">getUserData</a></li><li data-type='method'><a href="module-UserManagement.html#.unblockUser">unblockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPicture">uploadPicture</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPictureFromS3">uploadPictureFromS3</a></li></ul></li><li><a href="module-UserNotifications.html">UserNotifications</a><ul class='methods'><li data-type='method'><a href="module-UserNotifications.html#.deleteNotification">deleteNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotificationSettings">fetchNotificationSettings</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotifications">fetchNotifications</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchUnreadCount">fetchUnreadCount</a></li><li data-type='method'><a href="module-UserNotifications.html#.markAllNotificationsAsRead">markAllNotificationsAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsRead">markNotificationAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsUnread">markNotificationAsUnread</a></li><li data-type='method'><a href="module-UserNotifications.html#.updateNotificationSetting">updateNotificationSetting</a></li></ul></li><li><a href="module-UserProfile.html">UserProfile</a><ul class='methods'><li data-type='method'><a href="module-UserProfile.html#.otherStats">otherStats</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="ContentOrganization.html">ContentOrganization</a></li><li><a href="Gamification.html">Gamification</a></li><li><a href="UserManagementSystem.html">UserManagementSystem</a></li></ul><h3><a href="global.html">Global</a></h3>
33
33
 
34
34
  </nav>
35
35
 
@@ -55,16 +55,25 @@ import {
55
55
  fetchUserPracticeMeta,
56
56
  fetchUserPracticeNotes,
57
57
  fetchHandler,
58
- fetchRecentUserActivities, fetchChallengeLessonData
58
+ fetchRecentUserActivities,
59
+ fetchChallengeLessonData,
60
+ fetchLastInteractedChild,
59
61
  } from './railcontent'
60
62
  import { DataContext, UserActivityVersionKey } from './dataContext.js'
61
63
  import { fetchByRailContentIds, fetchShows } from './sanity'
62
- import {fetchPlaylist, fetchUserPlaylists} from "./content-org/playlists";
64
+ import {fetchPlaylist, fetchUserPlaylists} from "./content-org/playlists"
65
+ import {pinnedGuidedCourses} from "./content-org/guided-courses"
63
66
  import {convertToTimeZone, getMonday, getWeekNumber, isSameDate, isNextDay, getTimeRemainingUntilLocal} from './dateUtils.js'
64
67
  import { globalConfig } from './config'
65
68
  import {collectionLessonTypes, lessonTypesMapping, progressTypesMapping, showsLessonTypes, songs} from "../contentTypeConfig";
66
- import {getAllStartedOrCompleted, getProgressStateByIds} from "./contentProgress";
69
+ import {
70
+ getAllStartedOrCompleted,
71
+ getProgressPercentageByIds,
72
+ getProgressStateByIds,
73
+ getResumeTimeSecondsByIds
74
+ } from "./contentProgress";
67
75
  import {TabResponseType} from "../contentMetaData";
76
+ import {isContentLikedByIds} from "./contentLikes.js";
68
77
 
69
78
  const DATA_KEY_PRACTICES = 'practices'
70
79
  const DATA_KEY_LAST_UPDATED_TIME = 'u'
@@ -398,7 +407,7 @@ export async function removeUserPractice(id) {
398
407
  Object.keys(localContext.data[DATA_KEY_PRACTICES]).forEach((date) => {
399
408
  localContext.data[DATA_KEY_PRACTICES][date] = localContext.data[DATA_KEY_PRACTICES][
400
409
  date
401
- ].filter((practice) => practice.id !== id)
410
+ ].filter((practice) => practice.id !== id)
402
411
  })
403
412
  }
404
413
  },
@@ -958,26 +967,45 @@ export async function getProgressRows({ brand = null, limit = 8 } = {}) {
958
967
  'learning-path-course',
959
968
  'learning-path-level'
960
969
  ]);
970
+ // TODO slice progress to a reasonable number, say 100
971
+ const [recentPlaylists, progressContents, allPinnedGuidedCourse, userPinnedItem ] = await Promise.all([
972
+ fetchUserPlaylists(brand, { sort: '-last_progress', limit: limit}),
973
+ getAllStartedOrCompleted({onlyIds: false, brand: brand }),
974
+ pinnedGuidedCourses(brand),
975
+ getUserPinnedItem(brand),
976
+ ])
977
+
978
+ let pinnedGuidedCourse = allPinnedGuidedCourse?.[0] ?? null
961
979
 
962
- const recentPlaylists = await fetchUserPlaylists(brand, {
963
- sort: '-last_progress',
964
- limit: limit,
965
- });
966
980
  const playlists = recentPlaylists?.data || [];
967
981
  const eligiblePlaylistItems = await getEligiblePlaylistItems(playlists);
968
982
  const playlistEngagedOnContents = eligiblePlaylistItems.map(item => item.last_engaged_on);
969
- const playlistsContents = await fetchByRailContentIds(playlistEngagedOnContents, 'progress-tracker');
983
+
984
+ const nonPlaylistContentIds = Object.keys(progressContents)
985
+ if (pinnedGuidedCourse) {
986
+ nonPlaylistContentIds.push(pinnedGuidedCourse.content_id);
987
+ }
988
+ if (userPinnedItem?.progressType === 'content') {
989
+ nonPlaylistContentIds.push(userPinnedItem.id)
990
+ }
991
+ const [ playlistsContents, contents ] = await Promise.all([
992
+ fetchByRailContentIds(playlistEngagedOnContents, 'progress-tracker'),
993
+ fetchByRailContentIds(nonPlaylistContentIds, 'progress-tracker', brand),
994
+ ]);
995
+
970
996
  const excludedParents = new Set();
971
997
  const existingShows = new Set();
998
+ // TODO this doesn't work for guided courses as the GC card takes precedence over the playlist card
999
+ // https://musora.atlassian.net/browse/BEH-812
972
1000
  for (const item of playlistsContents) {
1001
+
973
1002
  const contentId = item.id ?? item.railcontent_id;
974
- excludedParents.add(contentId)
1003
+ delete progressContents[contentId]
975
1004
  const parentIds = item.parent_content_data || [];
976
- parentIds.forEach(id => excludedParents.add(id));
1005
+ parentIds.forEach(id => delete progressContents[id] );
977
1006
  }
978
1007
 
979
- const progressContents = await getAllStartedOrCompleted({onlyIds: false, brand: brand, excludedIds: Array.from(excludedParents) });
980
- const contents = await fetchByRailContentIds(Object.keys(progressContents), 'progress-tracker', brand);
1008
+
981
1009
  const contentsMap = {};
982
1010
  contents.forEach(content => {
983
1011
  contentsMap[content.railcontent_id] = content;
@@ -1032,28 +1060,38 @@ export async function getProgressRows({ brand = null, limit = 8 } = {}) {
1032
1060
  }
1033
1061
  }
1034
1062
  }
1035
- const pinnedItem = await extractPinnedItem({
1036
- brand,
1063
+ const pinnedItem = userPinnedItem ? await extractPinnedItem(
1064
+ userPinnedItem,
1037
1065
  progressMap,
1038
- playlistItems: eligiblePlaylistItems,
1039
- })
1040
- const progressList = Array.from(progressMap.values())
1066
+ eligiblePlaylistItems,
1067
+ ) : null
1068
+
1069
+ const pinnedId = pinnedItem?.id
1070
+ const guidedCourseID = pinnedGuidedCourse?.content_id
1071
+ let combined = [];
1072
+ if (pinnedGuidedCourse) {
1073
+ const guidedCourseContent = contentsMap[guidedCourseID]
1074
+ if (guidedCourseContent) {
1075
+ const temp = await extractPinnedGuidedCourseItem(guidedCourseContent, progressMap)
1076
+ temp.pinned = true
1077
+ combined.push(temp)
1078
+ }
1079
+ }
1041
1080
  if (pinnedItem) {
1042
1081
  pinnedItem.pinned = true
1082
+ combined.push(pinnedItem)
1043
1083
  }
1084
+ const progressList = Array.from(progressMap.values())
1044
1085
 
1045
- const pinnedId = pinnedItem?.id
1046
1086
  const filteredProgressList = pinnedId
1047
- ? progressList.filter(item => item.id !== pinnedId)
1087
+ ? progressList.filter(item => !(item.id === pinnedId || item.id === guidedCourseID))
1048
1088
  : progressList;
1049
1089
  const filteredPlaylists = pinnedId
1050
- ? eligiblePlaylistItems.filter(item => item.id !== pinnedId)
1090
+ ? (eligiblePlaylistItems.filter(item => !(item.id === pinnedId || item.id === guidedCourseID)))
1051
1091
  : eligiblePlaylistItems;
1052
- const combinedBase = [...filteredProgressList, ...filteredPlaylists]
1053
- const combined = pinnedItem ? [pinnedItem, ...combinedBase] : combinedBase
1054
1092
 
1093
+ combined = [...combined, ...filteredProgressList, ...filteredPlaylists]
1055
1094
  const finalCombined = mergeAndSortItems(combined, limit)
1056
-
1057
1095
  const results = await Promise.all(
1058
1096
  finalCombined.slice(0, limit).map(item =>
1059
1097
  item.type === 'playlist'
@@ -1069,15 +1107,21 @@ export async function getProgressRows({ brand = null, limit = 8 } = {}) {
1069
1107
  };
1070
1108
  }
1071
1109
 
1110
+ async function getUserPinnedItem(brand) {
1111
+ const userRaw = await globalConfig.localStorage.getItem('user');
1112
+ const user = userRaw ? JSON.parse(userRaw) : {};
1113
+ user.brand_pinned_progress = user.brand_pinned_progress || {}
1114
+ return user.brand_pinned_progress[brand] ?? null
1115
+ }
1116
+
1072
1117
  async function processContentItem(item) {
1073
1118
  let data = item.raw;
1074
1119
  const contentType = getFormattedType(data.type, data.brand);
1075
1120
  const status = item.state;
1076
-
1077
1121
  let ctaText = 'Continue';
1078
1122
  if (contentType === 'transcription' || contentType === 'play-along' || contentType === 'jam-track') ctaText = 'Replay Song';
1079
1123
  if (contentType === 'lesson') ctaText = status === 'completed' ? 'Revisit Lesson' : 'Continue';
1080
- if (collectionLessonTypes.includes(contentType) &amp;&amp; status === 'completed') ctaText = 'Revisit Lessons' ;
1124
+ if ((contentType === 'song tutorial' || collectionLessonTypes.includes(contentType)) &amp;&amp; status === 'completed') ctaText = 'Revisit Lessons' ;
1081
1125
  if (contentType === 'pack' &amp;&amp; status === 'completed') {
1082
1126
  ctaText = 'View Lessons';
1083
1127
  }
@@ -1111,6 +1155,29 @@ async function processContentItem(item) {
1111
1155
  const nextLesson = lessons.find(lesson => lesson.id === nextId)
1112
1156
  data.first_incomplete_child = nextLesson?.parent ?? nextLesson
1113
1157
  data.second_incomplete_child = (nextLesson?.parent) ? nextLesson : null
1158
+ if(data.type === 'guided-course'){
1159
+ let isLocked = new Date(nextLesson.published_on) > new Date()
1160
+ data.thumbnail = nextLesson.thumbnail
1161
+ // USHP-4 completed
1162
+ if (status === 'completed') {
1163
+ // duplicated code to above, but here for clarity
1164
+ ctaText = 'Revisit Lessons'
1165
+ // USHP-1 if lesson locked show unlock in X time
1166
+ } else if (isLocked) {
1167
+ data.is_locked = true
1168
+ const timeRemaining = getTimeRemainingUntilLocal(nextLesson.published_on, {withTotalSeconds: true})
1169
+ data.time_remaining_seconds = timeRemaining.totalSeconds
1170
+ ctaText = 'Next lesson in ' + timeRemaining.formatted
1171
+ }
1172
+ // USHP-2 start course if not started
1173
+ else if (status === 'not-started') {
1174
+ ctaText = "Start Course"
1175
+ }
1176
+ // USHP-3 in progress for lesson
1177
+ else {
1178
+ ctaText = "Continue"
1179
+ }
1180
+ }
1114
1181
  }
1115
1182
  }
1116
1183
 
@@ -1126,7 +1193,7 @@ async function processContentItem(item) {
1126
1193
  data.completed_children = completedCount;
1127
1194
  data.child_count = shows.length;
1128
1195
  item.percent = Math.round((completedCount / shows.length) * 100);
1129
- if(completedCount == shows.length) {
1196
+ if(completedCount === shows.length) {
1130
1197
  ctaText = 'Revisit Lessons';
1131
1198
  }
1132
1199
  }
@@ -1143,8 +1210,8 @@ async function processContentItem(item) {
1143
1210
  badge: data.badge ?? null,
1144
1211
  isLocked: data.is_locked ?? false,
1145
1212
  subtitle: !data.child_count || data.lesson_count === 1
1146
- ? (contentType === 'lesson') ? `${item.percent}% Complete`: `${data.difficulty_string} • ${data.artist_name}`
1147
- : `${data.completed_children} of ${data.lesson_count ?? data.child_count} Lessons Complete`
1213
+ ? (contentType === 'lesson') ? `${item.percent}% Complete`: `${data.difficulty_string} • ${data.artist_name}`
1214
+ : `${data.completed_children} of ${data.lesson_count ?? data.child_count} Lessons Complete`
1148
1215
  },
1149
1216
  cta: {
1150
1217
  text: ctaText,
@@ -1155,21 +1222,21 @@ async function processContentItem(item) {
1155
1222
  id: data.id,
1156
1223
  slug: data.slug,
1157
1224
  child: data.first_incomplete_child
1158
- ? {
1225
+ ? {
1159
1226
  id: data.first_incomplete_child.id,
1160
1227
  type: data.first_incomplete_child.type,
1161
1228
  brand: data.first_incomplete_child.brand,
1162
1229
  slug: data.first_incomplete_child.slug,
1163
1230
  child: data.second_incomplete_child
1164
- ? {
1231
+ ? {
1165
1232
  id: data.second_incomplete_child.id,
1166
1233
  type: data.second_incomplete_child.type,
1167
1234
  brand: data.second_incomplete_child.brand,
1168
1235
  slug: data.second_incomplete_child.slug
1169
1236
  }
1170
- : null
1237
+ : null
1171
1238
  }
1172
- : null
1239
+ : null
1173
1240
  }
1174
1241
  },
1175
1242
  progressTimestamp: item.progressTimestamp
@@ -1281,12 +1348,13 @@ function mergeAndSortItems(items, limit) {
1281
1348
  .sort((a, b) => {
1282
1349
  if (a.pinned &amp;&amp; !b.pinned) return -1;
1283
1350
  if (!a.pinned &amp;&amp; b.pinned) return 1;
1351
+ // TODO guided course should always be before user pinned item
1284
1352
  return b.progressTimestamp - a.progressTimestamp;
1285
1353
  })
1286
1354
  .slice(0, limit + 5);
1287
1355
  }
1288
1356
 
1289
- function findIncompleteLesson(progressOnItems, currentContentId, contentType) {
1357
+ export function findIncompleteLesson(progressOnItems, currentContentId, contentType) {
1290
1358
  const ids = Object.keys(progressOnItems).map(Number);
1291
1359
  if (contentType === 'guided-course') {
1292
1360
  // Return first incomplete lesson
@@ -1321,11 +1389,10 @@ function findIncompleteLesson(progressOnItems, currentContentId, contentType) {
1321
1389
  * .catch(error => console.error(error));
1322
1390
  */
1323
1391
  export async function pinProgressRow(brand, id, progressType) {
1324
- if (!(brand &amp;&amp; id &amp;&amp; progressType)) throw new Error(`undefined parameter progressType: ${progressType} brand: ${brand} or id: ${id}`)
1325
1392
  const url = `/api/user-management-system/v1/progress/pin?brand=${brand}&amp;id=${id}&amp;progressType=${progressType}`;
1326
1393
  const response = await fetchHandler(url, 'PUT', null)
1327
- if (response &amp;&amp; !response.error &amp;&amp; response['action'] === 'update_user_pin') {
1328
- await updateUserPinnedProgressRow(brand, {
1394
+ if (response &amp;&amp; !response.error) {
1395
+ await updatePinnedProgressRow(brand, {
1329
1396
  id,
1330
1397
  progressType,
1331
1398
  pinnedAt: new Date().toISOString(),
@@ -1337,25 +1404,23 @@ export async function pinProgressRow(brand, id, progressType) {
1337
1404
  * Unpins the current pinned progress row for a user, scoped by brand.
1338
1405
  *
1339
1406
  * @param {string} brand - The brand context for the unpin action.
1340
- * @param {string} id - The content or playlist id to unpin.
1341
1407
  * @returns {Promise&lt;Object>} - A promise resolving to the response from the unpin API.
1342
1408
  *
1343
1409
  * @example
1344
- * unpinProgressRow('drumeo', 123456)
1410
+ * unpinProgressRow('drumeo')
1345
1411
  * .then(response => console.log(response))
1346
1412
  * .catch(error => console.error(error));
1347
1413
  */
1348
- export async function unpinProgressRow(brand, id) {
1349
- if (!(brand &amp;&amp; id)) throw new Error(`undefined parameter brand: ${brand} or id: ${id}`)
1350
- const url = `/api/user-management-system/v1/progress/unpin?brand=${brand}&amp;id=${id}`
1414
+ export async function unpinProgressRow(brand) {
1415
+ const url = `/api/user-management-system/v1/progress/unpin?brand=${brand}`
1351
1416
  const response = await fetchHandler(url, 'PUT', null)
1352
- if (response &amp;&amp; !response.error &amp;&amp; response['action'] === 'clear_user_pin') {
1353
- await updateUserPinnedProgressRow(brand, null)
1417
+ if (response &amp;&amp; !response.error) {
1418
+ await updatePinnedProgressRow(brand, null)
1354
1419
  }
1355
1420
  return response
1356
1421
  }
1357
1422
 
1358
- async function updateUserPinnedProgressRow(brand, pinnedData) {
1423
+ async function updatePinnedProgressRow(brand, pinnedData) {
1359
1424
  const userRaw = await globalConfig.localStorage.getItem('user');
1360
1425
  const user = userRaw ? JSON.parse(userRaw) : {};
1361
1426
  user.brand_pinned_progress = user.brand_pinned_progress || {}
@@ -1363,14 +1428,7 @@ async function updateUserPinnedProgressRow(brand, pinnedData) {
1363
1428
  await globalConfig.localStorage.setItem('user', JSON.stringify(user))
1364
1429
  }
1365
1430
 
1366
- async function extractPinnedItem({brand, progressMap, playlistItems}) {
1367
- const userRaw = await globalConfig.localStorage.getItem('user');
1368
- const user = userRaw ? JSON.parse(userRaw) : {};
1369
- user.brand_pinned_progress = user.brand_pinned_progress || {}
1370
-
1371
- const pinned = user.brand_pinned_progress[brand]
1372
- if (!pinned) return null
1373
-
1431
+ async function extractPinnedItem(pinned, progressMap, playlistItems) {
1374
1432
  const {id, progressType, pinnedAt} = pinned
1375
1433
 
1376
1434
  if (progressType === 'content') {
@@ -1403,7 +1461,7 @@ async function extractPinnedItem({brand, progressMap, playlistItems}) {
1403
1461
  raw: playlist,
1404
1462
  progressTimestamp: new Date(pinnedAt).getTime(),
1405
1463
  type: 'playlist',
1406
- last_engaged_on: playlist.items[0],
1464
+ last_engaged_on: playlist.last_engaged_on,
1407
1465
  }
1408
1466
  }
1409
1467
  }
@@ -1411,6 +1469,35 @@ async function extractPinnedItem({brand, progressMap, playlistItems}) {
1411
1469
  return null
1412
1470
  }
1413
1471
 
1472
+ async function extractPinnedGuidedCourseItem(guidedCourse, progressMap) {
1473
+ const children = guidedCourse.lessons.map(child => child.id)
1474
+ let existingGuidedCourseProgress = null
1475
+ if (progressMap.has(guidedCourse.id)) {
1476
+ existingGuidedCourseProgress = progressMap.get(guidedCourse.id)
1477
+ progressMap.delete(guidedCourse.id)
1478
+ }
1479
+ let lastChild = null
1480
+ children.forEach(child => {
1481
+ if (progressMap.has(child)) {
1482
+ let childProgress = progressMap.get(child)
1483
+ if (!lastChild &amp;&amp; childProgress.state !== 'completed') {
1484
+ lastChild = childProgress
1485
+ lastChild.id = child
1486
+ }
1487
+ progressMap.delete(child)
1488
+ }
1489
+ })
1490
+ return existingGuidedCourseProgress ?? {
1491
+ id: guidedCourse.id,
1492
+ state: 'not-started',
1493
+ percent: 0,
1494
+ raw: guidedCourse,
1495
+ pinned: true,
1496
+ progressTimestamp: new Date().getTime(),
1497
+ childIndex: guidedCourse.id,
1498
+ }
1499
+ }
1500
+
1414
1501
  function getFirstLeafLessonId(data) {
1415
1502
  function findFirstLeaf(lessons) {
1416
1503
  for (const item of lessons) {
@@ -1427,7 +1514,6 @@ function getFirstLeafLessonId(data) {
1427
1514
  }
1428
1515
 
1429
1516
 
1430
-
1431
1517
  </code></pre>
1432
1518
  </article>
1433
1519
  </section>
@@ -1442,7 +1528,7 @@ function getFirstLeafLessonId(data) {
1442
1528
  <br class="clear">
1443
1529
 
1444
1530
  <footer>
1445
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Mon Jul 07 2025 16:10:04 GMT+0300 (Eastern European Summer Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1531
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Wed Jul 16 2025 14:58:03 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1446
1532
  </footer>
1447
1533
 
1448
1534
  <script>prettyPrint();</script>