From 6dadc087fdf08cc3fa119e6510510b3ae9e2b9d8 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Thu, 29 Apr 2021 20:05:42 +0400 Subject: [PATCH] Fix contact update Fix markdown --- src/lib/appManagers/apiUpdatesManager.ts | 11 +-- src/lib/appManagers/appDraftsManager.ts | 2 +- src/lib/appManagers/appMessagesManager.ts | 2 +- src/lib/appManagers/appUsersManager.ts | 13 ++-- src/lib/richtextprocessor.ts | 91 +++++++++++++++-------- 5 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/lib/appManagers/apiUpdatesManager.ts b/src/lib/appManagers/apiUpdatesManager.ts index 57bc290d..64194320 100644 --- a/src/lib/appManagers/apiUpdatesManager.ts +++ b/src/lib/appManagers/apiUpdatesManager.ts @@ -161,9 +161,9 @@ export class ApiUpdatesManager { } } - public processUpdateMessage = (updateMessage: any/* , options: Partial<{ - ignoreSyncLoading: boolean - }> = {} */) => { + public processUpdateMessage = (updateMessage: any, options: Partial<{ + override: boolean + }> = {}) => { // return forceGetDifference() const processOpts = { date: updateMessage.date, @@ -215,8 +215,8 @@ export class ApiUpdatesManager { case 'updatesCombined': case 'updates': - appUsersManager.saveApiUsers(updateMessage.users); - appChatsManager.saveApiChats(updateMessage.chats); + appUsersManager.saveApiUsers(updateMessage.users, options.override); + appChatsManager.saveApiChats(updateMessage.chats, options.override); updateMessage.updates.forEach((update: any) => { this.processUpdate(update, processOpts); @@ -593,6 +593,7 @@ export class ApiUpdatesManager { } public saveUpdate(update: Update) { + this.log('saveUpdate', update); rootScope.dispatchEvent(update._, update as any); } diff --git a/src/lib/appManagers/appDraftsManager.ts b/src/lib/appManagers/appDraftsManager.ts index 6c0d1f3e..495ab49a 100644 --- a/src/lib/appManagers/appDraftsManager.ts +++ b/src/lib/appManagers/appDraftsManager.ts @@ -169,7 +169,7 @@ export class AppDraftsManager { const myEntities = RichTextProcessor.parseEntities(draft.message); const apiEntities = draft.entities || []; - const totalEntities = RichTextProcessor.mergeEntities(apiEntities, myEntities); // ! only in this order, otherwise bold and emoji formatting won't work + const totalEntities = RichTextProcessor.mergeEntities(apiEntities.slice(), myEntities); // ! only in this order, otherwise bold and emoji formatting won't work draft.rMessage = RichTextProcessor.wrapDraftText(draft.message, {entities: totalEntities}); //draft.rReply = appMessagesManager.getRichReplyText(draft); diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index 388e500d..1dbbb027 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -2394,7 +2394,7 @@ export class AppMessagesManager { if(message.message && message.message.length && !message.totalEntities) { const myEntities = RichTextProcessor.parseEntities(message.message); const apiEntities = message.entities || []; - message.totalEntities = RichTextProcessor.mergeEntities(apiEntities, myEntities); // ! only in this order, otherwise bold and emoji formatting won't work + message.totalEntities = RichTextProcessor.mergeEntities(apiEntities.slice(), myEntities); // ! only in this order, otherwise bold and emoji formatting won't work } storage[mid] = message; diff --git a/src/lib/appManagers/appUsersManager.ts b/src/lib/appManagers/appUsersManager.ts index 7f76887d..0f0c1151 100644 --- a/src/lib/appManagers/appUsersManager.ts +++ b/src/lib/appManagers/appUsersManager.ts @@ -66,6 +66,7 @@ export class AppUsersManager { //user.sortStatus = this.getUserStatusForSort(user.status); rootScope.broadcast('user_update', userId); + this.setUserToStateIfNeeded(user); } //////else console.warn('No user by id:', userId); }, @@ -81,6 +82,8 @@ export class AppUsersManager { user.photo = safeReplaceObject(user.photo, update.photo); } + this.setUserToStateIfNeeded(user); + rootScope.broadcast('user_update', userId); rootScope.broadcast('avatar_update', userId); } else console.warn('No user by id:', userId); @@ -290,8 +293,8 @@ export class AppUsersManager { return !!searchIndexManager.search(query, index)[user.id]; } - public saveApiUsers(apiUsers: any[]) { - apiUsers.forEach((user) => this.saveApiUser(user)); + public saveApiUsers(apiUsers: any[], override?: boolean) { + apiUsers.forEach((user) => this.saveApiUser(user, override)); } public saveApiUser(user: MTUser, override?: boolean) { @@ -765,7 +768,7 @@ export class AppUsersManager { }); } - public onContactUpdated(userId: number, isContact: boolean) { + private onContactUpdated(userId: number, isContact: boolean) { const curIsContact = this.isContact(userId); if(isContact !== curIsContact) { if(isContact) { @@ -817,7 +820,7 @@ export class AppUsersManager { phone, add_phone_privacy_exception: showPhone }).then((updates) => { - apiUpdatesManager.processUpdateMessage(updates); + apiUpdatesManager.processUpdateMessage(updates, {override: true}); this.onContactUpdated(userId, true); }); @@ -827,7 +830,7 @@ export class AppUsersManager { return apiManager.invokeApi('contacts.deleteContacts', { id: userIds.map(userId => this.getUserInput(userId)) }).then((updates) => { - apiUpdatesManager.processUpdateMessage(updates); + apiUpdatesManager.processUpdateMessage(updates, {override: true}); userIds.forEach(userId => { this.onContactUpdated(userId, false); diff --git a/src/lib/richtextprocessor.ts b/src/lib/richtextprocessor.ts index e65f862e..896b34d5 100644 --- a/src/lib/richtextprocessor.ts +++ b/src/lib/richtextprocessor.ts @@ -232,6 +232,9 @@ namespace RichTextProcessor { } */ const entities: MessageEntity[] = []; + let pushedEntity = false; + const pushEntity = (entity: MessageEntity) => !findSameEntity(currentEntities, entity) ? (entities.push(entity), pushedEntity = true) : pushedEntity = false; + let raw = text; let match; let newText: any = []; @@ -239,64 +242,82 @@ namespace RichTextProcessor { while(match = raw.match(markdownRegExp)) { const matchIndex = rawOffset + match.index; newText.push(raw.substr(0, match.index)); - let text = (match[3] || match[8] || match[11] || match[14]); + let text = (match[3] || match[8] || match[11] || match[13]); rawOffset -= text.length; //text = text.replace(/^\s+|\s+$/g, ''); rawOffset += text.length; + let entity: MessageEntity; + pushedEntity = false; if(text.match(/^`*$/)) { newText.push(match[0]); } else if(match[3]) { // pre - if(match[5] === '\n') { - match[5] = ''; - rawOffset -= 1; - } - - newText.push(match[1] + text + match[5]); - entities.push({ + entity = { _: 'messageEntityPre', language: '', offset: matchIndex + match[1].length, length: text.length - }); + }; - rawOffset -= match[2].length + match[4].length; + if(pushEntity(entity)) { + if(match[5] === '\n') { + match[5] = ''; + rawOffset -= 1; + } + + newText.push(match[1] + text + match[5]); + + rawOffset -= match[2].length + match[4].length; + } } else if(match[7]) { // code|italic|bold const isSOH = match[6] === '\x01'; - if(!isSOH) { - newText.push(match[6] + text + match[9]); - } else { - newText.push(text); - } - entities.push({ + entity = { _: markdownEntities[match[7]], //offset: matchIndex + match[6].length, offset: matchIndex + (isSOH ? 0 : match[6].length), length: text.length - }); + }; - rawOffset -= match[7].length * 2 + (isSOH ? 2 : 0); + if(pushEntity(entity)) { + if(!isSOH) { + newText.push(match[6] + text + match[9]); + } else { + newText.push(text); + } + + rawOffset -= match[7].length * 2 + (isSOH ? 2 : 0); + } } else if(match[11]) { // custom mention - newText.push(text) - entities.push({ + entity = { _: 'messageEntityMentionName', user_id: +match[10], offset: matchIndex, length: text.length - }); - - rawOffset -= match[0].length - text.length; + }; + + if(pushEntity(entity)) { + newText.push(text); + + rawOffset -= match[0].length - text.length; + } } else if(match[12]) { // text url - newText.push(text); - entities.push({ + entity = { _: 'messageEntityTextUrl', - url: match[13], + url: match[14], offset: matchIndex, length: text.length - }); + }; + + if(pushEntity(entity)) { + newText.push(text); - rawOffset -= match[12].length - text.length; + rawOffset -= match[12].length - text.length; + } + } + + if(!pushedEntity) { + newText.push(match[0]); } raw = raw.substr(match.index + match[0].length); @@ -320,9 +341,19 @@ namespace RichTextProcessor { return newText; } + export function findSameEntity(currentEntities: MessageEntity[], newEntity: MessageEntity) { + return currentEntities.find(currentEntity => { + return newEntity._ === currentEntity._ && + newEntity.offset >= currentEntity.offset && + (newEntity.length + newEntity.offset) <= (currentEntity.length + currentEntity.offset); + }); + } + export function mergeEntities(currentEntities: MessageEntity[], newEntities: MessageEntity[]) { - currentEntities = currentEntities.slice(); - const filtered = newEntities.filter(e => !currentEntities.find(_e => e._ === _e._ && e.offset === _e.offset && e.length === _e.length)); + const filtered = newEntities.filter(e => { + return !findSameEntity(currentEntities, e); + }); + currentEntities.push(...filtered); currentEntities.sort((a, b) => a.offset - b.offset); return currentEntities;