@rixl/media-core 1.0.2 → 1.1.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.
Files changed (172) hide show
  1. package/README.md +74 -84
  2. package/dist/chunks/B-QvSqjj.js +1 -0
  3. package/dist/chunks/B2DDE32u.js +1 -0
  4. package/dist/chunks/DMkwQjgA.js +1 -0
  5. package/dist/index.d.ts +1906 -82
  6. package/dist/index.js +6 -73
  7. package/package.json +13 -6
  8. package/dist/api/analytics.d.ts +0 -16
  9. package/dist/api/analytics.js +0 -227
  10. package/dist/api/feed.js +0 -52
  11. package/dist/api/heatmap.d.ts +0 -6
  12. package/dist/api/heatmap.js +0 -28
  13. package/dist/api/hot-segments.d.ts +0 -7
  14. package/dist/api/hot-segments.js +0 -20
  15. package/dist/api/image.js +0 -11
  16. package/dist/api/rixl-client.d.ts +0 -3
  17. package/dist/api/rixl-client.js +0 -14
  18. package/dist/api/upload.d.ts +0 -76
  19. package/dist/api/upload.js +0 -150
  20. package/dist/api/video.js +0 -11
  21. package/dist/lib/analytics-builders.d.ts +0 -59
  22. package/dist/lib/analytics-builders.js +0 -88
  23. package/dist/lib/analytics-initialize.d.ts +0 -1
  24. package/dist/lib/analytics-initialize.js +0 -59
  25. package/dist/lib/analytics-utils.d.ts +0 -43
  26. package/dist/lib/analytics-utils.js +0 -85
  27. package/dist/lib/analytics-wire.js +0 -153
  28. package/dist/lib/buffer-progress.d.ts +0 -20
  29. package/dist/lib/buffer-progress.js +0 -37
  30. package/dist/lib/caption-styles.d.ts +0 -20
  31. package/dist/lib/caption-styles.js +0 -56
  32. package/dist/lib/caption-utils.d.ts +0 -80
  33. package/dist/lib/caption-utils.js +0 -111
  34. package/dist/lib/chapter-utils.d.ts +0 -102
  35. package/dist/lib/chapter-utils.js +0 -147
  36. package/dist/lib/click-disambiguation.d.ts +0 -44
  37. package/dist/lib/click-disambiguation.js +0 -80
  38. package/dist/lib/click-outside.d.ts +0 -68
  39. package/dist/lib/click-outside.js +0 -64
  40. package/dist/lib/colors.d.ts +0 -6
  41. package/dist/lib/colors.js +0 -16
  42. package/dist/lib/content-analytics.d.ts +0 -27
  43. package/dist/lib/content-analytics.js +0 -38
  44. package/dist/lib/environment-effects.d.ts +0 -89
  45. package/dist/lib/environment-effects.js +0 -139
  46. package/dist/lib/feed-autoscroll.d.ts +0 -10
  47. package/dist/lib/feed-autoscroll.js +0 -13
  48. package/dist/lib/feed-container-height.d.ts +0 -7
  49. package/dist/lib/feed-container-height.js +0 -11
  50. package/dist/lib/feed-description-overflow.d.ts +0 -1
  51. package/dist/lib/feed-description-overflow.js +0 -9
  52. package/dist/lib/feed-dwell.d.ts +0 -2
  53. package/dist/lib/feed-dwell.js +0 -8
  54. package/dist/lib/feed-loop.d.ts +0 -10
  55. package/dist/lib/feed-loop.js +0 -21
  56. package/dist/lib/feed-scroll.d.ts +0 -11
  57. package/dist/lib/feed-scroll.js +0 -19
  58. package/dist/lib/feed-transforms.d.ts +0 -5
  59. package/dist/lib/feed-transforms.js +0 -30
  60. package/dist/lib/filter-undefined.js +0 -11
  61. package/dist/lib/fullscreen-utils.d.ts +0 -1
  62. package/dist/lib/fullscreen-utils.js +0 -7
  63. package/dist/lib/hls-buffer-flush.js +0 -46
  64. package/dist/lib/hls-error-recovery.d.ts +0 -35
  65. package/dist/lib/hls-error-recovery.js +0 -75
  66. package/dist/lib/hls-event-handlers.js +0 -61
  67. package/dist/lib/hls-loader.js +0 -23
  68. package/dist/lib/hls-setup.d.ts +0 -72
  69. package/dist/lib/hls-setup.js +0 -144
  70. package/dist/lib/hls-utils.d.ts +0 -31
  71. package/dist/lib/hls-utils.js +0 -34
  72. package/dist/lib/image-render.d.ts +0 -29
  73. package/dist/lib/image-render.js +0 -63
  74. package/dist/lib/keyboard-config.d.ts +0 -66
  75. package/dist/lib/keyboard-config.js +0 -127
  76. package/dist/lib/keyboard-utils.d.ts +0 -4
  77. package/dist/lib/keyboard-utils.js +0 -11
  78. package/dist/lib/lifecycle-effects.d.ts +0 -67
  79. package/dist/lib/lifecycle-effects.js +0 -78
  80. package/dist/lib/loading-debounce.d.ts +0 -26
  81. package/dist/lib/loading-debounce.js +0 -38
  82. package/dist/lib/numbers.d.ts +0 -6
  83. package/dist/lib/numbers.js +0 -36
  84. package/dist/lib/pip-utils.d.ts +0 -16
  85. package/dist/lib/pip-utils.js +0 -32
  86. package/dist/lib/playback-handlers.d.ts +0 -33
  87. package/dist/lib/playback-handlers.js +0 -51
  88. package/dist/lib/playback-slider.d.ts +0 -23
  89. package/dist/lib/playback-slider.js +0 -24
  90. package/dist/lib/player-labels.d.ts +0 -23
  91. package/dist/lib/player-labels.js +0 -132
  92. package/dist/lib/player-menu-labels.d.ts +0 -80
  93. package/dist/lib/player-menu-labels.js +0 -829
  94. package/dist/lib/player-ui-actions.d.ts +0 -10
  95. package/dist/lib/player-ui-actions.js +0 -58
  96. package/dist/lib/progress-fraction.d.ts +0 -11
  97. package/dist/lib/progress-fraction.js +0 -20
  98. package/dist/lib/progress-persist.d.ts +0 -28
  99. package/dist/lib/progress-persist.js +0 -54
  100. package/dist/lib/segment-analytics.d.ts +0 -20
  101. package/dist/lib/segment-analytics.js +0 -29
  102. package/dist/lib/subtitle-logic.d.ts +0 -31
  103. package/dist/lib/subtitle-logic.js +0 -75
  104. package/dist/lib/subtitle-utils.d.ts +0 -16
  105. package/dist/lib/subtitle-utils.js +0 -37
  106. package/dist/lib/time.d.ts +0 -1
  107. package/dist/lib/time.js +0 -17
  108. package/dist/lib/track-persistence.d.ts +0 -4
  109. package/dist/lib/track-persistence.js +0 -35
  110. package/dist/lib/video-preload-config.d.ts +0 -34
  111. package/dist/lib/video-preload-config.js +0 -41
  112. package/dist/lib/video-spinner.d.ts +0 -25
  113. package/dist/lib/video-spinner.js +0 -35
  114. package/dist/lib/video-stats.d.ts +0 -28
  115. package/dist/lib/video-stats.js +0 -44
  116. package/dist/lib/volume-utils.d.ts +0 -59
  117. package/dist/lib/volume-utils.js +0 -55
  118. package/dist/progressbar.d.ts +0 -10
  119. package/dist/progressbar.js +0 -125
  120. package/dist/store/analytics-context-store.d.ts +0 -4
  121. package/dist/store/analytics-context-store.js +0 -13
  122. package/dist/store/analytics-device-store.d.ts +0 -8
  123. package/dist/store/analytics-device-store.js +0 -44
  124. package/dist/store/analytics-session-store.d.ts +0 -8
  125. package/dist/store/analytics-session-store.js +0 -40
  126. package/dist/store/analytics-store.d.ts +0 -30
  127. package/dist/store/analytics-store.js +0 -88
  128. package/dist/store/controls-store.d.ts +0 -16
  129. package/dist/store/controls-store.js +0 -53
  130. package/dist/store/feed-cache-store.d.ts +0 -24
  131. package/dist/store/feed-cache-store.js +0 -165
  132. package/dist/store/feed-interaction-store.d.ts +0 -17
  133. package/dist/store/feed-interaction-store.js +0 -32
  134. package/dist/store/feed-store.d.ts +0 -16
  135. package/dist/store/feed-store.js +0 -38
  136. package/dist/store/generic-store.js +0 -24
  137. package/dist/store/image-store.d.ts +0 -2
  138. package/dist/store/image-store.js +0 -8
  139. package/dist/store/player-container-element-store.d.ts +0 -10
  140. package/dist/store/player-container-element-store.js +0 -38
  141. package/dist/store/player-global-actions.js +0 -53
  142. package/dist/store/player-media-element-store.d.ts +0 -10
  143. package/dist/store/player-media-element-store.js +0 -38
  144. package/dist/store/player-store-actions.js +0 -197
  145. package/dist/store/player-store.d.ts +0 -94
  146. package/dist/store/player-store.js +0 -127
  147. package/dist/store/player-track-actions.js +0 -44
  148. package/dist/store/postStore.d.ts +0 -20
  149. package/dist/store/postStore.js +0 -112
  150. package/dist/store/settings/constants.d.ts +0 -15
  151. package/dist/store/settings/constants.js +0 -47
  152. package/dist/store/settings/defaults.d.ts +0 -2
  153. package/dist/store/settings/defaults.js +0 -24
  154. package/dist/store/settings/storage.d.ts +0 -3
  155. package/dist/store/settings/storage.js +0 -28
  156. package/dist/store/settings/store.d.ts +0 -32
  157. package/dist/store/settings/store.js +0 -59
  158. package/dist/store/settings/types.d.ts +0 -27
  159. package/dist/store/settings/validation.d.ts +0 -7
  160. package/dist/store/settings/validation.js +0 -55
  161. package/dist/store/settings-menu-store.d.ts +0 -19
  162. package/dist/store/settings-menu-store.js +0 -30
  163. package/dist/store/video-store.d.ts +0 -2
  164. package/dist/store/video-store.js +0 -8
  165. package/dist/types/analytics.d.ts +0 -113
  166. package/dist/types/feed.d.ts +0 -21
  167. package/dist/types/file.d.ts +0 -12
  168. package/dist/types/heatmap.d.ts +0 -5
  169. package/dist/types/hot-segments.d.ts +0 -9
  170. package/dist/types/image.d.ts +0 -9
  171. package/dist/types/uuid.d.ts +0 -1
  172. package/dist/types/video.d.ts +0 -22
@@ -1,94 +0,0 @@
1
- import { SubtitleTrack } from "../lib/subtitle-logic.js";
2
- import { AudioTrack } from "../lib/hls-utils.js";
3
- import { UUID } from "../types/uuid.js";
4
- import { MapStore } from "nanostores";
5
- import Hls from "hls.js";
6
- export interface PlayerState {
7
- paused: boolean;
8
- loading: boolean;
9
- ended: boolean;
10
- mounted: boolean;
11
- hasInteracted: boolean;
12
- whenInteracted: Date;
13
- isFullscreen: boolean;
14
- isPictureInPicture: boolean;
15
- muted: boolean;
16
- playbackRate: number;
17
- volume: number;
18
- previousVolume: number;
19
- viewport: {
20
- width: number;
21
- height: number;
22
- };
23
- resolution: number;
24
- subtitleTrack: number;
25
- availableSubtitleTracks: SubtitleTrack[];
26
- currentSubtitleText: string;
27
- audioTrack: number;
28
- availableAudioTracks: AudioTrack[];
29
- hlsInstance: Hls | null;
30
- }
31
- export interface PlayerProgressSnapshot {
32
- currentTime: number;
33
- duration: number;
34
- progress: number;
35
- buffered: number;
36
- }
37
- export interface PlayerStateStore {
38
- state: Map<UUID, MapStore<PlayerState>>;
39
- get: (id: UUID) => MapStore<PlayerState>;
40
- deletePlayer: (id: UUID) => void;
41
- getEffectiveMediaMuted: (player: Pick<PlayerState, "muted" | "volume" | "hasInteracted">) => boolean;
42
- muteMedia: (id: UUID) => void;
43
- unmuteMedia: (id: UUID) => void;
44
- toggleMediaMute: (id: UUID) => void;
45
- setMediaVolume: (id: UUID, volume: number) => void;
46
- playMedia: (id: UUID) => Promise<void>;
47
- pauseMedia: (id: UUID) => void;
48
- toggleMediaPlayback: (id: UUID) => Promise<void>;
49
- pauseOtherMedia: (except: UUID) => void;
50
- setMediaPlaybackRate: (id: UUID, playbackRate: number) => void;
51
- readProgressSnapshot: (id: UUID) => PlayerProgressSnapshot;
52
- subscribeToProgress: (id: UUID, onStoreChange: () => void) => () => void;
53
- seekProgressTo: (id: UUID, seconds: number) => void;
54
- seekProgressBy: (id: UUID, deltaSeconds: number) => void;
55
- getTrackOptions: (tracks: {
56
- label: string;
57
- language: string;
58
- kind: string;
59
- }[]) => {
60
- index: number;
61
- label: string;
62
- language: string;
63
- kind: string;
64
- }[];
65
- selectAudioTrack: (id: UUID, trackIndex: number) => void;
66
- selectSubtitleTrack: (id: UUID, trackIndex: number) => void;
67
- setAudioTrack: (id: UUID, audioTrack: number) => void;
68
- setAvailableAudioTracks: (id: UUID, tracks: AudioTrack[]) => void;
69
- setGlobalMuted: (muted: boolean) => void;
70
- setGlobalVolume: (volume: number) => void;
71
- setGlobalPlaybackRate: (rate: number) => void;
72
- setGlobalPreferredQuality: (quality: number | undefined) => void;
73
- setGlobalPreferredAudioLanguage: (language: string | undefined) => void;
74
- setGlobalPreferredSubtitleLanguage: (language: string | undefined) => void;
75
- pauseAllPlayers: () => void;
76
- setMounted: (id: UUID) => void;
77
- setHasInteracted: (id: UUID) => void;
78
- setPaused: (id: UUID, paused: boolean) => void;
79
- setLoading: (id: UUID, loading: boolean) => void;
80
- setEnded: (id: UUID, ended: boolean) => void;
81
- setFullscreen: (id: UUID, isFullscreen: boolean) => void;
82
- setPictureInPicture: (id: UUID, isPictureInPicture: boolean) => void;
83
- setMuted: (id: UUID, muted: boolean) => void;
84
- setPlaybackRate: (id: UUID, playbackRate: number) => void;
85
- setPreviousVolume: (id: UUID, previousVolume: number) => void;
86
- setVolume: (id: UUID, volume: number) => void;
87
- setViewport: (id: UUID, width: number, height: number) => void;
88
- setResolution: (id: UUID, resolution: number) => void;
89
- setSubtitleTrack: (id: UUID, subtitleTrack: number) => void;
90
- setAvailableSubtitleTracks: (id: UUID, tracks: SubtitleTrack[]) => void;
91
- setCurrentSubtitleText: (id: UUID, text: string) => void;
92
- setHlsInstance: (id: UUID, hlsInstance: Hls | null) => void;
93
- }
94
- export declare const playerStateStore: PlayerStateStore;
@@ -1,127 +0,0 @@
1
- import { getPersistedSubtitleTrack, persistSubtitleTrack } from "../lib/track-persistence.js";
2
- import { clamp } from "../lib/numbers.js";
3
- import { clampVolume } from "../lib/volume-utils.js";
4
- import { playerGlobalActions } from "./player-global-actions.js";
5
- import { playerStateActions } from "./player-store-actions.js";
6
- import { playerTrackActions } from "./player-track-actions.js";
7
- import { settingsStore } from "./settings/store.js";
8
- import { map } from "nanostores";
9
-
10
- // src/store/player-store.ts
11
- const MIN_PLAYBACK_RATE = .25;
12
- const MAX_PLAYBACK_RATE = 3;
13
- const createInitialPlayerState = () => {
14
- const settings = settingsStore.getSettings();
15
- const initialVolume = settings.volume;
16
- return {
17
- paused: true,
18
- loading: true,
19
- ended: false,
20
- mounted: false,
21
- hasInteracted: false,
22
- whenInteracted: /* @__PURE__ */ new Date(0),
23
- isFullscreen: false,
24
- isPictureInPicture: false,
25
- muted: settings.globalMutedPreference,
26
- playbackRate: clamp(settings.playbackSpeed, MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE),
27
- volume: initialVolume,
28
- previousVolume: initialVolume,
29
- viewport: {
30
- width: 0,
31
- height: 0
32
- },
33
- resolution: -1,
34
- subtitleTrack: getPersistedSubtitleTrack(),
35
- availableSubtitleTracks: [],
36
- currentSubtitleText: "",
37
- audioTrack: 0,
38
- availableAudioTracks: [],
39
- hlsInstance: null
40
- };
41
- };
42
- const createInitialPlayer = () => map(createInitialPlayerState());
43
- function setPlayerValue(playerId, key, value) {
44
- playerStateStore.get(playerId).setKey(key, value);
45
- }
46
- const playerStateStore = {
47
- state: /* @__PURE__ */ new Map(),
48
- get: (id) => {
49
- let player = playerStateStore.state.get(id);
50
- if (!player) {
51
- player = createInitialPlayer();
52
- playerStateStore.state.set(id, player);
53
- }
54
- return player;
55
- },
56
- deletePlayer: (id) => {
57
- playerStateStore.state.delete(id);
58
- },
59
- ...playerStateActions,
60
- ...playerTrackActions,
61
- ...playerGlobalActions,
62
- setMounted: (id) => {
63
- setPlayerValue(id, "mounted", true);
64
- },
65
- setHasInteracted: (id) => {
66
- const player = playerStateStore.get(id);
67
- player.setKey("hasInteracted", true);
68
- player.setKey("whenInteracted", /* @__PURE__ */ new Date());
69
- },
70
- setPaused: (id, paused) => {
71
- setPlayerValue(id, "paused", paused);
72
- },
73
- setLoading: (id, loading) => {
74
- setPlayerValue(id, "loading", loading);
75
- },
76
- setEnded: (id, ended) => {
77
- setPlayerValue(id, "ended", ended);
78
- },
79
- setFullscreen: (id, isFullscreen) => {
80
- setPlayerValue(id, "isFullscreen", isFullscreen);
81
- },
82
- setPictureInPicture: (id, isPictureInPicture) => {
83
- setPlayerValue(id, "isPictureInPicture", isPictureInPicture);
84
- },
85
- setMuted: (id, muted) => {
86
- setPlayerValue(id, "muted", muted);
87
- },
88
- setPlaybackRate: (id, playbackRate) => {
89
- setPlayerValue(id, "playbackRate", clamp(playbackRate, MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE));
90
- },
91
- setPreviousVolume: (id, previousVolume) => {
92
- setPlayerValue(id, "previousVolume", clampVolume(previousVolume));
93
- },
94
- setVolume: (id, volume) => {
95
- setPlayerValue(id, "volume", clampVolume(volume));
96
- },
97
- setViewport: (id, width, height) => {
98
- setPlayerValue(id, "viewport", {
99
- width,
100
- height
101
- });
102
- },
103
- setResolution: (id, resolution) => {
104
- setPlayerValue(id, "resolution", resolution);
105
- },
106
- setSubtitleTrack: (id, subtitleTrack) => {
107
- const player = playerStateStore.get(id);
108
- player.get().availableSubtitleTracks.forEach((track, index) => {
109
- track.track.mode = index === subtitleTrack ? "showing" : "disabled";
110
- });
111
- player.setKey("subtitleTrack", subtitleTrack);
112
- persistSubtitleTrack(subtitleTrack);
113
- },
114
- setAvailableSubtitleTracks: (id, tracks) => {
115
- playerStateStore.get(id).setKey("availableSubtitleTracks", tracks);
116
- const persistedTrack = getPersistedSubtitleTrack();
117
- if (persistedTrack >= 0 && persistedTrack < tracks.length) playerStateStore.setSubtitleTrack(id, persistedTrack);
118
- },
119
- setCurrentSubtitleText: (id, text) => {
120
- setPlayerValue(id, "currentSubtitleText", text);
121
- },
122
- setHlsInstance: (id, hlsInstance) => {
123
- setPlayerValue(id, "hlsInstance", hlsInstance);
124
- }
125
- };
126
-
127
- export { createInitialPlayerState, playerStateStore };
@@ -1,44 +0,0 @@
1
- import { getPersistedAudioTrack, persistAudioTrack } from "../lib/track-persistence.js";
2
-
3
- // src/store/player-track-actions.ts
4
- const EMPTY_TRACKS = [];
5
- function toTrackOption(track, index) {
6
- return {
7
- index,
8
- label: track.label,
9
- language: track.language,
10
- kind: track.kind
11
- };
12
- }
13
- const playerTrackActions = {
14
- getTrackOptions(tracks) {
15
- return tracks.length > 0 ? tracks.map(toTrackOption) : EMPTY_TRACKS;
16
- },
17
- selectAudioTrack(id, trackIndex) {
18
- const { availableAudioTracks } = this.get(id).get();
19
- if (trackIndex < 0 || trackIndex >= availableAudioTracks.length) return;
20
- this.setAudioTrack(id, trackIndex);
21
- },
22
- selectSubtitleTrack(id, trackIndex) {
23
- if (trackIndex !== -1) {
24
- const { availableSubtitleTracks } = this.get(id).get();
25
- if (trackIndex < 0 || trackIndex >= availableSubtitleTracks.length) return;
26
- }
27
- this.setSubtitleTrack(id, trackIndex);
28
- },
29
- setAudioTrack(id, audioTrack) {
30
- const player = this.get(id);
31
- const currentState = player.get();
32
- if (currentState.hlsInstance && currentState.hlsInstance.audioTracks && audioTrack >= 0 && audioTrack < currentState.hlsInstance.audioTracks.length) currentState.hlsInstance.audioTrack = audioTrack;
33
- player.setKey("audioTrack", audioTrack);
34
- persistAudioTrack(audioTrack);
35
- },
36
- setAvailableAudioTracks(id, tracks) {
37
- this.get(id).setKey("availableAudioTracks", tracks);
38
- const persistedTrack = getPersistedAudioTrack();
39
- if (persistedTrack >= 0 && persistedTrack < tracks.length) this.setAudioTrack(id, persistedTrack);
40
- else if (tracks.length > 0) this.setAudioTrack(id, 0);
41
- }
42
- };
43
-
44
- export { playerTrackActions };
@@ -1,20 +0,0 @@
1
- import { FeedPost } from "../types/feed.js";
2
- import { WritableAtom } from "nanostores";
3
- export interface PostStoreState {
4
- initialized: boolean;
5
- feedId: string;
6
- posts: FeedPost[];
7
- isLoadedInitial: boolean;
8
- isFetchingVideos: boolean;
9
- currentIndex: number;
10
- total: number;
11
- }
12
- export declare const postStore: WritableAtom<PostStoreState>;
13
- interface PostStoreActions {
14
- init: (feedId: string) => void;
15
- loadInitialPosts: () => Promise<void>;
16
- fetchNewVideos: () => Promise<void>;
17
- setCurrentIndex: (index: number) => void;
18
- }
19
- export declare const postStoreActions: PostStoreActions;
20
- export {};
@@ -1,112 +0,0 @@
1
- import { getFeedPosts } from "./feed-store.js";
2
- import { feedCacheStore } from "./feed-cache-store.js";
3
- import { atom } from "nanostores";
4
-
5
- // src/store/postStore.ts
6
- const postStore = atom({
7
- initialized: false,
8
- feedId: "",
9
- posts: [],
10
- isLoadedInitial: true,
11
- isFetchingVideos: false,
12
- currentIndex: 0,
13
- total: 0
14
- });
15
- /**
16
- * Identifies the feed a request belongs to.
17
- *
18
- * The feed id alone is not enough: switching away and back (A -> B -> A) would
19
- * let a response from the first visit be accepted on the second, merging posts
20
- * against a queue that has since been rebuilt. The counter, bumped on every
21
- * init, keeps each visit distinct.
22
- */
23
- let feedEpoch = 0;
24
- /** Whether the request that started under this epoch still owns the store. */
25
- function isCurrent(epoch) {
26
- return epoch === feedEpoch;
27
- }
28
- const postStoreActions = {
29
- init(feedId) {
30
- feedEpoch += 1;
31
- const cachedPosts = feedCacheStore.loadCache(feedId);
32
- postStore.set({
33
- ...postStore.get(),
34
- feedId,
35
- initialized: true,
36
- posts: cachedPosts,
37
- currentIndex: 0,
38
- total: 0,
39
- isLoadedInitial: cachedPosts.length > 0,
40
- isFetchingVideos: false
41
- });
42
- },
43
- async loadInitialPosts() {
44
- const state = postStore.get();
45
- if (state.isFetchingVideos) return;
46
- const epoch = feedEpoch;
47
- const feedId = state.feedId;
48
- postStore.set({
49
- ...state,
50
- isFetchingVideos: true
51
- });
52
- try {
53
- const currentState = postStore.get();
54
- const apiPosts = await getFeedPosts(feedId);
55
- if (!isCurrent(epoch)) return;
56
- const allPosts = [...currentState.posts, ...apiPosts.posts];
57
- const uniquePosts = Array.from(new Map(allPosts.map((post) => [post.id, post])).values());
58
- feedCacheStore.saveNewPosts(apiPosts.posts, feedId);
59
- postStore.set({
60
- ...postStore.get(),
61
- posts: uniquePosts,
62
- isLoadedInitial: true,
63
- total: apiPosts.total
64
- });
65
- } catch (error) {
66
- console.error("[PostStore] Error loading posts:", error);
67
- } finally {
68
- if (isCurrent(epoch)) postStore.set({
69
- ...postStore.get(),
70
- isFetchingVideos: false
71
- });
72
- }
73
- },
74
- async fetchNewVideos() {
75
- const state = postStore.get();
76
- if (state.isFetchingVideos || !state.initialized) return;
77
- const epoch = feedEpoch;
78
- const feedId = state.feedId;
79
- postStore.set({
80
- ...state,
81
- isFetchingVideos: true
82
- });
83
- try {
84
- const currentState = postStore.get();
85
- const apiPosts = await getFeedPosts(feedId, currentState.posts ? currentState.posts.length : 0);
86
- if (!isCurrent(epoch)) return;
87
- postStore.set({
88
- ...postStore.get(),
89
- posts: [...postStore.get().posts, ...apiPosts.posts],
90
- total: apiPosts.total
91
- });
92
- } finally {
93
- if (isCurrent(epoch)) postStore.set({
94
- ...postStore.get(),
95
- isFetchingVideos: false
96
- });
97
- }
98
- },
99
- setCurrentIndex(index) {
100
- const currentState = postStore.get();
101
- if (index !== currentState.currentIndex) {
102
- const currentVideo = currentState.posts[currentState.currentIndex];
103
- if (currentVideo) feedCacheStore.removePost(currentVideo.id);
104
- postStore.set({
105
- ...currentState,
106
- currentIndex: index
107
- });
108
- }
109
- }
110
- };
111
-
112
- export { postStore, postStoreActions };
@@ -1,15 +0,0 @@
1
- export declare const FONT_FAMILIES: {
2
- readonly monospace_serif: "\"Courier New\", Courier, \"Nimbus Mono L\", \"Cutive Mono\", monospace";
3
- readonly proportional_serif: "\"Times New Roman\", Times, Georgia, Cambria, \"PT Serif Caption\", serif";
4
- readonly monospace_sans: "\"Deja Vu Sans Mono\", \"Lucida Console\", Monaco, Consolas, \"PT Mono\", monospace";
5
- readonly proportional_sans: "Roboto, Arial, Helvetica, Verdana, \"PT Sans Caption\", sans-serif";
6
- readonly casual: "\"Comic Sans MS\", Impact, Handlee, fantasy";
7
- readonly cursive: "\"Monotype Corsiva\", \"URW Chancery L\", \"Apple Chancery\", \"Dancing Script\", cursive";
8
- readonly small_caps: "Arial, Helvetica, Verdana, \"Marcellus SC\", sans-serif";
9
- };
10
- export type FontFamilyKey = keyof typeof FONT_FAMILIES;
11
- export declare const FONT_SIZES: number[];
12
- export declare const COLORS: Record<string, string>;
13
- export declare const EDGE_STYLES: string[];
14
- export declare const PLAYBACK_SPEEDS: number[];
15
- export declare const LANG_TYPES: string[];
@@ -1,47 +0,0 @@
1
- // src/store/settings/constants.ts
2
- const FONT_FAMILIES = {
3
- monospace_serif: "\"Courier New\", Courier, \"Nimbus Mono L\", \"Cutive Mono\", monospace",
4
- proportional_serif: "\"Times New Roman\", Times, Georgia, Cambria, \"PT Serif Caption\", serif",
5
- monospace_sans: "\"Deja Vu Sans Mono\", \"Lucida Console\", Monaco, Consolas, \"PT Mono\", monospace",
6
- proportional_sans: "Roboto, Arial, Helvetica, Verdana, \"PT Sans Caption\", sans-serif",
7
- casual: "\"Comic Sans MS\", Impact, Handlee, fantasy",
8
- cursive: "\"Monotype Corsiva\", \"URW Chancery L\", \"Apple Chancery\", \"Dancing Script\", cursive",
9
- small_caps: "Arial, Helvetica, Verdana, \"Marcellus SC\", sans-serif"
10
- };
11
- const FONT_SIZES = [
12
- 50,
13
- 100,
14
- 150,
15
- 200
16
- ];
17
- const COLORS = {
18
- white: "#ffffff",
19
- yellow: "#ffff00",
20
- green: "#00ff00",
21
- cyan: "#00ffff",
22
- blue: "#0000ff",
23
- magenta: "#ff00ff",
24
- red: "#ff0000",
25
- black: "#000000"
26
- };
27
- const EDGE_STYLES = [
28
- "none",
29
- "drop-shadow",
30
- "raised",
31
- "depressed",
32
- "outline"
33
- ];
34
- const PLAYBACK_SPEEDS = [
35
- 1,
36
- 1.25,
37
- 1.5,
38
- 2,
39
- 3
40
- ];
41
- const LANG_TYPES = [
42
- "off",
43
- "eng",
44
- "auto"
45
- ];
46
-
47
- export { COLORS, EDGE_STYLES, FONT_FAMILIES, FONT_SIZES, LANG_TYPES, PLAYBACK_SPEEDS };
@@ -1,2 +0,0 @@
1
- import { SettingsState } from "./types.js";
2
- export declare const defaultSettings: SettingsState;
@@ -1,24 +0,0 @@
1
- // src/store/settings/defaults.ts
2
- const defaultSettings = {
3
- volume: 1,
4
- playbackSpeed: 1,
5
- customPlayback: 1,
6
- allowCaptions: false,
7
- captionPosition: {
8
- x: 20,
9
- y: 90
10
- },
11
- captionLang: "off",
12
- captionFontFamily: "proportional_sans",
13
- captionFontSize: 100,
14
- captionFontColor: "#ffffff",
15
- captionFontOpacity: 100,
16
- captionBGColor: "#000000",
17
- captionBGOpacity: 75,
18
- captionWindowColor: "#000000",
19
- captionWindowOpacity: 0,
20
- captionCharacterEdgeStyle: "none",
21
- globalMutedPreference: false
22
- };
23
-
24
- export { defaultSettings };
@@ -1,3 +0,0 @@
1
- import { SettingsState } from "./types.js";
2
- export declare const loadSettings: () => SettingsState;
3
- export declare const saveSettings: (settings: SettingsState) => void;
@@ -1,28 +0,0 @@
1
- import { defaultSettings } from "./defaults.js";
2
- import { validateSettings } from "./validation.js";
3
-
4
- // src/store/settings/storage.ts
5
- const SETTINGS_STORAGE_KEY = "videosdk_settings";
6
- const loadSettings = () => {
7
- if (typeof window === "undefined") return defaultSettings;
8
- try {
9
- const storedSettings = localStorage.getItem(SETTINGS_STORAGE_KEY);
10
- if (storedSettings) {
11
- const parsedSettings = JSON.parse(storedSettings);
12
- return validateSettings(parsedSettings);
13
- }
14
- } catch (error) {
15
- console.error("Failed to load settings from localStorage:", error);
16
- }
17
- return defaultSettings;
18
- };
19
- const saveSettings = (settings) => {
20
- if (typeof window === "undefined") return;
21
- try {
22
- localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
23
- } catch (error) {
24
- console.error("Failed to save settings to localStorage:", error);
25
- }
26
- };
27
-
28
- export { loadSettings, saveSettings };
@@ -1,32 +0,0 @@
1
- import { CaptionLangType, SettingsState } from "./types.js";
2
- import { MapStore } from "nanostores";
3
- interface SettingsStore {
4
- state: MapStore<SettingsState>;
5
- getSettings: () => SettingsState;
6
- setVolume: (volume: number) => number;
7
- setPlaybackSpeed: (playbackSpeed: number) => number;
8
- setCustomPlayback: (customPlayback: number) => number;
9
- setAllowCaptions: (allowCaptions: boolean) => boolean;
10
- setCaptionPosition: (x: number, y: number) => {
11
- x: number;
12
- y: number;
13
- };
14
- setSubtitleLang: (captionLang: CaptionLangType) => CaptionLangType;
15
- setCaptionFontFamily: (captionFontFamily: string) => string;
16
- setCaptionFontSize: (captionFontSize: number) => number;
17
- setCaptionFontColor: (captionFontColor: string) => string;
18
- setCaptionBGColor: (captionBGColor: string) => string;
19
- setCaptionBGOpacity: (captionOpacity: number) => number;
20
- setCaptionWindowColor: (captionWindowColor: string) => string;
21
- setCaptionWindowOpacity: (captionWindowOpacity: number) => number;
22
- setCaptionFontOpacity: (captionFontOpacity: number) => number;
23
- setCaptionCharacterEdgeStyle: (captionCharacterEdgeStyle: string) => string;
24
- resetCaptionSettings: () => void;
25
- setSelectedLanguageCode: (languageCode: string) => string | undefined;
26
- setMuted: (muted: boolean) => boolean;
27
- setPreferredQuality: (quality: number | undefined) => number | undefined;
28
- setPreferredAudioLanguage: (language: string | undefined) => string | undefined;
29
- setPreferredSubtitleLanguage: (language: string | undefined) => string | undefined;
30
- }
31
- export declare const settingsStore: SettingsStore;
32
- export {};
@@ -1,59 +0,0 @@
1
- import { defaultSettings } from "./defaults.js";
2
- import { loadSettings, saveSettings } from "./storage.js";
3
- import { clampVolume } from "../../lib/volume-utils.js";
4
- import { map } from "nanostores";
5
-
6
- // src/store/settings/store.ts
7
- const updateSettings = (key, value) => {
8
- settingsStore.state.setKey(key, value);
9
- saveSettings(settingsStore.state.get());
10
- return value;
11
- };
12
- const settingsState = map(loadSettings());
13
- const settingsStore = {
14
- state: settingsState,
15
- getSettings: () => settingsStore.state.get(),
16
- setVolume: (volume) => updateSettings("volume", clampVolume(volume)),
17
- setPlaybackSpeed: (playbackSpeed) => updateSettings("playbackSpeed", playbackSpeed),
18
- setCustomPlayback: (customPlayback) => updateSettings("customPlayback", customPlayback),
19
- setAllowCaptions: (allowCaptions) => updateSettings("allowCaptions", allowCaptions),
20
- setCaptionPosition: (x, y) => updateSettings("captionPosition", {
21
- x,
22
- y
23
- }),
24
- setSubtitleLang: (captionLang) => updateSettings("captionLang", captionLang),
25
- setCaptionFontFamily: (captionFontFamily) => updateSettings("captionFontFamily", captionFontFamily),
26
- setCaptionFontSize: (captionFontSize) => updateSettings("captionFontSize", captionFontSize),
27
- setCaptionFontColor: (captionFontColor) => updateSettings("captionFontColor", captionFontColor),
28
- setCaptionBGColor: (captionBGColor) => updateSettings("captionBGColor", captionBGColor),
29
- setCaptionBGOpacity: (captionOpacity) => updateSettings("captionBGOpacity", captionOpacity),
30
- setCaptionWindowColor: (captionWindowColor) => updateSettings("captionWindowColor", captionWindowColor),
31
- setCaptionWindowOpacity: (captionWindowOpacity) => updateSettings("captionWindowOpacity", captionWindowOpacity),
32
- setCaptionFontOpacity: (captionFontOpacity) => updateSettings("captionFontOpacity", captionFontOpacity),
33
- setCaptionCharacterEdgeStyle: (captionCharacterEdgeStyle) => updateSettings("captionCharacterEdgeStyle", captionCharacterEdgeStyle),
34
- resetCaptionSettings: () => {
35
- const resetSettings = {
36
- ...settingsStore.state.get(),
37
- captionPosition: defaultSettings.captionPosition,
38
- captionLang: defaultSettings.captionLang,
39
- captionFontFamily: defaultSettings.captionFontFamily,
40
- captionFontSize: defaultSettings.captionFontSize,
41
- captionFontColor: defaultSettings.captionFontColor,
42
- captionBGColor: defaultSettings.captionBGColor,
43
- captionBGOpacity: defaultSettings.captionBGOpacity,
44
- captionWindowColor: defaultSettings.captionWindowColor,
45
- captionWindowOpacity: defaultSettings.captionWindowOpacity,
46
- captionFontOpacity: defaultSettings.captionFontOpacity,
47
- captionCharacterEdgeStyle: defaultSettings.captionCharacterEdgeStyle
48
- };
49
- settingsStore.state.set(resetSettings);
50
- saveSettings(resetSettings);
51
- },
52
- setSelectedLanguageCode: (languageCode) => updateSettings("selectedLanguageCode", languageCode),
53
- setMuted: (muted) => updateSettings("globalMutedPreference", muted),
54
- setPreferredQuality: (quality) => updateSettings("preferredQuality", quality),
55
- setPreferredAudioLanguage: (language) => updateSettings("preferredAudioLanguage", language),
56
- setPreferredSubtitleLanguage: (language) => updateSettings("preferredSubtitleLanguage", language)
57
- };
58
-
59
- export { settingsStore };
@@ -1,27 +0,0 @@
1
- export type VideoTheme = "default" | "minimal" | "feed" | "hover" | "hideUI";
2
- export type CaptionLangType = "off" | "eng" | "auto";
3
- export interface SettingsState {
4
- volume: number;
5
- playbackSpeed: number;
6
- customPlayback: number;
7
- allowCaptions: boolean;
8
- captionPosition: {
9
- x: number;
10
- y: number;
11
- };
12
- captionLang: CaptionLangType;
13
- captionFontFamily: string;
14
- captionFontSize: number;
15
- captionFontColor: string;
16
- captionFontOpacity: number;
17
- captionBGColor: string;
18
- captionBGOpacity: number;
19
- captionWindowColor: string;
20
- captionWindowOpacity: number;
21
- captionCharacterEdgeStyle: string;
22
- selectedLanguageCode?: string;
23
- globalMutedPreference: boolean;
24
- preferredQuality?: number;
25
- preferredAudioLanguage?: string;
26
- preferredSubtitleLanguage?: string;
27
- }
@@ -1,7 +0,0 @@
1
- import { SettingsState } from "./types.js";
2
- /**
3
- * Validate and parse settings, returning defaults for invalid values
4
- * @param parsed - Raw settings object (e.g., from localStorage)
5
- * @returns Validated settings with defaults applied for invalid values
6
- */
7
- export declare const validateSettings: (parsed: unknown) => SettingsState;