Update replies footer
This commit is contained in:
parent
b9d6f916a4
commit
18debfb4a6
@ -1,7 +1,7 @@
|
|||||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||||
import appProfileManager from "../lib/appManagers/appProfileManager";
|
import appProfileManager from "../lib/appManagers/appProfileManager";
|
||||||
import rootScope from "../lib/rootScope";
|
import rootScope from "../lib/rootScope";
|
||||||
import { cancelEvent } from "../helpers/dom";
|
import { attachClickEvent, cancelEvent } from "../helpers/dom";
|
||||||
import AppMediaViewer, { AppMediaViewerAvatar } from "./appMediaViewer";
|
import AppMediaViewer, { AppMediaViewerAvatar } from "./appMediaViewer";
|
||||||
import { Photo } from "../layer";
|
import { Photo } from "../layer";
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ export default class AvatarElement extends HTMLElement {
|
|||||||
if(this.getAttribute('clickable') === '') {
|
if(this.getAttribute('clickable') === '') {
|
||||||
this.setAttribute('clickable', 'set');
|
this.setAttribute('clickable', 'set');
|
||||||
let loading = false;
|
let loading = false;
|
||||||
this.addEventListener('click', async(e) => {
|
attachClickEvent(this, async(e) => {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
if(loading) return;
|
if(loading) return;
|
||||||
//console.log('avatar clicked');
|
//console.log('avatar clicked');
|
||||||
@ -120,13 +120,6 @@ export default class AvatarElement extends HTMLElement {
|
|||||||
public update() {
|
public update() {
|
||||||
appProfileManager.putPhoto(this, this.peerId, this.isDialog, this.peerTitle);
|
appProfileManager.putPhoto(this, this.peerId, this.isDialog, this.peerTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
adoptedCallback() {
|
|
||||||
// вызывается, когда элемент перемещается в новый документ
|
|
||||||
// (происходит в document.adoptNode, используется очень редко)
|
|
||||||
}
|
|
||||||
|
|
||||||
// у элемента могут быть ещё другие методы и свойства
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("avatar-element", AvatarElement);
|
customElements.define("avatar-element", AvatarElement);
|
@ -38,6 +38,7 @@ import ListenerSetter from "../../helpers/listenerSetter";
|
|||||||
import PollElement from "../poll";
|
import PollElement from "../poll";
|
||||||
import AudioElement from "../audio";
|
import AudioElement from "../audio";
|
||||||
import { MessageEntity, MessageReplies, MessageReplyHeader } from "../../layer";
|
import { MessageEntity, MessageReplies, MessageReplyHeader } from "../../layer";
|
||||||
|
import { DEBUG, MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
|
||||||
|
|
||||||
const IGNORE_ACTIONS = ['messageActionHistoryClear'];
|
const IGNORE_ACTIONS = ['messageActionHistoryClear'];
|
||||||
|
|
||||||
@ -315,6 +316,17 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
this.listenerSetter.add(this.bubblesContainer, 'click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
this.listenerSetter.add(this.bubblesContainer, 'click', this.onBubblesClick/* , {capture: true, passive: false} */);
|
||||||
|
|
||||||
|
if(DEBUG) {
|
||||||
|
this.listenerSetter.add(this.bubblesContainer, 'dblclick', (e) => {
|
||||||
|
const bubble = findUpClassName(e.target, 'grouped-item') || findUpClassName(e.target, 'bubble');
|
||||||
|
if(bubble) {
|
||||||
|
const mid = +bubble.dataset.mid;
|
||||||
|
this.log('debug message:', this.chat.getMessage(mid));
|
||||||
|
this.chat.bubbles.highlightBubble(bubble);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
||||||
for(const timestamp in this.dateMessages) {
|
for(const timestamp in this.dateMessages) {
|
||||||
const dateMessage = this.dateMessages[timestamp];
|
const dateMessage = this.dateMessages[timestamp];
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
import { getFullDate } from "../../helpers/date";
|
import { getFullDate } from "../../helpers/date";
|
||||||
import { formatNumber } from "../../helpers/number";
|
import { formatNumber } from "../../helpers/number";
|
||||||
import { MessageReplies } from "../../layer";
|
import { Message } from "../../layer";
|
||||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||||
import RichTextProcessor from "../../lib/richtextprocessor";
|
import RichTextProcessor from "../../lib/richtextprocessor";
|
||||||
|
import rootScope from "../../lib/rootScope";
|
||||||
import { ripple } from "../ripple";
|
import { ripple } from "../ripple";
|
||||||
import Chat from "./chat";
|
import Chat from "./chat";
|
||||||
|
|
||||||
type Message = any;
|
|
||||||
|
|
||||||
export namespace MessageRender {
|
export namespace MessageRender {
|
||||||
/* export const setText = () => {
|
/* export const setText = () => {
|
||||||
|
|
||||||
}; */
|
}; */
|
||||||
|
|
||||||
export const setTime = (chat: Chat, message: Message, bubble: HTMLElement, bubbleContainer: HTMLElement, messageDiv: HTMLElement) => {
|
export const setTime = (chat: Chat, message: any, bubble: HTMLElement, bubbleContainer: HTMLElement, messageDiv: HTMLElement) => {
|
||||||
const date = new Date(message.date * 1000);
|
const date = new Date(message.date * 1000);
|
||||||
let time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
|
let time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||||
|
|
||||||
@ -69,50 +68,87 @@ export namespace MessageRender {
|
|||||||
message: any,
|
message: any,
|
||||||
messageDiv: HTMLElement
|
messageDiv: HTMLElement
|
||||||
}) => {
|
}) => {
|
||||||
const replies = message.replies as MessageReplies;
|
|
||||||
const isFooter = !bubble.classList.contains('sticker') && !bubble.classList.contains('emoji-big');
|
const isFooter = !bubble.classList.contains('sticker') && !bubble.classList.contains('emoji-big');
|
||||||
|
const repliesFooter = new RepliesFooterElement();
|
||||||
|
|
||||||
if(isFooter) {
|
if(isFooter) {
|
||||||
const container = document.createElement('div');
|
repliesFooter.message = message;
|
||||||
container.classList.add('replies-footer');
|
repliesFooter.type = 'footer';
|
||||||
|
bubbleContainer.prepend(repliesFooter);
|
||||||
let leftHTML = '', lastStyle = '';
|
|
||||||
if(replies?.recent_repliers) {
|
|
||||||
leftHTML += '<div class="replies-footer-avatars">'
|
|
||||||
/**
|
|
||||||
* MACOS, ANDROID - без реверса
|
|
||||||
* WINDOWS DESKTOP - реверс
|
|
||||||
* все приложения накладывают аватарку первую на вторую, а в макете зато вторая на первую, ЛОЛ!
|
|
||||||
*/
|
|
||||||
let l: string[] = [];
|
|
||||||
replies.recent_repliers/* .slice().reverse() */.forEach((peer, idx) => {
|
|
||||||
lastStyle = idx == 0 ? '' : `style="transform: translateX(-${idx * 12}px);"`;
|
|
||||||
l.push(`<avatar-element class="avatar-32" dialog="0" peer="${appPeersManager.getPeerId(peer)}" ${lastStyle}></avatar-element>`);
|
|
||||||
});
|
|
||||||
leftHTML += l.reverse().join('') + '</div>';
|
|
||||||
} else {
|
|
||||||
leftHTML = '<span class="tgico-comments"></span>';
|
|
||||||
}
|
|
||||||
|
|
||||||
let text: string;
|
|
||||||
if(replies?.replies) {
|
|
||||||
text = replies.replies + ' ' + (replies.replies > 1 ? 'Comments' : 'Comment');
|
|
||||||
} else {
|
|
||||||
text = 'Leave a Comment';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(replies) {
|
|
||||||
const historyStorage = appMessagesManager.getHistoryStorage(-replies.channel_id);
|
|
||||||
if(replies.read_max_id < replies.max_id && (!historyStorage.readMaxId || historyStorage.readMaxId < replies.max_id)) {
|
|
||||||
container.classList.add('is-unread');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.innerHTML = `${leftHTML}<span class="replies-footer-text" ${lastStyle}>${text}</span><span class="tgico-next"></span>`;
|
|
||||||
|
|
||||||
const rippleContainer = document.createElement('div');
|
|
||||||
container.append(rippleContainer);
|
|
||||||
ripple(rippleContainer);
|
|
||||||
bubbleContainer.prepend(container);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootScope.on('replies_updated', (e) => {
|
||||||
|
const message = e.detail;
|
||||||
|
(Array.from(document.querySelectorAll(`replies-footer-element[data-post-key="${message.peerId}_${message.mid}"]`)) as RepliesFooterElement[]).forEach(element => {
|
||||||
|
element.message = message;
|
||||||
|
element.render();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
class RepliesFooterElement extends HTMLElement {
|
||||||
|
public message: Message.message;
|
||||||
|
public type: 'footer' | 'beside';
|
||||||
|
|
||||||
|
private updated = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.classList.add('replies-footer');
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.render();
|
||||||
|
this.dataset.postKey = this.message.peerId + '_' + this.message.mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const replies = this.message.replies;
|
||||||
|
|
||||||
|
let leftHTML = '', lastStyle = '';
|
||||||
|
if(replies.recent_repliers) {
|
||||||
|
leftHTML += '<div class="replies-footer-avatars">'
|
||||||
|
/**
|
||||||
|
* MACOS, ANDROID - без реверса
|
||||||
|
* WINDOWS DESKTOP - реверс
|
||||||
|
* все приложения накладывают аватарку первую на вторую, а в макете зато вторая на первую, ЛОЛ!
|
||||||
|
*/
|
||||||
|
let l: string[] = [];
|
||||||
|
replies.recent_repliers/* .slice().reverse() */.forEach((peer, idx) => {
|
||||||
|
lastStyle = idx == 0 ? '' : `style="transform: translateX(-${idx * 12}px);"`;
|
||||||
|
l.push(`<avatar-element class="avatar-32" dialog="0" peer="${appPeersManager.getPeerId(peer)}" ${lastStyle}></avatar-element>`);
|
||||||
|
});
|
||||||
|
leftHTML += l.reverse().join('') + '</div>';
|
||||||
|
} else {
|
||||||
|
leftHTML = '<span class="tgico-comments"></span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
let text: string;
|
||||||
|
if(replies.replies) {
|
||||||
|
text = replies.replies + ' ' + (replies.replies > 1 ? 'Comments' : 'Comment');
|
||||||
|
} else {
|
||||||
|
text = 'Leave a Comment';
|
||||||
|
}
|
||||||
|
|
||||||
|
const historyStorage = appMessagesManager.getHistoryStorage(-replies.channel_id);
|
||||||
|
if(replies.read_max_id < replies.max_id && (!historyStorage.readMaxId || historyStorage.readMaxId < replies.max_id)) {
|
||||||
|
this.classList.add('is-unread');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.updated) {
|
||||||
|
appMessagesManager.subscribeRepliesThread(this.message.peerId, this.message.mid);
|
||||||
|
appMessagesManager.updateMessage(this.message.peerId, this.message.mid, 'replies_updated');
|
||||||
|
this.updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.innerHTML = `${leftHTML}<span class="replies-footer-text" ${lastStyle}>${text}</span><span class="tgico-next"></span>`;
|
||||||
|
|
||||||
|
const rippleContainer = document.createElement('div');
|
||||||
|
this.append(rippleContainer);
|
||||||
|
ripple(rippleContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('replies-footer-element', RepliesFooterElement);
|
@ -7,7 +7,7 @@ import PinnedContainer from "./pinnedContainer";
|
|||||||
import PinnedMessageBorder from "./pinnedMessageBorder";
|
import PinnedMessageBorder from "./pinnedMessageBorder";
|
||||||
import ReplyContainer, { wrapReplyDivAndCaption } from "./replyContainer";
|
import ReplyContainer, { wrapReplyDivAndCaption } from "./replyContainer";
|
||||||
import rootScope from "../../lib/rootScope";
|
import rootScope from "../../lib/rootScope";
|
||||||
import { cancelEvent, findUpClassName, getElementByPoint, handleScrollSideEvent } from "../../helpers/dom";
|
import { attachClickEvent, cancelEvent, findUpClassName, getElementByPoint, handleScrollSideEvent } from "../../helpers/dom";
|
||||||
import Chat from "./chat";
|
import Chat from "./chat";
|
||||||
import ListenerSetter from "../../helpers/listenerSetter";
|
import ListenerSetter from "../../helpers/listenerSetter";
|
||||||
import ButtonIcon from "../buttonIcon";
|
import ButtonIcon from "../buttonIcon";
|
||||||
@ -271,10 +271,10 @@ export default class ChatPinnedMessage {
|
|||||||
this.btnOpen = ButtonIcon('pinlist pinned-container-close pinned-message-pinlist', {noRipple: true});
|
this.btnOpen = ButtonIcon('pinlist pinned-container-close pinned-message-pinlist', {noRipple: true});
|
||||||
this.pinnedMessageContainer.divAndCaption.container.prepend(this.btnOpen);
|
this.pinnedMessageContainer.divAndCaption.container.prepend(this.btnOpen);
|
||||||
|
|
||||||
this.listenerSetter.add(this.btnOpen, 'click', (e) => {
|
attachClickEvent(this.btnOpen, (e) => {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
this.topbar.openPinned(true);
|
this.topbar.openPinned(true);
|
||||||
});
|
}, {listenerSetter: this.listenerSetter});
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope, 'peer_pinned_messages', (e) => {
|
this.listenerSetter.add(rootScope, 'peer_pinned_messages', (e) => {
|
||||||
const peerId = e.detail.peerId;
|
const peerId = e.detail.peerId;
|
||||||
|
@ -904,7 +904,9 @@ export default class AppSharedMediaTab implements SliderTab {
|
|||||||
setText(appPeersManager.getPeerUsername(peerId), this.profileElements.username);
|
setText(appPeersManager.getPeerUsername(peerId), this.profileElements.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.profileElements.notificationsCheckbox.checked = !appMessagesManager.isPeerMuted(peerId);
|
const muted = appMessagesManager.isPeerMuted(peerId);
|
||||||
|
this.profileElements.notificationsCheckbox.checked = !muted;
|
||||||
|
this.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
||||||
} else {
|
} else {
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
this.profileElements.notificationsRow.style.display = 'none';
|
this.profileElements.notificationsRow.style.display = 'none';
|
||||||
|
@ -19,7 +19,7 @@ import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
|||||||
import appPeersManager from './appPeersManager';
|
import appPeersManager from './appPeersManager';
|
||||||
import appStateManager from "./appStateManager";
|
import appStateManager from "./appStateManager";
|
||||||
import appUsersManager, { User } from "./appUsersManager";
|
import appUsersManager, { User } from "./appUsersManager";
|
||||||
import { App, MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
import { App, DEBUG, MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
||||||
import Button from "../../components/button";
|
import Button from "../../components/button";
|
||||||
import SetTransition from "../../components/singleTransition";
|
import SetTransition from "../../components/singleTransition";
|
||||||
import AppStorage from '../storage';
|
import AppStorage from '../storage';
|
||||||
@ -877,6 +877,16 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
}, {capture: true});
|
}, {capture: true});
|
||||||
|
|
||||||
|
if(DEBUG) {
|
||||||
|
list.addEventListener('dblclick', (e) => {
|
||||||
|
const li = findUpTag(e.target, 'LI');
|
||||||
|
if(li) {
|
||||||
|
const peerId = +li.getAttribute('data-peerId');
|
||||||
|
this.log('debug dialog:', appMessagesManager.getDialogByPeerId(peerId));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(withContext) {
|
if(withContext) {
|
||||||
attachContextMenuListener(list, this.contextMenu.onContextMenu);
|
attachContextMenuListener(list, this.contextMenu.onContextMenu);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { tsNow } from "../../helpers/date";
|
|||||||
import { copy, defineNotNumerableProperties, getObjectKeysAndSort } from "../../helpers/object";
|
import { copy, defineNotNumerableProperties, getObjectKeysAndSort } from "../../helpers/object";
|
||||||
import { randomLong } from "../../helpers/random";
|
import { randomLong } from "../../helpers/random";
|
||||||
import { splitStringByLength, limitSymbols } from "../../helpers/string";
|
import { splitStringByLength, limitSymbols } from "../../helpers/string";
|
||||||
import { Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputNotifyPeer, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PhotoSize, SendMessageAction, Update } from "../../layer";
|
import { Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputNotifyPeer, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PhotoSize, SendMessageAction, Update } from "../../layer";
|
||||||
import { InvokeApiOptions } from "../../types";
|
import { InvokeApiOptions } from "../../types";
|
||||||
import { langPack } from "../langPack";
|
import { langPack } from "../langPack";
|
||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
@ -110,6 +110,10 @@ export class AppMessagesManager {
|
|||||||
} = {};
|
} = {};
|
||||||
public pinnedMessages: {[peerId: string]: PinnedStorage} = {};
|
public pinnedMessages: {[peerId: string]: PinnedStorage} = {};
|
||||||
|
|
||||||
|
public threadsToReplies: {
|
||||||
|
[peerId_threadId: string]: string;
|
||||||
|
} = {};
|
||||||
|
|
||||||
public pendingByRandomId: {
|
public pendingByRandomId: {
|
||||||
[randomId: string]: {
|
[randomId: string]: {
|
||||||
peerId: number,
|
peerId: number,
|
||||||
@ -2399,7 +2403,7 @@ export class AppMessagesManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public markDialogUnread(peerId: number, read?: boolean) {
|
public markDialogUnread(peerId: number, read?: true) {
|
||||||
const dialog = this.getDialogByPeerId(peerId)[0];
|
const dialog = this.getDialogByPeerId(peerId)[0];
|
||||||
if(!dialog) return Promise.reject();
|
if(!dialog) return Promise.reject();
|
||||||
|
|
||||||
@ -3022,6 +3026,15 @@ export class AppMessagesManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public subscribeRepliesThread(peerId: number, mid: number) {
|
||||||
|
const repliesKey = peerId + '_' + mid;
|
||||||
|
for(const threadKey in this.threadsToReplies) {
|
||||||
|
if(this.threadsToReplies[threadKey] === repliesKey) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getDiscussionMessage(peerId, mid);
|
||||||
|
}
|
||||||
|
|
||||||
public getDiscussionMessage(peerId: number, mid: number) {
|
public getDiscussionMessage(peerId: number, mid: number) {
|
||||||
return apiManager.invokeApi('messages.getDiscussionMessage', {
|
return apiManager.invokeApi('messages.getDiscussionMessage', {
|
||||||
peer: appPeersManager.getInputPeerById(peerId),
|
peer: appPeersManager.getInputPeerById(peerId),
|
||||||
@ -3037,6 +3050,8 @@ export class AppMessagesManager {
|
|||||||
result.read_inbox_max_id = historyStorage.readMaxId = this.generateMessageId(result.read_inbox_max_id) || 0;
|
result.read_inbox_max_id = historyStorage.readMaxId = this.generateMessageId(result.read_inbox_max_id) || 0;
|
||||||
result.read_outbox_max_id = historyStorage.readOutboxMaxId = this.generateMessageId(result.read_outbox_max_id) || 0;
|
result.read_outbox_max_id = historyStorage.readOutboxMaxId = this.generateMessageId(result.read_outbox_max_id) || 0;
|
||||||
|
|
||||||
|
this.threadsToReplies[message.peerId + '_' + message.mid] = peerId + '_' + mid;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3315,11 +3330,10 @@ export class AppMessagesManager {
|
|||||||
// this.log.warn(dT(), 'message unread', message.mid, message.pFlags.unread)
|
// this.log.warn(dT(), 'message unread', message.mid, message.pFlags.unread)
|
||||||
|
|
||||||
const pendingMessage = this.checkPendingMessage(message);
|
const pendingMessage = this.checkPendingMessage(message);
|
||||||
|
|
||||||
const historyStorage = this.getHistoryStorage(peerId);
|
const historyStorage = this.getHistoryStorage(peerId);
|
||||||
|
|
||||||
const history = message.mid > 0 ? historyStorage.history : historyStorage.pending;
|
const history = message.mid > 0 ? historyStorage.history : historyStorage.pending;
|
||||||
if(history.indexOf(message.mid) != -1) {
|
if(history.indexOf(message.mid) !== -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const topMsgId = history[0];
|
const topMsgId = history[0];
|
||||||
@ -3338,8 +3352,8 @@ export class AppMessagesManager {
|
|||||||
rootScope.broadcast('history_reply_markup', {peerId});
|
rootScope.broadcast('history_reply_markup', {peerId});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!message.pFlags.out && message.from_id) {
|
if(message.fromId > 0 && !message.pFlags.out && message.from_id) {
|
||||||
appUsersManager.forceUserOnline(appPeersManager.getPeerId(message.from_id), message.date);
|
appUsersManager.forceUserOnline(message.fromId, message.date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!pendingMessage) {
|
if(!pendingMessage) {
|
||||||
@ -3352,6 +3366,8 @@ export class AppMessagesManager {
|
|||||||
this.newMessagesHandlePromise = window.setTimeout(this.handleNewMessages, 0);
|
this.newMessagesHandlePromise = window.setTimeout(this.handleNewMessages, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.updateMessageRepliesIfNeeded(message);
|
||||||
|
|
||||||
const dialog = foundDialog[0];
|
const dialog = foundDialog[0];
|
||||||
if(dialog) {
|
if(dialog) {
|
||||||
@ -3950,6 +3966,37 @@ 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 repliesKey = this.threadsToReplies[threadKey];
|
||||||
|
if(repliesKey) {
|
||||||
|
const [peerId, mid] = repliesKey.split('_').map(n => +n);
|
||||||
|
|
||||||
|
this.updateMessage(peerId, mid, 'replies_updated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
this.log.error('incrementMessageReplies err', err, threadMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(broadcastEventName) {
|
||||||
|
rootScope.broadcast(broadcastEventName, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
private checkPendingMessage(message: any) {
|
private checkPendingMessage(message: any) {
|
||||||
const randomId = this.pendingByMessageId[message.mid];
|
const randomId = this.pendingByMessageId[message.mid];
|
||||||
let pendingMessage: any;
|
let pendingMessage: any;
|
||||||
@ -4474,7 +4521,7 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
Promise.all(promises).finally(() => {
|
Promise.all(promises).finally(() => {
|
||||||
this.fetchSingleMessagesPromise = null;
|
this.fetchSingleMessagesPromise = null;
|
||||||
if(this.needSingleMessages.length) this.fetchSingleMessages();
|
if(Object.keys(this.needSingleMessages).length) this.fetchSingleMessages();
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
@ -4482,10 +4529,10 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public wrapSingleMessage(peerId: number, msgId: number, overwrite = false): Promise<void> {
|
public wrapSingleMessage(peerId: number, msgId: number, overwrite = false): Promise<void> {
|
||||||
if(this.getMessagesStorage(peerId)[msgId] && !overwrite) {
|
if(!this.getMessageByPeer(peerId, msgId).deleted && !overwrite) {
|
||||||
rootScope.broadcast('messages_downloaded', {peerId, mids: [msgId]});
|
rootScope.broadcast('messages_downloaded', {peerId, mids: [msgId]});
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else if(!this.needSingleMessages[peerId] || this.needSingleMessages[peerId].indexOf(msgId) == -1) {
|
} else if(!this.needSingleMessages[peerId] || this.needSingleMessages[peerId].indexOf(msgId) === -1) {
|
||||||
(this.needSingleMessages[peerId] ?? (this.needSingleMessages[peerId] = [])).push(msgId);
|
(this.needSingleMessages[peerId] ?? (this.needSingleMessages[peerId] = [])).push(msgId);
|
||||||
return this.fetchSingleMessages();
|
return this.fetchSingleMessages();
|
||||||
} else if(this.fetchSingleMessagesPromise) {
|
} else if(this.fetchSingleMessagesPromise) {
|
||||||
@ -4531,6 +4578,8 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.updateMessageRepliesIfNeeded(message);
|
||||||
|
|
||||||
if(!message.pFlags.out && message.pFlags.unread) {
|
if(!message.pFlags.out && message.pFlags.unread) {
|
||||||
history.unread++;
|
history.unread++;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { StickerSet, Update } from "../layer";
|
import type { Message, StickerSet, Update } from "../layer";
|
||||||
import type { MyDocument } from "./appManagers/appDocsManager";
|
import type { MyDocument } from "./appManagers/appDocsManager";
|
||||||
import type { AppMessagesManager, Dialog, MessagesStorage } from "./appManagers/appMessagesManager";
|
import type { AppMessagesManager, Dialog, MessagesStorage } from "./appManagers/appMessagesManager";
|
||||||
import type { Poll, PollResults } from "./appManagers/appPollsManager";
|
import type { Poll, PollResults } from "./appManagers/appPollsManager";
|
||||||
@ -46,6 +46,8 @@ type BroadcastEvents = {
|
|||||||
'messages_downloaded': {peerId: number, mids: number[]},
|
'messages_downloaded': {peerId: number, mids: number[]},
|
||||||
'messages_media_read': {peerId: number, mids: number[]},
|
'messages_media_read': {peerId: number, mids: number[]},
|
||||||
|
|
||||||
|
'replies_updated': Message.message,
|
||||||
|
|
||||||
'scheduled_new': {peerId: number, mid: number},
|
'scheduled_new': {peerId: number, mid: number},
|
||||||
'scheduled_delete': {peerId: number, mids: number[]},
|
'scheduled_delete': {peerId: number, mids: number[]},
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user