itube-specs 0.0.1029 → 0.0.1031
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/SITE_UPDATES.md +8 -0
- package/assets/scss/themes/light/_theme.scss +2 -2
- package/components/player/core.vue +3 -0
- package/package.json +1 -1
- package/runtime/utils/cleaners/__tests__/clean-video-data.test.ts +7 -2
- package/runtime/utils/cleaners/clean-video-data.ts +1 -0
- package/types/thumbs-urls.d.ts +2 -1
package/SITE_UPDATES.md
CHANGED
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
коммиты до бампа); `npm run patch` сам проставит ей номер версии. Формат пункта: что сделать и где,
|
|
12
12
|
кому именно (всем / сайтам с N), что будет, если не сделать.
|
|
13
13
|
|
|
14
|
+
## 0.0.1030 — 2026-10-13
|
|
15
|
+
|
|
16
|
+
- **Всем сайтам с плеером:** поднять `itube-modern-player` до `^0.15.0` (`npm install itube-modern-player@^0.15.0`).
|
|
17
|
+
Слой теперь отдаёт постеру ролика `fallback` — jpeg из `thumbUrls.jpeg` (его сохраняет `cleanVideoData`), и плеер
|
|
18
|
+
0.15 рисует webp-постер через `<picture>` с jpeg для браузеров без webp. Не поднять — ничего не сломается, поле
|
|
19
|
+
молча игнорируется, фолбэка просто не будет. Сайтам с форком `components/player/core.vue` (hdsex-remaster,
|
|
20
|
+
videosection-redesign) — добавить `fallback` в постер, образец — коммит videosection-redesign.
|
|
21
|
+
|
|
14
22
|
## 0.0.1029 — 2026-10-13
|
|
15
23
|
|
|
16
24
|
- **Сайтам с рекламными ссылками над контентом на мобиле (videosection-redesign):** новая вторая навигация —
|
|
@@ -1041,8 +1041,8 @@ $layout-second-nav-link-text: $color-white;
|
|
|
1041
1041
|
$layout-second-nav-dot-bg: $color-green-400;
|
|
1042
1042
|
|
|
1043
1043
|
// ─── Native card ───
|
|
1044
|
-
$native-card-bg: $color-
|
|
1045
|
-
$native-card-primary: $color-gray-
|
|
1044
|
+
$native-card-bg: $color-white;
|
|
1045
|
+
$native-card-primary: $color-gray-900;
|
|
1046
1046
|
$native-card-secondary: $color-gray-500;
|
|
1047
1047
|
|
|
1048
1048
|
// ─── Adv: плашка «Реклама» поверх креатива ───
|
|
@@ -172,6 +172,8 @@ const currentSource = computed<VideoSource>(() => {
|
|
|
172
172
|
const big = props.data.thumbUrls?.webp?.[ThumbSize.Big];
|
|
173
173
|
const medium = props.data.thumbUrls?.webp?.[ThumbSize.Medium];
|
|
174
174
|
const src = big || medium;
|
|
175
|
+
// jpeg — для браузеров без webp: плеер (0.15+) рисует <picture> с ним в <img>
|
|
176
|
+
const fallback = props.data.thumbUrls?.jpeg?.[ThumbSize.Big] || props.data.thumbUrls?.jpeg?.[ThumbSize.Medium];
|
|
175
177
|
|
|
176
178
|
return {
|
|
177
179
|
src: props.data.videoUrl,
|
|
@@ -181,6 +183,7 @@ const currentSource = computed<VideoSource>(() => {
|
|
|
181
183
|
poster: src
|
|
182
184
|
? {
|
|
183
185
|
src,
|
|
186
|
+
fallback,
|
|
184
187
|
srcset: big && medium ? `${medium} 480w, ${big} 1280w` : undefined,
|
|
185
188
|
sizes: big && medium ? '100vw' : undefined,
|
|
186
189
|
width: 1280,
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ describe('cleanVideoData', () => {
|
|
|
19
19
|
channel: { name: 'Channel', avatar_url: 'https://img.com/ch.jpg' },
|
|
20
20
|
url: '/video/1',
|
|
21
21
|
preview_url: 'https://img.com/preview.mp4',
|
|
22
|
-
thumb_urls: { webp: { '320x180': 'small' } },
|
|
22
|
+
thumb_urls: { webp: { '320x180': 'small' }, jpeg: { '320x180': 'small-jpeg' } },
|
|
23
23
|
vtt_url: '/vtt',
|
|
24
24
|
vtt_sprite_url: '/sprite',
|
|
25
25
|
created: 1700000000,
|
|
@@ -32,7 +32,7 @@ describe('cleanVideoData', () => {
|
|
|
32
32
|
const result = cleanVideoData(raw as any);
|
|
33
33
|
expect(result.guid).toBe('v-1');
|
|
34
34
|
expect(result.channelName).toBe('Channel');
|
|
35
|
-
expect(result.thumbUrls).toEqual({ webp: { '320x180': 'small' } });
|
|
35
|
+
expect(result.thumbUrls).toEqual({ webp: { '320x180': 'small' }, jpeg: { '320x180': 'small-jpeg' } });
|
|
36
36
|
expect(result.vttUrl).toBe('/vtt');
|
|
37
37
|
expect(result.videoUrl).toBe('/stream');
|
|
38
38
|
expect(result.isDeleted).toBe(false);
|
|
@@ -150,6 +150,11 @@ describe('cleanVideoData', () => {
|
|
|
150
150
|
]);
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
+
it('тумбы без jpeg — без ключа jpeg', () => {
|
|
154
|
+
const result = cleanVideoData({ thumb_urls: { webp: { '320x180': 'small' } } } as any);
|
|
155
|
+
expect(result.thumbUrls).toEqual({ webp: { '320x180': 'small' } });
|
|
156
|
+
});
|
|
157
|
+
|
|
153
158
|
it('пустые данные → дефолты', () => {
|
|
154
159
|
const result = cleanVideoData({} as any);
|
|
155
160
|
expect(result.guid).toBe('');
|
|
@@ -84,6 +84,7 @@ export const cleanVideoData = (data: IRawVideoData, theme?: string): IVideoData
|
|
|
84
84
|
previewUrl: data.preview_url || '',
|
|
85
85
|
thumbUrls: data.thumb_urls ? {
|
|
86
86
|
webp: data.thumb_urls.webp,
|
|
87
|
+
...(data.thumb_urls.jpeg ? { jpeg: data.thumb_urls.jpeg } : {}),
|
|
87
88
|
} : undefined,
|
|
88
89
|
vttUrl: data.vtt_url || '',
|
|
89
90
|
vttSpriteUrl: data.vtt_sprite_url || '',
|
package/types/thumbs-urls.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ThumbSize } from '../runtime/constants/thumb-size';
|
|
2
2
|
|
|
3
|
-
/** Очищенные
|
|
3
|
+
/** Очищенные тумбы: webp; jpeg — только у ролика целиком, фолбэк постера плеера. */
|
|
4
4
|
export interface IThumbUrls {
|
|
5
5
|
webp: Partial<Record<ThumbSize, string>>;
|
|
6
|
+
jpeg?: Partial<Record<ThumbSize, string>>;
|
|
6
7
|
}
|