-
Notifications
You must be signed in to change notification settings - Fork 171
/
report.vue
112 lines (103 loc) · 3.16 KB
/
report.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<template>
<VSkipToContentContainer
as="main"
class="mx-auto mb-6 mt-8 max-w-none gap-x-10 px-4 md:grid md:max-w-4xl md:grid-cols-2 md:px-6 lg:mb-30 lg:px-0 xl:max-w-4xl"
>
<figure class="mb-6 flex flex-col items-start gap-y-4">
<img
id="main-image"
:src="imageSrc"
:alt="image.title"
class="mx-auto h-auto w-full rounded-sm"
:width="imageWidth"
:height="imageHeight"
/>
<!-- Disable reason: We control the attribution HTML generation so this is safe and will not lead to XSS attacks -->
<!-- eslint-disable vue/no-v-html -->
<figcaption
class="block w-full text-left text-sr"
v-html="getAttributionMarkup({ includeIcons: false })"
/>
<!-- eslint-enable vue/no-v-html -->
<VButton
variant="bordered-gray"
:href="`/image/${image.id}`"
as="VLink"
size="medium"
class="label-bold"
>
{{ $t("report.image-details") }}
</VButton>
</figure>
<VContentReportForm
:close-fn="() => {}"
:media="image"
:allow-cancel="false"
:provider-name="image.providerName"
/>
</VSkipToContentContainer>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from "vue"
import { useI18n } from "~/composables/use-i18n"
import { IMAGE } from "~/constants/media"
import { useSingleResultStore } from "~/stores/media/single-result"
import type { ImageDetail } from "~/types/media"
import { AttributionOptions, getAttribution } from "~/utils/attribution-html"
import VButton from "~/components/VButton.vue"
import VContentReportForm from "~/components/VContentReport/VContentReportForm.vue"
import VSkipToContentContainer from "~/components/VSkipToContentContainer.vue"
export default defineComponent({
name: "ReportImage",
components: {
VButton,
VContentReportForm,
VSkipToContentContainer,
},
layout: "content-layout",
setup() {
const i18n = useI18n()
const singleResultStore = useSingleResultStore()
const image = computed(() =>
singleResultStore.mediaType === IMAGE
? (singleResultStore.mediaItem as ImageDetail)
: null
)
const imageWidth = ref(0)
const imageHeight = ref(0)
const imageType = ref("Unknown")
/**
* To make sure that image is loaded fast, we `src` to `image.thumbnail`,
* and then replace it with the provider image once it is loaded.
*/
const imageSrc = ref(image.value.thumbnail)
const getAttributionMarkup = (options?: AttributionOptions) =>
getAttribution(image.value, i18n, options)
return {
image,
imageWidth,
imageHeight,
imageType,
imageSrc,
getAttributionMarkup,
}
},
async asyncData({ app, error, route, $pinia }) {
const imageId = route.params.id
const singleResultStore = useSingleResultStore($pinia)
try {
await singleResultStore.fetch(IMAGE, imageId)
} catch (err) {
const errorMessage = app.i18n
.t("error.image-not-found", {
id: imageId,
})
.toString()
return error({
statusCode: 404,
message: errorMessage,
})
}
},
})
</script>