itube-specs 0.0.899 → 0.0.904
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/clock-filled.svg +1 -0
- 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/playlist.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/mixins/_breakpoints.scss +3 -2
- package/assets/scss/themes/dark/_theme.scss +29 -27
- package/assets/scss/themes/light/_theme.scss +29 -27
- package/assets/scss/vars/_palette.scss +1 -0
- package/components/card/category.vue +4 -8
- package/components/card/dropdown/index.vue +47 -9
- package/components/card/dropdown/trigger.vue +1 -0
- package/components/card/model.vue +1 -1
- package/components/card/playlist.vue +15 -6
- package/components/card/round.vue +3 -3
- package/components/card/video/actions.vue +123 -0
- package/components/card/video/index.vue +149 -30
- package/components/filter/selects.vue +1 -1
- package/components/info/grid.vue +1 -1
- package/components/layout/header-user.vue +1 -1
- package/components/library/feed.vue +65 -24
- package/components/library/follows.vue +8 -44
- package/components/library/item.vue +4 -4
- package/components/player/interface.vue +132 -58
- package/components/player/like.vue +81 -59
- package/components/player/playlist.vue +2 -2
- package/components/report/main.vue +20 -5
- package/components/ui/checkbox.vue +1 -1
- package/components/ui/dropdown.vue +1 -1
- package/components/ui/input.vue +2 -2
- package/components/ui/radio.vue +1 -1
- package/components/ui/toggle.vue +1 -1
- package/composables/use-report-popup.ts +26 -3
- package/composables/use-video-collections.ts +30 -0
- package/lib/scheme/profile-navigation-items.ts +1 -1
- package/package.json +1 -1
- package/pages/history.vue +12 -36
- package/pages/library/categories.vue +2 -1
- package/pages/library/channels.vue +1 -1
- package/pages/library/index.vue +3 -3
- package/pages/library/models.vue +4 -4
- package/stubs/library-follows.ts +19 -16
- package/types/library-feed.d.ts +6 -0
- package/types/video-card.d.ts +4 -0
- package/assets/icons/common/crest-in-circle.svg +0 -1
- package/components/card/history.vue +0 -359
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><mask id="clock-filled-hands"><rect width="24" height="24" fill="#fff"/><path d="M12 6v6l4 2" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></mask><circle cx="12" cy="12" r="10" fill="currentColor" mask="url(#clock-filled-hands)"/></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"><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 viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 5H3"></path><path d="M10 12H3"></path><path d="M10 19H3"></path><path d="M15 12.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997a1 1 0 0 1-1.517-.86z"></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>
|
|
@@ -77,12 +77,13 @@ $brkpnts: (
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
Hover с transition
|
|
80
|
+
Hover с transition. Условие — наличие наведения у устройства, а не ширина окна: на тач-экране
|
|
81
|
+
hover «залипает» после тапа и его правда не нужно, а вот узкому окну с мышью он нужен.
|
|
81
82
|
@include hover(background-color) { background-color: red; }
|
|
82
83
|
@include hover(background-color, color) { background-color: red; color: white; }
|
|
83
84
|
*/
|
|
84
85
|
@mixin hover($properties...) {
|
|
85
|
-
@
|
|
86
|
+
@media (hover: hover) {
|
|
86
87
|
$transitions: ();
|
|
87
88
|
|
|
88
89
|
@each $prop in $properties {
|
|
@@ -197,30 +197,26 @@ $video-card-text: $color-white;
|
|
|
197
197
|
$video-card-text--hover: $color-indigo-400;
|
|
198
198
|
$video-card-dropdown-icon: $color-zinc-500;
|
|
199
199
|
$video-card-dropdown-icon--hover: $color-white;
|
|
200
|
-
$video-card-resolution-bg: $color-green-500;
|
|
201
|
-
$video-card-resolution-text: $mono-black-100;
|
|
202
200
|
$video-card-secondary: $color-zinc-500;
|
|
203
201
|
$video-card-mini-title: $color-zinc-300;
|
|
204
202
|
$video-card-mini-weight: 400;
|
|
205
203
|
$video-card-user-text: $color-zinc-400;
|
|
206
204
|
$video-card-user-bg: $color-zinc-700;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
$
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
$
|
|
213
|
-
$
|
|
214
|
-
$
|
|
215
|
-
$
|
|
216
|
-
$
|
|
217
|
-
$
|
|
218
|
-
$
|
|
219
|
-
$
|
|
220
|
-
$
|
|
221
|
-
$
|
|
222
|
-
$history-card-progress-fill: $color-indigo-500;
|
|
223
|
-
$history-card-remaining: $color-indigo-400;
|
|
205
|
+
$video-card-progress-bg: $mono-white-50;
|
|
206
|
+
$video-card-progress-fill: $color-indigo-500;
|
|
207
|
+
$video-card-remaining: $color-indigo-400;
|
|
208
|
+
|
|
209
|
+
// ─── Video card actions (избранное / смотреть позже на постере) ───
|
|
210
|
+
$video-card-action-bg: $color-zinc-900-70;
|
|
211
|
+
$video-card-action-bg--hover: $color-zinc-800;
|
|
212
|
+
$video-card-action-border: $color-zinc-800-60;
|
|
213
|
+
$video-card-action-icon: $color-zinc-300;
|
|
214
|
+
$video-card-action-active-bg: $color-zinc-800;
|
|
215
|
+
$video-card-action-active-bg--hover: $color-red-600;
|
|
216
|
+
$video-card-action-active-border: $color-zinc-800;
|
|
217
|
+
$video-card-action-active-border--hover: $color-red-600;
|
|
218
|
+
$video-card-action-active-icon: $color-white;
|
|
219
|
+
$video-card-action-active-icon--hover: $color-white;
|
|
224
220
|
|
|
225
221
|
// ─── Video card dropdown ───
|
|
226
222
|
$video-card-dropdown-border: $color-zinc-800;
|
|
@@ -234,6 +230,13 @@ $video-info-description-text: $color-zinc-400;
|
|
|
234
230
|
// ─── Video interface ───
|
|
235
231
|
$video-interface-button-bg: $color-zinc-800;
|
|
236
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;
|
|
237
240
|
|
|
238
241
|
// ─── Video channel ───
|
|
239
242
|
$video-channel-bg: $color-zinc-800-60;
|
|
@@ -287,11 +290,12 @@ $video-playlist-header-button-text--active: $color-indigo-400;
|
|
|
287
290
|
$video-playlist-header-button-bg--active: $color-indigo-500-10;
|
|
288
291
|
|
|
289
292
|
// ─── Like ───
|
|
290
|
-
$like-text: $color-zinc-400;
|
|
291
293
|
$like-icon: $color-zinc-400;
|
|
292
|
-
$like-
|
|
293
|
-
$like-icon--active: $color-
|
|
294
|
-
$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;
|
|
295
299
|
$like-bar-bg: $color-zinc-700;
|
|
296
300
|
$like-bar-likes: $color-zinc-500;
|
|
297
301
|
|
|
@@ -992,18 +996,16 @@ $library-feed-name: $color-white;
|
|
|
992
996
|
$library-feed-name--hover: $color-indigo-400;
|
|
993
997
|
$library-feed-badge-bg: $color-indigo-600;
|
|
994
998
|
$library-feed-badge-text: $color-white;
|
|
999
|
+
$library-feed-params: $color-zinc-400;
|
|
1000
|
+
$library-feed-age: $color-zinc-500;
|
|
995
1001
|
$library-feed-meta: $color-zinc-500;
|
|
996
1002
|
$library-feed-meta-dot: $color-zinc-600;
|
|
997
1003
|
$library-feed-title: $color-zinc-500;
|
|
998
1004
|
|
|
999
1005
|
// ─── Page: library ───
|
|
1000
1006
|
$page-library-toggle-text: $color-zinc-300;
|
|
1001
|
-
$page-library-confirm-text: $color-zinc-300;
|
|
1002
1007
|
|
|
1003
1008
|
// ─── Page: history ───
|
|
1004
|
-
$page-history-group-title: $color-zinc-300;
|
|
1005
|
-
$page-history-group-icon: $color-zinc-500;
|
|
1006
|
-
$page-history-group-count: $color-zinc-500;
|
|
1007
1009
|
$page-history-confirm-text: $color-zinc-300;
|
|
1008
1010
|
$page-history-confirm-muted: $color-zinc-500;
|
|
1009
1011
|
$page-history-confirm-link: $color-indigo-400;
|
|
@@ -254,31 +254,27 @@ $video-card-text: $color-gray-900;
|
|
|
254
254
|
$video-card-text--hover: $color-gray-900;
|
|
255
255
|
$video-card-dropdown-icon: $color-gray-600;
|
|
256
256
|
$video-card-dropdown-icon--hover: $color-gray-900;
|
|
257
|
-
$video-card-resolution-bg: $color-green-500;
|
|
258
|
-
$video-card-resolution-text: $mono-black-100;
|
|
259
257
|
$video-card-secondary: $color-gray-600;
|
|
260
258
|
$video-card-mini-title: $color-gray-900;
|
|
261
259
|
$video-card-mini-weight: 500;
|
|
262
260
|
$video-card-user-text: $color-gray-700;
|
|
263
261
|
$video-card-user-bg: $color-gray-300;
|
|
264
262
|
$video-card-dropdown-size--hover: 1.25;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
$
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
$
|
|
271
|
-
$
|
|
272
|
-
$
|
|
273
|
-
$
|
|
274
|
-
$
|
|
275
|
-
$
|
|
276
|
-
$
|
|
277
|
-
$
|
|
278
|
-
$
|
|
279
|
-
$
|
|
280
|
-
$history-card-progress-fill: $color-indigo-500;
|
|
281
|
-
$history-card-remaining: $color-indigo-600;
|
|
263
|
+
$video-card-progress-bg: $color-gray-300;
|
|
264
|
+
$video-card-progress-fill: $color-indigo-500;
|
|
265
|
+
$video-card-remaining: $color-indigo-600;
|
|
266
|
+
|
|
267
|
+
// ─── Video card actions (избранное / смотреть позже на постере) ───
|
|
268
|
+
$video-card-action-bg: $color-white-75;
|
|
269
|
+
$video-card-action-bg--hover: $color-white;
|
|
270
|
+
$video-card-action-border: $color-gray-300-50;
|
|
271
|
+
$video-card-action-icon: $color-gray-700;
|
|
272
|
+
$video-card-action-active-bg: $color-white;
|
|
273
|
+
$video-card-action-active-bg--hover: $color-red-600;
|
|
274
|
+
$video-card-action-active-border: $color-gray-300;
|
|
275
|
+
$video-card-action-active-border--hover: $color-red-600;
|
|
276
|
+
$video-card-action-active-icon: $color-gray-900;
|
|
277
|
+
$video-card-action-active-icon--hover: $color-white;
|
|
282
278
|
|
|
283
279
|
// ─── Video card dropdown ───
|
|
284
280
|
$video-card-dropdown-border: transparent;
|
|
@@ -291,6 +287,13 @@ $video-info-description-text: $color-gray-700;
|
|
|
291
287
|
// ─── Video interface ───
|
|
292
288
|
$video-interface-button-bg: $color-slate-750;
|
|
293
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;
|
|
294
297
|
|
|
295
298
|
// ─── Video channel ───
|
|
296
299
|
$video-channel-bg: $color-gray-200;
|
|
@@ -344,11 +347,12 @@ $video-playlist-header-button-text--active: $color-indigo-soft;
|
|
|
344
347
|
$video-playlist-header-button-bg--active: $color-indigo-500-10;
|
|
345
348
|
|
|
346
349
|
// ─── Like ───
|
|
347
|
-
$like-text: $color-gray-400;
|
|
348
350
|
$like-icon: $color-gray-500;
|
|
349
|
-
$like-
|
|
350
|
-
$like-icon--active: $color-
|
|
351
|
-
$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;
|
|
352
356
|
$like-bar-bg: $color-slate-700;
|
|
353
357
|
$like-bar-likes: $color-gray-500;
|
|
354
358
|
|
|
@@ -1020,18 +1024,16 @@ $library-feed-name: $color-gray-900;
|
|
|
1020
1024
|
$library-feed-name--hover: $color-indigo-600;
|
|
1021
1025
|
$library-feed-badge-bg: $color-indigo-600;
|
|
1022
1026
|
$library-feed-badge-text: $color-white;
|
|
1027
|
+
$library-feed-params: $color-gray-600;
|
|
1028
|
+
$library-feed-age: $color-gray-500;
|
|
1023
1029
|
$library-feed-meta: $color-gray-500;
|
|
1024
1030
|
$library-feed-meta-dot: $color-gray-400;
|
|
1025
1031
|
$library-feed-title: $color-gray-500;
|
|
1026
1032
|
|
|
1027
1033
|
// ─── Page: library ───
|
|
1028
1034
|
$page-library-toggle-text: $color-gray-700;
|
|
1029
|
-
$page-library-confirm-text: $color-gray-700;
|
|
1030
1035
|
|
|
1031
1036
|
// ─── Page: history ───
|
|
1032
|
-
$page-history-group-title: $color-gray-900;
|
|
1033
|
-
$page-history-group-icon: $color-gray-500;
|
|
1034
|
-
$page-history-group-count: $color-gray-500;
|
|
1035
1037
|
$page-history-confirm-text: $color-gray-900;
|
|
1036
1038
|
$page-history-confirm-muted: $color-gray-500;
|
|
1037
1039
|
$page-history-confirm-link: $color-indigo-400;
|
|
@@ -5,6 +5,7 @@ $color-zinc-950-0: lab(2.51107% .242703 -.886115 / 0%); // zinc-950 / 0%
|
|
|
5
5
|
$color-zinc-950-75: lab(2.51107% .242703 -.886115 / 75%); // zinc-950 / 75%
|
|
6
6
|
$color-zinc-950-90: lab(2.51107% .242703 -.886115 / 90%); // zinc-950 / 90%
|
|
7
7
|
$color-zinc-900: lab(8.30603% .618205 -2.16572); // #18181b
|
|
8
|
+
$color-zinc-900-70: lab(8.30603% .618205 -2.16572 / 70%); // zinc-900 / 70%
|
|
8
9
|
$color-zinc-900-60: lab(8.30603% .618205 -2.16572 / 60%); // zinc-900 / 60%
|
|
9
10
|
$color-zinc-900-50: lab(8.30603% .618205 -2.16572 / 50%); // #18181b
|
|
10
11
|
$color-zinc-900-40: lab(8.30603% .618205 -2.16572 / 40%); // zinc-900 / 40%
|
|
@@ -85,12 +85,8 @@ const slug = computed(() => {
|
|
|
85
85
|
padding: 2px;
|
|
86
86
|
border-radius: $radius-xl;
|
|
87
87
|
|
|
88
|
-
@include
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
&:is(:hover, :focus-visible) {
|
|
92
|
-
box-shadow: $card-ring-shadow--hover;
|
|
93
|
-
}
|
|
88
|
+
@include hover(box-shadow) {
|
|
89
|
+
box-shadow: $card-ring-shadow--hover;
|
|
94
90
|
}
|
|
95
91
|
}
|
|
96
92
|
|
|
@@ -117,7 +113,7 @@ const slug = computed(() => {
|
|
|
117
113
|
text-overflow: ellipsis;
|
|
118
114
|
color: $category-card-title;
|
|
119
115
|
|
|
120
|
-
@
|
|
116
|
+
@media (hover: hover) {
|
|
121
117
|
transition: var(--transition) color;
|
|
122
118
|
}
|
|
123
119
|
}
|
|
@@ -132,7 +128,7 @@ const slug = computed(() => {
|
|
|
132
128
|
}
|
|
133
129
|
|
|
134
130
|
.card-category:is(:hover, :focus-visible) .card-category__title {
|
|
135
|
-
@
|
|
131
|
+
@media (hover: hover) {
|
|
136
132
|
color: $category-card-title--hover;
|
|
137
133
|
}
|
|
138
134
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Дропдаун-меню видео: добавить в плейлист,
|
|
1
|
+
<!-- Дропдаун-меню видео: смотреть позже, избранное, добавить в плейлист, поделиться, пожаловаться -->
|
|
2
2
|
<template>
|
|
3
3
|
<UiDropdown
|
|
4
4
|
ref="dropdownRef"
|
|
@@ -28,27 +28,39 @@
|
|
|
28
28
|
</template>
|
|
29
29
|
<template #items="className">
|
|
30
30
|
<button
|
|
31
|
+
v-if="showWatchLater"
|
|
31
32
|
:class="className"
|
|
32
33
|
type="button"
|
|
33
|
-
@click="
|
|
34
|
+
@click="toggleWatchLater(card.guid)"
|
|
34
35
|
>
|
|
35
36
|
<UiIcon
|
|
36
|
-
name="
|
|
37
|
+
name="clock"
|
|
37
38
|
size="20"
|
|
38
39
|
/>
|
|
39
|
-
{{
|
|
40
|
+
{{ watchLaterLabel }}
|
|
40
41
|
</button>
|
|
41
42
|
<button
|
|
42
|
-
v-if="
|
|
43
|
+
v-if="showFavorites"
|
|
43
44
|
:class="className"
|
|
44
45
|
type="button"
|
|
45
|
-
@click="
|
|
46
|
+
@click="toggleFavorite(card.guid)"
|
|
46
47
|
>
|
|
47
48
|
<UiIcon
|
|
48
|
-
name="
|
|
49
|
+
name="heart-stroke"
|
|
49
50
|
size="20"
|
|
50
51
|
/>
|
|
51
|
-
{{
|
|
52
|
+
{{ favoritesLabel }}
|
|
53
|
+
</button>
|
|
54
|
+
<button
|
|
55
|
+
:class="className"
|
|
56
|
+
type="button"
|
|
57
|
+
@click="onAddPlaylist"
|
|
58
|
+
>
|
|
59
|
+
<UiIcon
|
|
60
|
+
name="playlist"
|
|
61
|
+
size="20"
|
|
62
|
+
/>
|
|
63
|
+
{{ $t('add_to_playlist') }}
|
|
52
64
|
</button>
|
|
53
65
|
<button
|
|
54
66
|
v-if="showShare"
|
|
@@ -97,6 +109,7 @@ import { AuthorizationApiService } from '../../../services/api/authorization.ser
|
|
|
97
109
|
const props = defineProps<{
|
|
98
110
|
card: IVideoCard
|
|
99
111
|
showWatchLater?: boolean
|
|
112
|
+
showFavorites?: boolean
|
|
100
113
|
showShare?: boolean
|
|
101
114
|
showReport?: boolean
|
|
102
115
|
showRemove?: boolean
|
|
@@ -104,16 +117,41 @@ const props = defineProps<{
|
|
|
104
117
|
}>();
|
|
105
118
|
|
|
106
119
|
const emit = defineEmits<{
|
|
107
|
-
(e: 'watchLater'): void
|
|
108
120
|
(e: 'share'): void
|
|
109
121
|
(e: 'remove'): void
|
|
110
122
|
}>();
|
|
111
123
|
|
|
124
|
+
const { t } = useI18n();
|
|
125
|
+
|
|
112
126
|
const { isAuthorized } = useUser(AuthorizationApiService);
|
|
113
127
|
const { openReportPopup } = useReportPopup();
|
|
128
|
+
const { isFavorite, isWatchLater, toggleFavorite, toggleWatchLater } = useVideoCollections();
|
|
129
|
+
|
|
130
|
+
const favorite = computed(() => isFavorite(props.card.guid));
|
|
131
|
+
const later = computed(() => isWatchLater(props.card.guid));
|
|
132
|
+
|
|
133
|
+
// Тем же кликом, что переключает коллекцию, меню закрывается. Если менять надпись сразу, она
|
|
134
|
+
// дёргается прямо во время анимации закрытия, поэтому в меню живёт снапшот состояния — он
|
|
135
|
+
// догоняет реальное только к следующему открытию, когда пункт всё равно перерисовывается с нуля.
|
|
136
|
+
const shownFavorite = ref(favorite.value);
|
|
137
|
+
const shownLater = ref(later.value);
|
|
138
|
+
|
|
139
|
+
const favoritesLabel = computed(() => shownFavorite.value
|
|
140
|
+
? t('video_actions.remove_favorites')
|
|
141
|
+
: t('video_actions.add_favorites'));
|
|
142
|
+
|
|
143
|
+
const watchLaterLabel = computed(() => shownLater.value
|
|
144
|
+
? t('video_actions.remove_watch_later')
|
|
145
|
+
: t('video_actions.add_watch_later'));
|
|
114
146
|
|
|
115
147
|
const dropdownRef = ref();
|
|
116
148
|
|
|
149
|
+
watch(() => dropdownRef.value?.open, (isOpen) => {
|
|
150
|
+
if (!isOpen) return;
|
|
151
|
+
shownFavorite.value = favorite.value;
|
|
152
|
+
shownLater.value = later.value;
|
|
153
|
+
});
|
|
154
|
+
|
|
117
155
|
function openDropdown() {
|
|
118
156
|
dropdownRef.value?.openDropdown();
|
|
119
157
|
}
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
</p>
|
|
110
110
|
<div class="card-playlist__content-wrapper">
|
|
111
111
|
<UiDropdown
|
|
112
|
+
ref="dropdownRef"
|
|
112
113
|
right
|
|
113
114
|
use-v-if
|
|
114
115
|
class="card-playlist__dropdown"
|
|
@@ -132,26 +133,26 @@
|
|
|
132
133
|
</template>
|
|
133
134
|
<template #items="className">
|
|
134
135
|
<button
|
|
135
|
-
v-if="card.firstVideoId"
|
|
136
136
|
:class="className"
|
|
137
137
|
type="button"
|
|
138
|
+
@click="emit('share', card)"
|
|
138
139
|
>
|
|
139
140
|
<UiIcon
|
|
140
|
-
name="
|
|
141
|
+
name="share"
|
|
141
142
|
size="16"
|
|
142
143
|
/>
|
|
143
|
-
{{ t('
|
|
144
|
+
{{ t('share') }}
|
|
144
145
|
</button>
|
|
145
146
|
<button
|
|
146
147
|
:class="className"
|
|
147
148
|
type="button"
|
|
148
|
-
@click="
|
|
149
|
+
@click="onReport"
|
|
149
150
|
>
|
|
150
151
|
<UiIcon
|
|
151
|
-
name="
|
|
152
|
+
name="flag"
|
|
152
153
|
size="16"
|
|
153
154
|
/>
|
|
154
|
-
{{ t('
|
|
155
|
+
{{ t('report') }}
|
|
155
156
|
</button>
|
|
156
157
|
</template>
|
|
157
158
|
</UiDropdown>
|
|
@@ -187,6 +188,14 @@ const { t } = useI18n();
|
|
|
187
188
|
|
|
188
189
|
const { generateLink } = useGenerateLink();
|
|
189
190
|
|
|
191
|
+
const { openPlaylistReportPopup } = useReportPopup();
|
|
192
|
+
|
|
193
|
+
const dropdownRef = ref();
|
|
194
|
+
|
|
195
|
+
function onReport() {
|
|
196
|
+
openPlaylistReportPopup(props.card, () => dropdownRef.value?.openDropdown());
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
const userProfileData = computed(() => useState<IProfileData>('profileData').value);
|
|
191
200
|
|
|
192
201
|
const { isAuthorized } = useUser(AuthorizationApiService);
|
|
@@ -126,7 +126,7 @@ $badge-inset--mobile: 4px;
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
.card-round:is(:hover, :focus-visible) .card-round__img {
|
|
129
|
-
@
|
|
129
|
+
@media (hover: hover) {
|
|
130
130
|
border-color: $card-round-border--hover;
|
|
131
131
|
box-shadow: $card-ring-shadow--hover;
|
|
132
132
|
}
|
|
@@ -158,13 +158,13 @@ $badge-inset--mobile: 4px;
|
|
|
158
158
|
white-space: nowrap;
|
|
159
159
|
text-overflow: ellipsis;
|
|
160
160
|
|
|
161
|
-
@
|
|
161
|
+
@media (hover: hover) {
|
|
162
162
|
transition: var(--transition) color;
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
.card-round:is(:hover, :focus-visible) .card-round__title {
|
|
167
|
-
@
|
|
167
|
+
@media (hover: hover) {
|
|
168
168
|
color: $card-round-text--hover;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<!-- Кнопки коллекций поверх постера: избранное (только когда ролик уже в нём) и «смотреть позже» -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="card-video-actions">
|
|
4
|
+
<button
|
|
5
|
+
v-if="showFavorites && favorite"
|
|
6
|
+
:aria-label="t('video_actions.remove_aria', { title: card.title, name: t('favorites') })"
|
|
7
|
+
class="card-video-actions__btn --active"
|
|
8
|
+
type="button"
|
|
9
|
+
aria-pressed="true"
|
|
10
|
+
@click="toggleFavorite(card.guid)"
|
|
11
|
+
>
|
|
12
|
+
<UiIcon
|
|
13
|
+
name="heart"
|
|
14
|
+
size="18"
|
|
15
|
+
/>
|
|
16
|
+
</button>
|
|
17
|
+
<button
|
|
18
|
+
v-if="showWatchLater"
|
|
19
|
+
:aria-label="later
|
|
20
|
+
? t('video_actions.remove_aria', { title: card.title, name: t('video_submenu.watch_later') })
|
|
21
|
+
: t('video_actions.add_aria', { title: card.title, name: t('video_submenu.watch_later') })"
|
|
22
|
+
:aria-pressed="later"
|
|
23
|
+
:class="['card-video-actions__btn', '--watch-later', { '--active': later }]"
|
|
24
|
+
type="button"
|
|
25
|
+
@click="toggleWatchLater(card.guid)"
|
|
26
|
+
>
|
|
27
|
+
<UiIcon
|
|
28
|
+
:name="later ? 'clock-filled' : 'clock'"
|
|
29
|
+
size="18"
|
|
30
|
+
/>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
import type { IVideoCard } from '../../../types';
|
|
37
|
+
|
|
38
|
+
const props = defineProps<{
|
|
39
|
+
card: IVideoCard
|
|
40
|
+
showFavorites?: boolean
|
|
41
|
+
showWatchLater?: boolean
|
|
42
|
+
}>();
|
|
43
|
+
|
|
44
|
+
const { t } = useI18n();
|
|
45
|
+
|
|
46
|
+
const { isFavorite, isWatchLater, toggleFavorite, toggleWatchLater } = useVideoCollections();
|
|
47
|
+
|
|
48
|
+
const favorite = computed(() => isFavorite(props.card.guid));
|
|
49
|
+
const later = computed(() => isWatchLater(props.card.guid));
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<style lang="scss">
|
|
53
|
+
$action-inset: 8px;
|
|
54
|
+
$action-size: 36px;
|
|
55
|
+
|
|
56
|
+
.card-video-actions {
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: $action-inset;
|
|
59
|
+
right: $action-inset;
|
|
60
|
+
left: $action-inset;
|
|
61
|
+
z-index: $z-index-sub-loader;
|
|
62
|
+
display: flex;
|
|
63
|
+
column-gap: $action-inset;
|
|
64
|
+
pointer-events: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.card-video-actions__btn {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
width: $action-size;
|
|
72
|
+
height: $action-size;
|
|
73
|
+
border: 1px solid $video-card-action-border;
|
|
74
|
+
border-radius: $radius-md;
|
|
75
|
+
background-color: $video-card-action-bg;
|
|
76
|
+
color: $video-card-action-icon;
|
|
77
|
+
pointer-events: auto;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.card-video-actions__btn.--watch-later {
|
|
81
|
+
margin-left: auto;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.card-video-actions__btn.--active {
|
|
85
|
+
background-color: $video-card-action-active-bg;
|
|
86
|
+
border-color: $video-card-action-active-border;
|
|
87
|
+
color: $video-card-action-active-icon;
|
|
88
|
+
opacity: 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* С мышью неактивные кнопки проявляются по наведению на карточку. На тач-устройствах наведения нет,
|
|
92
|
+
поэтому там неактивные кнопки не показываем вовсе — только те, что уже в коллекции. */
|
|
93
|
+
@media (hover: hover) {
|
|
94
|
+
.card-video-actions__btn {
|
|
95
|
+
opacity: 0;
|
|
96
|
+
transition:
|
|
97
|
+
var(--transition) opacity,
|
|
98
|
+
var(--transition) background-color,
|
|
99
|
+
var(--transition) border-color,
|
|
100
|
+
var(--transition) color;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.card-video:is(:hover, :focus-within) .card-video-actions__btn {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.card-video-actions__btn:is(:hover, :focus-visible) {
|
|
108
|
+
background-color: $video-card-action-bg--hover;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.card-video-actions__btn.--active:is(:hover, :focus-visible) {
|
|
112
|
+
background-color: $video-card-action-active-bg--hover;
|
|
113
|
+
border-color: $video-card-action-active-border--hover;
|
|
114
|
+
color: $video-card-action-active-icon--hover;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@media (hover: none) {
|
|
119
|
+
.card-video-actions__btn:not(.--active) {
|
|
120
|
+
display: none;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
</style>
|