Files
api/sample/dev/talk/js/utils.js
2025-07-02 21:55:07 +09:00

383 lines
13 KiB
JavaScript

// 공통 유틸
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;