From 45fbff1b4a1bd9db56907b5f5e9e580c78c1826e Mon Sep 17 00:00:00 2001 From: or-else Date: Thu, 5 Jan 2023 17:20:20 -0800 Subject: [PATCH] rebuilt with sdk fix: incorrect reference when replying to edited message --- umd/tinode.dev.js | 428 +++++++++++++++++++++++++++------------------ umd/tinode.prod.js | 2 +- 2 files changed, 254 insertions(+), 176 deletions(-) diff --git a/umd/tinode.dev.js b/umd/tinode.dev.js index 75d46670..4d270687 100644 --- a/umd/tinode.dev.js +++ b/umd/tinode.dev.js @@ -303,6 +303,9 @@ class CBuffer { } this.buffer.splice(count); } + isEmpty() { + return this.buffer.length == 0; + } } exports.default = CBuffer; function _findNearest2(elem, arr, exact) { @@ -351,7 +354,7 @@ function _insertSorted2(elem, arr) { Object.defineProperty(exports, "__esModule", { value: true }); -exports.VERSION = exports.USER_NEW = exports.TOPIC_SYS = exports.TOPIC_P2P = exports.TOPIC_NEW_CHAN = exports.TOPIC_NEW = exports.TOPIC_ME = exports.TOPIC_GRP = exports.TOPIC_FND = exports.TOPIC_CHAN = exports.RECV_TIMEOUT = exports.PROTOCOL_VERSION = exports.MESSAGE_STATUS_TO_ME = exports.MESSAGE_STATUS_SENT = exports.MESSAGE_STATUS_SENDING = exports.MESSAGE_STATUS_RECEIVED = exports.MESSAGE_STATUS_READ = exports.MESSAGE_STATUS_QUEUED = exports.MESSAGE_STATUS_NONE = exports.MESSAGE_STATUS_FAILED = exports.MESSAGE_STATUS_DEL_RANGE = exports.LOCAL_SEQID = exports.LIBRARY = exports.EXPIRE_PROMISES_TIMEOUT = exports.EXPIRE_PROMISES_PERIOD = exports.DEL_CHAR = exports.DEFAULT_MESSAGES_PAGE = void 0; +exports.VERSION = exports.USER_NEW = exports.TOPIC_SYS = exports.TOPIC_P2P = exports.TOPIC_NEW_CHAN = exports.TOPIC_NEW = exports.TOPIC_ME = exports.TOPIC_GRP = exports.TOPIC_FND = exports.TOPIC_CHAN = exports.RECV_TIMEOUT = exports.PROTOCOL_VERSION = exports.MESSAGE_STATUS_TO_ME = exports.MESSAGE_STATUS_SENT = exports.MESSAGE_STATUS_SENDING = exports.MESSAGE_STATUS_RECEIVED = exports.MESSAGE_STATUS_READ = exports.MESSAGE_STATUS_QUEUED = exports.MESSAGE_STATUS_NONE = exports.MESSAGE_STATUS_FAILED = exports.LOCAL_SEQID = exports.LIBRARY = exports.EXPIRE_PROMISES_TIMEOUT = exports.EXPIRE_PROMISES_PERIOD = exports.DEL_CHAR = exports.DEFAULT_MESSAGES_PAGE = void 0; var _version = require("../version.json"); const PROTOCOL_VERSION = '0'; exports.PROTOCOL_VERSION = PROTOCOL_VERSION; @@ -395,8 +398,6 @@ const MESSAGE_STATUS_READ = 6; exports.MESSAGE_STATUS_READ = MESSAGE_STATUS_READ; const MESSAGE_STATUS_TO_ME = 7; exports.MESSAGE_STATUS_TO_ME = MESSAGE_STATUS_TO_ME; -const MESSAGE_STATUS_DEL_RANGE = 8; -exports.MESSAGE_STATUS_DEL_RANGE = MESSAGE_STATUS_DEL_RANGE; const EXPIRE_PROMISES_TIMEOUT = 5000; exports.EXPIRE_PROMISES_TIMEOUT = EXPIRE_PROMISES_TIMEOUT; const EXPIRE_PROMISES_PERIOD = 1000; @@ -664,7 +665,7 @@ function _init_lp2() { _classPrivateMethodGet(this, _boffStop, _boffStop2).call(this); this.connect(null, force); }; - this.disconnect = () => { + this.disconnect = _ => { _classPrivateFieldSet(this, _boffClosed, true); _classPrivateMethodGet(this, _boffStop, _boffStop2).call(this); if (_sender) { @@ -690,7 +691,7 @@ function _init_lp2() { throw new Error("Long poller failed to connect"); } }; - this.isConnected = () => { + this.isConnected = _ => { return _poller && true; }; } @@ -714,7 +715,7 @@ function _init_ws2() { conn.onerror = err => { reject(err); }; - conn.onopen = evt => { + conn.onopen = _ => { if (this.autoreconnect) { _classPrivateMethodGet(this, _boffStop, _boffStop2).call(this); } @@ -723,7 +724,7 @@ function _init_ws2() { } resolve(); }; - conn.onclose = evt => { + conn.onclose = _ => { _classPrivateFieldSet(this, _socket, null); if (this.onDisconnect) { const code = _classPrivateFieldGet(this, _boffClosed) ? NETWORK_USER : NETWORK_ERROR; @@ -745,7 +746,7 @@ function _init_ws2() { _classPrivateMethodGet(this, _boffStop, _boffStop2).call(this); this.connect(null, force); }; - this.disconnect = () => { + this.disconnect = _ => { _classPrivateFieldSet(this, _boffClosed, true); _classPrivateMethodGet(this, _boffStop, _boffStop2).call(this); if (!_classPrivateFieldGet(this, _socket)) { @@ -761,7 +762,7 @@ function _init_ws2() { throw new Error("Websocket is not connected"); } }; - this.isConnected = () => { + this.isConnected = _ => { return _classPrivateFieldGet(this, _socket) && _classPrivateFieldGet(this, _socket).readyState == _classPrivateFieldGet(this, _socket).OPEN; }; } @@ -859,7 +860,7 @@ class DB { } return new Promise((resolve, reject) => { const req = IDBProvider.deleteDatabase(DB_NAME); - req.onblocked = event => { + req.onblocked = _ => { if (this.db) { this.db.close(); } @@ -867,7 +868,7 @@ class DB { _classPrivateFieldGet(this, _logger).call(this, 'PCache', 'deleteDatabase', err); reject(err); }; - req.onsuccess = event => { + req.onsuccess = _ => { this.db = null; this.disabled = true; resolve(true); @@ -895,7 +896,7 @@ class DB { reject(event.target.error); }; const req = trx.objectStore('topic').get(topic.name); - req.onsuccess = event => { + req.onsuccess = _ => { trx.objectStore('topic').put(_classStaticPrivateMethodGet(DB, DB, _serializeTopic).call(DB, req.result, topic)); trx.commit(); }; @@ -1299,7 +1300,7 @@ const MAX_PREVIEW_ATTACHMENTS = 3; const MAX_PREVIEW_DATA_SIZE = 64; const JSON_MIME_TYPE = 'application/json'; const DRAFTY_MIME_TYPE = 'text/x-drafty'; -const ALLOWED_ENT_FIELDS = ['act', 'height', 'duration', 'incoming', 'mime', 'name', 'preview', 'ref', 'size', 'state', 'url', 'val', 'width']; +const ALLOWED_ENT_FIELDS = ['act', 'height', 'duration', 'incoming', 'mime', 'name', 'premime', 'preref', 'preview', 'ref', 'size', 'state', 'url', 'val', 'width']; const INLINE_STYLES = [{ name: 'ST', start: /(?:^|[\W_])(\*)[^\s*]/, @@ -1349,77 +1350,100 @@ const ENTITY_TYPES = [{ }, re: /\B#([\p{L}\p{N}][._\p{L}\p{N}]*[\p{L}\p{N}])/ug }]; -const HTML_TAGS = { +const FORMAT_TAGS = { AU: { - name: 'audio', + html_tag: 'audio', + md_tag: undefined, isVoid: false }, BN: { - name: 'button', + html_tag: 'button', + md_tag: undefined, isVoid: false }, BR: { - name: 'br', + html_tag: 'br', + md_tag: '\n', isVoid: true }, CO: { - name: 'tt', + html_tag: 'tt', + md_tag: '`', isVoid: false }, DL: { - name: 'del', + html_tag: 'del', + md_tag: '~', isVoid: false }, EM: { - name: 'i', + html_tag: 'i', + md_tag: '_', isVoid: false }, EX: { - name: '', + html_tag: '', + md_tag: undefined, isVoid: true }, FM: { - name: 'div', + html_tag: 'div', + md_tag: undefined, isVoid: false }, HD: { - name: '', + html_tag: '', + md_tag: undefined, isVoid: false }, HL: { - name: 'span', + html_tag: 'span', + md_tag: undefined, isVoid: false }, HT: { - name: 'a', + html_tag: 'a', + md_tag: undefined, isVoid: false }, IM: { - name: 'img', + html_tag: 'img', + md_tag: undefined, isVoid: false }, LN: { - name: 'a', + html_tag: 'a', + md_tag: undefined, isVoid: false }, MN: { - name: 'a', + html_tag: 'a', + md_tag: undefined, isVoid: false }, RW: { - name: 'div', + html_tag: 'div', + md_tag: undefined, isVoid: false }, QQ: { - name: 'div', + html_tag: 'div', + md_tag: undefined, isVoid: false }, ST: { - name: 'b', + html_tag: 'b', + md_tag: '*', isVoid: false }, VC: { - name: 'div', + html_tag: 'div', + md_tag: undefined, + isVoid: false + }, + VD: { + html_tag: 'video', + md_tag: undefined, isVoid: false } }; @@ -1594,6 +1618,29 @@ const DECORATORS = { 'data-state': data.state }; } + }, + VD: { + open: data => { + const tmpPreviewUrl = base64toDataUrl(data._tempPreview, data.mime); + const previewUrl = data.ref || base64toObjectUrl(data.preview, data.premime || 'image/json', Drafty.logger); + return ''; + }, + close: _ => '', + props: data => { + if (!data) return null; + return { + src: data.preref || base64toObjectUrl(data.preview, data.premime || 'image/json', Drafty.logger), + 'data-src': data.ref || base64toObjectUrl(data.val, data.mime, Drafty.logger), + 'data-width': data.width, + 'data-height': data.height, + 'data-preload': data.ref ? 'metadata' : 'auto', + 'data-preview': base64toObjectUrl(data.preview, data.premime || 'image/json', Drafty.logger), + 'data-duration': data.duration | 0, + 'data-name': data.name, + 'data-size': data.val ? data.val.length * 0.75 | 0 : data.size | 0, + 'data-mime': data.mime + }; + } } }; const Drafty = function () { @@ -1758,12 +1805,12 @@ Drafty.insertImage = function (content, at, imageDesc) { tp: 'IM', data: { mime: imageDesc.mime, - val: imageDesc.preview, + ref: imageDesc.refurl, + val: imageDesc.bits || imageDesc.preview, width: imageDesc.width, height: imageDesc.height, name: imageDesc.filename, - size: imageDesc.size | 0, - ref: imageDesc.refurl + size: imageDesc.size | 0 } }; if (imageDesc.urlPromise) { @@ -1780,6 +1827,47 @@ Drafty.insertImage = function (content, at, imageDesc) { content.ent.push(ex); return content; }; +Drafty.insertVideo = function (content, at, videoDesc) { + content = content || { + txt: ' ' + }; + content.ent = content.ent || []; + content.fmt = content.fmt || []; + content.fmt.push({ + at: at | 0, + len: 1, + key: content.ent.length + }); + const ex = { + tp: 'VD', + data: { + mime: videoDesc.mime, + ref: videoDesc.refurl, + val: videoDesc.bits, + preref: videoDesc.preref, + preview: videoDesc.preview, + width: videoDesc.width, + height: videoDesc.height, + duration: videoDesc.duration | 0, + name: videoDesc.filename, + size: videoDesc.size | 0 + } + }; + if (videoDesc.urlPromise) { + ex.data._tempPreview = videoDesc._tempPreview; + ex.data._processing = true; + videoDesc.urlPromise.then(urls => { + ex.data.ref = urls[0]; + ex.data.preref = urls[1]; + ex.data._tempPreview = undefined; + ex.data._processing = undefined; + }, _ => { + ex.data._processing = undefined; + }); + } + content.ent.push(ex); + return content; +}; Drafty.insertAudio = function (content, at, audioDesc) { content = content || { txt: ' ' @@ -1795,7 +1883,7 @@ Drafty.insertAudio = function (content, at, audioDesc) { tp: 'AU', data: { mime: audioDesc.mime, - val: audioDesc.data, + val: audioDesc.bits, duration: audioDesc.duration | 0, preview: audioDesc.preview, name: audioDesc.filename, @@ -1829,7 +1917,7 @@ Drafty.videoCall = function () { }; return content; }; -Drafty.updateVideoEnt = function (content, params) { +Drafty.updateVideoCall = function (content, params) { const fmt = ((content || {}).fmt || [])[0]; if (!fmt) { return content; @@ -1938,7 +2026,7 @@ Drafty.attachFile = function (content, attachmentDesc) { attachmentDesc.urlPromise.then(url => { ex.data.ref = url; ex.data._processing = undefined; - }, err => { + }, _ => { ex.data._processing = undefined; }); } @@ -2038,7 +2126,7 @@ Drafty.appendLineBreak = function (content) { return content; }; Drafty.UNSAFE_toHTML = function (doc) { - let tree = draftyToTree(doc); + const tree = draftyToTree(doc); const htmlFormatter = function (type, data, values) { const tag = DECORATORS[type]; let result = values ? values.join('') : ''; @@ -2098,7 +2186,16 @@ Drafty.replyContent = function (original, limit) { tree = treeTopDown(tree, convMNnQQnBR); tree = attachmentsToEnd(tree, MAX_PREVIEW_ATTACHMENTS); tree = shortenTree(tree, limit, '…'); - tree = lightEntity(tree, node => node.type == 'IM' ? ['val'] : null); + const filter = node => { + switch (node.type) { + case 'IM': + return ['val']; + case 'VD': + return ['preview']; + } + return null; + }; + tree = lightEntity(tree, filter); return treeToDrafty({}, tree, []); }; Drafty.preview = function (original, limit, forwarding) { @@ -2123,7 +2220,13 @@ Drafty.preview = function (original, limit, forwarding) { tree = treeTopDown(tree, convMNnQQnBR); tree = shortenTree(tree, limit, '…'); if (forwarding) { - tree = lightEntity(tree, node => node.type == 'IM' ? ['val'] : null); + const filter = { + IM: ['val'], + VD: ['preview'] + }; + tree = lightEntity(tree, node => { + return filter[node.type]; + }); } else { tree = lightEntity(tree); } @@ -2135,6 +2238,22 @@ Drafty.toPlainText = function (content) { Drafty.isPlainText = function (content) { return typeof content == 'string' || !(content.fmt || content.ent); }; +Drafty.toMarkdown = function (content) { + let tree = draftyToTree(content); + const mdFormatter = function (type, _, values) { + const def = FORMAT_TAGS[type]; + let result = values ? values.join('') : ''; + if (def) { + if (def.isVoid) { + result = def.md_tag || ''; + } else if (def.md_tag) { + result = def.md_tag + result + def.md_tag; + } + } + return result; + }; + return treeBottomUp(tree, mdFormatter, 0); +}; Drafty.isValid = function (content) { if (!content) { return false; @@ -2176,15 +2295,19 @@ Drafty.attachments = function (content, callback, context) { if (!Array.isArray(content.fmt)) { return; } - let i = 0; - content.fmt.forEach(fmt => { + let count = 0; + for (let i in content.ent) { + let fmt = content.fmt[i]; if (fmt && fmt.at < 0) { const ent = content.ent[fmt.key | 0]; if (ent && ent.tp == 'EX' && ent.data) { - callback.call(context, ent.data, i++, 'EX'); + if (callback.call(context, ent.data, count++, 'EX')) { + break; + } } } - }); + } + ; }; Drafty.hasEntities = function (content) { return content.ent && content.ent.length > 0; @@ -2193,7 +2316,21 @@ Drafty.entities = function (content, callback, context) { if (content.ent && content.ent.length > 0) { for (let i in content.ent) { if (content.ent[i]) { - callback.call(context, content.ent[i].data, i, content.ent[i].tp); + if (callback.call(context, content.ent[i].data, i, content.ent[i].tp)) { + break; + } + } + } + } +}; +Drafty.styles = function (content, callback, context) { + if (content.fmt && content.fmt.length > 0) { + for (let i in content.fmt) { + const fmt = content.fmt[i]; + if (fmt) { + if (callback.call(context, fmt.tp, fmt.at, fmt.len, fmt.key, i)) { + break; + } } } } @@ -2236,7 +2373,7 @@ Drafty.getEntityMimeType = function (entData) { return entData.mime || 'text/plain'; }; Drafty.tagName = function (style) { - return HTML_TAGS[style] && HTML_TAGS[style].name; + return FORMAT_TAGS[style] && FORMAT_TAGS[style].html_tag; }; Drafty.attrValue = function (style, data) { if (data && DECORATORS[style]) { @@ -2495,7 +2632,7 @@ function spansToTree(parent, text, start, end, spans) { break; } else if (inner.start < span.end) { if (inner.end <= span.end) { - const tag = HTML_TAGS[inner.tp] || {}; + const tag = FORMAT_TAGS[inner.tp] || {}; if (inner.start < inner.end || tag.isVoid) { subspans.push(inner); } @@ -3145,24 +3282,24 @@ function _get_subs_ims2() { * ... *