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('P_WO_ERROR', 'Error'), r('P_CU_TYPENOTSUPPORTED', 'File type "{type}" is now not supported.').replace('{type}', type)); return; } const isImage = /^image\//.test(type); if (!isImage && file.size > MaxAttachmentSize.limit) { showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS', `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]; } } const SymbolDropdown = Symbol.for('ui-dropdown'); class DropdownColumn { static create(col, trigger, parent) { const drop = new Dropdown({ ...col.dropOptions, parent }); drop.onselected = trigger; return drop.create(); } static _getDrop(element) { const dropGlobal = global[SymbolDropdown]; if (dropGlobal == null) { return null; } const dropId = element.dataset.dropId; const drop = dropGlobal[dropId]; if (drop == null) { return null; } return drop; } static _setValue(source, element, val) { const data = source?.find(v => v.value === val); if (data != null) { val = data.text; } super.setValue(element, val); } static setValue(element, val, _item, col) { if (element.tagName !== 'DIV') { this._setValue(col.source, element, val); return; } const drop = this._getDrop(element); if (drop == null) { return; } if (drop.source == null || drop.source.length === 0) { let source = col.source; if (source != null) { drop.source = source; } } drop.select(val, true); } static getValue(e) { return e.value; } } export function getMessageStatus(comm, r, _var) { const messageStatus = { 0: r('P_CU_PENDING', 'Pending'), 1: r('P_WO_SENT', 'Sent'), 5: r('P_CU_DELIVERYCONFIRMED', 'Delivery Confirmed'), 6: r('P_CU_RESENT', 'Resent'), 9: r('P_MA_FAILED', 'Failed'), 9999: r('P_CU_UNKNOWN', '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('P_CU_UPDATESTATUS', '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('P_CU_UPDATESTATUS', 'Update Status'), content: createElement('div', wrapper => { wrapper.className = 'update-status-wrapper'; wrapper.style.width = '500px'; }, gridContainer ), buttons: [ { text: r('P_WO_OK', '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('P_WO_CANCEL', 'Cancel'), key: 'cancel' } ] }); await popup.show(); const grid = new Grid(gridContainer); // grid.headerVisible = false; grid.allowHtml = true; grid.columns = [ { key: 'CustomerNumber', caption: r('P_JS_NUMBER', 'Number'), width: 150 }, /*{ key: 'customerName', caption: r('P_WOS_CUSTOMERNAME', 'Customer Name'), width: 120 },*/ { key: 'statusText', caption: r('P_CU_CURRENTSTATUS', 'Current Status'), width: 155 }, { key: 'statusChanged', caption: r('P_CU_REVISEDSTATUS', 'Revised Status'), width: 155, type: DropdownColumn, 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('P_CU_SENDTO_COLON', '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; } } } } }