Skip to content

Commit 11f5aa6

Browse files
committed
Add source and provider definition
Signed-off-by: Olga Bulat <obulat@gmail.com>
1 parent f830870 commit 11f5aa6

File tree

7 files changed

+98
-5
lines changed

7 files changed

+98
-5
lines changed

frontend/src/components/VIconButton/VIconButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default defineComponent({
4444
* The size of the button, matches the sizes of VButton component.
4545
*/
4646
size: {
47-
type: String as PropType<Exclude<ButtonSize, "disabled">>,
47+
type: String as PropType<ButtonSize>,
4848
required: true,
4949
},
5050
/**

frontend/src/components/VMediaInfo/VMetadata.vue

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<template>
22
<dl v-if="isSm" class="metadata grid gap-8" :style="columnCount">
33
<div v-for="datum in metadata" :key="`${datum.label}`">
4-
<dt class="label-regular mb-1 ps-1">{{ $t(datum.label) }}</dt>
4+
<dt class="label-regular mb-1 flex flex-row ps-1">
5+
{{ $t(datum.label) }}
6+
<VSourceProviderPopover
7+
v-if="datum.name && ['source', 'provider'].includes(datum.name)"
8+
:datum="datum"
9+
/>
10+
</dt>
511
<VMetadataValue
612
:datum="datum"
713
@click="sendVisitSourceLinkEvent(datum.source)"
@@ -10,8 +16,12 @@
1016
</dl>
1117
<dl v-else class="grid grid-cols-[auto,1fr] gap-x-4 gap-y-2">
1218
<template v-for="datum in metadata">
13-
<dt :key="`${datum.label}`" class="label-regular pt-1">
19+
<dt :key="`${datum.label}`" class="label-regular flex flex-row pt-1">
1420
{{ $t(datum.label) }}
21+
<VSourceProviderPopover
22+
v-if="datum.name && ['source', 'provider'].includes(datum.name)"
23+
:datum="datum"
24+
/>
1525
</dt>
1626
<VMetadataValue
1727
:key="`${datum.label}-value`"
@@ -30,10 +40,11 @@ import { useAnalytics } from "~/composables/use-analytics"
3040
import { useUiStore } from "~/stores/ui"
3141
3242
import VMetadataValue from "~/components/VMediaInfo/VMetadataValue.vue"
43+
import VSourceProviderPopover from "~/components/VMediaInfo/VSourceProviderPopover.vue"
3344
3445
export default defineComponent({
3546
name: "VMetadata",
36-
components: { VMetadataValue },
47+
components: { VSourceProviderPopover, VMetadataValue },
3748
props: {
3849
metadata: {
3950
type: Array as PropType<Metadata[]>,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<VPopover placement="top" :activate-on-hover="true">
3+
<template #trigger>
4+
<VIconButton
5+
:label="datum.label"
6+
variant="filled-white"
7+
size="disabled"
8+
class="ms-2 h-4 w-4"
9+
:icon-props="{ name: 'info', size: 4 }"
10+
/>
11+
</template>
12+
<template #default>
13+
<p
14+
class="caption-regular rounded-sm bg-dark-charcoal px-2 py-1 text-white"
15+
tabindex="0"
16+
>
17+
{{ description }}
18+
</p>
19+
</template>
20+
</VPopover>
21+
</template>
22+
<script lang="ts">
23+
import { computed, defineComponent, PropType } from "vue"
24+
25+
import type { Metadata } from "~/types/media"
26+
import { useI18n } from "~/composables/use-i18n"
27+
28+
import VIconButton from "~/components/VIconButton/VIconButton.vue"
29+
import VPopover from "~/components/VPopover/VPopover.vue"
30+
31+
export default defineComponent({
32+
name: "VSourceProviderPopover",
33+
components: { VIconButton, VPopover },
34+
props: {
35+
datum: {
36+
type: Object as PropType<Metadata>,
37+
required: true,
38+
},
39+
},
40+
setup(props) {
41+
const i18n = useI18n()
42+
const description = computed(() => {
43+
if (!props.datum.name) return ""
44+
return i18n.t(
45+
props.datum.name === "source"
46+
? "mediaDetails.sourceDescription"
47+
: "mediaDetails.providerDescription"
48+
)
49+
})
50+
51+
return {
52+
description,
53+
}
54+
},
55+
})
56+
</script>

frontend/src/components/VPopover/VPopover.vue

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
ref="triggerContainerRef"
77
class="flex w-min items-stretch whitespace-nowrap"
88
@click="onTriggerClick"
9+
@mouseenter="onTriggerMouseEnter"
10+
@focusin="onTriggerMouseEnter"
11+
@mouseleave="onTriggerMouseLeave"
12+
@focusout="onTriggerMouseLeave"
913
>
1014
<!--
1115
@slot The trigger, should be a button 99.99% of the time. If you need custom event handling on the trigger button, ensure bubbling is not prevented or else the popover will not open
@@ -64,6 +68,10 @@ export default defineComponent({
6468
* default for each of them can take over.
6569
*/
6670
props: {
71+
/**
72+
* Whether the popover should show when the trigger is hovered on.
73+
*/
74+
activateOnHover: { type: Boolean, default: undefined },
6775
/**
6876
* Whether the popover should hide when the <kbd>Escape</kbd> key is pressed.
6977
*
@@ -164,7 +172,7 @@ export default defineComponent({
164172
*/
165173
"close",
166174
],
167-
setup(_, { emit }) {
175+
setup(props, { emit }) {
168176
const visibleRef = ref(false)
169177
const triggerContainerRef = ref<HTMLElement | null>(null)
170178
@@ -179,13 +187,26 @@ export default defineComponent({
179187
emit: emit as SetupContext["emit"],
180188
})
181189
190+
const onTriggerMouseEnter = () => {
191+
if (props.activateOnHover) {
192+
open()
193+
}
194+
}
195+
const onTriggerMouseLeave = () => {
196+
if (props.activateOnHover) {
197+
close()
198+
}
199+
}
200+
182201
return {
183202
open,
184203
close,
185204
visibleRef,
186205
triggerContainerRef,
187206
triggerRef,
188207
onTriggerClick,
208+
onTriggerMouseEnter,
209+
onTriggerMouseLeave,
189210
triggerA11yProps,
190211
}
191212
},

frontend/src/locales/scripts/en.json5

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@
541541
},
542542
providerLabel: "Provider",
543543
sourceLabel: "Source",
544+
providerDescription: "Website where the content is hosted",
545+
sourceDescription: "Organization that created or owns the original content",
544546
loading: "Loading...",
545547
relatedError: "Error fetching related media",
546548
aria: {

frontend/src/types/media.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export const isMediaDetail = <T extends SupportedMediaType>(
131131
}
132132

133133
export type Metadata = {
134+
name?: string
134135
label: string
135136
url?: string
136137
value: string

frontend/src/utils/metadata.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const getMediaMetadata = (
4040
const metadata: Metadata[] = []
4141
if (media.source && media.providerName !== media.sourceName) {
4242
metadata.push({
43+
name: "provider",
4344
label: "mediaDetails.providerLabel",
4445
value: media.providerName || media.provider,
4546
})
@@ -50,6 +51,7 @@ export const getMediaMetadata = (
5051
)
5152
const sourceName = media.sourceName ?? media.providerName ?? media.provider
5253
metadata.push({
54+
name: "source",
5355
label: "mediaDetails.sourceLabel",
5456
source: media.source ?? media.provider,
5557
url: sourceUrl,

0 commit comments

Comments
 (0)