itube-specs 0.0.1060 → 0.0.1063

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 (52) hide show
  1. package/SITE_UPDATES.md +18 -0
  2. package/assets/icons/common/arrow-up.svg +1 -0
  3. package/assets/icons/common/link.svg +1 -0
  4. package/assets/icons/common/loader.svg +1 -0
  5. package/assets/icons/common/upload-arrow.svg +1 -0
  6. package/assets/scss/themes/dark/_theme.scss +89 -3
  7. package/assets/scss/themes/light/_theme.scss +87 -1
  8. package/assets/scss/vars/_palette.scss +1 -0
  9. package/components/layout/burger.vue +16 -8
  10. package/components/layout/footer-language.vue +4 -1
  11. package/components/layout/header.vue +129 -111
  12. package/components/layout/notifications.vue +29 -1
  13. package/components/library/upload-card.vue +448 -0
  14. package/components/library/uploads-grid.vue +145 -0
  15. package/components/library/uploads.vue +146 -0
  16. package/components/ui/confirm.vue +2 -1
  17. package/components/ui/link.vue +1 -1
  18. package/components/upload/combobox.vue +380 -0
  19. package/components/upload/details.vue +239 -0
  20. package/components/upload/main.vue +195 -0
  21. package/components/upload/models.vue +162 -0
  22. package/components/upload/picker.vue +319 -0
  23. package/components/upload/progress.vue +477 -0
  24. package/components/upload/publish.vue +153 -0
  25. package/components/upload/requirements.vue +179 -0
  26. package/components/upload/rules.vue +144 -0
  27. package/components/upload/section.vue +55 -0
  28. package/components/upload/sent.vue +299 -0
  29. package/components/upload/spinner.vue +35 -0
  30. package/components/upload/tags.vue +81 -0
  31. package/composables/use-my-uploads.ts +26 -0
  32. package/composables/use-upload-suggest.ts +40 -0
  33. package/composables/use-upload.ts +165 -0
  34. package/i18n/locales/en-US.json +251 -0
  35. package/package.json +1 -1
  36. package/pages/library/index.vue +31 -0
  37. package/pages/library/uploads.vue +41 -0
  38. package/pages/upload.vue +19 -0
  39. package/runtime/constants/upload.ts +70 -0
  40. package/runtime/index.ts +1 -0
  41. package/stubs/uploads.ts +80 -0
  42. package/types/index.d.ts +1 -0
  43. package/types/upload.d.ts +56 -0
  44. package/utils/upload/__tests__/check-upload-file.test.ts +34 -0
  45. package/utils/upload/__tests__/format-file-size.test.ts +16 -0
  46. package/utils/upload/__tests__/format-video-quality.test.ts +19 -0
  47. package/utils/upload/__tests__/strip-html-tags.test.ts +12 -0
  48. package/utils/upload/check-upload-file.ts +123 -0
  49. package/utils/upload/create-idle-upload-checks.ts +11 -0
  50. package/utils/upload/format-file-size.ts +8 -0
  51. package/utils/upload/format-video-quality.ts +13 -0
  52. package/utils/upload/strip-html-tags.ts +3 -0
package/SITE_UPDATES.md CHANGED
@@ -11,6 +11,24 @@
11
11
  коммиты до бампа); `npm run patch` сам проставит ей номер версии. Формат пункта: что сделать и где,
12
12
  кому именно (всем / сайтам с N), что будет, если не сделать.
13
13
 
14
+ ## 0.0.1062 — 2026-11-02
15
+
16
+ - **Всем — к сведению:** за тем же флагом `FeatureUploadEnabled` — страница «My videos» `/library/uploads` (загруженные
17
+ ролики пользователя: вкладки по статусу, видимость, ссылка, правка названия, удаление; данные — заглушка). Туда
18
+ ведёт «Go to my videos» после загрузки, а в `/library` появилась секция «My videos» (4 последних ролика, «Show all»). Новые общие ключи `my_uploads` и три ключа в `snackbar` (пока только en-US).
19
+ Делать ничего не надо.
20
+
21
+ ## 0.0.1061 — 2026-11-02
22
+
23
+ - **Всем — решить флаг:** новая страница загрузки видео `/upload` (выбор файла с проверкой в браузере → детали
24
+ во время загрузки → «отправлено» со статусом обработки) и кнопка Upload в шапке (десктоп) — за флагом
25
+ `FeatureUploadEnabled`. API загрузки ещё нет: прогресс и обработка имитируются таймерами. Хотите страницу —
26
+ добавьте `FeatureUploadEnabled: true` в `config/feature-flags.config.ts` (gay-cool-new включил). Без флага
27
+ `/upload` отдаёт 404, кнопки нет, а мёртвая кнопка Upload из бургера (была без действия) пропадает — делать
28
+ ничего не надо.
29
+ - **Всем — к сведению:** новая группа общих ключей `upload_page` (пока только en-US, остальные локали — через CSV
30
+ слоя). У `UiConfirm` необязательный проп `cancelText` (по умолчанию «Cancel», как было).
31
+
14
32
  ## 0.0.1060 — 2026-11-02
15
33
 
16
34
  - **Сайтам со своими `assets/scss/vars` (hdsex-remaster и др.), срочно:** с 0.0.1059 (лоадер, `0d412182`) без новых
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" viewBox="0 0 24 24"><path d="m5 12 7-7 7 7M12 19V5"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24"><path d="M9 17H7A5 5 0 0 1 7 7h2M15 7h2a5 5 0 1 1 0 10h-2M8 12h8"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" viewBox="0 0 18 18"><path fill="currentColor" d="M9 2.25 4.5 6.75h2.75V12h3.5V6.75h2.75z"/><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M2.5 14v1.25c0 .97.78 1.75 1.75 1.75h9.5c.97 0 1.75-.78 1.75-1.75V14"/></svg>
@@ -424,6 +424,8 @@ $niche-switch-text--checked: $color-white;
424
424
  $footer-language-bg: $color-zinc-800-50;
425
425
  $footer-language-bg--hover: $color-zinc-700;
426
426
  $footer-language-text: $color-zinc-400;
427
+ $footer-language-text--hover: $color-white;
428
+ $footer-language-badge: $color-zinc-200;
427
429
  $footer-language-menu-bg: $color-night;
428
430
  $footer-language-menu-border: $color-zinc-800;
429
431
  $footer-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
@@ -456,15 +458,18 @@ $header-burger-icon: $color-zinc-200;
456
458
  $header-user-icon: $color-zinc-500;
457
459
  $header-language-trigger: $color-zinc-400;
458
460
  $header-language-trigger--hover: $color-white;
459
- $header-language-trigger-bg: transparent;
460
- $header-language-trigger-bg--hover: transparent;
461
+ $header-language-trigger-bg: $color-zinc-800-50;
462
+ $header-language-trigger-bg--hover: $color-zinc-700;
463
+ $header-language-badge: $color-zinc-200;
461
464
  $header-language-menu-bg: $color-night;
462
465
  $header-language-menu-border: $color-zinc-800;
463
466
  $header-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
464
467
  $header-language-menu-item--hover: $color-zinc-800-50;
465
468
 
466
469
  // ─── notifications ───
467
- $notifications-icon: $color-zinc-300;
470
+ $notifications-icon: $color-zinc-400;
471
+ $notifications-bg: $color-zinc-800-50;
472
+ $notifications-bg--hover: $color-zinc-700;
468
473
  $notifications-icon--mobile: $color-zinc-200;
469
474
  $notifications-icon--hover: $color-white;
470
475
  $notifications-badge-bg: $color-indigo-600;
@@ -1214,3 +1219,84 @@ $player-tags-chip-bg: $color-zinc-800;
1214
1219
  $player-tags-tag-bg: $color-zinc-800-50;
1215
1220
  $player-tags-more-text: $color-zinc-400;
1216
1221
  $player-tags-more-text--hover: $color-white;
1222
+
1223
+ // ─── Header upload button ───
1224
+ $header-upload-bg: $color-indigo-600-20;
1225
+ $header-upload-border: $color-indigo-500-50;
1226
+ $header-upload-border--hover: $color-indigo-500;
1227
+ $header-upload-text: $color-white;
1228
+
1229
+ // ─── Upload page ───
1230
+ $upload-title: $color-white;
1231
+ $upload-text: $color-zinc-450;
1232
+ $upload-card-bg: $color-zinc-925;
1233
+ $upload-accent: $color-indigo-600;
1234
+ $upload-accent-text: $color-indigo-500;
1235
+ $upload-success: $color-emerald-500;
1236
+ $upload-error: $color-red-500;
1237
+ $upload-icon-bg: $color-zinc-850;
1238
+ $upload-dot: $color-zinc-550;
1239
+ $upload-check-icon: $color-zinc-550;
1240
+ $upload-dropzone-border: $color-zinc-800;
1241
+ $upload-dropzone-border--error: $color-red-500-50;
1242
+ $upload-dropzone-bg--active: $color-zinc-925;
1243
+ $upload-field-bg: $color-zinc-850;
1244
+ $upload-field-text: $color-white;
1245
+ $upload-field-placeholder: $color-zinc-450;
1246
+ $upload-field-border: transparent;
1247
+ $upload-field-border--hover: $color-zinc-800;
1248
+ $upload-field-bg--hover: $color-zinc-800;
1249
+ $upload-chip-bg: $color-zinc-850;
1250
+ $upload-chip-text: $color-white;
1251
+ $upload-chip-icon: $color-zinc-450;
1252
+ $upload-chip-icon--hover: $color-white;
1253
+ $upload-avatar-bg: $color-zinc-925;
1254
+ $upload-avatar-text: $color-zinc-450;
1255
+ $upload-listbox-bg: $color-zinc-850;
1256
+ $upload-listbox-border: $color-zinc-800;
1257
+ $upload-listbox-shadow: 0 12px 32px #{$mono-black-50}, 0 2px 8px #{$mono-black-42};
1258
+ $upload-option-bg--active: $color-zinc-800;
1259
+ $upload-poster-bg: $color-zinc-850;
1260
+ $upload-overlay-bg: $color-black-50;
1261
+ $upload-overlay-text: $color-white;
1262
+ $upload-overlay-subtext: $color-white-75;
1263
+ $upload-badge-bg: $color-black-75;
1264
+ $upload-badge-text: $color-white;
1265
+ $upload-track-bg: $color-black-50;
1266
+ $upload-stripes-from: $color-indigo-600;
1267
+ $upload-stripes-to: $color-indigo-800;
1268
+ $upload-step-line: $color-zinc-700;
1269
+ $upload-step-time: $color-zinc-500;
1270
+ $upload-step-icon: $color-white;
1271
+ $upload-radio-ring: $color-zinc-700;
1272
+ $upload-radio-dot: $color-white;
1273
+ $upload-rules-text: $color-zinc-400;
1274
+ $upload-rules-dot: $color-zinc-600;
1275
+
1276
+ // ─── My videos (library uploads) ───
1277
+ $library-upload-placeholder-from: $color-zinc-700;
1278
+ $library-upload-placeholder-to: $color-zinc-800;
1279
+ $library-upload-badge-bg: $color-black-75;
1280
+ $library-upload-badge-text: $color-white;
1281
+ $library-upload-dot: $color-indigo-400;
1282
+ $library-upload-dot--error: $color-red-500;
1283
+ $library-upload-title: $color-white;
1284
+ $library-upload-title--hover: $color-indigo-400;
1285
+ $library-upload-untitled: $color-zinc-500;
1286
+ $library-upload-meta: $color-zinc-500;
1287
+ $library-upload-meta--error: $color-red-400;
1288
+ $library-upload-menu-icon: $color-zinc-500;
1289
+ $library-upload-menu-icon--hover: $color-white;
1290
+ $library-upload-menu-value: $color-zinc-500;
1291
+ $library-upload-delete-text: $color-red-400;
1292
+ $library-upload-radio: $color-zinc-500;
1293
+ $library-upload-radio--checked: $color-indigo-600;
1294
+ $library-upload-radio-dot: $color-white;
1295
+ $library-upload-empty-icon-bg: $color-zinc-900;
1296
+ $library-upload-empty-icon-border: $color-zinc-800;
1297
+ $library-upload-empty-icon: $color-zinc-400;
1298
+ $library-upload-empty-title: $color-white;
1299
+ $library-upload-note: $color-zinc-500;
1300
+ $library-upload-tab-count: $color-zinc-500;
1301
+ $library-upload-tab-count--active: $color-white-70;
1302
+ $library-upload-fix-text: $color-zinc-400;
@@ -482,6 +482,8 @@ $niche-switch-text--checked: $color-white;
482
482
  $footer-language-bg: $color-slate-750;
483
483
  $footer-language-bg--hover: $color-slate-700;
484
484
  $footer-language-text: $color-white;
485
+ $footer-language-text--hover: $color-white;
486
+ $footer-language-badge: $color-gray-200;
485
487
  $footer-language-menu-bg: $color-slate-850;
486
488
  $footer-language-menu-border: $color-white-10;
487
489
  $footer-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
@@ -516,11 +518,14 @@ $header-language-trigger: $color-white;
516
518
  $header-language-trigger--hover: $color-white;
517
519
  $header-language-trigger-bg: $color-slate-750;
518
520
  $header-language-trigger-bg--hover: $color-slate-700;
521
+ $header-language-badge: $color-gray-200;
519
522
  $header-language-menu-bg: $color-slate-850;
520
523
  $header-language-menu-border: $color-white-10;
521
524
  $header-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
522
525
  $header-language-menu-item--hover: $color-white-5;
523
- $notifications-icon: $color-gray-300;
526
+ $notifications-icon: $color-gray-400;
527
+ $notifications-bg: $color-slate-750;
528
+ $notifications-bg--hover: $color-slate-700;
524
529
  $notifications-icon--mobile: $color-gray-200;
525
530
  $notifications-icon--hover: $color-white;
526
531
  $notifications-badge-bg: $color-indigo-600;
@@ -1243,3 +1248,84 @@ $player-tags-chip-bg: $color-gray-200;
1243
1248
  $player-tags-tag-bg: $color-gray-100;
1244
1249
  $player-tags-more-text: $color-gray-700;
1245
1250
  $player-tags-more-text--hover: $color-gray-900;
1251
+
1252
+ // ─── Header upload button ───
1253
+ $header-upload-bg: $color-indigo-600-20;
1254
+ $header-upload-border: $color-indigo-500-50;
1255
+ $header-upload-border--hover: $color-indigo-500;
1256
+ $header-upload-text: $color-white;
1257
+
1258
+ // ─── Upload page ───
1259
+ $upload-title: $color-gray-900;
1260
+ $upload-text: $color-gray-500;
1261
+ $upload-card-bg: $color-gray-100;
1262
+ $upload-accent: $color-indigo-600;
1263
+ $upload-accent-text: $color-indigo-600;
1264
+ $upload-success: $color-emerald-600;
1265
+ $upload-error: $color-red-500;
1266
+ $upload-icon-bg: $color-gray-200;
1267
+ $upload-dot: $color-gray-400;
1268
+ $upload-check-icon: $color-gray-400;
1269
+ $upload-dropzone-border: $color-gray-300;
1270
+ $upload-dropzone-border--error: $color-red-300;
1271
+ $upload-dropzone-bg--active: $color-gray-100;
1272
+ $upload-field-bg: $color-white;
1273
+ $upload-field-text: $color-gray-900;
1274
+ $upload-field-placeholder: $color-gray-400;
1275
+ $upload-field-border: $color-gray-200;
1276
+ $upload-field-border--hover: $color-gray-300;
1277
+ $upload-field-bg--hover: $color-gray-200;
1278
+ $upload-chip-bg: $color-gray-200;
1279
+ $upload-chip-text: $color-gray-900;
1280
+ $upload-chip-icon: $color-gray-500;
1281
+ $upload-chip-icon--hover: $color-gray-900;
1282
+ $upload-avatar-bg: $color-gray-100;
1283
+ $upload-avatar-text: $color-gray-500;
1284
+ $upload-listbox-bg: $color-white;
1285
+ $upload-listbox-border: $color-gray-200;
1286
+ $upload-listbox-shadow: 0 12px 32px #{$mono-black-15}, 0 2px 8px #{$mono-black-10};
1287
+ $upload-option-bg--active: $color-gray-100;
1288
+ $upload-poster-bg: $color-gray-200;
1289
+ $upload-overlay-bg: $color-black-50;
1290
+ $upload-overlay-text: $color-white;
1291
+ $upload-overlay-subtext: $color-white-75;
1292
+ $upload-badge-bg: $color-black-75;
1293
+ $upload-badge-text: $color-white;
1294
+ $upload-track-bg: $color-black-50;
1295
+ $upload-stripes-from: $color-indigo-600;
1296
+ $upload-stripes-to: $color-indigo-800;
1297
+ $upload-step-line: $color-gray-200;
1298
+ $upload-step-time: $color-gray-400;
1299
+ $upload-step-icon: $color-white;
1300
+ $upload-radio-ring: $color-gray-300;
1301
+ $upload-radio-dot: $color-white;
1302
+ $upload-rules-text: $color-gray-300;
1303
+ $upload-rules-dot: $color-gray-500;
1304
+
1305
+ // ─── My videos (library uploads) ───
1306
+ $library-upload-placeholder-from: $color-gray-200;
1307
+ $library-upload-placeholder-to: $color-gray-300;
1308
+ $library-upload-badge-bg: $color-black-75;
1309
+ $library-upload-badge-text: $color-white;
1310
+ $library-upload-dot: $color-indigo-400;
1311
+ $library-upload-dot--error: $color-red-500;
1312
+ $library-upload-title: $color-gray-900;
1313
+ $library-upload-title--hover: $color-indigo-600;
1314
+ $library-upload-untitled: $color-gray-500;
1315
+ $library-upload-meta: $color-gray-500;
1316
+ $library-upload-meta--error: $color-red-600;
1317
+ $library-upload-menu-icon: $color-gray-500;
1318
+ $library-upload-menu-icon--hover: $color-gray-900;
1319
+ $library-upload-menu-value: $color-gray-500;
1320
+ $library-upload-delete-text: $color-red-400;
1321
+ $library-upload-radio: $color-gray-400;
1322
+ $library-upload-radio--checked: $color-indigo-600;
1323
+ $library-upload-radio-dot: $color-white;
1324
+ $library-upload-empty-icon-bg: $color-gray-100;
1325
+ $library-upload-empty-icon-border: $color-gray-200;
1326
+ $library-upload-empty-icon: $color-gray-500;
1327
+ $library-upload-empty-title: $color-gray-900;
1328
+ $library-upload-note: $color-gray-500;
1329
+ $library-upload-tab-count: $color-gray-500;
1330
+ $library-upload-tab-count--active: $color-white-70;
1331
+ $library-upload-fix-text: $color-gray-300;
@@ -133,6 +133,7 @@ $color-red-400: lab(63.7053% 60.745 31.3109);
133
133
  $color-red-500: lab(55.4814% 75.0732 48.8528);
134
134
  $color-red-500-10: color-mix(in oklab, #{$color-red-500} 10%, transparent);
135
135
  $color-red-500-20: color-mix(in oklab, #{$color-red-500} 20%, transparent);
136
+ $color-red-500-50: color-mix(in oklab, #{$color-red-500} 50%, transparent);
136
137
  $color-red-600: lab(48.4493% 77.4328 61.5452);
137
138
  $color-red-600-20: color-mix(in oklab, #{$color-red-600} 20%, transparent);
138
139
  $color-red-600-30: color-mix(in oklab, #{$color-red-600} 30%, transparent);
@@ -33,11 +33,13 @@
33
33
  <UiAvatar :size="40"/>
34
34
  <span class="layout-burger__button-text">{{ data.username }}</span>
35
35
  </NuxtLink>
36
- <button
36
+ <component
37
37
  v-for="(btn, index) in burgerButtons"
38
+ :is="btn.link ? NuxtLink : 'button'"
38
39
  :key="`burger-btn-${index}`"
40
+ :to="btn.link"
41
+ :type="btn.link ? undefined : 'button'"
39
42
  class="layout-burger__button"
40
- type="button"
41
43
  @click="btn.action?.(); close()"
42
44
  >
43
45
  <span class="layout-burger__button-icon">
@@ -47,7 +49,7 @@
47
49
  />
48
50
  </span>
49
51
  {{ t(btn.label) }}
50
- </button>
52
+ </component>
51
53
  </div>
52
54
 
53
55
  <nav class="layout-burger__nav">
@@ -84,6 +86,7 @@
84
86
  </template>
85
87
 
86
88
  <script setup lang="ts">
89
+ import { NuxtLink } from '#components';
87
90
  import { AuthSteps, onBackdropClick, checkDeviceWidth } from '../../runtime';
88
91
  import type { IProfileData } from '../../types';
89
92
  import { CSS_BREAKPOINTS } from '../../config/css-breakpoints';
@@ -158,7 +161,9 @@ function logOut() {
158
161
  useUser(AuthorizationApiService).signOut();
159
162
  }
160
163
 
161
- const burgerButtons = computed(() => [
164
+ const featureFlags = useRuntimeConfig().public.featureFlags;
165
+
166
+ const burgerButtons = computed<{ icon: string, label: string, action?: () => void, link?: string }[]>(() => [
162
167
  ...isAuthorized.value ? [
163
168
  {
164
169
  icon: 'logout',
@@ -178,10 +183,13 @@ const burgerButtons = computed(() => [
178
183
  action: () => openAuthPopup(AuthSteps.Login),
179
184
  },
180
185
  ],
181
- {
182
- icon: 'upload',
183
- label: 'upload'
184
- },
186
+ ...featureFlags.FeatureUploadEnabled ? [
187
+ {
188
+ icon: 'upload',
189
+ label: 'upload',
190
+ link: generateLink('/upload'),
191
+ }
192
+ ] : [],
185
193
  ]);
186
194
 
187
195
  const router = useRouter();
@@ -82,13 +82,16 @@ function handler() {
82
82
  background-color: $footer-language-bg;
83
83
  color: $footer-language-text;
84
84
 
85
- @include hover(background-color) {
85
+ @include hover(background-color, color) {
86
+ color: $footer-language-text--hover;
86
87
  background-color: $footer-language-bg--hover;
87
88
  }
88
89
  }
89
90
 
90
91
  .layout-footer-language__badge {
91
92
  @include locale-badge;
93
+
94
+ color: $footer-language-badge;
92
95
  }
93
96
 
94
97
  .layout-footer-language__angle {