Added chat placeholders
This commit is contained in:
parent
c38e7c399e
commit
7f85c08a5e
@ -70,6 +70,8 @@ export default class AppSelectPeers {
|
|||||||
|
|
||||||
private placeholder: LangPackKey;
|
private placeholder: LangPackKey;
|
||||||
|
|
||||||
|
private selfPresence: LangPackKey = 'Presence.YourChat';
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
appendTo: AppSelectPeers['appendTo'],
|
appendTo: AppSelectPeers['appendTo'],
|
||||||
onChange?: AppSelectPeers['onChange'],
|
onChange?: AppSelectPeers['onChange'],
|
||||||
@ -81,7 +83,8 @@ export default class AppSelectPeers {
|
|||||||
multiSelect?: AppSelectPeers['multiSelect'],
|
multiSelect?: AppSelectPeers['multiSelect'],
|
||||||
rippleEnabled?: boolean,
|
rippleEnabled?: boolean,
|
||||||
avatarSize?: AppSelectPeers['avatarSize'],
|
avatarSize?: AppSelectPeers['avatarSize'],
|
||||||
placeholder?: LangPackKey
|
placeholder?: LangPackKey,
|
||||||
|
selfPresence?: LangPackKey
|
||||||
}) {
|
}) {
|
||||||
safeAssign(this, options);
|
safeAssign(this, options);
|
||||||
|
|
||||||
@ -449,7 +452,7 @@ export default class AppSelectPeers {
|
|||||||
if(peerId < 0) {
|
if(peerId < 0) {
|
||||||
subtitleEl = appProfileManager.getChatMembersString(-peerId);
|
subtitleEl = appProfileManager.getChatMembersString(-peerId);
|
||||||
} else if(peerId === rootScope.myId) {
|
} else if(peerId === rootScope.myId) {
|
||||||
subtitleEl = i18n('Presence.YourChat');
|
subtitleEl = i18n(this.selfPresence);
|
||||||
} else {
|
} else {
|
||||||
subtitleEl = appUsersManager.getUserStatusString(peerId);
|
subtitleEl = appUsersManager.getUserStatusString(peerId);
|
||||||
}
|
}
|
||||||
|
@ -67,15 +67,22 @@ import replaceContent from "../../helpers/dom/replaceContent";
|
|||||||
import setInnerHTML from "../../helpers/dom/setInnerHTML";
|
import setInnerHTML from "../../helpers/dom/setInnerHTML";
|
||||||
import whichChild from "../../helpers/dom/whichChild";
|
import whichChild from "../../helpers/dom/whichChild";
|
||||||
import { cancelAnimationByKey } from "../../helpers/animation";
|
import { cancelAnimationByKey } from "../../helpers/animation";
|
||||||
|
import assumeType from "../../helpers/assumeType";
|
||||||
|
import { EmoticonsDropdown } from "../emoticonsDropdown";
|
||||||
|
|
||||||
const USE_MEDIA_TAILS = false;
|
const USE_MEDIA_TAILS = false;
|
||||||
const IGNORE_ACTIONS: Message.messageService['action']['_'][] = ['messageActionHistoryClear'];
|
const IGNORE_ACTIONS: Set<Message.messageService['action']['_']> = new Set([
|
||||||
|
'messageActionHistoryClear',
|
||||||
|
'messageActionChatCreate'
|
||||||
|
]);
|
||||||
|
|
||||||
const TEST_SCROLL_TIMES: number = undefined;
|
const TEST_SCROLL_TIMES: number = undefined;
|
||||||
let TEST_SCROLL = TEST_SCROLL_TIMES;
|
let TEST_SCROLL = TEST_SCROLL_TIMES;
|
||||||
|
|
||||||
let queueId = 0;
|
let queueId = 0;
|
||||||
|
|
||||||
|
type GenerateLocalMessageType<IsService> = IsService extends true ? Message.messageService : Message.message;
|
||||||
|
|
||||||
export default class ChatBubbles {
|
export default class ChatBubbles {
|
||||||
public bubblesContainer: HTMLDivElement;
|
public bubblesContainer: HTMLDivElement;
|
||||||
private chatInner: HTMLDivElement;
|
private chatInner: HTMLDivElement;
|
||||||
@ -116,7 +123,7 @@ export default class ChatBubbles {
|
|||||||
private loadedBottomTimes = 0;
|
private loadedBottomTimes = 0;
|
||||||
|
|
||||||
private messagesQueuePromise: Promise<void> = null;
|
private messagesQueuePromise: Promise<void> = null;
|
||||||
private messagesQueue: {message: any, bubble: HTMLDivElement, reverse: boolean, promises: Promise<void>[]}[] = [];
|
private messagesQueue: {message: any, bubble: HTMLElement, reverse: boolean, promises: Promise<void>[]}[] = [];
|
||||||
private messagesQueueOnRender: () => void = null;
|
private messagesQueueOnRender: () => void = null;
|
||||||
private messagesQueueOnRenderAdditional: () => void = null;
|
private messagesQueueOnRenderAdditional: () => void = null;
|
||||||
|
|
||||||
@ -1825,7 +1832,7 @@ export default class ChatBubbles {
|
|||||||
this.chatInner.classList.toggle('is-channel', isChannel);
|
this.chatInner.classList.toggle('is-channel', isChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderMessagesQueue(message: any, bubble: HTMLDivElement, reverse: boolean, promises: Promise<any>[]) {
|
public renderMessagesQueue(message: any, bubble: HTMLElement, reverse: boolean, promises: Promise<any>[]) {
|
||||||
/* let dateMessage = this.getDateContainerByMessage(message, reverse);
|
/* let dateMessage = this.getDateContainerByMessage(message, reverse);
|
||||||
if(reverse) dateMessage.container.insertBefore(bubble, dateMessage.div.nextSibling);
|
if(reverse) dateMessage.container.insertBefore(bubble, dateMessage.div.nextSibling);
|
||||||
else dateMessage.container.append(bubble);
|
else dateMessage.container.append(bubble);
|
||||||
@ -1891,6 +1898,11 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setBubblePosition(bubble: HTMLElement, message: any, reverse: boolean) {
|
public setBubblePosition(bubble: HTMLElement, message: any, reverse: boolean) {
|
||||||
|
if(message.id < 0) {
|
||||||
|
this.chatInner.prepend(bubble);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const dateMessage = this.getDateContainerByMessage(message, reverse);
|
const dateMessage = this.getDateContainerByMessage(message, reverse);
|
||||||
if(this.chat.type === 'scheduled' || this.chat.type === 'pinned'/* || true */) { // ! TEMP COMMENTED
|
if(this.chat.type === 'scheduled' || this.chat.type === 'pinned'/* || true */) { // ! TEMP COMMENTED
|
||||||
const offset = this.stickyIntersector ? 2 : 1;
|
const offset = this.stickyIntersector ? 2 : 1;
|
||||||
@ -2031,18 +2043,24 @@ export default class ChatBubbles {
|
|||||||
const loadPromises: Promise<any>[] = [];
|
const loadPromises: Promise<any>[] = [];
|
||||||
|
|
||||||
if(message._ === 'messageService') {
|
if(message._ === 'messageService') {
|
||||||
let action = message.action;
|
assumeType<Message.messageService>(message);
|
||||||
let _ = action._;
|
|
||||||
if(IGNORE_ACTIONS.includes(_) || (langPack.hasOwnProperty(_) && !langPack[_])) {
|
const action = message.action;
|
||||||
|
if(action) {
|
||||||
|
const _ = action._;
|
||||||
|
if(IGNORE_ACTIONS.has(_) || (langPack.hasOwnProperty(_) && !langPack[_])) {
|
||||||
return bubble;
|
return bubble;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bubble.className = 'bubble service';
|
bubble.className = 'bubble service';
|
||||||
|
|
||||||
bubbleContainer.innerHTML = '';
|
bubbleContainer.innerHTML = '';
|
||||||
const s = document.createElement('div');
|
const s = document.createElement('div');
|
||||||
s.classList.add('service-msg');
|
s.classList.add('service-msg');
|
||||||
|
if(action) {
|
||||||
s.append(this.appMessagesManager.wrapMessageActionTextNew(message));
|
s.append(this.appMessagesManager.wrapMessageActionTextNew(message));
|
||||||
|
}
|
||||||
bubbleContainer.append(s);
|
bubbleContainer.append(s);
|
||||||
|
|
||||||
if(updatePosition) {
|
if(updatePosition) {
|
||||||
@ -3055,15 +3073,136 @@ export default class ChatBubbles {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private processLocalMessageRender(message: any) {
|
private renderEmptyPlaceholder(type: 'group' | 'saved' | 'noMessages' | 'noScheduledMessages' | 'greeting', bubble: HTMLElement, message: any, elements: (Node | string)[]) {
|
||||||
const bubble = this.renderMessage(message, false, false, undefined, false);
|
bubble.classList.add('empty-placeholder', 'empty-placeholder-' + type);
|
||||||
|
|
||||||
|
let title: HTMLElement;
|
||||||
|
if(type === 'group') title = i18n('GroupEmptyTitle1');
|
||||||
|
else if(type === 'saved') title = i18n('ChatYourSelfTitle');
|
||||||
|
else if(type === 'noMessages' || type === 'greeting') title = i18n('NoMessages');
|
||||||
|
else if(type === 'noScheduledMessages') title = i18n('NoScheduledMessages');
|
||||||
|
title.classList.add('center', 'empty-placeholder-title');
|
||||||
|
|
||||||
|
elements.push(title);
|
||||||
|
|
||||||
|
let listElements: HTMLElement[];
|
||||||
|
if(type === 'group') {
|
||||||
|
elements.push(i18n('GroupEmptyTitle2'));
|
||||||
|
listElements = [
|
||||||
|
i18n('GroupDescription1'),
|
||||||
|
i18n('GroupDescription2'),
|
||||||
|
i18n('GroupDescription3'),
|
||||||
|
i18n('GroupDescription4')
|
||||||
|
];
|
||||||
|
} else if(type === 'saved') {
|
||||||
|
listElements = [
|
||||||
|
i18n('ChatYourSelfDescription1'),
|
||||||
|
i18n('ChatYourSelfDescription2'),
|
||||||
|
i18n('ChatYourSelfDescription3'),
|
||||||
|
i18n('ChatYourSelfDescription4')
|
||||||
|
];
|
||||||
|
} else if(type === 'greeting') {
|
||||||
|
const subtitle = i18n('NoMessagesGreetingsDescription');
|
||||||
|
subtitle.classList.add('center', 'empty-placeholder-subtitle');
|
||||||
|
|
||||||
|
this.messagesQueue.findAndSplice(q => q.bubble === bubble);
|
||||||
|
|
||||||
|
const stickerDiv = document.createElement('div');
|
||||||
|
stickerDiv.classList.add('empty-placeholder-sticker');
|
||||||
|
|
||||||
|
const middleware = this.getMiddleware();
|
||||||
|
const loadPromise = this.appStickersManager.getGreetingSticker().then(doc => {
|
||||||
|
if(!middleware()) return;
|
||||||
|
|
||||||
|
const loadPromises: Promise<any>[] = [];
|
||||||
|
wrapSticker({
|
||||||
|
doc,
|
||||||
|
// doc: appDocsManager.getDoc("5431607541660389336"), // cubigator mockup
|
||||||
|
div: stickerDiv,
|
||||||
|
middleware,
|
||||||
|
lazyLoadQueue: this.lazyLoadQueue,
|
||||||
|
group: CHAT_ANIMATION_GROUP,
|
||||||
|
//play: !!message.pending || !multipleRender,
|
||||||
|
play: true,
|
||||||
|
loop: true,
|
||||||
|
withThumb: true,
|
||||||
|
loadPromises
|
||||||
|
});
|
||||||
|
|
||||||
|
attachClickEvent(stickerDiv, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
|
EmoticonsDropdown.onMediaClick({target: e.target});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.all(loadPromises);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.renderMessagesQueue(message, bubble, false, [loadPromise]);
|
||||||
|
|
||||||
|
elements.push(subtitle, stickerDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listElements) {
|
||||||
|
elements.push(
|
||||||
|
...listElements.map(elem => {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.classList.add('empty-placeholder-list-item');
|
||||||
|
span.append(elem);
|
||||||
|
return span;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if(type === 'group') {
|
||||||
|
listElements.forEach(elem => {
|
||||||
|
const i = document.createElement('span');
|
||||||
|
i.classList.add('tgico-check');
|
||||||
|
elem.prepend(i);
|
||||||
|
});
|
||||||
|
} else if(type === 'saved') {
|
||||||
|
listElements.forEach(elem => {
|
||||||
|
const i = document.createElement('span');
|
||||||
|
i.classList.add('empty-placeholder-list-bullet');
|
||||||
|
i.innerText = '•';
|
||||||
|
elem.prepend(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elements.length > 1) {
|
||||||
|
bubble.classList.add('has-description');
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.forEach((element: any) => element.classList.add('empty-placeholder-line'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private processLocalMessageRender(message: Message) {
|
||||||
|
const bubble = this.renderMessage(message);
|
||||||
bubble.classList.add('bubble-first', 'is-group-last', 'is-group-first');
|
bubble.classList.add('bubble-first', 'is-group-last', 'is-group-first');
|
||||||
bubble.classList.remove('can-have-tail', 'is-in');
|
bubble.classList.remove('can-have-tail', 'is-in');
|
||||||
|
|
||||||
const messageDiv = bubble.querySelector('.message');
|
const messageDiv = bubble.querySelector('.message, .service-msg');
|
||||||
|
const elements: (Node | string)[] = [];
|
||||||
|
if(this.appPeersManager.isBot(this.peerId)) {
|
||||||
const b = document.createElement('b');
|
const b = document.createElement('b');
|
||||||
b.append(i18n('BotInfoTitle'));
|
b.append(i18n('BotInfoTitle'));
|
||||||
messageDiv.prepend(b, '\n\n');
|
elements.push(b, '\n\n');
|
||||||
|
} else if(this.appPeersManager.isAnyGroup(this.peerId) && this.appPeersManager.getPeer(this.peerId).pFlags.creator) {
|
||||||
|
this.renderEmptyPlaceholder('group', bubble, message, elements);
|
||||||
|
} else if(rootScope.myId === this.peerId) {
|
||||||
|
this.renderEmptyPlaceholder('saved', bubble, message, elements);
|
||||||
|
} else if(this.peerId > 0 && this.appMessagesManager.canWriteToPeer(this.peerId) && this.chat.type === 'chat') {
|
||||||
|
this.renderEmptyPlaceholder('greeting', bubble, message, elements);
|
||||||
|
} else if(this.chat.type === 'scheduled') {
|
||||||
|
this.renderEmptyPlaceholder('noScheduledMessages', bubble, message, elements);
|
||||||
|
} else {
|
||||||
|
this.renderEmptyPlaceholder('noMessages', bubble, message, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for(let i = 1; i < elements.length; i += 2) {
|
||||||
|
elements.splice(i, 0, '\n');
|
||||||
|
} */
|
||||||
|
|
||||||
|
messageDiv.prepend(...elements);
|
||||||
|
|
||||||
if(this.messagesQueueOnRenderAdditional) {
|
if(this.messagesQueueOnRenderAdditional) {
|
||||||
this.onAnimateLadder = () => {
|
this.onAnimateLadder = () => {
|
||||||
@ -3080,6 +3219,29 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private generateLocalFirstMessage<T extends boolean>(service?: T, fill?: (message: GenerateLocalMessageType<T>) => void): GenerateLocalMessageType<T> {
|
||||||
|
const offset = this.appMessagesManager.generateMessageId(0);
|
||||||
|
|
||||||
|
const message: Omit<Message.message | Message.messageService, 'message'> & {message?: string} = {
|
||||||
|
_: service ? 'messageService' : 'message',
|
||||||
|
date: 0,
|
||||||
|
id: -(this.peerId + offset),
|
||||||
|
peer_id: this.appPeersManager.getOutputPeer(this.peerId),
|
||||||
|
pFlags: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!service) {
|
||||||
|
message.message = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
assumeType<GenerateLocalMessageType<T>>(message);
|
||||||
|
|
||||||
|
fill && fill(message);
|
||||||
|
|
||||||
|
this.appMessagesManager.saveMessages([message]);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
private setLoaded(side: SliceSides, value: boolean) {
|
private setLoaded(side: SliceSides, value: boolean) {
|
||||||
const willChange = this.scrollable.loadedAll[side] !== value;
|
const willChange = this.scrollable.loadedAll[side] !== value;
|
||||||
if(!willChange) {
|
if(!willChange) {
|
||||||
@ -3096,22 +3258,30 @@ export default class ChatBubbles {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const offset = this.appMessagesManager.generateMessageId(0);
|
const message = this.generateLocalFirstMessage(false, message => {
|
||||||
const message: Message.message = {
|
message.message = userFull.bot_info.description;
|
||||||
_: 'message',
|
});
|
||||||
date: 0,
|
|
||||||
id: -(this.peerId + offset),
|
|
||||||
message: userFull.bot_info.description,
|
|
||||||
peer_id: this.appPeersManager.getOutputPeer(this.peerId),
|
|
||||||
pFlags: {
|
|
||||||
bot_description: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.appMessagesManager.saveMessages([message]);
|
|
||||||
this.processLocalMessageRender(message);
|
this.processLocalMessageRender(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkIfEmptyPlaceholderNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkIfEmptyPlaceholderNeeded() {
|
||||||
|
if(this.scrollable.loadedAll.top &&
|
||||||
|
this.scrollable.loadedAll.bottom &&
|
||||||
|
!this.chatInner.childElementCount) {
|
||||||
|
this.log('inject empty peer placeholder');
|
||||||
|
|
||||||
|
const message = this.generateLocalFirstMessage(true);
|
||||||
|
this.processLocalMessageRender(message);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3409,6 +3579,8 @@ export default class ChatBubbles {
|
|||||||
delete this.dateMessages[i];
|
delete this.dateMessages[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkIfEmptyPlaceholderNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ export default class PopupForward extends PopupPickUser {
|
|||||||
},
|
},
|
||||||
onClose,
|
onClose,
|
||||||
placeholder: 'ShareModal.Search.ForwardPlaceholder',
|
placeholder: 'ShareModal.Search.ForwardPlaceholder',
|
||||||
chatRightsAction: 'send_messages'
|
chatRightsAction: 'send_messages',
|
||||||
|
selfPresence: 'ChatYourSelf'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ export default class PopupPickUser extends PopupElement {
|
|||||||
placeholder: LangPackKey,
|
placeholder: LangPackKey,
|
||||||
chatRightsAction?: AppSelectPeers['chatRightsAction'],
|
chatRightsAction?: AppSelectPeers['chatRightsAction'],
|
||||||
peerId?: number,
|
peerId?: number,
|
||||||
|
selfPresence?: LangPackKey
|
||||||
}) {
|
}) {
|
||||||
super('popup-forward', null, {closable: true, overlayClosable: true, body: true});
|
super('popup-forward', null, {closable: true, overlayClosable: true, body: true});
|
||||||
|
|
||||||
@ -54,7 +55,8 @@ export default class PopupPickUser extends PopupElement {
|
|||||||
rippleEnabled: false,
|
rippleEnabled: false,
|
||||||
avatarSize: 46,
|
avatarSize: 46,
|
||||||
peerId: options.peerId,
|
peerId: options.peerId,
|
||||||
placeholder: options.placeholder
|
placeholder: options.placeholder,
|
||||||
|
selfPresence: options.selfPresence
|
||||||
});
|
});
|
||||||
|
|
||||||
//this.scrollable = new Scrollable(this.body);
|
//this.scrollable = new Scrollable(this.body);
|
||||||
|
16
src/lang.ts
16
src/lang.ts
@ -494,6 +494,22 @@ const lang = {
|
|||||||
"AreYouSureClearDraftsTitle": "Delete cloud drafts",
|
"AreYouSureClearDraftsTitle": "Delete cloud drafts",
|
||||||
"AreYouSureClearDrafts": "Are you sure you want to delete all cloud drafts?",
|
"AreYouSureClearDrafts": "Are you sure you want to delete all cloud drafts?",
|
||||||
"BotInfoTitle": "What can this bot do?",
|
"BotInfoTitle": "What can this bot do?",
|
||||||
|
"ChatYourSelf": "forward here to save",
|
||||||
|
"GroupEmptyTitle1": "You have created a **group**.",
|
||||||
|
"GroupEmptyTitle2": "Groups can have:",
|
||||||
|
"GroupDescription1": "Up to 200,000 members",
|
||||||
|
"GroupDescription2": "Persistent chat history",
|
||||||
|
"GroupDescription3": "Public links such as t.me/title",
|
||||||
|
"GroupDescription4": "Admins with different rights",
|
||||||
|
"ChatYourSelfDescription1": "Forward messages here to save them",
|
||||||
|
"ChatYourSelfDescription2": "Send media and files to store them",
|
||||||
|
"ChatYourSelfDescription3": "Access this chat from any device",
|
||||||
|
"ChatYourSelfDescription4": "Use search to quickly find things",
|
||||||
|
"ChatYourSelfTitle": "Your cloud storage",
|
||||||
|
"ActionYouCreateGroup": "You created the group",
|
||||||
|
"NoMessages": "No messages here yet...",
|
||||||
|
"NoScheduledMessages": "No scheduled messages here yet...",
|
||||||
|
"NoMessagesGreetingsDescription": "Send a message or tap the greeting below.",
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
"AccountSettings.Filters": "Chat Folders",
|
"AccountSettings.Filters": "Chat Folders",
|
||||||
|
2
src/layer.d.ts
vendored
2
src/layer.d.ts
vendored
@ -833,7 +833,6 @@ export namespace Message {
|
|||||||
pinned?: true,
|
pinned?: true,
|
||||||
unread?: true,
|
unread?: true,
|
||||||
is_outgoing?: true,
|
is_outgoing?: true,
|
||||||
bot_description?: true,
|
|
||||||
}>,
|
}>,
|
||||||
id: number,
|
id: number,
|
||||||
from_id?: Peer,
|
from_id?: Peer,
|
||||||
@ -875,6 +874,7 @@ export namespace Message {
|
|||||||
legacy?: true,
|
legacy?: true,
|
||||||
unread?: true,
|
unread?: true,
|
||||||
is_outgoing?: true,
|
is_outgoing?: true,
|
||||||
|
is_single?: true,
|
||||||
}>,
|
}>,
|
||||||
id: number,
|
id: number,
|
||||||
from_id?: Peer,
|
from_id?: Peer,
|
||||||
|
@ -2788,12 +2788,22 @@ export class AppMessagesManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'messageActionChatCreate': {
|
||||||
|
const myId = appUsersManager.getSelf().id;
|
||||||
|
if(message.fromId === myId) {
|
||||||
|
_ += 'You';
|
||||||
|
} else {
|
||||||
|
args = [getNameDivHTML(message.fromId, plain)];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'messageActionPinMessage':
|
case 'messageActionPinMessage':
|
||||||
case 'messageActionContactSignUp':
|
case 'messageActionContactSignUp':
|
||||||
case 'messageActionChatReturn':
|
case 'messageActionChatReturn':
|
||||||
case 'messageActionChatLeave':
|
case 'messageActionChatLeave':
|
||||||
case 'messageActionChatJoined':
|
case 'messageActionChatJoined':
|
||||||
case 'messageActionChatCreate':
|
|
||||||
case 'messageActionChatEditPhoto':
|
case 'messageActionChatEditPhoto':
|
||||||
case 'messageActionChatDeletePhoto':
|
case 'messageActionChatDeletePhoto':
|
||||||
case 'messageActionChatEditVideo':
|
case 'messageActionChatEditVideo':
|
||||||
@ -3419,7 +3429,7 @@ export class AppMessagesManager {
|
|||||||
_: 'messageService',
|
_: 'messageService',
|
||||||
pFlags: {
|
pFlags: {
|
||||||
is_single: true
|
is_single: true
|
||||||
} as any,
|
},
|
||||||
id: this.generateMessageId(maxMessageId, true),
|
id: this.generateMessageId(maxMessageId, true),
|
||||||
date: message.date,
|
date: message.date,
|
||||||
from_id: {_: 'peerUser', user_id: 0}/* message.from_id */,
|
from_id: {_: 'peerUser', user_id: 0}/* message.from_id */,
|
||||||
|
@ -27,6 +27,10 @@ export class AppStickersManager {
|
|||||||
private getStickerSetPromises: {[setId: string]: Promise<MessagesStickerSet>} = {};
|
private getStickerSetPromises: {[setId: string]: Promise<MessagesStickerSet>} = {};
|
||||||
private getStickersByEmoticonsPromises: {[emoticon: string]: Promise<Document[]>} = {};
|
private getStickersByEmoticonsPromises: {[emoticon: string]: Promise<Document[]>} = {};
|
||||||
|
|
||||||
|
private greetingStickers: Document.document[];
|
||||||
|
private getGreetingStickersTimeout: number;
|
||||||
|
private getGreetingStickersPromise: Promise<void>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.getStickerSet({id: 'emoji'}, {saveById: true});
|
this.getStickerSet({id: 'emoji'}, {saveById: true});
|
||||||
|
|
||||||
@ -36,6 +40,37 @@ export class AppStickersManager {
|
|||||||
rootScope.dispatchEvent('stickers_installed', update.stickerset.set);
|
rootScope.dispatchEvent('stickers_installed', update.stickerset.set);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.getGreetingStickersTimeout = window.setTimeout(() => {
|
||||||
|
this.getGreetingStickersTimeout = undefined;
|
||||||
|
this.getGreetingSticker(true);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGreetingSticker(justPreload = false) {
|
||||||
|
if(this.getGreetingStickersTimeout) {
|
||||||
|
clearTimeout(this.getGreetingStickersTimeout);
|
||||||
|
this.getGreetingStickersTimeout = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.getGreetingStickersPromise) {
|
||||||
|
this.getGreetingStickersPromise = this.getStickersByEmoticon('👋', false).then(docs => {
|
||||||
|
this.greetingStickers = docs.slice() as Document.document[];
|
||||||
|
this.greetingStickers.sort((a, b) => Math.random() - Math.random());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getGreetingStickersPromise.then(() => {
|
||||||
|
let doc: Document.document;
|
||||||
|
if(!justPreload) {
|
||||||
|
doc = this.greetingStickers.shift();
|
||||||
|
this.greetingStickers.push(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
appDocsManager.downloadDoc(this.greetingStickers[0]); // preload next sticker
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveStickers(docs: Document[]) {
|
public saveStickers(docs: Document[]) {
|
||||||
@ -255,15 +290,15 @@ export class AppStickersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getStickersByEmoticon(emoticon: string) {
|
public getStickersByEmoticon(emoticon: string, includeOurStickers = true) {
|
||||||
if(this.getStickersByEmoticonsPromises[emoticon]) return this.getStickersByEmoticonsPromises[emoticon];
|
if(this.getStickersByEmoticonsPromises[emoticon]) return this.getStickersByEmoticonsPromises[emoticon];
|
||||||
|
|
||||||
return this.getStickersByEmoticonsPromises[emoticon] = Promise.all([
|
return this.getStickersByEmoticonsPromises[emoticon] = Promise.all([
|
||||||
apiManager.invokeApiHashable('messages.getStickers', {
|
apiManager.invokeApiHashable('messages.getStickers', {
|
||||||
emoticon
|
emoticon
|
||||||
}),
|
}),
|
||||||
this.preloadStickerSets(),
|
includeOurStickers ? this.preloadStickerSets() : [],
|
||||||
this.getRecentStickers()
|
includeOurStickers ? this.getRecentStickers().then(res => res.packs) : []
|
||||||
]).then(([messagesStickers, installedSets, recentStickers]) => {
|
]).then(([messagesStickers, installedSets, recentStickers]) => {
|
||||||
const foundStickers = (messagesStickers as MessagesStickers.messagesStickers).stickers.map(sticker => appDocsManager.saveDoc(sticker));
|
const foundStickers = (messagesStickers as MessagesStickers.messagesStickers).stickers.map(sticker => appDocsManager.saveDoc(sticker));
|
||||||
const cachedStickersAnimated: Document.document[] = [], cachedStickersStatic: Document.document[] = [];
|
const cachedStickersAnimated: Document.document[] = [], cachedStickersStatic: Document.document[] = [];
|
||||||
@ -281,7 +316,7 @@ export class AppStickersManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
iteratePacks(recentStickers.packs);
|
iteratePacks(recentStickers);
|
||||||
|
|
||||||
for(const set of installedSets) {
|
for(const set of installedSets) {
|
||||||
iteratePacks(set.packs);
|
iteratePacks(set.packs);
|
||||||
|
@ -17,6 +17,7 @@ import rootScope from "./rootScope";
|
|||||||
|
|
||||||
export const langPack: {[actionType: string]: LangPackKey} = {
|
export const langPack: {[actionType: string]: LangPackKey} = {
|
||||||
"messageActionChatCreate": "ActionCreateGroup",
|
"messageActionChatCreate": "ActionCreateGroup",
|
||||||
|
"messageActionChatCreateYou": "ActionYouCreateGroup",
|
||||||
"messageActionChatEditTitle": "ActionChangedTitle",
|
"messageActionChatEditTitle": "ActionChangedTitle",
|
||||||
"messageActionChatEditPhoto": "ActionChangedPhoto",
|
"messageActionChatEditPhoto": "ActionChangedPhoto",
|
||||||
"messageActionChatEditVideo": "ActionChangedVideo",
|
"messageActionChatEditVideo": "ActionChangedVideo",
|
||||||
|
@ -51,8 +51,7 @@
|
|||||||
{"name": "unread", "type": "true"},
|
{"name": "unread", "type": "true"},
|
||||||
{"name": "is_outgoing", "type": "true"},
|
{"name": "is_outgoing", "type": "true"},
|
||||||
{"name": "rReply", "type": "string"},
|
{"name": "rReply", "type": "string"},
|
||||||
{"name": "viaBotId", "type": "number"},
|
{"name": "viaBotId", "type": "number"}
|
||||||
{"name": "bot_description", "type": "true"}
|
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"predicate": "messageService",
|
"predicate": "messageService",
|
||||||
@ -64,7 +63,8 @@
|
|||||||
{"name": "unread", "type": "true"},
|
{"name": "unread", "type": "true"},
|
||||||
{"name": "is_outgoing", "type": "true"},
|
{"name": "is_outgoing", "type": "true"},
|
||||||
{"name": "rReply", "type": "string"},
|
{"name": "rReply", "type": "string"},
|
||||||
{"name": "viaBotId", "type": "number"}
|
{"name": "viaBotId", "type": "number"},
|
||||||
|
{"name": "is_single", "type": "true"}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"predicate": "messageEmpty",
|
"predicate": "messageEmpty",
|
||||||
|
@ -111,6 +111,10 @@ Utility Classes
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .reset-align {
|
||||||
|
text-align: unset;
|
||||||
|
} */
|
||||||
|
|
||||||
.justify-start {
|
.justify-start {
|
||||||
justify-content: flex-start!important;
|
justify-content: flex-start!important;
|
||||||
}
|
}
|
||||||
|
@ -728,6 +728,81 @@ $bubble-margin: .25rem;
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
&.empty-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
&.has-description {
|
||||||
|
.service-msg {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
padding: .75rem 1rem .875rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-placeholder-title {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-content {
|
||||||
|
border-radius: 1.5rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-placeholder-line + .empty-placeholder-line {
|
||||||
|
margin-top: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tgico-check {
|
||||||
|
margin-right: .25rem;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin-left: -.1875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-placeholder-list-bullet {
|
||||||
|
margin-right: .3125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:first-child:last-child) {
|
||||||
|
.bubble-content-wrapper {
|
||||||
|
transform: scale3d(.8, .8, 1) translateX(0);
|
||||||
|
//transform: scale(.8) translateX(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.empty-placeholder-group {
|
||||||
|
.empty-placeholder-list-item {
|
||||||
|
margin-top: .4375rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.empty-placeholder-greeting {
|
||||||
|
.service-msg {
|
||||||
|
max-width: 232px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-placeholder-subtitle {
|
||||||
|
margin-top: .25rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-placeholder-sticker {
|
||||||
|
margin-top: .75rem !important;
|
||||||
|
position: relative;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.time {
|
.time {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@ -1641,9 +1716,11 @@ $bubble-margin: .25rem;
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bubble:not(.service) & {
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
max-width: 85%;
|
max-width: 85%;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
max-width: calc(100% - var(--message-handhelds-margin));
|
max-width: calc(100% - var(--message-handhelds-margin));
|
||||||
@ -1681,6 +1758,10 @@ $bubble-margin: .25rem;
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
b {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.bubble-content {
|
.bubble-content {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: .875rem;
|
border-radius: .875rem;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user