diff --git a/umd/tinode.dev.js b/umd/tinode.dev.js
index 75d46670..3df38fe2 100644
--- a/umd/tinode.dev.js
+++ b/umd/tinode.dev.js
@@ -351,7 +351,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 +395,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 +662,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 +688,7 @@ function _init_lp2() {
throw new Error("Long poller failed to connect");
}
};
- this.isConnected = () => {
+ this.isConnected = _ => {
return _poller && true;
};
}
@@ -714,7 +712,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 +721,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 +743,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 +759,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 +857,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 +865,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 +893,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 +1297,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 +1347,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 +1615,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 || base64toDataUrl(data.val, data.mime),
+ '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 +1802,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 +1824,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 +1880,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 +1914,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 +2023,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 +2123,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 +2183,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) {
@@ -2135,6 +2229,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 +2286,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 +2307,9 @@ 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;
+ }
}
}
}
@@ -2236,7 +2352,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 +2611,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 +3261,24 @@ function _get_subs_ims2() {
* ...
*