@streamscloud/embeddable 13.0.0 → 13.1.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 (64) hide show
  1. package/dist/core/utils/utils.d.ts +1 -0
  2. package/dist/core/utils/utils.js +4 -0
  3. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.d.ts +2 -0
  4. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.js +4 -3
  5. package/dist/media-center/config/types.d.ts +2 -1
  6. package/dist/media-center/media-center/cmp.media-center-proxy.svelte +8 -3
  7. package/dist/media-center/media-center/discover/community-features.svelte +3 -3
  8. package/dist/media-center/media-center/discover/data-loading.js +1 -1
  9. package/dist/media-center/media-center/discover/discover-view-handler.svelte.d.ts +10 -3
  10. package/dist/media-center/media-center/discover/discover-view-handler.svelte.js +11 -11
  11. package/dist/media-center/media-center/discover/discover-view.svelte +17 -17
  12. package/dist/media-center/media-center/footer/media-center-footer.svelte +1 -1
  13. package/dist/media-center/media-center/header/media-center-header.svelte +18 -12
  14. package/dist/media-center/media-center/media-center-context.svelte.d.ts +14 -10
  15. package/dist/media-center/media-center/media-center-context.svelte.js +101 -43
  16. package/dist/media-center/media-center/media-center-settings.svelte.d.ts +3 -1
  17. package/dist/media-center/media-center/media-center-settings.svelte.js +8 -14
  18. package/dist/media-center/media-center/media-center-view.svelte +22 -25
  19. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.d.ts +13 -4
  20. package/dist/media-center/media-center/moments/moments-feed-handler.svelte.js +30 -6
  21. package/dist/media-center/media-center/moments/moments-state.svelte.d.ts +4 -1
  22. package/dist/media-center/media-center/moments/moments-state.svelte.js +10 -2
  23. package/dist/media-center/media-center/{feed → posts-feed}/feed-providers-generator.d.ts +4 -8
  24. package/dist/media-center/media-center/posts-feed/feed-providers-generator.js +61 -0
  25. package/dist/media-center/media-center/posts-feed/index.d.ts +1 -0
  26. package/dist/media-center/media-center/posts-feed/index.js +1 -0
  27. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.d.ts +42 -0
  28. package/dist/media-center/media-center/posts-feed/posts-feed-handler.svelte.js +106 -0
  29. package/dist/media-center/media-center/posts-feed/types.d.ts +8 -0
  30. package/dist/media-center/media-center/streams-feed/feed-providers-generator.d.ts +12 -0
  31. package/dist/media-center/media-center/streams-feed/feed-providers-generator.js +56 -0
  32. package/dist/media-center/media-center/streams-feed/index.d.ts +1 -0
  33. package/dist/media-center/media-center/streams-feed/index.js +1 -0
  34. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.d.ts +45 -0
  35. package/dist/media-center/media-center/streams-feed/streams-feed-handler.svelte.js +111 -0
  36. package/dist/media-center/media-center/streams-feed/types.d.ts +9 -0
  37. package/dist/media-center/media-center/types.d.ts +3 -1
  38. package/dist/media-center/navigation/index.d.ts +1 -1
  39. package/dist/media-center/navigation/{media-center-state.d.ts → media-center-state.types.d.ts} +4 -3
  40. package/dist/media-center/navigation/media-center-state.types.js +1 -0
  41. package/dist/media-center/navigation/mock-navigation-handler.svelte.d.ts +3 -2
  42. package/dist/media-center/navigation/mock-navigation-handler.svelte.js +5 -2
  43. package/dist/media-center/navigation/types.d.ts +1 -2
  44. package/dist/media-page/cmp.media-page.svelte +1 -1
  45. package/dist/media-page/index.d.ts +4 -1
  46. package/dist/streams/streams-player/streams-player-view.svelte +4 -4
  47. package/dist/streams/streams-player/types.d.ts +5 -0
  48. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.d.ts +1 -0
  49. package/dist/ui/player/providers/chunks-player-buffer/player-chunks-manager.svelte.js +10 -0
  50. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.d.ts +1 -0
  51. package/dist/ui/player/providers/default-chunks-player-buffer.svelte.js +3 -0
  52. package/dist/ui/player/providers/default-feed-player-buffer.svelte.d.ts +1 -0
  53. package/dist/ui/player/providers/default-feed-player-buffer.svelte.js +8 -0
  54. package/dist/ui/player/providers/types.d.ts +1 -0
  55. package/dist/ui/player/slider/cmp.player-slider.svelte +1 -1
  56. package/package.json +9 -7
  57. package/dist/media-center/media-center/feed/feed-handler.svelte.d.ts +0 -52
  58. package/dist/media-center/media-center/feed/feed-handler.svelte.js +0 -92
  59. package/dist/media-center/media-center/feed/feed-providers-generator.js +0 -83
  60. package/dist/media-center/media-center/feed/index.d.ts +0 -1
  61. package/dist/media-center/media-center/feed/index.js +0 -1
  62. package/dist/media-center/media-center/feed/types.d.ts +0 -12
  63. /package/dist/media-center/media-center/{feed → posts-feed}/types.js +0 -0
  64. /package/dist/media-center/{navigation/media-center-state.js → media-center/streams-feed/types.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  export declare class Utils {
2
+ static areEqual(value: unknown, other: unknown): boolean;
2
3
  static assertUnreachable(_x: never): never;
3
4
  static clone<T>(value: T): T;
4
5
  /**
@@ -1,4 +1,8 @@
1
+ import { dequal as isEqual } from 'dequal/lite';
1
2
  export class Utils {
3
+ static areEqual(value, other) {
4
+ return isEqual(value, other);
5
+ }
2
6
  static assertUnreachable(_x) {
3
7
  throw new Error("Didn't expect to get here");
4
8
  }
@@ -1,3 +1,4 @@
1
+ import type { MediaCenterState } from '../../media-center';
1
2
  import type { IMediaCenterDataProvider } from '../../media-center/config/types';
2
3
  export declare class InternalMediaCenterDataProvider implements IMediaCenterDataProvider {
3
4
  model: IMediaCenterDataProvider['model'];
@@ -11,5 +12,6 @@ export declare class InternalMediaCenterDataProvider implements IMediaCenterData
11
12
  initiator?: string;
12
13
  graphqlOrigin?: string;
13
14
  testingStuff?: boolean;
15
+ onNavigationStateChange?: (state: MediaCenterState) => void;
14
16
  });
15
17
  }
@@ -17,7 +17,7 @@ export class InternalMediaCenterDataProvider {
17
17
  fetchModel;
18
18
  graphql;
19
19
  constructor(input) {
20
- const { mediaPageId, graphqlOrigin, initiator, testingStuff } = input;
20
+ const { mediaPageId, graphqlOrigin, initiator, testingStuff, onNavigationStateChange } = input;
21
21
  this.graphql = createLocalGQLClient(graphqlOrigin, initiator ? { 'x-initiator': initiator } : undefined);
22
22
  this.fetchModel = async () => {
23
23
  const payload = await this.graphql.query(GetMediaPageConfigDocument, { mediaPageId }).toPromise();
@@ -58,7 +58,7 @@ export class InternalMediaCenterDataProvider {
58
58
  types: filter.types,
59
59
  statuses: [Status.Published],
60
60
  categoryId: filter.categoryId,
61
- ids: filter.includeIds,
61
+ ids: filter.ids,
62
62
  excludeIds: filter.excludeIds
63
63
  },
64
64
  continuationToken,
@@ -73,6 +73,7 @@ export class InternalMediaCenterDataProvider {
73
73
  filter: {
74
74
  mediaPageId,
75
75
  categoryId: filter.categoryId,
76
+ ids: filter.ids,
76
77
  excludeIds: filter.excludeIds,
77
78
  statuses: [StreamStatus.Published],
78
79
  showInFeed: true
@@ -95,7 +96,7 @@ export class InternalMediaCenterDataProvider {
95
96
  categoriesFollowingHandler: testingStuff ? new MockCategoryFollowingProvider() : undefined,
96
97
  socialInteractionsHandler: testingStuff ? new MockPostSocialInteractionsHandler() : undefined,
97
98
  membershipHandler: testingStuff ? new MockMembershipHandler() : undefined,
98
- navigationHandler: testingStuff ? new MockNavigationHandler() : undefined
99
+ navigationHandler: testingStuff && onNavigationStateChange ? new MockNavigationHandler(onNavigationStateChange) : undefined
99
100
  };
100
101
  }
101
102
  }
@@ -23,7 +23,7 @@ export interface IMediaCenterDataProvider {
23
23
  filter: {
24
24
  types: PostType[];
25
25
  categoryId?: string;
26
- includeIds?: string[];
26
+ ids?: string[];
27
27
  excludeIds?: string[];
28
28
  };
29
29
  limit: number;
@@ -37,6 +37,7 @@ export interface IMediaCenterDataProvider {
37
37
  getStreamsCursor: (input: {
38
38
  filter: {
39
39
  categoryId?: string;
40
+ ids?: string[];
40
41
  excludeIds?: string[];
41
42
  };
42
43
  limit: number;
@@ -15,19 +15,24 @@ const context = new MediaCenterContext({
15
15
  initialized: (instance) => {
16
16
  switch (modeProps.mode) {
17
17
  case 'posts':
18
- instance.playPostsFeed({
18
+ instance.postsFeedHandler.activateWithExistingProvider({
19
19
  dataProvider: modeProps.props.dataProvider,
20
20
  onPostActivated: modeProps.props.onPostActivated
21
21
  });
22
22
  break;
23
23
  case 'streams':
24
- instance.playStreamsFeed({
24
+ instance.streamsFeedHandler.activateWithExistingProvider({
25
25
  dataProvider: modeProps.props.dataProvider,
26
26
  onStreamActivated: modeProps.props.onStreamActivated
27
27
  });
28
28
  break;
29
29
  case 'default':
30
- instance.activateDiscover({ categoryId: null });
30
+ if (settings.state) {
31
+ instance.restoreState(settings.state);
32
+ }
33
+ else {
34
+ instance.activateDiscover({ categoryId: null });
35
+ }
31
36
  break;
32
37
  default:
33
38
  Utils.assertUnreachable(modeProps);
@@ -110,7 +110,7 @@ const onJoinMembershipClick = () => __awaiter(void 0, void 0, void 0, function*
110
110
  .community-features {
111
111
  display: flex;
112
112
  flex-wrap: nowrap;
113
- margin-top: 0.625rem;
113
+ margin-top: 0.25rem;
114
114
  gap: 8.125rem;
115
115
  align-items: center;
116
116
  /* Set 'container-type: inline-size;' to reference container*/
@@ -135,7 +135,7 @@ const onJoinMembershipClick = () => __awaiter(void 0, void 0, void 0, function*
135
135
  }
136
136
  .members__count {
137
137
  font-size: 0.9375rem;
138
- line-height: 1;
138
+ line-height: 1.75rem;
139
139
  font-weight: 500;
140
140
  /* Set 'container-type: inline-size;' to reference container*/
141
141
  }
@@ -146,7 +146,7 @@ const onJoinMembershipClick = () => __awaiter(void 0, void 0, void 0, function*
146
146
  }
147
147
  .members__label {
148
148
  font-size: 0.75rem;
149
- line-height: 1;
149
+ line-height: 1.75rem;
150
150
  font-weight: 400;
151
151
  color: var(--sc-mc-color--text-secondary);
152
152
  /* Set 'container-type: inline-size;' to reference container*/
@@ -26,7 +26,7 @@ export class DiscoverDataLoader {
26
26
  categoryId: holder.categoryId,
27
27
  types: [PostType.ShortVideo]
28
28
  },
29
- limit: 6,
29
+ limit: 5,
30
30
  continuationToken: holder.continuationToken
31
31
  });
32
32
  holder.shortVideos = [...holder.shortVideos, ...shortVideosResponse.items];
@@ -1,8 +1,7 @@
1
1
  import type { IMediaCenterDataProvider } from '../../config/types';
2
+ import type { MediaCenterState } from '../../navigation';
2
3
  import { ShortVideosInCategory, StreamsInCategory } from './types.svelte';
3
4
  export declare class DiscoverViewHandler {
4
- private readonly dataProvider;
5
- private _activated;
6
5
  private _state;
7
6
  private _streamsInCategoryCache;
8
7
  private _shortVideosInCategoryCache;
@@ -10,7 +9,11 @@ export declare class DiscoverViewHandler {
10
9
  private _shortVideosInCategory;
11
10
  private _dataLoader;
12
11
  private _shortVideosLoadingDeferred;
13
- constructor(dataProvider: IMediaCenterDataProvider);
12
+ private _callbacks;
13
+ constructor(data: {
14
+ dataProvider: IMediaCenterDataProvider;
15
+ on: Callbacks;
16
+ });
14
17
  get activated(): boolean;
15
18
  get active(): boolean;
16
19
  get loading(): boolean;
@@ -26,3 +29,7 @@ export declare class DiscoverViewHandler {
26
29
  }) => Promise<void>;
27
30
  deactivate: () => void;
28
31
  }
32
+ type Callbacks = {
33
+ navigationStateChanged: (state: MediaCenterState) => void;
34
+ };
35
+ export {};
@@ -2,27 +2,27 @@ import { Deferred } from '../../../core/deferred';
2
2
  import { DiscoverDataLoader } from './data-loading';
3
3
  import { ShortVideosInCategory, StreamsInCategory } from './types.svelte';
4
4
  export class DiscoverViewHandler {
5
- dataProvider;
6
- _activated = $state(false);
7
- _state = $state('loading');
5
+ _state = $state('inactive');
8
6
  _streamsInCategoryCache = $state.raw([]);
9
7
  _shortVideosInCategoryCache = $state.raw([]);
10
8
  _streamsInCategory = $state.raw(null);
11
9
  _shortVideosInCategory = $state.raw([]);
12
10
  _dataLoader;
13
11
  _shortVideosLoadingDeferred = null;
14
- constructor(dataProvider) {
15
- this.dataProvider = dataProvider;
16
- this._dataLoader = new DiscoverDataLoader(this.dataProvider);
12
+ _callbacks;
13
+ constructor(data) {
14
+ const { dataProvider, on } = data;
15
+ this._callbacks = on;
16
+ this._dataLoader = new DiscoverDataLoader(dataProvider);
17
17
  }
18
18
  get activated() {
19
- return this._activated;
19
+ return this._state !== 'inactive';
20
20
  }
21
21
  get active() {
22
- return this._activated && this._state === 'ready';
22
+ return this._state === 'ready';
23
23
  }
24
24
  get loading() {
25
- return this._activated && this._state === 'loading';
25
+ return this._state === 'loading';
26
26
  }
27
27
  get streamsHolder() {
28
28
  return this._streamsInCategory;
@@ -59,7 +59,6 @@ export class DiscoverViewHandler {
59
59
  };
60
60
  activate = async (data) => {
61
61
  const { activeCategoryId, childCategories } = data;
62
- this._activated = true;
63
62
  this._state = 'loading';
64
63
  try {
65
64
  const promises = [];
@@ -92,10 +91,11 @@ export class DiscoverViewHandler {
92
91
  }
93
92
  finally {
94
93
  this._state = 'ready';
94
+ this._callbacks.navigationStateChanged({ mode: 'discover', categoryId: activeCategoryId });
95
95
  }
96
96
  };
97
97
  deactivate = () => {
98
- this._activated = false;
98
+ this._state = 'inactive';
99
99
  this._shortVideosLoadingDeferred = null;
100
100
  };
101
101
  }
@@ -9,22 +9,22 @@ const handler = $derived(context.discoverHandler);
9
9
  const localization = $derived(new DiscoverViewLocalization(context.locale));
10
10
  </script>
11
11
 
12
- {#if !handler.loading}
13
- <div class="media-center-discover">
14
- <div class="media-center-discover__content">
15
- <Header context={context} />
16
- {#if handler.streamsHolder?.streams.length}
17
- <div class="media-center-discover__section">
18
- <div class="media-center-discover__section-header">
19
- {localization.latestStreamsSectionTitle}
20
- </div>
21
- <div class="media-center-discover__section-content media-center-discover__section-content--5">
22
- {#each handler.streamsHolder.streams as item (item.id)}
23
- <StreamCard stream={item} on={{ click: () => on.streamSelected(item) }}></StreamCard>
24
- {/each}
25
- </div>
12
+ <div class="media-center-discover">
13
+ <div class="media-center-discover__content">
14
+ <Header context={context} />
15
+ {#if handler.streamsHolder?.streams.length}
16
+ <div class="media-center-discover__section">
17
+ <div class="media-center-discover__section-header">
18
+ {localization.latestStreamsSectionTitle}
26
19
  </div>
27
- {/if}
20
+ <div class="media-center-discover__section-content media-center-discover__section-content--5">
21
+ {#each handler.streamsHolder.streams as item (item.id)}
22
+ <StreamCard stream={item} on={{ click: () => on.streamSelected(item) }}></StreamCard>
23
+ {/each}
24
+ </div>
25
+ </div>
26
+ {/if}
27
+ {#if !handler.loading}
28
28
  {#each handler.shortVideosHolders as holder, index (holder)}
29
29
  <InfiniteScrolling loadMore={handler.loadMoreShortVideos}>
30
30
  {#if holder.shortVideos.length}
@@ -54,9 +54,9 @@ const localization = $derived(new DiscoverViewLocalization(context.locale));
54
54
  {/if}
55
55
  </InfiniteScrolling>
56
56
  {/each}
57
- </div>
57
+ {/if}
58
58
  </div>
59
- {/if}
59
+ </div>
60
60
 
61
61
  <style>@keyframes fadeIn {
62
62
  0% {
@@ -11,7 +11,7 @@ let { context } = $props();
11
11
  <button
12
12
  type="button"
13
13
  class="media-center-footer__button"
14
- class:media-center-footer__button--active={context.feedHandler.active}
14
+ class:media-center-footer__button--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}
15
15
  onclick={() => context.playRootFeed()}>
16
16
  <Icon src={IconPhone} />
17
17
  </button>
@@ -142,8 +142,12 @@ const styles = $derived.by(() => {
142
142
  </button>
143
143
  <div class="media-center-header__scroll-area" use:onScrollMounted use:horizontalWheelScroll onscroll={handleScrollingAreaScroll}>
144
144
  <div class="media-center-header__scroll-area-block">
145
- <button type="button" class="control-button" class:control-button--active={context.feedHandler.active} onclick={() => context.playRootFeed()}>
146
- <span class="control-button__icon" class:control-button__icon--active={context.feedHandler.active}>
145
+ <button
146
+ type="button"
147
+ class="control-button"
148
+ class:control-button--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}
149
+ onclick={() => context.playRootFeed()}>
150
+ <span class="control-button__icon" class:control-button__icon--active={context.postsFeedHandler.activated || context.streamsFeedHandler.activated}>
147
151
  <Icon src={IconPhone} />
148
152
  </span>
149
153
  <span class="control-button__value">
@@ -170,16 +174,18 @@ const styles = $derived.by(() => {
170
174
  {localization.buttons.cart}
171
175
  </span>
172
176
  </button>
173
- <button
174
- type="button"
175
- class="control-button"
176
- class:control-button--active={context.momentsFeedHandler.active}
177
- class:control-button--indicator={context.momentsFeedHandler.hasUnwatchedMoments}
178
- onclick={() => context.playMoments()}>
179
- <span class="control-button__value">
180
- {localization.buttons.moments}
181
- </span>
182
- </button>
177
+ {#if context.momentsFeedHandler.hasMoments}
178
+ <button
179
+ type="button"
180
+ class="control-button"
181
+ class:control-button--active={context.momentsFeedHandler.active}
182
+ class:control-button--indicator={context.momentsFeedHandler.hasUnwatchedMoments}
183
+ onclick={() => context.playMoments()}>
184
+ <span class="control-button__value">
185
+ {localization.buttons.moments}
186
+ </span>
187
+ </button>
188
+ {/if}
183
189
  <button type="button" class="control-button" class:control-button--active={false} onclick={() => ({})}>
184
190
  <span class="control-button__value">
185
191
  {localization.buttons.webpage}
@@ -1,20 +1,23 @@
1
1
  import type { IMediaCenterDataProvider } from '../config/types';
2
+ import type { MediaCenterState } from '../navigation';
2
3
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
3
4
  import { DiscoverViewHandler } from './discover';
4
- import { FeedHandler } from './feed';
5
5
  import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
6
6
  import type { MediaCenterSettings } from './media-center-settings.svelte';
7
7
  import { PopularStreamsPanelHandler } from './menu';
8
8
  import { MomentsFeedHandler } from './moments';
9
+ import { PostsFeedHandler } from './posts-feed';
10
+ import { StreamsFeedHandler } from './streams-feed';
9
11
  import { StreamsInCategoryPanelHandler } from './streams-in-category';
10
12
  import type { MediaCenterMode } from './types';
11
13
  export declare class MediaCenterContext {
12
14
  initializing: boolean;
13
15
  initialized: boolean;
14
- readonly mediaCenterMode: MediaCenterMode;
16
+ readonly mediaCenterMode: MediaCenterMode | null;
15
17
  menuActive: boolean;
16
18
  categoriesHandler: CategoriesHandler;
17
- feedHandler: FeedHandler;
19
+ postsFeedHandler: PostsFeedHandler;
20
+ streamsFeedHandler: StreamsFeedHandler;
18
21
  momentsFeedHandler: MomentsFeedHandler;
19
22
  discoverHandler: DiscoverViewHandler;
20
23
  popularStreamsHandler: PopularStreamsPanelHandler;
@@ -22,6 +25,7 @@ export declare class MediaCenterContext {
22
25
  settingsHandler: MediaCenterSettingsHandler;
23
26
  closeOrchestrator: ICloseOrchestrator;
24
27
  private _dataProvider;
28
+ private _currentState;
25
29
  constructor(data: {
26
30
  dataProvider: IMediaCenterDataProvider;
27
31
  closeOrchestrator: ICloseOrchestrator;
@@ -37,10 +41,7 @@ export declare class MediaCenterContext {
37
41
  backgroundImageUrl: string | null;
38
42
  backgroundColor?: string | null;
39
43
  };
40
- get feedPlayerProps(): import("./types").PlayerProps | null;
41
- get momentsPlayerProps(): import("../../posts/posts-player/types").PostsPlayerProps | null;
42
44
  get membershipHandler(): import("..").IMediaCenterMembershipHandler | null;
43
- get navigationHandler(): import("..").IMediaCenterNavigationHandler | null;
44
45
  get categoriesFollowingHandler(): import("..").IContentCategoryFollowingHandler | null;
45
46
  get locale(): import("../../core/locale").Locale;
46
47
  toggleMenu: () => void;
@@ -49,12 +50,15 @@ export declare class MediaCenterContext {
49
50
  activateDiscover: (options: {
50
51
  categoryId: string | null;
51
52
  }) => Promise<void>;
52
- playPostsFeed: (options: Parameters<FeedHandler["activatePostsFeed"]>[0]) => Promise<void>;
53
- playStreamsFeed: (options: Parameters<FeedHandler["activateStreamsFeed"]>[0]) => Promise<void>;
54
- playMoments: () => Promise<void>;
53
+ backToDiscover: () => Promise<void>;
54
+ playPostsFeed: (options: Parameters<PostsFeedHandler["activate"]>[0]) => Promise<void>;
55
+ playStreamsFeed: (options: Parameters<StreamsFeedHandler["activate"]>[0]) => Promise<void>;
56
+ playMoments: (options?: Parameters<MomentsFeedHandler["activate"]>[0]) => Promise<void>;
55
57
  playRootFeed: () => Promise<void>;
56
58
  tryActivateStreamsInCategory: (categoryId: string) => Promise<void>;
57
- private deactivateOtherThanFeed;
59
+ restoreState: (state: MediaCenterState) => Promise<void>;
60
+ handleNavigationStateChanged: (state: MediaCenterState) => void;
61
+ private deactivateAllBut;
58
62
  private init;
59
63
  }
60
64
  type MediaCenterContextInitializationCallbacks = {
@@ -1,9 +1,12 @@
1
+ import { Utils } from '../../core/utils';
1
2
  import { DiscoverViewHandler } from './discover';
2
- import { FeedHandler } from './feed';
3
3
  import { CategoriesHandler, MediaCenterSettingsHandler } from './handlers';
4
4
  import { PopularStreamsPanelHandler } from './menu';
5
5
  import { MomentsFeedHandler } from './moments';
6
+ import { PostsFeedHandler } from './posts-feed';
7
+ import { StreamsFeedHandler } from './streams-feed';
6
8
  import { StreamsInCategoryPanelHandler } from './streams-in-category';
9
+ import { untrack } from 'svelte';
7
10
  export class MediaCenterContext {
8
11
  initializing = $state(true);
9
12
  initialized = $state(false);
@@ -14,11 +17,18 @@ export class MediaCenterContext {
14
17
  if (this.momentsFeedHandler.active) {
15
18
  return 'moments';
16
19
  }
17
- return 'feed';
20
+ if (this.postsFeedHandler.activated) {
21
+ return 'posts-feed';
22
+ }
23
+ if (this.streamsFeedHandler.activated) {
24
+ return 'streams-feed';
25
+ }
26
+ return null;
18
27
  });
19
28
  menuActive = $state(false);
20
29
  categoriesHandler;
21
- feedHandler;
30
+ postsFeedHandler;
31
+ streamsFeedHandler;
22
32
  momentsFeedHandler;
23
33
  discoverHandler;
24
34
  popularStreamsHandler;
@@ -26,27 +36,45 @@ export class MediaCenterContext {
26
36
  settingsHandler;
27
37
  closeOrchestrator;
28
38
  _dataProvider;
39
+ _currentState = null;
29
40
  constructor(data) {
30
41
  const { dataProvider, closeOrchestrator, settings, on } = data;
31
42
  this._dataProvider = dataProvider;
32
43
  this.closeOrchestrator = closeOrchestrator;
33
44
  this.closeOrchestrator.setCloseTriggerAttached(true);
34
45
  this.settingsHandler = new MediaCenterSettingsHandler({ settings, dataProvider });
35
- this.feedHandler = new FeedHandler({
46
+ this.postsFeedHandler = new PostsFeedHandler({
36
47
  dataProvider,
37
48
  mediaCenterSettingsHandler: this.settingsHandler,
38
49
  closeOrchestrator,
39
- onPlayerReachedEnd: () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId })
50
+ on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
51
+ });
52
+ this.streamsFeedHandler = new StreamsFeedHandler({
53
+ dataProvider,
54
+ mediaCenterSettingsHandler: this.settingsHandler,
55
+ closeOrchestrator,
56
+ on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
40
57
  });
41
58
  this.categoriesHandler = new CategoriesHandler(dataProvider);
42
- this.discoverHandler = new DiscoverViewHandler(dataProvider);
59
+ this.discoverHandler = new DiscoverViewHandler({ dataProvider, on: { navigationStateChanged: this.handleNavigationStateChanged } });
43
60
  this.popularStreamsHandler = new PopularStreamsPanelHandler(dataProvider);
44
61
  this.streamsInCategoryHandler = new StreamsInCategoryPanelHandler(dataProvider);
45
62
  this.momentsFeedHandler = new MomentsFeedHandler({
46
63
  dataProvider,
47
64
  mediaCenterSettingsHandler: this.settingsHandler,
48
65
  closeOrchestrator,
49
- onPlayerReachedEnd: () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId })
66
+ on: { playerReachedEnd: this.backToDiscover, navigationStateChanged: this.handleNavigationStateChanged }
67
+ });
68
+ $effect(() => {
69
+ if (this.initialized) {
70
+ void settings.state;
71
+ untrack(() => {
72
+ if (!settings.state) {
73
+ return;
74
+ }
75
+ this.restoreState(settings.state);
76
+ });
77
+ }
50
78
  });
51
79
  this.init(dataProvider, on);
52
80
  }
@@ -57,7 +85,7 @@ export class MediaCenterContext {
57
85
  return this.settingsHandler.actualMediaCenterColors;
58
86
  }
59
87
  get loading() {
60
- return this.discoverHandler.loading || this.streamsInCategoryHandler.loading;
88
+ return this.discoverHandler.loading || this.postsFeedHandler.loading || this.streamsFeedHandler.loading || this.streamsInCategoryHandler.loading;
61
89
  }
62
90
  get overlayIsActive() {
63
91
  return this.streamsInCategoryHandler.activated;
@@ -65,18 +93,9 @@ export class MediaCenterContext {
65
93
  get backgroundWrapperProps() {
66
94
  return this.settingsHandler.backgroundWrapperProps;
67
95
  }
68
- get feedPlayerProps() {
69
- return this.feedHandler.feedPlayerProps;
70
- }
71
- get momentsPlayerProps() {
72
- return this.momentsFeedHandler.momentsPlayerProps;
73
- }
74
96
  get membershipHandler() {
75
97
  return this._dataProvider.handlers?.membershipHandler || null;
76
98
  }
77
- get navigationHandler() {
78
- return this._dataProvider.handlers?.navigationHandler || null;
79
- }
80
99
  get categoriesFollowingHandler() {
81
100
  return this._dataProvider.handlers?.categoriesFollowingHandler || null;
82
101
  }
@@ -100,10 +119,7 @@ export class MediaCenterContext {
100
119
  };
101
120
  activateDiscover = async (options) => {
102
121
  this.settingsHandler.updateBackgroundImageUrl('not-applicable');
103
- this.hideMenu();
104
- this.feedHandler.deactivate();
105
- this.momentsFeedHandler.deactivate();
106
- this.streamsInCategoryHandler.deactivate();
122
+ this.deactivateAllBut('discover');
107
123
  this.categoriesHandler.selectedCategoryId = options.categoryId;
108
124
  const childCategories = this.categoriesHandler.allCategories.filter((c) => c.parentId === this.categoriesHandler.selectedCategoryId);
109
125
  await this.discoverHandler.activate({
@@ -111,50 +127,92 @@ export class MediaCenterContext {
111
127
  childCategories: childCategories.map((c) => ({ id: c.id, name: c.name }))
112
128
  });
113
129
  };
130
+ backToDiscover = () => this.activateDiscover({ categoryId: this.categoriesHandler.selectedCategoryId });
114
131
  playPostsFeed = async (options) => {
115
- this.deactivateOtherThanFeed();
132
+ this.deactivateAllBut('posts-feed');
116
133
  this.categoriesHandler.selectedCategoryId = options.filter?.categoryId ?? null;
117
- this.feedHandler.activatePostsFeed(options);
134
+ this.postsFeedHandler.activate(options);
118
135
  };
119
136
  playStreamsFeed = async (options) => {
120
- this.deactivateOtherThanFeed();
137
+ this.deactivateAllBut('streams-feed');
121
138
  this.categoriesHandler.selectedCategoryId = options.filter?.categoryId ?? null;
122
- this.feedHandler.activateStreamsFeed(options);
139
+ this.streamsFeedHandler.activate(options);
123
140
  };
124
- playMoments = async () => {
141
+ playMoments = async (options) => {
125
142
  if (!this.momentsFeedHandler.hasMoments) {
126
143
  return;
127
144
  }
128
- this.hideMenu();
129
- this.feedHandler.deactivate();
130
- this.discoverHandler.deactivate();
131
- this.streamsInCategoryHandler.deactivate();
132
- this.momentsFeedHandler.activateMoments();
145
+ this.deactivateAllBut('moments');
146
+ this.momentsFeedHandler.activate(options);
133
147
  };
134
148
  playRootFeed = async () => {
135
- this.deactivateOtherThanFeed();
136
149
  this.categoriesHandler.selectedCategoryId = null;
137
- if (this.feedPlayerProps?.type === 'streams') {
138
- this.feedHandler.activateStreamsFeed({});
150
+ if (this.streamsFeedHandler.active) {
151
+ this.streamsFeedHandler.activate({});
139
152
  }
140
153
  else {
141
- this.feedHandler.activatePostsFeed({});
154
+ this.deactivateAllBut('posts-feed');
155
+ this.postsFeedHandler.activate({});
142
156
  }
143
157
  };
144
158
  tryActivateStreamsInCategory = async (categoryId) => {
145
159
  const selectedCategoryData = this.categoriesHandler.getCategoryData(categoryId);
146
160
  await this.streamsInCategoryHandler.activate(selectedCategoryData);
147
- this.hideMenu();
148
- this.feedHandler.deactivate();
149
- this.momentsFeedHandler.deactivate();
150
- this.discoverHandler.deactivate();
161
+ this.deactivateAllBut('streams-in-category');
151
162
  this.categoriesHandler.selectedCategoryId = categoryId;
152
163
  };
153
- deactivateOtherThanFeed = () => {
164
+ restoreState = async (state) => {
165
+ if (Utils.areEqual(this._currentState, state)) {
166
+ return;
167
+ }
168
+ this._currentState = state;
169
+ switch (state.mode) {
170
+ case 'posts-feed':
171
+ await this.playPostsFeed({ filter: { categoryId: state.categoryId }, init: { initialPostId: state.postId } });
172
+ break;
173
+ case 'streams-feed':
174
+ await this.playStreamsFeed({
175
+ filter: { categoryId: state.categoryId },
176
+ init: { initialStreamId: state.streamId, initialStreamPageId: state.streamPageId }
177
+ });
178
+ break;
179
+ case 'discover':
180
+ await this.activateDiscover({ categoryId: state.categoryId });
181
+ break;
182
+ case 'moments':
183
+ await this.playMoments({ initialMomentId: state.momentId });
184
+ break;
185
+ }
186
+ };
187
+ handleNavigationStateChanged = (state) => {
188
+ if (Utils.areEqual(this._currentState, state)) {
189
+ return;
190
+ }
191
+ const navigationHandler = this._dataProvider.handlers?.navigationHandler;
192
+ if (!navigationHandler) {
193
+ return;
194
+ }
195
+ this._currentState = state;
196
+ navigationHandler.onChange(state);
197
+ };
198
+ deactivateAllBut = (...params) => {
154
199
  this.hideMenu();
155
- this.momentsFeedHandler.deactivate();
156
- this.discoverHandler.deactivate();
157
- this.streamsInCategoryHandler.deactivate();
200
+ const keep = new Set(params);
201
+ if (!keep.has('moments')) {
202
+ this.momentsFeedHandler.deactivate();
203
+ }
204
+ if (!keep.has('discover')) {
205
+ this.discoverHandler.deactivate();
206
+ }
207
+ if (!keep.has('posts-feed')) {
208
+ this.postsFeedHandler.deactivate();
209
+ }
210
+ if (!keep.has('streams-feed')) {
211
+ this.streamsFeedHandler.deactivate();
212
+ }
213
+ if (!keep.has('streams-in-category')) {
214
+ this.streamsInCategoryHandler.deactivate();
215
+ }
158
216
  };
159
217
  init = async (config, on) => {
160
218
  try {