musora-content-services 2.25.1 → 2.26.1

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,15 @@
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.26.1](https://github.com/railroadmedia/musora-content-services/compare/v2.26.0...v2.26.1) (2025-07-16)
6
+
7
+ ## [2.26.0](https://github.com/railroadmedia/musora-content-services/compare/v2.25.1...v2.26.0) (2025-07-16)
8
+
9
+
10
+ ### Features
11
+
12
+ * **MU2-805:** Set a pauseLiveEventPollingUntil field when user mark all notificatio… ([#351](https://github.com/railroadmedia/musora-content-services/issues/351)) ([bfe1010](https://github.com/railroadmedia/musora-content-services/commit/bfe10107c522ea725436e4a6338a869e852c08d5))
13
+
5
14
  ### [2.25.1](https://github.com/railroadmedia/musora-content-services/compare/v2.25.0...v2.25.1) (2025-07-16)
6
15
 
7
16
 
package/link_mcs.sh CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.25.1",
3
+ "version": "2.26.1",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.d.ts CHANGED
@@ -219,6 +219,7 @@ import {
219
219
  fetchScheduledReleases,
220
220
  fetchShows,
221
221
  fetchShowsData,
222
+ fetchSiblingContent,
222
223
  fetchSongArtistCount,
223
224
  fetchSongById,
224
225
  fetchTabData,
@@ -266,6 +267,8 @@ import {
266
267
  markAllNotificationsAsRead,
267
268
  markNotificationAsRead,
268
269
  markNotificationAsUnread,
270
+ pauseLiveEventPollingUntil,
271
+ startLiveEventPolling,
269
272
  updateNotificationSetting
270
273
  } from './services/user/notifications.js';
271
274
 
@@ -408,6 +411,7 @@ declare module 'musora-content-services' {
408
411
  fetchScheduledReleases,
409
412
  fetchShows,
410
413
  fetchShowsData,
414
+ fetchSiblingContent,
411
415
  fetchSimilarItems,
412
416
  fetchSongArtistCount,
413
417
  fetchSongById,
@@ -484,6 +488,7 @@ declare module 'musora-content-services' {
484
488
  markNotificationAsUnread,
485
489
  openComment,
486
490
  otherStats,
491
+ pauseLiveEventPollingUntil,
487
492
  pinGuidedCourse,
488
493
  pinProgressRow,
489
494
  pinnedGuidedCourses,
@@ -522,6 +527,7 @@ declare module 'musora-content-services' {
522
527
  sendPasswordResetEmail,
523
528
  setStudentViewForUser,
524
529
  setupAccount,
530
+ startLiveEventPolling,
525
531
  status,
526
532
  togglePlaylistPrivate,
527
533
  unEnrollUserInGuidedCourse,
package/src/index.js CHANGED
@@ -219,6 +219,7 @@ import {
219
219
  fetchScheduledReleases,
220
220
  fetchShows,
221
221
  fetchShowsData,
222
+ fetchSiblingContent,
222
223
  fetchSongArtistCount,
223
224
  fetchSongById,
224
225
  fetchTabData,
@@ -266,6 +267,8 @@ import {
266
267
  markAllNotificationsAsRead,
267
268
  markNotificationAsRead,
268
269
  markNotificationAsUnread,
270
+ pauseLiveEventPollingUntil,
271
+ startLiveEventPolling,
269
272
  updateNotificationSetting
270
273
  } from './services/user/notifications.js';
271
274
 
@@ -407,6 +410,7 @@ export {
407
410
  fetchScheduledReleases,
408
411
  fetchShows,
409
412
  fetchShowsData,
413
+ fetchSiblingContent,
410
414
  fetchSimilarItems,
411
415
  fetchSongArtistCount,
412
416
  fetchSongById,
@@ -483,6 +487,7 @@ export {
483
487
  markNotificationAsUnread,
484
488
  openComment,
485
489
  otherStats,
490
+ pauseLiveEventPollingUntil,
486
491
  pinGuidedCourse,
487
492
  pinProgressRow,
488
493
  pinnedGuidedCourses,
@@ -521,6 +526,7 @@ export {
521
526
  sendPasswordResetEmail,
522
527
  setStudentViewForUser,
523
528
  setupAccount,
529
+ startLiveEventPolling,
524
530
  status,
525
531
  togglePlaylistPrivate,
526
532
  unEnrollUserInGuidedCourse,
File without changes
@@ -1440,7 +1440,50 @@ async function fetchRelatedByLicense(railcontentId, brand, onlyUseSongTypes, cou
1440
1440
  }
1441
1441
 
1442
1442
  /**
1443
- * Fetch related lessons for a specific lesson by RailContent ID and type.
1443
+ * Fetch sibling lessons to a specific lesson
1444
+ * @param {string} railContentId - The RailContent ID of the current lesson.
1445
+ * @param {string} brand - The current brand.
1446
+ * @returns {Promise<Array<Object>|null>} - The fetched related lessons data or null if not found.
1447
+ */
1448
+ export async function fetchSiblingContent(railContentId, brand)
1449
+ {
1450
+ const filterGetParent = await new FilterBuilder(`references(^._id) && _type == ^.parent_type`, {
1451
+ pullFutureContent: true,
1452
+ }).buildFilter()
1453
+ const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
1454
+
1455
+ const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, artist->, "permission_id": permission[]->railcontent_id, "genre": genre[]->name`
1456
+
1457
+ const query = `*[railcontent_id == ${railContentId} && brand == "${brand}"]{
1458
+ _type, parent_type, 'parent_id': parent_content_data[0].id, railcontent_id,
1459
+ 'for-calculations': *[${filterGetParent}][0]{
1460
+ 'siblings-list': child[]->railcontent_id,
1461
+ 'parents-list': *[${filterGetParent}][0].child[]->railcontent_id
1462
+ },
1463
+ "related_lessons" : *[${filterGetParent}][0].child[${childrenFilter}]->{${queryFields}}
1464
+ }`
1465
+
1466
+ let result = await fetchSanity(query, false)
1467
+
1468
+ //there's no way in sanity to retrieve the index of an array, so we must calculate after fetch
1469
+ if (result['for-calculations'] && result['for-calculations']['parents-list']) {
1470
+ const calc = result['for-calculations']
1471
+ const parentCount = calc['parents-list'].length
1472
+ const currentParentIndex = calc['parents-list'].indexOf(result['parent_id']) + 1
1473
+ const siblingCount = calc['siblings-list'].length
1474
+ const currentSiblingIndex = calc['siblings-list'].indexOf(result['railcontent_id']) + 1
1475
+
1476
+ delete result['for-calculations']
1477
+ result = { ...result, parentCount, currentParentIndex, siblingCount, currentSiblingIndex }
1478
+ return result
1479
+ } else {
1480
+ delete result['for-calculations']
1481
+ return result
1482
+ }
1483
+ }
1484
+
1485
+ /**
1486
+ * Fetch lessons related to a specific lesson by RailContent ID and type.
1444
1487
  * @param {string} railContentId - The RailContent ID of the current lesson.
1445
1488
  * @param {string} brand - The current brand.
1446
1489
  * @returns {Promise<Array<Object>|null>} - The fetched related lessons data or null if not found.
@@ -1458,43 +1501,18 @@ export async function fetchRelatedLessons(railContentId, brand) {
1458
1501
  const filterSongSameGenre = await new FilterBuilder(
1459
1502
  `_type=="song" && _type==^._type && brand == "${brand}" && references(^.genre[]->_id) && railcontent_id !=${railContentId}`
1460
1503
  ).buildFilter()
1461
- const filterNeighbouringSiblings = await new FilterBuilder(`references(^._id)`, {
1462
- pullFutureContent: true,
1463
- }).buildFilter()
1464
- const childrenFilter = await new FilterBuilder(``, { isChildrenFilter: true }).buildFilter()
1465
1504
  const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, railcontent_id, artist->,"permission_id": permission[]->railcontent_id,_type, "genre": genre[]->name`
1466
1505
  const queryFieldsWithSort = queryFields + ', sort'
1467
1506
  const query = `*[railcontent_id == ${railContentId} && brand == "${brand}" && (!defined(permission) || references(*[_type=='permission']._id))]{
1468
- _type, parent_type, 'parent_id': parent_content_data[0].id, railcontent_id,
1469
- 'for-calculations': *[references(^._id) && !(_type in ['license'])][0]{
1470
- 'siblings-list': child[]->railcontent_id,
1471
- 'parents-list': *[references(^._id)][0].child[]->railcontent_id
1472
- },
1507
+ _type, parent_type, railcontent_id,
1473
1508
  "related_lessons" : array::unique([
1474
- ...(*[${filterNeighbouringSiblings}][0].child[${childrenFilter}]->{${queryFields}}),
1475
1509
  ...(*[${filterSongSameArtist}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1476
1510
  ...(*[${filterSongSameGenre}]{${queryFields}}|order(published_on desc, title asc)[0...10]),
1477
1511
  ...(*[${filterSameTypeAndSortOrder}]{${queryFieldsWithSort}}|order(sort asc, title asc)[0...10]),
1478
1512
  ...(*[${filterSameType}]{${queryFields}}|order(published_on desc, title asc)[0...10])
1479
1513
  ,
1480
1514
  ])[0...10]}`
1481
- let result = await fetchSanity(query, false)
1482
-
1483
- //there's no way in sanity to retrieve the index of an array, so we must calculate after fetch
1484
- if (result['for-calculations'] && result['for-calculations']['parents-list']) {
1485
- const calc = result['for-calculations']
1486
- const parentCount = calc['parents-list'].length
1487
- const currentParent = calc['parents-list'].indexOf(result['parent_id']) + 1
1488
- const siblingCount = calc['siblings-list'].length
1489
- const currentSibling = calc['siblings-list'].indexOf(result['railcontent_id']) + 1
1490
-
1491
- delete result['for-calculations']
1492
- result = { ...result, parentCount, currentParent, siblingCount, currentSibling }
1493
- return result
1494
- } else {
1495
- delete result['for-calculations']
1496
- return result
1497
- }
1515
+ return await fetchSanity(query, false)
1498
1516
  }
1499
1517
 
1500
1518
  /**
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { fetchHandler } from '../railcontent.js'
5
5
  import './types.js'
6
+ import {fetchLiveEvent} from "../sanity";
6
7
 
7
8
  const baseUrl = `/api/notifications`
8
9
 
@@ -68,7 +69,12 @@ export async function markNotificationAsRead(notificationId) {
68
69
  * .then(response => console.log(response))
69
70
  * .catch(error => console.error(error));
70
71
  */
71
- export async function markAllNotificationsAsRead() {
72
+ export async function markAllNotificationsAsRead(brand = 'drumeo') {
73
+ const liveEvent = await fetchLiveEvent(brand)
74
+ if(liveEvent){
75
+ await pauseLiveEventPollingUntil(liveEvent.live_event_end_time)
76
+ }
77
+
72
78
  const url = `${baseUrl}/v1/read`
73
79
  return fetchHandler(url, 'put')
74
80
  }
@@ -224,6 +230,35 @@ export async function updateNotificationSetting({ brand, settingName, email, pus
224
230
  return fetchHandler(url, 'PUT', null, payload);
225
231
  }
226
232
 
233
+ /**
234
+ * Pauses live event polling until the specified time.
235
+ * @param {string|null} [until=null] - ISO timestamp string or null to unpause
236
+ * @returns {Promise<Object>} - Promise resolving to the API response
237
+ */
238
+ export async function pauseLiveEventPollingUntil(until = null) {
239
+ const url = `/api/user-management-system/v1/users/pause-polling${until ? `?until=${until}` : ''}`
240
+ return fetchHandler(url, 'PUT', null)
241
+ }
242
+
243
+ /**
244
+ * Start live event polling.
245
+ * @returns {Promise<Object>} - Promise resolving to the API response
246
+ */
247
+ export async function startLiveEventPolling() {
248
+ const url = `/api/user-management-system/v1/users/start-polling`
249
+ return fetchHandler(url, 'PUT', null)
250
+ }
251
+
252
+ /**
253
+ * Fetches the current live event polling state.
254
+ + @returns {Promise<Object>} - Promise resolving to the polling state
255
+ */
256
+
257
+ export async function fetchLiveEventPollingState() {
258
+ const url = `/api/user-management-system/v1/users/polling`
259
+ return fetchHandler(url, 'GET', null)
260
+ }
261
+
227
262
 
228
263
 
229
264