itube-specs 0.0.911 → 0.0.913
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/scss/base/_animations.scss +11 -10
- package/assets/scss/mixins/_font-sizes.scss +5 -2
- package/assets/scss/themes/dark/_theme.scss +22 -18
- package/assets/scss/themes/light/_theme.scss +17 -13
- package/assets/scss/vars/_tokens.scss +1 -1
- package/assets/scss/vars/_vars.scss +1 -0
- package/components/auth/register.vue +0 -4
- package/components/card/collections-more.vue +1 -1
- package/components/card/dropdown/index.vue +2 -2
- package/components/card/playlist.vue +7 -8
- package/components/card/video/actions.vue +2 -2
- package/components/card/video/index.vue +9 -9
- package/components/filter/popup.vue +1 -0
- package/components/library/feed.vue +1 -14
- package/components/playlist/add.vue +123 -113
- package/components/playlist/edit.vue +133 -199
- package/components/playlist/input.vue +23 -133
- package/components/playlist/main.vue +21 -40
- package/components/playlist/visibility.vue +149 -0
- package/components/section/collections.vue +2 -2
- package/components/section/swiper-cards.vue +3 -3
- package/components/ui/chips.vue +7 -2
- package/components/ui/confirm.vue +17 -5
- package/components/ui/dropdown.vue +17 -8
- package/components/ui/expand-row.vue +0 -4
- package/components/ui/popup.vue +33 -15
- package/components/ui/section-title.vue +6 -6
- package/components/ui/tooltip.vue +35 -14
- package/composables/__tests__/use-overlay-stack.test.ts +110 -0
- package/composables/__tests__/use-video-collections.test.ts +75 -0
- package/composables/use-overlay-stack.ts +58 -0
- package/composables/use-playlist-edit.ts +13 -3
- package/composables/use-snackbar.ts +15 -1
- package/composables/use-user.ts +0 -4
- package/composables/use-video-collections.ts +27 -5
- package/package.json +1 -1
- package/pages/following.vue +4 -4
- package/pages/history.vue +1 -1
- package/pages/library/index.vue +4 -4
- package/pages/playlists/index.vue +7 -76
- package/runtime/constants/playlist-type.ts +5 -0
- package/components/playlist/private-toggle.vue +0 -20
- package/composables/use-favorites.ts +0 -20
- package/pages/favorites.vue +0 -31
|
@@ -1,119 +1,80 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
v-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<UiConfirm
|
|
3
|
+
v-model="isDeleteStep"
|
|
4
|
+
:title="$t('playlist.delete_playlist')"
|
|
5
|
+
:confirm-text="$t('playlist.delete')"
|
|
6
|
+
:loading="loadingAll"
|
|
7
|
+
transparent-backdrop
|
|
8
|
+
@confirm="onDeleteClick"
|
|
9
|
+
>
|
|
10
|
+
<i18n-t
|
|
11
|
+
keypath="playlist.confirm_delete"
|
|
12
|
+
tag="p"
|
|
13
|
+
scope="global"
|
|
14
|
+
class="playlist-edit__confirm"
|
|
15
|
+
>
|
|
16
|
+
<strong>{{ selectedPlaylist?.name }}</strong>
|
|
17
|
+
</i18n-t>
|
|
18
|
+
<p class="playlist-edit__confirm-note">
|
|
19
|
+
{{ $t('playlist.confirm_delete_note', { videos: $t('plural.videos', selectedPlaylist?.videosCount ?? 0) }) }}
|
|
20
|
+
</p>
|
|
21
|
+
</UiConfirm>
|
|
6
22
|
|
|
7
|
-
<!--
|
|
23
|
+
<!-- Edit-->
|
|
8
24
|
<transition mode="out-in">
|
|
9
25
|
<UiPopup
|
|
10
|
-
v-if="isPlaylistEditOpen && currentStep === PlaylistStep.
|
|
26
|
+
v-if="isPlaylistEditOpen && currentStep === PlaylistStep.Edit"
|
|
11
27
|
v-model="isPlaylistEditOpen"
|
|
28
|
+
:back="!!onBack"
|
|
29
|
+
class="playlist-edit"
|
|
12
30
|
sheet
|
|
13
31
|
transparent-backdrop
|
|
32
|
+
@back="goBack"
|
|
33
|
+
@close="closePlaylistEditAll"
|
|
14
34
|
>
|
|
15
|
-
<template #title>{{ $t('playlist.
|
|
35
|
+
<template #title>{{ $t('playlist.edit_playlist') }}</template>
|
|
16
36
|
|
|
17
37
|
<div
|
|
18
38
|
:class="{'_loading': loadingAll}"
|
|
19
|
-
class="playlist-
|
|
39
|
+
class="playlist-edit__form"
|
|
20
40
|
>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
<UiInput
|
|
42
|
+
v-model="inputValue"
|
|
43
|
+
:placeholder="$t('playlist_name')"
|
|
44
|
+
@enter="onSaveClick"
|
|
25
45
|
/>
|
|
26
|
-
<
|
|
46
|
+
<PlaylistVisibility v-model="typeValue"/>
|
|
27
47
|
</div>
|
|
28
|
-
<template #footer>
|
|
29
|
-
<div class="playlist-edit__buttons">
|
|
30
|
-
<UiBtn
|
|
31
|
-
:disabled="loadingAll"
|
|
32
|
-
size="l"
|
|
33
|
-
wide
|
|
34
|
-
theme="secondary"
|
|
35
|
-
@click="closePlaylistEdit"
|
|
36
|
-
>{{ $t('cancel') }}
|
|
37
|
-
</UiBtn>
|
|
38
|
-
<UiBtn
|
|
39
|
-
:disabled="loadingAll"
|
|
40
|
-
size="l"
|
|
41
|
-
wide
|
|
42
|
-
theme="primary"
|
|
43
|
-
@click="onDeleteClick"
|
|
44
|
-
>{{ $t('playlist.delete') }}
|
|
45
|
-
</UiBtn>
|
|
46
|
-
</div>
|
|
47
|
-
</template>
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<!-- Delete-->
|
|
52
|
-
|
|
53
|
-
<!-- Edit-->
|
|
54
|
-
<transition mode="out-in">
|
|
55
|
-
<UiPopup
|
|
56
|
-
v-if="isPlaylistEditOpen && currentStep === PlaylistStep.Edit && data"
|
|
57
|
-
v-model="isPlaylistEditOpen"
|
|
58
|
-
transparent-backdrop
|
|
59
|
-
>
|
|
60
|
-
<template #title>{{ $t('playlist.edit_playlist') }}</template>
|
|
61
|
-
|
|
62
|
-
<template #fixedContent>
|
|
63
|
-
<div class="playlist-edit__subheader-wrapper">
|
|
64
|
-
<UiInput
|
|
65
|
-
v-model="inputValue"
|
|
66
|
-
:label="$t('playlist.playlist')"
|
|
67
|
-
/>
|
|
68
|
-
<PlaylistPrivateToggle v-model="toggleValue"/>
|
|
69
|
-
</div>
|
|
70
|
-
</template>
|
|
71
|
-
|
|
72
|
-
<div
|
|
73
|
-
v-if="data && data.items.length"
|
|
74
|
-
:class="{'_loading': loadingAll}"
|
|
75
|
-
class="playlist-edit__grid"
|
|
76
|
-
>
|
|
77
|
-
<div
|
|
78
|
-
v-for="(card, index) in data.items"
|
|
79
|
-
:key="`playlist-edit-${index}`"
|
|
80
|
-
class="playlist-edit__card-wrapper"
|
|
81
|
-
>
|
|
82
|
-
<CardVideoMini
|
|
83
|
-
:card="card"
|
|
84
|
-
class="playlist-edit__card"
|
|
85
|
-
/>
|
|
49
|
+
<template #footer>
|
|
50
|
+
<div class="playlist-edit__footer">
|
|
86
51
|
<button
|
|
87
52
|
class="playlist-edit__delete"
|
|
88
53
|
type="button"
|
|
89
|
-
@click="openPlaylistEdit(PlaylistStep.
|
|
54
|
+
@click="openPlaylistEdit(PlaylistStep.Delete, true, selectedPlaylist)"
|
|
90
55
|
>
|
|
91
56
|
<UiIcon
|
|
92
57
|
name="trash-bin"
|
|
93
|
-
size="
|
|
58
|
+
size="16"
|
|
94
59
|
/>
|
|
60
|
+
{{ $t('delete') }}
|
|
95
61
|
</button>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
wide
|
|
113
|
-
theme="primary"
|
|
114
|
-
@click="onSaveClick"
|
|
115
|
-
>{{ $t('save') }}
|
|
116
|
-
</UiBtn>
|
|
62
|
+
<div class="playlist-edit__actions">
|
|
63
|
+
<UiBtn
|
|
64
|
+
:disabled="loadingAll"
|
|
65
|
+
size="l"
|
|
66
|
+
theme="muted"
|
|
67
|
+
@click="goBack"
|
|
68
|
+
>{{ $t('cancel') }}
|
|
69
|
+
</UiBtn>
|
|
70
|
+
<UiBtn
|
|
71
|
+
:disabled="loadingAll || !inputValue.trim()"
|
|
72
|
+
size="l"
|
|
73
|
+
theme="primary"
|
|
74
|
+
@click="onSaveClick"
|
|
75
|
+
>{{ $t('save') }}
|
|
76
|
+
</UiBtn>
|
|
77
|
+
</div>
|
|
117
78
|
</div>
|
|
118
79
|
</template>
|
|
119
80
|
<!-- Edit-->
|
|
@@ -124,18 +85,16 @@
|
|
|
124
85
|
|
|
125
86
|
<script setup lang="ts">
|
|
126
87
|
import { PlaylistStep, PlaylistType, AsyncData } from '../../runtime';
|
|
127
|
-
import type {
|
|
88
|
+
import type { IPlaylistData } from '../../types';
|
|
128
89
|
|
|
129
90
|
const props = defineProps<{
|
|
130
91
|
loadingPlaylists: boolean
|
|
131
92
|
loadingRefresh: boolean
|
|
132
|
-
loadingEditVideos: boolean
|
|
133
93
|
loadingPlaylistDelete: boolean
|
|
134
94
|
}>();
|
|
135
95
|
|
|
136
96
|
const emit = defineEmits<{
|
|
137
97
|
(eventName: 'delete-playlist', eventValue: string): void
|
|
138
|
-
(eventName: 'open-edit', eventValue: string): void
|
|
139
98
|
(eventName: 'save-edit', eventValue: {
|
|
140
99
|
id: string
|
|
141
100
|
playlistName: string
|
|
@@ -144,32 +103,45 @@ const emit = defineEmits<{
|
|
|
144
103
|
}>();
|
|
145
104
|
|
|
146
105
|
const inputValue = ref('');
|
|
147
|
-
const
|
|
106
|
+
const typeValue = ref<PlaylistType>(PlaylistType.Public);
|
|
107
|
+
|
|
108
|
+
const {
|
|
109
|
+
isPlaylistEditOpen,
|
|
110
|
+
closePlaylistEdit,
|
|
111
|
+
closePlaylistEditAll,
|
|
112
|
+
currentStep,
|
|
113
|
+
selectedPlaylist,
|
|
114
|
+
openPlaylistEdit,
|
|
115
|
+
onBack,
|
|
116
|
+
} = usePlaylistEdit();
|
|
117
|
+
|
|
118
|
+
/** Возврат к попапу, откуда пришли (список плейлистов), либо просто закрытие. */
|
|
119
|
+
function goBack() {
|
|
120
|
+
const back = onBack.value;
|
|
121
|
+
closePlaylistEditAll();
|
|
122
|
+
back?.();
|
|
123
|
+
}
|
|
148
124
|
|
|
149
|
-
const
|
|
125
|
+
const isDeleteStep = computed({
|
|
126
|
+
get: () => isPlaylistEditOpen.value && currentStep.value === PlaylistStep.Delete,
|
|
127
|
+
set: (val: boolean) => {
|
|
128
|
+
if (!val) closePlaylistEdit();
|
|
129
|
+
},
|
|
130
|
+
});
|
|
150
131
|
const { show } = useSnackbar();
|
|
151
132
|
|
|
152
133
|
const route = useRoute();
|
|
153
|
-
const id = computed(() => route.params[ 'playlistId' ] ? String(route.params[ 'playlistId' ]) :
|
|
154
|
-
|
|
155
|
-
const videosStateKey = computed(() =>
|
|
156
|
-
id.value ? `data-${AsyncData.GetPlaylistsVideo}-${id.value}` : null
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const data = computed<PaginatedResponse<IVideoCard> | null>(() => {
|
|
160
|
-
return useState<PaginatedResponse<IVideoCard> | null>(
|
|
161
|
-
videosStateKey.value || '',
|
|
162
|
-
() => null
|
|
163
|
-
).value;
|
|
164
|
-
});
|
|
134
|
+
const id = computed(() => selectedPlaylist.value?.id ?? (route.params[ 'playlistId' ] ? String(route.params[ 'playlistId' ]) : undefined));
|
|
165
135
|
|
|
166
136
|
const playlistsData = useState<IPlaylistData>(`data-${AsyncData.PlaylistById}-${id.value}`);
|
|
167
137
|
|
|
168
138
|
async function onDeleteClick() {
|
|
169
139
|
try {
|
|
140
|
+
const name = selectedPlaylist.value?.name;
|
|
141
|
+
|
|
170
142
|
emit('delete-playlist', id.value || '');
|
|
171
|
-
|
|
172
|
-
|
|
143
|
+
goBack();
|
|
144
|
+
show('deleted', { icon: 'trash-bin', highlight: name });
|
|
173
145
|
} catch {
|
|
174
146
|
console.log('error delete');
|
|
175
147
|
}
|
|
@@ -177,19 +149,17 @@ async function onDeleteClick() {
|
|
|
177
149
|
|
|
178
150
|
async function onSaveClick() {
|
|
179
151
|
try {
|
|
180
|
-
const playlistType = toggleValue.value ? PlaylistType.Private : PlaylistType.Public;
|
|
181
|
-
|
|
182
152
|
emit('save-edit', {
|
|
183
153
|
id: id.value || '',
|
|
184
154
|
playlistName: inputValue.value,
|
|
185
|
-
playlistType:
|
|
155
|
+
playlistType: typeValue.value,
|
|
186
156
|
});
|
|
187
157
|
|
|
188
158
|
if (playlistsData.value) {
|
|
189
159
|
playlistsData.value.name = inputValue.value ? inputValue.value : playlistsData.value.name;
|
|
190
|
-
playlistsData.value.playlistType =
|
|
160
|
+
playlistsData.value.playlistType = typeValue.value;
|
|
191
161
|
}
|
|
192
|
-
|
|
162
|
+
goBack();
|
|
193
163
|
show('changes_soon');
|
|
194
164
|
} catch {
|
|
195
165
|
console.log('error save');
|
|
@@ -197,123 +167,87 @@ async function onSaveClick() {
|
|
|
197
167
|
}
|
|
198
168
|
|
|
199
169
|
watch(
|
|
200
|
-
() => [isPlaylistEditOpen.value, currentStep.value,
|
|
201
|
-
([open, step
|
|
202
|
-
if (!open || step !== PlaylistStep.Edit
|
|
203
|
-
|
|
204
|
-
emit('open-edit', String(playlistId));
|
|
170
|
+
() => [isPlaylistEditOpen.value, currentStep.value, selectedPlaylist.value],
|
|
171
|
+
([open, step]) => {
|
|
172
|
+
if (!open || step !== PlaylistStep.Edit) return;
|
|
205
173
|
|
|
206
174
|
inputValue.value = selectedPlaylist.value?.name || '';
|
|
175
|
+
typeValue.value = selectedPlaylist.value?.playlistType ?? PlaylistType.Public;
|
|
207
176
|
},
|
|
208
177
|
{ immediate: true }
|
|
209
178
|
);
|
|
210
179
|
|
|
211
|
-
|
|
212
|
-
if (newType !== undefined && newType !== null) {
|
|
213
|
-
toggleValue.value = newType === PlaylistType.Private;
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
const loadingAll = computed(() => props.loadingRefresh || props.loadingEditVideos || props.loadingPlaylists || props.loadingPlaylistDelete);
|
|
180
|
+
const loadingAll = computed(() => props.loadingRefresh || props.loadingPlaylists || props.loadingPlaylistDelete);
|
|
218
181
|
</script>
|
|
219
182
|
|
|
220
183
|
<style lang="scss">
|
|
221
|
-
.playlist-
|
|
222
|
-
|
|
223
|
-
display: grid;
|
|
224
|
-
gap: 8px;
|
|
225
|
-
border-top: 1px solid $playlist-edit-border;
|
|
184
|
+
.playlist-edit__confirm {
|
|
185
|
+
@include font-sm;
|
|
226
186
|
|
|
227
|
-
|
|
228
|
-
padding: 16px;
|
|
229
|
-
grid-template-columns: 1fr 1fr;
|
|
230
|
-
}
|
|
187
|
+
line-height: 1.5;
|
|
231
188
|
}
|
|
232
189
|
|
|
233
|
-
.playlist-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
display: grid;
|
|
237
|
-
padding-inline: 8px;
|
|
238
|
-
|
|
239
|
-
@include from-br(sm) {
|
|
240
|
-
max-width: 400px;
|
|
241
|
-
padding-inline: 16px;
|
|
242
|
-
}
|
|
190
|
+
.playlist-edit__confirm strong {
|
|
191
|
+
font-weight: 600;
|
|
192
|
+
color: $playlist-edit-confirm-highlight;
|
|
243
193
|
}
|
|
244
194
|
|
|
245
|
-
.playlist-
|
|
246
|
-
|
|
247
|
-
row-gap: 8px;
|
|
195
|
+
.playlist-edit__confirm-note {
|
|
196
|
+
@include font-sm;
|
|
248
197
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
198
|
+
margin-top: 12px;
|
|
199
|
+
line-height: 1.5;
|
|
200
|
+
color: $playlist-edit-confirm-note;
|
|
253
201
|
}
|
|
254
202
|
|
|
255
|
-
.playlist-
|
|
256
|
-
|
|
257
|
-
padding-block: 8px;
|
|
258
|
-
|
|
259
|
-
@include from-br(sm) {
|
|
260
|
-
row-gap: 16px;
|
|
261
|
-
padding-block: 16px;
|
|
262
|
-
}
|
|
203
|
+
.playlist-edit .ui-popup__content {
|
|
204
|
+
padding: 0;
|
|
263
205
|
}
|
|
264
206
|
|
|
265
|
-
.playlist-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
font-weight: 400;
|
|
269
|
-
text-align: center;
|
|
207
|
+
.playlist-edit .ui-popup__footer {
|
|
208
|
+
padding-inline: 24px;
|
|
209
|
+
}
|
|
270
210
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
211
|
+
.playlist-edit__form {
|
|
212
|
+
display: grid;
|
|
213
|
+
row-gap: 16px;
|
|
214
|
+
padding: 20px 24px;
|
|
274
215
|
}
|
|
275
216
|
|
|
276
|
-
.playlist-
|
|
277
|
-
|
|
278
|
-
margin: 0 auto;
|
|
217
|
+
.playlist-edit__form .ui-input {
|
|
218
|
+
--input-bg: #{$playlist-input-bg};
|
|
279
219
|
}
|
|
280
220
|
|
|
281
|
-
.playlist-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
backdrop-filter: blur(8px);
|
|
221
|
+
.playlist-edit__form .ui-input__input {
|
|
222
|
+
@include from-br(sm) {
|
|
223
|
+
padding-block: 12px;
|
|
224
|
+
}
|
|
286
225
|
}
|
|
287
226
|
|
|
288
|
-
.playlist-
|
|
227
|
+
.playlist-edit__footer {
|
|
289
228
|
display: flex;
|
|
290
229
|
align-items: center;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
border-bottom: 1px solid $playlist-edit-border;
|
|
294
|
-
|
|
295
|
-
@include from-br(sm) {
|
|
296
|
-
padding-block: 16px;
|
|
297
|
-
}
|
|
230
|
+
justify-content: space-between;
|
|
231
|
+
column-gap: 12px;
|
|
298
232
|
}
|
|
299
233
|
|
|
300
|
-
.playlist-
|
|
301
|
-
|
|
234
|
+
.playlist-edit__actions {
|
|
235
|
+
display: flex;
|
|
236
|
+
column-gap: 12px;
|
|
302
237
|
}
|
|
303
238
|
|
|
304
239
|
.playlist-edit__delete {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
@include hover(opacity) {
|
|
308
|
-
opacity: 0.4;
|
|
309
|
-
}
|
|
240
|
+
@include font-sm;
|
|
310
241
|
|
|
311
|
-
|
|
312
|
-
|
|
242
|
+
display: flex;
|
|
243
|
+
align-items: center;
|
|
244
|
+
column-gap: 8px;
|
|
245
|
+
font-weight: 500;
|
|
246
|
+
color: $playlist-edit-delete-text;
|
|
313
247
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
248
|
+
@include hover(color) {
|
|
249
|
+
color: $playlist-edit-delete-text--hover;
|
|
317
250
|
}
|
|
318
251
|
}
|
|
252
|
+
|
|
319
253
|
</style>
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
v-model="name"
|
|
8
8
|
:placeholder="placeholder"
|
|
9
9
|
:error="error"
|
|
10
|
-
:icon="name.length > 0 ? 'close' : ''"
|
|
11
|
-
@icon-click="name = ''"
|
|
12
10
|
@update:error="$emit('update:error', $event)"
|
|
13
11
|
/>
|
|
14
12
|
<button
|
|
@@ -21,69 +19,32 @@
|
|
|
21
19
|
size="20"
|
|
22
20
|
/>
|
|
23
21
|
</button>
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
>
|
|
29
|
-
<div class="playlist-input__toggle-wrapper">
|
|
30
|
-
<UiIcon
|
|
31
|
-
:name="PLAYLIST_TYPE_ICON[PlaylistType.Public]"
|
|
32
|
-
class="playlist-input__toggle-icon"
|
|
33
|
-
size="14"
|
|
34
|
-
/>
|
|
35
|
-
{{ $t('public') }}
|
|
36
|
-
</div>
|
|
37
|
-
</UiToggle>
|
|
38
|
-
<UiTooltip
|
|
39
|
-
class="playlist-input__tooltip"
|
|
40
|
-
right
|
|
41
|
-
>
|
|
42
|
-
<template #trigger>
|
|
43
|
-
<span class="playlist-input__hint">?</span>
|
|
44
|
-
</template>
|
|
45
|
-
<p class="playlist-input__tooltip-text"><span>{{ $t('public') }}: </span>{{ $t('public_hint') }}</p>
|
|
46
|
-
<p class="playlist-input__tooltip-text"><span>{{ $t('private') }}: </span>{{ $t('private_hint') }}</p>
|
|
47
|
-
</UiTooltip>
|
|
48
|
-
<button
|
|
49
|
-
v-if="editPlaylist"
|
|
50
|
-
type="button"
|
|
51
|
-
class="playlist-input__delete"
|
|
52
|
-
@click="$emit('delete')"
|
|
53
|
-
>
|
|
54
|
-
{{ $t('delete') }}
|
|
55
|
-
</button>
|
|
56
|
-
</div>
|
|
22
|
+
<PlaylistVisibility
|
|
23
|
+
v-model="currentType"
|
|
24
|
+
class="playlist-input__visibility"
|
|
25
|
+
/>
|
|
57
26
|
</div>
|
|
58
27
|
</template>
|
|
59
28
|
|
|
60
29
|
<script setup lang="ts">
|
|
61
|
-
import { PlaylistType } from '../../runtime';
|
|
62
|
-
|
|
63
|
-
const PLAYLIST_TYPE_ICON: Record<PlaylistType, string> = {
|
|
64
|
-
[PlaylistType.Public]: 'user-group',
|
|
65
|
-
[PlaylistType.Private]: 'lock',
|
|
66
|
-
};
|
|
30
|
+
import type { PlaylistType } from '../../runtime';
|
|
67
31
|
|
|
68
32
|
const props = withDefaults(defineProps<{
|
|
69
33
|
modelValue: string
|
|
70
|
-
type:
|
|
34
|
+
type: PlaylistType
|
|
71
35
|
error?: boolean
|
|
72
36
|
placeholder?: string
|
|
73
|
-
editPlaylist?: boolean
|
|
74
37
|
}>(), {
|
|
75
38
|
error: false,
|
|
76
39
|
placeholder: '',
|
|
77
|
-
editPlaylist: false,
|
|
78
40
|
});
|
|
79
41
|
|
|
80
42
|
const emit = defineEmits<{
|
|
81
43
|
(eventName: 'update:modelValue', value: string): void
|
|
82
|
-
(eventName: 'update:type', value:
|
|
44
|
+
(eventName: 'update:type', value: PlaylistType): void
|
|
83
45
|
(eventName: 'update:error', value: boolean): void
|
|
84
46
|
(eventName: 'close'): void
|
|
85
47
|
(eventName: 'submit'): void
|
|
86
|
-
(eventName: 'delete'): void
|
|
87
48
|
}>();
|
|
88
49
|
|
|
89
50
|
const name = computed({
|
|
@@ -93,7 +54,7 @@ const name = computed({
|
|
|
93
54
|
|
|
94
55
|
const currentType = computed({
|
|
95
56
|
get: () => props.type,
|
|
96
|
-
set: (val:
|
|
57
|
+
set: (val: PlaylistType) => emit('update:type', val),
|
|
97
58
|
});
|
|
98
59
|
</script>
|
|
99
60
|
|
|
@@ -103,110 +64,39 @@ const currentType = computed({
|
|
|
103
64
|
display: grid;
|
|
104
65
|
grid-template-columns: 1fr auto;
|
|
105
66
|
align-items: center;
|
|
106
|
-
column-gap:
|
|
107
|
-
|
|
108
|
-
@include from-br(sm) {
|
|
109
|
-
column-gap: 16px;
|
|
110
|
-
}
|
|
67
|
+
column-gap: 8px;
|
|
111
68
|
}
|
|
112
69
|
|
|
113
|
-
.playlist-input .ui-
|
|
114
|
-
|
|
70
|
+
.playlist-input .ui-input {
|
|
71
|
+
--input-bg: #{$playlist-input-bg};
|
|
115
72
|
}
|
|
116
73
|
|
|
117
|
-
.playlist-
|
|
118
|
-
|
|
74
|
+
.playlist-input .ui-input__input {
|
|
75
|
+
@include from-br(sm) {
|
|
76
|
+
padding-block: 12px;
|
|
77
|
+
}
|
|
119
78
|
}
|
|
120
79
|
|
|
121
80
|
.playlist-input__visibility {
|
|
122
81
|
grid-column: 1;
|
|
123
|
-
display: flex;
|
|
124
|
-
align-items: center;
|
|
125
|
-
flex-wrap: wrap;
|
|
126
|
-
gap: 12px;
|
|
127
82
|
margin-top: 12px;
|
|
128
|
-
|
|
129
|
-
@include from-br(sm) {
|
|
130
|
-
gap: 10px;
|
|
131
|
-
}
|
|
132
83
|
}
|
|
133
84
|
|
|
134
85
|
.playlist-input__back {
|
|
135
86
|
grid-column: 2;
|
|
136
87
|
grid-row: 1;
|
|
137
|
-
|
|
88
|
+
display: grid;
|
|
89
|
+
place-content: center;
|
|
90
|
+
width: 44px;
|
|
91
|
+
height: 44px;
|
|
92
|
+
border-radius: $radius-12;
|
|
138
93
|
color: $playlist-input-back;
|
|
94
|
+
background-color: $playlist-input-back-bg;
|
|
139
95
|
|
|
140
|
-
|
|
141
|
-
@include area-point;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@include hover(color) {
|
|
96
|
+
@include hover(background-color, color) {
|
|
145
97
|
color: $playlist-input-back--hover;
|
|
98
|
+
background-color: $playlist-input-back-bg--hover;
|
|
146
99
|
}
|
|
147
100
|
}
|
|
148
101
|
|
|
149
|
-
.playlist-input__tooltip {
|
|
150
|
-
margin-left: 0;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.playlist-input__hint {
|
|
154
|
-
@include font-xs;
|
|
155
|
-
|
|
156
|
-
display: inline-grid;
|
|
157
|
-
place-content: center;
|
|
158
|
-
width: 20px;
|
|
159
|
-
height: 20px;
|
|
160
|
-
border-radius: $radius-full;
|
|
161
|
-
color: $playlist-input-hint-text;
|
|
162
|
-
background-color: $playlist-input-hint-bg;
|
|
163
|
-
font-weight: 700;
|
|
164
|
-
line-height: 1;
|
|
165
|
-
cursor: help;
|
|
166
|
-
flex-shrink: 0;
|
|
167
|
-
|
|
168
|
-
@include hover(background-color) {
|
|
169
|
-
background-color: $playlist-input-hint-bg--hover;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.playlist-input__tooltip-text:not(:last-child) {
|
|
174
|
-
margin-bottom: 8px;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.playlist-input__tooltip-text span {
|
|
178
|
-
color: $playlist-input-tooltip-highlight;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.playlist-input__tooltip-text {
|
|
182
|
-
@include font-xs;
|
|
183
|
-
|
|
184
|
-
max-width: 184px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.playlist-input__delete {
|
|
188
|
-
@include font-xs;
|
|
189
|
-
|
|
190
|
-
margin-left: auto;
|
|
191
|
-
color: $playlist-input-delete-text;
|
|
192
|
-
background-color: $playlist-input-delete-bg;
|
|
193
|
-
padding: 6px 12px;
|
|
194
|
-
border-radius: $radius-lg;
|
|
195
|
-
|
|
196
|
-
@include hover(background-color) {
|
|
197
|
-
background-color: $playlist-input-delete-bg--hover;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.playlist-input__toggle-icon {
|
|
202
|
-
color: $playlist-input-toggle-icon--active;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.playlist-input__toggle-wrapper {
|
|
206
|
-
@include font-sm;
|
|
207
|
-
|
|
208
|
-
display: flex;
|
|
209
|
-
align-items: center;
|
|
210
|
-
column-gap: 8px;
|
|
211
|
-
}
|
|
212
102
|
</style>
|