import { createElement, setTooltip, showAlert, createPicture, createAudio, createVideo, createFile, createIcon, Popup, Grid, Dropdown } from "../../ui"; import { global, isEmail } from "../../utility"; export function createBox(title, functions) { const container = createElement('div', 'comm'); const header = createElement('div', 'title-bar', title, createElement('div', 'title-functions', ...functions) ); container.appendChild(header); return container; }; export function appendMedia(container, mimeType, url) { switch (mimeType) { case 'application/pdf': case '.pdf': container.appendChild(createFile(url, 'file-pdf')); break; case 'application/msword': case 'application/vnd.ms-word': case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': case '.doc': case '.docx': container.appendChild(createFile(url, 'file-word')); break; case 'application/vnd.ms-excel': case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': case '.xls': case '.xlsx': container.appendChild(createFile(url, 'file-excel')); break; case 'application/vnd.ms-powerpoint': case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': case '.ppt': case '.pptx': container.appendChild(createFile(url, 'file-powerpoint')); break; case 'application/smil': case '.smil': // TODO: ignore smil files // container.appendChild(createFile(url, 'smile')); break; case 'audio/aac': case 'audio/amr': case 'audio/mp3': case 'audio/mpeg': case 'audio/x-mpeg': case 'audio/ogg': case 'audio/opus': case 'audio/wav': case 'audio/webm': case '.aac': case '.amr': case '.mp3': case '.ogg': case '.opus': case '.wav': container.appendChild(createAudio(mimeType, url)); break; case 'text/plain': case 'text/x-vcard': case '.txt': case '.vcard': container.appendChild(createFile(url, 'id-card')); break; case 'video/3gpp': case 'video/mp2t': case 'video/mp4': case 'video/mpeg': case 'video/x-mpeg': case 'video/quicktime': case 'video/webm': case '.3gp': case '.3gpp': case '.mp4': case '.mpg': case '.mov': case '.webm': container.appendChild(createVideo(url)); break; case '.jpg': case '.jpeg': case '.jfif': case '.png': case '.gif': case '.bmp': container.appendChild(createPicture(url)); break; default: if (/^image\//.test(mimeType)) { container.appendChild(createPicture(url)); } else if (/^audio\//.test(mimeType)) { container.appendChild(createFile(url, 'music')); } else if (/^video\//.test(mimeType)) { container.appendChild(createFile(url, 'video')); } else { container.appendChild(createFile(url)); } break; } return container; }; const MaxAttachmentSize = { limit: 1_258_291, text: '1.2MB' }; export const fileSupported = [ '.amr', '.ogv', 'application/msword', 'application/vnd.ms-word', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/pdf', 'audio/aac', 'audio/amr', 'audio/mp3', 'audio/mpeg', 'audio/x-mpeg', 'audio/ogg', 'audio/opus', 'audio/wav', 'audio/webm', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jfif', 'image/png', 'image/tiff', 'image/webp', 'text/plain', 'text/vcard', 'text/x-vcard', 'video/3gpp', 'video/mp2t', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/webm', ]; export function insertFile(container, file, r) { const label = container.querySelector('.file-selector>.selector-name'); if (label != null && file != null) { let type = file.type; if (type == null || type.length === 0) { type = file.name; type = type.substring(type.lastIndexOf('.')); } if (fileSupported.indexOf(type) < 0) { showAlert(r('FLTL_01165', 'Error'), r('FLTL_01385', 'File type "{type}" is now not supported.').replace('{type}', type)); return; } const isImage = /^image\//.test(type); if (!isImage && file.size > MaxAttachmentSize.limit) { showAlert(r('FLTL_01165', 'Error'), r('FLTL_00407', `Attachment size exceeds the maximum allowed to be sent (${MaxAttachmentSize.text})`), 'warn'); return; } const fn = file.name; label.style.display = ''; label.innerText = fn; if (isImage) { const img = new Image(); const reader = new FileReader(); reader.onload = e => { img.src = e.target.result; setTooltip(label, img); }; reader.onerror = () => setTooltip(label, fn); reader.readAsDataURL(file); // img.src = URL.createObjectURL(file); // setTooltip(label, img); } else { setTooltip(label, fn); } return file; } }; function getStatusText(status, dict) { switch (status) { case 0: case 1: case 5: case 6: return dict[status]; case 9: case 10: case 412: return dict[9]; default: return dict[9999]; } } export function getMessageStatus(comm, r, _var) { const messageStatus = { 0: r('FLTL_02186', 'Pending'), 1: r('FLTL_02711', 'Sent'), 5: r('FLTL_00864', 'Delivery Confirmed'), 6: r('FLTL_02478', 'Resent'), 9: r('FLTL_01224', 'Failed'), 9999: r('FLTL_03152', 'Unknown') }; const knownStatus = [0, 1, 5, 6, 9, 10, 412]; const okStatus = [1, 5, 6]; const failedStatus = [9, 10, 412]; let status = -100; // 没有状态,页面上不显示 const ls = []; const msgs = []; if (!comm.StatusIncorrect && comm.Participator?.length > 0) { // if (comm.Id === 433339) { // comm.Participator[4].Status = 6; // } for (let p of comm.Participator) { if (!isEmail(p.CustomerNumber)) { if (ls.indexOf(p.Status) < 0) { ls.push(p.Status); } p.statusText = getStatusText(p.Status, messageStatus); msgs.push(p); } } } if (ls.length === 1) { status = ls[0]; } else if (ls.length > 1) { // status = -10; // 多种状态 status = ls .filter(s => okStatus.indexOf(s) < 0) // ok status .sort((a, b) => b - a)[0] ?? 1; } const statusText = messageStatus[failedStatus.includes(status) ? 9 : status] ?? messageStatus[9999]; const statusColor = okStatus.includes(status) ? null : '#ffc107'; const statusUpdatable = _var.option.statusUpdatable; let statusTips; if (statusUpdatable !== false || ls.length > 1) { statusTips = createElement('div', tip => { for (let i = 0; i < msgs.length; ++i) { tip.appendChild(createElement('div', t => { const p = msgs[i]; if (statusUpdatable !== false && p.StatusChanged) { t.append( createElement('span', s => s.innerText = `${p.CustomerNumber}: `), createElement('span', s => { s.style.color = '#2140fb'; s.style.cursor = 'pointer'; s.innerText = p.statusText; s.addEventListener('click', () => { if (typeof _var.option.onMessageStatusClicked === 'function') { _var.option.onMessageStatusClicked(p); } }); }) ) } else { t.innerText = `${p.CustomerNumber}: ${p.statusText}`; } })); } if (statusUpdatable !== false) { tip.appendChild(createElement('div', b => { b.className = 'tip-function-button'; // setTooltip(b, r('FLTL_03174', 'Update Status')); b.addEventListener('click', async () => { for (let p of comm.Participator) { switch (p.Status) { case 0: case 1: case 5: case 6: p.statusChanged = String(p.Status); break; case 9: case 10: case 412: p.statusChanged = '9'; break; default: p.statusChanged = '-1'; break; } } const gridContainer = createElement('div', 'status-grid'); const popup = new Popup({ onMasking: _var.option.onMasking, title: r('FLTL_03174', 'Update Status'), content: createElement('div', wrapper => { wrapper.className = 'update-status-wrapper'; wrapper.style.width = '500px'; }, gridContainer ), buttons: [ { text: r('FLTL_02057', 'OK'), key: 'ok', trigger: () => { const changed = msgs.filter(m => { switch (m.statusChanged) { case '-1': return knownStatus.includes(m.Status); case '9': return failedStatus.indexOf(m.Status) < 0; default: return String(m.Status) !== m.statusChanged; } }).map(m => { let status = Number(m.statusChanged); if (isNaN(status) || status < 0) { status = 9999; } return { Id: m.Id, Status: status }; }); if (typeof _var.option.onUpdateMessageStatus === 'function') { _var.option.onUpdateMessageStatus(changed); } } }, { text: r('FLTL_00499', 'Cancel'), key: 'cancel' } ] }); await popup.show(); const grid = new Grid(gridContainer); // grid.headerVisible = false; grid.allowHtml = true; grid.columns = [ { key: 'CustomerNumber', caption: r('FLTL_02026', 'Number'), width: 150 }, /*{ key: 'customerName', caption: r('FLTL_00742', 'Customer Name'), width: 120 },*/ { key: 'statusText', caption: r('FLTL_00725', 'Current Status'), width: 155 }, { key: 'statusChanged', caption: r('FLTL_02511', 'Revised Status'), width: 155, type: Grid.ColumnTypes.Dropdown, source: [ { value: '-1', text: messageStatus[9999] }, { value: '0', text: messageStatus[0] }, { value: '1', text: messageStatus[1] }, { value: '5', text: messageStatus[5] }, { value: '6', text: messageStatus[6] }, { value: '9', text: messageStatus[9] } ] } ]; grid.init(); grid.source = msgs; }); }, createIcon('fa-light', 'wave-sine'))); } }); } return [status, statusText, statusColor, statusTips]; }; export function getMessageSendTo(comm, contacts, followers, r) { let sendto = ''; if (!comm.IsReply && comm.OriPhoneNumbers?.length > 0) { for (let oriph of comm.OriPhoneNumbers) { let cname; const email = isEmail(oriph); if (contacts?.length > 0) { let c = email ? contacts.find(c => c.Email === oriph) : contacts.find(c => c.MobilePhone === oriph); if (c != null) { cname = `${email ? c.Email : c.MobilePhoneDisplayText} - ${c.Name}`; } else if (followers?.length > 0) { c = email ? followers.find(f => f.Email === oriph) : followers.find(f => f.MobilePhone === oriph); if (c != null) { cname = `${email ? c.Email : c.MobilePhoneDisplayText} - ${c.Name}`; } } } sendto += (cname ?? oriph) + '\n'; } } if (sendto !== '') { sendto = r('FLTL_02716', 'Sent to :') + `\n${sendto}`; } return sendto; } export function updateCustomerName(messages, contacts) { if (messages?.length > 0 && contacts?.length > 0) { for (let m of messages) { if (m.Participator?.length > 0) { for (let p of m.Participator) { const contact = contacts.filter(c => c.MobilePhoneDisplayText === p.CustomerNumber)[0]; p.customerName = contact?.Name; } } } } } export function createHideMessageTitleButton(This, optionName) { const option = This._var.option; return createElement('span', span => { if (option.userIsAdmin) { if (option[optionName]) { span.className = 'msgadminsetting sbutton iconview'; } else { span.className = 'msgadminsetting sbutton iconnotview'; } span.style.padding = '0px 0px 0px 5px'; setTooltip(span, option?.getText('FLTL_01860', 'Manage Messages')); span.addEventListener('click', function () { const container = This._var.container; if (!option[optionName]) { this.classList.remove('iconnotview'); this.classList.add('iconview'); option[optionName] = true; container.querySelectorAll('.msgsetting').forEach(x => x.style.display = ''); container.querySelectorAll('.msgHistory').forEach(h => h.style.display = h.getAttribute('ModifyCount') > 0 ? '' : 'none'); container.querySelectorAll('.hidden-content').forEach(c => c.style.display = ''); } else { this.classList.remove('iconview'); this.classList.add('iconnotview'); option[optionName] = false; container.querySelectorAll('.msgsetting').forEach(x => x.style.display = 'none'); container.querySelectorAll('.msgHistory').forEach(h => h.style.display = 'none'); container.querySelectorAll('.hidden-content').forEach(c => c.style.display = 'none'); } }); } }); } export function createHideMessageCommentTail(This, optionName, comment, commentTime, func, hisFunc) { const option = This._var.option; const showTooltip = option?.getText('FLTL_03267', 'Visible'); const notShowTooltip = option?.getText('FLTL_02006', 'Not Visible'); return createElement('div', div => { div.className = 'item-time'; div.style.display = 'flex'; div.style.alignItems = 'center'; }, createElement('span', span => { span.className = 'msgsetting sbutton ' + (comment.Hidden ? 'iconnotview' : 'iconview'); span.style.padding = '0'; span.style.fontSize = '12px'; setTooltip(span, comment.Hidden ? notShowTooltip : showTooltip); span.style.display = option[optionName] ? '' : 'none'; span.addEventListener('click', function () { if (this.classList.contains('iconview')) { func(comment.Id, true); this.classList.remove('iconview'); this.classList.add('iconnotview'); setTooltip(this, notShowTooltip); } else { func(comment.Id, false); this.classList.remove('iconnotview'); this.classList.add('iconview'); setTooltip(this, showTooltip); } if (isNaN(comment.ModifyCount)) { comment.ModifyCount = 1; } else { comment.ModifyCount += 1; } const x = This._var.container.querySelector('.history-span-' + comment.Id); if (x != null) { x.setAttribute('ModifyCount', comment.ModifyCount); x.style.display = (option[optionName] && comment.ModifyCount > 0) ? '' : 'none'; } }); }), createElement('span', span => { span.className = 'msgHistory history-span-' + comment.Id; span.setAttribute('ModifyCount', comment.ModifyCount ?? 0); span.style.display = (option[optionName] && comment.ModifyCount > 0) ? '' : 'none'; setTooltip(span, option?.getText('FLTL_01508', 'Hidden History')); const icon = createIcon('fa-light', 'wave-sine'); icon.style.height = '12px'; icon.style.width = '12px'; icon.style.margin = '0 5px 0 0'; icon.style.cursor = 'pointer'; icon.style.border = '1px solid'; icon.style.borderRadius = '6px'; icon.style.borderColor = '#000'; icon.style.display = 'block'; span.appendChild(icon); span.addEventListener('click', () => hisFunc(comment.Id)); }), createElement('span', span => { span.innerText = comment[commentTime]; }) ); }