Browse Source

reply to message & save sidebar right state

master
Eduard Kuzmenko 4 years ago
parent
commit
ff118053f6
  1. 6
      src/components/pageIm.ts
  2. 5
      src/lib/appManagers/appDialogsManager.ts
  3. 54
      src/lib/appManagers/appImManager.ts
  4. 12
      src/lib/appManagers/appMessagesManager.ts
  5. 80
      src/lib/appManagers/appSidebarRight.ts
  6. 138
      src/scss/partials/_chat.scss
  7. 7
      src/scss/partials/_chatlist.scss

6
src/components/pageIm.ts

@ -594,7 +594,11 @@ export default () => import('../lib/services').then(services => {
//console.log('childnode str after:', str); //console.log('childnode str after:', str);
appMessagesManager.sendText(appImManager.peerID, str); appMessagesManager.sendText(appImManager.peerID, str, {
replyToMsgID: appImManager.replyToMsgID == 0 ? undefined : appImManager.replyToMsgID
});
appImManager.replyToMsgID = 0;
appImManager.replyElements.container.classList.remove('active');
appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight; appImManager.scroll.scrollTop = appImManager.scroll.scrollHeight;
messageInput.innerText = ''; messageInput.innerText = '';

5
src/lib/appManagers/appDialogsManager.ts

@ -146,6 +146,11 @@ export class AppDialogsManager {
let dialog = dialogs[i]; let dialog = dialogs[i];
if(!dialog.pFlags.pinned) break; if(!dialog.pFlags.pinned) break;
pinnedDialogs.push(dialog); pinnedDialogs.push(dialog);
let dom = this.getDialogDom(dialog.peerID);
if(dom) {
dom.listEl.append(this.pinnedDelimiter);
}
} }
let sorted = dialogs let sorted = dialogs

54
src/lib/appManagers/appImManager.ts

@ -140,6 +140,13 @@ export class AppImManager {
private contextMenuPin = this.contextMenu.querySelector('.menu-pin') as HTMLDivElement; private contextMenuPin = this.contextMenu.querySelector('.menu-pin') as HTMLDivElement;
private contextMenuMsgID: number; private contextMenuMsgID: number;
public replyElements: {
container?: HTMLDivElement,
cancelBtn?: HTMLButtonElement,
titleEl?: HTMLDivElement,
subtitleEl?: HTMLDivElement
} = {};
private popupDeleteMessage: { private popupDeleteMessage: {
popupEl?: HTMLDivElement, popupEl?: HTMLDivElement,
deleteBothBtn?: HTMLButtonElement, deleteBothBtn?: HTMLButtonElement,
@ -147,6 +154,8 @@ export class AppImManager {
cancelBtn?: HTMLButtonElement cancelBtn?: HTMLButtonElement
} = {}; } = {};
public replyToMsgID = 0;
constructor() { constructor() {
this.log = logger('IM'); this.log = logger('IM');
@ -157,6 +166,11 @@ export class AppImManager {
this.popupDeleteMessage.deleteMeBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-delete-me') as HTMLButtonElement; this.popupDeleteMessage.deleteMeBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-delete-me') as HTMLButtonElement;
this.popupDeleteMessage.cancelBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-close') as HTMLButtonElement; this.popupDeleteMessage.cancelBtn = this.popupDeleteMessage.popupEl.querySelector('.popup-close') as HTMLButtonElement;
this.replyElements.container = this.pageEl.querySelector('.reply-wrapper') as HTMLDivElement;
this.replyElements.cancelBtn = this.replyElements.container.querySelector('.reply-cancel') as HTMLButtonElement;
this.replyElements.titleEl = this.replyElements.container.querySelector('.reply-title') as HTMLDivElement;
this.replyElements.subtitleEl = this.replyElements.container.querySelector('.reply-subtitle') as HTMLDivElement;
apiManager.getUserID().then((id) => { apiManager.getUserID().then((id) => {
this.myID = id; this.myID = id;
}); });
@ -356,6 +370,15 @@ export class AppImManager {
this.popupDeleteMessage.popupEl.classList.add('active'); this.popupDeleteMessage.popupEl.classList.add('active');
}); });
this.contextMenu.querySelector('.menu-reply').addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.contextMenuMsgID);
let title = appPeersManager.getPeerTitle(message.fromID).split(' ')[0];
this.replyElements.titleEl.innerText = title;
this.replyElements.subtitleEl.innerText = message.message || '';
this.replyElements.container.classList.add('active');
this.replyToMsgID = this.contextMenuMsgID;
});
this.contextMenuPin.addEventListener('click', () => { this.contextMenuPin.addEventListener('click', () => {
apiManager.invokeApi('messages.updatePinnedMessage', { apiManager.invokeApi('messages.updatePinnedMessage', {
@ -368,6 +391,11 @@ export class AppImManager {
}); });
}); });
this.replyElements.cancelBtn.addEventListener('click', () => {
this.replyElements.container.classList.remove('active');
this.replyToMsgID = 0;
});
this.popupDeleteMessage.deleteBothBtn.addEventListener('click', () => { this.popupDeleteMessage.deleteBothBtn.addEventListener('click', () => {
this.deleteMessages(true); this.deleteMessages(true);
this.popupDeleteMessage.cancelBtn.click(); this.popupDeleteMessage.cancelBtn.click();
@ -1113,7 +1141,7 @@ export class AppImManager {
/* let fromTitle = */appPeersManager.getPeerTitle(fwd.from_id); /* let fromTitle = */appPeersManager.getPeerTitle(fwd.from_id);
} }
if((this.peerID < 0 && !our) || message.fwd_from) { // chat if((this.peerID < 0 && !our) || message.fwd_from || message.reply_to_mid) { // chat
let title = appPeersManager.getPeerTitle(message.fwdFromID || message.fromID); let title = appPeersManager.getPeerTitle(message.fwdFromID || message.fromID);
//this.log(title); //this.log(title);
@ -1152,6 +1180,7 @@ export class AppImManager {
box.append(quote); box.append(quote);
bubble.append(box); bubble.append(box);
//bubble.classList.add('reply');
} }
/* if(message.media) { /* if(message.media) {
@ -1171,7 +1200,7 @@ export class AppImManager {
nameDiv.classList.add('name'); nameDiv.classList.add('name');
nameDiv.innerText = title; nameDiv.innerText = title;
bubble.append(nameDiv); bubble.append(nameDiv);
} else { } else if(!message.reply_to_mid) {
bubble.classList.add('hide-name'); bubble.classList.add('hide-name');
} }
@ -1243,11 +1272,22 @@ export class AppImManager {
let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); let justDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
let dateTimestamp = justDate.getTime(); let dateTimestamp = justDate.getTime();
if(!(dateTimestamp in this.dateMessages)) { if(!(dateTimestamp in this.dateMessages)) {
const months = ['January', 'February', 'March', 'April', 'May', 'June', let str = '';
'July', 'August', 'September', 'October', 'November', 'December'];
let str = justDate.getFullYear() == new Date().getFullYear() ? let today = new Date();
months[justDate.getMonth()] + ' ' + justDate.getDate() : today.setHours(0);
justDate.toISOString().split('T')[0].split('-').reverse().join('.'); today.setMinutes(0);
today.setSeconds(0);
if(today < date) {
str = 'Today';
} else {
const months = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'];
str = justDate.getFullYear() == new Date().getFullYear() ?
months[justDate.getMonth()] + ' ' + justDate.getDate() :
justDate.toISOString().split('T')[0].split('-').reverse().join('.');
}
let div = document.createElement('div'); let div = document.createElement('div');
div.classList.add('service'); div.classList.add('service');

12
src/lib/appManagers/appMessagesManager.ts

@ -188,7 +188,7 @@ export class AppMessagesManager {
var message: any; var message: any;
if(historyStorage === undefined) { if(historyStorage === undefined) {
historyStorage = this.historiesStorage[peerID] = {count: null, history: [], pending: []} historyStorage = this.historiesStorage[peerID] = {count: null, history: [], pending: []};
} }
var fromID = appUsersManager.getSelf().id; var fromID = appUsersManager.getSelf().id;
@ -203,14 +203,14 @@ export class AppMessagesManager {
} }
if(replyToMsgID) { if(replyToMsgID) {
flags |= 8 flags |= 8;
} }
if(asChannel) { if(asChannel) {
fromID = 0 fromID = 0;
pFlags.post = true pFlags.post = true;
} else { } else {
flags |= 256 flags |= 256;
} }
message = { message = {
@ -340,7 +340,7 @@ export class AppMessagesManager {
if(this.pendingAfterMsgs[peerID] === sentRequestOptions) { if(this.pendingAfterMsgs[peerID] === sentRequestOptions) {
delete this.pendingAfterMsgs[peerID]; delete this.pendingAfterMsgs[peerID];
} }
}) });
this.pendingAfterMsgs[peerID] = sentRequestOptions; this.pendingAfterMsgs[peerID] = sentRequestOptions;
} }

80
src/lib/appManagers/appSidebarRight.ts

@ -21,6 +21,7 @@ class AppSidebarRight {
bio: this.profileContentEl.querySelector('.profile-row-bio') as HTMLDivElement, bio: this.profileContentEl.querySelector('.profile-row-bio') as HTMLDivElement,
username: this.profileContentEl.querySelector('.profile-row-username') as HTMLDivElement, username: this.profileContentEl.querySelector('.profile-row-username') as HTMLDivElement,
phone: this.profileContentEl.querySelector('.profile-row-phone') as HTMLDivElement, phone: this.profileContentEl.querySelector('.profile-row-phone') as HTMLDivElement,
notificationsRow: this.profileContentEl.querySelector('.profile-row-notifications') as HTMLDivElement,
notificationsCheckbox: this.profileContentEl.querySelector('#profile-notifications') as HTMLInputElement, notificationsCheckbox: this.profileContentEl.querySelector('#profile-notifications') as HTMLInputElement,
notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p') as HTMLParagraphElement notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p') as HTMLParagraphElement
}; };
@ -69,23 +70,53 @@ class AppSidebarRight {
private peerID = 0; private peerID = 0;
public sidebarScroll: Scrollable = null; public sidebarScroll: Scrollable = null;
private savedVirtualStates: {
[id: number]: {
hiddenElements: any,
paddings: any
}
}
private profileTabs: HTMLUListElement;
private prevTabID = -1;
constructor() { constructor() {
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement; let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
let tabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement; this.profileTabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement;
this.sidebarScroll = new Scrollable(this.sidebarEl); this.sidebarScroll = new Scrollable(this.sidebarEl);
this.sidebarScroll.container.addEventListener('scroll', this.onSidebarScroll.bind(this)); this.sidebarScroll.container.addEventListener('scroll', this.onSidebarScroll.bind(this));
horizontalMenu(tabs, container, (id, tabContent) => { horizontalMenu(this.profileTabs, container, (id, tabContent) => {
this.sharedMediaType = this.sharedMediaTypes[id]; this.sharedMediaType = this.sharedMediaTypes[id];
this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement; this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement;
this.log('setVirtualContainer', this.sharedMediaSelected); if(this.prevTabID != -1) {
this.savedVirtualStates[this.prevTabID] = {
hiddenElements: {
up: this.sidebarScroll.hiddenElements.up.slice(),
down: this.sidebarScroll.hiddenElements.down.slice(),
},
paddings: {
up: this.sidebarScroll.paddings.up,
down: this.sidebarScroll.paddings.down
}
};
}
this.prevTabID = id;
this.log('setVirtualContainer', id, this.sharedMediaSelected);
this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected); this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
if(this.savedVirtualStates[id]) {
this.log(this.savedVirtualStates[id]);
this.sidebarScroll.hiddenElements = this.savedVirtualStates[id].hiddenElements;
this.sidebarScroll.paddings = this.savedVirtualStates[id].paddings;
}
}, this.onSidebarScroll.bind(this)); }, this.onSidebarScroll.bind(this));
(tabs.children[1] as HTMLLIElement).click(); // set media //(this.profileTabs.children[1] as HTMLLIElement).click(); // set media
let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement; let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement;
sidebarCloseBtn.addEventListener('click', () => { sidebarCloseBtn.addEventListener('click', () => {
@ -297,14 +328,21 @@ class AppSidebarRight {
this.loadSidebarMediaPromises = {}; this.loadSidebarMediaPromises = {};
this.lastSharedMediaDiv = document.createElement('div'); this.lastSharedMediaDiv = document.createElement('div');
this.log('fillProfileElements');
this.savedVirtualStates = {};
this.prevTabID = -1;
(this.profileTabs.children[1] as HTMLLIElement).click(); // set media
if(this.sharedMediaSelected) { if(this.sharedMediaSelected) {
this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected); //this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
} }
this.profileContentEl.parentElement.scrollTop = 0; this.profileContentEl.parentElement.scrollTop = 0;
this.profileElements.bio.style.display = 'none'; this.profileElements.bio.style.display = 'none';
this.profileElements.phone.style.display = 'none'; this.profileElements.phone.style.display = 'none';
this.profileElements.username.style.display = 'none'; this.profileElements.username.style.display = 'none';
this.profileElements.notificationsRow.style.display = '';
this.profileElements.notificationsCheckbox.checked = true; this.profileElements.notificationsCheckbox.checked = true;
this.profileElements.notificationsStatus.innerText = 'Enabled'; this.profileElements.notificationsStatus.innerText = 'Enabled';
@ -329,14 +367,16 @@ class AppSidebarRight {
}; };
// username // username
let username = appPeersManager.getPeerUsername(peerID); if(peerID != appImManager.myID) {
if(username) { let username = appPeersManager.getPeerUsername(peerID);
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username); if(username) {
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username);
}
} }
if(peerID > 0) { if(peerID > 0) {
let user = appUsersManager.getUser(peerID); let user = appUsersManager.getUser(peerID);
if(user.phone) { if(user.phone && peerID != appImManager.myID) {
setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone); setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone);
} }
@ -346,7 +386,7 @@ class AppSidebarRight {
return; return;
} }
if(userFull.rAbout) { if(userFull.rAbout && peerID != appImManager.myID) {
setText(userFull.rAbout, this.profileElements.bio); setText(userFull.rAbout, this.profileElements.bio);
} }
@ -374,15 +414,19 @@ class AppSidebarRight {
}); });
} }
let dialog: any = appMessagesManager.getDialogByPeerID(peerID); if(peerID != appImManager.myID) {
if(dialog.length) { let dialog: any = appMessagesManager.getDialogByPeerID(peerID);
dialog = dialog[0]; if(dialog.length) {
let muted = false; dialog = dialog[0];
if(dialog.notify_settings && dialog.notify_settings.mute_until) { let muted = false;
muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date(); if(dialog.notify_settings && dialog.notify_settings.mute_until) {
muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date();
}
appImManager.setMutedState(muted);
} }
} else {
appImManager.setMutedState(muted); this.profileElements.notificationsRow.style.display = 'none';
} }
//this.loadSidebarMedia(); //this.loadSidebarMedia();

138
src/scss/partials/_chat.scss

@ -94,54 +94,6 @@
} }
} }
} }
.pinned-message {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
overflow: hidden;
box-sizing: border-box;
width: 150px;
margin-right: 1rem;
max-height: 35px;
/* padding: .25rem; */
&:hover {
background-color: rgba(112, 117, 121, 0.08);
}
.pinned-message-border {
height: 32px;
border-radius: 1px;
min-width: 2px;
background: $blue;
}
.pinned-message-content {
margin-left: 8px;
flex-grow: 1;
flex-shrink: 1;
overflow: hidden;
pointer-events: none;
}
.pinned-message-title {
color: $blue;
}
.pinned-message-title, .pinned-message-subtitle {
font-size: 14px;
line-height: 18px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.pinned-message-subtitle {
white-space: nowrap;
}
}
} }
#bubbles { #bubbles {
@ -418,6 +370,7 @@
.name { .name {
font-weight: 500; font-weight: 500;
display: inline!important;
} }
&:not(.web) { &:not(.web) {
@ -720,14 +673,15 @@
.input-message { .input-message {
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column;
width: calc(100% - 3.75rem); width: calc(100% - 3.75rem);
justify-content: space-between; justify-content: center;
background-color: #fff; background-color: #fff;
border-radius: 12px; border-radius: 12px;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07); box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07);
margin-right: .5rem; margin-right: .5rem;
padding: 0 .5rem; padding: 4.5px .5rem;
min-height: 3.25rem; min-height: 3.25rem;
max-height: 30rem; max-height: 30rem;
caret-color: $button-primary-background; caret-color: $button-primary-background;
@ -747,6 +701,41 @@
transform: scaleX(-1); transform: scaleX(-1);
} }
> div {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
//min-height: inherit;
}
.reply-wrapper {
justify-content: flex-start;
overflow: hidden;
transition: .2s all;
height: 0px;
&.active {
height: 35px;
}
.reply {
width: 100%;
margin-left: .5rem;
min-height: 35px;
}
}
.new-message-wrapper {
//padding: 4.5px 0;
//padding-bottom: 4.5px;
align-items: flex-end;
.btn-icon:before {
vertical-align: middle;
}
}
.input-message-container { .input-message-container {
width: 1%; width: 1%;
max-height: inherit; max-height: inherit;
@ -804,6 +793,7 @@
width: 3.25rem; width: 3.25rem;
color: #9e9e9e; color: #9e9e9e;
background-color: #fff; background-color: #fff;
align-self: flex-end;
&.tgico-send { &.tgico-send {
color: $blue; color: $blue;
@ -815,6 +805,54 @@
} }
} }
.pinned-message, .reply {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
overflow: hidden;
box-sizing: border-box;
width: 150px;
margin-right: 1rem;
max-height: 35px;
/* padding: .25rem; */
&:hover {
background-color: rgba(112, 117, 121, 0.08);
}
&-border {
height: 32px;
border-radius: 1px;
min-width: 2px;
background: $blue;
}
&-content {
margin-left: 8px;
flex-grow: 1;
flex-shrink: 1;
overflow: hidden;
pointer-events: none;
}
&-title {
color: $blue;
}
&-title, &-subtitle {
font-size: 14px;
line-height: 18px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&-subtitle {
white-space: nowrap;
}
}
/* #chat-closed { /* #chat-closed {
position: absolute; position: absolute;
left: 0; left: 0;

7
src/scss/partials/_chatlist.scss

@ -99,10 +99,15 @@
align-items: center; align-items: center;
height: 1.7rem; // hot-fix height: 1.7rem; // hot-fix
span:not(.tgico-pinnedchat):not(.emoji):last-child { /* span:not(.tgico-pinnedchat):not(.emoji):last-child { */
.user-title + span {
/* font-size: .9rem; */ /* font-size: .9rem; */
font-size: .8rem; font-size: .8rem;
} }
.user-last-message + span:not(.tgico-pinnedchat) {
font-size: .9rem;
}
} }
span { span {

Loading…
Cancel
Save