Browse Source

Hide empty tabs in shared media

Fix sending, deleting comments
Fix multiline checkbox
Fix "null comments"
Fix wrong input privacy key for photo
Fix opening member from shared media on handhelds
master
morethanwords 4 years ago
parent
commit
ba3551c0c3
  1. 94
      src/components/appSearchSuper..ts
  2. 4
      src/components/chat/bubbles.ts
  3. 11
      src/components/chat/topbar.ts
  4. 6
      src/components/sidebarLeft/tabs/background.ts
  5. 2
      src/components/sidebarLeft/tabs/privacy/profilePhoto.ts
  6. 8
      src/components/sidebarRight/tabs/editChannel.ts
  7. 4
      src/components/sidebarRight/tabs/editGroup.ts
  8. 6
      src/components/sidebarRight/tabs/groupPermissions.ts
  9. 1
      src/components/sortedUserList.ts
  10. 46
      src/helpers/listenerSetter.ts
  11. 15
      src/layer.d.ts
  12. 2
      src/lib/appManagers/appImManager.ts
  13. 146
      src/lib/appManagers/appMessagesManager.ts
  14. 10
      src/lib/rootScope.ts
  15. 13
      src/scripts/in/schema_additional_params.json
  16. 3
      src/scss/partials/_checkbox.scss
  17. 8
      src/scss/partials/_leftSidebar.scss
  18. 6
      src/scss/partials/_profile.scss
  19. 3
      src/scss/partials/_rightSidebar.scss

94
src/components/appSearchSuper..ts

@ -35,6 +35,10 @@ import { getMiddleware } from "../helpers/middleware"; @@ -35,6 +35,10 @@ import { getMiddleware } from "../helpers/middleware";
import appProfileManager from "../lib/appManagers/appProfileManager";
import { ChannelParticipant, ChatFull, ChatParticipant, ChatParticipants } from "../layer";
import SortedUserList from "./sortedUserList";
import findUpTag from "../helpers/dom/findUpTag";
import appSidebarRight from "./sidebarRight";
import mediaSizes from "../helpers/mediaSizes";
import appImManager from "../lib/appManagers/appImManager";
//const testScroll = false;
@ -88,6 +92,7 @@ export default class AppSearchSuper { @@ -88,6 +92,7 @@ export default class AppSearchSuper {
private loadPromises: Partial<{[type in SearchSuperType]: Promise<void>}> = {};
private loaded: Partial<{[type in SearchSuperType]: boolean}> = {};
private loadedChats = false;
private firstLoad = true;
private log = logger('SEARCH-SUPER');
public selectTab: ReturnType<typeof horizontalMenu>;
@ -855,6 +860,22 @@ export default class AppSearchSuper { @@ -855,6 +860,22 @@ export default class AppSearchSuper {
if(!this.membersList) {
this.membersList = new SortedUserList();
this.membersList.list.addEventListener('click', (e) => {
const li = findUpTag(e.target, 'LI');
if(!li) {
return;
}
const peerId = +li.dataset.peerId;
let promise: Promise<any> = Promise.resolve();
if(mediaSizes.isMobile) {
promise = appSidebarRight.toggleSidebar(false);
}
promise.then(() => {
appImManager.setInnerPeer(peerId);
});
});
mediaTab.contentTab.append(this.membersList.list);
this.afterPerforming(1, mediaTab.contentTab);
}
@ -1039,7 +1060,7 @@ export default class AppSearchSuper { @@ -1039,7 +1060,7 @@ export default class AppSearchSuper {
});
}
public load(single = false, justLoad = false) {
public async load(single = false, justLoad = false) {
// if(testScroll/* || 1 === 1 */) {
// return;
// }
@ -1048,6 +1069,57 @@ export default class AppSearchSuper { @@ -1048,6 +1069,57 @@ export default class AppSearchSuper {
const peerId = this.searchContext.peerId;
this.log('load', single, peerId, this.loadPromises);
const middleware = this.middleware.get();
if(this.firstLoad) {
if(this.hideEmptyTabs) {
const mediaTabs = this.mediaTabs.filter(mediaTab => mediaTab.inputFilter !== 'inputMessagesFilterEmpty')
const filters = mediaTabs.map(mediaTab => ({_: mediaTab.inputFilter}));
const counters = await appMessagesManager.getSearchCounters(peerId, filters);
if(!middleware()) {
return;
}
if(this.loadMutex) {
await this.loadMutex;
if(!middleware()) {
return;
}
}
let firstMediaTab: SearchSuperMediaTab;
mediaTabs.forEach(mediaTab => {
const counter = counters.find(c => c.filter._ === mediaTab.inputFilter);
mediaTab.menuTab.classList.toggle('hide', !counter.count);
mediaTab.menuTab.classList.remove('active');
//mediaTab.contentTab.classList.toggle('hide', !counter.count);
if(counter.count && firstMediaTab === undefined) {
firstMediaTab = mediaTab;
}
});
const membersTab = this.mediaTabsMap.get('members');
const canViewMembers = this.canViewMembers();
membersTab.menuTab.classList.toggle('hide', !canViewMembers);
if(canViewMembers) {
firstMediaTab = membersTab;
}
this.container.classList.toggle('hide', !firstMediaTab);
this.container.parentElement.classList.toggle('search-empty', !firstMediaTab);
this.selectTab(this.mediaTabs.indexOf(firstMediaTab), false);
if(firstMediaTab) {
firstMediaTab.menuTab.classList.add('active');
}
}
this.firstLoad = false;
}
let toLoad = single ? [this.mediaTab] : this.mediaTabs.filter(t => t !== this.mediaTab);
toLoad = toLoad.filter(mediaTab => {
@ -1060,12 +1132,11 @@ export default class AppSearchSuper { @@ -1060,12 +1132,11 @@ export default class AppSearchSuper {
}
const loadCount = justLoad ? 50 : Math.round((appPhotosManager.windowH / 130 | 0) * 3 * 1.25); // that's good for all types
const middleware = this.middleware.get();
const promises: Promise<any>[] = toLoad.map(mediaTab => {
return this.loadType(mediaTab, justLoad, loadCount, middleware)
});
return Promise.all(promises).catch(err => {
this.log.error('Load error all promises:', err);
});
@ -1118,6 +1189,7 @@ export default class AppSearchSuper { @@ -1118,6 +1189,7 @@ export default class AppSearchSuper {
this.loaded = {};
this.loadedChats = false;
this.nextRates = {};
this.firstLoad = true;
this.lazyLoadQueue.clear();
@ -1126,11 +1198,11 @@ export default class AppSearchSuper { @@ -1126,11 +1198,11 @@ export default class AppSearchSuper {
});
// * must go to first tab (это костыль)
const membersTab = this.mediaTabsMap.get('members');
/* const membersTab = this.mediaTabsMap.get('members');
if(membersTab) {
const tab = this.canViewMembers() ? membersTab : this.mediaTabs[this.mediaTabs.indexOf(membersTab) + 1];
this.mediaTab = tab;
}
} */
this.middleware.clean();
this.cleanScrollPositions();
@ -1154,9 +1226,11 @@ export default class AppSearchSuper { @@ -1154,9 +1226,11 @@ export default class AppSearchSuper {
this.mediaTabs.forEach((tab) => {
tab.contentTab.innerHTML = '';
/* if(this.hideEmptyTabs) {
tab.menuTab.classList.add('hide');
} */
if(this.hideEmptyTabs) {
//tab.menuTab.classList.add('hide');
this.container.classList.add('hide');
this.container.parentElement.classList.add('search-empty');
}
if(tab.type === 'chats') {
return;
@ -1177,7 +1251,7 @@ export default class AppSearchSuper { @@ -1177,7 +1251,7 @@ export default class AppSearchSuper {
}
});
if(goFirst) {
/* if(goFirst) {
const membersTab = this.mediaTabsMap.get('members');
if(membersTab) {
let idx = this.canViewMembers() ? 0 : 1;
@ -1187,7 +1261,7 @@ export default class AppSearchSuper { @@ -1187,7 +1261,7 @@ export default class AppSearchSuper {
} else {
this.selectTab(0, false);
}
}
} */
this.monthContainers = {};
this.searchGroupMedia.clear();

4
src/components/chat/bubbles.ts

@ -181,6 +181,8 @@ export default class ChatBubbles { @@ -181,6 +181,8 @@ export default class ChatBubbles {
}
});
//this.listenerSetter.add(rootScope, '')
this.listenerSetter.add(rootScope, 'dialog_flush', (e) => {
let peerId: number = e.peerId;
if(this.peerId === peerId) {
@ -434,7 +436,7 @@ export default class ChatBubbles { @@ -434,7 +436,7 @@ export default class ChatBubbles {
const msgIdsByPeer = e;
if(!(this.peerId in msgIdsByPeer)) return;
const msgIds = (msgIdsByPeer[this.peerId] as number[]).slice().sort((a, b) => b - a);
const msgIds = Array.from(msgIdsByPeer[this.peerId] as number[]).slice().sort((a, b) => b - a);
this.renderNewMessagesByIds(msgIds);
});

11
src/components/chat/topbar.ts

@ -451,7 +451,7 @@ export default class ChatTopbar { @@ -451,7 +451,7 @@ export default class ChatTopbar {
else titleEl = i18n('PinnedMessagesCount', [count]);
if(count === undefined) {
this.appMessagesManager.getSearchCounters(this.peerId, [{_: 'inputMessagesFilterPinned'}]).then(result => {
this.appMessagesManager.getSearchCounters(this.peerId, [{_: 'inputMessagesFilterPinned'}], false).then(result => {
const count = result[0].count;
this.setTitle(count);
@ -490,7 +490,14 @@ export default class ChatTopbar { @@ -490,7 +490,14 @@ export default class ChatTopbar {
this.appMessagesManager.getHistory(this.peerId, 0, 1, 0, this.chat.threadId),
Promise.resolve()
]).then(() => {
this.setTitle(this.appMessagesManager.getHistoryStorage(this.peerId, this.chat.threadId).count);
const count = this.appMessagesManager.getHistoryStorage(this.peerId, this.chat.threadId).count;
if(count === null) {
setTimeout(() => {
this.setTitle();
}, 30);
} else {
this.setTitle(count);
}
});
}
} else if(this.chat.type === 'chat') {

6
src/components/sidebarLeft/tabs/background.ts

@ -32,8 +32,8 @@ export default class AppBackgroundTab extends SliderSuperTab { @@ -32,8 +32,8 @@ export default class AppBackgroundTab extends SliderSuperTab {
{
const container = generateSection(this.scrollable);
const uploadButton = Button('btn-primary btn-transparent', {icon: 'cameraadd', text: 'ChatBackground.UploadWallpaper', disabled: true});
const colorButton = Button('btn-primary btn-transparent', {icon: 'colorize', text: 'ChatBackground.SetColor', disabled: true});
//const uploadButton = Button('btn-primary btn-transparent', {icon: 'cameraadd', text: 'ChatBackground.UploadWallpaper', disabled: true});
//const colorButton = Button('btn-primary btn-transparent', {icon: 'colorize', text: 'ChatBackground.SetColor', disabled: true});
const blurCheckboxField = new CheckboxField({
text: 'ChatBackground.Blur',
@ -51,7 +51,7 @@ export default class AppBackgroundTab extends SliderSuperTab { @@ -51,7 +51,7 @@ export default class AppBackgroundTab extends SliderSuperTab {
}, 100);
});
container.append(uploadButton, colorButton, blurCheckboxField.label);
container.append(/* uploadButton, colorButton, */blurCheckboxField.label);
}
const grid = document.createElement('div');

2
src/components/sidebarLeft/tabs/privacy/profilePhoto.ts

@ -18,7 +18,7 @@ export default class AppPrivacyProfilePhotoTab extends SliderSuperTabEventable { @@ -18,7 +18,7 @@ export default class AppPrivacyProfilePhotoTab extends SliderSuperTabEventable {
new PrivacySection({
tab: this,
title: 'PrivacyProfilePhotoTitle',
inputKey: 'inputPrivacyKeyChatInvite',
inputKey: 'inputPrivacyKeyProfilePhoto',
captions: [caption, caption, caption],
exceptionTexts: ['PrivacySettingsController.NeverShare', 'PrivacySettingsController.AlwaysShare'],
appendTo: this.scrollable,

8
src/components/sidebarRight/tabs/editChannel.ts

@ -95,7 +95,7 @@ export default class AppEditChannelTab extends SliderSuperTab { @@ -95,7 +95,7 @@ export default class AppEditChannelTab extends SliderSuperTab {
}, {listenerSetter: this.listenerSetter});
}
if(appChatsManager.hasRights(-this.peerId, 'change_type')) {
/* if(appChatsManager.hasRights(-this.peerId, 'change_type')) {
const channelTypeRow = new Row({
titleLangKey: 'ChannelType',
subtitleLangKey: 'TypePrivate',
@ -133,12 +133,12 @@ export default class AppEditChannelTab extends SliderSuperTab { @@ -133,12 +133,12 @@ export default class AppEditChannelTab extends SliderSuperTab {
});
section.content.append(signMessagesCheckboxField.label);
}
} */
this.scrollable.append(section.container);
}
{
/* {
const section = new SettingSection({
});
@ -154,7 +154,7 @@ export default class AppEditChannelTab extends SliderSuperTab { @@ -154,7 +154,7 @@ export default class AppEditChannelTab extends SliderSuperTab {
section.content.append(subscribersRow.container);
this.scrollable.append(section.container);
}
} */
if(appChatsManager.hasRights(-this.peerId, 'delete_chat')) {
const section = new SettingSection({

4
src/components/sidebarRight/tabs/editGroup.ts

@ -132,14 +132,14 @@ export default class AppEditGroupTab extends SliderSuperTab { @@ -132,14 +132,14 @@ export default class AppEditGroupTab extends SliderSuperTab {
});
}
const administratorsRow = new Row({
/* const administratorsRow = new Row({
titleLangKey: 'PeerInfo.Administrators',
subtitle: '' + ((chatFull as ChatFull.channelFull).admins_count || 1),
icon: 'admin',
clickable: true
});
section.content.append(administratorsRow.container);
section.content.append(administratorsRow.container); */
this.scrollable.append(section.container);

6
src/components/sidebarRight/tabs/groupPermissions.ts

@ -185,14 +185,16 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable { @@ -185,14 +185,16 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
tab.open();
};
const removedUsersRow = new Row({
section.content.append(addExceptionRow.container);
/* const removedUsersRow = new Row({
titleLangKey: 'ChannelBlockedUsers',
subtitleLangKey: 'NoBlockedUsers',
icon: 'deleteuser',
clickable: true
});
section.content.append(addExceptionRow.container, removedUsersRow.container);
section.content.append(removedUsersRow.container); */
const c = section.generateContentElement();
c.classList.add('chatlist-container');

1
src/components/sortedUserList.ts

@ -23,7 +23,6 @@ export default class SortedUserList { @@ -23,7 +23,6 @@ export default class SortedUserList {
constructor() {
this.list = appDialogsManager.createChatList();
appDialogsManager.setListClickListener(this.list, undefined, undefined, true, true);
this.users = new Map();
this.sorted = [];

46
src/helpers/listenerSetter.ts

@ -4,32 +4,56 @@ @@ -4,32 +4,56 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export type Listener = {element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions};
export type ListenerElement = any;
export type ListenerEvent = string;
export type ListenerOptions = any;
import type { RootScope } from "../lib/rootScope";
import { ArgumentTypes } from "../types";
/* export type Listener<T extends ListenerElement> = {
element: ListenerElement,
event: ListenerEvent<T>,
callback: ListenerCallback<T>,
options?: ListenerOptions
};
export type ListenerElement = HTMLElement | RootScope;
export type ListenerEvent<T extends ListenerElement> = ArgumentTypes<T['addEventListener']>[0];
export type ListenerCallback<T extends ListenerElement> = ArgumentTypes<T['addEventListener']>[1];
export type ListenerOptions = any; */
export type Listener<T extends ListenerElement> = {
element: ListenerElement,
event: ListenerEvent<T>,
callback: ListenerCallback,
options?: ListenerOptions
};
export type ListenerElement = Window | Document | HTMLElement | Element | RootScope | any;
//export type ListenerEvent<T extends ListenerElement> = ArgumentTypes<T['addEventListener']>[0];
export type ListenerEvent<T extends ListenerElement> = string;
export type ListenerCallback = (...args: any[]) => any;
export type ListenerOptions = any;
export default class ListenerSetter {
private listeners: Set<Listener> = new Set();
private listeners: Set<Listener<any>> = new Set();
public add(element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) {
const listener = {element, event, callback, options};
public add<T extends ListenerElement>(element: T, event: ListenerEvent<T>, callback: ListenerCallback, options?: ListenerOptions) {
const listener: Listener<T> = {element, event, callback, options};
this.addManual(listener);
return listener;
}
public addManual(listener: Listener) {
public addManual<T extends ListenerElement>(listener: Listener<T>) {
// @ts-ignore
listener.element.addEventListener(listener.event, listener.callback, listener.options);
this.listeners.add(listener);
}
public remove(listener: Listener) {
public remove<T extends ListenerElement>(listener: Listener<T>) {
// @ts-ignore
listener.element.removeEventListener(listener.event, listener.callback, listener.options);
this.listeners.delete(listener);
}
public removeManual(element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) {
let listener: Listener;
public removeManual<T extends ListenerElement>(element: T, event: ListenerEvent<T>, callback: ListenerCallback, options?: ListenerOptions) {
let listener: Listener<T>;
for(const _listener of this.listeners) {
if(_listener.element === element && _listener.event === event && _listener.callback === callback && _listener.options === options) {
listener = _listener;

15
src/layer.d.ts vendored

@ -1882,7 +1882,7 @@ export namespace MessagesFilter { @@ -1882,7 +1882,7 @@ export namespace MessagesFilter {
/**
* @link https://core.telegram.org/type/Update
*/
export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped;
export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped | Update.updateNewDiscussionMessage | Update.updateDeleteDiscussionMessages;
export namespace Update {
export type updateNewMessage = {
@ -2524,6 +2524,17 @@ export namespace Update { @@ -2524,6 +2524,17 @@ export namespace Update {
stopped: boolean,
qts: number
};
export type updateNewDiscussionMessage = {
_: 'updateNewDiscussionMessage',
message?: Message
};
export type updateDeleteDiscussionMessages = {
_: 'updateDeleteDiscussionMessages',
messages?: number[],
channel_id?: number
};
}
/**
@ -9619,6 +9630,8 @@ export interface ConstructorDeclMap { @@ -9619,6 +9630,8 @@ export interface ConstructorDeclMap {
'messageActionChatReturn': MessageAction.messageActionChatReturn,
'messageActionChatJoinedYou': MessageAction.messageActionChatJoinedYou,
'messageActionChatReturnYou': MessageAction.messageActionChatReturnYou,
'updateNewDiscussionMessage': Update.updateNewDiscussionMessage,
'updateDeleteDiscussionMessages': Update.updateDeleteDiscussionMessages,
}
export type InvokeAfterMsg = {

2
src/lib/appManagers/appImManager.ts

@ -408,7 +408,7 @@ export class AppImManager { @@ -408,7 +408,7 @@ export class AppImManager {
const msgIdsByPeer = e;
for(const peerId in msgIdsByPeer) {
appSidebarRight.sharedMediaTab.renderNewMessages(+peerId, msgIdsByPeer[peerId]);
appSidebarRight.sharedMediaTab.renderNewMessages(+peerId, Array.from(msgIdsByPeer[peerId]));
}
});

146
src/lib/appManagers/appMessagesManager.ts

@ -141,6 +141,7 @@ export class AppMessagesManager { @@ -141,6 +141,7 @@ export class AppMessagesManager {
[randomId: string]: {
peerId: number,
tempId: number,
threadId: number,
storage: MessagesStorage
}
} = {};
@ -169,7 +170,7 @@ export class AppMessagesManager { @@ -169,7 +170,7 @@ export class AppMessagesManager {
public migratedToFrom: {[peerId: number]: number} = {};
public newMessagesHandlePromise = 0;
public newMessagesToHandle: {[peerId: string]: number[]} = {};
public newMessagesToHandle: {[peerId: string]: Set<number>} = {};
public newDialogsHandlePromise = 0;
public newDialogsToHandle: {[peerId: string]: {reload: true} | Dialog} = {};
public newUpdatesAfterReloadToHandle: {[peerId: string]: Set<any>} = {};
@ -1095,8 +1096,10 @@ export class AppMessagesManager { @@ -1095,8 +1096,10 @@ export class AppMessagesManager {
return this.sendFile(peerId, file, o).message;
});
if(options.clearDraft) {
if(options.threadId) {
appDraftsManager.syncDraft(peerId, options.threadId);
} else {
appDraftsManager.saveDraft(peerId, options.threadId, null, {notify: true});
}
// * test pending
@ -1382,16 +1385,16 @@ export class AppMessagesManager { @@ -1382,16 +1385,16 @@ export class AppMessagesManager {
rootScope.broadcast('scheduled_new', {peerId, mid: messageId});
}, 0);
} else {
if(options.threadId && this.threadsStorage[peerId]) {
/* if(options.threadId && this.threadsStorage[peerId]) {
delete this.threadsStorage[peerId][options.threadId];
}
//if(options.threadId) {
const historyStorage = this.getHistoryStorage(peerId/* , options.threadId */);
} */
if(options.threadId) {
const historyStorage = this.getHistoryStorage(peerId, options.threadId);
historyStorage.history.unshift(messageId);
//}
}
/* const historyStorage = this.getHistoryStorage(peerId);
historyStorage.history.unshift(messageId); */
const historyStorage = this.getHistoryStorage(peerId);
historyStorage.history.unshift(messageId);
//if(!options.isGroupedItem) {
this.saveMessages([message], {storage, isOutgoing: true});
@ -1401,11 +1404,20 @@ export class AppMessagesManager { @@ -1401,11 +1404,20 @@ export class AppMessagesManager {
}, 0);
}
if(!options.isGroupedItem && options.clearDraft && !options.threadId) {
appDraftsManager.syncDraft(peerId, options.threadId);
if(!options.isGroupedItem && options.clearDraft) {
if(options.threadId) {
appDraftsManager.syncDraft(peerId, options.threadId);
} else {
appDraftsManager.saveDraft(peerId, options.threadId, null, {notify: true});
}
}
this.pendingByRandomId[message.random_id] = {peerId, tempId: messageId, storage};
this.pendingByRandomId[message.random_id] = {
peerId,
tempId: messageId,
threadId: options.threadId,
storage
};
if(!options.isGroupedItem && message.send) {
setTimeout(message.send, 0);
@ -3259,8 +3271,9 @@ export class AppMessagesManager { @@ -3259,8 +3271,9 @@ export class AppMessagesManager {
return this.searchesStorage[peerId][inputFilter];
}
public getSearchCounters(peerId: number, filters: MessagesFilter[]) {
return apiManager.invokeApi('messages.getSearchCounters', {
public getSearchCounters(peerId: number, filters: MessagesFilter[], canCache = true) {
const func = (canCache ? apiManager.invokeApiCacheable : apiManager.invokeApi).bind(apiManager);
return func('messages.getSearchCounters', {
peer: appPeersManager.getInputPeerById(peerId),
filters
});
@ -3907,13 +3920,16 @@ export class AppMessagesManager { @@ -3907,13 +3920,16 @@ export class AppMessagesManager {
const pendingData = this.pendingByRandomId[randomId];
//this.log('AMM updateMessageID:', update, pendingData);
if(pendingData) {
const {peerId, tempId, storage} = pendingData;
const {peerId, tempId, threadId, storage} = pendingData;
//const mid = update.id;
const mid = this.generateMessageId(update.id);
const message = this.getMessageFromStorage(storage, mid);
if(!message.deleted) {
const historyStorage = this.getHistoryStorage(peerId);
historyStorage.history.delete(tempId);
[this.getHistoryStorage(peerId), threadId ? this.getHistoryStorage(peerId, threadId) : undefined]
.filter(Boolean)
.forEach(storage => {
storage.history.delete(tempId);
});
this.finalizePendingMessageCallbacks(storage, tempId, mid);
} else {
@ -3924,6 +3940,7 @@ export class AppMessagesManager { @@ -3924,6 +3940,7 @@ export class AppMessagesManager {
break;
}
case 'updateNewDiscussionMessage':
case 'updateNewMessage':
case 'updateNewChannelMessage': {
const message = update.message as MyMessage;
@ -3931,7 +3948,24 @@ export class AppMessagesManager { @@ -3931,7 +3948,24 @@ export class AppMessagesManager {
const storage = this.getMessagesStorage(peerId);
const foundDialog = this.getDialogByPeerId(peerId);
if(!foundDialog.length) {
// * local update
const isLocalThreadUpdate = update._ === 'updateNewDiscussionMessage';
// * temporary save the message for info (peerId, reply mids...)
this.saveMessages([message], {storage: {}});
const threadKey = this.getThreadKey(message);
const threadId = threadKey ? +threadKey.split('_')[1] : undefined;
if(threadId && !isLocalThreadUpdate && this.threadsStorage[peerId] && this.threadsStorage[peerId][threadId]) {
const update = {
_: 'updateNewDiscussionMessage',
message
} as Update.updateNewDiscussionMessage;
this.handleUpdate(update);
}
if(!foundDialog.length && !isLocalThreadUpdate) {
let good = true;
if(peerId < 0) {
const chat = appChatsManager.getChat(-peerId);
@ -3974,8 +4008,11 @@ export class AppMessagesManager { @@ -3974,8 +4008,11 @@ export class AppMessagesManager {
} */
const pendingMessage = this.checkPendingMessage(message);
const historyStorage = this.getHistoryStorage(peerId);
this.updateMessageRepliesIfNeeded(message);
const historyStorage = this.getHistoryStorage(peerId, isLocalThreadUpdate ? threadId : undefined);
if(!isLocalThreadUpdate) {
this.updateMessageRepliesIfNeeded(message);
}
if(historyStorage.history.findSlice(message.mid)) {
return false;
@ -3994,7 +4031,7 @@ export class AppMessagesManager { @@ -3994,7 +4031,7 @@ export class AppMessagesManager {
if(historyStorage.count !== null) {
historyStorage.count++;
}
if(this.mergeReplyKeyboard(historyStorage, message)) {
rootScope.broadcast('history_reply_markup', {peerId});
}
@ -4005,14 +4042,18 @@ export class AppMessagesManager { @@ -4005,14 +4042,18 @@ export class AppMessagesManager {
if(!pendingMessage) {
if(this.newMessagesToHandle[peerId] === undefined) {
this.newMessagesToHandle[peerId] = [];
this.newMessagesToHandle[peerId] = new Set();
}
this.newMessagesToHandle[peerId].push(message.mid);
this.newMessagesToHandle[peerId].add(message.mid);
if(!this.newMessagesHandlePromise) {
this.newMessagesHandlePromise = window.setTimeout(this.handleNewMessages, 0);
}
}
if(isLocalThreadUpdate) {
break;
}
const dialog = foundDialog[0];
const inboxUnread = !message.pFlags.out && message.pFlags.unread;
@ -4402,16 +4443,33 @@ export class AppMessagesManager { @@ -4402,16 +4443,33 @@ export class AppMessagesManager {
const channelId: number = (update as Update.updateDeleteChannelMessages).channel_id;
//const messages = (update as any as Update.updateDeleteChannelMessages).messages;
const messages = (update as any as Update.updateDeleteChannelMessages).messages.map(id => this.generateMessageId(id));
const peerId = channelId ? -channelId : this.getMessageById(messages[0]).peerId;
const peerId: number = channelId ? -channelId : this.getMessageById(messages[0]).peerId;
if(!peerId) {
break;
}
apiManager.clearCache('messages.getSearchCounters', (params) => {
return appPeersManager.getPeerId(params.peer) === peerId;
});
const threadKeys: Set<string> = new Set();
for(const mid of messages) {
const message = this.getMessageByPeer(peerId, mid);
const threadKey = this.getThreadKey(message);
if(threadKey && this.threadsStorage[peerId] && this.threadsStorage[peerId][+threadKey.split('_')[1]]) {
threadKeys.add(threadKey);
}
}
const historyUpdated = this.handleDeletedMessages(peerId, this.getMessagesStorage(peerId), messages);
const historyStorage = this.getHistoryStorage(peerId);
//if(historyStorage !== undefined) {
const threadsStorages = Array.from(threadKeys).map(threadKey => {
const splitted = threadKey.split('_');
return this.getHistoryStorage(+splitted[0], +splitted[1]);
});
[this.getHistoryStorage(peerId)].concat(threadsStorages).forEach(historyStorage => {
for(const mid in historyUpdated.msgs) {
historyStorage.history.delete(+mid);
}
@ -4423,9 +4481,9 @@ export class AppMessagesManager { @@ -4423,9 +4481,9 @@ export class AppMessagesManager {
historyStorage.count = 0;
}
}
});
rootScope.broadcast('history_delete', {peerId, msgs: historyUpdated.msgs});
//}
rootScope.broadcast('history_delete', {peerId, msgs: historyUpdated.msgs});
const foundDialog = this.getDialogByPeerId(peerId)[0];
if(foundDialog) {
@ -4658,9 +4716,8 @@ export class AppMessagesManager { @@ -4658,9 +4716,8 @@ export class AppMessagesManager {
private updateMessageRepliesIfNeeded(threadMessage: MyMessage) {
try { // * на всякий случай, скорее всего это не понадобится
if(threadMessage.peerId < 0 && threadMessage.reply_to) {
const threadId = threadMessage.reply_to.reply_to_top_id || threadMessage.reply_to.reply_to_msg_id;
const threadKey = threadMessage.peerId + '_' + threadId;
const threadKey = this.getThreadKey(threadMessage);
if(threadKey) {
const repliesKey = this.threadsToReplies[threadKey];
if(repliesKey) {
const [peerId, mid] = repliesKey.split('_').map(n => +n);
@ -4673,6 +4730,16 @@ export class AppMessagesManager { @@ -4673,6 +4730,16 @@ export class AppMessagesManager {
}
}
private getThreadKey(threadMessage: MyMessage) {
let threadKey = '';
if(threadMessage.peerId < 0 && threadMessage.reply_to) {
const threadId = threadMessage.reply_to.reply_to_top_id || threadMessage.reply_to.reply_to_msg_id;
threadKey = threadMessage.peerId + '_' + threadId;
}
return threadKey;
}
public updateMessage(peerId: number, mid: number, broadcastEventName?: 'replies_updated'): Promise<Message.message> {
const promise: Promise<Message.message> = this.wrapSingleMessage(peerId, mid, true).then(() => {
const message = this.getMessageByPeer(peerId, mid);
@ -4738,11 +4805,15 @@ export class AppMessagesManager { @@ -4738,11 +4805,15 @@ export class AppMessagesManager {
// this.log('pdata', randomID, pendingData)
if(pendingData) {
const {peerId, tempId, storage} = pendingData;
const historyStorage = this.getHistoryStorage(peerId);
const {peerId, tempId, threadId, storage} = pendingData;
[this.getHistoryStorage(peerId), threadId ? this.getHistoryStorage(peerId, threadId) : undefined]
.filter(Boolean)
.forEach(storage => {
storage.history.delete(tempId);
});
// this.log('pending', randomID, historyStorage.pending)
historyStorage.history.delete(tempId);
const message = this.getMessageFromStorage(storage, tempId);
if(!message.deleted) {
@ -5322,11 +5393,8 @@ export class AppMessagesManager { @@ -5322,11 +5393,8 @@ export class AppMessagesManager {
delete storage[mid];
const peerMessagesToHandle = this.newMessagesToHandle[peerId];
if(peerMessagesToHandle && peerMessagesToHandle.length) {
const peerMessagesHandlePos = peerMessagesToHandle.indexOf(mid);
if(peerMessagesHandlePos !== -1) {
peerMessagesToHandle.splice(peerMessagesHandlePos);
}
if(peerMessagesToHandle && peerMessagesToHandle.has(mid)) {
peerMessagesToHandle.delete(mid);
}
}

10
src/lib/rootScope.ts

@ -112,7 +112,7 @@ export type BroadcastEvents = { @@ -112,7 +112,7 @@ export type BroadcastEvents = {
'language_change': void,
};
class RootScope extends EventListenerBase<any> {
export class RootScope extends EventListenerBase<any> {
private _overlayIsActive: boolean = false;
public myId = 0;
public idle = {
@ -169,3 +169,11 @@ class RootScope extends EventListenerBase<any> { @@ -169,3 +169,11 @@ class RootScope extends EventListenerBase<any> {
const rootScope = new RootScope();
MOUNT_CLASS_TO.rootScope = rootScope;
export default rootScope;
rootScope.addEventListener('album_edit', (e) => {
});
rootScope.addEventListener<'album_edit'>('album_edit', (e) => {
});

13
src/scripts/in/schema_additional_params.json

@ -214,4 +214,17 @@ @@ -214,4 +214,17 @@
{"name": "local", "type": "boolean"},
{"name": "appVersion", "type": "string"}
]
}, {
"predicate": "updateNewDiscussionMessage",
"params": [
{"name": "message", "type": "Message"}
],
"type": "Update"
}, {
"predicate": "updateDeleteDiscussionMessages",
"params": [
{"name": "messages", "type": "number[]"},
{"name": "channel_id", "type": "number"}
],
"type": "Update"
}]

3
src/scss/partials/_checkbox.scss

@ -98,7 +98,8 @@ @@ -98,7 +98,8 @@
padding-left: 3.3125rem;
cursor: pointer;
display: inline-block;
height: 24px;
min-height: 24px;
margin-top: 1px;
line-height: 26px;
user-select: none;
transition: .2s opacity;

8
src/scss/partials/_leftSidebar.scss

@ -893,6 +893,14 @@ @@ -893,6 +893,14 @@
.general-settings-container {
user-select: none;
.sidebar-left-section {
padding-bottom: 0;
}
.sidebar-left-section:last-child {
padding-bottom: .5rem;
}
}
.two-step-verification {

6
src/scss/partials/_profile.scss

@ -174,6 +174,12 @@ @@ -174,6 +174,12 @@
top: -12px;
}
} */
&.search-empty {
.gradient-delimiter {
display: none;
}
}
}
&-container {

3
src/scss/partials/_rightSidebar.scss

@ -301,7 +301,8 @@ @@ -301,7 +301,8 @@
.preloader {
padding: 0;
position: absolute !important;
height: 100%;
top: 100px;
transform: translate(-50%);
> svg {
height: 50px;

Loading…
Cancel
Save