itube-specs 0.0.321 → 0.0.323

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.
@@ -9,10 +9,11 @@
9
9
  <SImg
10
10
  class="s-video-mini-card__img"
11
11
  sizes="96px"
12
- :src="card.thumbUrl"
12
+ :src="currentPoster"
13
13
  width="96"
14
14
  height="64"
15
15
  :alt="card.title"
16
+ @error="onPosterError"
16
17
  />
17
18
  <SLabel
18
19
  class="s-video-mini-card__duration"
@@ -34,6 +35,8 @@ const props = defineProps<{
34
35
  prefix?: string
35
36
  }>()
36
37
 
38
+ const posterError = ref(false)
39
+
37
40
  const duration = computed(() => {
38
41
  return getDuration(props.card.duration)
39
42
  })
@@ -46,4 +49,15 @@ const component = computed(() => {
46
49
  })
47
50
 
48
51
  const { generateLink } = useGenerateLink();
52
+
53
+ const posterPlaceholder = '/img/placeholder.webp'
54
+
55
+ const currentPoster = computed(() => {
56
+ if (posterError.value) return posterPlaceholder
57
+ return props.card.thumbUrl || posterPlaceholder
58
+ })
59
+
60
+ function onPosterError() {
61
+ posterError.value = true
62
+ }
49
63
  </script>
@@ -0,0 +1,36 @@
1
+ import { useRoute } from 'vue-router';
2
+ import { EAsyncData, ELanguage } from '../runtime';
3
+ import type { IChannelCard, PaginatedResponse } from '../types';
4
+
5
+ export const useFetchChannelsByModel = (
6
+ apiMethod: (...args: any[]) => Promise<PaginatedResponse<IChannelCard>>
7
+ ) => {
8
+ const lang = useI18n().locale.value as ELanguage;
9
+ const route = useRoute();
10
+ const slug = useSlug();
11
+ const key = EAsyncData.ChannelsByModel;
12
+ const stateKey = computed(() => `data-${key}-${slug.value}-${lang}`);
13
+
14
+ const { data, status, error } = useAsyncData<PaginatedResponse<IChannelCard>>(
15
+ key,
16
+ () => useApiFetcher<PaginatedResponse<IChannelCard>>(
17
+ stateKey.value,
18
+ apiMethod,
19
+ lang,
20
+ {
21
+ page: 1,
22
+ },
23
+ slug.value,
24
+ )(),
25
+ {
26
+ watch: [
27
+ () => {
28
+ const currentQuery = route.query;
29
+ return JSON.stringify(currentQuery);
30
+ },
31
+ ],
32
+ }
33
+ );
34
+
35
+ return { data, status, error };
36
+ };
@@ -0,0 +1,23 @@
1
+ import { EAsyncData, ELanguage } from '../runtime';
2
+ import type { IPopularTagsModel } from '../types';
3
+
4
+ export const useFetchPopularTagsByModelName = (
5
+ apiMethod: (...args: any[]) => Promise<IPopularTagsModel[]>
6
+ ) => {
7
+ const lang = useI18n().locale.value as ELanguage;
8
+ const slug = useSlug();
9
+ const key = EAsyncData.PopularTagsByModel;
10
+ const stateKey = computed(() => `data-${key}-${slug.value}-${lang}`);
11
+
12
+ const { data, status, error } = useAsyncData<IPopularTagsModel[]>(
13
+ key,
14
+ () => useApiFetcher<IPopularTagsModel[]>(
15
+ stateKey.value,
16
+ apiMethod,
17
+ lang,
18
+ slug.value,
19
+ )()
20
+ );
21
+
22
+ return { data, status, error };
23
+ };
@@ -0,0 +1,48 @@
1
+ import { convertString, EAsyncData, ELanguage, getSelectedQuery } from '../runtime';
2
+ import type { IVideoCard, PaginatedResponse } from '../types';
3
+ import { selectAddedItems, selectDurationItems, sortItemsDefault } from '../lib';
4
+ import { useRoute } from 'vue-router';
5
+
6
+ export const useFetchVideosByModelAndChannel = async (apiMethod: (...args: any[]) => Promise<PaginatedResponse<IVideoCard>>) => {
7
+ const route = useRoute();
8
+ const { locale } = useI18n();
9
+ const lang = locale.value as ELanguage;
10
+ const slug = useSlug();
11
+ const channel = computed(() => {
12
+ const tagRaw = route.params['channel'];
13
+ const slug = convertString().fromSlug(String(tagRaw));
14
+ return Array.isArray(slug) ? slug[ 0 ] : slug;
15
+ });
16
+ const filters = computed(() => useGetVideosFilterRequest(route, selectDurationItems, selectAddedItems));
17
+ const key = EAsyncData.VideosByModelAndChannel;
18
+ const stateKey = computed(() => `data-${key}-${slug.value}-${channel.value}-${JSON.stringify(route.query)}-${lang}`);
19
+
20
+ const { data, status, error } = await useAsyncData<PaginatedResponse<IVideoCard>>(
21
+ key,
22
+ () => useApiFetcher<PaginatedResponse<IVideoCard>>(
23
+ stateKey.value,
24
+ apiMethod,
25
+ {
26
+ page: Number(route.query[ 'page' ]) || 1,
27
+ 'per-page': 48,
28
+ },
29
+ filters.value,
30
+ slug.value,
31
+ channel.value,
32
+ lang,
33
+ getSelectedQuery(route, sortItemsDefault) || '-popularity'
34
+ )(),
35
+ {
36
+ watch: [
37
+ () => {
38
+ if (route.query) {
39
+ const currentQuery = route.query;
40
+ return JSON.stringify(currentQuery);
41
+ }
42
+ },
43
+ ],
44
+ }
45
+ );
46
+
47
+ return { data, status, error };
48
+ };
@@ -0,0 +1,48 @@
1
+ import { convertString, EAsyncData, ELanguage, getSelectedQuery } from '../runtime';
2
+ import type { IVideoCard, PaginatedResponse } from '../types';
3
+ import { selectAddedItems, selectDurationItems, sortItemsDefault } from '../lib';
4
+ import { useRoute } from 'vue-router';
5
+
6
+ export const useFetchVideosByModelAndTag = async (apiMethod: (...args: any[]) => Promise<PaginatedResponse<IVideoCard>>) => {
7
+ const route = useRoute();
8
+ const { locale } = useI18n();
9
+ const lang = locale.value as ELanguage;
10
+ const slug = useSlug();
11
+ const tag = computed(() => {
12
+ const tagRaw = route.params['tag'];
13
+ const slug = convertString().fromSlug(String(tagRaw));
14
+ return Array.isArray(slug) ? slug[ 0 ] : slug;
15
+ });
16
+ const filters = computed(() => useGetVideosFilterRequest(route, selectDurationItems, selectAddedItems));
17
+ const key = EAsyncData.VideosByModelAndTag;
18
+ const stateKey = computed(() => `data-${key}-${slug.value}-${tag.value}-${JSON.stringify(route.query)}-${lang}`);
19
+
20
+ const { data, status, error } = await useAsyncData<PaginatedResponse<IVideoCard>>(
21
+ key,
22
+ () => useApiFetcher<PaginatedResponse<IVideoCard>>(
23
+ stateKey.value,
24
+ apiMethod,
25
+ {
26
+ page: Number(route.query[ 'page' ]) || 1,
27
+ 'per-page': 48,
28
+ },
29
+ filters.value,
30
+ slug.value,
31
+ tag.value,
32
+ lang,
33
+ getSelectedQuery(route, sortItemsDefault) || '-popularity'
34
+ )(),
35
+ {
36
+ watch: [
37
+ () => {
38
+ if (route.query) {
39
+ const currentQuery = route.query;
40
+ return JSON.stringify(currentQuery);
41
+ }
42
+ },
43
+ ],
44
+ }
45
+ );
46
+
47
+ return { data, status, error };
48
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itube-specs",
3
3
  "type": "module",
4
- "version": "0.0.321",
4
+ "version": "0.0.323",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "./types/index.d.ts",
7
7
  "scripts": {
@@ -49,4 +49,6 @@ export enum EAsyncData {
49
49
  SetPlaylistView = 'set-playlist-view',
50
50
  PopularTagsByModel = 'popular-tags-by-model',
51
51
  ChannelsByModel = 'channels-by-model',
52
+ VideosByModelAndChannel = 'videos-by-model-and-channel',
53
+ VideosByModelAndTag = 'videos-by-model-and-tag',
52
54
  }