itube-specs 0.0.760 → 0.0.761

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/package.json +1 -1
  2. package/components/auth/s-auth-icon.vue +0 -20
  3. package/components/auth/s-auth-login.vue +0 -120
  4. package/components/auth/s-auth-popup.vue +0 -69
  5. package/components/auth/s-auth-recovery.vue +0 -104
  6. package/components/auth/s-auth-register.vue +0 -176
  7. package/components/cards/s-video-mini-card.vue +0 -62
  8. package/components/grids/s-grid-categories.vue +0 -20
  9. package/components/grids/s-grid-channels.vue +0 -23
  10. package/components/grids/s-grid-models.vue +0 -25
  11. package/components/grids/s-grid-playlists.vue +0 -21
  12. package/components/grids/s-grid-videos.vue +0 -68
  13. package/components/page-components/s-breadcrumbs.vue +0 -44
  14. package/components/page-components/s-expand-row.vue +0 -113
  15. package/components/page-components/s-filter-button.vue +0 -41
  16. package/components/page-components/s-filter-chips.vue +0 -34
  17. package/components/page-components/s-filter-page.vue +0 -178
  18. package/components/page-components/s-filter-popup.vue +0 -155
  19. package/components/page-components/s-filter-slider.vue +0 -145
  20. package/components/page-components/s-filter-videos-chips.vue +0 -105
  21. package/components/page-components/s-filter.vue +0 -357
  22. package/components/page-components/s-footer-models.vue +0 -28
  23. package/components/page-components/s-info-grid.vue +0 -89
  24. package/components/page-components/s-info-socials.vue +0 -33
  25. package/components/page-components/s-like.vue +0 -121
  26. package/components/page-components/s-model-filters.vue +0 -235
  27. package/components/page-components/s-navigation-links.vue +0 -63
  28. package/components/page-components/s-pagination.vue +0 -214
  29. package/components/page-components/s-report.vue +0 -277
  30. package/components/page-components/s-section-title.vue +0 -35
  31. package/components/page-components/s-share.vue +0 -145
  32. package/components/playlist/s-playlist-add.vue +0 -299
  33. package/components/playlist/s-playlist-delete-video.vue +0 -79
  34. package/components/playlist/s-playlist-edit.vue +0 -215
  35. package/components/playlist/s-playlist-input.vue +0 -88
  36. package/components/playlist/s-playlist-private-toggle.vue +0 -20
  37. package/components/ui/s-avatar.vue +0 -33
  38. package/components/ui/s-button.vue +0 -51
  39. package/components/ui/s-checkbox.vue +0 -57
  40. package/components/ui/s-chips.vue +0 -142
  41. package/components/ui/s-count.vue +0 -17
  42. package/components/ui/s-dropdown.vue +0 -152
  43. package/components/ui/s-icon.vue +0 -19
  44. package/components/ui/s-img.vue +0 -59
  45. package/components/ui/s-input.vue +0 -181
  46. package/components/ui/s-label.vue +0 -20
  47. package/components/ui/s-link.vue +0 -46
  48. package/components/ui/s-notification.vue +0 -72
  49. package/components/ui/s-popup.vue +0 -119
  50. package/components/ui/s-radio.vue +0 -56
  51. package/components/ui/s-select.vue +0 -105
  52. package/components/ui/s-slider.vue +0 -67
  53. package/components/ui/s-snackbar.vue +0 -27
  54. package/components/ui/s-timestamp.vue +0 -59
  55. package/components/ui/s-toggle.vue +0 -30
  56. package/components/ui/s-tooltip.vue +0 -57
  57. package/components/video/s-video-autoplay.vue +0 -29
@@ -1,68 +0,0 @@
1
- <template>
2
- <div
3
- class="s-grid-videos"
4
- :class="[
5
- {'--first-hidden': hideFirstRow},
6
- ]"
7
- >
8
- <slot name="grid-start"/>
9
- <SVideoCard
10
- v-for="(item, index) in eagerItems"
11
- :key="`video-${item.guid}`"
12
- class="s-grid-videos__card"
13
- :card="item"
14
- :priority="priority && index < eagerCount"
15
- :loading="!related ? 'eager' : 'lazy'"
16
- :top-chips="topChips"
17
- :playlist-id="playlistId"
18
- :playlist="playlist"
19
- />
20
- <slot/>
21
- <LazySVideoCard
22
- v-for="item in idleItems"
23
- :key="`video-idle-${item.guid}`"
24
- class="s-grid-videos__card"
25
- :card="item"
26
- loading="lazy"
27
- :top-chips="topChips"
28
- :playlist-id="playlistId"
29
- :playlist="playlist"
30
- hydrate-on-idle
31
- />
32
- <LazySVideoCard
33
- v-for="item in lazyItems"
34
- :key="`video-lazy-${item.guid}`"
35
- class="s-grid-videos__card"
36
- :card="item"
37
- loading="lazy"
38
- :top-chips="topChips"
39
- :playlist-id="playlistId"
40
- :playlist="playlist"
41
- hydrate-on-visible
42
- />
43
- <slot name="grid-end"/>
44
- </div>
45
- </template>
46
-
47
- <script setup lang="ts">
48
- import type { IVideoCard } from '../../types';
49
-
50
- const IDLE_COUNT = 4;
51
-
52
- const props = defineProps<{
53
- items: Array<IVideoCard>
54
- hideFirstRow?: boolean
55
- priority?: boolean
56
- related?: boolean
57
- playlist?: boolean
58
- playlistId?: string
59
- topChips?: string[]
60
- }>();
61
-
62
- const isMobile = useState<boolean>('isMobile');
63
- const eagerCount = computed(() => isMobile.value ? 4 : 12);
64
-
65
- const eagerItems = computed(() => props.items.slice(0, eagerCount.value));
66
- const idleItems = computed(() => props.items.slice(eagerCount.value, eagerCount.value + IDLE_COUNT));
67
- const lazyItems = computed(() => props.items.slice(eagerCount.value + IDLE_COUNT));
68
- </script>
@@ -1,44 +0,0 @@
1
- <template>
2
- <nav class="s-breadcrumbs" aria-label="Breadcrumb" role="navigation" itemscope itemtype="https://schema.org/BreadcrumbList">
3
- <ol>
4
- <li
5
- v-for="(item, index) in resultItems"
6
- :key="`breadcrumb-${index}`"
7
- itemscope
8
- itemprop="itemListElement"
9
- itemtype="https://schema.org/ListItem"
10
- >
11
- <NuxtLink
12
- :to="generateLink(item.to || '/')"
13
- class="s-breadcrumbs__item"
14
- itemprop="item"
15
- >
16
- <span itemprop="name" v-html="item.name" />
17
- </NuxtLink>
18
- <meta itemprop="position" :content="String(index + 1)" >
19
- </li>
20
- <li
21
- itemscope
22
- itemprop="itemListElement"
23
- itemtype="https://schema.org/ListItem"
24
- >
25
- <span class="s-breadcrumbs__item" aria-current="page" itemprop="name" v-html="items[items.length - 1].name" />
26
- <meta itemprop="position" :content="String(items.length)" >
27
- </li>
28
- </ol>
29
- </nav>
30
- </template>
31
-
32
- <script setup lang="ts">
33
- import type { IBreadcrumbItem } from '../../types';
34
-
35
- const props = defineProps<{
36
- items: IBreadcrumbItem[]
37
- }>()
38
-
39
- const { generateLink } = useGenerateLink();
40
-
41
- const resultItems = computed(() => {
42
- return props.items.slice(0, props.items.length - 1)
43
- })
44
- </script>
@@ -1,113 +0,0 @@
1
- <template>
2
- <div
3
- ref="containerRef"
4
- class="s-expand-row"
5
- :class="[
6
- { '--expand-show': isExpandOpened },
7
- { '--alphabet': alphabet },
8
- { '--mobile-expand': mobileExpand },
9
- ]"
10
- >
11
- <div
12
- class="s-expand-row__wrapper"
13
- :class="[{ '--more-show': isElementsOverflow }]"
14
- >
15
- <slot name="prepend">
16
- <span v-if="preText" class="s-expand-row__pre-text">{{ preText }}</span>
17
- </slot>
18
- <slot>
19
- <SChips
20
- v-for="item in itemsResult"
21
- :key="item.title"
22
- :item="item"
23
- :alphabet="alphabet"
24
- is-link
25
- :mini="mini"
26
- />
27
- </slot>
28
- <div
29
- v-if="!hideMore"
30
- v-show="isElementsOverflow"
31
- class="s-expand-row__more-wrapper"
32
- :class="{'--small': mini}"
33
- >
34
- <SChips
35
- class="s-expand-row__button --more"
36
- :item="{
37
- title: moreButtonName,
38
- icon: isExpandOpened ? 'minus' : 'plus',
39
- }"
40
- :mini="mini"
41
- @click="onMoreClick"
42
- />
43
- </div>
44
- </div>
45
- </div>
46
- </template>
47
-
48
- <script setup lang="ts">
49
- import type { IChipsItem } from '../../types';
50
-
51
- const props = withDefaults(
52
- defineProps<{
53
- items?: IChipsItem[];
54
- alphabet?: boolean;
55
- hideMore?: boolean;
56
- mini?: boolean;
57
- mobileExpand?: boolean;
58
- maximumButtons?: number;
59
- preText?: string;
60
- }>(), {
61
- maximumButtons: 20, // вычислено на глаз, приблизительно
62
- }
63
- );
64
-
65
- const { t } = useI18n()
66
-
67
- const emit = defineEmits<{
68
- (eventName: 'more', eventValue: boolean): void
69
- }>()
70
-
71
- const containerRef = ref();
72
-
73
- const isExpandOpened = ref(false);
74
-
75
- const itemsResult = computed(() => {
76
- return props.items?.slice(
77
- 0,
78
- !props.alphabet && !isExpandOpened.value
79
- ? props.maximumButtons
80
- : props.items.length,
81
- );
82
- });
83
-
84
- const moreButtonName = computed(() => isExpandOpened.value ? t('less') : t('more'));
85
-
86
- const isElementsOverflow = ref(false);
87
-
88
- function checkIsElementOverflow() {
89
- isElementsOverflow.value = !!(
90
- containerRef.value &&
91
- containerRef.value.scrollHeight > containerRef.value.clientHeight
92
- );
93
- }
94
-
95
- function onMoreClick() {
96
- isExpandOpened.value = !isExpandOpened.value
97
- emit('more', isExpandOpened.value)
98
- }
99
-
100
- onMounted(() => {
101
- requestAnimationFrame(() => checkIsElementOverflow());
102
- });
103
-
104
- let checkTimer: ReturnType<typeof setTimeout> | null = null;
105
-
106
- watch(() => useRoute().query, () => {
107
- checkTimer = setTimeout(() => checkIsElementOverflow(), 100);
108
- });
109
-
110
- onBeforeUnmount(() => {
111
- if (checkTimer) clearTimeout(checkTimer);
112
- });
113
- </script>
@@ -1,41 +0,0 @@
1
- <template>
2
- <SButton
3
- class="s-filter-button"
4
- :size="size"
5
- :theme="theme"
6
- aria-label="Filter"
7
- :title="t('filter')"
8
- @click="emit('update:modelValue', true)"
9
- >
10
- <SIcon name="adjustments-horizontal" size="16"/>
11
- <span class="_from-sm"
12
- >{{ t('filter') }}
13
- </span>
14
- <span
15
- v-if="count > 0"
16
- class="s-filter-button__count"
17
- >{{ mobileCount }}</span>
18
- </SButton>
19
- </template>
20
-
21
- <script setup lang="ts">
22
- import type { ButtonSizes, ButtonThemes } from '../../types';
23
-
24
- const props = defineProps<{
25
- count: number
26
- modelValue: boolean
27
- size?: ButtonSizes
28
- theme?: ButtonThemes
29
- }>()
30
-
31
- const emit = defineEmits<{
32
- (eventName: 'update:modelValue', value: boolean): void
33
- }>()
34
-
35
- const { t } = useI18n()
36
-
37
- const mobileCount = computed(() => props.count > 9 ? '9+' : props.count);
38
- </script>
39
-
40
- <style scoped lang="scss">
41
- </style>
@@ -1,34 +0,0 @@
1
- <template>
2
- <SExpandRow v-if="items.length > 0">
3
- <template #prepend>
4
- <slot/>
5
- </template>
6
- <SChips
7
- v-for="(item, index) in items"
8
- class="s-filter-chips"
9
- with-close
10
- :index="`s-filter-page-chips${index}`"
11
- :item="item"
12
- @click="onChipsClick(item)"
13
- />
14
- </SExpandRow>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import type { IChipsItem } from '../../types';
19
-
20
- defineProps<{
21
- items: IChipsItem[]
22
- }>();
23
-
24
- const emit = defineEmits<{
25
- (eventName: 'click', eventValue: IChipsItem): void
26
- }>()
27
-
28
- function onChipsClick(item: IChipsItem) {
29
- emit('click', item)
30
- }
31
- </script>
32
-
33
- <style scoped lang="scss">
34
- </style>
@@ -1,178 +0,0 @@
1
- <template>
2
- <div class="s-filter-page">
3
- <div class="s-filter-page__items-wrapper">
4
- <h2
5
- v-if="title"
6
- class="s-filter-page__title"
7
- >{{ title }}
8
- </h2>
9
- <div
10
- v-for="(group, index) in groups"
11
- :key="`filter-group-${index}`"
12
- class="s-filter-page__group"
13
- :class="{'--short': group.name === 'tags'}"
14
- >
15
- <div
16
- v-if="filters.length > 0"
17
- class="s-filter-page__group-header"
18
- >
19
- <span class="s-filter-page__group-title">
20
- {{ group?.title }}
21
- </span>
22
- <SSegmentedControl
23
- v-if="group?.name === 'physical'"
24
- :items="unitItems"
25
- :model-value="units"
26
- small
27
- @update:model-value="units = $event"
28
- />
29
- </div>
30
- <div
31
- v-if="getGroupSliders(group?.name).length > 1"
32
- class="s-filter-page__sliders"
33
- :style="{ '--slider-count': getGroupSliders(group?.name).length }"
34
- >
35
- <SFilterSlider
36
- v-for="(item, subIndex) in getGroupSliders(group?.name)"
37
- :key="`slider-${subIndex}`"
38
- :item="item"
39
- :group-name="item.group.name"
40
- :index="subIndex"
41
- />
42
- </div>
43
- <div class="s-filter-page__items">
44
- <template v-for="(item, subIndex) in filters">
45
- <SFilterSlider
46
- v-if="(item.kind === 'range') && (item.group.name === group?.name) && !hiddenByUnits.has(item.name) && getGroupSliders(group?.name).length === 1"
47
- class="s-filter-page__slider"
48
- :item="item"
49
- :group-name="item.group.name"
50
- :index="subIndex"
51
- />
52
- <SSelect
53
- v-if="(item.kind === 'select') && (item.group.name === group?.name) && !hiddenByUnits.has(item.name)"
54
- class="s-filter-page__select"
55
- :key="`model-filter-select-${subIndex}`"
56
- :name="item.name"
57
- :model-value="getValue(item.name)"
58
- :items="selectItems(item)"
59
- size="s"
60
- :active="isActiveSelect(item.name)"
61
- :label="item.title"
62
- @update:model-value="val => updateFilter(item.name, val)"
63
- />
64
- <SSegmentedControl
65
- v-if="(item.kind === 'radio') && (item.group.name === group?.name)"
66
- class="s-filter-page__radio"
67
- :items="getRadioItems(item.options)"
68
- :title="item.title"
69
- :model-value="getValue(item.name)"
70
- @update:model-value="val => updateFilter(item.name, val)"
71
- />
72
- </template>
73
- </div>
74
- </div>
75
- </div>
76
- </div>
77
- </template>
78
-
79
- <script setup lang="ts">
80
- import type { IModelFilter, IModelFilterOptions } from '../../types';
81
-
82
- import { useRoute, useRouter } from 'vue-router';
83
-
84
- const props = defineProps<{
85
- filters: IModelFilter[]
86
- count: number
87
- title?: string
88
- }>();
89
-
90
- const route = useRoute();
91
- const router = useRouter();
92
-
93
- const { t } = useI18n();
94
-
95
- const { units, hiddenByUnits } = useUnits();
96
-
97
- watch(units, () => {
98
- const query = { ...route.query };
99
- const unitFields = ['height_cm', 'height_in', 'weight_kg', 'weight_lb'];
100
- for (const field of unitFields) {
101
- delete query[`filter_${field}_from`];
102
- delete query[`filter_${field}_to`];
103
- }
104
- router.replace({ query });
105
- });
106
-
107
- const unitItems = computed(() => [
108
- { name: 'imperial', title: t('units_imperial'), quantity: 0 },
109
- { name: 'metric', title: t('units_metric'), quantity: 0 },
110
- ]);
111
-
112
- const groups = computed(() => {
113
- const uniqueNames = [...new Set(props.filters.map(item => item.group.title))];
114
- return uniqueNames.map(name => {
115
- return props.filters.find(filter => filter.group.title === name)?.group;
116
- }).sort((a, b) => a?.order - b?.order)
117
- });
118
-
119
- function getGroupSliders(groupName: string) {
120
- return props.filters.filter(
121
- (item) => item.kind === 'range' && item.group.name === groupName && !hiddenByUnits.value.has(item.name)
122
- );
123
- }
124
-
125
- function selectItems(item: IModelFilter) {
126
- return [
127
- ...item.options.map(item => ({
128
- value: item.name,
129
- title: `${item.title} (${item.quantity})`,
130
- }))
131
- ]
132
- }
133
-
134
- function updateFilter(name: string, val: any) {
135
- const query = { ...route.query };
136
-
137
- if (!val || val === 'all') {
138
- delete query[ `filter_${name}` ];
139
- } else {
140
- query[ `filter_${name}` ] = val;
141
- }
142
-
143
- router.replace({ query });
144
- }
145
-
146
- function isActiveSelect(name: string) {
147
- const baseName = name.replace(/_(from|to)$/, '');
148
- return Object.keys(route.query).some(key => key.startsWith(`filter_${baseName}`));
149
- }
150
-
151
- function getValue(name: string) {
152
- const value = route.query[ `filter_${name}` ];
153
- if (value) {
154
- return value;
155
- }
156
- const filter = props.filters.find(f => f.name === name);
157
- if (filter && filter.options.length > 0) {
158
- return filter.options[ 0 ].name;
159
- }
160
- return null;
161
- }
162
-
163
- function getRadioItems(items: IModelFilterOptions[]) {
164
- const filteredItems = items.filter((item) => item.name !== 'unspecified');
165
- const order = ['all', 'yes'];
166
- return filteredItems.sort((a, b) => {
167
- const aIndex = order.indexOf(a.name);
168
- const bIndex = order.indexOf(b.name);
169
- if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
170
- if (aIndex !== -1) return -1;
171
- if (bIndex !== -1) return 1;
172
- return 0;
173
- });
174
- }
175
- </script>
176
-
177
- <style scoped lang="scss">
178
- </style>
@@ -1,155 +0,0 @@
1
- <template>
2
- <SPopup
3
- v-if="model"
4
- v-model="model"
5
- drawer
6
- class="s-filter-popup"
7
- >
8
- <template #title>
9
- <div class="s-filter-popup__title-wrapper">
10
- {{ title ?? t('filter') }}
11
- <span
12
- v-if="activeCount"
13
- class="s-filter-popup__active"
14
- >{{ activeCount }} active</span>
15
- </div>
16
- </template>
17
-
18
- <div
19
- class="s-filter-popup__content"
20
- :class="{ '_loading': loading }"
21
- >
22
- <div
23
- v-if="activeChips && activeChips.length > 0"
24
- class="s-filter-popup__active-filters"
25
- >
26
- <span class="s-filter-popup__active-filters-title">{{ t('filter_popup.active_title') }}</span>
27
- <div class="s-filter-popup__active-chips">
28
- <SChips
29
- v-for="(chip, index) in activeChips"
30
- :key="`s-filter-popup-active-${index}`"
31
- class="s-filter-popup__chips"
32
- with-close
33
- :index="`s-filter-popup-chips-${index}`"
34
- :item="chip"
35
- @click="$emit('chip-click', chip)"
36
- />
37
- </div>
38
- </div>
39
-
40
- <div
41
- v-if="quick && quick.length > 0"
42
- class="s-filter-popup__quick"
43
- >
44
- <span class="s-filter-popup__quick-title">{{ t('filter_popup.quick_title') }}</span>
45
- <div class="s-filter-popup__grid">
46
- <template v-for="(item, index) in quick" :key="`quick-${index}`">
47
- <slot
48
- name="quick-field"
49
- :item="item"
50
- :index="index"
51
- >
52
- <SSelect
53
- class="s-filter-popup__select"
54
- :name="(item as any).name"
55
- :model-value="(item as any).value"
56
- :items="(item as any).items"
57
- size="s"
58
- :is-first-placeholder="modelsPage"
59
- :active="(item as any).active"
60
- :label="(item as any).label ?? (item as any).title"
61
- :label-icon="(item as any).icon ? { icon: (item as any).icon, prefix: (item as any).iconPrefix ?? (modelsPage ? 'models' : 'categories') } : undefined"
62
- :placeholder="(item as any).placeholder"
63
- @update:model-value="val => $emit('field-update', { name: (item as any).name, value: val })"
64
- />
65
- </slot>
66
- </template>
67
- </div>
68
- </div>
69
-
70
- <details
71
- v-for="(group, groupIndex) in groups"
72
- :key="`group-${groupIndex}`"
73
- class="s-filter-popup__group"
74
- >
75
- <summary class="s-filter-popup__summary">
76
- <SIcon
77
- name="angle-right"
78
- size="16"
79
- class="s-filter-popup__summary-arrow"
80
- />
81
- <span class="s-filter-popup__summary-title">{{ group.title }}</span>
82
- <span class="s-filter-popup__summary-count">{{ t('filter_popup.fields', { count: group.count ?? group.fields.length }) }}</span>
83
- <span
84
- v-if="group.description"
85
- class="s-filter-popup__summary-description"
86
- >{{ group.description }}</span>
87
- </summary>
88
- <div class="s-filter-popup__group-content">
89
- <template
90
- v-for="(field, fieldIndex) in group.fields"
91
- :key="`field-${groupIndex}-${fieldIndex}`"
92
- >
93
- <slot
94
- name="field"
95
- :field="field"
96
- :group="group"
97
- :index="fieldIndex"
98
- >
99
- <SSelect
100
- class="s-filter-popup__select"
101
- :name="(field as any).name"
102
- :model-value="(field as any).value"
103
- :items="(field as any).items"
104
- size="s"
105
- :active="(field as any).active"
106
- :label="(field as any).label ?? (field as any).title"
107
- :label-icon="(field as any).icon ? { icon: (field as any).icon, prefix: (field as any).iconPrefix ?? (modelsPage ? 'models' : 'categories') } : undefined"
108
- :placeholder="(field as any).placeholder"
109
- @update:model-value="val => $emit('field-update', { name: (field as any).name, value: val })"
110
- />
111
- </slot>
112
- </template>
113
- </div>
114
- </details>
115
- </div>
116
-
117
- <template #footer>
118
- <slot name="footer"/>
119
- </template>
120
- </SPopup>
121
- </template>
122
-
123
- <script setup lang="ts" generic="TField">
124
- import type { IChipsItem } from '../../types';
125
-
126
- export interface FilterGroup<T> {
127
- key: string
128
- title: string
129
- description?: string
130
- count?: number
131
- fields: T[]
132
- }
133
-
134
- defineProps<{
135
- title?: string
136
- activeCount?: number
137
- activeChips?: IChipsItem[]
138
- quick?: TField[]
139
- groups?: FilterGroup<TField>[]
140
- loading?: boolean
141
- modelsPage?: boolean
142
- }>();
143
-
144
- defineEmits<{
145
- (e: 'chip-click', item: IChipsItem): void
146
- (e: 'field-update', payload: { name: string, value: any }): void
147
- }>();
148
-
149
- const model = defineModel<boolean>();
150
-
151
- const { t } = useI18n();
152
- </script>
153
-
154
- <style scoped lang="scss">
155
- </style>