@lancom/shared 0.0.218 → 0.0.219
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.
|
@@ -1,94 +1,69 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
class="Gallery__wrapper"
|
|
4
|
-
@click="canLoadImages = true">
|
|
2
|
+
<div class="Gallery__wrapper">
|
|
5
3
|
<div class="Gallery__big">
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
:infinite="false"
|
|
12
|
-
:swipe="false"
|
|
13
|
-
:speed="800"
|
|
14
|
-
@beforeChange="onChange">
|
|
4
|
+
<div class="Gallery__big-image">
|
|
5
|
+
<img
|
|
6
|
+
:src="staticLink(currentImage.large)"
|
|
7
|
+
:alt="product.name"
|
|
8
|
+
class="Gallery__big-image-src" />
|
|
15
9
|
<div
|
|
16
|
-
v-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
v-hammer:panend="onPanend"
|
|
22
|
-
class="Gallery__big-image"
|
|
23
|
-
:style="{
|
|
24
|
-
// 'background-image': `url(${staticLink(image.large)}`,
|
|
25
|
-
// 'background-size': backgroundSize,
|
|
26
|
-
// 'background-position': backgroundPosition,
|
|
27
|
-
'touch-action': zoomEnable ? 'none' : 'auto'
|
|
28
|
-
}"
|
|
29
|
-
@mousedown="onMouseDown"
|
|
30
|
-
@mouseenter="onMouseEnter"
|
|
31
|
-
@mouseleave="onMouseLeave"
|
|
32
|
-
@mousemove="onMouseMove">
|
|
33
|
-
<img
|
|
34
|
-
v-if="index === 0 || canLoadImages"
|
|
35
|
-
:src="staticLink(image.large)"
|
|
36
|
-
:alt="product.name"
|
|
37
|
-
class="Gallery__big-image-src" />
|
|
10
|
+
v-if="currentImage.print"
|
|
11
|
+
class="Gallery__big-print">
|
|
12
|
+
<div class="Gallery__big-print-name">
|
|
13
|
+
{{ currentImage.print.name }}
|
|
14
|
+
</div>
|
|
38
15
|
<div
|
|
39
|
-
v-if="
|
|
40
|
-
class="Gallery__big-print">
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
v-if="image.print.pricing"
|
|
46
|
-
class="Gallery__big-print-price">
|
|
47
|
-
Printing at <price :price="image.print.pricing.price" /> for ({{ image.print.pricing.min || 1 }}+)
|
|
48
|
-
</div>
|
|
49
|
-
<div class="Gallery__big-print-price-info">
|
|
50
|
-
example only
|
|
51
|
-
</div>
|
|
16
|
+
v-if="currentImage.print.pricing"
|
|
17
|
+
class="Gallery__big-print-price">
|
|
18
|
+
Printing at <price :price="currentImage.print.pricing.price" /> for ({{ image.print.pricing.min || 1 }}+)
|
|
19
|
+
</div>
|
|
20
|
+
<div class="Gallery__big-print-price-info">
|
|
21
|
+
example only
|
|
52
22
|
</div>
|
|
53
23
|
</div>
|
|
54
|
-
</vue-slick-carousel> -->
|
|
55
|
-
<div
|
|
56
|
-
v-if="!isTouch"
|
|
57
|
-
class="Gallery__zoom"
|
|
58
|
-
@click="onMouseDown($event)">
|
|
59
|
-
<i :class="zoomEnable ? 'icon-zoom-out' : 'icon-zoom-in'"></i>
|
|
60
24
|
</div>
|
|
25
|
+
<button
|
|
26
|
+
type="button"
|
|
27
|
+
class="slick-arrow slick-prev slick-disabled"
|
|
28
|
+
@click="goToPrev()">
|
|
29
|
+
Previous
|
|
30
|
+
</button>
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
class="slick-arrow slick-next"
|
|
34
|
+
@click="goToNext()">
|
|
35
|
+
Next
|
|
36
|
+
</button>
|
|
61
37
|
</div>
|
|
62
38
|
<div class="Gallery__small">
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
:key="
|
|
66
|
-
|
|
67
|
-
:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
:
|
|
74
|
-
class="Gallery__small-image"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}"
|
|
78
|
-
@click="goToSlideAndChangeColor(index)"
|
|
79
|
-
:style="{
|
|
80
|
-
// 'background-image': `url(${staticLink(image.small)}`
|
|
81
|
-
}">
|
|
82
|
-
<img
|
|
83
|
-
v-if="index < 6 || canLoadImages"
|
|
84
|
-
:src="staticLink(image.small)"
|
|
85
|
-
:alt="product.name"
|
|
86
|
-
class="Gallery__small-image-src" />
|
|
87
|
-
<div class="Gallery__small-printed">
|
|
88
|
-
{{ image.printType ? 'Printed' : (product.prePrint ? product.prePrintText : image.colorName || 'Blank') }}
|
|
89
|
-
</div>
|
|
39
|
+
<div
|
|
40
|
+
v-for="(image, index) in visibleImages"
|
|
41
|
+
:key="image.large"
|
|
42
|
+
class="Gallery__small-image"
|
|
43
|
+
:class="{
|
|
44
|
+
'Gallery__small-image--active': (visibleImagesFrom + index) === activeIndex
|
|
45
|
+
}"
|
|
46
|
+
@click="goToSlideAndChangeColor(visibleImagesFrom + index)">
|
|
47
|
+
<img
|
|
48
|
+
:src="staticLink(image.small)"
|
|
49
|
+
:alt="product.name"
|
|
50
|
+
class="Gallery__small-image-src" />
|
|
51
|
+
<div class="Gallery__small-printed">
|
|
52
|
+
{{ image.printType ? 'Printed' : (product.prePrint ? product.prePrintText : image.colorName || 'Blank') }}
|
|
90
53
|
</div>
|
|
91
|
-
</
|
|
54
|
+
</div>
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
class="slick-arrow slick-prev slick-disabled"
|
|
58
|
+
@click="goToPrevPage()">
|
|
59
|
+
Previous
|
|
60
|
+
</button>
|
|
61
|
+
<button
|
|
62
|
+
type="button"
|
|
63
|
+
class="slick-arrow slick-next"
|
|
64
|
+
@click="goToNextPage()">
|
|
65
|
+
Next
|
|
66
|
+
</button>
|
|
92
67
|
</div>
|
|
93
68
|
<div
|
|
94
69
|
v-if="hasValidFilters"
|
|
@@ -112,8 +87,6 @@
|
|
|
112
87
|
|
|
113
88
|
<script>
|
|
114
89
|
import { mapGetters, mapActions } from 'vuex';
|
|
115
|
-
// import VueSlickCarousel from 'vue-slick-carousel';
|
|
116
|
-
// import 'vue-slick-carousel/dist/vue-slick-carousel.css';
|
|
117
90
|
import { staticLink } from '@lancom/shared/assets/js/utils/filters';
|
|
118
91
|
import { isValidImageTypes } from '@lancom/shared/assets/js/utils/colors';
|
|
119
92
|
import Price from '@lancom/shared/components/common/price';
|
|
@@ -121,7 +94,6 @@ import Price from '@lancom/shared/components/common/price';
|
|
|
121
94
|
export default {
|
|
122
95
|
name: 'Gallery',
|
|
123
96
|
components: {
|
|
124
|
-
// VueSlickCarousel,
|
|
125
97
|
Price
|
|
126
98
|
},
|
|
127
99
|
props: {
|
|
@@ -132,10 +104,8 @@ export default {
|
|
|
132
104
|
},
|
|
133
105
|
data() {
|
|
134
106
|
return {
|
|
135
|
-
isTouch: ('ontouchstart' in window),
|
|
136
|
-
zoomEnable: false,
|
|
137
107
|
activeIndex: 0,
|
|
138
|
-
|
|
108
|
+
thumbsPage: 0,
|
|
139
109
|
updateCarouselTime: Date.now(),
|
|
140
110
|
filters: [{
|
|
141
111
|
name: 'FRONT / BACK',
|
|
@@ -162,6 +132,15 @@ export default {
|
|
|
162
132
|
validFilters() {
|
|
163
133
|
return this.filters.filter(filter => (this.images || []).some(i => this.isValidImageByFilter(filter, i)));
|
|
164
134
|
},
|
|
135
|
+
currentImage() {
|
|
136
|
+
return this.filteredImages[this.activeIndex];
|
|
137
|
+
},
|
|
138
|
+
visibleImagesFrom() {
|
|
139
|
+
return this.thumbsPage * this.slidesPerRow;
|
|
140
|
+
},
|
|
141
|
+
visibleImages() {
|
|
142
|
+
return this.filteredImages.slice(this.visibleImagesFrom, this.visibleImagesFrom + this.slidesPerRow);
|
|
143
|
+
},
|
|
165
144
|
filteredImages() {
|
|
166
145
|
const images = this.filterType ? this.images.filter(i => this.isValidImageByFilter(this.filterType, i)) : this.images;
|
|
167
146
|
return images.map(image => {
|
|
@@ -192,13 +171,6 @@ export default {
|
|
|
192
171
|
this.skipUpdateGallery = false;
|
|
193
172
|
}
|
|
194
173
|
},
|
|
195
|
-
mounted() {
|
|
196
|
-
// const index = this.filteredImages.findIndex(i => i.color === this.editableColor?._id);
|
|
197
|
-
// if (index > -1) {
|
|
198
|
-
// this.goToSlide(index, true);
|
|
199
|
-
// }
|
|
200
|
-
// console.log('filteredImages: ', this.filteredImages);
|
|
201
|
-
},
|
|
202
174
|
methods: {
|
|
203
175
|
...mapActions('product', ['selectColor']),
|
|
204
176
|
staticLink,
|
|
@@ -211,14 +183,10 @@ export default {
|
|
|
211
183
|
}
|
|
212
184
|
},
|
|
213
185
|
goToSlide(index, dontAnimate = false) {
|
|
214
|
-
this
|
|
186
|
+
this.activeIndex = Math.max(0, Math.min(this.filteredImages.length - 1, index));
|
|
187
|
+
this.recalculateThumbsPage();
|
|
215
188
|
this.$emit('selected', this.filteredImages[index]);
|
|
216
189
|
},
|
|
217
|
-
onChange(prev, current) {
|
|
218
|
-
this.activeIndex = current;
|
|
219
|
-
const smallIndex = Number.parseInt(current / this.slidesPerRow);
|
|
220
|
-
this.$refs.smallCarousel.goTo(smallIndex);
|
|
221
|
-
},
|
|
222
190
|
isValidImageByFilter(filterType, image) {
|
|
223
191
|
return filterType.filterBy ? filterType.filterBy(image) : isValidImageTypes(image, filterType.types);
|
|
224
192
|
},
|
|
@@ -227,49 +195,20 @@ export default {
|
|
|
227
195
|
this.updateCarouselTime = Date.now();
|
|
228
196
|
this.activeIndex = 0;
|
|
229
197
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.zoomEnable = true;
|
|
233
|
-
this.onMouseEnter(e.srcEvent);
|
|
234
|
-
}
|
|
198
|
+
goToPrev() {
|
|
199
|
+
this.goToSlideAndChangeColor(this.activeIndex - 1);
|
|
235
200
|
},
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
this.onMouseMove(e.srcEvent);
|
|
239
|
-
}
|
|
201
|
+
goToNext() {
|
|
202
|
+
this.goToSlideAndChangeColor(this.activeIndex + 1);
|
|
240
203
|
},
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.zoomEnable = false;
|
|
244
|
-
this.onMouseLeave(e.srcEvent);
|
|
245
|
-
}
|
|
204
|
+
recalculateThumbsPage() {
|
|
205
|
+
this.thumbsPage = Math.ceil((this.activeIndex + 1) / this.slidesPerRow) - 1;
|
|
246
206
|
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
this.zoomEnable = !this.zoomEnable;
|
|
250
|
-
if (this.zoomEnable) {
|
|
251
|
-
this.onMouseEnter(e);
|
|
252
|
-
} else {
|
|
253
|
-
this.onMouseLeave();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
onMouseEnter(e) {
|
|
258
|
-
if (this.zoomEnable) {
|
|
259
|
-
this.backgroundSize = '1000px';
|
|
260
|
-
this.galerySize = e.target.getBoundingClientRect();
|
|
261
|
-
}
|
|
207
|
+
goToPrevPage() {
|
|
208
|
+
this.thumbsPage = Math.max(0, this.thumbsPage - 1);
|
|
262
209
|
},
|
|
263
|
-
|
|
264
|
-
this.
|
|
265
|
-
this.backgroundPosition = null;
|
|
266
|
-
this.galerySize = null;
|
|
267
|
-
},
|
|
268
|
-
onMouseMove({ offsetX, offsetY }) {
|
|
269
|
-
if (this.galerySize) {
|
|
270
|
-
const { width, height } = this.galerySize;
|
|
271
|
-
this.backgroundPosition = `${offsetX / width * 100}% ${offsetY / height * 100}%`;
|
|
272
|
-
}
|
|
210
|
+
goToNextPage() {
|
|
211
|
+
this.thumbsPage = Math.min(Math.ceil((this.filteredImages.length) / this.slidesPerRow) - 1, this.thumbsPage + 1);
|
|
273
212
|
}
|
|
274
213
|
}
|
|
275
214
|
};
|
|
@@ -6,15 +6,21 @@
|
|
|
6
6
|
<div
|
|
7
7
|
v-if="hasReviews"
|
|
8
8
|
class="ProductReviews__carousel">
|
|
9
|
-
|
|
10
|
-
:
|
|
11
|
-
:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</
|
|
9
|
+
<product-review
|
|
10
|
+
:key="currentReview._id"
|
|
11
|
+
:review="currentReview" />
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
class="slick-arrow slick-prev slick-disabled"
|
|
15
|
+
@click="goToPrev()">
|
|
16
|
+
Previous
|
|
17
|
+
</button>
|
|
18
|
+
<button
|
|
19
|
+
type="button"
|
|
20
|
+
class="slick-arrow slick-next"
|
|
21
|
+
@click="goToNext()">
|
|
22
|
+
Next
|
|
23
|
+
</button>
|
|
18
24
|
</div>
|
|
19
25
|
<div class="ProductReviews__add">
|
|
20
26
|
<btn
|
|
@@ -27,15 +33,11 @@
|
|
|
27
33
|
</template>
|
|
28
34
|
|
|
29
35
|
<script>
|
|
30
|
-
// import VueSlickCarousel from 'vue-slick-carousel';
|
|
31
|
-
// import 'vue-slick-carousel/dist/vue-slick-carousel.css';
|
|
32
36
|
import ProductReview from './product_review/product-review';
|
|
33
|
-
import AddReviewModal from './add_review_modal/add-review-modal';
|
|
34
37
|
|
|
35
38
|
export default {
|
|
36
39
|
name: 'ProductReviews',
|
|
37
40
|
components: {
|
|
38
|
-
// VueSlickCarousel,
|
|
39
41
|
ProductReview
|
|
40
42
|
},
|
|
41
43
|
mixins: [],
|
|
@@ -45,6 +47,7 @@ export default {
|
|
|
45
47
|
const mainReview = reviews.find(review => review._id === mainReviewId);
|
|
46
48
|
console.log('mainReviewId: ', mainReviewId);
|
|
47
49
|
return {
|
|
50
|
+
activeIndex: 0,
|
|
48
51
|
scrollInterval: null,
|
|
49
52
|
mainReview,
|
|
50
53
|
reviews: [
|
|
@@ -60,35 +63,27 @@ export default {
|
|
|
60
63
|
}
|
|
61
64
|
},
|
|
62
65
|
computed: {
|
|
66
|
+
currentReview() {
|
|
67
|
+
return this.reviews[this.activeIndex];
|
|
68
|
+
},
|
|
63
69
|
hasReviews() {
|
|
64
70
|
return this.reviews.length > 0;
|
|
65
71
|
}
|
|
66
72
|
},
|
|
67
|
-
mounted() {
|
|
68
|
-
setTimeout(() => {
|
|
69
|
-
if (this.mainReview) {
|
|
70
|
-
const [first, second] = document.querySelectorAll(`#review-${this.mainReview._id}`) || [];
|
|
71
|
-
const mainReviewEl = second || first;
|
|
72
|
-
let top = 0;
|
|
73
|
-
if (mainReviewEl) {
|
|
74
|
-
this.scrollInterval = setInterval(() => {
|
|
75
|
-
top += 50;
|
|
76
|
-
window.scroll(0, top);
|
|
77
|
-
const rect = mainReviewEl.getBoundingClientRect();
|
|
78
|
-
console.log('mainReviewEl: ', mainReviewEl, rect.top);
|
|
79
|
-
if (rect.top < 300) {
|
|
80
|
-
clearInterval(this.scrollInterval);
|
|
81
|
-
}
|
|
82
|
-
}, 50);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}, 100);
|
|
86
|
-
},
|
|
87
73
|
destroyed() {
|
|
88
74
|
clearInterval(this.scrollInterval);
|
|
89
75
|
},
|
|
90
76
|
methods: {
|
|
91
|
-
|
|
77
|
+
goToPrev() {
|
|
78
|
+
this.goToSlide(this.activeIndex - 1);
|
|
79
|
+
},
|
|
80
|
+
goToNext() {
|
|
81
|
+
this.goToSlide(this.activeIndex + 1);
|
|
82
|
+
},
|
|
83
|
+
goToSlide(index) {
|
|
84
|
+
this.activeIndex = Math.max(0, Math.min(this.reviews.length - 1, index));
|
|
85
|
+
},
|
|
86
|
+
async showAddReviewModal() {
|
|
92
87
|
const params = {
|
|
93
88
|
name: 'add-review',
|
|
94
89
|
root: this.$root,
|
|
@@ -98,6 +93,7 @@ export default {
|
|
|
98
93
|
clickToClose: true,
|
|
99
94
|
transition: 'from-right-to-left'
|
|
100
95
|
};
|
|
96
|
+
const AddReviewModal = await import('./add_review_modal/add-review-modal');
|
|
101
97
|
this.$modal.show(AddReviewModal, {
|
|
102
98
|
product: this.product
|
|
103
99
|
}, params);
|