Fix links tab in shared media
Minor improvements
This commit is contained in:
parent
e76942d0bb
commit
9948bab8b0
@ -8,6 +8,7 @@ import appUsersManager from "../../lib/appManagers/appUsersManager";
|
||||
import { logger, LogLevels } from "../../lib/logger";
|
||||
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
||||
import $rootScope from "../../lib/rootScope";
|
||||
import { getAbbreviation, limitSymbols } from "../../lib/utils";
|
||||
import AvatarElement from "../avatar";
|
||||
import { horizontalMenu } from "../horizontalMenu";
|
||||
import LazyLoadQueue from "../lazyLoadQueue";
|
||||
@ -108,7 +109,7 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
private loadMutex: Promise<any> = Promise.resolve();
|
||||
|
||||
private log = logger('SM', LogLevels.error);
|
||||
private log = logger('SM'/* , LogLevels.error */);
|
||||
|
||||
public init() {
|
||||
this.container = document.getElementById('shared-media-container');
|
||||
@ -226,11 +227,16 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
container.style.paddingRight = '0';
|
||||
};
|
||||
|
||||
public filterMessagesByType(ids: number[], type: string) {
|
||||
public filterMessagesByType(ids: number[], type: SharedMediaType) {
|
||||
let messages: any[] = [];
|
||||
for(let mid of ids) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
if(message.media) messages.push(message);
|
||||
|
||||
if(type != 'inputMessagesFilterUrl') {
|
||||
for(let mid of ids) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
if(message.media) messages.push(message);
|
||||
}
|
||||
} else {
|
||||
messages = ids.slice().map(mid => appMessagesManager.getMessage(mid));
|
||||
}
|
||||
|
||||
let filtered: any[] = [];
|
||||
@ -257,7 +263,7 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
case 'inputMessagesFilterDocument': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.document || message.media.document.type == 'voice' || message.media.document.type == 'audio') {
|
||||
if(!message.media.document || ['voice', 'audio', 'gif'].includes(message.media.document.type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -274,12 +280,11 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
this.log('inputMessagesFilterUrl', messages);
|
||||
for(let message of messages) {
|
||||
if(!message.media.webpage || message.media.webpage._ == 'webPageEmpty') {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
//if((message.media.webpage && message.media.webpage._ != 'webPageEmpty')) {
|
||||
filtered.push(message);
|
||||
//}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -443,15 +448,63 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
sharedMediaDiv = this.sharedMedia.contentLinks;
|
||||
|
||||
for(let message of messages) {
|
||||
let webpage = message.media.webpage;
|
||||
let webpage: any;
|
||||
|
||||
if(message.media?.webpage && message.media.webpage._ != 'webPageEmpty') {
|
||||
webpage = message.media.webpage;
|
||||
} else {
|
||||
const entity = message.totalEntities.find((e: any) => e._ == 'messageEntityUrl' || e._ == 'messageEntityTextUrl');
|
||||
let url: string, display_url: string, sliced: string;
|
||||
|
||||
if(!entity) {
|
||||
this.log.error('NO ENTITY:', message);
|
||||
const match = RichTextProcessor.matchUrl(message.message);
|
||||
if(!match) {
|
||||
this.log.error('NO ENTITY AND NO MATCH:', message);
|
||||
}
|
||||
|
||||
url = match[0];
|
||||
} else {
|
||||
sliced = message.message.slice(entity.offset, entity.offset + entity.length);
|
||||
}
|
||||
|
||||
if(entity?._ == 'messageEntityTextUrl') {
|
||||
url = entity.url;
|
||||
//display_url = sliced;
|
||||
} else {
|
||||
url = url || sliced;
|
||||
}
|
||||
|
||||
display_url = url;
|
||||
|
||||
const same = message.message == url;
|
||||
if(!url.match(/^(ftp|http|https):\/\//)) {
|
||||
display_url = 'https://' + url;
|
||||
url = url.includes('@') ? url : 'https://' + url;
|
||||
}
|
||||
|
||||
display_url = new URL(display_url).hostname;
|
||||
|
||||
webpage = {
|
||||
url,
|
||||
display_url
|
||||
};
|
||||
|
||||
if(!same) {
|
||||
webpage.description = message.message;
|
||||
webpage.rDescription = RichTextProcessor.wrapRichText(limitSymbols(message.message, 150, 180));
|
||||
}
|
||||
}
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.dataset.mid = '' + message.mid;
|
||||
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview');
|
||||
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
previewDiv.innerText = (webpage.title || webpage.description || webpage.url || webpage.display_url).slice(0, 1);
|
||||
previewDiv.innerHTML = getAbbreviation(webpage.title || webpage.display_url || webpage.description || webpage.url, true);
|
||||
previewDiv.classList.add('empty');
|
||||
if(webpage.photo) {
|
||||
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 60, 60))
|
||||
@ -476,7 +529,11 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
if(!title) {
|
||||
//title = new URL(webpage.url).hostname;
|
||||
title = webpage.display_url.split('/', 1)[0];
|
||||
title = RichTextProcessor.wrapPlainText(webpage.display_url.split('/', 1)[0]);
|
||||
}
|
||||
|
||||
if(webpage.description?.includes('Еще в начале')) {
|
||||
this.log.error('FROM THE START', webpage);
|
||||
}
|
||||
|
||||
div.append(previewDiv);
|
||||
@ -566,6 +623,8 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
const history = historyStorage[type] ?? (historyStorage[type] = []);
|
||||
|
||||
const logStr = `loadSidebarMedia [${type}]: `;
|
||||
|
||||
// render from cache
|
||||
if(history.length && this.usedFromHistory[type] < history.length) {
|
||||
let messages: any[] = [];
|
||||
@ -573,7 +632,7 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
|
||||
do {
|
||||
let ids = history.slice(used, used + loadCount);
|
||||
this.log('loadSidebarMedia: will render from cache', used, history, ids, loadCount);
|
||||
this.log(logStr + 'will render from cache', used, history, ids, loadCount);
|
||||
used += ids.length;
|
||||
|
||||
messages.push(...this.filterMessagesByType(ids, type));
|
||||
@ -597,19 +656,14 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
// заливать новую картинку сюда только после полной отправки!
|
||||
let maxID = history[history.length - 1] || 0;
|
||||
|
||||
let ids = !maxID && appMessagesManager.historiesStorage[peerID]
|
||||
? appMessagesManager.historiesStorage[peerID].history.slice() : [];
|
||||
|
||||
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
|
||||
this.log('loadSidebarMedia: search house of glass pre', type, ids, maxID);
|
||||
this.log(logStr + 'search house of glass pre', type, maxID);
|
||||
|
||||
//let loadCount = history.length ? 50 : 15;
|
||||
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, loadCount)
|
||||
.then(value => {
|
||||
ids = ids.concat(value.history);
|
||||
history.push(...ids);
|
||||
history.push(...value.history);
|
||||
|
||||
this.log('loadSidebarMedia: search house of glass', type, value, ids);
|
||||
this.log(logStr + 'search house of glass', type, value);
|
||||
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
@ -617,22 +671,25 @@ export default class AppSharedMediaTab implements SliderTab {
|
||||
}
|
||||
|
||||
if(value.history.length < loadCount) {
|
||||
this.log(logStr + 'loaded all media', value, loadCount);
|
||||
this.loadedAllMedia[type] = true;
|
||||
}
|
||||
|
||||
this.usedFromHistory[type] = history.length;
|
||||
|
||||
//if(ids.length) {
|
||||
return this.performSearchResult(this.filterMessagesByType(ids, type), type);
|
||||
//if(value.history.length) {
|
||||
return this.performSearchResult(this.filterMessagesByType(value.history, type), type);
|
||||
//}
|
||||
}, (err) => {
|
||||
}).catch(err => {
|
||||
this.log.error('load error:', err);
|
||||
}).then(() => {
|
||||
}).finally(() => {
|
||||
this.loadSidebarMediaPromises[type] = null;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
return Promise.all(promises).catch(err => {
|
||||
this.log.error('Load error all promises:', err);
|
||||
});
|
||||
}
|
||||
|
||||
public cleanup() {
|
||||
|
@ -308,7 +308,7 @@ export function wrapDocument(doc: MyDocument, withTime = false, uploading = fals
|
||||
const icoDiv = document.createElement('div');
|
||||
icoDiv.classList.add('document-ico');
|
||||
|
||||
if(doc.type == 'photo') {
|
||||
if(doc.thumbs?.length || uploading) {
|
||||
docDiv.classList.add('photo');
|
||||
|
||||
if(uploading) {
|
||||
|
@ -168,7 +168,7 @@ export class ApiUpdatesManager {
|
||||
date: updateMessage.date,
|
||||
message: updateMessage.message,
|
||||
fwd_from: updateMessage.fwd_from,
|
||||
reply_to_msg_id: updateMessage.reply_to_msg_id,
|
||||
reply_to: updateMessage.reply_to,
|
||||
entities: updateMessage.entities
|
||||
},
|
||||
pts: updateMessage.pts,
|
||||
|
@ -969,7 +969,7 @@ export class AppDialogsManager {
|
||||
}
|
||||
|
||||
let messageWrapped = RichTextProcessor.wrapRichText(messageText, {
|
||||
noLinebreakers: true,
|
||||
noLinebreaks: true,
|
||||
entities: entities,
|
||||
noTextFormat: true
|
||||
});
|
||||
@ -995,7 +995,7 @@ export class AppDialogsManager {
|
||||
}
|
||||
|
||||
//senderBold.innerText = str + ': ';
|
||||
senderBold.innerHTML = RichTextProcessor.wrapRichText(str, {noLinebreakers: true}) + ': ';
|
||||
senderBold.innerHTML = RichTextProcessor.wrapRichText(str, {noLinebreaks: true}) + ': ';
|
||||
//console.log(sender, senderBold.innerText);
|
||||
dom.lastMessageSpan.prepend(senderBold);
|
||||
} //////// else console.log('no sender', lastMessage, peerID);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack, getObjectKeysAndSort } from "../utils";
|
||||
import { copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack, getObjectKeysAndSort, limitSymbols } from "../utils";
|
||||
import appMessagesIDsManager from "./appMessagesIDsManager";
|
||||
import appChatsManager from "./appChatsManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
@ -822,7 +822,7 @@ export class AppMessagesManager {
|
||||
date: tsNow(true) + serverTimeManager.serverTimeOffset,
|
||||
message: text,
|
||||
random_id: randomIDS,
|
||||
reply_to_msg_id: replyToMsgID,
|
||||
reply_to: {reply_to_msg_id: replyToMsgID},
|
||||
via_bot_id: options.viaBotID,
|
||||
reply_markup: options.reply_markup,
|
||||
entities: entities,
|
||||
@ -1184,7 +1184,7 @@ export class AppMessagesManager {
|
||||
document: file
|
||||
} : media,
|
||||
random_id: randomIDS,
|
||||
reply_to_msg_id: replyToMsgID,
|
||||
reply_to: {reply_to_msg_id: replyToMsgID},
|
||||
views: asChannel && 1,
|
||||
pending: true
|
||||
};
|
||||
@ -1459,7 +1459,7 @@ export class AppMessagesManager {
|
||||
media: media,
|
||||
random_id: randomIDS,
|
||||
randomID: randomID,
|
||||
reply_to_msg_id: replyToMsgID,
|
||||
reply_to: {reply_to_msg_id: replyToMsgID},
|
||||
views: asChannel && 1,
|
||||
pending: true,
|
||||
error: false
|
||||
@ -1752,7 +1752,7 @@ export class AppMessagesManager {
|
||||
message: '',
|
||||
media: media,
|
||||
random_id: randomIDS,
|
||||
reply_to_msg_id: replyToMsgID,
|
||||
reply_to: {reply_to_msg_id: replyToMsgID},
|
||||
via_bot_id: options.viaBotID,
|
||||
reply_markup: options.reply_markup,
|
||||
views: asChannel && 1,
|
||||
@ -2132,7 +2132,8 @@ export class AppMessagesManager {
|
||||
return this.messagesStorage[messageID] || {
|
||||
_: 'messageEmpty',
|
||||
id: messageID,
|
||||
deleted: true
|
||||
deleted: true,
|
||||
pFlags: {}
|
||||
};
|
||||
}
|
||||
|
||||
@ -2308,8 +2309,8 @@ export class AppMessagesManager {
|
||||
}
|
||||
// this.log(dT(), 'msg unread', mid, apiMessage.pFlags.out, dialog && dialog[apiMessage.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id'])
|
||||
|
||||
if(apiMessage.reply_to_msg_id) {
|
||||
apiMessage.reply_to_mid = appMessagesIDsManager.getFullMessageID(apiMessage.reply_to_msg_id, channelID);
|
||||
if(apiMessage.reply_to && apiMessage.reply_to.reply_to_msg_id) {
|
||||
apiMessage.reply_to_mid = appMessagesIDsManager.getFullMessageID(apiMessage.reply_to.reply_to_msg_id, channelID);
|
||||
}
|
||||
|
||||
apiMessage.date -= serverTimeManager.serverTimeOffset;
|
||||
@ -2575,14 +2576,12 @@ export class AppMessagesManager {
|
||||
let messageWrapped = '';
|
||||
if(text) {
|
||||
// * 80 for chatlist in landscape orientation
|
||||
if(text.length > 80) {
|
||||
text = text.substr(0, 75) + '...';
|
||||
}
|
||||
text = limitSymbols(text, 75, 80);
|
||||
|
||||
let entities = RichTextProcessor.parseEntities(text.replace(/\n/g, ' '), {noLinebreakers: true});
|
||||
|
||||
messageWrapped = RichTextProcessor.wrapRichText(text, {
|
||||
noLinebreakers: true,
|
||||
noLinebreaks: true,
|
||||
entities: entities,
|
||||
noTextFormat: true
|
||||
});
|
||||
@ -2827,6 +2826,10 @@ export class AppMessagesManager {
|
||||
this.saveMessages([message]);
|
||||
}
|
||||
|
||||
if(!message?.pFlags) {
|
||||
this.log.error('saveConversation no message:', dialog, message);
|
||||
}
|
||||
|
||||
if(!channelID && peerID < 0) {
|
||||
const chat = appChatsManager.getChat(-peerID);
|
||||
if(chat && chat.migrated_to && chat.pFlags.deactivated) {
|
||||
@ -2886,7 +2889,7 @@ export class AppMessagesManager {
|
||||
public mergeReplyKeyboard(historyStorage: HistoryStorage, message: any) {
|
||||
// this.log('merge', message.mid, message.reply_markup, historyStorage.reply_markup)
|
||||
if(!message.reply_markup &&
|
||||
!message.pFlags.out &&
|
||||
!message.pFlags?.out &&
|
||||
!message.action) {
|
||||
return false;
|
||||
}
|
||||
@ -2966,10 +2969,10 @@ export class AppMessagesManager {
|
||||
history: number[]
|
||||
}> {
|
||||
//peerID = peerID ? parseInt(peerID) : 0;
|
||||
var foundMsgs: number[] = [];
|
||||
var useSearchCache = !query;
|
||||
var newSearchFilter = {peer: peerID, filter: inputFilter};
|
||||
var sameSearchCache = useSearchCache && deepEqual(this.lastSearchFilter, newSearchFilter);
|
||||
const foundMsgs: number[] = [];
|
||||
const useSearchCache = !query;
|
||||
const newSearchFilter = {peer: peerID, filter: inputFilter};
|
||||
const sameSearchCache = useSearchCache && deepEqual(this.lastSearchFilter, newSearchFilter);
|
||||
|
||||
if(useSearchCache && !sameSearchCache) {
|
||||
// this.log.warn(dT(), 'new search filter', lastSearchFilter, newSearchFilter)
|
||||
@ -2987,7 +2990,6 @@ export class AppMessagesManager {
|
||||
[messageMediaType: string]: boolean
|
||||
} = {},
|
||||
neededDocTypes: string[] = [];
|
||||
var message;
|
||||
|
||||
switch(inputFilter._) {
|
||||
case 'inputMessagesFilterPhotos':
|
||||
@ -3033,9 +3035,9 @@ export class AppMessagesManager {
|
||||
neededContents['url'] = true;
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterMyMentions':
|
||||
/* case 'inputMessagesFilterMyMentions':
|
||||
neededContents['mentioned'] = true;
|
||||
break;
|
||||
break; */
|
||||
|
||||
default:
|
||||
return Promise.resolve({
|
||||
@ -3045,8 +3047,12 @@ export class AppMessagesManager {
|
||||
});
|
||||
}
|
||||
|
||||
for(let i = 0; i < historyStorage.history.length; i++) {
|
||||
message = this.messagesStorage[historyStorage.history[i]];
|
||||
for(let i = 0, length = historyStorage.history.length; i < length; i++) {
|
||||
const message = this.messagesStorage[historyStorage.history[i]];
|
||||
|
||||
//|| (neededContents['mentioned'] && message.totalEntities.find((e: any) => e._ == 'messageEntityMention'));
|
||||
|
||||
let found = false;
|
||||
if(message.media && neededContents[message.media._]) {
|
||||
if(neededDocTypes.length &&
|
||||
message.media._ == 'messageMediaDocument' &&
|
||||
@ -3054,6 +3060,12 @@ export class AppMessagesManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
} else if(neededContents['url'] && message.message && RichTextProcessor.matchUrl(message.message)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if(found) {
|
||||
foundMsgs.push(message.mid);
|
||||
if(foundMsgs.length >= limit) {
|
||||
break;
|
||||
@ -3078,15 +3090,20 @@ export class AppMessagesManager {
|
||||
}
|
||||
|
||||
if(foundMsgs.length) {
|
||||
if(useSearchCache) {
|
||||
this.lastSearchResults = listMergeSorted(this.lastSearchResults, foundMsgs)
|
||||
if(foundMsgs.length < limit) {
|
||||
maxID = foundMsgs[foundMsgs.length - 1];
|
||||
limit = limit - foundMsgs.length;
|
||||
} else {
|
||||
if(useSearchCache) {
|
||||
this.lastSearchResults = listMergeSorted(this.lastSearchResults, foundMsgs)
|
||||
}
|
||||
|
||||
return Promise.resolve({
|
||||
count: 0,
|
||||
next_rate: 0,
|
||||
history: foundMsgs
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve({
|
||||
count: 0,
|
||||
next_rate: 0,
|
||||
history: foundMsgs
|
||||
});
|
||||
}
|
||||
|
||||
let apiPromise: Promise<any>;
|
||||
@ -3141,15 +3158,14 @@ export class AppMessagesManager {
|
||||
appChatsManager.saveApiChats(searchResult.chats);
|
||||
this.saveMessages(searchResult.messages);
|
||||
|
||||
///////////this.log('messages.search result:', searchResult);
|
||||
this.log('messages.search result:', inputFilter, searchResult);
|
||||
|
||||
var foundCount: number = searchResult.count || searchResult.messages.length;
|
||||
const foundCount: number = searchResult.count || (foundMsgs.length + searchResult.messages.length);
|
||||
|
||||
foundMsgs = [];
|
||||
searchResult.messages.forEach((message: any) => {
|
||||
var peerID = this.getMessagePeer(message);
|
||||
const peerID = this.getMessagePeer(message);
|
||||
if(peerID < 0) {
|
||||
var chat = appChatsManager.getChat(-peerID);
|
||||
const chat = appChatsManager.getChat(-peerID);
|
||||
if(chat.migrated_to) {
|
||||
this.migrateChecks(peerID, -chat.migrated_to.channel_id);
|
||||
}
|
||||
@ -3413,7 +3429,7 @@ export class AppMessagesManager {
|
||||
}
|
||||
|
||||
public handleUpdate(update: any) {
|
||||
this.log('AMM: handleUpdate:', update._);
|
||||
this.log.debug('AMM: handleUpdate:', update._);
|
||||
switch(update._) {
|
||||
case 'updateMessageID': {
|
||||
var randomID = update.random_id;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { Dialog, DialogsStorage, FiltersStorage } from './appMessagesManager';
|
||||
import type { AppStickersManager } from './appStickersManager';
|
||||
import type { AppPeersManager } from './appPeersManager';
|
||||
import { App, MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||
import { App, MOUNT_CLASS_TO, UserAuth } from '../mtproto/mtproto_config';
|
||||
import EventListenerBase from '../../helpers/eventListenerBase';
|
||||
import $rootScope from '../rootScope';
|
||||
import AppStorage from '../storage';
|
||||
@ -45,14 +45,14 @@ export class AppStateManager extends EventListenerBase<{
|
||||
|
||||
public loadSavedState() {
|
||||
if(this.loaded) return this.loaded;
|
||||
console.time('load state');
|
||||
//console.time('load state');
|
||||
return this.loaded = new Promise((resolve) => {
|
||||
AppStorage.get<[State, {id: number}]>('state', 'user_auth').then(([state, auth]) => {
|
||||
AppStorage.get<[State, UserAuth]>('state', 'user_auth').then(([state, auth]) => {
|
||||
const time = Date.now();
|
||||
if(state) {
|
||||
if(state?.version != STATE_VERSION) {
|
||||
if(state.version != STATE_VERSION) {
|
||||
state = {};
|
||||
} else if((state?.stateCreatedTime ?? 0) + REFRESH_EVERY < time) {
|
||||
} else if((state.stateCreatedTime || 0) + REFRESH_EVERY < time) {
|
||||
this.log('will refresh state', state.stateCreatedTime, time);
|
||||
REFRESH_KEYS.forEach(key => {
|
||||
delete state[key];
|
||||
@ -62,7 +62,7 @@ export class AppStateManager extends EventListenerBase<{
|
||||
}
|
||||
|
||||
// will not throw error because state can be `FALSE`
|
||||
const {peers, updates} = state;
|
||||
const {peers} = state;
|
||||
|
||||
this.state = state || {};
|
||||
this.state.peers = peers || {};
|
||||
@ -81,7 +81,7 @@ export class AppStateManager extends EventListenerBase<{
|
||||
$rootScope.$broadcast('user_auth', {id: auth.id});
|
||||
}
|
||||
|
||||
console.timeEnd('load state');
|
||||
//console.timeEnd('load state');
|
||||
resolve(state);
|
||||
}).catch(resolve).finally(() => {
|
||||
setInterval(() => this.saveState(), 10000);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { safeReplaceObject } from "../utils";
|
||||
import { limitSymbols, safeReplaceObject } from "../utils";
|
||||
import appPhotosManager from "./appPhotosManager";
|
||||
import appDocsManager from "./appDocsManager";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
@ -59,10 +59,7 @@ class AppWebPagesManager {
|
||||
}
|
||||
|
||||
// delete apiWebPage.description
|
||||
var shortDescriptionText = (apiWebPage.description || '');
|
||||
if(shortDescriptionText.length > 180) {
|
||||
shortDescriptionText = shortDescriptionText.substr(0, 150).replace(/(\n|\s)+$/, '') + '...';
|
||||
}
|
||||
var shortDescriptionText = limitSymbols(apiWebPage.description || '', 150, 180);
|
||||
apiWebPage.rDescription = RichTextProcessor.wrapRichText(shortDescriptionText, {
|
||||
contextSite: siteName || 'external',
|
||||
contextHashtag: contextHashtag
|
||||
|
@ -204,7 +204,9 @@ class TLSerialization {
|
||||
|
||||
var len = bytes.length;
|
||||
if((bits % 32) || (len * 8) != bits) {
|
||||
throw new Error('Invalid bits: ' + bits + ', ' + bytes.length);
|
||||
const error = new Error('Invalid bits: ' + bits + ', ' + bytes.length);
|
||||
console.error(error, bytes, field);
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.debug && console.log('>>>', bytesToHex(bytes), (field || '') + ':int' + bits);
|
||||
|
@ -271,7 +271,7 @@ function parseMarkdown(text: string, entities: any[], noTrim?: any) {
|
||||
}
|
||||
return newText
|
||||
}
|
||||
function mergeEntities (currentEntities: any[], newEntities: any[], fromApi: any) {
|
||||
function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any) {
|
||||
var totalEntities = newEntities.slice();
|
||||
var i;
|
||||
var len = currentEntities.length;
|
||||
@ -337,14 +337,26 @@ function mergeEntities (currentEntities: any[], newEntities: any[], fromApi: any
|
||||
// console.log('merge', currentEntities, newEntities, totalEntities)
|
||||
return totalEntities;
|
||||
}
|
||||
function wrapRichNestedText (text: string, nested: any, options: any) {
|
||||
if (nested === undefined) {
|
||||
return encodeEntities(text)
|
||||
function wrapRichNestedText(text: string, nested: any, options: any) {
|
||||
if(nested === undefined) {
|
||||
return encodeEntities(text);
|
||||
}
|
||||
options.hasNested = true
|
||||
return wrapRichText(text, {entities: nested, nested: true})
|
||||
|
||||
options.hasNested = true;
|
||||
return wrapRichText(text, {entities: nested, nested: true});
|
||||
}
|
||||
function wrapRichText (text: string, options: any = {}) {
|
||||
function wrapRichText(text: string, options: Partial<{
|
||||
entities: any,
|
||||
contextSite: string,
|
||||
highlightUsername: string,
|
||||
noLinks: boolean,
|
||||
noLinebreaks: boolean,
|
||||
noCommands: boolean,
|
||||
fromBot: boolean,
|
||||
noTextFormat: boolean,
|
||||
nested?: boolean,
|
||||
contextHashtag?: string
|
||||
}> = {}) {
|
||||
if(!text || !text.length) {
|
||||
return ''
|
||||
}
|
||||
@ -713,7 +725,7 @@ function wrapEmojiText(text: string) {
|
||||
let entities = parseEntities(text).filter(e => e._ == 'messageEntityEmoji');
|
||||
return wrapRichText(text, {entities});
|
||||
}
|
||||
function wrapUrl(url: string, unsafe: any): string {
|
||||
function wrapUrl(url: string, unsafe: number | boolean): string {
|
||||
if(!url.match(/^https?:\/\//i)) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
@ -765,18 +777,23 @@ function wrapUrl(url: string, unsafe: any): string {
|
||||
return url;
|
||||
}
|
||||
|
||||
function matchUrl(text: string) {
|
||||
return text.match(urlRegExp);
|
||||
}
|
||||
|
||||
let RichTextProcessor = {
|
||||
wrapRichText: wrapRichText,
|
||||
wrapPlainText: wrapPlainText,
|
||||
wrapDraftText: wrapDraftText,
|
||||
wrapUrl: wrapUrl,
|
||||
wrapEmojiText: wrapEmojiText,
|
||||
parseEntities: parseEntities,
|
||||
parseMarkdown: parseMarkdown,
|
||||
parseEmojis: parseEmojis,
|
||||
mergeEntities: mergeEntities,
|
||||
getEmojiSpritesheetCoords: getEmojiSpritesheetCoords,
|
||||
emojiSupported: emojiSupported
|
||||
wrapRichText,
|
||||
wrapPlainText,
|
||||
wrapDraftText,
|
||||
wrapUrl,
|
||||
wrapEmojiText,
|
||||
parseEntities,
|
||||
parseMarkdown,
|
||||
parseEmojis,
|
||||
mergeEntities,
|
||||
getEmojiSpritesheetCoords,
|
||||
emojiSupported,
|
||||
matchUrl
|
||||
};
|
||||
|
||||
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.RichTextProcessor = RichTextProcessor);
|
||||
|
@ -235,7 +235,7 @@ export function tsNow(seconds?: boolean) {
|
||||
}
|
||||
|
||||
const el = document.createElement('span');
|
||||
export function getAbbreviation(str: string) {
|
||||
export function getAbbreviation(str: string, onlyFirst = false) {
|
||||
const wrapped = RichTextProcessor.wrapEmojiText(str);
|
||||
el.innerHTML = wrapped;
|
||||
|
||||
@ -246,6 +246,8 @@ export function getAbbreviation(str: string) {
|
||||
if('length' in firstNode) first = (firstNode as any).textContent.charAt(0).toUpperCase();
|
||||
else first = (firstNode as HTMLElement).outerHTML;
|
||||
|
||||
if(onlyFirst) return first;
|
||||
|
||||
if(str.indexOf(' ') !== -1) {
|
||||
const lastNode = childNodes[childNodes.length - 1];
|
||||
if(lastNode == firstNode) last = lastNode.textContent.split(' ').pop().charAt(0).toUpperCase();
|
||||
@ -292,6 +294,14 @@ export function safeReplaceArrayInObject<K>(key: K, wasObject: any, newObject: a
|
||||
}
|
||||
}
|
||||
|
||||
export function limitSymbols(str: string, length: number, limitFrom = length + 10) {
|
||||
if(str.length > limitFrom) {
|
||||
str = str.slice(0, length).replace(/(\n|\s)+$/, '') + '...';
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function numberWithCommas(x: number) {
|
||||
var parts = x.toString().split(".");
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
|
Loading…
x
Reference in New Issue
Block a user