zz-shopify-components
Version:
Reusable Shopify components for theme projects
248 lines (239 loc) • 8.16 kB
JavaScript
class WorldVideoCommentsDialog extends HTMLElement {
isOpen = false;
swiper = null; // swiper实例
mediaId = '';
page = 1;
pageSize = 15;
hasMore = true;
constructor() {
super();
}
connectedCallback() {
this.shopSelect = this.dataset.shopSelect;
this.baseUrl =
this.dataset.requestType === 'prod'
? 'https://h130-app-server-us.hoverx1.cn'
: 'https://h130-app-server-test-us.hoverx1.cn';
if (this.shopSelect === 'JP') {
this.baseUrl =
this.dataset.requestType === 'prod'
? 'https://h130-app-server-jp.hoverx1.cn'
: 'https://h130-app-server-test-jp.hoverx1.cn';
}
this.init();
}
init() {
const closeBtn = this.querySelector('.close-modal-btn');
closeBtn.addEventListener('click', () => {
this.closeModal();
});
this.addSubCommentAction();
}
addFooterAction() {
// 监听 word-video-comments-list-footer 出现在视口上就发送请求第二页数据
const videoPageContentFooter = this.querySelector(
'.word-video-comments-list-footer'
);
if (!videoPageContentFooter) {
console.warn('Footer element not found');
return;
}
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (this.hasMore) {
this.page++;
this.getComments();
}
}
});
});
observer.observe(videoPageContentFooter);
}
addSubCommentAction() {
// 使用事件委托,在父元素上监听点击事件
const commentsList = this.querySelector('.word-video-comments-list');
if (commentsList) {
commentsList.addEventListener('click', (event) => {
// 检查点击的元素是否是 .more-comment 或其子元素
const moreCommentBtn = event.target.closest('.more-comment');
if (moreCommentBtn) {
const id = moreCommentBtn.getAttribute('data-id');
const total = moreCommentBtn.getAttribute('data-total');
const subCommentId = moreCommentBtn.getAttribute(
'data-sub-comment-id'
);
this.getSubComments(id, total, subCommentId, moreCommentBtn);
}
});
}
}
// 初始化
showModal(id) {
this.mediaId = id;
this.getComments();
const modal = this.querySelector('.word-video-comments-modal');
const mask = this.querySelector('.world-video-comments-mask');
modal.style.display = 'block';
if (window.innerWidth < 1024) {
mask.style.display = 'block';
}
setTimeout(() => {
modal.classList.add('show');
}, 10);
const swiperDialog = document.querySelector('world-video-dialog');
if (swiperDialog) {
swiperDialog.closeTouchMove();
}
}
closeModal() {
this.mediaId = '';
const modal = this.querySelector('.word-video-comments-modal');
const mask = this.querySelector('.world-video-comments-mask');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
mask.style.display = 'none';
}, 300);
const swiperDialog = document.querySelector('world-video-dialog');
if (swiperDialog) {
swiperDialog.openTouchMove();
}
}
getComments() {
if (this.hasMore === false || (this.isOpen && this.page === 1)) {
return;
}
httpRequest
.get(
'/shopify/comment-list',
{
page: this.page,
pageSize: this.pageSize,
mediaId: this.mediaId,
source: 1,
},
{ baseUrl: this.baseUrl }
)
.then((res) => {
if (res.code === 200) {
this.isOpen = true;
if (res.data.list.length < this.pageSize) {
this.hasMore = false;
this.hideFooter();
}
this.updateComments(res.data.list);
this.updateReplyTitleNum(res.data.total);
}
});
}
formatTimestamp(ts) {
if (!ts) return '';
const date = new Date(ts);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}/${month}/${day} ${hour}:${minute}`;
}
hideFooter() {
const footer = this.querySelector('.word-video-comments-list-footer');
if (footer) {
footer.style.display = 'none';
}
}
updateComments(newComments) {
const template = $('#video-comment').html();
newComments.forEach((item) => {
let replacedTemplate = template
.replace(new RegExp('{commentId}', 'g'), item.commentId)
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
.replace(new RegExp('{content}', 'g'), item.content);
if (item.time) {
const time = this.formatTimestamp(item.time);
replacedTemplate = replacedTemplate.replace(
new RegExp('{time}', 'g'),
time
);
}
if (item.subCommentCount == 0) {
replacedTemplate = replacedTemplate.replace(
new RegExp('{hasReply}', 'g'),
'tw-hidden'
);
} else if (item.subCommentCount == 1) {
replacedTemplate = replacedTemplate
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
.replace(new RegExp('{hasMore}', 'g'), 'tw-hidden');
} else if (item.subCommentCount > 1) {
replacedTemplate = replacedTemplate
.replace(new RegExp('{hasReply}', 'g'), 'tw-block')
.replace(new RegExp('{hasMore}', 'g'), 'tw-block')
.replace(new RegExp('{moreNum}', 'g'), item.subCommentCount - 1)
.replace(new RegExp('{total}', 'g'), item.subCommentCount);
}
if (item.subComments.length > 0) {
const subComments = item.subComments[0];
replacedTemplate = replacedTemplate
.replace(new RegExp('{sub-avatar}', 'g'), subComments.user.avatar)
.replace(new RegExp('{sub-nickname}', 'g'), subComments.user.nickname)
.replace(new RegExp('{sub-content}', 'g'), subComments.content)
.replace(
new RegExp('{sub-time}', 'g'),
this.formatTimestamp(subComments.time)
)
.replace(new RegExp('{subCommentId}', 'g'), subComments.commentId);
}
const footer = this.querySelector('.word-video-comments-list-footer');
$(footer).before(replacedTemplate);
this.addFooterAction();
});
}
updateReplyTitleNum(num) {
const replyTitle = this.querySelector('.reply-title-num');
if (replyTitle) {
replyTitle.textContent = num;
}
}
updateSubComments(id, newSubComments) {
const template = $('#video-comment').html();
newSubComments.forEach((item, index) => {
const replacedTemplate = template
.replace(new RegExp('{avatar}', 'g'), item.user.avatar)
.replace(new RegExp('{nickname}', 'g'), item.user.nickname)
.replace(new RegExp('{content}', 'g'), item.content)
.replace(new RegExp('{time}', 'g'), this.formatTimestamp(item.time))
.replace(new RegExp('{hasReply}', 'g'), 'tw-hidden');
// 找到 data-comment-id 为 id 的元素
const commentItem = this.querySelector(`[data-comment-id="${id}"]`);
if (commentItem) {
$(commentItem).append(replacedTemplate);
}
});
}
getSubComments(id, total, subCommentId, moreCommentBtn) {
// 二级评论 展开更多
httpRequest
.get(
'/shopify/sub-comment-list',
{
page: 1,
pageSize: total,
mediaId: this.mediaId,
commentId: id,
source: 1,
subTopCommentIds: subCommentId,
},
{ baseUrl: this.baseUrl }
)
.then((res) => {
if (res.code === 200) {
this.updateSubComments(id, res.data.list);
moreCommentBtn.classList.add('tw-hidden');
}
});
}
}
customElements.define('world-video-comments-dialog', WorldVideoCommentsDialog);