itube-specs 0.0.899 → 0.0.902
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/scss/mixins/_breakpoints.scss +3 -2
- package/assets/scss/themes/dark/_theme.scss +17 -23
- package/assets/scss/themes/light/_theme.scss +17 -23
- 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/like.vue +1 -1
- 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/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>
|
|
@@ -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;
|
|
@@ -992,18 +988,16 @@ $library-feed-name: $color-white;
|
|
|
992
988
|
$library-feed-name--hover: $color-indigo-400;
|
|
993
989
|
$library-feed-badge-bg: $color-indigo-600;
|
|
994
990
|
$library-feed-badge-text: $color-white;
|
|
991
|
+
$library-feed-params: $color-zinc-400;
|
|
992
|
+
$library-feed-age: $color-zinc-500;
|
|
995
993
|
$library-feed-meta: $color-zinc-500;
|
|
996
994
|
$library-feed-meta-dot: $color-zinc-600;
|
|
997
995
|
$library-feed-title: $color-zinc-500;
|
|
998
996
|
|
|
999
997
|
// ─── Page: library ───
|
|
1000
998
|
$page-library-toggle-text: $color-zinc-300;
|
|
1001
|
-
$page-library-confirm-text: $color-zinc-300;
|
|
1002
999
|
|
|
1003
1000
|
// ─── 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
1001
|
$page-history-confirm-text: $color-zinc-300;
|
|
1008
1002
|
$page-history-confirm-muted: $color-zinc-500;
|
|
1009
1003
|
$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;
|
|
@@ -1020,18 +1016,16 @@ $library-feed-name: $color-gray-900;
|
|
|
1020
1016
|
$library-feed-name--hover: $color-indigo-600;
|
|
1021
1017
|
$library-feed-badge-bg: $color-indigo-600;
|
|
1022
1018
|
$library-feed-badge-text: $color-white;
|
|
1019
|
+
$library-feed-params: $color-gray-600;
|
|
1020
|
+
$library-feed-age: $color-gray-500;
|
|
1023
1021
|
$library-feed-meta: $color-gray-500;
|
|
1024
1022
|
$library-feed-meta-dot: $color-gray-400;
|
|
1025
1023
|
$library-feed-title: $color-gray-500;
|
|
1026
1024
|
|
|
1027
1025
|
// ─── Page: library ───
|
|
1028
1026
|
$page-library-toggle-text: $color-gray-700;
|
|
1029
|
-
$page-library-confirm-text: $color-gray-700;
|
|
1030
1027
|
|
|
1031
1028
|
// ─── 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
1029
|
$page-history-confirm-text: $color-gray-900;
|
|
1036
1030
|
$page-history-confirm-muted: $color-gray-500;
|
|
1037
1031
|
$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>
|