// 공통 유틸 import {global} from "http://devtalk.kospo.co.kr:3000/static/js/module/variable.js"; let masterVar = false; const Common = { isMasterVar : () => { return masterVar; }, sleep: (delay) => { return new Promise(resolve => setTimeout(resolve, delay)); }, nowDateDifference: (date1) => { // date1과 date2 문자열을 Date 객체로 변환합니다. const now = new Date(); const midNow = new Date(`${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate() + 1}`); // 두 날짜 간의 시간 차이를 밀리초 단위로 계산합니다. let diffTime = midNow.getTime() - date1.getTime(); // 밀리초를 일 단위로 변환합니다. let diffDays = diffTime / (1000 * 60 * 60 * 24); // 일수 차이를 반환합니다. return diffDays; }, dateDifference: (date1, date2) => { // date1과 date2 문자열을 Date 객체로 변환합니다. // 두 날짜 간의 시간 차이를 밀리초 단위로 계산합니다. let diffTime = date1.getTime() - date2.getTime(); // 일수 차이를 반환합니다. return diffTime > 0; }, dateWithNanos: (date) => { 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 minutes = String(date.getMinutes()).padStart(2, '0') const seconds = String(date.getSeconds()).padStart(2, '0') const millisNanos = String(date.getMilliseconds()).padStart(3, '0') const additionalNanos = String(Math.floor(Math.random() * 999)).padStart(3, '0'); return `${year}-${month}-${day} ${hour}:${minutes}:${seconds}.${millisNanos}${additionalNanos}` }, getAttachVnm: (date, tabId) => { 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 minutes = String(date.getMinutes()).padStart(2, '0') const seconds = String(date.getSeconds()).padStart(2, '0') const millisNanos = String(date.getMilliseconds()).padStart(3, '0') const nanoSecond = Math.round(Math.random() * 999).toString().padEnd(3, '0') return `${year}${month}${day}${hour}${minutes}${seconds}${millisNanos}${nanoSecond}_${tabId}` }, nowDate: () => { // 날짜 포맷터 생성 const dateFormatter = new Intl.DateTimeFormat('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); // 날짜와 시간 포맷팅 const parts = dateFormatter.formatToParts(now); // 원하는 형식으로 조합 let formattedDate = ''; let datePart = ''; let timePart = ''; parts.forEach(({type, value}) => { switch (type) { case 'year': case 'month': case 'day': datePart += (type === 'year' ? value : '-' + value.padStart(2, '0')); break; case 'hour': case 'minute': case 'second': timePart += (timePart ? ':' : '') + value.padStart(2, '0'); break; } }); formattedDate = `${datePart} ${timePart}`; return formattedDate; }, //대화방 리스트에서 사용 talkListDateFormat: (str) => { const convertDate = new Date(str); let formatOptions; let prefix = ''; const diffDay = Common.nowDateDifference(convertDate); if (diffDay > 0 && diffDay <= 1) { formatOptions = { // year: 'numeric', // month: '2-digit', // day: '2-digit', hour: '2-digit', minute: '2-digit', // second: '2-digit', hour12: false } prefix = '' } else if (diffDay > 1 && diffDay <= 2) { formatOptions = { // year: 'numeric', // month: '2-digit', // day: '2-digit', hour: '2-digit', minute: '2-digit', // second: '2-digit', hour12: false } prefix = '어제 ' } else { formatOptions = { year: 'numeric', month: '2-digit', day: '2-digit', // hour: '2-digit', // minute: '2-digit', // second: '2-digit', hour12: false } } // 날짜 포맷터 생성 const dateFormatter = new Intl.DateTimeFormat('ko-KR', formatOptions); // 날짜와 시간 포맷팅 const parts = dateFormatter.formatToParts(convertDate); // 원하는 형식으로 조합 let formattedDate = ''; let datePart = ''; let timePart = ''; parts.forEach(({type, value}) => { switch (type) { case 'year': case 'month': case 'day': datePart += (type === 'year' ? value : '-' + value.padStart(2, '0')); break; case 'hour': timePart += (parseInt(value) > 12 ? '오후 ' : '오전 ') + (timePart ? ':' : '') + (parseInt(value) > 12 ? parseInt(value) % 12 : parseInt(value)); break; case 'minute': case 'second': timePart += (timePart ? ':' : '') + value.padStart(2, '0'); break; } }); formattedDate = `${prefix}${prefix !== '' ? '' : datePart} ${prefix !== '' ? '' : timePart}`; return formattedDate; }, //대화방 글작성시 사용 talkDateFormat: (str) => { // 문자열을 Date 객체로 변환 const date = new Date(str); // 시간을 가져옴 let hours = date.getHours(); const minutes = date.getMinutes(); // 오전/오후 결정 const ampm = hours >= 12 ? '오후' : '오전'; // 12시간 형식으로 변환 hours = hours % 12; hours = hours ? hours : 12; // 0시를 12시로 표시 // 분이 한 자리 수일 경우 앞에 0을 붙임 const minutesStr = minutes < 10 ? '0' + minutes : minutes; // 최종 형식으로 조합 return `${ampm} ${hours}:${minutesStr}`; }, dayOfWeek: (yyyymmdd) => { const dow = new Date(yyyymmdd).getDay(); const week = { '0': '일', '1': '월', '2': '화', '3': '수', '4': '목', '5': '금', '6': '토', } return `${yyyymmdd} (${week[dow]})`; }, nullCheck: (value) => { let result = value; if (value === undefined || value === null) { result = '' } return result; }, fileToBase64: async (file) => { const reader = new FileReader(); let result; reader.readAsDataURL(file) reader.onload = async () => { result = await reader.result } return result }, cropImage: (image, size) => { const widthRatio = size / image.width; const heightRatio = size / image.height; const ratio = Math.max(widthRatio, heightRatio); const newWidth = image.width * ratio; const newHeight = image.height * ratio; return new Promise((resolve, reject) => { // 썸네일 생성 const canvas = document.createElement('canvas'); canvas.width = newWidth; canvas.height = newHeight; const ctx = canvas.getContext('2d'); // 이미지 크기 조정 및 그리기 (Bicubic과 같은 고품질 스케일링) ctx.imageSmoothingEnabled = true; ctx.imageSmoothingQuality = 'high'; ctx.drawImage(image, 0, 0, newWidth, newHeight); resolve(canvas.toDataURL()); }); }, mergeObject: (target, source) => { for(let key in source) { if(source[key] instanceof Object) { target[key] = Object.assign({}, Common.mergeObject(source[key], target[key])) } target = Object.assign({}, source, target); } return target; }, addDelegatedEventListener: (parentElement, eventType, selector, handler) => { function elementMatches(el, selector) { const matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector; if (matches) { return matches.call(el, selector); } else { // matches 메서드를 지원하지 않는 브라우저를 위한 폴백 const allElements = el.parentNode.querySelectorAll(selector); return Array.prototype.indexOf.call(allElements, el) !== -1; } } parentElement.addEventListener(eventType, function (e) { const path = e.composedPath && e.composedPath() || e.path || (function (target) { const path = []; while (target.parentElement) { path.push(target); target = target.parentElement; } path.push(document, window); return path; })(e.target); for (let element of path) { if (element === parentElement) break; if (elementMatches(element, selector)) { const wrappedEvent = new Proxy(e, { get: function (target, prop) { if (prop === 'target' || prop === 'currentTarget') { return element; } if (prop === 'preventDefault') { return () => e.preventDefault(); } if (prop === 'stopPropagation') { return () => { e.stopImmediatePropagation(); e.stopPropagation(); }; } if (typeof target[prop] === 'function') { return target[prop].bind(target); } return target[prop]; } }); const result = handler.call(element, wrappedEvent); if (result === false) { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); } if (wrappedEvent.defaultPrevented) { e.preventDefault(); } break; } } }, true); }, findParentElement: (node, parentClass) => { let pa = node.parentElement; if(pa === null) { return null; } else { if (pa.classList.contains(parentClass)) { return pa; } else { return Common.findParentElement(pa, parentClass) } } }, getListening: (talkId) => { const xhr = new XMLHttpRequest(); xhr.open('GET', `${global.apiUrl}/api/user/listening?talkId=${talkId}`, false); xhr.withCredentials = true; xhr.send(); if(xhr.status === 200) { console.log(xhr.responseText) return Number(xhr.responseText); } }, setListening: (talkId, status) => { const xhr = new XMLHttpRequest(); xhr.open('POST', `${global.apiUrl}/api/user/listening`, false); xhr.withCredentials = true; xhr.setRequestHeader("content-type", "application/json") xhr.send(JSON.stringify({"talkId":talkId, "status":status})); if(xhr.status === 200) { console.log(xhr.responseText) } }, isMaster() { try { return global.stomp.connected; } catch(e) { return false; } }, setCookie: (key, value) => { document.cookie = `${key}=${value};Path=/;domain=.kospo.co.kr` }, getCookie: (key) => { const value = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)'); return value ? value[2] : null; } } export default Common;