parent
1004533b8d
commit
847a504f9a
|
@ -161,9 +161,9 @@ export class ApiUpdatesManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public processUpdateMessage = (updateMessage: any/* , options: Partial<{
|
public processUpdateMessage = (updateMessage: any, options: Partial<{
|
||||||
ignoreSyncLoading: boolean
|
override: boolean
|
||||||
}> = {} */) => {
|
}> = {}) => {
|
||||||
// return forceGetDifference()
|
// return forceGetDifference()
|
||||||
const processOpts = {
|
const processOpts = {
|
||||||
date: updateMessage.date,
|
date: updateMessage.date,
|
||||||
|
@ -215,8 +215,8 @@ export class ApiUpdatesManager {
|
||||||
|
|
||||||
case 'updatesCombined':
|
case 'updatesCombined':
|
||||||
case 'updates':
|
case 'updates':
|
||||||
appUsersManager.saveApiUsers(updateMessage.users);
|
appUsersManager.saveApiUsers(updateMessage.users, options.override);
|
||||||
appChatsManager.saveApiChats(updateMessage.chats);
|
appChatsManager.saveApiChats(updateMessage.chats, options.override);
|
||||||
|
|
||||||
updateMessage.updates.forEach((update: any) => {
|
updateMessage.updates.forEach((update: any) => {
|
||||||
this.processUpdate(update, processOpts);
|
this.processUpdate(update, processOpts);
|
||||||
|
@ -593,6 +593,7 @@ export class ApiUpdatesManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveUpdate(update: Update) {
|
public saveUpdate(update: Update) {
|
||||||
|
this.log('saveUpdate', update);
|
||||||
rootScope.dispatchEvent(update._, update as any);
|
rootScope.dispatchEvent(update._, update as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ export class AppDraftsManager {
|
||||||
|
|
||||||
const myEntities = RichTextProcessor.parseEntities(draft.message);
|
const myEntities = RichTextProcessor.parseEntities(draft.message);
|
||||||
const apiEntities = draft.entities || [];
|
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.rMessage = RichTextProcessor.wrapDraftText(draft.message, {entities: totalEntities});
|
||||||
//draft.rReply = appMessagesManager.getRichReplyText(draft);
|
//draft.rReply = appMessagesManager.getRichReplyText(draft);
|
||||||
|
|
|
@ -2394,7 +2394,7 @@ export class AppMessagesManager {
|
||||||
if(message.message && message.message.length && !message.totalEntities) {
|
if(message.message && message.message.length && !message.totalEntities) {
|
||||||
const myEntities = RichTextProcessor.parseEntities(message.message);
|
const myEntities = RichTextProcessor.parseEntities(message.message);
|
||||||
const apiEntities = message.entities || [];
|
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;
|
storage[mid] = message;
|
||||||
|
|
|
@ -66,6 +66,7 @@ export class AppUsersManager {
|
||||||
|
|
||||||
//user.sortStatus = this.getUserStatusForSort(user.status);
|
//user.sortStatus = this.getUserStatusForSort(user.status);
|
||||||
rootScope.broadcast('user_update', userId);
|
rootScope.broadcast('user_update', userId);
|
||||||
|
this.setUserToStateIfNeeded(user);
|
||||||
} //////else console.warn('No user by id:', userId);
|
} //////else console.warn('No user by id:', userId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -81,6 +82,8 @@ export class AppUsersManager {
|
||||||
user.photo = safeReplaceObject(user.photo, update.photo);
|
user.photo = safeReplaceObject(user.photo, update.photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setUserToStateIfNeeded(user);
|
||||||
|
|
||||||
rootScope.broadcast('user_update', userId);
|
rootScope.broadcast('user_update', userId);
|
||||||
rootScope.broadcast('avatar_update', userId);
|
rootScope.broadcast('avatar_update', userId);
|
||||||
} else console.warn('No user by id:', userId);
|
} else console.warn('No user by id:', userId);
|
||||||
|
@ -290,8 +293,8 @@ export class AppUsersManager {
|
||||||
return !!searchIndexManager.search(query, index)[user.id];
|
return !!searchIndexManager.search(query, index)[user.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveApiUsers(apiUsers: any[]) {
|
public saveApiUsers(apiUsers: any[], override?: boolean) {
|
||||||
apiUsers.forEach((user) => this.saveApiUser(user));
|
apiUsers.forEach((user) => this.saveApiUser(user, override));
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveApiUser(user: MTUser, override?: boolean) {
|
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);
|
const curIsContact = this.isContact(userId);
|
||||||
if(isContact !== curIsContact) {
|
if(isContact !== curIsContact) {
|
||||||
if(isContact) {
|
if(isContact) {
|
||||||
|
@ -817,7 +820,7 @@ export class AppUsersManager {
|
||||||
phone,
|
phone,
|
||||||
add_phone_privacy_exception: showPhone
|
add_phone_privacy_exception: showPhone
|
||||||
}).then((updates) => {
|
}).then((updates) => {
|
||||||
apiUpdatesManager.processUpdateMessage(updates);
|
apiUpdatesManager.processUpdateMessage(updates, {override: true});
|
||||||
|
|
||||||
this.onContactUpdated(userId, true);
|
this.onContactUpdated(userId, true);
|
||||||
});
|
});
|
||||||
|
@ -827,7 +830,7 @@ export class AppUsersManager {
|
||||||
return apiManager.invokeApi('contacts.deleteContacts', {
|
return apiManager.invokeApi('contacts.deleteContacts', {
|
||||||
id: userIds.map(userId => this.getUserInput(userId))
|
id: userIds.map(userId => this.getUserInput(userId))
|
||||||
}).then((updates) => {
|
}).then((updates) => {
|
||||||
apiUpdatesManager.processUpdateMessage(updates);
|
apiUpdatesManager.processUpdateMessage(updates, {override: true});
|
||||||
|
|
||||||
userIds.forEach(userId => {
|
userIds.forEach(userId => {
|
||||||
this.onContactUpdated(userId, false);
|
this.onContactUpdated(userId, false);
|
||||||
|
|
|
@ -232,6 +232,9 @@ namespace RichTextProcessor {
|
||||||
} */
|
} */
|
||||||
|
|
||||||
const entities: MessageEntity[] = [];
|
const entities: MessageEntity[] = [];
|
||||||
|
let pushedEntity = false;
|
||||||
|
const pushEntity = (entity: MessageEntity) => !findSameEntity(currentEntities, entity) ? (entities.push(entity), pushedEntity = true) : pushedEntity = false;
|
||||||
|
|
||||||
let raw = text;
|
let raw = text;
|
||||||
let match;
|
let match;
|
||||||
let newText: any = [];
|
let newText: any = [];
|
||||||
|
@ -239,64 +242,82 @@ namespace RichTextProcessor {
|
||||||
while(match = raw.match(markdownRegExp)) {
|
while(match = raw.match(markdownRegExp)) {
|
||||||
const matchIndex = rawOffset + match.index;
|
const matchIndex = rawOffset + match.index;
|
||||||
newText.push(raw.substr(0, 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;
|
rawOffset -= text.length;
|
||||||
//text = text.replace(/^\s+|\s+$/g, '');
|
//text = text.replace(/^\s+|\s+$/g, '');
|
||||||
rawOffset += text.length;
|
rawOffset += text.length;
|
||||||
|
|
||||||
|
let entity: MessageEntity;
|
||||||
|
pushedEntity = false;
|
||||||
if(text.match(/^`*$/)) {
|
if(text.match(/^`*$/)) {
|
||||||
newText.push(match[0]);
|
newText.push(match[0]);
|
||||||
} else if(match[3]) { // pre
|
} else if(match[3]) { // pre
|
||||||
if(match[5] === '\n') {
|
entity = {
|
||||||
match[5] = '';
|
|
||||||
rawOffset -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
newText.push(match[1] + text + match[5]);
|
|
||||||
entities.push({
|
|
||||||
_: 'messageEntityPre',
|
_: 'messageEntityPre',
|
||||||
language: '',
|
language: '',
|
||||||
offset: matchIndex + match[1].length,
|
offset: matchIndex + match[1].length,
|
||||||
length: text.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
|
} else if(match[7]) { // code|italic|bold
|
||||||
const isSOH = match[6] === '\x01';
|
const isSOH = match[6] === '\x01';
|
||||||
if(!isSOH) {
|
|
||||||
newText.push(match[6] + text + match[9]);
|
|
||||||
} else {
|
|
||||||
newText.push(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
entities.push({
|
entity = {
|
||||||
_: markdownEntities[match[7]],
|
_: markdownEntities[match[7]],
|
||||||
//offset: matchIndex + match[6].length,
|
//offset: matchIndex + match[6].length,
|
||||||
offset: matchIndex + (isSOH ? 0 : match[6].length),
|
offset: matchIndex + (isSOH ? 0 : match[6].length),
|
||||||
length: text.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
|
} else if(match[11]) { // custom mention
|
||||||
newText.push(text)
|
entity = {
|
||||||
entities.push({
|
|
||||||
_: 'messageEntityMentionName',
|
_: 'messageEntityMentionName',
|
||||||
user_id: +match[10],
|
user_id: +match[10],
|
||||||
offset: matchIndex,
|
offset: matchIndex,
|
||||||
length: text.length
|
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
|
} else if(match[12]) { // text url
|
||||||
newText.push(text);
|
entity = {
|
||||||
entities.push({
|
|
||||||
_: 'messageEntityTextUrl',
|
_: 'messageEntityTextUrl',
|
||||||
url: match[13],
|
url: match[14],
|
||||||
offset: matchIndex,
|
offset: matchIndex,
|
||||||
length: text.length
|
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);
|
raw = raw.substr(match.index + match[0].length);
|
||||||
|
@ -320,9 +341,19 @@ namespace RichTextProcessor {
|
||||||
return newText;
|
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[]) {
|
export function mergeEntities(currentEntities: MessageEntity[], newEntities: MessageEntity[]) {
|
||||||
currentEntities = currentEntities.slice();
|
const filtered = newEntities.filter(e => {
|
||||||
const filtered = newEntities.filter(e => !currentEntities.find(_e => e._ === _e._ && e.offset === _e.offset && e.length === _e.length));
|
return !findSameEntity(currentEntities, e);
|
||||||
|
});
|
||||||
|
|
||||||
currentEntities.push(...filtered);
|
currentEntities.push(...filtered);
|
||||||
currentEntities.sort((a, b) => a.offset - b.offset);
|
currentEntities.sort((a, b) => a.offset - b.offset);
|
||||||
return currentEntities;
|
return currentEntities;
|
||||||
|
|
Loading…
Reference in New Issue