musora-content-services 2.147.1 → 2.149.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.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.149.0](https://github.com/railroadmedia/musora-content-services/compare/v2.148.0...v2.149.0) (2026-04-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* remove countdown logic for GC in progress card ([#897](https://github.com/railroadmedia/musora-content-services/issues/897)) ([254bc2a](https://github.com/railroadmedia/musora-content-services/commit/254bc2a0a695f68e449a49a71197be01654ba9aa))
|
|
11
|
+
|
|
12
|
+
## [2.148.0](https://github.com/railroadmedia/musora-content-services/compare/v2.145.6...v2.148.0) (2026-04-03)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* Add children to fetchScheduledAndNewReleases for navigateTo calculations ([#901](https://github.com/railroadmedia/musora-content-services/issues/901)) ([3ade1ad](https://github.com/railroadmedia/musora-content-services/commit/3ade1ad400e1dd9e56d245f3a37d77d709a0d4e1))
|
|
18
|
+
* **BEHLPT-18:** remove user from muppet ([#891](https://github.com/railroadmedia/musora-content-services/issues/891)) ([ecdf778](https://github.com/railroadmedia/musora-content-services/commit/ecdf778108f974f59885c3d442c47c90152c5554))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* patches indexedDB.deleteDatabase to silence noisy safari errs ([#888](https://github.com/railroadmedia/musora-content-services/issues/888)) ([c67d408](https://github.com/railroadmedia/musora-content-services/commit/c67d40800ffe64d3eab204b97eaf26413b5a6e79))
|
|
24
|
+
|
|
5
25
|
### [2.147.1](https://github.com/railroadmedia/musora-content-services/compare/v2.147.0...v2.147.1) (2026-04-02)
|
|
6
26
|
|
|
7
27
|
|
package/package.json
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
showsLessonTypes,
|
|
13
13
|
songs,
|
|
14
14
|
} from '../../../contentTypeConfig.js'
|
|
15
|
-
import { getTimeRemainingUntilLocal } from '../../dateUtils.js'
|
|
16
15
|
import { PARENT_ID_TOP_LEVEL } from '../../sync/models/ContentProgress'
|
|
17
16
|
|
|
18
17
|
/**
|
|
@@ -58,7 +57,7 @@ function generateContentPromises(contents) {
|
|
|
58
57
|
const promises = []
|
|
59
58
|
if (!contents) return promises
|
|
60
59
|
const existingShows = new Set()
|
|
61
|
-
|
|
60
|
+
const allRecentTypeSet = new Set(Object.values(recentTypes.homeRow))
|
|
62
61
|
allRecentTypeSet.delete('learning-path-v2') // we do this to remove from homepage, until we allow a-la-carte learning paths
|
|
63
62
|
contents.forEach((content) => {
|
|
64
63
|
const type = content.type
|
|
@@ -80,33 +79,12 @@ function generateContentPromises(contents) {
|
|
|
80
79
|
export async function processContentItem(content) {
|
|
81
80
|
const contentType = getFormattedType(content.type, content.brand)
|
|
82
81
|
const isLive = content.isLive ?? false
|
|
83
|
-
|
|
82
|
+
const ctaText = getDefaultCTATextForContent(content, contentType)
|
|
84
83
|
|
|
85
84
|
const { completedChildren, allChildren } = await getCompletedChildren(content, contentType)
|
|
86
85
|
content.completed_children = completedChildren
|
|
87
86
|
content.all_children = allChildren
|
|
88
87
|
|
|
89
|
-
if (content.type === 'guided-course') {
|
|
90
|
-
const nextLessonPublishedOn = content.children.find(
|
|
91
|
-
(child) => child.id === content.navigateTo.id
|
|
92
|
-
)?.published_on
|
|
93
|
-
let isLocked = new Date(nextLessonPublishedOn) > new Date()
|
|
94
|
-
if (isLocked) {
|
|
95
|
-
content.is_locked = true
|
|
96
|
-
const timeRemaining = getTimeRemainingUntilLocal(nextLessonPublishedOn, {
|
|
97
|
-
withTotalSeconds: true,
|
|
98
|
-
})
|
|
99
|
-
content.time_remaining_seconds = timeRemaining.totalSeconds
|
|
100
|
-
ctaText = 'Next lesson in ' + timeRemaining.formatted
|
|
101
|
-
} else if (
|
|
102
|
-
!content.progressStatus ||
|
|
103
|
-
content.progressStatus === 'not-started' ||
|
|
104
|
-
content.progressPercentage === 0
|
|
105
|
-
) {
|
|
106
|
-
ctaText = 'Start Course'
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
88
|
return {
|
|
111
89
|
id: content.id,
|
|
112
90
|
progressType: 'content',
|
|
@@ -125,16 +103,10 @@ export async function processContentItem(content) {
|
|
|
125
103
|
badge_template: content.badge_template ?? null,
|
|
126
104
|
badge_template_rear: content.badge_template_rear ?? null,
|
|
127
105
|
isLocked: content.is_locked ?? false,
|
|
128
|
-
subtitle:
|
|
129
|
-
collectionLessonTypes.includes(content.type) || content.lesson_count > 1
|
|
130
|
-
? `${content.completed_children ?? 0} of ${content.all_children ?? content.lesson_count ?? content.child_count} Lessons Complete`
|
|
131
|
-
: (contentType === 'lesson' || contentType === 'show') && isLive === false
|
|
132
|
-
? `${content.progressPercentage}% Complete`
|
|
133
|
-
: `${content.difficulty_string} • ${content.artist_name}`,
|
|
106
|
+
subtitle: getSubtitle(content, contentType, isLive),
|
|
134
107
|
},
|
|
135
108
|
cta: {
|
|
136
109
|
text: ctaText,
|
|
137
|
-
timeRemainingToUnlockSeconds: content.time_remaining_seconds ?? null,
|
|
138
110
|
action: {
|
|
139
111
|
type: content.type,
|
|
140
112
|
brand: content.brand,
|
|
@@ -147,21 +119,37 @@ export async function processContentItem(content) {
|
|
|
147
119
|
}
|
|
148
120
|
}
|
|
149
121
|
|
|
122
|
+
function getSubtitle(content, contentType, isLive) {
|
|
123
|
+
if (collectionLessonTypes.includes(content.type) || content.lesson_count > 1) {
|
|
124
|
+
return `${content.completed_children ?? 0} of ${content.all_children ?? content.lesson_count ?? content.child_count} Lessons Complete`
|
|
125
|
+
}
|
|
126
|
+
if ((contentType === 'lesson' || contentType === 'show') && !isLive) {
|
|
127
|
+
return `${content.progressPercentage}% Complete`
|
|
128
|
+
}
|
|
129
|
+
return `${content.difficulty_string} • ${content.artist_name}`
|
|
130
|
+
}
|
|
131
|
+
|
|
150
132
|
function getDefaultCTATextForContent(content, contentType) {
|
|
151
|
-
|
|
133
|
+
const notStarted =
|
|
134
|
+
!content.progressStatus ||
|
|
135
|
+
content.progressStatus === 'not-started' ||
|
|
136
|
+
content.progressPercentage === 0
|
|
137
|
+
if (content.type === 'guided-course' && notStarted) return 'Start Course'
|
|
138
|
+
|
|
152
139
|
if (content.progressStatus === 'completed') {
|
|
153
140
|
if (
|
|
154
141
|
contentType === songs[content.brand] ||
|
|
155
142
|
contentType === 'play along' ||
|
|
156
143
|
contentType === 'jam track'
|
|
157
144
|
)
|
|
158
|
-
|
|
159
|
-
if (contentType === 'lesson' || contentType === 'show')
|
|
145
|
+
return 'Replay Song'
|
|
146
|
+
if (contentType === 'lesson' || contentType === 'show') return 'Revisit Lesson'
|
|
160
147
|
if (contentType === 'song tutorial' || collectionLessonTypes.includes(content.type))
|
|
161
|
-
|
|
162
|
-
if (contentType === 'course-collection')
|
|
148
|
+
return 'Revisit Lessons'
|
|
149
|
+
if (contentType === 'course-collection') return 'View Lessons'
|
|
163
150
|
}
|
|
164
|
-
|
|
151
|
+
|
|
152
|
+
return 'Continue'
|
|
165
153
|
}
|
|
166
154
|
|
|
167
155
|
async function getCompletedChildren(content, contentType) {
|
|
@@ -718,8 +718,7 @@ export async function calculateLongestStreaks(userId = globalConfig.sessionConfi
|
|
|
718
718
|
let practiceDates = Object.keys(practices)
|
|
719
719
|
.map((dateStr) => {
|
|
720
720
|
const [y, m, d] = dateStr.split('-').map(Number)
|
|
721
|
-
const newDate = new Date()
|
|
722
|
-
newDate.setFullYear(y, m - 1, d)
|
|
721
|
+
const newDate = new Date(y, m - 1, d, 0, 0, 0, 0)
|
|
723
722
|
return newDate
|
|
724
723
|
})
|
|
725
724
|
.sort((a, b) => a - b)
|
|
@@ -744,7 +743,7 @@ export async function calculateLongestStreaks(userId = globalConfig.sessionConfi
|
|
|
744
743
|
let currentDailyStreak = 1
|
|
745
744
|
for (let i = 1; i < normalizedDates.length; i++) {
|
|
746
745
|
const diffInDays = (normalizedDates[i] - normalizedDates[i - 1]) / (1000 * 60 * 60 * 24)
|
|
747
|
-
if (diffInDays === 1) {
|
|
746
|
+
if (Math.round(diffInDays) === 1) {
|
|
748
747
|
currentDailyStreak++
|
|
749
748
|
longestDailyStreak = Math.max(longestDailyStreak, currentDailyStreak)
|
|
750
749
|
} else {
|
|
@@ -770,7 +769,7 @@ export async function calculateLongestStreaks(userId = globalConfig.sessionConfi
|
|
|
770
769
|
|
|
771
770
|
for (let i = 1; i < weekStartDates.length; i++) {
|
|
772
771
|
const diffInWeeks = (weekStartDates[i] - weekStartDates[i - 1]) / (1000 * 60 * 60 * 24 * 7)
|
|
773
|
-
if (diffInWeeks === 1) {
|
|
772
|
+
if (Math.round(diffInWeeks) === 1) {
|
|
774
773
|
currentWeeklyStreak++
|
|
775
774
|
longestWeeklyStreak = Math.max(longestWeeklyStreak, currentWeeklyStreak)
|
|
776
775
|
} else {
|