Browser History: Fix opening chat from Left Search (#1869)
This commit is contained in:
parent
e4b2b0911f
commit
c333f31f02
@ -62,7 +62,7 @@ const ChatMessage: FC<OwnProps & StateProps> = ({
|
|||||||
const isRoundVideo = Boolean(getMessageRoundVideo(message));
|
const isRoundVideo = Boolean(getMessageRoundVideo(message));
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
focusMessage({ chatId, messageId: message.id });
|
focusMessage({ chatId, messageId: message.id, shouldReplaceHistory: true });
|
||||||
}, [chatId, focusMessage, message.id]);
|
}, [chatId, focusMessage, message.id]);
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|||||||
@ -48,6 +48,7 @@ let isAlteringHistory = false;
|
|||||||
// Unfortunately Safari doesn't really like when there's 2+ consequent history operations in one frame, so we need
|
// Unfortunately Safari doesn't really like when there's 2+ consequent history operations in one frame, so we need
|
||||||
// to delay them to the next raf
|
// to delay them to the next raf
|
||||||
let deferredHistoryOperations: HistoryOperation[] = [];
|
let deferredHistoryOperations: HistoryOperation[] = [];
|
||||||
|
let deferredPopstateOperations: HistoryOperationState[] = [];
|
||||||
let isSafariGestureAnimation = false;
|
let isSafariGestureAnimation = false;
|
||||||
|
|
||||||
// Do not remove: used for history unit tests
|
// Do not remove: used for history unit tests
|
||||||
@ -84,13 +85,25 @@ function applyDeferredHistoryOperations() {
|
|||||||
const goOperations = deferredHistoryOperations.filter((op) => op.type === 'go') as HistoryOperationGo[];
|
const goOperations = deferredHistoryOperations.filter((op) => op.type === 'go') as HistoryOperationGo[];
|
||||||
const stateOperations = deferredHistoryOperations.filter((op) => op.type !== 'go') as HistoryOperationState[];
|
const stateOperations = deferredHistoryOperations.filter((op) => op.type !== 'go') as HistoryOperationState[];
|
||||||
const goCount = goOperations.reduce((acc, op) => acc + op.delta, 0);
|
const goCount = goOperations.reduce((acc, op) => acc + op.delta, 0);
|
||||||
if (goCount) {
|
|
||||||
window.history.go(goCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
stateOperations.forEach((op) => window.history[op.type](op.data, '', op.hash));
|
|
||||||
|
|
||||||
deferredHistoryOperations = [];
|
deferredHistoryOperations = [];
|
||||||
|
|
||||||
|
if (goCount) {
|
||||||
|
window.history.go(goCount);
|
||||||
|
|
||||||
|
// If we have some `state` operations after the `go` operations, we need to wait until the popstate event
|
||||||
|
// so the order of operations is correctly preserved
|
||||||
|
if (stateOperations.length) {
|
||||||
|
deferredPopstateOperations.push(...stateOperations);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processStateOperations(stateOperations);
|
||||||
|
}
|
||||||
|
|
||||||
|
function processStateOperations(stateOperations: HistoryOperationState[]) {
|
||||||
|
stateOperations.forEach((op) => window.history[op.type](op.data, '', op.hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
function deferHistoryOperation(historyOperation: HistoryOperation) {
|
function deferHistoryOperation(historyOperation: HistoryOperation) {
|
||||||
@ -145,6 +158,10 @@ function cleanupTrashedState() {
|
|||||||
window.addEventListener('popstate', ({ state }: PopStateEvent) => {
|
window.addEventListener('popstate', ({ state }: PopStateEvent) => {
|
||||||
if (isAlteringHistory) {
|
if (isAlteringHistory) {
|
||||||
isAlteringHistory = false;
|
isAlteringHistory = false;
|
||||||
|
if (deferredPopstateOperations.length) {
|
||||||
|
processStateOperations(deferredPopstateOperations);
|
||||||
|
deferredPopstateOperations = [];
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import BigInt from 'big-integer';
|
import BigInt from 'big-integer';
|
||||||
import { UpdateConnectionState } from '../network';
|
import { UpdateConnectionState } from '../network';
|
||||||
import Request from '../tl/api';
|
import Api from '../tl/api';
|
||||||
import { Api as GramJs } from '..';
|
|
||||||
|
|
||||||
type Peer = {
|
type Peer = {
|
||||||
peer: GramJs.Chat | GramJs.Channel | GramJs.User;
|
peer: Api.Chat | Api.Channel | Api.User;
|
||||||
TEST_messages: GramJs.Message[];
|
inputPeer: Api.TypePeer;
|
||||||
TEST_sendMessage: (data: CreateMessageParams) => GramJs.Message | undefined;
|
TEST_messages: Api.Message[];
|
||||||
|
TEST_sendMessage: (data: CreateMessageParams) => Api.Message | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CreateMessageParams = {
|
type CreateMessageParams = {
|
||||||
fromId?: any;
|
fromId?: any;
|
||||||
repliesChannelId?: any;
|
repliesChannelId?: any;
|
||||||
replyingTo?: GramJs.MessageReplyHeader;
|
replyingTo?: Api.MessageReplyHeader;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TelegramClient {
|
class TelegramClient {
|
||||||
@ -24,7 +24,7 @@ class TelegramClient {
|
|||||||
|
|
||||||
private peers: Peer[] = [];
|
private peers: Peer[] = [];
|
||||||
|
|
||||||
private dialogs: GramJs.Dialog[] = [];
|
private dialogs: Api.Dialog[] = [];
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
}
|
}
|
||||||
@ -57,12 +57,12 @@ class TelegramClient {
|
|||||||
const { id } = discussion.TEST_sendMessage({})!;
|
const { id } = discussion.TEST_sendMessage({})!;
|
||||||
|
|
||||||
discussion.TEST_sendMessage({
|
discussion.TEST_sendMessage({
|
||||||
fromId: new GramJs.PeerUser({
|
fromId: new Api.PeerUser({
|
||||||
userId: user.peer.id,
|
userId: user.peer.id,
|
||||||
}),
|
}),
|
||||||
replyingTo: new GramJs.MessageReplyHeader({
|
replyingTo: new Api.MessageReplyHeader({
|
||||||
replyToMsgId: id,
|
replyToMsgId: id,
|
||||||
replyToPeerId: new GramJs.PeerChannel({
|
replyToPeerId: new Api.PeerChannel({
|
||||||
channelId: channel.peer.id,
|
channelId: channel.peer.id,
|
||||||
}),
|
}),
|
||||||
replyToTopId: message!.id,
|
replyToTopId: message!.id,
|
||||||
@ -70,8 +70,8 @@ class TelegramClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createDialog(peer: GramJs.TypePeer) {
|
createDialog(peer: Api.TypePeer) {
|
||||||
return new GramJs.Dialog({
|
return new Api.Dialog({
|
||||||
peer,
|
peer,
|
||||||
topMessage: 0,
|
topMessage: 0,
|
||||||
readInboxMaxId: 0,
|
readInboxMaxId: 0,
|
||||||
@ -79,11 +79,11 @@ class TelegramClient {
|
|||||||
unreadCount: 0,
|
unreadCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
unreadReactionsCount: 0,
|
unreadReactionsCount: 0,
|
||||||
notifySettings: new GramJs.PeerNotifySettings({}),
|
notifySettings: new Api.PeerNotifySettings({}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createMessage(peer: GramJs.TypePeer) {
|
createMessage(peer: Api.TypePeer) {
|
||||||
return ({
|
return ({
|
||||||
fromId,
|
fromId,
|
||||||
repliesChannelId,
|
repliesChannelId,
|
||||||
@ -93,18 +93,18 @@ class TelegramClient {
|
|||||||
const p = this.getPeer(peer);
|
const p = this.getPeer(peer);
|
||||||
if (!p || pi === undefined) return undefined;
|
if (!p || pi === undefined) return undefined;
|
||||||
|
|
||||||
const message = new GramJs.Message({
|
const message = new Api.Message({
|
||||||
id: p.TEST_messages.length + 1,
|
id: p.TEST_messages.length + 1,
|
||||||
fromId,
|
fromId,
|
||||||
peerId: peer,
|
peerId: peer,
|
||||||
date: Number(new Date()) / 1000 + pi * 60,
|
date: Number(new Date()) / 1000 + pi * 60,
|
||||||
message: 'lol @channel',
|
message: 'lol @channel',
|
||||||
entities: [new GramJs.MessageEntityMention({
|
entities: [new Api.MessageEntityMention({
|
||||||
offset: 4,
|
offset: 4,
|
||||||
length: 8,
|
length: 8,
|
||||||
})],
|
})],
|
||||||
replyTo: replyingTo,
|
replyTo: replyingTo,
|
||||||
replies: new GramJs.MessageReplies({
|
replies: new Api.MessageReplies({
|
||||||
comments: true,
|
comments: true,
|
||||||
replies: 0,
|
replies: 0,
|
||||||
repliesPts: 0,
|
repliesPts: 0,
|
||||||
@ -117,22 +117,24 @@ class TelegramClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createChat() {
|
createChat() {
|
||||||
const chat = new GramJs.Chat({
|
const chat = new Api.Chat({
|
||||||
id: BigInt(this.lastId++),
|
id: BigInt(this.lastId++),
|
||||||
title: 'Some chat',
|
title: 'Some chat',
|
||||||
photo: new GramJs.ChatPhotoEmpty(),
|
photo: new Api.ChatPhotoEmpty(),
|
||||||
participantsCount: 1,
|
participantsCount: 1,
|
||||||
date: 1000,
|
date: 1000,
|
||||||
version: 1,
|
version: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const peerChat = new GramJs.PeerChat({
|
const peerChat = new Api.PeerChat({
|
||||||
chatId: chat.id,
|
chatId: chat.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogs.push(this.createDialog(peerChat));
|
this.dialogs.push(this.createDialog(peerChat));
|
||||||
|
|
||||||
const testChat: Peer = { peer: chat, TEST_messages: [], TEST_sendMessage: this.createMessage(peerChat) };
|
const testChat: Peer = {
|
||||||
|
peer: chat, inputPeer: peerChat, TEST_messages: [], TEST_sendMessage: this.createMessage(peerChat),
|
||||||
|
};
|
||||||
|
|
||||||
this.peers.push(testChat);
|
this.peers.push(testChat);
|
||||||
|
|
||||||
@ -144,24 +146,26 @@ class TelegramClient {
|
|||||||
username: string;
|
username: string;
|
||||||
isMegagroup?: boolean;
|
isMegagroup?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const channel = new GramJs.Channel({
|
const channel = new Api.Channel({
|
||||||
username,
|
username,
|
||||||
id: BigInt(this.lastId++),
|
id: BigInt(this.lastId++),
|
||||||
megagroup: isMegagroup ? true : undefined,
|
megagroup: isMegagroup ? true : undefined,
|
||||||
title,
|
title,
|
||||||
photo: new GramJs.ChatPhotoEmpty(),
|
photo: new Api.ChatPhotoEmpty(),
|
||||||
participantsCount: 1,
|
participantsCount: 1,
|
||||||
date: 1000,
|
date: 1000,
|
||||||
creator: true,
|
creator: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const peerChannel = new GramJs.PeerChannel({
|
const peerChannel = new Api.PeerChannel({
|
||||||
channelId: channel.id,
|
channelId: channel.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogs.push(this.createDialog(peerChannel));
|
this.dialogs.push(this.createDialog(peerChannel));
|
||||||
|
|
||||||
const testChat: Peer = { peer: channel, TEST_messages: [], TEST_sendMessage: this.createMessage(peerChannel) };
|
const testChat: Peer = {
|
||||||
|
peer: channel, inputPeer: peerChannel, TEST_messages: [], TEST_sendMessage: this.createMessage(peerChannel),
|
||||||
|
};
|
||||||
|
|
||||||
this.peers.push(testChat);
|
this.peers.push(testChat);
|
||||||
|
|
||||||
@ -175,7 +179,7 @@ class TelegramClient {
|
|||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
}): Peer {
|
}): Peer {
|
||||||
const user = new GramJs.User({
|
const user = new Api.User({
|
||||||
// self: true,
|
// self: true,
|
||||||
verified: true,
|
verified: true,
|
||||||
id: BigInt(this.lastId++),
|
id: BigInt(this.lastId++),
|
||||||
@ -192,23 +196,25 @@ class TelegramClient {
|
|||||||
// langCode?: string;
|
// langCode?: string;
|
||||||
});
|
});
|
||||||
|
|
||||||
const peerUser = new GramJs.PeerUser({
|
const peerUser = new Api.PeerUser({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogs.push(this.createDialog(peerUser));
|
this.dialogs.push(this.createDialog(peerUser));
|
||||||
|
|
||||||
const testChat: Peer = { peer: user, TEST_messages: [], TEST_sendMessage: this.createMessage(peerUser) };
|
const testChat: Peer = {
|
||||||
|
peer: user, inputPeer: peerUser, TEST_messages: [], TEST_sendMessage: this.createMessage(peerUser),
|
||||||
|
};
|
||||||
|
|
||||||
this.peers.push(testChat);
|
this.peers.push(testChat);
|
||||||
|
|
||||||
return testChat;
|
return testChat;
|
||||||
}
|
}
|
||||||
|
|
||||||
invoke(request: Request) {
|
invoke(request: any) {
|
||||||
// await new Promise(resolve => setTimeout(resolve, 1000))
|
// await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
if (request instanceof GramJs.messages.GetDiscussionMessage) {
|
if (request instanceof Api.messages.GetDiscussionMessage) {
|
||||||
return new GramJs.messages.DiscussionMessage({
|
return new Api.messages.DiscussionMessage({
|
||||||
messages: [
|
messages: [
|
||||||
this.peers[3].TEST_messages[0],
|
this.peers[3].TEST_messages[0],
|
||||||
],
|
],
|
||||||
@ -218,21 +224,21 @@ class TelegramClient {
|
|||||||
users: [],
|
users: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (request instanceof GramJs.messages.GetHistory) {
|
if (request instanceof Api.messages.GetHistory) {
|
||||||
const peer = this.getPeer(request.peer);
|
const peer = this.getPeer(request.peer);
|
||||||
if (!peer) return undefined;
|
if (!peer) return undefined;
|
||||||
|
|
||||||
return new GramJs.messages.Messages({
|
return new Api.messages.Messages({
|
||||||
messages: peer.TEST_messages,
|
messages: peer.TEST_messages,
|
||||||
chats: [],
|
chats: [],
|
||||||
users: [],
|
users: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (request instanceof GramJs.messages.GetReplies) {
|
if (request instanceof Api.messages.GetReplies) {
|
||||||
const peer = this.peers[3];
|
const peer = this.peers[3];
|
||||||
if (!peer) return undefined;
|
if (!peer) return undefined;
|
||||||
|
|
||||||
return new GramJs.messages.ChannelMessages({
|
return new Api.messages.ChannelMessages({
|
||||||
messages: peer.TEST_messages,
|
messages: peer.TEST_messages,
|
||||||
pts: 0,
|
pts: 0,
|
||||||
count: peer.TEST_messages.length,
|
count: peer.TEST_messages.length,
|
||||||
@ -240,8 +246,8 @@ class TelegramClient {
|
|||||||
users: [],
|
users: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (request instanceof GramJs.messages.GetDialogFilters) {
|
if (request instanceof Api.messages.GetDialogFilters) {
|
||||||
return [new GramJs.DialogFilter({
|
return [new Api.DialogFilter({
|
||||||
contacts: true,
|
contacts: true,
|
||||||
nonContacts: true,
|
nonContacts: true,
|
||||||
groups: true,
|
groups: true,
|
||||||
@ -258,13 +264,31 @@ class TelegramClient {
|
|||||||
excludePeers: [],
|
excludePeers: [],
|
||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
if (request instanceof GramJs.messages.GetPinnedDialogs) {
|
if (request instanceof Api.contacts.GetTopPeers) {
|
||||||
return new GramJs.messages.PeerDialogs({
|
return new Api.contacts.TopPeers({
|
||||||
|
categories: [new Api.TopPeerCategoryPeers({
|
||||||
|
category: new Api.TopPeerCategoryCorrespondents(),
|
||||||
|
count: 1,
|
||||||
|
peers: [
|
||||||
|
new Api.TopPeer({
|
||||||
|
peer: this.peers[0].inputPeer,
|
||||||
|
rating: 100,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})],
|
||||||
|
chats: [],
|
||||||
|
users: [
|
||||||
|
this.getUsers()[0],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (request instanceof Api.messages.GetPinnedDialogs) {
|
||||||
|
return new Api.messages.PeerDialogs({
|
||||||
dialogs: [],
|
dialogs: [],
|
||||||
chats: [],
|
chats: [],
|
||||||
messages: [],
|
messages: [],
|
||||||
users: [],
|
users: [],
|
||||||
state: new GramJs.updates.State({
|
state: new Api.updates.State({
|
||||||
pts: 0,
|
pts: 0,
|
||||||
qts: 0,
|
qts: 0,
|
||||||
date: 0,
|
date: 0,
|
||||||
@ -273,9 +297,9 @@ class TelegramClient {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (request instanceof GramJs.messages.GetDialogs) {
|
if (request instanceof Api.messages.GetDialogs) {
|
||||||
if (request.folderId || !(request.offsetPeer instanceof GramJs.InputPeerEmpty)) {
|
if (request.folderId || !(request.offsetPeer instanceof Api.InputPeerEmpty)) {
|
||||||
return new GramJs.messages.Dialogs({
|
return new Api.messages.Dialogs({
|
||||||
dialogs: [],
|
dialogs: [],
|
||||||
users: [],
|
users: [],
|
||||||
chats: [],
|
chats: [],
|
||||||
@ -283,7 +307,7 @@ class TelegramClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GramJs.messages.Dialogs({
|
return new Api.messages.Dialogs({
|
||||||
dialogs: this.dialogs,
|
dialogs: this.dialogs,
|
||||||
messages: this.getAllMessages(),
|
messages: this.getAllMessages(),
|
||||||
chats: this.getChats(),
|
chats: this.getChats(),
|
||||||
@ -294,7 +318,7 @@ class TelegramClient {
|
|||||||
// console.log(request.className, request);
|
// console.log(request.className, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPeerIndex(peer: GramJs.TypeInputPeer) {
|
private getPeerIndex(peer: Api.TypeInputPeer) {
|
||||||
const id = 'channelId' in peer ? peer.channelId : (
|
const id = 'channelId' in peer ? peer.channelId : (
|
||||||
'userId' in peer ? peer.userId : (
|
'userId' in peer ? peer.userId : (
|
||||||
'chatId' in peer ? peer.chatId : undefined
|
'chatId' in peer ? peer.chatId : undefined
|
||||||
@ -306,7 +330,7 @@ class TelegramClient {
|
|||||||
return this.peers.findIndex((l) => l.peer.id.toString() === id.toString());
|
return this.peers.findIndex((l) => l.peer.id.toString() === id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPeer(peer: GramJs.TypeInputPeer) {
|
private getPeer(peer: Api.TypeInputPeer) {
|
||||||
const index = this.getPeerIndex(peer);
|
const index = this.getPeerIndex(peer);
|
||||||
if (index === undefined) return undefined;
|
if (index === undefined) return undefined;
|
||||||
|
|
||||||
@ -314,18 +338,18 @@ class TelegramClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getAllMessages() {
|
private getAllMessages() {
|
||||||
return this.peers.reduce((acc: GramJs.Message[], el) => {
|
return this.peers.reduce((acc: Api.Message[], el) => {
|
||||||
acc.push(...el.TEST_messages);
|
acc.push(...el.TEST_messages);
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getChats() {
|
private getChats() {
|
||||||
return this.peers.filter((l) => !(l.peer instanceof GramJs.User)).map((l) => l.peer);
|
return this.peers.filter((l) => !(l.peer instanceof Api.User)).map((l) => l.peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getUsers() {
|
private getUsers() {
|
||||||
return this.peers.filter((l) => l.peer instanceof GramJs.User).map((l) => l.peer);
|
return this.peers.filter((l) => l.peer instanceof Api.User).map((l) => l.peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user