Added possibility to jump by pin service message
This commit is contained in:
parent
180d151ac9
commit
2ee82d7597
@ -1466,7 +1466,7 @@ export default class ChatBubbles {
|
|||||||
this.deleteEmptyDateGroups();
|
this.deleteEmptyDateGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderNewMessagesByIds(mids: number[], scrolledDown = this.scrolledDown) {
|
public renderNewMessagesByIds(mids: number[], scrolledDown?: boolean) {
|
||||||
if(!this.scrollable.loadedAll.bottom) { // seems search active or sliced
|
if(!this.scrollable.loadedAll.bottom) { // seems search active or sliced
|
||||||
//this.log('renderNewMessagesByIds: seems search is active, skipping render:', mids);
|
//this.log('renderNewMessagesByIds: seems search is active, skipping render:', mids);
|
||||||
return;
|
return;
|
||||||
@ -1487,19 +1487,29 @@ export default class ChatBubbles {
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
if(!scrolledDown) {
|
if(!scrolledDown) {
|
||||||
if(this.scrollingToBubble && this.scrollingToBubble === this.getLastBubble()) {
|
scrolledDown = this.scrolledDown && (!this.scrollingToBubble || this.scrollingToBubble === this.getLastBubble());
|
||||||
scrolledDown = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const middleware = this.getMiddleware();
|
const middleware = this.getMiddleware();
|
||||||
let isPaddingNeeded = false;
|
let isPaddingNeeded = false;
|
||||||
|
let setPaddingTo: HTMLElement;
|
||||||
if(!this.isTopPaddingSet) {
|
if(!this.isTopPaddingSet) {
|
||||||
const {scrollHeight} = this.scrollable;
|
const {clientHeight, scrollHeight} = this.scrollable.container;
|
||||||
const clientHeight = this.scrollable.container.clientHeight;
|
|
||||||
isPaddingNeeded = clientHeight === scrollHeight;
|
isPaddingNeeded = clientHeight === scrollHeight;
|
||||||
|
/* const firstEl = this.chatInner.firstElementChild as HTMLElement;
|
||||||
|
if(this.chatInner.firstElementChild) {
|
||||||
|
const visibleRect = getVisibleRect(firstEl, this.scrollable.container);
|
||||||
|
isPaddingNeeded = !visibleRect.overflow.top && (visibleRect.rect.top - firstEl.offsetTop) !== this.scrollable.container.getBoundingClientRect().top;
|
||||||
|
} else {
|
||||||
|
isPaddingNeeded = true;
|
||||||
|
} */
|
||||||
|
|
||||||
if(isPaddingNeeded) {
|
if(isPaddingNeeded) {
|
||||||
this.chatInner.style.paddingTop = clientHeight + 'px';
|
/* const add = clientHeight - scrollHeight;
|
||||||
|
this.chatInner.style.paddingTop = add + 'px';
|
||||||
|
this.scrollable.scrollTop += add; */
|
||||||
|
setPaddingTo = this.chatInner;
|
||||||
|
setPaddingTo.style.paddingTop = clientHeight + 'px';
|
||||||
this.scrollable.scrollTop = scrollHeight;
|
this.scrollable.scrollTop = scrollHeight;
|
||||||
this.isTopPaddingSet = true;
|
this.isTopPaddingSet = true;
|
||||||
}
|
}
|
||||||
@ -1522,7 +1532,7 @@ export default class ChatBubbles {
|
|||||||
if(isPaddingNeeded) {
|
if(isPaddingNeeded) {
|
||||||
promise.then(() => { // it will be called only once even if was set multiple times (that won't happen)
|
promise.then(() => { // it will be called only once even if was set multiple times (that won't happen)
|
||||||
if(middleware() && isPaddingNeeded) {
|
if(middleware() && isPaddingNeeded) {
|
||||||
this.chatInner.style.paddingTop = '';
|
setPaddingTo.style.paddingTop = '';
|
||||||
this.isTopPaddingSet = false;
|
this.isTopPaddingSet = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -3029,6 +3039,15 @@ export default class ChatBubbles {
|
|||||||
} else {
|
} else {
|
||||||
title = new PeerTitle({peerId: message.viaBotId || message.fwdFromId || message.fromId}).element;
|
title = new PeerTitle({peerId: message.viaBotId || message.fwdFromId || message.fromId}).element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(message.reply_to_mid && message.reply_to_mid !== this.chat.threadId) {
|
||||||
|
MessageRender.setReply({
|
||||||
|
chat: this.chat,
|
||||||
|
bubble,
|
||||||
|
bubbleContainer,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//this.log(title);
|
//this.log(title);
|
||||||
|
|
||||||
@ -3094,15 +3113,6 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.reply_to_mid && message.reply_to_mid !== this.chat.threadId) {
|
|
||||||
MessageRender.setReply({
|
|
||||||
chat: this.chat,
|
|
||||||
bubble,
|
|
||||||
bubbleContainer,
|
|
||||||
message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const needAvatar = this.chat.isAnyGroup() && !isOut;
|
const needAvatar = this.chat.isAnyGroup() && !isOut;
|
||||||
if(needAvatar) {
|
if(needAvatar) {
|
||||||
let avatarElem = new AvatarElement();
|
let avatarElem = new AvatarElement();
|
||||||
|
6
src/layer.d.ts
vendored
6
src/layer.d.ts
vendored
@ -869,7 +869,8 @@ export namespace Message {
|
|||||||
pending?: boolean,
|
pending?: boolean,
|
||||||
error?: any,
|
error?: any,
|
||||||
send?: () => Promise<any>,
|
send?: () => Promise<any>,
|
||||||
totalEntities?: MessageEntity[]
|
totalEntities?: MessageEntity[],
|
||||||
|
reply_to_mid?: number
|
||||||
};
|
};
|
||||||
|
|
||||||
export type messageService = {
|
export type messageService = {
|
||||||
@ -902,7 +903,8 @@ export namespace Message {
|
|||||||
pending?: boolean,
|
pending?: boolean,
|
||||||
error?: any,
|
error?: any,
|
||||||
send?: () => Promise<any>,
|
send?: () => Promise<any>,
|
||||||
random_id?: string
|
random_id?: string,
|
||||||
|
reply_to_mid?: number
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2345,6 +2345,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(message._ === 'messageEmpty') {
|
if(message._ === 'messageEmpty') {
|
||||||
|
message.deleted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2977,17 +2978,37 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'messageActionPinMessage': {
|
case 'messageActionPinMessage': {
|
||||||
const pinnedMessage = this.getMessageByPeer(message.peerId, message.reply_to_mid);
|
const peerId = message.peerId;
|
||||||
|
const pinnedMessage = this.getMessageByPeer(peerId, message.reply_to_mid);
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
getNameDivHTML(message.fromId, plain),
|
getNameDivHTML(message.fromId, plain),
|
||||||
];
|
];
|
||||||
|
|
||||||
if(pinnedMessage.deleted || true) {
|
if(pinnedMessage.deleted/* || true */) {
|
||||||
langPackKey = 'ActionPinnedNoText';
|
langPackKey = 'ActionPinnedNoText';
|
||||||
|
|
||||||
|
if(message.reply_to_mid) { // refresh original message
|
||||||
|
this.fetchMessageReplyTo(message).then(originalMessage => {
|
||||||
|
if(!originalMessage.deleted && !message.deleted) {
|
||||||
|
rootScope.dispatchEvent('message_edit', {
|
||||||
|
storage: this.getMessagesStorage(peerId),
|
||||||
|
peerId: peerId,
|
||||||
|
mid: message.mid
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this.isMessageIsTopMessage(message)) {
|
||||||
|
rootScope.dispatchEvent('dialogs_multiupdate', {
|
||||||
|
[peerId]: this.getDialogOnly(peerId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('i');
|
||||||
a.dataset.savedFrom = pinnedMessage.peerId + '_' + pinnedMessage.mid;
|
a.dataset.savedFrom = pinnedMessage.peerId + '_' + pinnedMessage.mid;
|
||||||
|
a.dir = 'auto';
|
||||||
a.append(this.wrapMessageForReply(pinnedMessage, undefined, undefined, plain as any));
|
a.append(this.wrapMessageForReply(pinnedMessage, undefined, undefined, plain as any));
|
||||||
args.push(a);
|
args.push(a);
|
||||||
}
|
}
|
||||||
@ -4836,12 +4857,16 @@ export class AppMessagesManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public setDialogToStateIfMessageIsTop(message: MyMessage) {
|
public setDialogToStateIfMessageIsTop(message: MyMessage) {
|
||||||
const dialog = this.getDialogOnly(message.peerId);
|
if(this.isMessageIsTopMessage(message)) {
|
||||||
if(dialog && dialog.top_message === message.mid) {
|
this.dialogsStorage.setDialogToState(this.getDialogOnly(message.peerId));
|
||||||
this.dialogsStorage.setDialogToState(dialog);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isMessageIsTopMessage(message: MyMessage) {
|
||||||
|
const dialog = this.getDialogOnly(message.peerId);
|
||||||
|
return dialog && dialog.top_message === message.mid;
|
||||||
|
}
|
||||||
|
|
||||||
private updateMessageRepliesIfNeeded(threadMessage: MyMessage) {
|
private updateMessageRepliesIfNeeded(threadMessage: MyMessage) {
|
||||||
try { // * на всякий случай, скорее всего это не понадобится
|
try { // * на всякий случай, скорее всего это не понадобится
|
||||||
const threadKey = this.getThreadKey(threadMessage);
|
const threadKey = this.getThreadKey(threadMessage);
|
||||||
@ -5562,6 +5587,18 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fetchMessageReplyTo(message: MyMessage): Promise<Message> {
|
||||||
|
if(!message.reply_to_mid) return Promise.resolve(this.generateEmptyMessage(0));
|
||||||
|
const replyToPeerId = message.reply_to.reply_to_peer_id ? appPeersManager.getPeerId(message.reply_to.reply_to_peer_id) : message.peerId;
|
||||||
|
return this.wrapSingleMessage(replyToPeerId, message.reply_to_mid).then(originalMessage => {
|
||||||
|
if(originalMessage.deleted) { // ! чтобы не пыталось бесконечно загрузить удалённое сообщение
|
||||||
|
delete message.reply_to_mid; // ! WARNING!
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalMessage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public setTyping(peerId: PeerId, action: SendMessageAction): Promise<boolean> {
|
public setTyping(peerId: PeerId, action: SendMessageAction): Promise<boolean> {
|
||||||
let typing = this.typings[peerId];
|
let typing = this.typings[peerId];
|
||||||
if(!rootScope.myId ||
|
if(!rootScope.myId ||
|
||||||
|
@ -77,7 +77,8 @@
|
|||||||
{"name": "pending", "type": "boolean"},
|
{"name": "pending", "type": "boolean"},
|
||||||
{"name": "error", "type": "any"},
|
{"name": "error", "type": "any"},
|
||||||
{"name": "send", "type": "() => Promise<any>"},
|
{"name": "send", "type": "() => Promise<any>"},
|
||||||
{"name": "totalEntities", "type": "MessageEntity[]"}
|
{"name": "totalEntities", "type": "MessageEntity[]"},
|
||||||
|
{"name": "reply_to_mid", "type": "number"}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"predicate": "messageService",
|
"predicate": "messageService",
|
||||||
@ -94,7 +95,8 @@
|
|||||||
{"name": "pending", "type": "boolean"},
|
{"name": "pending", "type": "boolean"},
|
||||||
{"name": "error", "type": "any"},
|
{"name": "error", "type": "any"},
|
||||||
{"name": "send", "type": "() => Promise<any>"},
|
{"name": "send", "type": "() => Promise<any>"},
|
||||||
{"name": "random_id", "type": "string"}
|
{"name": "random_id", "type": "string"},
|
||||||
|
{"name": "reply_to_mid", "type": "number"}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"predicate": "messageEmpty",
|
"predicate": "messageEmpty",
|
||||||
|
@ -1018,8 +1018,6 @@ $chat-helper-size: 36px;
|
|||||||
.bubbles {
|
.bubbles {
|
||||||
--translateY: 0;
|
--translateY: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -1145,9 +1143,7 @@ $chat-helper-size: 36px;
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 1;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
box-sizing: border-box;
|
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding: 0 $chat-padding;
|
padding: 0 $chat-padding;
|
||||||
|
@ -792,9 +792,12 @@ $bubble-beside-button-width: 38px;
|
|||||||
order: -1;
|
order: -1;
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex: 1 1 auto;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
|
@include animation-level(0) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.bubble-content-wrapper {
|
.bubble-content-wrapper {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@ -1040,7 +1043,8 @@ $bubble-beside-button-width: 38px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.just-media):not(.is-message-empty) .reply {
|
// &:not(.just-media):not(.is-message-empty) .reply {
|
||||||
|
.message + .reply {
|
||||||
// margin-bottom: .125rem; // ! JS2 mockup
|
// margin-bottom: .125rem; // ! JS2 mockup
|
||||||
margin-bottom: 0; // ! same margin as between name and message
|
margin-bottom: 0; // ! same margin as between name and message
|
||||||
}
|
}
|
||||||
@ -1293,7 +1297,8 @@ $bubble-beside-button-width: 38px;
|
|||||||
left: -75vw;
|
left: -75vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-highlighted, &.is-selected {
|
&.is-highlighted,
|
||||||
|
&.is-selected {
|
||||||
.document-wrapper {
|
.document-wrapper {
|
||||||
&:before {
|
&:before {
|
||||||
content: " ";
|
content: " ";
|
||||||
@ -1314,7 +1319,8 @@ $bubble-beside-button-width: 38px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
body:not(.animation-level-0) & {
|
body:not(.animation-level-0) & {
|
||||||
.document-selection, .document-wrapper:before {
|
.document-selection,
|
||||||
|
.document-wrapper:before {
|
||||||
animation: bubbleSelected 2s linear;
|
animation: bubbleSelected 2s linear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1326,12 +1332,14 @@ $bubble-beside-button-width: 38px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
body:not(.animation-level-0) & {
|
body:not(.animation-level-0) & {
|
||||||
.document-selection, .document-wrapper:before {
|
.document-selection,
|
||||||
|
.document-wrapper:before {
|
||||||
animation: fade-in-opacity .2s linear forwards;
|
animation: fade-in-opacity .2s linear forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.backwards {
|
&.backwards {
|
||||||
.document-selection, .document-wrapper:before {
|
.document-selection,
|
||||||
|
.document-wrapper:before {
|
||||||
animation: fade-in-backwards-opacity .2s linear forwards;
|
animation: fade-in-backwards-opacity .2s linear forwards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1417,8 +1425,9 @@ $bubble-beside-button-width: 38px;
|
|||||||
padding: .25rem .5rem;
|
padding: .25rem .5rem;
|
||||||
|
|
||||||
> .name {
|
> .name {
|
||||||
|
// padding: .0625rem 0 .375rem;
|
||||||
padding: 0 0 .25rem 0;
|
padding: 0 0 .25rem 0;
|
||||||
margin-top: -.25rem;
|
margin-top: -.1875rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,7 +1658,7 @@ $bubble-beside-button-width: 38px;
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
order: 1;
|
// order: 1;
|
||||||
//width: max-content;
|
//width: max-content;
|
||||||
//white-space: nowrap;
|
//white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -1933,6 +1942,11 @@ $bubble-beside-button-width: 38px;
|
|||||||
.bubble-content {
|
.bubble-content {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: .875rem;
|
border-radius: .875rem;
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.service-msg {
|
.service-msg {
|
||||||
@ -1960,7 +1974,8 @@ $bubble-beside-button-width: 38px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
.peer-title {
|
.peer-title,
|
||||||
|
[data-saved-from] {
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -2019,7 +2034,8 @@ $bubble-beside-button-width: 38px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.just-media {
|
&.just-media {
|
||||||
.reply, .name {
|
.reply,
|
||||||
|
.name {
|
||||||
left: calc(100% + 10px);
|
left: calc(100% + 10px);
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user