forked from cc-archive/cccatalog-frontend
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPhotoDetailPage.vue
More file actions
167 lines (163 loc) · 4.7 KB
/
Copy pathPhotoDetailPage.vue
File metadata and controls
167 lines (163 loc) · 4.7 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<template>
<div class="photo-detail-page">
<header-section showNavSearch="true" />
<main role="main" aria-label="main content">
<photo-details
:image="image"
:breadCrumbURL="breadCrumbURL"
:shouldShowBreadcrumb="shouldShowBreadcrumb"
:query="query"
:imageWidth="imageWidth"
:imageHeight="imageHeight"
:imageType="imageType"
:socialSharingEnabled="socialSharingEnabled"
@onImageLoaded="onImageLoaded"
/>
<div class="padding-normal margin-vertical-big">
<photo-tags :tags="tags" :showHeader="true" />
</div>
<aside
role="complementary"
aria-label="related images"
class="padding-normal margin-vertical-big"
>
<related-images
:relatedImages="relatedImages"
:imagesCount="imagesCount"
:query="query"
:filter="filter"
:isPrimaryImageLoaded="isPrimaryImageLoaded"
/>
</aside>
</main>
<footer-section></footer-section>
</div>
</template>
<script>
import axios from 'redaxios'
import PhotoDetails from '@/components/ImageDetails/PhotoDetails'
import PhotoTags from '@/components/PhotoTags'
import RelatedImages from '@/components/RelatedImages'
import HeaderSection from '@/components/HeaderSection'
import FooterSection from '@/components/FooterSection'
import featureFlags from '@/featureFlags'
import { mapActions, mapMutations, mapState } from 'vuex'
import { FETCH_IMAGE, FETCH_RELATED_IMAGES } from '@/store/action-types'
import { SET_IMAGE } from '@/store/mutation-types'
const PhotoDetailPage = {
name: 'photo-detail-page',
props: {
id: {
type: String,
default: '',
},
},
components: {
HeaderSection,
RelatedImages,
FooterSection,
PhotoDetails,
PhotoTags,
},
data: () => ({
breadCrumbURL: '',
hasClarifaiTags: false,
imagecountseparator: 'of',
isPrimaryImageLoaded: false,
shouldShowBreadcrumb: false,
imageWidth: 0,
imageHeight: 0,
imageType: 'Unknown',
socialSharingEnabled: featureFlags.socialSharing,
}),
computed: mapState({
relatedImages: 'relatedImages',
filter: 'query.filter',
images: 'images',
imagesCount: 'imagesCount',
query: 'query',
tags: 'image.tags',
image: 'image',
}),
watch: {
image() {
this.getRelatedImages()
},
},
beforeRouteUpdate(to, from, next) {
// this is called when users navigate to this page.
// To avoid having previously loaded image being displayed,
// this resets the image data and then load the actual image that
// is supposed to be displayed.
this.resetImageOnRouteChanged()
this.loadImage(to.params.id)
next()
},
beforeRouteLeave(to, from, next) {
// this resets the image once the user navigates away from the page
this.resetImageOnRouteChanged()
next()
},
beforeRouteEnter(to, previousPage, nextPage) {
// sets the internal value shouldShowBreadcrumb so that the
// "back to search results" link is rendered with the correct link
// to the results page the user was before.
nextPage((_this) => {
if (
previousPage.path === '/search' ||
previousPage.path === '/search/image'
) {
_this.shouldShowBreadcrumb = true // eslint-disable-line no-param-reassign
_this.breadCrumbURL = `/search?q=${previousPage.query.q}` // eslint-disable-line no-param-reassign
}
})
},
methods: {
...mapActions([FETCH_RELATED_IMAGES, FETCH_IMAGE]),
...mapMutations([SET_IMAGE]),
resetImageOnRouteChanged() {
this.imageHeight = 0
this.imageWidth = 0
this.SET_IMAGE({ image: {} })
},
onImageLoaded(event) {
this.imageWidth = event.target.naturalWidth
this.imageHeight = event.target.naturalHeight
this.isPrimaryImageLoaded = true
// Make a HEAD request to get the image content-type header
// @todo: Should probably refactor this, just seems too trival to warrant it's own service or class
axios.head(event.target.src).then((res) => {
this.imageType = res.headers['content-type']
})
},
getRelatedImages() {
if (this.image && this.image.id) {
this.FETCH_RELATED_IMAGES({ id: this.image.id })
}
},
loadImage(id) {
return this.FETCH_IMAGE({ id })
},
},
mounted() {
if (!this.$store.state.image.id) {
return this.loadImage(this.$route.params.id)
}
return this.getRelatedImages()
},
serverPrefetch() {
return this.loadImage(this.$route.params.id)
},
metaInfo() {
return {
meta: [
{
vmid: 'monetization',
content: null,
},
],
}
},
}
export default PhotoDetailPage
</script>