Skip to content

Commit b7d7ede

Browse files
committed
feat(links): adds custom links and alias integration
1 parent b29ddb4 commit b7d7ede

File tree

8 files changed

+306
-7
lines changed

8 files changed

+306
-7
lines changed

src/components/views/panel/MoviePanelDetails.vue

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { computed, type PropType, toRefs } from 'vue';
44
55
import type { TraktMovieExtended } from '~/models/trakt/trakt-movie.model';
66
7+
import PanelAlias from '~/components/views/panel/PanelAlias.vue';
78
import PanelDetail from '~/components/views/panel/PanelDetail.vue';
89
910
import PanelLinks from '~/components/views/panel/PanelLinks.vue';
@@ -113,6 +114,13 @@ const country = computed(() => {
113114
/>
114115
</NFlex>
115116

117+
<!-- Movie name alias -->
118+
<PanelAlias
119+
:id="movie?.ids?.trakt.toString()"
120+
scope="movie"
121+
:placeholder="movie?.title"
122+
/>
123+
116124
<NFlex class="lists" vertical size="large">
117125
<!-- Genres -->
118126
<PanelDetail
@@ -123,7 +131,7 @@ const country = computed(() => {
123131
/>
124132

125133
<!-- links -->
126-
<PanelLinks :ids="movie?.ids" mode="movie" />
134+
<PanelLinks :ids="movie?.ids" mode="movie" :title="movie?.title" />
127135
</NFlex>
128136
</NFlex>
129137
</template>
@@ -136,6 +144,6 @@ const country = computed(() => {
136144
}
137145
138146
.lists {
139-
margin: 1.25rem 0 1rem;
147+
margin: 0.25rem 0 1.25rem;
140148
}
141149
</style>
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<script lang="ts" setup>
2+
import { NFlex, NInput } from 'naive-ui';
3+
import { computed, nextTick, type PropType, ref, toRefs } from 'vue';
4+
5+
import type { InputInst } from 'naive-ui';
6+
7+
import PanelDetail from '~/components/views/panel/PanelDetail.vue';
8+
import {
9+
type AliasScope,
10+
useLinksStore,
11+
useLinksStoreRefs,
12+
} from '~/stores/settings/links.store';
13+
import { useI18n } from '~/utils';
14+
15+
const props = defineProps({
16+
id: {
17+
type: String,
18+
required: false,
19+
default: null,
20+
},
21+
scope: {
22+
type: String as PropType<AliasScope>,
23+
required: true,
24+
},
25+
placeholder: {
26+
type: String,
27+
required: false,
28+
default: 'none',
29+
},
30+
});
31+
32+
const { scope, id, placeholder } = toRefs(props);
33+
34+
const { aliasEnabled } = useLinksStoreRefs();
35+
const { getAlias } = useLinksStore();
36+
37+
const alias = getAlias(scope.value, id);
38+
39+
const value = computed(() => {
40+
if (!id.value) return;
41+
return alias.value || placeholder.value;
42+
});
43+
44+
const hover = ref(false);
45+
const focus = ref(false);
46+
47+
const inputRef = ref<InputInst>();
48+
49+
const onClick = async () => {
50+
if (!id.value || !aliasEnabled.value) return;
51+
hover.value = true;
52+
await nextTick();
53+
inputRef.value?.focus();
54+
};
55+
56+
const i18n = useI18n('panel', 'alias');
57+
</script>
58+
59+
<template>
60+
<NFlex
61+
v-if="aliasEnabled"
62+
class="alias-container"
63+
vertical
64+
size="large"
65+
justify="center"
66+
>
67+
<!-- Alias Input -->
68+
<NInput
69+
v-if="hover || focus"
70+
ref="inputRef"
71+
v-model:value="alias"
72+
class="alias-input"
73+
:placeholder="placeholder"
74+
@focus="focus = true"
75+
@blur="focus = false"
76+
@mouseleave="hover = false"
77+
>
78+
<template #prefix>
79+
<span class="alias-prefix">{{ i18n('label') }}</span>
80+
</template>
81+
</NInput>
82+
83+
<!-- Alias -->
84+
<PanelDetail
85+
v-else
86+
class="alias-detail"
87+
:label="i18n('label')"
88+
:value="value"
89+
:skeleton="{ width: '6.25rem' }"
90+
@click="onClick"
91+
/>
92+
</NFlex>
93+
</template>
94+
95+
<style lang="scss" scoped>
96+
.alias-container {
97+
box-sizing: border-box;
98+
min-height: 36px;
99+
}
100+
101+
.alias-detail {
102+
border-top: 1px solid transparent;
103+
}
104+
105+
.alias-input {
106+
margin: 0 -0.75rem;
107+
font-size: 1rem;
108+
109+
.alias-prefix {
110+
min-width: 3rem;
111+
color: var(--white-50);
112+
font-weight: 600;
113+
}
114+
}
115+
</style>

src/components/views/panel/PanelLinks.vue

+30-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import { computed, type PropType, toRefs } from 'vue';
44
import type { TagLink } from '~/models/tag.model';
55
import type { TraktApiIds } from '~/models/trakt/trakt-id.model';
66
7+
import IconExternalLinkRounded from '~/components/icons/IconExternalLinkRounded.vue';
78
import IconIMDb from '~/components/icons/IconIMDb.vue';
89
import IconTMDb from '~/components/icons/IconTMDb.vue';
910
import IconTVDb from '~/components/icons/IconTVDb.vue';
1011
import IconTrakt from '~/components/icons/IconTrakt.vue';
1112
import PanelDetail from '~/components/views/panel/PanelDetail.vue';
1213
1314
import { ResolveExternalLinks } from '~/settings/external.links';
15+
import { resolveLinkUrl, useLinksStore } from '~/stores/settings/links.store';
1416
import { useI18n } from '~/utils';
1517
1618
const props = defineProps({
@@ -31,9 +33,17 @@ const props = defineProps({
3133
type: Number,
3234
required: false,
3335
},
36+
alias: {
37+
type: String,
38+
required: false,
39+
},
40+
title: {
41+
type: String,
42+
required: false,
43+
},
3444
});
3545
36-
const { ids, mode, season, episode } = toRefs(props);
46+
const { ids, mode, season, episode, alias, title } = toRefs(props);
3747
3848
const i18n = useI18n('panel', 'detail');
3949
@@ -46,6 +56,24 @@ const labelKey = computed(() => {
4656
};
4757
});
4858
59+
const { getLinks } = useLinksStore();
60+
61+
const customLinksTemplate = getLinks(mode);
62+
const customLinks = computed(() => {
63+
if (!customLinksTemplate.value) return;
64+
return customLinksTemplate.value.map(link => ({
65+
...link,
66+
url: resolveLinkUrl(link.url, {
67+
...ids?.value,
68+
alias: alias?.value,
69+
season: season?.value,
70+
episode: episode?.value,
71+
title: title?.value,
72+
}),
73+
icon: IconExternalLinkRounded,
74+
}));
75+
});
76+
4977
const links = computed(() => {
5078
if (!ids?.value) return;
5179
const _links: TagLink[] = [];
@@ -112,6 +140,7 @@ const links = computed(() => {
112140
},
113141
});
114142
}
143+
if (customLinks.value) _links.push(...customLinks.value);
115144
return _links;
116145
});
117146
</script>

src/components/views/panel/ShowPanelDetails.vue

+20-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import type { TraktEpisodeExtended } from '~/models/trakt/trakt-episode.model';
66
import type { TraktSeasonExtended } from '~/models/trakt/trakt-season.model';
77
import type { TraktShowExtended } from '~/models/trakt/trakt-show.model';
88
9+
import PanelAlias from '~/components/views/panel/PanelAlias.vue';
910
import PanelDetail from '~/components/views/panel/PanelDetail.vue';
1011
1112
import PanelLinks from '~/components/views/panel/PanelLinks.vue';
13+
import { useLinksStore } from '~/stores/settings/links.store';
1214
import { useI18n } from '~/utils';
13-
import { capitalizeEachWord } from '~/utils/string.utils';
15+
import { capitalizeEachWord, deCapitalise } from '~/utils/string.utils';
1416
1517
const props = defineProps({
1618
episode: {
@@ -133,6 +135,14 @@ const ids = computed(() => {
133135
if (!show?.value) return;
134136
return show.value?.ids;
135137
});
138+
139+
const title = computed(() =>
140+
deCapitalise(episode?.value?.title ?? season?.value?.title ?? show?.value?.title),
141+
);
142+
143+
const { getAlias } = useLinksStore();
144+
const showId = computed(() => show?.value?.ids?.trakt.toString());
145+
const alias = getAlias('show', showId);
136146
</script>
137147

138148
<template>
@@ -205,6 +215,13 @@ const ids = computed(() => {
205215
/>
206216
</NFlex>
207217

218+
<!-- Show name alias -->
219+
<PanelAlias
220+
:id="show?.ids?.trakt.toString()"
221+
scope="show"
222+
:placeholder="show?.title"
223+
/>
224+
208225
<NFlex class="lists" vertical size="large">
209226
<!-- Genres -->
210227
<PanelDetail
@@ -220,6 +237,8 @@ const ids = computed(() => {
220237
:mode="mode"
221238
:season="episode?.season ?? season?.number"
222239
:episode="episode?.number"
240+
:alias="alias"
241+
:title="title"
223242
/>
224243
</NFlex>
225244
</NFlex>

src/i18n/en/panel/panel-alias.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"panel__alias__label": {
3+
"message": "Alias",
4+
"description": "Label for the alias field"
5+
}
6+
}

src/stores/data/list.store.ts

-3
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,6 @@ export const useListStore = defineStore('data.list', () => {
383383
]
384384
.filter(Boolean)
385385
.join(' '),
386-
{
387-
duration: 50000,
388-
},
389386
);
390387
} catch (e) {
391388
console.error('Failed to add item to list');

0 commit comments

Comments
 (0)