(() => { 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); }); })();