Files
api/sample/dev/talk/js/talk.js
2025-10-11 15:04:32 +09:00

2397 lines
107 KiB
JavaScript

import m from 'http://devtalk.kospo.co.kr:3000/static/bundle/mithril-2.2.2/mithril.js';
import {global} from 'http://devtalk.kospo.co.kr:3000/static/js/module/variable.js';
import SocketQueue from 'http://devtalk.kospo.co.kr:3000/static/js/module/queue.js';
import {talkEvent} from 'http://devtalk.kospo.co.kr:3000/static/js/module/talkEvent.js';
import {
talkInit,
getUser,
getTalkList,
getMoreMessageLine,
getMessageSearch,
getAllContentSearch,
getManual,
getVideoManual,
setTalkMark,
setChatRead,
setITSMSatis,
setSCMSatis,
deleteTalk, getMessageAll,
} from 'http://devtalk.kospo.co.kr:3000/static/js/module/apis.js';
import {attachUpload} from 'http://devtalk.kospo.co.kr:3000/static/js/module/attach.js'
import {messageMapping, talkMapping} from "http://devtalk.kospo.co.kr:3000/static/js/module/render.js";
import {
Carousel,
Dropdown,
Modal,
Tab
} from "http://devtalk.kospo.co.kr:3000/static/bundle/bootstrap-5.1.3/js/bootstrap.esm.js";
import AWN from "http://devtalk.kospo.co.kr:3000/static/bundle/awesome-notifications-3.1.1/index.js";
import "http://devtalk.kospo.co.kr:3000/static/bundle/stompjs-esm/stomp.js";
import SimpleBar from "http://devtalk.kospo.co.kr:3000/static/bundle/simplebar-6.2.7/simplebar.js";
import Common from "http://devtalk.kospo.co.kr:3000/static/js/utils.js";
import Hub from "http://devtalk.kospo.co.kr:3000/static/js/module/hub.js";
import {HubEvent} from "http://devtalk.kospo.co.kr:3000/static/js/module/hubEvent.js";
import {requestNotificationPermission} from "http://devtalk.kospo.co.kr:3000/static/js/notification.js";
const default_options = {
url: '',
button: {},
container: {},
serviceWorkerLocation: '',
}
class Talk {
constructor(options) {
global.option = Common.mergeObject(options, default_options)
/*서비스워커 윈도우 클라이언트 특정 하기 위한 url 맵핑*/
if(options.url !== '' && options.url !== undefined) {
global.currentUrl = options.url;
} else {
global.currentUrl = window.location.href;
}
if (global.option.workId) global.currentWorkId = global.option.workId;
global.apiUrl = "http://devtalk.kospo.co.kr:3000";
// global.apiUrl = "http://kisp.kospo.co.kr:8010";
// 현재탭의 고유 아이디 생성
global.tabId = talkEvent.generateTabUUID()
// 헬프톡 브라우저 위치 설정
if (global.option.position === 'br') {
global.option.vertical = 'bottom';
global.option.horizontal = 'right'
} else if (global.option.position === 'bl') {
global.option.vertical = 'bottom';
global.option.horizontal = 'left'
} else if (global.option.position === 'tr') {
global.option.vertical = 'top';
global.option.horizontal = 'right'
}
if (global.option.position === 'tl') {
global.option.vertical = 'top';
global.option.horizontal = 'left'
}
// api 호출 공통 로직 재정의
global.request = (options) => {
options.url = `${global.apiUrl}${options.url}`
if (global.option.encSabun) {
options.headers = {
"Authentication": global.option.encSabun
};
}
return m.request(options)
}
global.queue = new SocketQueue()
}
/*잠금화면으로 이동안하도록 조치*/
async requestWakeLock() {
try {
if ('wakeLock' in navigator) {
const wakeLock = await navigator.wakeLock.request('screen')
console.log('wake lock is active', wakeLock)
}
} catch(e) {
console.log(e)
}
}
/*메시지 전송후 소켓 통신이 없을시 재접속 로직*/
checker() {
if(global.checker.flag) {
const currentTalkId = localStorage.getItem(global.tabId);
console.log(new Date() - global.checker.inDate)
if(new Date() - global.checker.inDate > 3000) {
HubEvent.kill(global.talkParams({
type: 'KILL',
channelSabun: global.user.sabun
}))
talkEvent.allUnsubscribe();
global.registration.unregister();
global.checker.flag = false;
global.checker.inDate = '';
global.currentServer = '';
global.talkData = [];
Common.sleep(200).then(() => {
global.hub = new Hub()
/*서비스워커 설치*/
global.hub.install().then(() => {
/* 서비스워커 서버로 연결 */
global.hub.start();
/* 마스터는 소켓 접속 및 톡방 리스트 호출 */
talkEvent.connect().then(() => {
// 참여중인 톡방 호출 및 구독
try {
getTalkList(true).then(async (isEmpty) => {
if (!isEmpty) {
getMessageAll(true).then(() => {
const cacheTalk = global.talkData.filter((talk) => talk.talkId === currentTalkId)[0];
messageMapping(currentTalkId, cacheTalk.talkMessages, 'before', true)
})
}
});
} catch (e) {
window.location.reload()
}
// 서버측에 HUB 정보 저장
HubEvent.start(global.talkParams({
type: 'START',
tabId: global.tabId
}))
// 다른탭에 연결 된 소켓이 있다면 종료 명령
HubEvent.send(global.talkParams({
type: 'UNSUBSCRIBE',
tabId: global.tabId
}))
/// 개인 사번 소켓 연결
try {
global.subscribeList[global.user.sabun] = talkEvent.userSubscribe();
} catch (e) {
}
// 업무별 소켓 연결
try {
global.subscribeList[global.work.workId] = talkEvent.workSubscribe();
} catch (e) {
}
})
}).catch(() => {
});
})
}
}
}
// 헬프톡 실행
run() {
return new Promise(async (resolve, reject) => {
if ('serviceWorker' in navigator) {
//사용자 정보 조회
await getUser()
if (global.user !== null) {
// const getUrl = new URL(window.location.href);
// global.requestParams = getUrl.searchParams\
const $root = document.createElement('div')
$root.style.display = 'none';
$root.classList.add('chat-root')
$root.setAttribute('id', 'chat-area')
document.body.append($root)
/*html 주입*/
this.#htmlInjection();
/*현재 접속 업무 정보 조회*/
talkInit();
global.hub = new Hub()
/*서비스워커 설치*/
global.hub.install().then(() => {
/* 서비스워커 서버로 연결 */
global.hub.start();
/* 마스터는 소켓 접속 및 톡방 리스트 호출 */
talkEvent.connect().then(() => {
// 참여중인 톡방 호출 및 구독
try {
getTalkList(true).then(async (isEmpty) => {
if (!isEmpty) {
getMessageAll(true)
}
});
} catch (e) {
window.location.reload()
}
// 서버측에 HUB 정보 저장
HubEvent.start(global.talkParams({
type: 'START',
tabId: global.tabId
}))
// 다른탭에 연결 된 소켓이 있다면 종료 명령
HubEvent.send(global.talkParams({
type: 'UNSUBSCRIBE',
tabId: global.tabId
}))
/// 개인 사번 소켓 연결
try {
global.subscribeList[global.user.sabun] = talkEvent.userSubscribe();
} catch (e) {
}
// 업무별 소켓 연결
try {
global.subscribeList[global.work.workId] = talkEvent.workSubscribe();
} catch (e) {
}
resolve();
/* 전체 로딩 완료시 상태 변경(
다른탭에서 구독 해제 메시지 방지용
위 설정 빠르게 처리 될때 대비 2초 뒤에 상태 변경
) */
setTimeout(() => {
global.init = true;
}, 1500)
})
const open = () => {
$root.style.display = 'block';
}
// 모든 설정 정의 된후 버튼 활성화
setTimeout(open, 1000)
// 웹페이지 notication 설정
const globalOptions = {
position: 'top-right',
labels: {
alert: ''
}
}
global.notifier = new AWN(globalOptions);
}).catch(() => {
});
} else {
console.log('유지보수자 접근 불가')
reject();
}
}
setInterval(this.checker, 1000)
})
}
// 운영 배포시 삭제
getGlobal() {
return global;
}
async #htmlInjection() {
const docReady = (fn) => {
// see if DOM is already available
if (global.shadowRoot.readyState === 'loading') {
global.shadowRoot.addEventListener('DOMContentLoaded', fn);
} else {
setTimeout(fn, 1);
}
};
const errorPage = m('div', {
class: 'server-error cus-hide'
}, [
m('div', {class: 'server-error-wrapper'}, [
m('div', {class: 'server-error-body'}, [
m('p', '서버 오류로 인하여 중단 되었어요.'),
m('p', '유지보수 담당자에게 연락주세요.')
])
])
]);
const socketErrorPage = m('div', {
class: 'socket-error cus-hide'
}, [
m('div', {class: 'server-error-wrapper'}, [
m('div', {class: 'server-error-body'}, [
m('p', '이런, 오류가 발생했어요.'),
m('p', '아래 재시작버튼을 눌러 다시 시작해주세요.'),
m('button', {class: 'btn btn-primary', id: 'socket-reset-btn'}, '재시작')
])
])
]);
const notificationPermission = m('div', {
id: 'noti-permission-card',
class: 'card mt-1',
style: 'background-color:var(--falcon-low-purple-hover) !important; color:white;'
}, [
m('div', {class: 'card-body'}, [
m('div', {id: 'intro-title'}, [
m('i', {
class: "bi bi-bell-fill",
style: "font-size:1.1em;padding-right:10px;"
}),
m('span', {class: 'fw-bold'}, '브라우저 알림을 받아보세요!'),
m('button', {class: 'btn btn-sm btn-primary', id: 'noti-permission-btn'}, '사용하기')
])
])
])
const main = m('div', {
class: 'tab-pane fade cus-show active',
id: 'intro',
role: "tabpanel",
style: 'padding: 10px 13px 10px 13px!important;',
'aria-labelledby': "intro-tab"
}, [
Notification.permission === 'default' ? notificationPermission : '',
m('div', {class: 'card mt-1'}, [
m('div', {class: 'card-body'}, [
m('div', {id: 'intro-title'}, [
m('span', {id: 'intro-user'}),
m('span', '님'),
m('br'),
m('span', '궁금한 점을 질문해주세요.'),
m('br'),
m('span', {id: 'intro-work'}),
m('span', ' 관련 모든 문의를 지원합니다.'),
m('br'),
m('span', '질문, 요청사항 아래 문의하기를 눌러주세요.')
]),
m('div', {class: "pt-3 pb-1", style: "display:flex; margin:0px auto; justify-content: center"}, [
m('button', {
type: "button",
id: "chat-inquiry",
class: "btn form-control",
}, [
m('i', {
class: "bi bi-send-fill",
style: "font-size:1.1em; padding-right:5px;border-radius:20px;"
}),
m('span', '문의하기')
]),
]),
m('div', {id: 'intro-online'}, '')
])
]),
m('div', {class: 'card mt-4'}, [
m('div', {class: 'card-header pb-0'}, [
m('h5-6', {class: 'fw-bold'}, '자주 찾는 질문')
]),
m('div', {class: "card-body", id: "question"})
]),
m('div', {class: 'card mt-4'}, [
m('div', {class: "card-body"}, [
m('div', {
id: "manual-play",
class: "carousel slide carousel-fade",
'data-bs-ride': "carousel",
style: 'min-height:100px;'
}, [
m('div', {class: 'carousel-inner'}, [])
])
])
])
])
const chat = m('div', {
class: "tab-pane fade",
id: "chat",
style: 'padding: 0px !important; ',
role: "tabpanel",
'aria-labelledby': "chat-tab"
}, [
m('div', {class: "card card-chat overflow-hidden", style: "height: 580px;"}, [
m('div', {class: "card-body d-flex p-0 h-100"}, [
m('div', {class: "chat-sidebar", style: "left: 0px;"}, [
m('div', {class: "contacts-list scrollbar-overlay"}, [
m('div', {
id: "chat-list",
class: "nav nav-tabs border-0 flex-column",
role: "tablist",
'aria-orientation': "vertical"
})
])
]),
m('div', {class: 'tab-content card-chat-content'}, [
m('div', {
class: "tab-pane card-chat-pane",
id: "chat-0",
role: "tabpanel",
'aria-labelledby': "chat-link-0",
style: 'display:block;'
}, [
m('div', {class: "chat-content-header"}, [
m('div', {id: "chat-content-header-main", class: "row flex-between-center"}, [
m('div', {class: 'col-8 col-sm-8 d-flex align-items-center'}, [
m('button', {class: "pe-3 text-700 contacts-list-show bg-transparent", type: "button"}, [
m('i', {class: "bi bi-chevron-left bi-color-grey"})
]),
m('div', {class: "min-w-0"}, [
m('h5', {class: 'mb-0 text-truncate fs-9', id: 'work-nm'}),
m('div', {class: "fs-10 text-400 status-online", id: "work-sm-nm"})
])
]),
m('div', {class: "col-4 col-sm-4 d-flex justify-content-end"}, [
m('i', {
id: "chat-option",
class: "bi bi-three-dots-vertical bi-color-grey dropdown-toggle",
style: "font-size:1.6em",
'data-toggle': 'dropdown',
'aria-haspopup': 'true',
'aria-expanded': 'false'
}),
m('div', {
class: 'dropdown-menu chat-option-menu',
'aria-labelledby': '#chat-option'
}, [
m('div', {id: 'chat-content-search', class: 'dropdown-item'}, '검색'),
m('div', {id: 'chat-content-font', class: 'dropdown-item'}, '설정'),
])
]),
// m('div', {class: "col-4 col-sm-4 d-flex justify-content-end"}, [
// m('i', {
// id: "chat-content-search",
// class: "bi bi-search bi-color-grey",
// style: "font-size:1.6em"
// })
// ])
]),
m('div', {id: "chat-content-header-sub", class: "row flex-between-center cus-hide"}, [
m('div', {class: 'input-group'}, [
m('div', {id: 'chat-search-tot', "data-tot": "0/0"}),
m('input', {
type: "text",
id: "chat-search-text",
placeholder: '채팅 검색',
'aria-label': "search content",
}),
m('div', {
class: 'input-group-divider left'
}),
m('button', {
class: "btn btn-sm chat-file-upload shadow-none",
type: "button"
}, [
m('i', {
id: 'chat-search-prev',
class: 'bi bi-chevron-up bi-color-grey'
}),
]),
m('button', {
class: "btn btn-sm chat-file-upload shadow-none",
type: "button",
}, [
m('i', {
id: 'chat-search-next',
class: 'bi bi-chevron-down bi-color-grey'
}),
]),
])
])
]),
m('div', {class: 'chat-content-body'}, [
m('div', {id: "chat-content", class: "chat-content-scroll-area scrollbar-overlay"})
])
]),
m('div', {class: 'message-preview cus-hide'}, [
m('div', {class: 'preview-wrap d-flex justify-content-between'}, [
m('div', {class: 'msg'}, ''),
m('i', {class: 'bottom-scroll-icon bi bi-arrow-down-circle-fill bi-color-white'})
]),
]),
m('form', {class: 'chat-editor-area'}, [
m('div', {class: 'input-group'}, [
m('button', {
class: "btn btn-sm chat-file-upload shadow-none",
id: "chat-upload-btn",
type: "button",
style: "padding-left:10px;padding-right:0px;"
}, [
m('i', {class: "bi bi-paperclip bi-color-grey"})
]),
m('div', {
class: 'input-group-divider right'
}),
m('div', {
class: "chat-editor outline-none",
contenteditable: "true",
placeholder: "메시지 작성 (ctrl+엔터 줄바꿈)"
}),
m('div', {
class: 'input-group-divider left'
}),
m('button', {
class: "btn btn-sm btn-send shadow-none",
type: "button",
style: "padding-left:0px;padding-right:0px;"
}, [
m('i', {class: 'bi bi-send bi-color-grey'})
]),
]),
// m('button', {
// class: "btn btn-sm chat-file-upload shadow-none",
// id: "chat-upload-btn",
// type: "button",
// style: "padding-right:10px;"
// }, [
// m('i', {class: "bi bi-paperclip bi-color-grey"})
// ]),
// m('div', {
// class: "chat-editor outline-none",
// contenteditable: "true",
// placeholder: "메시지 작성 (ctrl+엔터 줄바꿈)"
// }),
// m('button', {
// class: "btn btn-sm btn-send shadow-none",
// type: "button",
// style: "padding-left:10px;"
// }, [
// m('i', {class: 'bi bi-send bi-color-grey'})
// ]),
m('input', {
class: "d-none",
type: "file",
id: "chat-file-upload",
multiple: "multiple",
accept: 'image/*, .xls, .xlsx, .doc, .docx, .hwp, .pdf, .txt, .pdf, .ppt, .zip, .egg'
}),
])
]),
])
])
])
const allSearchEmpty = m('div', {style: 'font-size:var(--chat-content-font-size); text-align:center;'}, '조회된 내용이 없어요');
const search = m('div', {
class: "tab-pane fade ",
id: "search",
role: "tabpanel",
style: 'padding: 10px 13px 10px 13px !important;',
'aria-labelledby': "search-tab"
}, [
m('div', {class: 'card mt-1'}, [
m('div', {class: 'card-body'}, [
m('div', {class: 'row justify-content-between'}, [
m('h5-6', {
class: 'form-label h6 col-5 search-label fw-bold',
for: 'chat-all-search-text'
}, '통합검색'),
m('div', {class: 'col-7 search'}, [
m('input', {
id: 'chat-all-search-text',
type: "text",
class: "form-control bg-white search-control",
placeholder: "전체 채팅 검색"
}),
])
]),
m('div', {
class: 'scrollbar-overlay mt-3',
id: 'chat-all-search-list',
style: 'min-height:30px; max-height: 150px;'
}, [
allSearchEmpty
])
])
]),
m('div', {class: 'card mt-4'}, [
m('div', {class: 'card-body'}, [
m('div', {class: 'row justify-content-between', style: 'margin-bottom:10px;'}, [
m('h5-6', {class: 'form-label h6 col-5 search-label fw-bold', for: 'manual-doc-text'}, '매뉴얼'),
m('div', {class: 'col-7 search'}, [
m('input', {
id: 'manual-doc-text',
type: "text",
class: "form-control bg-white search-control",
placeholder: "매뉴얼 검색"
}),
])
]),
m('div', {class: 'row justify-content-start manual-header'}, [
m('div', {class: 'col-7 p-0'}, '파일명'),
m('div', {class: 'col-2 p-0 text-sm-end'}, '버전'),
m('div', {class: 'col-3 p-0 text-sm-end'}, '다운로드')
]),
m('div', {
class: 'scrollbar-overlay mt-2',
id: 'manual-doc-body',
style: 'min-height:100px; max-height: 170px;'
})
])
]),
m('div', {class: 'card mt-4'}, [
m('div', {class: 'card-header pb-0'}, [
m('div', {class: 'row justify-content-between'}, [
m('h5-6', {
class: 'form-label h6 col-5 search-label fw-bold',
for: 'manual-video-text'
}, '동영상 매뉴얼'),
m('div', {class: 'col-7 search'}, [
m('input', {
id: 'manual-video-text',
type: "text",
class: "form-control bg-white search-control",
placeholder: "동영상 검색"
}),
])
]),
]),
m('div', {class: 'card-body'}, [
m('div', {
class: 'scrollbar-overlay cus-show',
id: 'manual-video-body',
style: 'min-height:170px; max-height: 210px;'
}),
m('div', {
id: 'manual-video-play',
class: 'cus-hide',
style: 'min-height:130px; position:absolute; left:0px; top:50px;'
}, [
m('video', {id: 'manual-video', controls: true, autoplay: true}, [
/* url 재정의 필요 */
m('source', {'src': ``})
]),
m('div', {id: 'manual-video-back'}, [
m('i', {class: 'bi bi-arrow-left-short cursor-pointer'})
])
])
])
]),
])
const nav = m('nav', {
class: "navbar chat-navbar navbar-light navbar-expand fixed-bottom shadow",
style: "background-color:var(--falcon-low-purple); border-top-right-radius: 0px; border-top-left-radius: 0px;"
}, [
m('ul', {class: "nav nav-justified w-100", id: "myTab", role: "tablist"}, [
m('li', {class: "nav-item active", role: "presentation"}, [
m('button', {
class: "nav-link active",
id: "intro-tab",
'data-bs-toggle': "tab",
'data-bs-target': "#intro",
type: "button",
role: "tab",
'aria-controls': "intro",
'aria-selected': "true",
style: 'position:relative; padding-top:0;'
}, [
m('i', {class: 'bi bi-house-door bi-md'}),
m('label', {class: 'nav-item-label'}, '홈')
])
]),
m('li', {class: "nav-item", role: "presentation"}, [
m('button', {
class: "nav-link",
id: "chat-tab",
'data-bs-toggle': "tab",
'data-bs-target': "#chat",
type: "button",
role: "tab",
'aria-controls': "chat",
'aria-selected': "false",
style: 'position:relative; padding-top:0;'
}, [
m('i', {class: 'bi bi-chat-dots bi-md'}),
m('label', {class: 'nav-item-label'}, '채팅')
])
]),
m('li', {class: "nav-item", role: "presentation"}, [
m('button', {
class: "nav-link",
id: "search-tab",
'data-bs-toggle': "tab",
'data-bs-target': "#search",
type: "button",
role: "tab",
'aria-controls': "chat",
'aria-selected': "false",
style: 'position:relative; padding-top:0;'
}, [
m('i', {class: 'bi bi-book bi-md'}),
m('label', {class: 'nav-item-label'}, '메뉴얼')
])
]),
])
])
const modal = m('div', {
class: "modal fade",
id: "imageModal",
'data-bs-keyboard': "false",
tabindex: "-1",
"aria-labelledby": "staticBackdropLabel",
"aria-hidden": "false"
}, [
m('div', {
class: "modal-dialog modal-dialog-centered modal-xxl",
style: 'margin:0px auto;justify-content:center;'
}, [
m('div', {class: "modal-content", style: 'border:0px; width:auto; margin-left:5%; margin-right:5%;'}, [
m('div', {class: "modal-body"}, [])
])
]),
])
const info = m('div', {class: 'chat-confirm-wrapper chat-delete-confirm-wrapper cus-hide'}, [
m('div', {class: 'chat-confirm-fixed'}, [
m('div', {class: 'card'}, [
m('div', {class: 'card-body', style: 'text-align:center;'}, [
m('p', {class: 'chat-confirm-title'}, '대화를 삭제하시면 더이상 내용(진행상태) 확인을 할 수 없어요.\n 그래도 삭제 할까요?'),
m('button', {class: 'btn btn-sm chat-confirm-btn chat-delete-btn'}, '대화 삭제하기')
])
]),
m('div', {class: 'chat-confirm-cancel cursor-pointer'}, 'x')
])
])
const upload = m('div', {class: 'chat-confirm-wrapper chat-upload-confirm-wrapper cus-hide'}, [
m('div', {class: 'chat-confirm-fixed'}, [
m('div', {class: 'card'}, [
m('div', {class: 'card-body', style: 'text-align:center;'}, [
m('p', {class: 'chat-confirm-title'}, '이미지 또는 파일을 첨부해 주세요.'),
m('div', {class: 'p-1'}, [
m('button', {class: 'btn btn-sm chat-confirm-btn chat-file-upload-btn'}, '파일 첨부하기'),
]),
])
]),
m('div', {class: 'chat-confirm-cancel cursor-pointer'}, 'x')
])
])
const paste = m('div', {class: 'chat-confirm-wrapper chat-clipboard-confirm-wrapper cus-hide'}, [
m('div', {class: 'chat-confirm-fixed'}, [
m('div', {class: 'card'}, [
m('div', {class: 'card-body', style: 'text-align:center;'}, [
m('div', {class: ''}, [
m('img', {src: '', class: 'chat-clipboard-img'})
]),
m('p', {class: 'chat-confirm-title pt-2'}, '클립보드 이미지를 업로드 할까요?'),
m('div', {class: 'p-1'}, [
m('button', {class: 'btn btn-sm chat-confirm-btn chat-clipboard-btn'}, '업로드'),
]),
])
]),
m('div', {class: 'chat-confirm-cancel cursor-pointer'}, 'x')
])
])
const fontResize = m('div', {class: 'chat-confirm-wrapper chat-font-confirm-wrapper cus-hide'}, [
m('div', {class: 'chat-confirm-fixed', style: 'bottom: 330px !important;'}, [
m('div', {class: 'card'}, [
m('div', {class: 'card-body', style: 'text-align:center;'}, [
m('div', {class: 'resize-body'}, [
m('div', '대화방의 글자 크기가 아래와 같이 변경되요.'),
m('div', {class: 'pb-3'}, '슬라이드를 움직여 크기를 조절해보세요.'),
m('div', {
class: 'pb-3 sample-text chat-content-custom-font-size',
'style': `font-size: ${Common.getCookie('fontSize')}px;`
}, '안녕하세요.'),
m('input', {
type: 'range',
class: 'form-range',
min: '14',
max: '26',
step: '1',
value: `${Common.getCookie('fontSize') ?? 14}`,
id: 'resize-font'
})
]),
m('div', {class: 'p-1'}, [
m('button', {class: 'btn btn-sm chat-confirm-btn chat-font-btn'}, '저장'),
]),
])
]),
m('div', {class: 'chat-confirm-cancel cursor-pointer'}, 'x')
])
])
const rating = m('div', {class: 'chat-confirm-wrapper chat-rating-confirm-wrapper cus-hide'}, [
m('div', {class: 'chat-confirm-fixed'}, [
m('div', {class: 'card'}, [
m('div', {class: 'card-body', style: 'text-align:center;'}, [
m('p', {class: 'text-pre-wrap'}, '상담이 종료되었어요.\n' +
'만약 요청주신 작업이 있으시다면\n' +
'작업처리 후 알려드릴 예정이에요.\n' +
'이번 상담이 만족스러우셨나요?\n' +
'(최소 10점, 최대 100점까지 클릭)'),
m('div', {class: "star-rate", "data-val": "5", 'data-max': '5'}, [
m('span', {'class': 'cont m-1l'}, [
m('span', {'class': 'ctrl'}),
m('i', {'class': 'bi bi-star-fill'}),
m('i', {'class': 'bi bi-star-fill'}),
m('i', {'class': 'bi bi-star-fill'}),
m('i', {'class': 'bi bi-star-fill'}),
m('i', {'class': 'bi bi-star-fill'})
]),
]),
m('p', {class: 'text-pre-wrap'}, '개선점이나 칭찬할 부분이 있으신가요?\n' +
'아래에 내용을 작성해주세요.'),
m('div', [
m('textarea', {class: 'form-control', id: 'review'})
]),
m('div', {class: 'pt-3'}, [
m('button', {class: 'btn btn-sm chat-confirm-btn chat-rating-btn'}, '저장'),
]),
])
]),
m('div', {class: 'chat-confirm-cancel cursor-pointer'}, 'x')
])
])
const fullscreen = m('div', {id: 'fullscreen-container', class: 'cus-hide'});
const detail = m('div', {id: 'detail-container', class: 'cus-hide'}, [
m('iframe', {frameborder:0, align:'center', src:''}),
m('div', {id:'detail-close'}, [
m('i', {class: "bi bi-x-lg bi-color-grey",}),
])
]);
const loading = m('div', {class: 'loading-wrap cus-hide'}, [
m('div', {
class: 'fade',
style: 'width: 100%;height: 100%;position: absolute;top: 0;left: 0;background-color: black;z-index: 1111111;opacity: 0.4;'
}),
m('div', {
class: 'loading-indicator',
style: 'position: absolute; width: 100%;height: 100%;z-index: 10;top: 45%;left: 45%;'
}, [
m('span', {
class: "spinner-border",
role: "status",
'aria-hidden': "true",
style: "width: 3rem; height: 3rem;"
}),
])
])
const floatingBtnStyle = `cursor:grab;${global.option.vertical === 'bottom' ? 'bottom:' + global.option.button.offsetY + 'px;' : 'top:' + global.option.button.offsetY + 'px;'} ${global.option.horizontal === 'right' ? 'right:' + global.option.button.offsetX + 'px;' : 'left:' + global.option.button.offsetX + 'px;'}`
const floatingBtn = m('div', {class: 'chat-floating-btn', style: floatingBtnStyle}, [
m('i', {class: 'bi-msg-icon bi-color-low-purple'}, [
m('span', {
class: 'position-absolute top-8-px start-100 translate-middle badge unread rounded-pill bg-danger cus-hide',
style: '--falcon-badge-font-size: 0.57em;'
}, [
m.trust(),
m('span', {class: 'visually-hidden'}, '미확인 메시지')
])
])
])
const css = [
m('link', {
rel: 'stylesheet',
href: 'http://devtalk.kospo.co.kr:3000/static/bundle/bootstrap-5.1.3/css/bootstrap.min.css'
}),
m('link', {
rel: 'stylesheet',
href: 'http://devtalk.kospo.co.kr:3000/static/bundle/bootstrap-icon-1.11.3/bootstrap-icons.css'
}),
m('link', {
rel: 'stylesheet',
href: 'http://devtalk.kospo.co.kr:3000/static/bundle/simplebar-6.2.7/simplebar.min.css'
}),
m('link', {
rel: 'stylesheet',
href: 'http://devtalk.kospo.co.kr:3000/static/bundle/awesome-notifications-3.1.1/style.css'
}),
m('link', {rel: 'stylesheet', href: 'http://devtalk.kospo.co.kr:3000/static/css/theme.css'}),
m('link', {rel: 'stylesheet', href: 'http://devtalk.kospo.co.kr:3000/static/css/imp.css'}),
]
let floatingBodyStyle = `${global.option.vertical === 'bottom' ? 'bottom:' + global.option.container.offsetY + 'px;' : 'top:' + global.option.container.offsetY + 'px;'} right:${global.option.container.offsetX}px`
if (global.option.horizontal === 'left') {
floatingBodyStyle = `bottom:${global.option.container.offsetY}px; left:${global.option.container.offsetX}px`
}
const floatingBody = m('div', {class: 'chat-floating cus-hide', style: floatingBodyStyle}, [
m('div', {class: 'tab-content chat-content', id: 'chat-tab-content'}, [
main,
chat,
search,
info,
upload,
paste,
fontResize,
rating,
m('iframe', {name: '_download_', style: 'display:none; visibility:hidden;'})
]),
nav,
loading,
errorPage,
socketErrorPage
])
const chatArea = document.querySelector('#chat-area');
global.shadowRoot = chatArea.attachShadow({mode: 'closed'});
const allHtml = m('body', [m('head', css), floatingBtn, floatingBody, modal, fullscreen, detail]);
m.render(global.shadowRoot, allHtml)
/*아이콘 이미지 색상 변경*/
if (global.option.button.color !== null) document.documentElement.style.setProperty('--chat-main-icon', global.option.button.color)
if (global.option.button.hoverColor !== null) document.documentElement.style.setProperty('--chat-main-icon-hover', global.option.button.hoverColor)
if (global.option.container.offsetY !== null) document.documentElement.style.setProperty('--chat-confirm-fixed-height', `${global.option.container.offsetY + 70}px`)
/*전체 색상 변경*/
if (global.option.container.color !== null) document.documentElement.style.setProperty('--falcon-low-purple', global.option.container.color)
if (global.option.container.hoverColor !== null) document.documentElement.style.setProperty('--falcon-low-purple-hover', global.option.container.hoverColor)
if (global.option.container.activeColor !== null) document.documentElement.style.setProperty('--falcon-purple', global.option.container.activeColor)
/*쿠키에 설정된 채팅방 폰트 사이즈 변경*/
const getContentFontSize = Common.getCookie('fontSize') ?? 14;
document.documentElement.style.setProperty('--chat-content-custom-font-size', `${getContentFontSize}px`)
/*톡방 메시지 엘리먼트 변수*/
global.element.chatSidebar = global.shadowRoot.querySelector('.chat-sidebar');
global.element.chatEditor = global.shadowRoot.querySelector('.chat-editor');
global.element.chatEditorArea = global.shadowRoot.querySelector('.chat-editor-area')
global.element.btnSend = global.shadowRoot.querySelector('.btn-send');
global.element.currentChatArea = global.shadowRoot.querySelector('.chat-content-scroll-area');
/*대화방 내용 검색 기능 엘리먼트 변수*/
const $contentSearch = global.shadowRoot.querySelector('#chat-content-search');
const $contentSearchText = global.shadowRoot.querySelector('#chat-search-text');
const $contentSearchPrev = global.shadowRoot.querySelector('#chat-search-prev');
const $contentSearchNext = global.shadowRoot.querySelector('#chat-search-next');
const $contentSearchSub = global.shadowRoot.querySelector('#chat-content-header-sub');
const $contentSearchTot = global.shadowRoot.querySelector('#chat-search-tot')
/*메뉴 탭*/
const $myTab = global.shadowRoot.querySelector('#myTab');
/*알림 권한 버튼*/
const $notiPermission = global.shadowRoot.querySelector('#noti-permission-btn')
/*채팅 활성화 버튼*/
const $chatFloatingBtn = global.shadowRoot.querySelector('.chat-floating-btn')
const $chatScrollDownBtn = global.shadowRoot.querySelector('.bottom-scroll-icon');
/* 문의 하기 버튼 */
const $chatInquiry = global.shadowRoot.querySelector('#chat-inquiry')
const $manualPlaying = global.shadowRoot.querySelector('#manual-play');
let $carousel = null;
/* 파일 관련 엘리먼트 */
const $chatUploadBtn = global.shadowRoot.querySelector('#chat-upload-btn');
const $chatFileUploadBtn = global.shadowRoot.querySelector('.chat-file-upload-btn')
const $chatFileUpload = global.shadowRoot.querySelector('#chat-file-upload')
/* 클립보드 관련 엘리먼트 */
const $chatClipboardBtn = global.shadowRoot.querySelector('.chat-clipboard-btn');
/* 폰트 사이즈 수정 엘리먼트 */
const $chatContentFont = global.shadowRoot.querySelector('#chat-content-font');
const $resizeFont = global.shadowRoot.querySelector('#resize-font');
const $resizeSample = global.shadowRoot.querySelector('.sample-text');
const $chatFontBtn = global.shadowRoot.querySelector('.chat-font-btn');
/*평가*/
const $chatRating = global.shadowRoot.querySelector('.star-rate');
const $chatRatingCtrl = $chatRating.querySelector('.star-rate span.ctrl');
const $chatRatingBtn = global.shadowRoot.querySelector('.chat-rating-btn');
const $chatRatingReview = global.shadowRoot.querySelector('#review');
/*세번째 탭 전체 검색 엘리먼트*/
const $chatAllSearchText = global.shadowRoot.querySelector('#chat-all-search-text');
const $chatAllSearchList = global.shadowRoot.querySelector('#chat-all-search-list');
/*세번째 탭 매뉴얼 검색*/
const $manualDocText = global.shadowRoot.querySelector('#manual-doc-text');
const $manualDocBody = global.shadowRoot.querySelector('#manual-doc-body');
/*세번째 탭 동영상 매뉴얼 검색*/
const $manualVideoText = global.shadowRoot.querySelector('#manual-video-text');
const $manualVideoBody = global.shadowRoot.querySelector('#manual-video-body');
/*채팅방내 엘리먼트*/
// 설정 드랍다운
let $contentDropdownOption;
const $contentOption = global.shadowRoot.querySelector('#chat-option');
const $contentOptionShow = global.shadowRoot.querySelector('.bi-three-dots-vertical');
/* 자세히 보기 설정 */
const $detailClose = global.shadowRoot.querySelector('#detail-close');
/*첨부파일 변수 정의*/
let $files = [];
/*타이핑 여부*/
let $typedFlag = false;
/*내용 검색 관련 변수*/
let lines = [];
let lines_idx = 0
if ($notiPermission) {
$notiPermission.addEventListener('click', async function () {
const permission = await requestNotificationPermission();
if (permission === 'granted') {
const notiCard = global.shadowRoot.querySelector('#noti-permission-card')
notiCard.remove();
allHtml.children[2].children[0].children[0].children.splice(0, 1)
}
})
}
/*bootstrap 수동 이벤트 설정*/
/*메뉴 탭 선택시 색상*/
$myTab.querySelectorAll('button[data-bs-toggle="tab"]').forEach(function (el) {
el.addEventListener('click', function (e) {
const tabTrigger = new Tab(e.currentTarget);
e.preventDefault();
if (!e.currentTarget.classList.contains('active')) {
tabTrigger.show();
$myTab.querySelectorAll('button[data-bs-toggle="tab"]').forEach(function (li) {
li.classList.remove('active');
li.parentNode.classList.remove('active');
})
e.currentTarget.classList.add('active');
e.currentTarget.parentNode.classList.add('active')
/*현재 톡방 진입되어 있을시 뒤로가기 처리*/
if (e.currentTarget.getAttribute("id") !== 'chat-tab') {
const chatBack = global.shadowRoot.querySelector('.contacts-list-show');
chatBack.click();
/*검색 닫기*/
global.searchClose();
}
/*홈 화면 매뉴얼 동영상 제어 */
const activePlay = $manualPlaying.querySelector('.active');
if (activePlay) {
const play = activePlay.querySelector("video")
if (e.currentTarget.dataset.bsTarget === '#intro') {
if (play) play.play()
$carousel.cycle();
} else {
if (play) play.pause()
$carousel.pause();
}
}
}
})
})
// 새로고침 이벤트 (untyped 메시지 전송, 로컬스토리지 제거, 쿠키 정보 삭제)
window.addEventListener('beforeunload', function (e) {
unload()
});
function unload() {
console.log('beforeunload')
/*현재 탭이 소켓 연결 되어 있으면 다른탭으로 소켓 전달*/
if (Common.isMaster()) {
HubEvent.sendSetMaster(global.talkParams({
type: 'SEND_SET_MASTER'
}))
}
/* 서버 서비스워커 연결 해제*/
HubEvent.close({
type: 'TAB_CLOSE',
tabId: global.tabId,
url: global.apiUrl,
sabun: global.user.sabun,
channelSabun: global.user.sabun,
site: global.currentUrl
});
/* 로컬 스토리지에 저장 되어 있는 탭정보 제거 */
const talkId = localStorage.getItem(global.tabId);
const workId = localStorage.getItem('workId');
localStorage.removeItem(global.tabId)
localStorage.removeItem('workId')
try {
/* 메시지 작성 내용이 없을시 해당 톡방 제거 */
const currentTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
if (currentTalk.lastMessage === null || currentTalk.lastMessage === '') {
talkEvent.leave(global.talkParams({
type: "LEAVE",
talkId: talkId,
workId: global.work.workId,
}))
}
if(talkId !== null || talkId !== '') {
/* 작성중인 메시지가 있을시 타이핑 메시지 해제 */
talkEvent.send(global.talkParams({
type: "UNTYPED",
talkId: talkId,
workId: workId
}))
}
} catch (e) {
}
talkEvent.allUnsubscribe()
global.hub.stop();
}
// 톡방 뒤로가기 클릭시 이벤트
const chatBack = global.shadowRoot.querySelector('.contacts-list-show');
chatBack.addEventListener('click', function () {
const talkId = localStorage.getItem(global.tabId);
// const workId = localStorage.getItem('workId');
// talkEvent.send(global.talkParams({
// type: "UNTYPED",
// talkId: talkId,
// workId: workId
// }))
// 톡방 옵션 자동 닫기
if ($contentDropdownOption) $contentDropdownOption.hide();
// 채팅목록 하이라이트 자동 제거
/*
*메시지 작성 내용이 없을시 해당 톡방 제거
*이미 삭제된 톡방 예외 처리
*/
const currentTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
if(currentTalk) {
try {
if (currentTalk.lastMessage === null || currentTalk.lastMessage === '') {
talkEvent.leave(global.talkParams({
type: "LEAVE",
talkId: talkId,
}))
} else {
currentTalk.talkMessages.talks = currentTalk.talkMessages.talks.splice(currentTalk.talkMessages.talks.length - 30, currentTalk.talkMessages.talks.length)
talkEvent.talkHeaderChange('', '')
global.reset();
}
} catch (e) {
currentTalk.talkMessages.talks = currentTalk.talkMessages.talks.splice(currentTalk.talkMessages.talks.length - 30, currentTalk.talkMessages.talks.length)
talkEvent.talkHeaderChange('', '')
global.reset();
}
}
/* 접속한 톡방 색상 표시 */
try {
const prevRoom = global.shadowRoot.querySelector(`div[data-talk-id="${talkId}"]`)
prevRoom.classList.add('bg-purple');
setTimeout(() => {
prevRoom.classList.remove('bg-purple');
}, 800)
} catch (e) {
}
global.scrollMoreFlag = true;
global.scrollObserveFlag = true;
});
// 오토 하이드 스크롤 정의
const scrollbarSetting = () => {
Array.prototype.forEach.call(global.shadowRoot.querySelectorAll('.scrollbar-overlay'), function (el) {
return new SimpleBar(el, {
autoHide: true,
forceVisible: true
});
});
new SimpleBar(global.shadowRoot.querySelector('.chat-floating'), {
autoHide: true
});
};
// 이미지 동영상 슬라이드 설정
const carouselSetting = () => {
$carousel = new Carousel($manualPlaying, {
interval: 10000,
wrap: true,
});
$manualPlaying.addEventListener('slide.bs.carousel', (e) => {
const prevVideo = $manualPlaying.querySelectorAll('video')[e.from];
if (prevVideo) {
prevVideo.pause();
prevVideo.currentTime = 0;
}
try {
const video = e.relatedTarget.querySelector('video')
video.play()
} catch (e) {
}
})
};
// 채팅 내용 입력시 자동 하단 스크롤
const contentResizeObserver = () => {
const contentBody = global.shadowRoot.querySelector('.chat-content-body');
const scrollbarVertical = contentBody.querySelector('.simplebar-vertical')
// const scrollbar = scrollbarVertical.querySelector('.simplebar-scrollbar')
const scrollBody = contentBody.querySelector('.simplebar-content')
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target.classList.contains('simplebar-content')) {
const contentSc = contentBody.querySelector('.simplebar-content-wrapper')
if (global.scrollObserveFlag) {
contentSc.scrollTop = scrollBody.clientHeight - contentSc.offsetHeight + 10000;
}
}
}
});
resizeObserver.observe(scrollBody);
// 채팅 내용 스크롤 (채팅 내용 호출)
contentBody.querySelector('.simplebar-content-wrapper').addEventListener('scroll', contentScrollEvent)
async function contentScrollEvent(e) {
const _contentScroll = e.currentTarget;
const scrollBody = contentBody.querySelector('.simplebar-content')
// 최종 스크롤 위치 저장
global.oldScrollPosition = (_contentScroll.scrollHeight - _contentScroll.scrollTop)
// 스크롤 활성화 되어 있는 상태에서 하단 높이가 100PX 보다 크면 옵저버 비황성화
if ((scrollBody.clientHeight - _contentScroll.offsetHeight) - _contentScroll.scrollTop >= 400) {
global.scrollObserveFlag = false;
}
if (_contentScroll.scrollTop < 400 && global.scrollMoreFlag) {
// 다중 호출 방지용
global.scrollMoreFlag = false;
const talkId = localStorage.getItem(global.tabId);
if (talkId) {
const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
// 메인탭 일시 메시지 호출
// 메인탭이 아닐시 메인탭으로 데이터 호출 하도록 통신
if (cacheTalk.talkMessages) {
if (cacheTalk.talkMessages.talks.length !== cacheTalk.talkMessages.total) {
cacheTalk.messageParams.start = cacheTalk.messageParams.start + cacheTalk.messageParams.row;
getMoreMessageLine(talkId).then((result) => {
if (result === 'success') {
global.scrollMoreFlag = true;
} else if (result === 'last') {
global.scrollMoreFlag = false;
}
}).catch((e) => {
global.scrollMoreFlag = false;
cacheTalk.messageParams.start = cacheTalk.messageParams.start - cacheTalk.messageParams.row;
})
}
}
}
}
// 스크롤 비활성화 되어 있는 상태에서 하단 높이가 200PX 미만 이면 옵저버 활성화
if (!global.scrollObserveFlag) {
if ((scrollBody.clientHeight - _contentScroll.offsetHeight) - _contentScroll.scrollTop < 400) {
console.log('스크롤 옵저버 활성화')
global.scrollObserveFlag = true;
global.shadowRoot.querySelector('.message-preview').classList.add('cus-hide');
}
}
}
}
// 채팅 버튼 클릭시
$chatFloatingBtn.addEventListener('click', () => {
const chatFloating = global.shadowRoot.querySelector('.chat-floating')
const chatBadge = global.shadowRoot.querySelector('.unread.badge');
const currentCarousel = global.shadowRoot.querySelector('.carousel-item.active');
if (currentCarousel !== '' && currentCarousel !== null) {
const currentVideo = currentCarousel.querySelector('video');
if (chatFloating.classList.contains('cus-hide')) {
if (currentVideo) currentVideo.play();
} else {
if (currentVideo) currentVideo.pause();
}
}
if (chatFloating.classList.contains('cus-hide')) {
chatFloating.classList.remove('cus-hide')
chatFloating.classList.add('cus-show')
$chatFloatingBtn.classList.add('active')
$carousel.cycle()
} else {
$chatFloatingBtn.classList.remove('active')
chatFloating.classList.remove('cus-show')
chatFloating.classList.add('cus-hide')
$carousel.pause();
}
if (chatBadge.innerText !== '0') chatBadge.classList.remove('cus-hide')
})
// 메시지 팝업창 스크롤 다운 버튼 클릭시 위치 조정
$chatScrollDownBtn.addEventListener('click', function () {
const contentBody = global.shadowRoot.querySelector('.chat-content-body');
const contentSc = contentBody.querySelector('.simplebar-content-wrapper')
const scrollBody = contentBody.querySelector('.simplebar-content')
contentSc.scrollTop = scrollBody.clientHeight - contentSc.offsetHeight
global.shadowRoot.querySelector('.message-preview').classList.add('cus-hide');
global.scrollObserveFlag = true;
})
/*문의 하기 이벤트 */
$chatInquiry.addEventListener('click', function () {
const talkId = talkEvent.generateUUID();
// 키보드 숨김 해제
global.element.chatEditorArea.classList.remove('cus-hide');
global.element.chatEditor.focus()
// 채팅 구독 메시지 보내기
localStorage.setItem(global.tabId, talkId)
localStorage.setItem('workId', global.work.workId)
talkEvent.join(global.talkParams({
type: 'JOIN',
talkId: talkId,
workId: global.work.workId,
introOwner: 'your'
}));
talkEvent.messageShow()
})
// 메시지 전송 이벤트
global.element.btnSend.addEventListener('click', function () {
const talkId = localStorage.getItem(global.tabId);
const workId = localStorage.getItem('workId');
const workNm = localStorage.getItem('workNm');
if(talkId === null || workId === null) {
global.notifier.alert('통신 오류가 발생 했어요.<br/>새로고침 해주세요.')
return;
}
// talkEvent.send(global.talkParams({
// type: "UNTYPED",
// talkId: talkId,
// workId: workId,
// workNm: workNm
// }))
const msg = global.element.chatEditor.innerText.trim();
if (msg) {
talkEvent.send(global.talkParams({
type: 'MESSAGE',
message: msg,
talkId: talkId,
workId: workId,
workNm: workNm
}))
global.checker.flag = true;
global.checker.inDate = new Date();
}
// 채팅 input 초기화
global.element.chatEditor.innerHTML = '';
// 첨부파일 초기화
$files = [];
$typedFlag = false;
})
// 채팅 에디트 붙여넣기 이벤트
global.element.chatEditor.addEventListener('paste', async function (e) {
e.preventDefault();
let isText = false;
for (const item of Array.from(e.clipboardData.items)) {
if (!item.type.includes('text')) {
global.clipboardData = item.getAsFile()
global.clipboardObjectUrl = URL.createObjectURL(global.clipboardData);
const clipboardConfirmWrap = global.shadowRoot.querySelector('.chat-clipboard-confirm-wrapper');
const clipboardImg = clipboardConfirmWrap.querySelector('img')
clipboardImg.setAttribute('src', global.clipboardObjectUrl);
clipboardConfirmWrap.classList.remove('cus-hide')
} else {
isText = true;
}
}
if (isText) {
// 클립보드에서 텍스트 가져오기
const clipboard = e.clipboardData || window.clipboardData;
document.execCommand('insertText', false, clipboard.getData("Text").trim());
// const textType = e.clipboardData.items[e.clipboardData.items.length - 1].type
// if(textType === 'text/rtf') {
// const clipboard = e.clipboardData || window.clipboardData;
//
// console.log(clipboard.getData("Text"))
// } else {
// e.clipboardData.items[e.clipboardData.items.length - 1].getAsString(data => {
// // HTML 태그 제거
// const cleanText = data.replace(/<[^>]*>/g, '');
// document.execCommand('insertText', false, cleanText.trim());
// });
// }
}
})
// 채팅 에디트 컨트롤 + ENTER 이벤트
let prevMessage = "";
global.element.chatEditor.addEventListener('keyup', function (e) {
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
insertNewlineAtCursor();
}
function insertNewlineAtCursor() {
document.execCommand('insertText', false, '\n');
// 변경 이벤트 발생
const event = new InputEvent('input', {
bubbles: true,
cancelable: true,
});
global.element.chatEditor.dispatchEvent(event);
// 스크롤 조정
global.element.chatEditor.scrollTop = global.element.chatEditor.scrollHeight;
}
const message = global.element.chatEditor.innerText
if (message.trim() === '' && prevMessage !== message) {
$typedFlag = false;
const workId = localStorage.getItem('workId');
const workNm = localStorage.getItem('workNm');
const talkId = localStorage.getItem(global.tabId);
global.queue.enqueue({
type: 'UNTYPED',
talkId: talkId,
workId: workId,
workNm: workNm
})
// talkEvent.send(global.talkParams({
// type: 'UNTYPED',
// talkId: talkId,
// workId: workId,
// workNm: workNm
// }))
/*contentededitable 빈값 일시 br 태그 제거*/
global.element.chatEditor.innerHTML = global.element.chatEditor.innerHTML.replace('<br>', '');
} else if (message.trim() !== '') {
if (!$typedFlag) {
$typedFlag = true;
const workId = localStorage.getItem('workId');
const workNm = localStorage.getItem('workNm');
const talkId = localStorage.getItem(global.tabId);
global.queue.enqueue({
type: 'TYPED',
talkId: talkId,
workId: workId,
workNm: workNm
})
// talkEvent.send(global.talkParams({
// type: 'TYPED',
// talkId: talkId,
// workId: workId,
// workNm: workNm
// }))
}
}
prevMessage = message
})
//채팅 에디트 ENTER 이벤트
global.element.chatEditor.addEventListener('keydown', function (e) {
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
} else if (e.key === 'Enter') {
e.preventDefault();
global.element.btnSend.click()
}
})
/* 클립보드 이미지 업로드 이벤트 */
$chatClipboardBtn.addEventListener('click', function (e) {
const dataTransfer = new DataTransfer();
dataTransfer.items.add(global.clipboardData);
const files = dataTransfer.files;
attachUpload(files).then(() => {
global.clipboardData = null;
URL.revokeObjectURL(global.clipboardObjectUrl)
global.clipboardObjectUrl = null;
})
const clipboardConfirmWrap = global.shadowRoot.querySelector('.chat-clipboard-confirm-wrapper');
clipboardConfirmWrap.classList.add('cus-hide')
})
// 채팅방 파일첨부 버튼 이벤트
$chatUploadBtn.addEventListener('click', function (e) {
const chatUploadConfirmWrapper = global.shadowRoot.querySelector('.chat-upload-confirm-wrapper')
chatUploadConfirmWrapper.classList.remove('cus-hide');
})
// 채팅방 파일첨부 확인 이벤트
$chatFileUploadBtn.addEventListener('click', function () {
$chatFileUpload.click();
const chatUploadConfirmWrapper = global.shadowRoot.querySelector('.chat-upload-confirm-wrapper')
chatUploadConfirmWrapper.classList.add('cus-hide');
})
// 첨부파일 업로드 이벤트
$chatFileUpload.addEventListener('change', async function (e) {
const fileInput = e.currentTarget;
let totSize = 0;
let next = true;
if (fileInput.files.length > 0) {
Array.from(fileInput.files).forEach((f) => {
const currentSize = Math.floor(f.size / (1024*1024));
if(Math.ceil(currentSize / (1024*1024)) > 10) {
next = false;
}
totSize += currentSize;
})
if(totSize > 30) {
global.notifier.alert('첨부파일 사이즈는 전체 30MB를 초과 할수 없어요.')
return false;
}
if(next) {
attachUpload(fileInput.files)
} else {
global.notifier.alert('파일 하나당 10MB를 초과 할수 없어요.')
return false;
}
}
})
// 톡방 설정 선택시 폰트 사이즈 변경 모달 활성화
$chatContentFont.addEventListener('click', (e) => {
$contentDropdownOption.hide();
const chatFontConfirmWrapper = global.shadowRoot.querySelector('.chat-font-confirm-wrapper')
chatFontConfirmWrapper.classList.remove('cus-hide');
})
// 폰트 사이즈 변경 마우스 이벤트
$resizeFont.addEventListener('mousemove', (e) => {
$resizeSample.style.fontSize = e.target.value + 'px';
})
// 폰트 사이즈 변경 저장시 캐시에 데이터 저장 모든 업무 공유용
$chatFontBtn.addEventListener('click', () => {
Common.setCookie("fontSize", $resizeFont.value);
const chatFontConfirmWrapper = global.shadowRoot.querySelector('.chat-font-confirm-wrapper')
chatFontConfirmWrapper.classList.add('cus-hide');
// document.documentElement.style.setProperty('--chat-content-custom-font-size', `${$resizeFont.value}px`)
global.registration.active.postMessage({type: 'FONT_CHANGE', size: $resizeFont.value})
})
// 채팅방 검색 버튼 이벤트
$contentSearch.addEventListener('click', () => {
if ($contentDropdownOption) $contentDropdownOption.hide();
global.scrollMoreFlag = false;
global.scrollObserveFlag = false;
$contentSearchSub.classList.remove('cus-hide')
$contentSearchSub.classList.add('cus-show')
$contentOption.classList.remove('bi-three-dots-vertical')
$contentOption.classList.add('bi-x-lg')
$contentSearchText.focus()
})
// 검색된 문자열 이동 이벤트
$contentSearchPrev.addEventListener('click', () => {
if (lines.length > 0 && lines_idx > 0) {
lines_idx = lines_idx - 1;
searchMove($contentSearchText.value);
}
})
// 검색된 문자열 이동 이벤트
$contentSearchNext.addEventListener('click', () => {
if (lines.length > 0 && lines.length > lines_idx + 1) {
lines_idx = lines_idx + 1;
searchMove($contentSearchText.value);
}
})
// 채팅방 검색 이벤트
$contentSearchText.addEventListener('keyup', (e) => {
const talkId = localStorage.getItem(global.tabId)
const _this = e.currentTarget;
if (e.key === 'Enter') {
searchHighLightReset()
if (_this.value.length < 2) {
global.notifier.alert('최소 2글자 이상 작성 해주세요')
return;
}
global.talkClean()
lines = [];
getMessageSearch({
talkId: talkId,
search: _this.value,
callback: function (lists) {
const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
if (lists.talks.length === 0) {
global.notifier.alert('조회된 대화 내용이 없어요')
} else {
cacheTalk.messageParams.start = lists.talks.length;
const chatContent = global.shadowRoot.querySelector('#chat-content');
const content = chatContent.querySelector('.simplebar-content');
content.style.marginTop = '50px'
messageMapping(talkId, lists, 'before', true);
const contentBody = global.shadowRoot.querySelector('.chat-content-body');
const wrappers = contentBody.querySelectorAll('.chat-text-wrapper');
wrappers.forEach((wp) => {
const value = wp.querySelector('.chat-message').innerText
const searchYn = wp.querySelector('.chat-message').getAttribute('search-yn');
if (value.includes(_this.value) && JSON.parse(searchYn)) {
lines.push(wp)
}
})
if (lines.length !== 0) {
lines_idx = lines.length - 1;
searchMove(_this.value);
}
}
}
})
}
})
// 위치 이동 기능
const searchMove = (search) => {
$contentSearchTot.setAttribute('data-tot', `${lines_idx + 1}/${lines.length}`)
const elementPosition = lines[lines_idx].offsetTop;
const contentBody = global.shadowRoot.querySelector('.chat-content-body')
const contentSc = contentBody.querySelector('.simplebar-content-wrapper')
searchHighLightReset();
const chatMassage = lines[lines_idx].querySelector('.chat-message');
chatMassage.innerHTML = chatMassage.textContent.replace(search, `<span class="search-text">${search}</span>`)
contentSc.scrollTo(0, elementPosition - 50)
try {
const checker = setInterval(() => {
console.log(contentSc.scrollTop, elementPosition)
if(contentSc.scrollTop === elementPosition - 50) {
const indicate = global.shadowRoot.querySelector('.loading-wrap')
indicate.classList.remove('cus-loading-show')
indicate.classList.add('cus-hide')
console.log('move ok')
clearInterval(checker)
}
}, 100)
} catch(e) {}
}
// 검색 문자열 하이라이트 기능
const searchHighLightReset = () => {
lines.forEach((li) => {
try {
const chatM = li.querySelector('.chat-message')
chatM.innerHTML = chatM.textContent;
} catch (e) {
}
})
}
// 톡방 전체 검색 ENTER 이벤트
$chatAllSearchText.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
searchHighLightReset()
const vNode = [];
const search = e.currentTarget.value;
const sc = $chatAllSearchList.querySelector('.simplebar-content');
if (search.length < 2 && search.length !== 0) {
global.notifier.alert('최소 2글자 이상 작성 해주세요')
return;
}
if (search.length === 0) {
vNode.push(allSearchEmpty)
m.render(sc, vNode);
return;
}
getAllContentSearch({
search: search,
callback: function (lists) {
if (lists.length > 0) {
lists.forEach((se) => {
const room = global.shadowRoot.querySelector(`div[data-talk-id="${se.talkId}"]`)
const workNm = room.dataset.workNm
vNode.push([
m('div', {
class: 'd-flex p-1 chat-text-wrapper chat-all-search cursor-pointer',
"data-all-line": `${se.line}`,
'data-all-chat-id': `${se.talkId}`,
}, [
m('div', {class: 'avatar avatar-l me-2', style: 'flex-basis:5%;'}, [
m('div', {
class: "rounded-circle",
style: "width:30px;height:30px;border-radius:10px;background-color:#A9E4FF;text-align:center; line-height:32px;"
}, workNm.substring(0, 1))
]),
m('div', {class: 'w-xxl-85', style: 'flex-basis:63%;'}, [
m('div', {
class: `chat-message bg-200 p-2 rounded-2 ml-10 your`,
style: 'max-width: 100% !important;font-size:0.83333em;'
}, se.message),
m('div', {
class: `ml-10`,
style: 'font-size:12px'
}, `${workNm} (${se.insName})`)
]),
m('div', {class: 'text-400 fs-11 chat-date ml-10'}, se.insDate.substring(0, 10))
])
]);
});
m.render(sc, vNode);
} else {
vNode.push(allSearchEmpty)
m.render(sc, vNode);
}
}
})
}
})
/*매뉴얼 검색 이벤트*/
$manualDocText.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
getManual({
search: e.currentTarget.value,
workId: e.currentTarget.value === '' ? global.work.workId : '',
type: '0000',
callback: function (lists) {
const manualVNode = [];
const content = $manualDocBody.querySelector('.simplebar-content');
if (lists.length !== 0) {
lists.map((ma) => {
manualVNode.push(
m('div', {class: "d-flex justify-content-evenly manual-content"}, [
m('div', {
class: "p-2 text-ellipsis",
style: "font-size:13px; width:70%;"
}, `${ma.onm}`),
m('div', {class: "p-2", style: "font-size:13px; width:20%;"}, `${ma.version}`),
m('a', {
href: `${global.apiUrl}/api/manual/download/doc?workId=${ma.workId}&vnm=${ma.vnm}`,
style: 'padding-top:3px;'
}, [
m('i', {
class: "bi bi-download text-black",
style: "padding-right:10px; font-size:1.0rem; cursor:pointer;"
})
])
])
)
})
m.render(content, manualVNode)
} else {
manualVNode.push(allSearchEmpty)
m.render(content, manualVNode)
}
}
})
}
})
/*동영상 매뉴얼 검색 이벤트*/
$manualVideoText.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
getVideoManual({
search: e.currentTarget.value,
workId: e.currentTarget.value === '' ? global.work.workId : '',
callback: function (lists) {
const manualVNode = [];
const content = $manualVideoBody.querySelector('.simplebar-content');
if (lists.length !== 0) {
lists.map((ma) => {
manualVNode.push(
m('div', {class: "d-flex justify-content-evenly manual-content"}, [
m('div', {
class: "p-2 text-ellipsis",
style: "font-size:13px; width:70%;"
}, `${ma.onm}`),
m('button', {
class: 'btn btn-sm btn-play manual-play-btn p-0',
'data-id': ma.id,
}, '재생')
])
)
})
m.render(content, manualVNode)
} else {
manualVNode.push(allSearchEmpty)
m.render(content, manualVNode);
}
// videoManualPlayEvent();
}
})
}
})
// 사이드바 위치 검색 기능
const calcSliderPos = (e, maxV) => {
return (e.offsetX / e.target.clientWidth) * parseInt(maxV, 10);
}
// 만족도 조사 별점 스타일 변경 이벤트
const upStar = (val) => {
val = parseFloat(val);
$chatRating.dataset.val = val;
const full = Number.isInteger(val);
val = parseInt(val);
const stars = $chatRating.querySelectorAll('i')
Array.from(stars).slice(0, val).forEach((star) => star.setAttribute('class', 'bi bi-star-fill'));
Array.from(stars).slice(val, 5).forEach((star) => star.setAttribute('class', 'bi bi-star'));
}
let hoverValue = 0
$chatRating.addEventListener('click', function (e) {
e.target.dataset.val = hoverValue;
})
// 만족도 조사 별점 선택 이벤트
$chatRatingCtrl.addEventListener('click', function (e) {
const maxV = parseInt($chatRating.dataset.max)
hoverValue = Math.ceil(calcSliderPos(e, maxV) * 2) / 2;
if (hoverValue < 1) hoverValue = 1
upStar(hoverValue)
})
// 만족도 조자 저장 이벤트
$chatRatingBtn.addEventListener('click', function (e) {
const chatRatingConfirmWrapper = global.shadowRoot.querySelector('.chat-rating-confirm-wrapper')
/* ratingYn = true 변경 */
const talk = global.talkData.filter((talk) => talk.talkId === localStorage.getItem(global.tabId));
talk[0].ratingYn = true;
talkMapping(global.talkData)
const reqId = talk[0].reqId;
const star = $chatRating.dataset.val
const content = $chatRatingReview.value
if (star < 5 && (content === null || content === '')) {
global.notifier.alert('만족도 조사 내용을 작성해 주세요.')
return false;
}
chatRatingConfirmWrapper.classList.add('cus-hide')
/* api전송 로직 추가*/
if(reqId.includes('REQ')) {
setSCMSatis(talk[0].talkId, reqId, star, content)
} else {
setITSMSatis(talk[0].talkId, reqId, star, content)
}
/*파라미터 초기화*/
$chatRating.dataset.val = 5;
$chatRatingCtrl.dataset.val = 5;
$chatRating.querySelectorAll('i').forEach((i) => {
i.classList.remove('bi-star-half');
i.classList.remove('bi-star');
i.classList.add('bi-star-fill')
})
$chatRatingReview.value = "";
})
/*자세히보기 닫기 이벤트*/
$detailClose.addEventListener('click', () => {
const detailContainer = global.shadowRoot.querySelector('#detail-container');
detailContainer.classList.remove('cus-show')
detailContainer.classList.add('cus-hide')
detailContainer.setAttribute('src', '')
})
/*----------- 동적 생성 엘리먼트 이벤트 정의 시작 ---------------*/
// 톡방 검색 닫기 버튼 클릭시 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '#chat-option.bi-x-lg', function (e) {
e.preventDefault();
e.stopPropagation();
const chatContent = global.shadowRoot.querySelector('#chat-content');
const content = chatContent.querySelector('.simplebar-content');
content.style.marginTop = '0px'
global.scrollMoreFlag = false
global.scrollObserveFlag = false;
$contentSearchText.value = ""
$contentSearchTot.setAttribute('data-tot', `0/0`)
$contentSearchSub.classList.remove('cus-show');
$contentSearchSub.classList.add('cus-hide');
$contentOption.classList.add('bi-three-dots-vertical')
$contentOption.classList.remove('bi-x-lg')
searchHighLightReset();
// 자동 증가 되는 로우 수 만큼 뺌(스크롤시 자동증가 되는거 만큼 빼줌)
// global.messageParams.start = global.messageData.length - global.messageParams.row;
// global.scrollMoreFlag = false;
// global.scrollObserveFlag = false;
function scrollEnable() {
global.scrollMoreFlag = true;
global.scrollObserveFlag = true;
}
setTimeout(scrollEnable, 1000)
if ($contentDropdownOption) $contentDropdownOption.hide();
})
// 채팅방 검색 및 폰트 설정 드랍다운 설정
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.bi-three-dots-vertical', function (e) {
e.preventDefault();
e.stopPropagation();
const el = e.currentTarget;
/* 드랍다운 오류(z-index 강제 변경 로직 추가)*/
$contentDropdownOption = new Dropdown(el, {
autoClose: "true",
});
$contentDropdownOption.toggle();
})
// 컨펌 취소 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-confirm-cancel', function (e) {
const chatConfirmWrapper = Common.findParentElement(e.target, 'chat-confirm-wrapper');
chatConfirmWrapper.classList.add('cus-hide');
chatConfirmWrapper.classList.remove('cus-show');
})
/*톡목록 옵션 선택 이벤트*/
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-options', function (e) {
e.preventDefault();
e.stopPropagation();
const el = e.currentTarget;
/* 드랍다운 오류(z-index 강제 변경 로직 추가)*/
const drop = new Dropdown(el, {
autoClose: "true"
});
global.shadowRoot.querySelectorAll('.chat-options').forEach(function (el1) {
if (el !== el1) {
const otherDrop = new Dropdown(el1, {
autoClose: "true"
});
otherDrop.hide();
el1.parentElement.parentElement.parentElement.style.zIndex = 0;
} else {
if ((global.element.chatSidebar.getBoundingClientRect().bottom - el.getBoundingClientRect().bottom) < 100) {
el.parentElement.classList.add('dropup')
} else {
el.parentElement.classList.remove('dropup')
}
}
});
const ul = el.nextElementSibling;
if (ul.classList.contains('cus-show')) {
el.parentElement.parentElement.parentElement.style.zIndex = 0;
drop.hide()
} else {
drop.show();
el.parentElement.parentElement.parentElement.style.zIndex = Number(el.parentElement.parentElement.parentElement.style.zIndex) + 10;
}
return false;
})
/* 톡방 보관 이벤트*/
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-mark', function (e) {
e.preventDefault();
e.stopPropagation();
const dropdownWrap = Common.findParentElement(e.target, 'dropdown');
const drop = new Dropdown(dropdownWrap.querySelector('.chat-options'));
drop.hide()
const chatWrap = Common.findParentElement(e.target, 'chat-wrap')
const talkId = chatWrap.dataset.talkId;
setTalkMark({
talkId: talkId,
callback: (data) => {
HubEvent.send(global.talkParams({
type: 'MARK',
talkId: talkId
}))
}
})
})
//톡방 삭제버튼 클릭 컨펌창 활성화
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-delete', function (e) {
const chatDeleteConfirmWrapper = global.shadowRoot.querySelector('.chat-confirm-wrapper')
chatDeleteConfirmWrapper.classList.remove('cus-hide');
e.stopPropagation();
e.preventDefault();
const dropdownWrap = Common.findParentElement(e.target, 'dropdown');
const drop = new Dropdown(dropdownWrap.querySelector('.chat-options'));
drop.hide()
const chatWrap = Common.findParentElement(e.target, 'chat-wrap')
chatDeleteConfirmWrapper.dataset.talkId = chatWrap.dataset.talkId;
chatDeleteConfirmWrapper.dataset.closeYn = chatWrap.dataset.closeYn;
chatDeleteConfirmWrapper.dataset.compYn = chatWrap.dataset.compYn;
})
// 톡방 삭제 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-delete-btn', function (e) {
const chatDeleteConfirmWrapper = global.shadowRoot.querySelector('.chat-confirm-wrapper')
chatDeleteConfirmWrapper.classList.add('cus-hide');
const talkId = chatDeleteConfirmWrapper.dataset.talkId;
const closeYn = chatDeleteConfirmWrapper.dataset.closeYn;
const compYn = chatDeleteConfirmWrapper.dataset.compYn;
if (closeYn === 'false') {
global.notifier.alert("상담 종료후 삭제 가능해요.")
return;
}
deleteTalk({
talkId: talkId,
callback: (data) => {
if (data) {
if (localStorage.getItem('talkId') === talkId) {
const chatBack = global.shadowRoot.querySelector('.contacts-list-show');
chatBack.click();
}
// talkEvent.talkRemove(talkId)
HubEvent.send(global.talkParams({
type: 'DELETE',
talkId: talkId
}))
} else {
global.notifier.alert("상담 종료후 삭제 가능해요.")
}
}
})
})
// 톡방 입장 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-wrap', function (e) {
global.scrollMoreFlag = true;
global.scrollObserveFlag = true;
const _this = e.currentTarget;
const unreadFlag = _this.classList.contains('unread-message');
_this.classList.add('active');
!e.target.classList.contains('hover-actions') && (global.element.chatSidebar.style.left = '-100%');
// _this.classList.contains('unread-message') && _this.classList.remove('unread-message');
/*룸 클릭시 채팅 내용 호출 */
const talkId = _this.dataset.talkId;
const workId = _this.dataset.workId;
const workNm = _this.dataset.workNm;
const workSmNm = _this.dataset.workSmNm;
const closeYn = _this.dataset.closeYn;
const ratingYn = _this.dataset.ratingYn;
console.log(talkId);
// 방 접속시 기본 데이터 저장
localStorage.setItem(global.tabId, talkId);
localStorage.setItem('workId', workId);
localStorage.setItem('workNm', workNm);
global.element.chatEditor.focus()
/*톡방 만족도 조사 실행 로직*/
if (JSON.parse(closeYn)) {
global.element.chatEditorArea.classList.add('cus-hide');
} else {
global.element.chatEditorArea.classList.remove('cus-hide');
}
if (JSON.parse(closeYn) && !JSON.parse(ratingYn)) {
const chatRatingConfirmWrapper = global.shadowRoot.querySelector('.chat-rating-confirm-wrapper')
function ratingShow() {
chatRatingConfirmWrapper.classList.remove('cus-hide')
chatRatingConfirmWrapper.classList.add('cus-show')
}
setTimeout(ratingShow, 800)
}
talkEvent.talkHeaderChange(workNm, workSmNm)
const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
messageMapping(talkId, cacheTalk.talkMessages, 'before', true)
// 안읽은 메시지 있을시 진행
if (unreadFlag) {
// 구독된 톡방 읽음처리
if (Object.keys(global.subscribeList).includes(talkId)) {
// 소켓 연결이 존재 할시 읽음처리 브로드캐스트로 메시지 읽음 전송
talkEvent.send(global.talkParams({
type: 'READ',
talkId: talkId,
workId: workId
}))
} else {
setChatRead(talkId).then((result) => {
// talkEvent.readMessage(talkId)
// talkMapping(global.talkData)
})
}
// 구독이 안된 톡방 읽음처리 브로드캐스트로 메시지 읽음 전송
HubEvent.send(global.talkParams({
type: "READ",
talkId: talkId,
insSabun: global.user.sabun
}))
}
// const chatContent = global.shadowRoot.querySelector('#chat-0');
// chatContent.querySelector('.simplebar-offset').style.bottom = '0px';
})
// 톡방 이미지 모달 수동 제어 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', 'div[data-bs-toggle="modal"]', function (e) {
const imageModal = global.shadowRoot.querySelector(e.target.getAttribute('data-bs-target'));
const modal = new Modal(imageModal, {
backdrop: true,
keyboard: true,
})
modal.show()
})
// 동영상 메뉴얼 재생 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.manual-play-btn', function (e) {
const id = e.currentTarget.dataset.id;
const videoPlayArea = global.shadowRoot.querySelector('#manual-video-play');
const videoPlay = videoPlayArea.querySelector('video');
const videoPlaySource = videoPlay.querySelector('source');
const videoList = global.shadowRoot.querySelector('#manual-video-body');
videoPlayArea.classList.remove('cus-hide')
videoPlayArea.classList.add('cus-show')
// videoList.classList.remove('cus-show')
// videoList.classList.add('hide-08s')
videoPlaySource.setAttribute('src', `${global.apiUrl}/api/manual/view/video?id=${id}&type=O`)
videoPlay.load();
videoPlay.play();
// m.render(videoPlay, video)
global.shadowRoot.querySelector('#manual-video-back').addEventListener('click', function () {
videoPlayArea.classList.remove('cus-show')
videoPlayArea.classList.add('cus-hide')
// videoList.classList.remove('hide-08s')
// videoList.classList.add('cus-show')
videoPlay.pause();
videoPlaySource.setAttribute('src', '')
})
})
// 톡방 전체 검색 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '.chat-all-search', function (e) {
const indicate = global.shadowRoot.querySelector('.loading-wrap')
indicate.classList.remove('cus-hide')
indicate.classList.add('cus-loading-show')
lines = [];
const line = e.currentTarget.getAttribute("data-all-line")
const talkId = e.currentTarget.getAttribute("data-all-chat-id")
const room = global.shadowRoot.querySelector(`div[data-talk-id="${talkId}"]`)
const workNm = room.dataset.workNm
const workSmNm = room.dataset.workSmNm
talkEvent.talkHeaderChange(workNm, workSmNm)
localStorage.setItem(global.tabId, talkId);
global.messageParams.talkId = talkId;
const findText = $chatAllSearchText.value;
getMessageSearch({
talkId: talkId,
search: findText,
callback: function (lists) {
talkEvent.messageShow()
$contentSearch.click();
$contentSearchText.value = findText;
messageMapping(talkId, lists, 'before', true);
const contentBody = global.shadowRoot.querySelector('.chat-content-body');
const wrappers = contentBody.querySelectorAll('.chat-text-wrapper');
for(let idx =0; idx< wrappers.length; idx++) {
const wp = wrappers[idx];
const msg = wp.querySelector('.chat-message')
const value = msg.innerText
const searchYn = msg.getAttribute('search-yn');
if (value.includes(findText) && JSON.parse(searchYn)) {
lines.push(wp)
const getLine = msg.getAttribute('data-line');
if (line === getLine) {
lines_idx = lines.length - 1;
}
}
}
setTimeout(searchMove, 200, findText)
}
});
})
// 톡방 전체 검색 이벤트
Common.addDelegatedEventListener(global.shadowRoot, 'click', '#socket-reset-btn', function (e) {
talkEvent.repair()
})
/*----------- 동적 생성 엘리먼트 이벤트 정의 종료 ---------------*/
// HTML 로드 완료후 스크롤, 비디오, 스크롤 옵저버 호출
docReady(scrollbarSetting)
docReady(carouselSetting)
docReady(contentResizeObserver)
// 홈탭 동영상 풀스크린 실행시 숏동영상 정지 처리
document.addEventListener('fullscreenchange', function () {
const activePlay = $manualPlaying.querySelector('.active');
if (activePlay) {
const isFullScreen = document.fullScrenn || document.mozFullScreen || document.webkitIsFullScreen;
if (isFullScreen) {
$carousel.pause();
} else {
$carousel.cycle();
}
}
})
// 홈탭 동영상 풀스크린 실행시 숏동영상 정지 처리
document.addEventListener('webkitfullscreenchange', function (e) {
const activePlay = $manualPlaying.querySelector('.active');
if (activePlay) {
const isFullScreen = document.fullScrenn || document.mozFullScreen || document.webkitIsFullScreen;
if (isFullScreen) {
$carousel.pause();
} else {
$carousel.cycle();
}
}
})
// 홈탭 동영상 풀스크린 실행시 숏동영상 정지 처리
document.addEventListener('mozfullscreenchange', function () {
const activePlay = $manualPlaying.querySelector('.active');
if (activePlay) {
const isFullScreen = document.fullScrenn || document.mozFullScreen || document.webkitIsFullScreen;
if (isFullScreen) {
$carousel.pause();
} else {
$carousel.cycle();
}
}
})
// 헬프톡 제외한 다른 탭 선택시 헬프톡 비활성화 이벤트
document.addEventListener('click', function (e) {
if (e.target.getAttribute('id') !== 'chat-area') {
const chatFloating = global.shadowRoot.querySelector('.chat-floating')
if (!chatFloating.classList.contains('cus-hide')) {
$chatFloatingBtn.click();
const chatBack = global.shadowRoot.querySelector('.contacts-list-show');
chatBack.click();
}
}
})
// 화면 꺼짐 방지용
document.addEventListener('click', () => {
this.requestWakeLock()
}, {once: true})
// 중복 이벤트 방지
let isHandlingEvent = false;
// 브라우저 탭 활성화 시 서비스워커 꺠우기 및 소켓 재연결 처리
document.addEventListener('visibilitychange', function () {
if(document.hidden) {
const chatBack = global.shadowRoot.querySelector('.contacts-list-show');
chatBack.click();
} else {
tabChangeEvent();
}
global.registration.active.postMessage({"type":"WAKEUP"})
});
// 톡방 itsm, scm 자세히 보기 클릭시 이벤트 해당 요청 및 작성지시 팝업
global.shadowRoot.addEventListener('click', (e) => {
if(e.target.classList.contains('detail-btn')) {
const detailContainer = global.shadowRoot.querySelector('#detail-container');
detailContainer.querySelector('iframe').setAttribute('src', e.target.dataset.href)
detailContainer.classList.remove('cus-hide')
detailContainer.classList.add('cus-show')
}
})
global.shadowRoot.addEventListener('keydown', (e) => {
e.stopPropagation();
})
document.addEventListener('mouseenter', function() {
tabChangeEvent();
})
const tabChangeEvent = (e) => {
if(!Common.isMaster() && global.init) {
console.log('탭이동 및 마우스 엔터 재연결 시도 성공')
} else if(Common.isMaster) {
console.log('활성화된 탭')
} else if(!global.init) {
console.log('재접속 하기 위한 초기화가 되지 않음')
}
if (!Common.isMaster()) {
if(!global.init) return;
// 허브 이벤트 제거
global.hub.stop();
try {
if (global.sockJS.readyState !== 1 && !global.forceKill) {
// 초기화 완료 상태값 변경
global.init = false;
talkEvent.reConnect()
}
} catch (e) {
global.init = false;
talkEvent.reConnect();
}
}
}
}
}
export {Talk}