(() => {
const { EventManager, constants, utils, actions } = ShopbySkin;
const { deleteArticle, checkIsArticleEditable, sendCancelReport } = ShopbySkin.pageHelper.articleViewHelper();
const url = new URL(window.location.href);
const searchParams = new URLSearchParams(url.search);
const boardId = searchParams.get('boardId');
const boardNo = searchParams.get('boardNo');
const articleNo = Number(searchParams.get('articleNo'));
let shopbyCommonData = {};
EventManager.on('PAGE_LOAD_COMPLETED', (commonData) => {
shopbyCommonData = commonData;
});
const getBoardConfig = ({ boardId, boardNo }) => {
const { boardConfigs = [] } = shopbyCommonData.allBoardConfig;
return boardConfigs.find((config) => config.boardId === boardId || config.boardNo === Number(boardNo));
};
const restrictionCauseMessageWithNextUrlMap = {
MEMBER_ONLY: (writable) => {
if (writable) {
return {};
}
return {
modalType: 'MODAL_CONFIRM_OPEN',
message: '로그인하셔야 본 서비스를 이용하실 수 있습니다.',
nextUrl: `${location.origin}${constants.PAGE.SIGN_IN}`,
};
},
SPECIFIC_MEMBERS: (writable) => {
if (writable) {
return {};
}
if (!utils.isSignedIn())
return {
modalType: 'MODAL_CONFIRM_OPEN',
message: '로그인하셔야 본 서비스를 이용하실 수 있습니다.',
nextUrl: `${location.origin}${constants.PAGE.SIGN_IN}`,
};
return {
modalType: 'MODAL_ALERT_OPEN',
message: '글쓰기 권한이 없습니다.',
};
},
};
const moveToList = () => {
let queryString = '';
if (boardId) {
queryString += `boardId=${boardId}`;
} else if (boardNo) {
queryString += `boardNo=${boardNo}`;
}
utils.moveTo({
url: `${constants.PAGE.POST_LIST}${queryString && `?${queryString}`}`,
});
};
const openPasswordFormModal = (nextAction) => {
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'check-post-password-form',
title: '비밀번호 인증',
modalAddClass: 'password-form-modal',
isFull: false,
onClose: ({ reason, state = {} }) => {
if (reason === 'DID_SUBMIT' && nextAction) {
nextAction(state);
}
},
});
};
const openPostFormModal = ({ boardName, password = '' }) => {
const { boardConfigs = [] } = shopbyCommonData.allBoardConfig;
const boardConfig = getBoardConfig({ boardId, boardNo });
if (!boardConfig) {
return;
}
EventManager.fire('OPEN_LAYER_MODAL', {
title: boardName,
name: 'article-write-form',
data: {
boardId,
boardNo,
articleNo,
password,
boardConfigs,
isModify: true,
usesAttachment: boardConfig.attachmentUsed,
canSecretPosting: boardConfig.secretPostingUsed,
},
onClose: ({ reason }) => {
if (reason === 'DID_SUBMIT') {
location.reload();
}
},
});
};
const postFormModal = ({ registerType, boardName }) => {
if (registerType === 'GUEST') {
openPasswordFormModal(({ password }) => {
if (password) {
openPostFormModal({ boardName, password });
}
});
} else {
openPostFormModal({ boardName });
}
};
const deleteAction = async (state) => {
const { password = '' } = state ?? {};
const param = {
boardNo: boardId || boardNo,
articleNo,
password,
};
await deleteArticle(param);
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'SUCCESS',
message: '삭제가 완료되었습니다.',
onClose: () => {
moveToList();
},
});
};
const articleReport = async ({ boardNo, articleNo, reportReasonType, content }) => {
const { status } = await actions.postArticleReport({
boardNo: Number(boardNo),
articleNo: Number(articleNo),
reportReasonType,
content,
});
if (status === 204) {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'success',
message: '신고 되었습니다.',
onClose: () => {
location.reload();
},
});
}
};
const cancelReport = async ({ articleNo, boardNo }) => {
await sendCancelReport({
articleNo,
boardNo,
});
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'SUCCESS',
message: '신고가 취소되었습니다.',
onClose: () => {
location.reload();
},
});
};
const moduleActionHandler = {
LIST: moveToList,
MODIFY: async ({ target }) => {
const boardName = document.querySelector('[shopby-board-name]')?.getAttribute('shopby-board-name');
const registerType = target.closest('[shopby-register-type]')?.getAttribute('shopby-register-type');
if (registerType !== 'GUEST') {
const isArticleEditable = await checkIsArticleEditable({
boardNo: boardId || boardNo,
articleNo,
});
if (!isArticleEditable) {
EventManager.fire('MODAL_ALERT_OPEN', {
message: '권한이 없습니다.',
});
return;
}
}
postFormModal({ registerType, boardName });
},
DELETE: ({ target }) => {
const registerType = target.closest('[shopby-register-type]')?.getAttribute('shopby-register-type');
const shopbyReply = target.closest('[shopby-reply]')?.getAttribute('shopby-reply');
const message = shopbyReply ? '답글을 삭제하시겠습니까?' : '게시글을 삭제하시겠습니까?';
EventManager.fire('MODAL_CONFIRM_OPEN', {
noticeType: 'WARNING',
message: `${message}`,
onConfirm: () => {
if (registerType === 'GUEST') {
openPasswordFormModal((state) => {
deleteAction(state);
});
} else {
deleteAction();
}
},
});
},
MOVE_TO_PARENT_POST: ({ target }) => {
const parentArticleNo = target.closest('[shopby-parent-article-no]')?.getAttribute('shopby-parent-article-no');
searchParams.set('articleNo', parentArticleNo);
location.href = `/pages/board/post-detail.html?${searchParams.toString()}`;
},
WRITE_REPLY: ({ target }) => {
const authorityType = target.getAttribute('shopby-authority-type');
const { profile, allBoardConfig } = shopbyCommonData;
const { data: writable } = actions.queryBoardDisplayableStatus({
profile,
boardNo,
boardId,
boardConfigs: allBoardConfig.boardConfigs,
permissionType: constants.BOARD_PERMISSION_CONFIG_TYPE.REPLAY_WRITE_PERMISSION,
});
const { message, modalType, nextUrl } = restrictionCauseMessageWithNextUrlMap[authorityType]?.(writable) ?? {};
if (message) {
EventManager.fire(modalType, {
message,
noticeType: constants.NOTICE_MODAL_TYPE.WARNING,
onConfirm: () => {
if (!nextUrl) {
return;
}
utils.moveTo({ url: `${nextUrl}?from=${encodeURIComponent(location.href)}` });
},
});
return;
}
const boardConfig = getBoardConfig({ boardId, boardNo });
if (!boardConfig) {
return;
}
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'article-write-form',
title: '답글 등록',
data: {
boardId,
boardNo,
boardConfigs: shopbyCommonData.allBoardConfig?.boardConfigs ?? [],
parentArticleNo: articleNo,
isReply: true,
usesAttachment: boardConfig.attachmentUsed,
canSecretPosting: boardConfig.secretPostingUsed,
},
onClose: ({ reason }) => {
if (reason === 'DID_SUBMIT') {
location.reload();
}
},
});
},
DOWNLOAD_FILE: async ({ target }) => {
const fileName = target.getAttribute('shopby-file-name');
const originFileName = target.getAttribute('shopby-origin-file-name');
const { data: blob } = await ShopbySkin.utils.downloadArticleFile(boardNo, articleNo, fileName);
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = originFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
GO_TO_REPLY_DETAIL: (event) => {
event.preventDefault();
const { target } = event;
const linkEl = target?.href ? target : target.closest('[href]');
if (!linkEl) {
return;
}
const { profile, allBoardConfig } = shopbyCommonData;
const { data: readable } = actions.queryBoardDisplayableStatus({
profile,
boardConfigs: allBoardConfig.boardConfigs,
boardId,
boardNo,
permissionType: constants.BOARD_PERMISSION_CONFIG_TYPE.REPLAY_READ_PERMISSION,
});
if (readable) {
const url = new URL(linkEl.href);
url.searchParams.set('from', encodeURIComponent(location.href));
utils.moveTo({ url: url.toString() });
} else {
EventManager.fire('MODAL_ALERT_OPEN', {
message: '답글 읽기 권한이 없습니다.',
noticeType: constants.NOTICE_MODAL_TYPE.WARNING,
});
}
},
REPORT_WRITE: ({ target }) => {
const articleNo = target.closest('[shopby-article-no]')?.getAttribute('shopby-article-no');
if (!utils.isSignedIn()) {
EventManager.fire('MODAL_CONFIRM_OPEN', {
noticeType: 'WARNING',
message: '로그인 후 이용할 수 있습니다.',
onConfirm: () => {
utils.moveTo({ url: `/pages/sign-in/sign-in.html?from=${encodeURIComponent(location.href)}` });
},
});
return;
}
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'article-report-form',
title: '신고하기',
isFull: false,
onClose: ({ reason }) => {
if (reason === 'DID_SUBMIT') {
location.reload();
}
},
onConfirm: ({ reportReasonType, content }) => {
articleReport({
boardNo: Number(boardNo),
articleNo: Number(articleNo),
reportReasonType,
content,
});
},
});
},
CANCEL_REPORT: ({ target }) => {
const articleNo = target.closest('[shopby-article-no]')?.getAttribute('shopby-article-no');
if (!utils.isSignedIn()) {
EventManager.fire('MODAL_CONFIRM_OPEN', {
noticeType: 'WARNING',
message: '로그인 후 이용할 수 있습니다.',
onConfirm: () => {
utils.moveTo({ url: `/pages/sign-in/sign-in.html?from=${encodeURIComponent(location.href)}` });
},
});
return;
}
EventManager.fire('MODAL_CONFIRM_OPEN', {
noticeType: 'WARNING',
message: '신고를 취소 하시겠습니까?',
confirmLabel: '확인',
onConfirm: () => {
cancelReport({
articleNo: Number(articleNo),
boardNo: Number(boardNo),
});
},
});
},
};
// 비밀번호 인증이 필요한 경우
EventManager.on('NEED_PASSWORD_FORM', () => {
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'check-post-password-form',
title: '비밀번호 인증',
modalAddClass: 'password-form-modal',
isFull: false,
onClose: ({ reason }) => {
if (reason === 'DID_CLOSE') {
if (!document.referrer || location.href === document.referrer) {
history.back();
return;
}
utils.moveTo({
url: document.referrer,
});
}
},
});
});
// 해당 게시글에 접근할 권한이 없는 경우
EventManager.on('FORBIDDEN_ARTICLE', () => {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'WARNING',
message: '비밀글 조회 권한이 없습니다.',
onClose: () => {
if (!document.referrer || location.href === document.referrer) {
history.back();
return;
}
utils.moveTo({
url: document.referrer,
});
},
});
});
// 답글 접근 권한이 없는 경우 V2
EventManager.on('FORBIDDEN_ARTICLE_REPLY', () => {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: '답글 읽기 권한이 없습니다.',
onClose: () => {
const searchParams = new URLSearchParams(location.search);
const from = searchParams.get('from');
utils.moveTo({
url: from ? decodeURIComponent(from) : '/',
replace: true,
});
},
});
});
// 게시글 상세 권한이 없는 경우 V2
EventManager.on('FORBIDDEN_ARTICLE_DETAIL', () => {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: '게시글 읽기 권한이 없습니다.',
onClose: () => {
location.href = `${location.origin}/pages/board/post-list.html?boardNo=${boardNo}`;
},
});
});
// 차단 된 게시물인 경우
EventManager.on('ALERT_ARTICLE', ({ message, type }) => {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: type,
message: `${message}`,
onClose: () => {
history.back();
},
});
});
document.querySelector('article-view-v2')?.addEventListener('click', (event) => {
const action = event.target.getAttribute('shopby-action');
moduleActionHandler[action]?.(event);
});
document.querySelector('article-view-btns')?.addEventListener('click', (event) => {
const action = event.target.getAttribute('shopby-action');
moduleActionHandler[action]?.(event);
});
document.querySelector('article-replies-v2')?.addEventListener('click', (event) => {
const action =
event.target.getAttribute('shopby-action') ||
event.target.closest('[shopby-action]')?.getAttribute('shopby-action');
moduleActionHandler[action]?.(event);
});
})();