zz-shopify-components 0.0.27 → 0.0.28-beta.2
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.
- package/CHANGELOG.md +21 -21
- package/README.md +70 -56
- package/assets/ScrollTrigger.min.js +11 -11
- package/assets/gsap.min.js +11 -11
- package/assets/jquery.js +2 -2
- package/assets/lazy-video.js +2 -2
- package/assets/lazyload.min.js +1 -1
- package/assets/lozad.js +10 -10
- package/assets/site-jump.js +52 -52
- package/assets/site-jumpV2.js +35 -35
- package/assets/swiper-bundle.min.css +12 -12
- package/assets/swiper-bundle.min.js +13 -13
- package/assets/swiper.css +330 -330
- package/assets/zz-components.css +322 -322
- package/assets/zz-components.js +166 -166
- package/assets/zz-fade-in-content.js +169 -169
- package/assets/zz-http-request.js +73 -73
- package/assets/zz-world-video-comments-dialog.js +240 -240
- package/assets/zz-world-video-dialog.js +190 -190
- package/assets/zz-world-video-list.js +317 -317
- package/assets/zz-world-video.js +270 -270
- package/blocks/zz-accessories-item.liquid +188 -188
- package/blocks/zz-accessories-swiper.liquid +223 -223
- package/blocks/zz-button.liquid +216 -216
- package/blocks/zz-content-description-html.liquid +201 -201
- package/blocks/zz-content-description.liquid +209 -209
- package/blocks/zz-flex-layout-bg-block.liquid +524 -524
- package/blocks/zz-flex-layout-block.liquid +549 -549
- package/blocks/zz-flex-layout-widget.liquid +321 -321
- package/blocks/zz-full-screen-swiper.liquid +443 -443
- package/blocks/zz-icon.liquid +46 -46
- package/blocks/zz-mail.liquid +135 -135
- package/blocks/zz-mb-swiper-pc-flex.liquid +273 -273
- package/blocks/zz-price-tag-mini.liquid +106 -106
- package/blocks/zz-price-tag.liquid +41 -41
- package/blocks/zz-ratio-image.liquid +181 -181
- package/blocks/zz-ratio-video.liquid +115 -115
- package/blocks/zz-responsive-width-image.liquid +222 -222
- package/blocks/zz-responsive-width-video.liquid +166 -166
- package/blocks/zz-scroll-animate-bg-text.liquid +268 -268
- package/blocks/zz-scroll-cover.liquid +67 -67
- package/blocks/zz-tag.liquid +50 -50
- package/blocks/zz-text.liquid +227 -227
- package/blocks/zz-title.liquid +287 -287
- package/blocks/zz-video-button.liquid +84 -84
- package/blocks/zz-video-img-item.liquid +203 -203
- package/blocks/zz-video-img-list.liquid +166 -166
- package/blocks/zz-video-swiper-perview-item.liquid +221 -221
- package/blocks/zz-video-swiper-perview.liquid +585 -585
- package/blocks/zz-world-video.liquid +639 -639
- package/component.config.json +7 -7
- package/package.json +1 -1
- package/scripts/postinstall-v1.js +39 -39
- package/scripts/postinstall-v2.js +47 -47
- package/scripts/postinstall-v3.js +51 -51
- package/scripts/publish-npm.js +43 -43
- package/sections/zz-flex-layout-section.liquid +269 -269
- package/sections/zz-navigation-tab-v3.liquid +409 -409
- package/sections/zz-navigation-tab.liquid +411 -411
- package/sections/zz-shopping-card-list.liquid +399 -399
- package/sections/zz-video-collapse-swiper.liquid +522 -522
- package/sections/zz-video-tab-swiper.liquid +748 -748
- package/snippets/zz-button.liquid +70 -70
- package/snippets/zz-content-h3.liquid +15 -15
- package/snippets/zz-content-text.liquid +56 -56
- package/snippets/zz-h2.liquid +31 -31
- package/snippets/zz-h3.liquid +31 -31
- package/snippets/zz-h4.liquid +30 -30
- package/snippets/zz-h5.liquid +39 -39
- package/snippets/zz-h6.liquid +39 -39
- package/snippets/zz-icon-next.liquid +17 -17
- package/snippets/zz-icon-prev.liquid +17 -17
- package/snippets/zz-icon.liquid +74 -74
- package/snippets/zz-img-md.liquid +44 -44
- package/snippets/zz-img.liquid +44 -44
- package/snippets/zz-prev-next-blur-icon.liquid +36 -36
- package/snippets/zz-prev-next-btn.liquid +62 -62
- package/snippets/zz-price-tag.liquid +22 -22
- package/snippets/zz-spoke.liquid +142 -142
- package/snippets/zz-tag.liquid +22 -22
- package/snippets/zz-video-button.liquid +54 -54
- package/snippets/zz-video-md.liquid +117 -117
- package/snippets/zz-video.liquid +117 -117
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
(function () {
|
|
2
|
-
const DEFAULT_BASE_URL = 'https://h130-app-server-us.hoverx1.cn';
|
|
3
|
-
|
|
4
|
-
const DEFAULT_TIMEOUT = 60000;
|
|
5
|
-
|
|
6
|
-
function getToken() {
|
|
7
|
-
return localStorage.getItem('token') || '';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function buildUrl(url, params = {}) {
|
|
11
|
-
const queryString = new URLSearchParams(params).toString();
|
|
12
|
-
return queryString ? `${url}?${queryString}` : url;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function timeoutFetch(fetchPromise, timeout = DEFAULT_TIMEOUT) {
|
|
16
|
-
return Promise.race([
|
|
17
|
-
fetchPromise,
|
|
18
|
-
new Promise((_, reject) =>
|
|
19
|
-
setTimeout(() => reject(new Error('请求超时,请重试')), timeout)
|
|
20
|
-
),
|
|
21
|
-
]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function request(method, url, params = {}, options = {}) {
|
|
25
|
-
const baseUrl = options.baseUrl || DEFAULT_BASE_URL;
|
|
26
|
-
|
|
27
|
-
const timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
28
|
-
|
|
29
|
-
const fullUrl = baseUrl + url;
|
|
30
|
-
|
|
31
|
-
let fetchOptions = {
|
|
32
|
-
method: method.toUpperCase(),
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': 'application/json',
|
|
35
|
-
...(options.headers || {}),
|
|
36
|
-
},
|
|
37
|
-
...options,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
if (method.toLowerCase() === 'get') {
|
|
41
|
-
return timeoutFetch(
|
|
42
|
-
fetch(buildUrl(fullUrl, params), fetchOptions),
|
|
43
|
-
timeout
|
|
44
|
-
).then(handleResponse);
|
|
45
|
-
} else {
|
|
46
|
-
fetchOptions.body = JSON.stringify(params);
|
|
47
|
-
return timeoutFetch(fetch(fullUrl, fetchOptions), timeout).then(
|
|
48
|
-
handleResponse
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function handleResponse(response) {
|
|
54
|
-
if (!response.ok) {
|
|
55
|
-
if (response.status === 401) {
|
|
56
|
-
// 未登录或登录过期,即将跳转登录页
|
|
57
|
-
}
|
|
58
|
-
return response.json().then((err) => {
|
|
59
|
-
throw err;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
return response.json();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
window.httpRequest = {
|
|
66
|
-
get: function (url, params = {}, options = {}) {
|
|
67
|
-
return request('get', url, params, options);
|
|
68
|
-
},
|
|
69
|
-
post: function (url, params = {}, options = {}) {
|
|
70
|
-
return request('post', url, params, options);
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
})();
|
|
1
|
+
(function () {
|
|
2
|
+
const DEFAULT_BASE_URL = 'https://h130-app-server-us.hoverx1.cn';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TIMEOUT = 60000;
|
|
5
|
+
|
|
6
|
+
function getToken() {
|
|
7
|
+
return localStorage.getItem('token') || '';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function buildUrl(url, params = {}) {
|
|
11
|
+
const queryString = new URLSearchParams(params).toString();
|
|
12
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function timeoutFetch(fetchPromise, timeout = DEFAULT_TIMEOUT) {
|
|
16
|
+
return Promise.race([
|
|
17
|
+
fetchPromise,
|
|
18
|
+
new Promise((_, reject) =>
|
|
19
|
+
setTimeout(() => reject(new Error('请求超时,请重试')), timeout)
|
|
20
|
+
),
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function request(method, url, params = {}, options = {}) {
|
|
25
|
+
const baseUrl = options.baseUrl || DEFAULT_BASE_URL;
|
|
26
|
+
|
|
27
|
+
const timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
28
|
+
|
|
29
|
+
const fullUrl = baseUrl + url;
|
|
30
|
+
|
|
31
|
+
let fetchOptions = {
|
|
32
|
+
method: method.toUpperCase(),
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
...(options.headers || {}),
|
|
36
|
+
},
|
|
37
|
+
...options,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (method.toLowerCase() === 'get') {
|
|
41
|
+
return timeoutFetch(
|
|
42
|
+
fetch(buildUrl(fullUrl, params), fetchOptions),
|
|
43
|
+
timeout
|
|
44
|
+
).then(handleResponse);
|
|
45
|
+
} else {
|
|
46
|
+
fetchOptions.body = JSON.stringify(params);
|
|
47
|
+
return timeoutFetch(fetch(fullUrl, fetchOptions), timeout).then(
|
|
48
|
+
handleResponse
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function handleResponse(response) {
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
if (response.status === 401) {
|
|
56
|
+
// 未登录或登录过期,即将跳转登录页
|
|
57
|
+
}
|
|
58
|
+
return response.json().then((err) => {
|
|
59
|
+
throw err;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return response.json();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
window.httpRequest = {
|
|
66
|
+
get: function (url, params = {}, options = {}) {
|
|
67
|
+
return request('get', url, params, options);
|
|
68
|
+
},
|
|
69
|
+
post: function (url, params = {}, options = {}) {
|
|
70
|
+
return request('post', url, params, options);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
})();
|
|
@@ -1,240 +1,240 @@
|
|
|
1
|
-
class WorldVideoCommentsDialog extends HTMLElement {
|
|
2
|
-
isOpen = false;
|
|
3
|
-
swiper = null; // swiper实例
|
|
4
|
-
mediaId = '';
|
|
5
|
-
page = 1;
|
|
6
|
-
|
|
7
|
-
pageSize = 15;
|
|
8
|
-
hasMore = true;
|
|
9
|
-
|
|
10
|
-
constructor() {
|
|
11
|
-
super();
|
|
12
|
-
this.init();
|
|
13
|
-
}
|
|
14
|
-
connectedCallback() {
|
|
15
|
-
this.baseUrl =
|
|
16
|
-
this.dataset.requestType === 'prod'
|
|
17
|
-
? 'https://h130-app-server-us.hoverx1.cn'
|
|
18
|
-
: 'https://h130-app-server-test-us.hoverx1.cn';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
init() {
|
|
22
|
-
const closeBtn = this.querySelector('.close-modal-btn');
|
|
23
|
-
closeBtn.addEventListener('click', () => {
|
|
24
|
-
this.closeModal();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
this.addSubCommentAction();
|
|
28
|
-
}
|
|
29
|
-
addFooterAction() {
|
|
30
|
-
// 监听 word-video-comments-list-footer 出现在视口上就发送请求第二页数据
|
|
31
|
-
const videoPageContentFooter = this.querySelector(
|
|
32
|
-
'.word-video-comments-list-footer'
|
|
33
|
-
);
|
|
34
|
-
if (!videoPageContentFooter) {
|
|
35
|
-
console.warn('Footer element not found');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const observer = new IntersectionObserver((entries) => {
|
|
39
|
-
entries.forEach((entry) => {
|
|
40
|
-
if (entry.isIntersecting) {
|
|
41
|
-
if (this.hasMore) {
|
|
42
|
-
this.page++;
|
|
43
|
-
this.getComments();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
observer.observe(videoPageContentFooter);
|
|
49
|
-
}
|
|
50
|
-
addSubCommentAction() {
|
|
51
|
-
// 使用事件委托,在父元素上监听点击事件
|
|
52
|
-
const commentsList = this.querySelector('.word-video-comments-list');
|
|
53
|
-
if (commentsList) {
|
|
54
|
-
commentsList.addEventListener('click', (event) => {
|
|
55
|
-
// 检查点击的元素是否是 .more-comment 或其子元素
|
|
56
|
-
const moreCommentBtn = event.target.closest('.more-comment');
|
|
57
|
-
if (moreCommentBtn) {
|
|
58
|
-
const id = moreCommentBtn.getAttribute('data-id');
|
|
59
|
-
const total = moreCommentBtn.getAttribute('data-total');
|
|
60
|
-
const subCommentId = moreCommentBtn.getAttribute(
|
|
61
|
-
'data-sub-comment-id'
|
|
62
|
-
);
|
|
63
|
-
this.getSubComments(id, total, subCommentId, moreCommentBtn);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// 初始化
|
|
69
|
-
showModal(id) {
|
|
70
|
-
this.mediaId = id;
|
|
71
|
-
this.getComments();
|
|
72
|
-
const modal = this.querySelector('.word-video-comments-modal');
|
|
73
|
-
const mask = this.querySelector('.world-video-comments-mask');
|
|
74
|
-
modal.style.display = 'block';
|
|
75
|
-
if (window.innerWidth < 1024) {
|
|
76
|
-
mask.style.display = 'block';
|
|
77
|
-
}
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
modal.classList.add('show');
|
|
80
|
-
}, 10);
|
|
81
|
-
const swiperDialog = document.querySelector('world-video-dialog');
|
|
82
|
-
if (swiperDialog) {
|
|
83
|
-
swiperDialog.closeTouchMove();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
closeModal() {
|
|
87
|
-
this.mediaId = '';
|
|
88
|
-
const modal = this.querySelector('.word-video-comments-modal');
|
|
89
|
-
const mask = this.querySelector('.world-video-comments-mask');
|
|
90
|
-
|
|
91
|
-
modal.classList.remove('show');
|
|
92
|
-
setTimeout(() => {
|
|
93
|
-
modal.style.display = 'none';
|
|
94
|
-
mask.style.display = 'none';
|
|
95
|
-
}, 300);
|
|
96
|
-
const swiperDialog = document.querySelector('world-video-dialog');
|
|
97
|
-
if (swiperDialog) {
|
|
98
|
-
swiperDialog.openTouchMove();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
getComments() {
|
|
102
|
-
if (this.hasMore === false || (this.isOpen && this.page === 1)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
httpRequest
|
|
106
|
-
.get(
|
|
107
|
-
'/shopify/comment-list',
|
|
108
|
-
{
|
|
109
|
-
page: this.page,
|
|
110
|
-
pageSize: this.pageSize,
|
|
111
|
-
mediaId: this.mediaId,
|
|
112
|
-
source: 1,
|
|
113
|
-
},
|
|
114
|
-
{ baseUrl: this.baseUrl }
|
|
115
|
-
)
|
|
116
|
-
.then((res) => {
|
|
117
|
-
if (res.code === 200) {
|
|
118
|
-
this.isOpen = true;
|
|
119
|
-
if (res.data.list.length < this.pageSize) {
|
|
120
|
-
this.hasMore = false;
|
|
121
|
-
this.hideFooter();
|
|
122
|
-
}
|
|
123
|
-
this.updateComments(res.data.list);
|
|
124
|
-
this.updateReplyTitleNum(res.data.total);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
formatTimestamp(ts) {
|
|
129
|
-
if (!ts) return '';
|
|
130
|
-
const date = new Date(ts);
|
|
131
|
-
const year = date.getFullYear();
|
|
132
|
-
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
133
|
-
const day = String(date.getDate()).padStart(2, '0');
|
|
134
|
-
const hour = String(date.getHours()).padStart(2, '0');
|
|
135
|
-
const minute = String(date.getMinutes()).padStart(2, '0');
|
|
136
|
-
return `${year}/${month}/${day} ${hour}:${minute}`;
|
|
137
|
-
}
|
|
138
|
-
hideFooter() {
|
|
139
|
-
const footer = this.querySelector('.word-video-comments-list-footer');
|
|
140
|
-
if (footer) {
|
|
141
|
-
footer.style.display = 'none';
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
updateComments(newComments) {
|
|
145
|
-
const template = $('#video-comment').html();
|
|
146
|
-
newComments.forEach((item) => {
|
|
147
|
-
let replacedTemplate = template
|
|
148
|
-
.replace(new RegExp('{commentId}', 'g'), item.commentId)
|
|
149
|
-
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
|
|
150
|
-
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
|
|
151
|
-
.replace(new RegExp('{content}', 'g'), item.content);
|
|
152
|
-
|
|
153
|
-
if (item.time) {
|
|
154
|
-
const time = this.formatTimestamp(item.time);
|
|
155
|
-
replacedTemplate = replacedTemplate.replace(
|
|
156
|
-
new RegExp('{time}', 'g'),
|
|
157
|
-
time
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
if (item.subCommentCount == 0) {
|
|
161
|
-
replacedTemplate = replacedTemplate.replace(
|
|
162
|
-
new RegExp('{hasReply}', 'g'),
|
|
163
|
-
'tw-hidden'
|
|
164
|
-
);
|
|
165
|
-
} else if (item.subCommentCount == 1) {
|
|
166
|
-
replacedTemplate = replacedTemplate
|
|
167
|
-
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
|
|
168
|
-
.replace(new RegExp('{hasMore}', 'g'), 'tw-hidden');
|
|
169
|
-
} else if (item.subCommentCount > 1) {
|
|
170
|
-
replacedTemplate = replacedTemplate
|
|
171
|
-
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
|
|
172
|
-
.replace(new RegExp('{hasMore}', 'g'), 'tw-block')
|
|
173
|
-
.replace(new RegExp('{moreNum}', 'g'), item.subCommentCount - 1)
|
|
174
|
-
.replace(new RegExp('{total}', 'g'), item.subCommentCount);
|
|
175
|
-
}
|
|
176
|
-
if (item.subComments.length > 0) {
|
|
177
|
-
const subComments = item.subComments[0];
|
|
178
|
-
replacedTemplate = replacedTemplate
|
|
179
|
-
.replace(new RegExp('{sub-avatar}', 'g'), subComments.user.avatar)
|
|
180
|
-
.replace(new RegExp('{sub-nickname}', 'g'), subComments.user.nickname)
|
|
181
|
-
.replace(new RegExp('{sub-content}', 'g'), subComments.content)
|
|
182
|
-
.replace(
|
|
183
|
-
new RegExp('{sub-time}', 'g'),
|
|
184
|
-
this.formatTimestamp(subComments.time)
|
|
185
|
-
)
|
|
186
|
-
.replace(new RegExp('{subCommentId}', 'g'), subComments.commentId);
|
|
187
|
-
}
|
|
188
|
-
const footer = this.querySelector('.word-video-comments-list-footer');
|
|
189
|
-
$(footer).before(replacedTemplate);
|
|
190
|
-
this.addFooterAction();
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
updateReplyTitleNum(num) {
|
|
194
|
-
const replyTitle = this.querySelector('.reply-title-num');
|
|
195
|
-
if (replyTitle) {
|
|
196
|
-
replyTitle.textContent = num;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
updateSubComments(id, newSubComments) {
|
|
201
|
-
const template = $('#video-comment').html();
|
|
202
|
-
newSubComments.forEach((item, index) => {
|
|
203
|
-
const replacedTemplate = template
|
|
204
|
-
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
|
|
205
|
-
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
|
|
206
|
-
.replace(new RegExp('{content}', 'g'), item.content)
|
|
207
|
-
.replace(new RegExp('{time}', 'g'), this.formatTimestamp(item.time))
|
|
208
|
-
.replace(new RegExp('{hasReply}', 'g'), 'tw-hidden');
|
|
209
|
-
|
|
210
|
-
// 找到 data-comment-id 为 id 的元素
|
|
211
|
-
const commentItem = this.querySelector(`[data-comment-id="${id}"]`);
|
|
212
|
-
if (commentItem) {
|
|
213
|
-
$(commentItem).append(replacedTemplate);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
getSubComments(id, total, subCommentId, moreCommentBtn) {
|
|
218
|
-
// 二级评论 展开更多
|
|
219
|
-
httpRequest
|
|
220
|
-
.get(
|
|
221
|
-
'/shopify/sub-comment-list',
|
|
222
|
-
{
|
|
223
|
-
page: 1,
|
|
224
|
-
pageSize: total,
|
|
225
|
-
mediaId: this.mediaId,
|
|
226
|
-
commentId: id,
|
|
227
|
-
source: 1,
|
|
228
|
-
subTopCommentIds: subCommentId,
|
|
229
|
-
},
|
|
230
|
-
{ baseUrl: this.baseUrl }
|
|
231
|
-
)
|
|
232
|
-
.then((res) => {
|
|
233
|
-
if (res.code === 200) {
|
|
234
|
-
this.updateSubComments(id, res.data.list);
|
|
235
|
-
moreCommentBtn.classList.add('tw-hidden');
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
customElements.define('world-video-comments-dialog', WorldVideoCommentsDialog);
|
|
1
|
+
class WorldVideoCommentsDialog extends HTMLElement {
|
|
2
|
+
isOpen = false;
|
|
3
|
+
swiper = null; // swiper实例
|
|
4
|
+
mediaId = '';
|
|
5
|
+
page = 1;
|
|
6
|
+
|
|
7
|
+
pageSize = 15;
|
|
8
|
+
hasMore = true;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.init();
|
|
13
|
+
}
|
|
14
|
+
connectedCallback() {
|
|
15
|
+
this.baseUrl =
|
|
16
|
+
this.dataset.requestType === 'prod'
|
|
17
|
+
? 'https://h130-app-server-us.hoverx1.cn'
|
|
18
|
+
: 'https://h130-app-server-test-us.hoverx1.cn';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
init() {
|
|
22
|
+
const closeBtn = this.querySelector('.close-modal-btn');
|
|
23
|
+
closeBtn.addEventListener('click', () => {
|
|
24
|
+
this.closeModal();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
this.addSubCommentAction();
|
|
28
|
+
}
|
|
29
|
+
addFooterAction() {
|
|
30
|
+
// 监听 word-video-comments-list-footer 出现在视口上就发送请求第二页数据
|
|
31
|
+
const videoPageContentFooter = this.querySelector(
|
|
32
|
+
'.word-video-comments-list-footer'
|
|
33
|
+
);
|
|
34
|
+
if (!videoPageContentFooter) {
|
|
35
|
+
console.warn('Footer element not found');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const observer = new IntersectionObserver((entries) => {
|
|
39
|
+
entries.forEach((entry) => {
|
|
40
|
+
if (entry.isIntersecting) {
|
|
41
|
+
if (this.hasMore) {
|
|
42
|
+
this.page++;
|
|
43
|
+
this.getComments();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
observer.observe(videoPageContentFooter);
|
|
49
|
+
}
|
|
50
|
+
addSubCommentAction() {
|
|
51
|
+
// 使用事件委托,在父元素上监听点击事件
|
|
52
|
+
const commentsList = this.querySelector('.word-video-comments-list');
|
|
53
|
+
if (commentsList) {
|
|
54
|
+
commentsList.addEventListener('click', (event) => {
|
|
55
|
+
// 检查点击的元素是否是 .more-comment 或其子元素
|
|
56
|
+
const moreCommentBtn = event.target.closest('.more-comment');
|
|
57
|
+
if (moreCommentBtn) {
|
|
58
|
+
const id = moreCommentBtn.getAttribute('data-id');
|
|
59
|
+
const total = moreCommentBtn.getAttribute('data-total');
|
|
60
|
+
const subCommentId = moreCommentBtn.getAttribute(
|
|
61
|
+
'data-sub-comment-id'
|
|
62
|
+
);
|
|
63
|
+
this.getSubComments(id, total, subCommentId, moreCommentBtn);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 初始化
|
|
69
|
+
showModal(id) {
|
|
70
|
+
this.mediaId = id;
|
|
71
|
+
this.getComments();
|
|
72
|
+
const modal = this.querySelector('.word-video-comments-modal');
|
|
73
|
+
const mask = this.querySelector('.world-video-comments-mask');
|
|
74
|
+
modal.style.display = 'block';
|
|
75
|
+
if (window.innerWidth < 1024) {
|
|
76
|
+
mask.style.display = 'block';
|
|
77
|
+
}
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
modal.classList.add('show');
|
|
80
|
+
}, 10);
|
|
81
|
+
const swiperDialog = document.querySelector('world-video-dialog');
|
|
82
|
+
if (swiperDialog) {
|
|
83
|
+
swiperDialog.closeTouchMove();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
closeModal() {
|
|
87
|
+
this.mediaId = '';
|
|
88
|
+
const modal = this.querySelector('.word-video-comments-modal');
|
|
89
|
+
const mask = this.querySelector('.world-video-comments-mask');
|
|
90
|
+
|
|
91
|
+
modal.classList.remove('show');
|
|
92
|
+
setTimeout(() => {
|
|
93
|
+
modal.style.display = 'none';
|
|
94
|
+
mask.style.display = 'none';
|
|
95
|
+
}, 300);
|
|
96
|
+
const swiperDialog = document.querySelector('world-video-dialog');
|
|
97
|
+
if (swiperDialog) {
|
|
98
|
+
swiperDialog.openTouchMove();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
getComments() {
|
|
102
|
+
if (this.hasMore === false || (this.isOpen && this.page === 1)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
httpRequest
|
|
106
|
+
.get(
|
|
107
|
+
'/shopify/comment-list',
|
|
108
|
+
{
|
|
109
|
+
page: this.page,
|
|
110
|
+
pageSize: this.pageSize,
|
|
111
|
+
mediaId: this.mediaId,
|
|
112
|
+
source: 1,
|
|
113
|
+
},
|
|
114
|
+
{ baseUrl: this.baseUrl }
|
|
115
|
+
)
|
|
116
|
+
.then((res) => {
|
|
117
|
+
if (res.code === 200) {
|
|
118
|
+
this.isOpen = true;
|
|
119
|
+
if (res.data.list.length < this.pageSize) {
|
|
120
|
+
this.hasMore = false;
|
|
121
|
+
this.hideFooter();
|
|
122
|
+
}
|
|
123
|
+
this.updateComments(res.data.list);
|
|
124
|
+
this.updateReplyTitleNum(res.data.total);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
formatTimestamp(ts) {
|
|
129
|
+
if (!ts) return '';
|
|
130
|
+
const date = new Date(ts);
|
|
131
|
+
const year = date.getFullYear();
|
|
132
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
133
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
134
|
+
const hour = String(date.getHours()).padStart(2, '0');
|
|
135
|
+
const minute = String(date.getMinutes()).padStart(2, '0');
|
|
136
|
+
return `${year}/${month}/${day} ${hour}:${minute}`;
|
|
137
|
+
}
|
|
138
|
+
hideFooter() {
|
|
139
|
+
const footer = this.querySelector('.word-video-comments-list-footer');
|
|
140
|
+
if (footer) {
|
|
141
|
+
footer.style.display = 'none';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
updateComments(newComments) {
|
|
145
|
+
const template = $('#video-comment').html();
|
|
146
|
+
newComments.forEach((item) => {
|
|
147
|
+
let replacedTemplate = template
|
|
148
|
+
.replace(new RegExp('{commentId}', 'g'), item.commentId)
|
|
149
|
+
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
|
|
150
|
+
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
|
|
151
|
+
.replace(new RegExp('{content}', 'g'), item.content);
|
|
152
|
+
|
|
153
|
+
if (item.time) {
|
|
154
|
+
const time = this.formatTimestamp(item.time);
|
|
155
|
+
replacedTemplate = replacedTemplate.replace(
|
|
156
|
+
new RegExp('{time}', 'g'),
|
|
157
|
+
time
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
if (item.subCommentCount == 0) {
|
|
161
|
+
replacedTemplate = replacedTemplate.replace(
|
|
162
|
+
new RegExp('{hasReply}', 'g'),
|
|
163
|
+
'tw-hidden'
|
|
164
|
+
);
|
|
165
|
+
} else if (item.subCommentCount == 1) {
|
|
166
|
+
replacedTemplate = replacedTemplate
|
|
167
|
+
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
|
|
168
|
+
.replace(new RegExp('{hasMore}', 'g'), 'tw-hidden');
|
|
169
|
+
} else if (item.subCommentCount > 1) {
|
|
170
|
+
replacedTemplate = replacedTemplate
|
|
171
|
+
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
|
|
172
|
+
.replace(new RegExp('{hasMore}', 'g'), 'tw-block')
|
|
173
|
+
.replace(new RegExp('{moreNum}', 'g'), item.subCommentCount - 1)
|
|
174
|
+
.replace(new RegExp('{total}', 'g'), item.subCommentCount);
|
|
175
|
+
}
|
|
176
|
+
if (item.subComments.length > 0) {
|
|
177
|
+
const subComments = item.subComments[0];
|
|
178
|
+
replacedTemplate = replacedTemplate
|
|
179
|
+
.replace(new RegExp('{sub-avatar}', 'g'), subComments.user.avatar)
|
|
180
|
+
.replace(new RegExp('{sub-nickname}', 'g'), subComments.user.nickname)
|
|
181
|
+
.replace(new RegExp('{sub-content}', 'g'), subComments.content)
|
|
182
|
+
.replace(
|
|
183
|
+
new RegExp('{sub-time}', 'g'),
|
|
184
|
+
this.formatTimestamp(subComments.time)
|
|
185
|
+
)
|
|
186
|
+
.replace(new RegExp('{subCommentId}', 'g'), subComments.commentId);
|
|
187
|
+
}
|
|
188
|
+
const footer = this.querySelector('.word-video-comments-list-footer');
|
|
189
|
+
$(footer).before(replacedTemplate);
|
|
190
|
+
this.addFooterAction();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
updateReplyTitleNum(num) {
|
|
194
|
+
const replyTitle = this.querySelector('.reply-title-num');
|
|
195
|
+
if (replyTitle) {
|
|
196
|
+
replyTitle.textContent = num;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
updateSubComments(id, newSubComments) {
|
|
201
|
+
const template = $('#video-comment').html();
|
|
202
|
+
newSubComments.forEach((item, index) => {
|
|
203
|
+
const replacedTemplate = template
|
|
204
|
+
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
|
|
205
|
+
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
|
|
206
|
+
.replace(new RegExp('{content}', 'g'), item.content)
|
|
207
|
+
.replace(new RegExp('{time}', 'g'), this.formatTimestamp(item.time))
|
|
208
|
+
.replace(new RegExp('{hasReply}', 'g'), 'tw-hidden');
|
|
209
|
+
|
|
210
|
+
// 找到 data-comment-id 为 id 的元素
|
|
211
|
+
const commentItem = this.querySelector(`[data-comment-id="${id}"]`);
|
|
212
|
+
if (commentItem) {
|
|
213
|
+
$(commentItem).append(replacedTemplate);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
getSubComments(id, total, subCommentId, moreCommentBtn) {
|
|
218
|
+
// 二级评论 展开更多
|
|
219
|
+
httpRequest
|
|
220
|
+
.get(
|
|
221
|
+
'/shopify/sub-comment-list',
|
|
222
|
+
{
|
|
223
|
+
page: 1,
|
|
224
|
+
pageSize: total,
|
|
225
|
+
mediaId: this.mediaId,
|
|
226
|
+
commentId: id,
|
|
227
|
+
source: 1,
|
|
228
|
+
subTopCommentIds: subCommentId,
|
|
229
|
+
},
|
|
230
|
+
{ baseUrl: this.baseUrl }
|
|
231
|
+
)
|
|
232
|
+
.then((res) => {
|
|
233
|
+
if (res.code === 200) {
|
|
234
|
+
this.updateSubComments(id, res.data.list);
|
|
235
|
+
moreCommentBtn.classList.add('tw-hidden');
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
customElements.define('world-video-comments-dialog', WorldVideoCommentsDialog);
|