musora-content-services 2.45.0 → 2.47.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 (68) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/docs/ContentOrganization.html +2 -2
  3. package/docs/Forums.html +2 -2
  4. package/docs/Gamification.html +2 -2
  5. package/docs/UserManagementSystem.html +2 -2
  6. package/docs/api_types.js.html +2 -2
  7. package/docs/config.js.html +2 -2
  8. package/docs/content-org_content-org.js.html +2 -2
  9. package/docs/content-org_guided-courses.ts.html +2 -2
  10. package/docs/content-org_playlists-types.js.html +2 -2
  11. package/docs/content-org_playlists.js.html +2 -2
  12. package/docs/content.js.html +2 -2
  13. package/docs/forums_categories.ts.html +2 -2
  14. package/docs/forums_forums.ts.html +2 -2
  15. package/docs/forums_posts.ts.html +2 -2
  16. package/docs/forums_threads.ts.html +30 -3
  17. package/docs/gamification_awards.ts.html +2 -2
  18. package/docs/gamification_gamification.js.html +2 -2
  19. package/docs/global.html +2 -2
  20. package/docs/index.html +2 -2
  21. package/docs/module-Accounts.html +2 -2
  22. package/docs/module-Awards.html +2 -2
  23. package/docs/module-Categories.html +0 -0
  24. package/docs/module-Config.html +2 -2
  25. package/docs/module-Content-Services-V2.html +2 -2
  26. package/docs/module-ForumCategories.html +0 -0
  27. package/docs/module-Forums.html +1726 -598
  28. package/docs/module-GuidedCourses.html +2 -2
  29. package/docs/module-Interests.html +2 -2
  30. package/docs/module-Payments.html +2 -2
  31. package/docs/module-Permissions.html +2 -2
  32. package/docs/module-Playlists.html +2 -2
  33. package/docs/module-Railcontent-Services.html +2 -2
  34. package/docs/module-Sanity-Services.html +2 -2
  35. package/docs/module-Sessions.html +2 -2
  36. package/docs/module-Threads.html +0 -0
  37. package/docs/module-UserActivity.html +2 -2
  38. package/docs/module-UserChat.html +2 -2
  39. package/docs/module-UserManagement.html +2 -2
  40. package/docs/module-UserMemberships.html +2 -2
  41. package/docs/module-UserNotifications.html +2 -2
  42. package/docs/module-UserProfile.html +2 -2
  43. package/docs/railcontent.js.html +2 -2
  44. package/docs/sanity.js.html +2 -2
  45. package/docs/userActivity.js.html +3 -3
  46. package/docs/user_account.ts.html +2 -2
  47. package/docs/user_chat.js.html +2 -2
  48. package/docs/user_interests.js.html +2 -2
  49. package/docs/user_management.js.html +2 -2
  50. package/docs/user_memberships.js.html +2 -2
  51. package/docs/user_notifications.js.html +2 -2
  52. package/docs/user_payments.ts.html +2 -2
  53. package/docs/user_permissions.js.html +2 -2
  54. package/docs/user_profile.js.html +2 -2
  55. package/docs/user_sessions.js.html +2 -2
  56. package/docs/user_types.js.html +2 -2
  57. package/docs/user_user-management-system.js.html +2 -2
  58. package/package.json +1 -1
  59. package/src/contentMetaData.js +31 -362
  60. package/src/contentTypeConfig.js +3 -2
  61. package/src/index.d.ts +4 -2
  62. package/src/index.js +4 -2
  63. package/src/services/contentProgress.js +0 -0
  64. package/src/services/forums/categories.ts +0 -0
  65. package/src/services/forums/threads.ts +28 -1
  66. package/src/services/gamification/awards.ts +0 -0
  67. package/src/services/user/memberships.js +0 -0
  68. package/src/services/userActivity.js +1 -1
@@ -56,132 +56,6 @@ export const TabResponseType = {
56
56
  };
57
57
 
58
58
  const commonMetadata = {
59
- instructor: {
60
- name: 'Coaches',
61
- icon: 'icon-coach',
62
- allowableFilters: ['genre', 'focus'],
63
- sortBy: '-published_on',
64
- },
65
- course: {
66
- name: 'Courses',
67
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory', 'creativity', 'lifestyle'],
68
- icon: 'icon-courses',
69
- tabs: [
70
- Tabs.Courses,
71
- Tabs.Instructors,
72
- Tabs.Genres,
73
- ],
74
- },
75
- pack: {
76
- allowableFilters: [],
77
- },
78
- 'student-review': {
79
- name: 'Student Reviews',
80
- icon: 'icon-student-focus',
81
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory', 'creativity', 'lifestyle'],
82
- sortBy: '-published_on',
83
- tabs: [
84
- Tabs.Lessons,
85
- Tabs.Instructors,
86
- Tabs.Genres,
87
- ],
88
- },
89
- song: {
90
- name: 'Songs',
91
- icon: 'icon-songs',
92
- description:
93
- 'Play the songs you love with note-for-note transcriptions and handy practice tools.',
94
- allowableFilters: ['difficulty', 'genre', 'lifestyle', 'instrumentless'],
95
- tabs: [
96
- Tabs.Songs,
97
- Tabs.Artists,
98
- Tabs.Genres,
99
- ],
100
- },
101
- 'quick-tips': {
102
- name: 'Quick Tips',
103
- icon: 'icon-shows',
104
- description:
105
- 'Only have 10 minutes? These short lessons are designed to inspire you with quick tips and exercises, even if you don’t have lots of time to practice.',
106
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory', 'lifestyle', 'creativity'],
107
- sortBy: '-published_on',
108
- tabs: [
109
- Tabs.Lessons,
110
- Tabs.Instructors,
111
- Tabs.Genres,
112
- ],
113
- },
114
- 'question-and-answer': {
115
- name: 'Q&A',
116
- description:
117
- 'Each week we go live to answer your questions. Submit your questions in advance using the button below, in the Q&A thread in the forums, or live in the community chat.',
118
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory'],
119
- sortBy: '-published_on',
120
- },
121
- recommendation: {
122
- tabs: [
123
- { name: 'All', is_group_by: true, value: ['group_by,Recommended'] },
124
- { name: 'Songs', value: ['filter,song'] },
125
- { name: 'Lessons', value: ['filter,lesson'] },
126
- { name: 'Workouts', value: ['filter,workout'] },
127
- ],
128
- },
129
- workout: {
130
- name: 'Workouts',
131
- shortname: 'Workouts',
132
- allowableFilters: ['difficulty', 'genre', 'topic'],
133
- tabs: [
134
- Tabs.All,
135
- {
136
- name: '5 Minutes',
137
- short_name: '5 MINS',
138
- is_required_field: true,
139
- value: 'length_in_seconds,-450',
140
- value_web: ['length_in_seconds < 450'],
141
- },
142
- {
143
- name: '10 Minutes',
144
- short_name: '10 MINS',
145
- is_required_field: true,
146
- value: 'length_in_seconds,450-750',
147
- value_web: ['length_in_seconds > 451', 'length_in_seconds < 751'],
148
- },
149
- {
150
- name: '15+ Minutes',
151
- short_name: '15+ MINS',
152
- is_required_field: true,
153
- value: 'length_in_seconds,750+',
154
- value_web: ['length_in_seconds > 750'],
155
- },
156
- Tabs.Instructors,
157
- ],
158
- modalText:
159
- 'Workouts are fun play-along lessons that help hone your musical skills. They cover various topics, and have multiple difficulty and duration options — so there’s always a perfect Workout for you. Just pick one, press start, and play along!',
160
- },
161
- 'coach-lessons': {
162
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory', 'lifestyle', 'type'],
163
- },
164
- 'lesson-history': {
165
- name: 'Lesson History',
166
- shortname: 'Lesson History',
167
- icon: 'bookmark',
168
- allowableFilters: ['difficulty', 'type'],
169
- sortBy: '-published_on',
170
- tabs: [
171
- Tabs.InProgress,
172
- Tabs.Completed,
173
- ],
174
- },
175
- 'new-release': {
176
- name: 'New Releases',
177
- description:
178
- "Here's a list of all lessons recently added to Drumeo. Browse on your own or use search to find whatever it is you'd like to learn!",
179
- allowableFilters: ['type'],
180
- sortBy: '-published_on',
181
- tabs: [
182
- Tabs.Lessons,
183
- ],
184
- },
185
59
  'lessons': {
186
60
  name: 'Lessons',
187
61
  filterOptions: {
@@ -225,6 +99,22 @@ const commonMetadata = {
225
99
  Tabs.ExploreAll
226
100
  ],
227
101
  },
102
+ 'recent': {
103
+ name: 'Recent Lessons',
104
+ tabs: [
105
+ Tabs.RecentAll,
106
+ Tabs.RecentIncomplete,
107
+ Tabs.RecentCompleted
108
+ ],
109
+ },
110
+ recommendation: {
111
+ tabs: [
112
+ { name: 'All', is_group_by: true, value: ['group_by,Recommended'] },
113
+ { name: 'Songs', value: ['filter,song'] },
114
+ { name: 'Lessons', value: ['filter,lesson'] },
115
+ { name: 'Workouts', value: ['filter,workout'] },
116
+ ],
117
+ },
228
118
  'recent-activities': {
229
119
  name: 'Recent Activity',
230
120
  onlyAvailableTabs: true,
@@ -239,84 +129,6 @@ const commonMetadata = {
239
129
  }
240
130
  const contentMetadata = {
241
131
  drumeo: {
242
- instructor: {
243
- description:
244
- 'Your drumming journey is unique. You need personalized coaching that helps you reach your goals. Learn from some of the best drummers in the world!',
245
- },
246
- live: {
247
- thumbnailUrl: 'https://dpwjbsxqtam5n.cloudfront.net/shows/show-live.jpg',
248
- name: 'Live',
249
- url: '/live-streams',
250
- shortname: 'Live Lessons',
251
- icon: 'icon-shows',
252
- description:
253
- 'Practice sessions, Q&A, celebrations, and more are available during Drumeo live lessons. Subscribe to an event or the whole calendar, so you don’t miss out!',
254
- allowableFilters: ['difficulty', 'genre', 'essential', 'theory'],
255
- sortBy: '-published_on',
256
- tabs: [
257
- Tabs.Lessons,
258
- Tabs.Instructors,
259
- Tabs.Genres,
260
- ],
261
- },
262
- 'odd-times': {
263
- thumbnailUrl:
264
- 'https://musora.com/cdn-cgi/imagedelivery/0Hon__GSkIjm-B_W77SWCA/1bf6fc7a-d1a5-4934-d322-b9f6da454000/public',
265
- name: 'Odd Times With Aaron Edgar',
266
- shortname: 'Episodes',
267
- icon: 'icon-shows',
268
- allowableFilters: [],
269
- sortBy: 'sort',
270
- },
271
- rudiment: {
272
- name: 'Rudiments',
273
- icon: 'icon-drums',
274
- description:
275
- 'The 40 drum rudiments are essential for any drummer, no matter the style, genre, or scenario. You can use the videos below to help you learn, practice, and perfect every single one.',
276
- allowableFilters: ['difficulty', 'genre', 'gear', 'topic'],
277
- tabs: [
278
- Tabs.All,
279
- {
280
- name: 'Drags',
281
- short_name: 'DRAGS',
282
- is_required_field: true,
283
- value: 'topic,Drags',
284
- },
285
- {
286
- name: 'Flams',
287
- short_name: 'FLAMS',
288
- is_required_field: true,
289
- value: 'topic,Flams',
290
- },
291
- {
292
- name: 'Paradiddles',
293
- short_name: 'PARADIDDLES',
294
- is_required_field: true,
295
- value: 'topic,Paradiddles',
296
- },
297
- {
298
- name: 'Rolls',
299
- short_name: 'ROLLS',
300
- is_required_field: true,
301
- value: 'topic,Rolls',
302
- },
303
- ],
304
- sortBy: 'sort',
305
- },
306
- 'play-along': {
307
- name: 'Play-Alongs',
308
- icon: 'icon-play-alongs',
309
- description:
310
- 'Add your drumming to high-quality drumless play-along tracks - with handy playback tools to help you create the perfect performance.',
311
- allowableFilters: ['difficulty', 'genre', 'bpm'],
312
- tabs: [
313
- {
314
- name: 'All Play-Alongs',
315
- short_name: 'ALL',
316
- value: '',
317
- },
318
- ],
319
- },
320
132
  'lessons': {
321
133
  name: 'Lessons',
322
134
  filterOptions: {
@@ -325,32 +137,6 @@ const contentMetadata = {
325
137
  type: ['Single Lessons', 'Practice Alongs', 'Performances', 'Courses', 'Shows', 'Documentaries', 'Live Archives', 'Student Archives'],
326
138
  progress: PROGRESS_NAMES,
327
139
  },
328
- tabs: [
329
- Tabs.ForYou,
330
- Tabs.Individuals,
331
- Tabs.Collections,
332
- Tabs.ExploreAll
333
- ],
334
- },
335
- 'recent': {
336
- name: 'Recent Lessons',
337
- tabs: [
338
- Tabs.RecentAll,
339
- Tabs.RecentIncomplete,
340
- Tabs.RecentCompleted
341
- ],
342
- },
343
- 'songs': {
344
- name: 'Songs',
345
- filterOptions: {
346
- difficulty: DIFFICULTY_STRINGS,
347
- style: [
348
- 'Blues', 'Christian', 'Classical', 'Country', 'Disco', 'Electronic', 'Folk', 'Funk', 'Hip-Hop/Rap', 'Holiday', 'Jazz', 'Soundtrack',
349
- 'World', 'Metal', 'Pop', 'R&B/Soul', 'Rock'
350
- ],
351
- type: ['Tutorials', 'Transcriptions', 'Play-Alongs', 'Jam Tracks'],
352
- progress: PROGRESS_NAMES,
353
- },
354
140
  sortingOptions: {
355
141
  title: 'Sort By',
356
142
  type: 'radio',
@@ -358,13 +144,12 @@ const contentMetadata = {
358
144
  },
359
145
  tabs: [
360
146
  Tabs.ForYou,
361
- Tabs.Tutorials,
362
- Tabs.Transcriptions,
363
- Tabs.PlayAlongs,
364
- Tabs.JamTracks,
147
+ Tabs.Individuals,
148
+ Tabs.Collections,
365
149
  Tabs.ExploreAll
366
150
  ],
367
151
  },
152
+ 'songs-types': ['Tutorials', 'Transcriptions', 'Play-Alongs', 'Jam Tracks'],
368
153
  },
369
154
  pianote: {
370
155
  'lessons': {
@@ -375,24 +160,6 @@ const contentMetadata = {
375
160
  type: ['Single Lessons', 'Practice Alongs', 'Performances', 'Courses', 'Live Archives', 'Student Archives'],
376
161
  progress: PROGRESS_NAMES,
377
162
  },
378
- tabs: [
379
- Tabs.ForYou,
380
- Tabs.Individuals,
381
- Tabs.Collections,
382
- Tabs.ExploreAll
383
- ],
384
- },
385
- 'songs': {
386
- name: 'Songs',
387
- filterOptions: {
388
- difficulty: DIFFICULTY_STRINGS,
389
- style: [
390
- 'Blues', 'Christian', 'Classical', 'Country', 'Disco', 'Electronic', 'Folk', 'Funk', 'Hip-Hop/Rap', 'Holiday', 'Jazz', 'Soundtrack',
391
- 'World', 'Metal', 'Pop', 'R&B/Soul', 'Rock'
392
- ],
393
- type: ['Tutorials', 'Sheet Music', 'Play-Alongs', 'Jam Tracks'],
394
- progress: PROGRESS_NAMES,
395
- },
396
163
  sortingOptions: {
397
164
  title: 'Sort By',
398
165
  type: 'radio',
@@ -400,114 +167,21 @@ const contentMetadata = {
400
167
  },
401
168
  tabs: [
402
169
  Tabs.ForYou,
403
- Tabs.Tutorials,
404
- Tabs.Transcriptions,
405
- Tabs.PlayAlongs,
406
- Tabs.JamTracks,
170
+ Tabs.Individuals,
171
+ Tabs.Collections,
407
172
  Tabs.ExploreAll
408
173
  ],
409
174
  },
410
- 'recent': {
411
- name: 'Recent Lessons',
412
- tabs: [
413
- Tabs.RecentAll,
414
- Tabs.RecentIncomplete,
415
- Tabs.RecentCompleted
416
- ],
417
- },
175
+ 'songs-types': ['Tutorials', 'Sheet Music', 'Play-Alongs', 'Jam Tracks'],
418
176
  },
419
177
  guitareo: {
420
- instructor: {
421
- description:
422
- 'Tackle your next guitar goal with bite-sized courses from many of the world\'s best guitarists.',
423
- },
424
- recording: {
425
- name: 'Archives',
426
- shortname: 'Lessons',
427
- icon: 'icon-library',
428
- description:
429
- 'Miss a live event or just want to watch a particular episode again? This is the place to do it. All of the Guitareo live broadcasts are archived here for you to watch at your leisure. If you have any questions or want to discuss the topics mentioned in the videos you can always post in the forum.',
430
- allowableFilters: ['difficulty', 'genre'],
431
- tabs: [
432
- Tabs.Lessons,
433
- Tabs.Instructors,
434
- Tabs.Genres,
435
- ],
436
- },
437
- 'songs': {
438
- name: 'Songs',
439
- filterOptions: {
440
- difficulty: DIFFICULTY_STRINGS,
441
- style: [
442
- 'Blues', 'Christian', 'Classical', 'Country', 'Disco', 'Electronic', 'Folk', 'Funk', 'Hip-Hop/Rap', 'Holiday', 'Jazz', 'Soundtrack',
443
- 'World', 'Metal', 'Pop', 'R&B/Soul', 'Rock'
444
- ],
445
- type: ['Tutorials', 'Tabs', 'Play-Alongs', 'Jam Tracks'],
446
- progress: PROGRESS_NAMES,
447
- },
448
- sortingOptions: {
449
- title: 'Sort By',
450
- type: 'radio',
451
- items: SortingOptions.AllSortingOptions,
452
- },
453
- tabs: [
454
- Tabs.ForYou,
455
- Tabs.Tutorials,
456
- Tabs.Transcriptions,
457
- Tabs.PlayAlongs,
458
- Tabs.JamTracks,
459
- Tabs.ExploreAll
460
- ],
461
- },
462
- 'recent': {
463
- name: 'Recent Lessons',
464
- tabs: [
465
- Tabs.RecentAll,
466
- Tabs.RecentIncomplete,
467
- Tabs.RecentCompleted
468
- ],
469
- },
178
+ 'songs-types': ['Tutorials', 'Tabs', 'Play-Alongs', 'Jam Tracks'],
179
+ },
180
+ playbass: {
181
+ 'songs-types': ['Tutorials', 'Tabs', 'Play-Alongs', 'Jam Tracks'],
470
182
  },
471
183
  singeo: {
472
- 'student-review': {
473
- thumbnailUrl: 'https://d1923uyy6spedc.cloudfront.net/student-reviews.png',
474
- icon: 'icon-student-focus',
475
- description:
476
- 'Want feedback on your singing? Submit a video for student review. We will watch your submission and then provide helpful encouragement and feedback. This is a great way to build accountability and benefit from the expertise of our teachers.',
477
- },
478
- 'songs': {
479
- name: 'Songs',
480
- filterOptions: {
481
- difficulty: DIFFICULTY_STRINGS,
482
- style: [
483
- 'Blues', 'Christian', 'Classical', 'Country', 'Disco', 'Electronic', 'Folk', 'Funk', 'Hip-Hop/Rap', 'Holiday', 'Jazz', 'Soundtrack',
484
- 'World', 'Metal', 'Pop', 'R&B/Soul', 'Rock'
485
- ],
486
- type: ['Tutorials', 'Sheet Music', 'Play-Alongs', 'Jam Tracks'],
487
- progress: PROGRESS_NAMES,
488
- },
489
- sortingOptions: {
490
- title: 'Sort By',
491
- type: 'radio',
492
- items: SortingOptions.AllSortingOptions,
493
- },
494
- tabs: [
495
- Tabs.ForYou,
496
- Tabs.Tutorials,
497
- Tabs.Transcriptions,
498
- Tabs.PlayAlongs,
499
- Tabs.JamTracks,
500
- Tabs.ExploreAll
501
- ],
502
- },
503
- 'recent': {
504
- name: 'Recent Lessons',
505
- tabs: [
506
- Tabs.RecentAll,
507
- Tabs.RecentIncomplete,
508
- Tabs.RecentCompleted
509
- ],
510
- },
184
+ 'songs-types': ['Tutorials', 'Sheet Music', 'Play-Alongs', 'Jam Tracks'],
511
185
  }
512
186
  }
513
187
 
@@ -519,22 +193,17 @@ export const typeWithSortOrder = [
519
193
 
520
194
  export function processMetadata(brand, type, withFilters = false) {
521
195
  let brandMetaData = contentMetadata[brand]?.[type]
522
- // If the type is explicitly defined as null or the brand doesn't exist return null
523
- // Specifically this is for drumeo.student-review
524
- if (brandMetaData === null) {
525
- return null
526
- }
527
196
  let commonMetaData = commonMetadata[type]
528
197
  brandMetaData = { ...commonMetaData, ...brandMetaData }
198
+ if (type === 'songs' && contentMetadata[brand]?.['songs-types']) {
199
+ brandMetaData['filterOptions']['type'] = contentMetadata[brand]['songs-types']
200
+ }
529
201
  if (Object.keys(brandMetaData).length === 0) {
530
202
  return null
531
203
  }
532
204
  const processedData = {
533
205
  type,
534
- thumbnailUrl: brandMetaData.thumbnailUrl || null,
535
206
  name: brandMetaData.name || null,
536
- description: brandMetaData.description || null,
537
- url: brandMetaData.url ? brand + brandMetaData.url : brand + '/' + type,
538
207
  sort: brandMetaData.sortingOptions || null,
539
208
  tabs: brandMetaData.tabs || [],
540
209
  }
@@ -545,7 +214,7 @@ export function processMetadata(brand, type, withFilters = false) {
545
214
 
546
215
  if (withFilters && !brandMetaData.filterOptions) {
547
216
  Object.keys(brandMetaData).forEach((key) => {
548
- if (!['thumbnailUrl', 'name', 'description'].includes(key)) {
217
+ if ('name' !== key) {
549
218
  processedData[key] = brandMetaData[key]
550
219
  }
551
220
  })
@@ -150,6 +150,7 @@ export const showsTypes = {
150
150
  pianote: ['student-review', 'question-and-answer'],
151
151
  guitareo: ['student-review', 'question-and-answer', 'archives', 'recording'],
152
152
  singeo: ['student-review', 'question-and-answer'],
153
+ playbass: ['student-review', 'question-and-answer'],
153
154
  }
154
155
 
155
156
  export const coachLessonsTypes = [
@@ -241,6 +242,7 @@ export const songs = {
241
242
  guitareo: 'tab',
242
243
  pianote: 'sheet music',
243
244
  singeo: 'sheet music',
245
+ playbass: 'tab',
244
246
  }
245
247
 
246
248
  export const filterTypes = {
@@ -631,6 +633,7 @@ export function getNewReleasesTypes(brand) {
631
633
  return [...baseNewTypes, 'archives', 'recording', 'chords-and-scales']
632
634
  case 'pianote':
633
635
  case 'singeo':
636
+ case 'playbass':
634
637
  default:
635
638
  return baseNewTypes
636
639
  }
@@ -678,8 +681,6 @@ export function getUpcomingEventsTypes(brand) {
678
681
  ]
679
682
  case 'guitareo':
680
683
  return [...baseLiveTypes, 'archives']
681
- case 'pianote':
682
- case 'singeo':
683
684
  default:
684
685
  return baseLiveTypes
685
686
  }
package/src/index.d.ts CHANGED
@@ -105,6 +105,8 @@ import {
105
105
 
106
106
  import {
107
107
  createThread,
108
+ fetchFollowedThreads,
109
+ fetchLatestThreads,
108
110
  fetchThreads,
109
111
  followThread,
110
112
  lockThread,
@@ -313,7 +315,6 @@ import {
313
315
 
314
316
  import {
315
317
  login,
316
- loginWithProvider,
317
318
  logout
318
319
  } from './services/user/sessions.js';
319
320
 
@@ -410,6 +411,7 @@ declare module 'musora-content-services' {
410
411
  fetchContentRows,
411
412
  fetchCustomerPayments,
412
413
  fetchEnrollmentPageMetadata,
414
+ fetchFollowedThreads,
413
415
  fetchForumCategories,
414
416
  fetchFoundation,
415
417
  fetchGenreLessons,
@@ -417,6 +419,7 @@ declare module 'musora-content-services' {
417
419
  fetchHierarchy,
418
420
  fetchInterests,
419
421
  fetchLastInteractedChild,
422
+ fetchLatestThreads,
420
423
  fetchLeaving,
421
424
  fetchLessonContent,
422
425
  fetchLessonsFeaturingThisContent,
@@ -530,7 +533,6 @@ declare module 'musora-content-services' {
530
533
  lockThread,
531
534
  logUserPractice,
532
535
  login,
533
- loginWithProvider,
534
536
  logout,
535
537
  markAllNotificationsAsRead,
536
538
  markContentAsInterested,
package/src/index.js CHANGED
@@ -105,6 +105,8 @@ import {
105
105
 
106
106
  import {
107
107
  createThread,
108
+ fetchFollowedThreads,
109
+ fetchLatestThreads,
108
110
  fetchThreads,
109
111
  followThread,
110
112
  lockThread,
@@ -313,7 +315,6 @@ import {
313
315
 
314
316
  import {
315
317
  login,
316
- loginWithProvider,
317
318
  logout
318
319
  } from './services/user/sessions.js';
319
320
 
@@ -409,6 +410,7 @@ export {
409
410
  fetchContentRows,
410
411
  fetchCustomerPayments,
411
412
  fetchEnrollmentPageMetadata,
413
+ fetchFollowedThreads,
412
414
  fetchForumCategories,
413
415
  fetchFoundation,
414
416
  fetchGenreLessons,
@@ -416,6 +418,7 @@ export {
416
418
  fetchHierarchy,
417
419
  fetchInterests,
418
420
  fetchLastInteractedChild,
421
+ fetchLatestThreads,
419
422
  fetchLeaving,
420
423
  fetchLessonContent,
421
424
  fetchLessonsFeaturingThisContent,
@@ -529,7 +532,6 @@ export {
529
532
  lockThread,
530
533
  logUserPractice,
531
534
  login,
532
- loginWithProvider,
533
535
  logout,
534
536
  markAllNotificationsAsRead,
535
537
  markContentAsInterested,
File without changes
File without changes
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { HttpClient } from '../../infrastructure/http/HttpClient'
5
5
  import { globalConfig } from '../config.js'
6
- import { ForumThread } from './types'
6
+ import { ForumCategory, ForumThread } from './types'
7
7
  import { PaginatedResponse } from '../api/types'
8
8
 
9
9
  const baseUrl = `/api/forums`
@@ -157,3 +157,30 @@ export async function unlockThread(threadId: number, brand: string): Promise<voi
157
157
  return httpClient.delete<void>(`${baseUrl}/v1/threads/${threadId}/lock?brand=${brand}`)
158
158
  }
159
159
 
160
+ /**
161
+ * Fetches followed forum Threads for the given brand and current user.
162
+ *
163
+ * @param {string} brand - The brand context (e.g., "drumeo", "singeo").
164
+ * @returns {Promise<PaginatedResponse<ForumThread>>} - A promise that resolves to the list of forum threads.
165
+ * @throws {HttpError} - If the request fails.
166
+ */
167
+ export async function fetchFollowedThreads(
168
+ brand: string
169
+ ): Promise<PaginatedResponse<ForumThread>> {
170
+ const httpClient = new HttpClient(globalConfig.baseUrl)
171
+ return httpClient.get<PaginatedResponse<ForumThread>>(`${baseUrl}/v1/threads?brand=${brand}`)
172
+ }
173
+
174
+ /**
175
+ * Fetches latest forum Threads for the given brand and not blocked to current user.
176
+ *
177
+ * @param {string} brand - The brand context (e.g., "drumeo", "singeo").
178
+ * @returns {Promise<PaginatedResponse<ForumThread>>} - A promise that resolves to the list of forum threads.
179
+ * @throws {HttpError} - If the request fails.
180
+ */
181
+ export async function fetchLatestThreads(
182
+ brand: string
183
+ ): Promise<PaginatedResponse<ForumThread>> {
184
+ const httpClient = new HttpClient(globalConfig.baseUrl)
185
+ return httpClient.get<PaginatedResponse<ForumThread>>(`${baseUrl}/v1/threads/latest?brand=${brand}`)
186
+ }
File without changes
File without changes
@@ -1118,7 +1118,7 @@ async function processContentItem(content) {
1118
1118
  })
1119
1119
  content.time_remaining_seconds = timeRemaining.totalSeconds
1120
1120
  ctaText = 'Next lesson in ' + timeRemaining.formatted
1121
- } else if (!content.progressStatus || content.progressStatus === 'not-started') {
1121
+ } else if (!content.progressStatus || content.progressStatus === 'not-started' || content.progressPercentage === 0) {
1122
1122
  ctaText = 'Start Course'
1123
1123
  }
1124
1124
  }