Browse Source

Added possibility to jump by pin service message

master
morethanwords 3 years ago
parent
commit
2ee82d7597
  1. 44
      src/components/chat/bubbles.ts
  2. 6
      src/layer.d.ts
  3. 49
      src/lib/appManagers/appMessagesManager.ts
  4. 6
      src/scripts/in/schema_additional_params.json
  5. 4
      src/scss/partials/_chat.scss
  6. 36
      src/scss/partials/_chatBubble.scss

44
src/components/chat/bubbles.ts

@ -1466,7 +1466,7 @@ export default class ChatBubbles { @@ -1466,7 +1466,7 @@ export default class ChatBubbles {
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
//this.log('renderNewMessagesByIds: seems search is active, skipping render:', mids);
return;
@ -1487,19 +1487,29 @@ export default class ChatBubbles { @@ -1487,19 +1487,29 @@ export default class ChatBubbles {
} */
if(!scrolledDown) {
if(this.scrollingToBubble && this.scrollingToBubble === this.getLastBubble()) {
scrolledDown = true;
}
scrolledDown = this.scrolledDown && (!this.scrollingToBubble || this.scrollingToBubble === this.getLastBubble());
}
const middleware = this.getMiddleware();
let isPaddingNeeded = false;
let setPaddingTo: HTMLElement;
if(!this.isTopPaddingSet) {
const {scrollHeight} = this.scrollable;
const clientHeight = this.scrollable.container.clientHeight;
const {clientHeight, scrollHeight} = this.scrollable.container;
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) {
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.isTopPaddingSet = true;
}
@ -1522,7 +1532,7 @@ export default class ChatBubbles { @@ -1522,7 +1532,7 @@ export default class ChatBubbles {
if(isPaddingNeeded) {
promise.then(() => { // it will be called only once even if was set multiple times (that won't happen)
if(middleware() && isPaddingNeeded) {
this.chatInner.style.paddingTop = '';
setPaddingTo.style.paddingTop = '';
this.isTopPaddingSet = false;
}
});
@ -3029,6 +3039,15 @@ export default class ChatBubbles { @@ -3029,6 +3039,15 @@ export default class ChatBubbles {
} else {
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);
@ -3094,15 +3113,6 @@ export default class ChatBubbles { @@ -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;
if(needAvatar) {
let avatarElem = new AvatarElement();

6
src/layer.d.ts vendored

@ -869,7 +869,8 @@ export namespace Message { @@ -869,7 +869,8 @@ export namespace Message {
pending?: boolean,
error?: any,
send?: () => Promise<any>,
totalEntities?: MessageEntity[]
totalEntities?: MessageEntity[],
reply_to_mid?: number
};
export type messageService = {
@ -902,7 +903,8 @@ export namespace Message { @@ -902,7 +903,8 @@ export namespace Message {
pending?: boolean,
error?: any,
send?: () => Promise<any>,
random_id?: string
random_id?: string,
reply_to_mid?: number
};
}

49
src/lib/appManagers/appMessagesManager.ts

@ -2345,6 +2345,7 @@ export class AppMessagesManager { @@ -2345,6 +2345,7 @@ export class AppMessagesManager {
}
if(message._ === 'messageEmpty') {
message.deleted = true;
return;
}
@ -2977,17 +2978,37 @@ export class AppMessagesManager { @@ -2977,17 +2978,37 @@ export class AppMessagesManager {
}
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 = [
getNameDivHTML(message.fromId, plain),
];
if(pinnedMessage.deleted || true) {
if(pinnedMessage.deleted/* || true */) {
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 {
const a = document.createElement('a');
const a = document.createElement('i');
a.dataset.savedFrom = pinnedMessage.peerId + '_' + pinnedMessage.mid;
a.dir = 'auto';
a.append(this.wrapMessageForReply(pinnedMessage, undefined, undefined, plain as any));
args.push(a);
}
@ -4836,12 +4857,16 @@ export class AppMessagesManager { @@ -4836,12 +4857,16 @@ export class AppMessagesManager {
};
public setDialogToStateIfMessageIsTop(message: MyMessage) {
const dialog = this.getDialogOnly(message.peerId);
if(dialog && dialog.top_message === message.mid) {
this.dialogsStorage.setDialogToState(dialog);
if(this.isMessageIsTopMessage(message)) {
this.dialogsStorage.setDialogToState(this.getDialogOnly(message.peerId));
}
}
public isMessageIsTopMessage(message: MyMessage) {
const dialog = this.getDialogOnly(message.peerId);
return dialog && dialog.top_message === message.mid;
}
private updateMessageRepliesIfNeeded(threadMessage: MyMessage) {
try { // * на всякий случай, скорее всего это не понадобится
const threadKey = this.getThreadKey(threadMessage);
@ -5562,6 +5587,18 @@ export class AppMessagesManager { @@ -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> {
let typing = this.typings[peerId];
if(!rootScope.myId ||

6
src/scripts/in/schema_additional_params.json

@ -77,7 +77,8 @@ @@ -77,7 +77,8 @@
{"name": "pending", "type": "boolean"},
{"name": "error", "type": "any"},
{"name": "send", "type": "() => Promise<any>"},
{"name": "totalEntities", "type": "MessageEntity[]"}
{"name": "totalEntities", "type": "MessageEntity[]"},
{"name": "reply_to_mid", "type": "number"}
]
}, {
"predicate": "messageService",
@ -94,7 +95,8 @@ @@ -94,7 +95,8 @@
{"name": "pending", "type": "boolean"},
{"name": "error", "type": "any"},
{"name": "send", "type": "() => Promise<any>"},
{"name": "random_id", "type": "string"}
{"name": "random_id", "type": "string"},
{"name": "reply_to_mid", "type": "number"}
]
}, {
"predicate": "messageEmpty",

4
src/scss/partials/_chat.scss

@ -1018,8 +1018,6 @@ $chat-helper-size: 36px; @@ -1018,8 +1018,6 @@ $chat-helper-size: 36px;
.bubbles {
--translateY: 0;
width: 100%;
height: 100%;
max-height: 100%;
flex: 1 1 auto;
position: relative;
@ -1145,9 +1143,7 @@ $chat-helper-size: 36px; @@ -1145,9 +1143,7 @@ $chat-helper-size: 36px;
width: 100%;
display: flex;
flex-direction: column;
flex-shrink: 1;
margin: 0 auto;
box-sizing: border-box;
min-height: 100%;
justify-content: flex-end;
padding: 0 $chat-padding;

36
src/scss/partials/_chatBubble.scss

@ -792,9 +792,12 @@ $bubble-beside-button-width: 38px; @@ -792,9 +792,12 @@ $bubble-beside-button-width: 38px;
order: -1;
margin-top: .5rem;
justify-content: center;
flex: 1 1 auto;
align-items: center;
max-width: 100%;
@include animation-level(0) {
flex: 1 1 auto;
}
.bubble-content-wrapper {
max-width: 100%;
@ -1040,7 +1043,8 @@ $bubble-beside-button-width: 38px; @@ -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: 0; // ! same margin as between name and message
}
@ -1293,7 +1297,8 @@ $bubble-beside-button-width: 38px; @@ -1293,7 +1297,8 @@ $bubble-beside-button-width: 38px;
left: -75vw;
}
&.is-highlighted, &.is-selected {
&.is-highlighted,
&.is-selected {
.document-wrapper {
&:before {
content: " ";
@ -1314,7 +1319,8 @@ $bubble-beside-button-width: 38px; @@ -1314,7 +1319,8 @@ $bubble-beside-button-width: 38px;
}
body:not(.animation-level-0) & {
.document-selection, .document-wrapper:before {
.document-selection,
.document-wrapper:before {
animation: bubbleSelected 2s linear;
}
}
@ -1326,12 +1332,14 @@ $bubble-beside-button-width: 38px; @@ -1326,12 +1332,14 @@ $bubble-beside-button-width: 38px;
}
body:not(.animation-level-0) & {
.document-selection, .document-wrapper:before {
.document-selection,
.document-wrapper:before {
animation: fade-in-opacity .2s linear forwards;
}
&.backwards {
.document-selection, .document-wrapper:before {
.document-selection,
.document-wrapper:before {
animation: fade-in-backwards-opacity .2s linear forwards;
}
}
@ -1417,8 +1425,9 @@ $bubble-beside-button-width: 38px; @@ -1417,8 +1425,9 @@ $bubble-beside-button-width: 38px;
padding: .25rem .5rem;
> .name {
// padding: .0625rem 0 .375rem;
padding: 0 0 .25rem 0;
margin-top: -.25rem;
margin-top: -.1875rem;
}
}
@ -1649,7 +1658,7 @@ $bubble-beside-button-width: 38px; @@ -1649,7 +1658,7 @@ $bubble-beside-button-width: 38px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
order: 1;
// order: 1;
//width: max-content;
//white-space: nowrap;
}
@ -1933,6 +1942,11 @@ $bubble-beside-button-width: 38px; @@ -1933,6 +1942,11 @@ $bubble-beside-button-width: 38px;
.bubble-content {
background-color: transparent;
border-radius: .875rem;
&-wrapper {
max-width: 100%;
padding: 0 2rem;
}
}
.service-msg {
@ -1960,7 +1974,8 @@ $bubble-beside-button-width: 38px; @@ -1960,7 +1974,8 @@ $bubble-beside-button-width: 38px;
}
a,
.peer-title {
.peer-title,
[data-saved-from] {
&:hover {
text-decoration: underline;
cursor: pointer;
@ -2019,7 +2034,8 @@ $bubble-beside-button-width: 38px; @@ -2019,7 +2034,8 @@ $bubble-beside-button-width: 38px;
}
&.just-media {
.reply, .name {
.reply,
.name {
left: calc(100% + 10px);
@include respond-to(handhelds) {

Loading…
Cancel
Save