Browse Source

Handle peer change for chat list elements

Handle contextmenu event for ripple
master
Eduard Kuzmenko 4 years ago
parent
commit
44beca2458
  1. 7
      src/components/appSearch.ts
  2. 5
      src/components/ripple.ts
  3. 10
      src/components/sidebarLeft/index.ts
  4. 3
      src/components/sidebarLeft/tabs/contacts.ts
  5. 2
      src/components/sidebarRight/tabs/pollResults.ts
  6. 112
      src/lib/appManagers/appDialogsManager.ts

7
src/components/appSearch.ts

@ -15,7 +15,7 @@ export class SearchGroup {
nameEl: HTMLDivElement; nameEl: HTMLDivElement;
list: HTMLUListElement; list: HTMLUListElement;
constructor(public name: string, public type: string, private clearable = true, className?: string, clickable = true) { constructor(public name: string, public type: string, private clearable = true, className?: string, clickable = true, public autonomous = true) {
this.list = document.createElement('ul'); this.list = document.createElement('ul');
this.container = document.createElement('div'); this.container = document.createElement('div');
if(className) this.container.className = className; if(className) this.container.className = className;
@ -32,7 +32,7 @@ export class SearchGroup {
this.container.style.display = 'none'; this.container.style.display = 'none';
if(clickable) { if(clickable) {
appDialogsManager.setListClickListener(this.list); appDialogsManager.setListClickListener(this.list, undefined, undefined, autonomous);
} }
} }
@ -183,7 +183,8 @@ export default class AppSearch {
dialog: peerId, dialog: peerId,
container: group.list, container: group.list,
drawStatus: false, drawStatus: false,
avatarSize: 48 avatarSize: 48,
autonomous: group.autonomous
}); });
if(showMembersCount && (peer.participants_count || peer.participants)) { if(showMembersCount && (peer.participants_count || peer.participants)) {

5
src/components/ripple.ts

@ -55,6 +55,10 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
}, duration / 2); }, duration / 2);
} }
if(!isTouchSupported) {
window.removeEventListener('contextmenu', handler);
}
handler = null; handler = null;
touchStartFired = false; touchStartFired = false;
}; };
@ -171,6 +175,7 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
let {clientX, clientY} = e; let {clientX, clientY} = e;
drawRipple(clientX, clientY); drawRipple(clientX, clientY);
window.addEventListener('mouseup', handler, {once: true}); window.addEventListener('mouseup', handler, {once: true});
window.addEventListener('contextmenu', handler, {once: true});
}); });
} }
} }

10
src/components/sidebarLeft/index.ts

@ -167,8 +167,8 @@ export class AppSidebarLeft extends SidebarSlider {
contacts: new SearchGroup('Chats', 'contacts'), contacts: new SearchGroup('Chats', 'contacts'),
globalContacts: new SearchGroup('Global Search', 'contacts'), globalContacts: new SearchGroup('Global Search', 'contacts'),
messages: new SearchGroup('Global Search', 'messages'), messages: new SearchGroup('Global Search', 'messages'),
people: new SearchGroup('People', 'contacts', false, 'search-group-people'), people: new SearchGroup('People', 'contacts', false, 'search-group-people', true, false),
recent: new SearchGroup('Recent', 'contacts', false, 'search-group-recent') recent: new SearchGroup('Recent', 'contacts', false, 'search-group-recent', true, false)
}; };
this.globalSearch = new AppSearch(this.searchContainer, this.inputSearch, this.searchGroups, (count) => { this.globalSearch = new AppSearch(this.searchContainer, this.inputSearch, this.searchGroups, (count) => {
@ -222,7 +222,8 @@ export class AppSidebarLeft extends SidebarSlider {
container: this.searchGroups.people.list, container: this.searchGroups.people.list,
drawStatus: false, drawStatus: false,
onlyFirstName: true, onlyFirstName: true,
avatarSize: 54 avatarSize: 54,
autonomous: false
}); });
}); });
} }
@ -358,7 +359,8 @@ export class AppSidebarLeft extends SidebarSlider {
container: this.searchGroups.recent.list, container: this.searchGroups.recent.list,
drawStatus: false, drawStatus: false,
meAsSaved: true, meAsSaved: true,
avatarSize: 48 avatarSize: 48,
autonomous: false
}); });
dom.lastMessageSpan.innerText = peerId > 0 ? appUsersManager.getUserStatusString(peerId) : appChatsManager.getChatMembersString(peerId); dom.lastMessageSpan.innerText = peerId > 0 ? appUsersManager.getUserStatusString(peerId) : appChatsManager.getChatMembersString(peerId);

3
src/components/sidebarLeft/tabs/contacts.ts

@ -94,7 +94,8 @@ export default class AppContactsTab implements SliderTab {
dialog: user.id, dialog: user.id,
container: this.list, container: this.list,
drawStatus: false, drawStatus: false,
avatarSize: 48 avatarSize: 48,
autonomous: false
}); });
let status = appUsersManager.getUserStatusString(user.id); let status = appUsersManager.getUserStatusString(user.id);

2
src/components/sidebarRight/tabs/pollResults.ts

@ -72,7 +72,7 @@ export default class AppPollResultsTab implements SliderTab {
appDialogsManager.setListClickListener(list, () => { appDialogsManager.setListClickListener(list, () => {
this.closeBtn.click(); this.closeBtn.click();
}); }, undefined, true);
list.style.minHeight = Math.min(result.voters, 4) * 50 + 'px'; list.style.minHeight = Math.min(result.voters, 4) * 50 + 'px';

112
src/lib/appManagers/appDialogsManager.ts

@ -4,16 +4,16 @@ import { horizontalMenu } from "../../components/horizontalMenu";
import { attachContextMenuListener, putPreloader } from "../../components/misc"; import { attachContextMenuListener, putPreloader } from "../../components/misc";
import { ripple } from "../../components/ripple"; import { ripple } from "../../components/ripple";
//import Scrollable from "../../components/scrollable"; //import Scrollable from "../../components/scrollable";
import Scrollable, { ScrollableX, SliceSides, SliceSidesContainer } from "../../components/scrollable"; import Scrollable, { ScrollableX, SliceSides } from "../../components/scrollable";
import appSidebarLeft from "../../components/sidebarLeft"; import appSidebarLeft from "../../components/sidebarLeft";
import { formatDateAccordingToToday } from "../../helpers/date"; import { formatDateAccordingToToday } from "../../helpers/date";
import { escapeRegExp } from "../../helpers/string"; import { escapeRegExp } from "../../helpers/string";
import { isApple, isSafari } from "../../helpers/userAgent"; import { isApple } from "../../helpers/userAgent";
import { logger, LogLevels } from "../logger"; import { logger, LogLevels } from "../logger";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope"; import rootScope from "../rootScope";
import { findUpClassName, findUpTag, positionElementByIndex } from "../../helpers/dom"; import { findUpClassName, findUpTag, positionElementByIndex } from "../../helpers/dom";
import appImManager, { AppImManager } from "./appImManager"; import appImManager from "./appImManager";
import appMessagesManager, { Dialog } from "./appMessagesManager"; import appMessagesManager, { Dialog } from "./appMessagesManager";
import {MyDialogFilter as DialogFilter} from "../storages/filters"; import {MyDialogFilter as DialogFilter} from "../storages/filters";
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
@ -157,7 +157,6 @@ export class AppDialogsManager {
public chatList = this._chatList; public chatList = this._chatList;
public doms: {[peerId: number]: DialogDom} = {}; public doms: {[peerId: number]: DialogDom} = {};
public lastActiveListElement: HTMLElement = null;
public chatsContainer = document.getElementById('chatlist-container') as HTMLDivElement; public chatsContainer = document.getElementById('chatlist-container') as HTMLDivElement;
private chatsPreloader: HTMLDivElement; private chatsPreloader: HTMLDivElement;
@ -199,6 +198,8 @@ export class AppDialogsManager {
private sliceTimeout: number; private sliceTimeout: number;
private reorderDialogsTimeout: number; private reorderDialogsTimeout: number;
private lastActiveElements: Set<HTMLElement> = new Set();
constructor() { constructor() {
this.chatsPreloader = putPreloader(null, true); this.chatsPreloader = putPreloader(null, true);
@ -335,21 +336,22 @@ export class AppDialogsManager {
}); });
rootScope.on('peer_changed', (e) => { rootScope.on('peer_changed', (e) => {
let peerId = e.detail; const peerId = e.detail;
let lastPeerId = this.lastActiveListElement && +this.lastActiveListElement.getAttribute('data-peerId'); //const perf = performance.now();
if(this.lastActiveListElement && lastPeerId != peerId) { for(const element of this.lastActiveElements) {
this.lastActiveListElement.classList.remove('active'); if(+element.getAttribute('data-peerid') !== peerId) {
this.lastActiveListElement = null; element.classList.remove('active');
} this.lastActiveElements.delete(element);
if(lastPeerId != peerId) {
let dom = this.getDialogDom(peerId);
if(dom) {
this.lastActiveListElement = dom.listEl;
dom.listEl.classList.add('active');
} }
} }
const elements = Array.from(document.querySelectorAll(`[data-autonomous="0"] li[data-peerid="${peerId}"]`)) as HTMLElement[];
elements.forEach(element => {
element.classList.add('active');
this.lastActiveElements.add(element);
});
//this.log('peer_changed total time:', performance.now() - perf);
}); });
rootScope.on('filter_update', (e) => { rootScope.on('filter_update', (e) => {
@ -519,7 +521,6 @@ export class AppDialogsManager {
this.doms = {}; this.doms = {};
this.scroll.loadedAll.top = true; this.scroll.loadedAll.top = true;
this.scroll.loadedAll.bottom = false; this.scroll.loadedAll.bottom = false;
this.lastActiveListElement = null;
this.loadDialogsPromise = undefined; this.loadDialogsPromise = undefined;
this.chatList = this.chatLists[this.filterId]; this.chatList = this.chatLists[this.filterId];
this.loadDialogs(); this.loadDialogs();
@ -561,10 +562,6 @@ export class AppDialogsManager {
const listEl = this.doms[peerId].listEl; const listEl = this.doms[peerId].listEl;
listEl.remove(); listEl.remove();
delete this.doms[peerId]; delete this.doms[peerId];
if(this.lastActiveListElement == listEl) {
this.lastActiveListElement = null;
}
} }
} }
} }
@ -687,50 +684,17 @@ export class AppDialogsManager {
if(result.dialogs.length) { if(result.dialogs.length) {
const dialogs = side == 'top' ? result.dialogs.slice().reverse() : result.dialogs; const dialogs = side == 'top' ? result.dialogs.slice().reverse() : result.dialogs;
/* let previousScrollHeightMinusTop: number;
//if(isApple || true) {
if(isApple && side == 'top') {
const {scrollTop, scrollHeight} = this.scroll;
previousScrollHeightMinusTop = side == 'top' ? scrollHeight - scrollTop : scrollTop;
//this.scroll.scrollLocked = 1;
} */
dialogs.forEach((dialog) => { dialogs.forEach((dialog) => {
this.addDialogNew({ this.addDialogNew({
dialog, dialog,
append: side == 'bottom' append: side == 'bottom'
}); });
}); });
/* if(previousScrollHeightMinusTop !== undefined) {
const newScrollTop = side == 'top' ? this.scroll.scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
// touchSupport for safari iOS
isTouchSupported && isApple && (this.scroll.container.style.overflow = 'hidden');
this.scroll.scrollTop = newScrollTop;
isTouchSupported && isApple && (this.scroll.container.style.overflow = '');
} */
//this.scroll.scrollLocked = 0;
//if(side == 'bottom' || true || (testTopSlice-- > 0 && side == 'top')) {
//setTimeout(() => {
/* const sliced = this.scroll.slice(side == 'bottom' ? 'top' : 'bottom', 30); // result.dialogs.length
sliced.forEach(el => {
const peerId = +el.getAttribute('data-peerId');
delete this.doms[peerId];
}); */
//}, 0);
//}
} }
this.log.debug('getDialogs ' + loadCount + ' dialogs by offset:', offsetIndex, result, this.chatList.childElementCount); this.log.debug('getDialogs ' + loadCount + ' dialogs by offset:', offsetIndex, result, this.chatList.childElementCount);
setTimeout(() => { setTimeout(() => {
/* setTimeout(() => {
this.scroll.slice(true);
}, 100); */
this.scroll.onScroll(); this.scroll.onScroll();
}, 0); }, 0);
} catch(err) { } catch(err) {
@ -839,7 +803,10 @@ export class AppDialogsManager {
this.loadDialogs(side); this.loadDialogs(side);
}; };
public setListClickListener(list: HTMLUListElement, onFound?: () => void, withContext = false) { public setListClickListener(list: HTMLUListElement, onFound?: () => void, withContext = false, autonomous = false) {
let lastActiveListElement: HTMLElement;
list.dataset.autonomous = '' + +autonomous;
list.addEventListener('mousedown', (e) => { list.addEventListener('mousedown', (e) => {
if(e.button != 0) return; if(e.button != 0) return;
//cancelEvent(e); //cancelEvent(e);
@ -854,10 +821,17 @@ export class AppDialogsManager {
elem = elem.parentElement; elem = elem.parentElement;
let samePeer = this.lastActiveListElement == elem; if(autonomous) {
let sameElement = lastActiveListElement === elem;
if(lastActiveListElement && !sameElement) {
lastActiveListElement.classList.remove('active');
}
if(this.lastActiveListElement && !samePeer) { if(elem) {
this.lastActiveListElement.classList.remove('active'); elem.classList.add('active');
lastActiveListElement = elem;
this.lastActiveElements.add(elem);
}
} }
if(elem) { if(elem) {
@ -866,11 +840,6 @@ export class AppDialogsManager {
let peerId = +elem.getAttribute('data-peerId'); let peerId = +elem.getAttribute('data-peerId');
let lastMsgId = +elem.dataset.mid || undefined; let lastMsgId = +elem.dataset.mid || undefined;
if(!samePeer) {
elem.classList.add('active');
this.lastActiveListElement = elem;
}
appImManager.setPeer(peerId, lastMsgId); appImManager.setPeer(peerId, lastMsgId);
} else { } else {
appImManager.setPeer(0); appImManager.setPeer(0);
@ -1120,12 +1089,13 @@ export class AppDialogsManager {
onlyFirstName?: boolean, onlyFirstName?: boolean,
meAsSaved?: boolean, meAsSaved?: boolean,
append?: boolean, append?: boolean,
avatarSize?: number avatarSize?: number,
autonomous?: boolean
}) { }) {
return this.addDialog(options.dialog, options.container, options.drawStatus, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize); return this.addDialog(options.dialog, options.container, options.drawStatus, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous);
} }
public addDialog(_dialog: Dialog | number, container?: HTMLUListElement | Scrollable, drawStatus = true, rippleEnabled = true, onlyFirstName = false, meAsSaved = true, append = true, avatarSize = 54) { public addDialog(_dialog: Dialog | number, container?: HTMLUListElement | Scrollable, drawStatus = true, rippleEnabled = true, onlyFirstName = false, meAsSaved = true, append = true, avatarSize = 54, autonomous = !!container) {
let dialog: Dialog; let dialog: Dialog;
if(typeof(_dialog) === 'number') { if(typeof(_dialog) === 'number') {
@ -1276,11 +1246,6 @@ export class AppDialogsManager {
this.doms[dialog.peerId] = dom; this.doms[dialog.peerId] = dom;
if(appImManager.chat?.peerId == peerId) {
li.classList.add('active');
this.lastActiveListElement = li;
}
/* if(container) { /* if(container) {
container.append(li); container.append(li);
} */ } */
@ -1289,6 +1254,11 @@ export class AppDialogsManager {
} else { } else {
container[method](li); container[method](li);
} }
if(!autonomous && appImManager.chat?.peerId === peerId) {
li.classList.add('active');
this.lastActiveElements.add(li);
}
return {dom, dialog}; return {dom, dialog};
} }

Loading…
Cancel
Save