itube-specs 0.0.902 → 0.0.910
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/assets/icons/common/flag.svg +1 -1
- package/assets/icons/common/heart-stroke.svg +1 -1
- package/assets/icons/common/heart.svg +1 -1
- package/assets/icons/common/share.svg +1 -1
- package/assets/icons/common/thumbs-down-filled.svg +1 -0
- package/assets/icons/common/thumbs-down.svg +1 -1
- package/assets/icons/common/thumbs-up-filled.svg +1 -0
- package/assets/icons/common/thumbs-up.svg +1 -1
- package/assets/scss/themes/dark/_theme.scss +49 -19
- package/assets/scss/themes/light/_theme.scss +46 -16
- package/assets/scss/vars/_palette.scss +5 -0
- package/assets/scss/vars/_vars.scss +1 -0
- package/components/auth/login.vue +2 -2
- package/components/auth/recovery.vue +2 -2
- package/components/auth/register.vue +2 -2
- package/components/card/collections-more.vue +133 -0
- package/components/card/playlist.vue +6 -1
- package/components/grid/playlists.vue +3 -0
- package/components/info/main.vue +18 -14
- package/components/library/feed.vue +20 -39
- package/components/library/follows.vue +19 -4
- package/components/player/interface.vue +132 -58
- package/components/player/like.vue +82 -60
- package/components/playlist/add.vue +2 -2
- package/components/playlist/delete-video.vue +2 -2
- package/components/playlist/edit.vue +3 -3
- package/components/profile/delete.vue +2 -2
- package/components/profile/setup.vue +2 -2
- package/components/report/main.vue +9 -4
- package/components/search/input.vue +9 -9
- package/components/section/collections.vue +110 -0
- package/components/ui/follow-btn.vue +162 -0
- package/components/ui/section-title.vue +2 -0
- package/components/ui/snackbar.vue +93 -44
- package/composables/__tests__/use-snackbar.test.ts +126 -20
- package/composables/use-snackbar.ts +75 -20
- package/composables/use-user.ts +4 -4
- package/package.json +1 -1
- package/pages/contacts.vue +2 -2
- package/pages/library/index.vue +1 -1
- package/pages/playlists/index.vue +55 -4
- package/assets/icons/common/crest-in-circle.svg +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg fill="none" stroke="currentColor" stroke-width="2"
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528"></path></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"></path></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg fill="currentColor"
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"></path></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg fill="none" stroke="currentColor" stroke-width="2"
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"></line><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"></line></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"></path><path d="M17 14V2"></path></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"></path><path d="M17 14V2"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"></path><path d="M7 10v12"></path></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"></path><path d="M7 10v12"></path></svg>
|
|
@@ -43,7 +43,7 @@ $nav-border--hover: transparent;
|
|
|
43
43
|
$nav-border: $color-zinc-700-50;
|
|
44
44
|
$nav-icon: $color-zinc-400;
|
|
45
45
|
$nav-icon-accent: $color-red-400;
|
|
46
|
-
$nav-icon--active: $
|
|
46
|
+
$nav-icon--active: $color-zinc-400;
|
|
47
47
|
$nav-container-bg: $color-black;
|
|
48
48
|
$nav-down-icon: $color-zinc-500;
|
|
49
49
|
$nav-menu-bg: $color-zinc-900;
|
|
@@ -105,7 +105,7 @@ $count-bg: $color-zinc-800;
|
|
|
105
105
|
$count-text: $color-zinc-400;
|
|
106
106
|
|
|
107
107
|
// ─── Search ───
|
|
108
|
-
$search-bg: $color-zinc-800;
|
|
108
|
+
$search-bg: $color-zinc-800-50;
|
|
109
109
|
$search-text: $color-white;
|
|
110
110
|
$search-bg--mobile: $color-zinc-800;
|
|
111
111
|
$search-border--active--mobile: $color-indigo-500;
|
|
@@ -119,7 +119,7 @@ $search-button-bg: $color-indigo-600;
|
|
|
119
119
|
$search-button-bg--hover: $color-indigo-500;
|
|
120
120
|
$search-max-width: 500px;
|
|
121
121
|
$search-max-width-md: 672px;
|
|
122
|
-
$search-mobile-bg: $
|
|
122
|
+
$search-mobile-bg: $color-neutral-940-95;
|
|
123
123
|
$search-mobile-border: $color-zinc-800;
|
|
124
124
|
$search-mobile-decorate: $mono-black-50;
|
|
125
125
|
$search-mobile-button: $color-zinc-200;
|
|
@@ -230,6 +230,13 @@ $video-info-description-text: $color-zinc-400;
|
|
|
230
230
|
// ─── Video interface ───
|
|
231
231
|
$video-interface-button-bg: $color-zinc-800;
|
|
232
232
|
$video-interface-button-text: $color-zinc-400;
|
|
233
|
+
$video-interface-button-bg--hover: $color-zinc-700;
|
|
234
|
+
$video-interface-button-text--hover: $color-white;
|
|
235
|
+
$video-interface-button-bg--active: $color-zinc-700;
|
|
236
|
+
$video-interface-button-text--active: $color-white;
|
|
237
|
+
$video-interface-mobile-icon: $color-white;
|
|
238
|
+
$video-interface-mobile-label: $color-zinc-300;
|
|
239
|
+
$video-interface-mobile-border: $color-zinc-800;
|
|
233
240
|
|
|
234
241
|
// ─── Video channel ───
|
|
235
242
|
$video-channel-bg: $color-zinc-800-60;
|
|
@@ -283,11 +290,12 @@ $video-playlist-header-button-text--active: $color-indigo-400;
|
|
|
283
290
|
$video-playlist-header-button-bg--active: $color-indigo-500-10;
|
|
284
291
|
|
|
285
292
|
// ─── Like ───
|
|
286
|
-
$like-text: $color-zinc-400;
|
|
287
293
|
$like-icon: $color-zinc-400;
|
|
288
|
-
$like-
|
|
289
|
-
$like-icon--active: $color-
|
|
290
|
-
$like-
|
|
294
|
+
$like-icon--hover: $color-white;
|
|
295
|
+
$like-icon--active: $color-white;
|
|
296
|
+
$like-count: $color-zinc-500;
|
|
297
|
+
$like-mobile-icon: $color-white;
|
|
298
|
+
$like-mobile-count: $color-zinc-300;
|
|
291
299
|
$like-bar-bg: $color-zinc-700;
|
|
292
300
|
$like-bar-likes: $color-zinc-500;
|
|
293
301
|
|
|
@@ -460,18 +468,29 @@ $dropdown-crest: $color-zinc-500;
|
|
|
460
468
|
$dropdown-separator: $color-zinc-800-60;
|
|
461
469
|
|
|
462
470
|
// ─── Snackbar ───
|
|
471
|
+
$snackbar-bg: $color-zinc-800;
|
|
472
|
+
$snackbar-border: $color-zinc-700;
|
|
463
473
|
$snackbar-text: $color-zinc-200;
|
|
464
|
-
$snackbar-
|
|
465
|
-
$snackbar-
|
|
466
|
-
$snackbar-
|
|
467
|
-
$snackbar-
|
|
468
|
-
$snackbar-
|
|
469
|
-
$snackbar-
|
|
470
|
-
$snackbar-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
$
|
|
474
|
-
$
|
|
474
|
+
$snackbar-highlight: $color-white;
|
|
475
|
+
$snackbar-icon: $color-zinc-300;
|
|
476
|
+
$snackbar-icon-bg: $color-zinc-700-60;
|
|
477
|
+
$snackbar-shadow: 0 10px 15px -3px #{$mono-black-25}, 0 4px 6px -4px #{$mono-black-25};
|
|
478
|
+
$snackbar-action-bg: $color-indigo-600;
|
|
479
|
+
$snackbar-action-bg--hover: $color-indigo-500;
|
|
480
|
+
$snackbar-action-text: $color-white;
|
|
481
|
+
|
|
482
|
+
// ─── Follow button ───
|
|
483
|
+
$follow-btn-bg: $color-indigo-600;
|
|
484
|
+
$follow-btn-bg--hover: $color-indigo-500;
|
|
485
|
+
$follow-btn-border: $color-indigo-500;
|
|
486
|
+
$follow-btn-border--hover: $color-indigo-500;
|
|
487
|
+
$follow-btn-text: $color-white;
|
|
488
|
+
$follow-btn-following-bg: $color-zinc-800;
|
|
489
|
+
$follow-btn-following-bg--hover: $color-red-600;
|
|
490
|
+
$follow-btn-following-border: $color-zinc-800;
|
|
491
|
+
$follow-btn-following-border--hover: $color-red-500;
|
|
492
|
+
$follow-btn-following-text: $color-white;
|
|
493
|
+
$follow-btn-following-text--hover: $color-white;
|
|
475
494
|
|
|
476
495
|
// ─── Button ───
|
|
477
496
|
$button-primary-bg: $color-indigo-600;
|
|
@@ -846,6 +865,18 @@ $playlist-card-placeholder-bg: $color-zinc-700;
|
|
|
846
865
|
$playlist-card-dropdown-icon: $color-zinc-500;
|
|
847
866
|
$playlist-card-dropdown-icon--hover: $color-white;
|
|
848
867
|
|
|
868
|
+
// ─── Collections section ───
|
|
869
|
+
$collections-badge-text: $color-indigo-300;
|
|
870
|
+
$collections-badge-bg: $color-indigo-500-20;
|
|
871
|
+
$collections-badge-border: $color-indigo-500-40;
|
|
872
|
+
$collections-more-bg: $color-zinc-800;
|
|
873
|
+
$collections-more-border: $color-zinc-800-50;
|
|
874
|
+
$collections-more-border--hover: $color-zinc-700;
|
|
875
|
+
$collections-more-scrim: $color-black-50;
|
|
876
|
+
$collections-more-scrim--hover: $color-black-42;
|
|
877
|
+
$collections-more-count: $color-white;
|
|
878
|
+
$collections-more-text: $color-zinc-200;
|
|
879
|
+
|
|
849
880
|
// ─── Channel card ───
|
|
850
881
|
$channel-card-border: $color-zinc-800-50;
|
|
851
882
|
$channel-card-bg: $color-zinc-800-50;
|
|
@@ -978,7 +1009,6 @@ $library-item-badge-bordered-text: $color-zinc-400;
|
|
|
978
1009
|
// ─── Library feed (блок подписки: модель / канал / категория) ───
|
|
979
1010
|
$library-feed-bg: $color-zinc-900-40;
|
|
980
1011
|
$library-feed-border: $color-zinc-800;
|
|
981
|
-
$library-feed-fade: $color-zinc-950;
|
|
982
1012
|
$library-feed-avatar-border: $color-zinc-700;
|
|
983
1013
|
$library-feed-avatar-border--hover: $color-zinc-500;
|
|
984
1014
|
$library-feed-initials: $color-zinc-400;
|
|
@@ -287,6 +287,13 @@ $video-info-description-text: $color-gray-700;
|
|
|
287
287
|
// ─── Video interface ───
|
|
288
288
|
$video-interface-button-bg: $color-slate-750;
|
|
289
289
|
$video-interface-button-text: $color-gray-400;
|
|
290
|
+
$video-interface-button-bg--hover: $color-slate-700;
|
|
291
|
+
$video-interface-button-text--hover: $color-white;
|
|
292
|
+
$video-interface-button-bg--active: $color-slate-700;
|
|
293
|
+
$video-interface-button-text--active: $color-white;
|
|
294
|
+
$video-interface-mobile-icon: $color-gray-900;
|
|
295
|
+
$video-interface-mobile-label: $color-gray-500;
|
|
296
|
+
$video-interface-mobile-border: $color-gray-200;
|
|
290
297
|
|
|
291
298
|
// ─── Video channel ───
|
|
292
299
|
$video-channel-bg: $color-gray-200;
|
|
@@ -340,11 +347,12 @@ $video-playlist-header-button-text--active: $color-indigo-soft;
|
|
|
340
347
|
$video-playlist-header-button-bg--active: $color-indigo-500-10;
|
|
341
348
|
|
|
342
349
|
// ─── Like ───
|
|
343
|
-
$like-text: $color-gray-400;
|
|
344
350
|
$like-icon: $color-gray-500;
|
|
345
|
-
$like-
|
|
346
|
-
$like-icon--active: $color-
|
|
347
|
-
$like-
|
|
351
|
+
$like-icon--hover: $color-gray-900;
|
|
352
|
+
$like-icon--active: $color-gray-900;
|
|
353
|
+
$like-count: $color-gray-400;
|
|
354
|
+
$like-mobile-icon: $color-gray-900;
|
|
355
|
+
$like-mobile-count: $color-gray-500;
|
|
348
356
|
$like-bar-bg: $color-slate-700;
|
|
349
357
|
$like-bar-likes: $color-gray-500;
|
|
350
358
|
|
|
@@ -515,18 +523,29 @@ $dropdown-crest: $color-gray-400;
|
|
|
515
523
|
$dropdown-separator: $color-slate-750;
|
|
516
524
|
|
|
517
525
|
// ─── Snackbar ───
|
|
526
|
+
$snackbar-bg: $color-slate-800;
|
|
527
|
+
$snackbar-border: $color-slate-750;
|
|
518
528
|
$snackbar-text: $color-gray-200;
|
|
519
|
-
$snackbar-
|
|
520
|
-
$snackbar-
|
|
521
|
-
$snackbar-
|
|
522
|
-
$snackbar-
|
|
523
|
-
$snackbar-
|
|
524
|
-
$snackbar-
|
|
525
|
-
$snackbar-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
$
|
|
529
|
-
$
|
|
529
|
+
$snackbar-highlight: $color-white;
|
|
530
|
+
$snackbar-icon: $color-gray-300;
|
|
531
|
+
$snackbar-icon-bg: $color-slate-700;
|
|
532
|
+
$snackbar-shadow: 0 10px 15px -3px #{$mono-black-25}, 0 4px 6px -4px #{$mono-black-25};
|
|
533
|
+
$snackbar-action-bg: $color-indigo-600;
|
|
534
|
+
$snackbar-action-bg--hover: $color-indigo-500;
|
|
535
|
+
$snackbar-action-text: $color-white;
|
|
536
|
+
|
|
537
|
+
// ─── Follow button ───
|
|
538
|
+
$follow-btn-bg: $color-indigo-600;
|
|
539
|
+
$follow-btn-bg--hover: $color-indigo-500;
|
|
540
|
+
$follow-btn-border: $color-indigo-500;
|
|
541
|
+
$follow-btn-border--hover: $color-indigo-500;
|
|
542
|
+
$follow-btn-text: $color-white;
|
|
543
|
+
$follow-btn-following-bg: $color-gray-300;
|
|
544
|
+
$follow-btn-following-bg--hover: $color-red-500;
|
|
545
|
+
$follow-btn-following-border: $color-gray-300;
|
|
546
|
+
$follow-btn-following-border--hover: $color-red-500;
|
|
547
|
+
$follow-btn-following-text: $color-gray-700;
|
|
548
|
+
$follow-btn-following-text--hover: $color-white;
|
|
530
549
|
|
|
531
550
|
// ─── Button ───
|
|
532
551
|
$button-primary-bg: $color-indigo-600;
|
|
@@ -874,6 +893,18 @@ $playlist-card-placeholder-bg: $color-gray-300;
|
|
|
874
893
|
$playlist-card-dropdown-icon: $color-gray-600;
|
|
875
894
|
$playlist-card-dropdown-icon--hover: $color-gray-900;
|
|
876
895
|
|
|
896
|
+
// ─── Collections section ───
|
|
897
|
+
$collections-badge-text: $color-indigo-600;
|
|
898
|
+
$collections-badge-bg: $color-indigo-500-10;
|
|
899
|
+
$collections-badge-border: $color-indigo-500-20;
|
|
900
|
+
$collections-more-bg: $color-gray-300;
|
|
901
|
+
$collections-more-border: $color-gray-300;
|
|
902
|
+
$collections-more-border--hover: $color-gray-400;
|
|
903
|
+
$collections-more-scrim: $color-black-45;
|
|
904
|
+
$collections-more-scrim--hover: $color-black-32;
|
|
905
|
+
$collections-more-count: $color-white;
|
|
906
|
+
$collections-more-text: $color-white;
|
|
907
|
+
|
|
877
908
|
// ─── Channel card ───
|
|
878
909
|
$channel-card-border: transparent;
|
|
879
910
|
$channel-card-bg: $color-gray-100;
|
|
@@ -1006,7 +1037,6 @@ $library-item-badge-bordered-text: $color-gray-600;
|
|
|
1006
1037
|
// ─── Library feed (блок подписки: модель / канал / категория) ───
|
|
1007
1038
|
$library-feed-bg: $color-gray-100;
|
|
1008
1039
|
$library-feed-border: transparent;
|
|
1009
|
-
$library-feed-fade: $color-gray-100;
|
|
1010
1040
|
$library-feed-avatar-border: $color-gray-300;
|
|
1011
1041
|
$library-feed-avatar-border--hover: $color-indigo-500-50;
|
|
1012
1042
|
$library-feed-initials: $color-gray-600;
|
|
@@ -22,6 +22,7 @@ $color-zinc-750: lab(21.3843% .9572 -2.5207); // #333337
|
|
|
22
22
|
$color-zinc-700: lab(26.8019% 1.35387 -4.68303); // #3f3f46
|
|
23
23
|
$color-zinc-700-80: lab(26.8019% 1.35387 -4.68303 / 80%); // zinc-700 / 70%
|
|
24
24
|
$color-zinc-700-70: lab(26.8019% 1.35387 -4.68303 / 70%); // zinc-700 / 70%
|
|
25
|
+
$color-zinc-700-60: lab(26.8019% 1.35387 -4.68303 / 60%); // zinc-700 / 60%
|
|
25
26
|
$color-zinc-700-50: lab(26.8019% 1.35387 -4.68303 / 50%); // zinc-700 / 50%
|
|
26
27
|
$color-zinc-700-30: lab(26.8019% 1.35387 -4.68303 / 30%); // zinc-700 / 50%
|
|
27
28
|
$color-zinc-650: lab(31.3256% 2.0703 -5.3354); // #494952
|
|
@@ -65,6 +66,10 @@ $color-indigo-800: lab(26.6645% 37.9804 -68.6402); // #372aac
|
|
|
65
66
|
$color-indigo-900: lab(23.3911% 24.6978 -50.4718); // #312c85
|
|
66
67
|
$color-indigo-950: lab(12.9255% 18.7583 -31.0075); // #1e1a4d
|
|
67
68
|
|
|
69
|
+
// Neutral gray (untinted — no zinc blue tint)
|
|
70
|
+
$color-neutral-940: lab(3.6355% 0 0); // #0d0d0d
|
|
71
|
+
$color-neutral-940-95: lab(3.6355% 0 0 / 95%); // #0d0d0d / 95%
|
|
72
|
+
|
|
68
73
|
// Monochrome black (opacity variants)
|
|
69
74
|
$mono-black-100: lab(0% 0 0);
|
|
70
75
|
$mono-black-95: lab(0% 0 0 / 95%);
|
|
@@ -94,7 +94,7 @@ function onCreateClick() {
|
|
|
94
94
|
|
|
95
95
|
const loading = ref(false);
|
|
96
96
|
|
|
97
|
-
const { setErrorState, showError,
|
|
97
|
+
const { setErrorState, showError, show, resetSnackbar } = useSnackbar();
|
|
98
98
|
|
|
99
99
|
async function login() {
|
|
100
100
|
resetSnackbar();
|
|
@@ -115,7 +115,7 @@ async function login() {
|
|
|
115
115
|
loading.value = true;
|
|
116
116
|
await useUser(AuthorizationApiService).login(form.value);
|
|
117
117
|
useAuthPopup().closeAuthPopup();
|
|
118
|
-
|
|
118
|
+
show('Welcome back!');
|
|
119
119
|
} catch (error) {
|
|
120
120
|
setErrorState(error);
|
|
121
121
|
} finally {
|
|
@@ -70,7 +70,7 @@ function onLoginClick() {
|
|
|
70
70
|
|
|
71
71
|
const loading = ref(false);
|
|
72
72
|
|
|
73
|
-
const { setErrorState, showError,
|
|
73
|
+
const { setErrorState, showError, show, resetSnackbar } = useSnackbar();
|
|
74
74
|
|
|
75
75
|
// Загружаем reCAPTCHA при открытии формы (onMounted) — даёт Google время собрать данные о поведении
|
|
76
76
|
onMounted(async () => {
|
|
@@ -97,7 +97,7 @@ async function submit() {
|
|
|
97
97
|
form.value.token = await getRecaptchaToken('password_reset');
|
|
98
98
|
await useUser(AuthorizationApiService).password(form.value);
|
|
99
99
|
useAuthPopup().closeAuthPopup();
|
|
100
|
-
|
|
100
|
+
show('Check your email');
|
|
101
101
|
} catch (error) {
|
|
102
102
|
setErrorState(error);
|
|
103
103
|
} finally {
|
|
@@ -129,7 +129,7 @@ function onLoginClick() {
|
|
|
129
129
|
|
|
130
130
|
const loading = ref(false);
|
|
131
131
|
|
|
132
|
-
const { setErrorState, showError,
|
|
132
|
+
const { setErrorState, showError, show, resetSnackbar } = useSnackbar();
|
|
133
133
|
// Загружаем reCAPTCHA при открытии формы (onMounted) — даёт Google время собрать данные о поведении
|
|
134
134
|
onMounted(async () => {
|
|
135
135
|
try {
|
|
@@ -176,7 +176,7 @@ async function submit() {
|
|
|
176
176
|
// await PlaylistsApiService.postPlaylist(FAVORITES_KEY, PlaylistType.Private);
|
|
177
177
|
|
|
178
178
|
useAuthPopup().closeAuthPopup();
|
|
179
|
-
|
|
179
|
+
show('Registration success');
|
|
180
180
|
} catch (err) {
|
|
181
181
|
setErrorState(err);
|
|
182
182
|
console.error('Ошибка reCAPTCHA или регистрации:', err);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<!-- Плитка «показать ещё» в сетке коллекций: 16 размытых обложек сеткой 4×4, поверх счётчик и подпись -->
|
|
2
|
+
<template>
|
|
3
|
+
<NuxtLink
|
|
4
|
+
:to="generateLink(to)"
|
|
5
|
+
class="card-collections-more"
|
|
6
|
+
>
|
|
7
|
+
<span
|
|
8
|
+
v-if="images.length > 0"
|
|
9
|
+
class="card-collections-more__thumbs"
|
|
10
|
+
aria-hidden="true"
|
|
11
|
+
>
|
|
12
|
+
<UiImg
|
|
13
|
+
v-for="(src, index) in images"
|
|
14
|
+
:key="`collections-more-thumb-${index}`"
|
|
15
|
+
:src="src"
|
|
16
|
+
:width="ThumbSize.Small.split('x')[0]"
|
|
17
|
+
:height="ThumbSize.Small.split('x')[1]"
|
|
18
|
+
alt=""
|
|
19
|
+
class="card-collections-more__thumb"
|
|
20
|
+
/>
|
|
21
|
+
</span>
|
|
22
|
+
|
|
23
|
+
<span class="card-collections-more__content">
|
|
24
|
+
<span
|
|
25
|
+
v-if="count"
|
|
26
|
+
class="card-collections-more__count"
|
|
27
|
+
>+{{ count }}</span>
|
|
28
|
+
<span class="card-collections-more__text">{{ text }}</span>
|
|
29
|
+
</span>
|
|
30
|
+
</NuxtLink>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { ThumbSize } from '../../runtime';
|
|
35
|
+
import type { IThumbUrls } from '../../types';
|
|
36
|
+
|
|
37
|
+
const props = defineProps<{
|
|
38
|
+
to: string
|
|
39
|
+
text: string
|
|
40
|
+
/** Обложки для мозаики: лишние отбрасываем, если меньше 16 — повторяем по кругу */
|
|
41
|
+
thumbs?: IThumbUrls[]
|
|
42
|
+
/** Сколько коллекций осталось за кадром — «+18» */
|
|
43
|
+
count?: number
|
|
44
|
+
}>();
|
|
45
|
+
|
|
46
|
+
const { generateLink } = useGenerateLink();
|
|
47
|
+
|
|
48
|
+
/** Ячеек в мозаике — сетка 4×4 */
|
|
49
|
+
const CELLS = 16;
|
|
50
|
+
|
|
51
|
+
const images = computed(() => {
|
|
52
|
+
const sources = (props.thumbs || [])
|
|
53
|
+
.map(thumb => thumb?.webp?.[ThumbSize.Small])
|
|
54
|
+
.filter((src): src is string => Boolean(src));
|
|
55
|
+
|
|
56
|
+
if (sources.length === 0) return [];
|
|
57
|
+
|
|
58
|
+
/* добиваем по кругу, чтобы мозаика всегда была полной, а не с дырами */
|
|
59
|
+
return Array.from({ length: CELLS }, (_, index) => sources[index % sources.length]);
|
|
60
|
+
});
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<style lang="scss">
|
|
64
|
+
.card-collections-more {
|
|
65
|
+
position: relative;
|
|
66
|
+
display: grid;
|
|
67
|
+
place-content: center;
|
|
68
|
+
min-height: 240px;
|
|
69
|
+
padding: 12px;
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
text-align: center;
|
|
72
|
+
border-radius: $radius-xl;
|
|
73
|
+
border: 1px solid $collections-more-border;
|
|
74
|
+
background-color: $collections-more-bg;
|
|
75
|
+
|
|
76
|
+
@include hover(border-color) {
|
|
77
|
+
border-color: $collections-more-border--hover;
|
|
78
|
+
|
|
79
|
+
&::after {
|
|
80
|
+
background-color: $collections-more-scrim--hover;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* затемнение поверх обложек — псевдоэлементом, без отдельной ноды-оверлея */
|
|
85
|
+
&::after {
|
|
86
|
+
content: '';
|
|
87
|
+
position: absolute;
|
|
88
|
+
inset: 0;
|
|
89
|
+
background-color: $collections-more-scrim;
|
|
90
|
+
transition: var(--transition) background-color;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.card-collections-more__thumbs {
|
|
95
|
+
position: absolute;
|
|
96
|
+
inset: 0;
|
|
97
|
+
display: grid;
|
|
98
|
+
|
|
99
|
+
/* minmax(0, 1fr), иначе auto-минимум трека = min-content картинки и сетка распирает блок */
|
|
100
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
101
|
+
grid-template-rows: repeat(4, minmax(0, 1fr));
|
|
102
|
+
gap: 2px;
|
|
103
|
+
filter: blur(12px);
|
|
104
|
+
transform: scale(1.1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.card-collections-more__thumb {
|
|
108
|
+
width: 100%;
|
|
109
|
+
height: 100%;
|
|
110
|
+
object-fit: cover;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.card-collections-more__content {
|
|
114
|
+
position: relative;
|
|
115
|
+
z-index: $z-index-plus;
|
|
116
|
+
display: grid;
|
|
117
|
+
row-gap: 2px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.card-collections-more__count {
|
|
121
|
+
@include font-2xl;
|
|
122
|
+
|
|
123
|
+
font-weight: 700;
|
|
124
|
+
color: $collections-more-count;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.card-collections-more__text {
|
|
128
|
+
@include font-sm;
|
|
129
|
+
|
|
130
|
+
font-weight: 500;
|
|
131
|
+
color: $collections-more-text;
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -107,7 +107,10 @@
|
|
|
107
107
|
<p class="card-playlist__user">
|
|
108
108
|
{{ card.username }}
|
|
109
109
|
</p>
|
|
110
|
-
<div
|
|
110
|
+
<div
|
|
111
|
+
v-if="!noActions"
|
|
112
|
+
class="card-playlist__content-wrapper"
|
|
113
|
+
>
|
|
111
114
|
<UiDropdown
|
|
112
115
|
ref="dropdownRef"
|
|
113
116
|
right
|
|
@@ -177,6 +180,8 @@ import { CSS_BREAKPOINTS } from '../../config/css-breakpoints';
|
|
|
177
180
|
const props = defineProps<{
|
|
178
181
|
card: IPlaylistCard
|
|
179
182
|
topPlaylists?: boolean
|
|
183
|
+
/** Без меню «три точки» — вместе с ним уходят share и report */
|
|
184
|
+
noActions?: boolean
|
|
180
185
|
priority?: boolean
|
|
181
186
|
}>();
|
|
182
187
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:key="`user-playlist-${index}`"
|
|
7
7
|
:card="item"
|
|
8
8
|
:top-playlists="topPlaylists"
|
|
9
|
+
:no-actions="noActions"
|
|
9
10
|
:priority="priority && index === 0"
|
|
10
11
|
@share="onShare"
|
|
11
12
|
/>
|
|
@@ -32,6 +33,8 @@ import type { IPlaylistCard } from '../../types';
|
|
|
32
33
|
defineProps<{
|
|
33
34
|
items: IPlaylistCard[]
|
|
34
35
|
topPlaylists?: boolean
|
|
36
|
+
/** Скрыть меню карточки (три точки: share/report) — например у редакционных подборок */
|
|
37
|
+
noActions?: boolean
|
|
35
38
|
priority?: boolean
|
|
36
39
|
}>();
|
|
37
40
|
|
package/components/info/main.vue
CHANGED
|
@@ -30,19 +30,6 @@
|
|
|
30
30
|
class="info-main__count"
|
|
31
31
|
icon="video-camera"
|
|
32
32
|
>{{ videosCount || card.videosCount }}</UiCount>
|
|
33
|
-
<UiBtn
|
|
34
|
-
v-if="featureFlags.FeatureFollowEnabled"
|
|
35
|
-
theme="muted"
|
|
36
|
-
class="info-main__header-button"
|
|
37
|
-
size="s"
|
|
38
|
-
@click="onFollowClick"
|
|
39
|
-
>
|
|
40
|
-
<UiIcon
|
|
41
|
-
name="plus"
|
|
42
|
-
size="16"
|
|
43
|
-
/>
|
|
44
|
-
{{ t('follow') }}
|
|
45
|
-
</UiBtn>
|
|
46
33
|
<UiBtn
|
|
47
34
|
theme="muted"
|
|
48
35
|
size="s"
|
|
@@ -55,6 +42,14 @@
|
|
|
55
42
|
/>
|
|
56
43
|
{{ t('share') }}
|
|
57
44
|
</UiBtn>
|
|
45
|
+
<UiFollowBtn
|
|
46
|
+
v-if="featureFlags.FeatureFollowEnabled"
|
|
47
|
+
:following="isFollowing"
|
|
48
|
+
:name="title"
|
|
49
|
+
class="info-main__header-follow"
|
|
50
|
+
size="s"
|
|
51
|
+
@toggle="onFollowClick"
|
|
52
|
+
/>
|
|
58
53
|
</div>
|
|
59
54
|
</div>
|
|
60
55
|
|
|
@@ -190,9 +185,12 @@ function showParameters() {
|
|
|
190
185
|
|
|
191
186
|
const authPopupText = 'register_first';
|
|
192
187
|
|
|
188
|
+
/** Заглушка вместо ручки подписки: состояние живёт только в компоненте, на бэк ничего не уходит */
|
|
189
|
+
const isFollowing = ref(false);
|
|
190
|
+
|
|
193
191
|
function onFollowClick() {
|
|
194
192
|
if (isAuthorized.value) {
|
|
195
|
-
|
|
193
|
+
isFollowing.value = !isFollowing.value;
|
|
196
194
|
} else {
|
|
197
195
|
openAuthPopup(AuthSteps.Login, authPopupText);
|
|
198
196
|
}
|
|
@@ -464,4 +462,10 @@ const socialItems = computed<ILinkItem[]>(() => {
|
|
|
464
462
|
.info-main__header-button {
|
|
465
463
|
@include button-variant(info-button);
|
|
466
464
|
}
|
|
465
|
+
|
|
466
|
+
.info-main__header-follow {
|
|
467
|
+
@include to-br(sm) {
|
|
468
|
+
margin-inline-start: auto;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
467
471
|
</style>
|