itube-specs 0.0.760 → 0.0.762

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 (58) hide show
  1. package/composables/use-noindex.ts +11 -0
  2. package/package.json +1 -1
  3. package/components/auth/s-auth-icon.vue +0 -20
  4. package/components/auth/s-auth-login.vue +0 -120
  5. package/components/auth/s-auth-popup.vue +0 -69
  6. package/components/auth/s-auth-recovery.vue +0 -104
  7. package/components/auth/s-auth-register.vue +0 -176
  8. package/components/cards/s-video-mini-card.vue +0 -62
  9. package/components/grids/s-grid-categories.vue +0 -20
  10. package/components/grids/s-grid-channels.vue +0 -23
  11. package/components/grids/s-grid-models.vue +0 -25
  12. package/components/grids/s-grid-playlists.vue +0 -21
  13. package/components/grids/s-grid-videos.vue +0 -68
  14. package/components/page-components/s-breadcrumbs.vue +0 -44
  15. package/components/page-components/s-expand-row.vue +0 -113
  16. package/components/page-components/s-filter-button.vue +0 -41
  17. package/components/page-components/s-filter-chips.vue +0 -34
  18. package/components/page-components/s-filter-page.vue +0 -178
  19. package/components/page-components/s-filter-popup.vue +0 -155
  20. package/components/page-components/s-filter-slider.vue +0 -145
  21. package/components/page-components/s-filter-videos-chips.vue +0 -105
  22. package/components/page-components/s-filter.vue +0 -357
  23. package/components/page-components/s-footer-models.vue +0 -28
  24. package/components/page-components/s-info-grid.vue +0 -89
  25. package/components/page-components/s-info-socials.vue +0 -33
  26. package/components/page-components/s-like.vue +0 -121
  27. package/components/page-components/s-model-filters.vue +0 -235
  28. package/components/page-components/s-navigation-links.vue +0 -63
  29. package/components/page-components/s-pagination.vue +0 -214
  30. package/components/page-components/s-report.vue +0 -277
  31. package/components/page-components/s-section-title.vue +0 -35
  32. package/components/page-components/s-share.vue +0 -145
  33. package/components/playlist/s-playlist-add.vue +0 -299
  34. package/components/playlist/s-playlist-delete-video.vue +0 -79
  35. package/components/playlist/s-playlist-edit.vue +0 -215
  36. package/components/playlist/s-playlist-input.vue +0 -88
  37. package/components/playlist/s-playlist-private-toggle.vue +0 -20
  38. package/components/ui/s-avatar.vue +0 -33
  39. package/components/ui/s-button.vue +0 -51
  40. package/components/ui/s-checkbox.vue +0 -57
  41. package/components/ui/s-chips.vue +0 -142
  42. package/components/ui/s-count.vue +0 -17
  43. package/components/ui/s-dropdown.vue +0 -152
  44. package/components/ui/s-icon.vue +0 -19
  45. package/components/ui/s-img.vue +0 -59
  46. package/components/ui/s-input.vue +0 -181
  47. package/components/ui/s-label.vue +0 -20
  48. package/components/ui/s-link.vue +0 -46
  49. package/components/ui/s-notification.vue +0 -72
  50. package/components/ui/s-popup.vue +0 -119
  51. package/components/ui/s-radio.vue +0 -56
  52. package/components/ui/s-select.vue +0 -105
  53. package/components/ui/s-slider.vue +0 -67
  54. package/components/ui/s-snackbar.vue +0 -27
  55. package/components/ui/s-timestamp.vue +0 -59
  56. package/components/ui/s-toggle.vue +0 -30
  57. package/components/ui/s-tooltip.vue +0 -57
  58. 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>