Blocked users almost finished
This commit is contained in:
parent
ac313c94bd
commit
64f2a64351
@ -44,8 +44,8 @@ export default class AppSelectPeers {
|
|||||||
private appendTo: HTMLElement;
|
private appendTo: HTMLElement;
|
||||||
private onChange: (length: number) => void;
|
private onChange: (length: number) => void;
|
||||||
private peerType: PeerType[] = ['dialogs'];
|
private peerType: PeerType[] = ['dialogs'];
|
||||||
private renderResultsFunc?: (peerIds: number[]) => void;
|
private renderResultsFunc: (peerIds: number[]) => void;
|
||||||
private chatRightsAction?: ChatRights;
|
private chatRightsAction: ChatRights;
|
||||||
private multiSelect = true;
|
private multiSelect = true;
|
||||||
private rippleEnabled = true;
|
private rippleEnabled = true;
|
||||||
|
|
||||||
|
@ -1,48 +1,24 @@
|
|||||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
|
||||||
import appImManager from "../../lib/appManagers/appImManager";
|
import appImManager from "../../lib/appManagers/appImManager";
|
||||||
import AppSelectPeers from "../appSelectPeers";
|
import PopupPickUser from "./pickUser";
|
||||||
import PopupElement from ".";
|
|
||||||
|
|
||||||
export default class PopupForward extends PopupElement {
|
|
||||||
private selector: AppSelectPeers;
|
|
||||||
//private scrollable: Scrollable;
|
|
||||||
|
|
||||||
|
export default class PopupForward extends PopupPickUser {
|
||||||
constructor(fromPeerId: number, mids: number[], onSelect?: () => Promise<void> | void, onClose?: () => void) {
|
constructor(fromPeerId: number, mids: number[], onSelect?: () => Promise<void> | void, onClose?: () => void) {
|
||||||
super('popup-forward', null, {closable: true, overlayClosable: true, body: true});
|
super({
|
||||||
|
peerTypes: ['dialogs', 'contacts'],
|
||||||
if(onClose) this.onClose = onClose;
|
onSelect: async(peerId) => {
|
||||||
|
if(onSelect) {
|
||||||
this.selector = new AppSelectPeers({
|
const res = onSelect();
|
||||||
appendTo: this.body,
|
if(res instanceof Promise) {
|
||||||
onChange: async() => {
|
await res;
|
||||||
const peerId = this.selector.getSelected()[0];
|
}
|
||||||
this.btnClose.click();
|
}
|
||||||
|
|
||||||
this.selector = null;
|
|
||||||
|
|
||||||
await (onSelect ? onSelect() || Promise.resolve() : Promise.resolve());
|
|
||||||
|
|
||||||
appImManager.setInnerPeer(peerId);
|
appImManager.setInnerPeer(peerId);
|
||||||
appImManager.chat.input.initMessagesForward(fromPeerId, mids.slice());
|
appImManager.chat.input.initMessagesForward(fromPeerId, mids.slice());
|
||||||
},
|
},
|
||||||
peerType: ['dialogs', 'contacts'],
|
onClose,
|
||||||
onFirstRender: () => {
|
placeholder: 'Forward to...',
|
||||||
this.show();
|
chatRightsAction: 'send'
|
||||||
this.selector.checkForTriggers(); // ! due to zero height before mounting
|
|
||||||
|
|
||||||
if(!isTouchSupported) {
|
|
||||||
this.selector.input.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
chatRightsAction: 'send',
|
|
||||||
multiSelect: false,
|
|
||||||
rippleEnabled: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//this.scrollable = new Scrollable(this.body);
|
|
||||||
|
|
||||||
this.selector.input.placeholder = 'Forward to...';
|
|
||||||
this.title.append(this.selector.input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
53
src/components/popups/pickUser.ts
Normal file
53
src/components/popups/pickUser.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||||
|
import AppSelectPeers from "../appSelectPeers";
|
||||||
|
import PopupElement from ".";
|
||||||
|
|
||||||
|
export default class PopupPickUser extends PopupElement {
|
||||||
|
protected selector: AppSelectPeers;
|
||||||
|
|
||||||
|
constructor(options: {
|
||||||
|
peerTypes: AppSelectPeers['peerType'],
|
||||||
|
onSelect?: (peerId: number) => Promise<void> | void,
|
||||||
|
onClose?: () => void,
|
||||||
|
placeholder: string,
|
||||||
|
chatRightsAction?: AppSelectPeers['chatRightsAction']
|
||||||
|
}) {
|
||||||
|
super('popup-forward', null, {closable: true, overlayClosable: true, body: true});
|
||||||
|
|
||||||
|
if(options.onClose) this.onClose = options.onClose;
|
||||||
|
|
||||||
|
this.selector = new AppSelectPeers({
|
||||||
|
appendTo: this.body,
|
||||||
|
onChange: async() => {
|
||||||
|
const peerId = this.selector.getSelected()[0];
|
||||||
|
this.btnClose.click();
|
||||||
|
|
||||||
|
this.selector = null;
|
||||||
|
|
||||||
|
if(options.onSelect) {
|
||||||
|
const res = options.onSelect(peerId);
|
||||||
|
if(res instanceof Promise) {
|
||||||
|
await res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
peerType: options.peerTypes,
|
||||||
|
onFirstRender: () => {
|
||||||
|
this.show();
|
||||||
|
this.selector.checkForTriggers(); // ! due to zero height before mounting
|
||||||
|
|
||||||
|
if(!isTouchSupported) {
|
||||||
|
this.selector.input.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chatRightsAction: options.chatRightsAction,
|
||||||
|
multiSelect: false,
|
||||||
|
rippleEnabled: false
|
||||||
|
});
|
||||||
|
|
||||||
|
//this.scrollable = new Scrollable(this.body);
|
||||||
|
|
||||||
|
this.selector.input.placeholder = options.placeholder;
|
||||||
|
this.title.append(this.selector.input);
|
||||||
|
}
|
||||||
|
}
|
115
src/components/sidebarLeft/tabs/blockedUsers.ts
Normal file
115
src/components/sidebarLeft/tabs/blockedUsers.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { SliderSuperTab } from "../../slider";
|
||||||
|
import { SettingSection } from "..";
|
||||||
|
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
|
||||||
|
import { attachClickEvent, findUpTag } from "../../../helpers/dom";
|
||||||
|
import ButtonMenu from "../../buttonMenu";
|
||||||
|
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||||
|
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||||
|
import Button from "../../button";
|
||||||
|
import PopupPickUser from "../../popups/pickUser";
|
||||||
|
import rootScope from "../../../lib/rootScope";
|
||||||
|
|
||||||
|
export default class AppBlockedUsersTab extends SliderSuperTab {
|
||||||
|
public peerIds: number[];
|
||||||
|
private menuElement: HTMLElement;
|
||||||
|
|
||||||
|
protected init() {
|
||||||
|
this.container.classList.add('blocked-users-container');
|
||||||
|
this.title.innerText = 'Blocked Users';
|
||||||
|
|
||||||
|
{
|
||||||
|
const section = new SettingSection({
|
||||||
|
caption: 'Blocked users will not be able to contact you and will not see your Last Seen time.'
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scrollable.append(section.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
const btnAdd = Button('btn-circle btn-corner tgico-add is-visible');
|
||||||
|
this.content.append(btnAdd);
|
||||||
|
|
||||||
|
attachClickEvent(btnAdd, (e) => {
|
||||||
|
new PopupPickUser({
|
||||||
|
peerTypes: ['contacts'],
|
||||||
|
placeholder: 'Block user...',
|
||||||
|
onSelect: (peerId) => {
|
||||||
|
//console.log('block', peerId);
|
||||||
|
appUsersManager.toggleBlock(peerId, true);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, {listenerSetter: this.listenerSetter});
|
||||||
|
|
||||||
|
const list = document.createElement('ul');
|
||||||
|
this.scrollable.container.classList.add('chatlist-container');
|
||||||
|
this.scrollable.append(list);
|
||||||
|
|
||||||
|
const add = (peerId: number, append: boolean) => {
|
||||||
|
const {dom} = appDialogsManager.addDialogNew({
|
||||||
|
dialog: peerId,
|
||||||
|
container: list,
|
||||||
|
drawStatus: false,
|
||||||
|
rippleEnabled: true,
|
||||||
|
avatarSize: 48,
|
||||||
|
append
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = appUsersManager.getUser(peerId);
|
||||||
|
dom.lastMessageSpan.innerHTML = user.pFlags.bot ? ('@' + user.username) : user.rPhone || (user.username ? '@' + user.username : appUsersManager.getUserStatusString(peerId));
|
||||||
|
};
|
||||||
|
|
||||||
|
for(const peerId of this.peerIds) {
|
||||||
|
add(peerId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let target: HTMLElement;
|
||||||
|
const onUnblock = () => {
|
||||||
|
const peerId = +target.dataset.peerId;
|
||||||
|
appUsersManager.toggleBlock(peerId, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const element = this.menuElement = ButtonMenu([{
|
||||||
|
icon: 'unlock',
|
||||||
|
text: 'Unblock',
|
||||||
|
onClick: onUnblock,
|
||||||
|
options: {listenerSetter: this.listenerSetter}
|
||||||
|
}]);
|
||||||
|
element.id = 'blocked-users-contextmenu';
|
||||||
|
element.classList.add('contextmenu');
|
||||||
|
|
||||||
|
document.getElementById('page-chats').append(element);
|
||||||
|
|
||||||
|
attachContextMenuListener(this.scrollable.container, (e) => {
|
||||||
|
target = findUpTag(e.target, 'LI');
|
||||||
|
if(!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e instanceof MouseEvent) e.preventDefault();
|
||||||
|
// smth
|
||||||
|
if(e instanceof MouseEvent) e.cancelBubble = true;
|
||||||
|
|
||||||
|
positionMenu(e, element);
|
||||||
|
openBtnMenu(element);
|
||||||
|
}, this.listenerSetter);
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope, 'peer_block', (update) => {
|
||||||
|
const {peerId, blocked} = update;
|
||||||
|
if(blocked) {
|
||||||
|
add(peerId, false);
|
||||||
|
} else {
|
||||||
|
const li = list.querySelector(`[data-peer-id="${peerId}"]`);
|
||||||
|
if(li) {
|
||||||
|
li.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCloseAfterTimeout() {
|
||||||
|
if(this.menuElement) {
|
||||||
|
this.menuElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onCloseAfterTimeout();
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,8 @@ import AppPrivacyAddToGroupsTab from "./privacy/addToGroups";
|
|||||||
import AppPrivacyCallsTab from "./privacy/calls";
|
import AppPrivacyCallsTab from "./privacy/calls";
|
||||||
import AppActiveSessionsTab from "./activeSessions";
|
import AppActiveSessionsTab from "./activeSessions";
|
||||||
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
||||||
|
import AppBlockedUsersTab from "./blockedUsers";
|
||||||
|
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||||
|
|
||||||
export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
||||||
protected init() {
|
protected init() {
|
||||||
@ -26,12 +28,18 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
|||||||
{
|
{
|
||||||
const section = new SettingSection({noDelimiter: true});
|
const section = new SettingSection({noDelimiter: true});
|
||||||
|
|
||||||
|
let blockedPeerIds: number[];
|
||||||
const blockedUsersRow = new Row({
|
const blockedUsersRow = new Row({
|
||||||
icon: 'deleteuser',
|
icon: 'deleteuser',
|
||||||
title: 'Blocked Users',
|
title: 'Blocked Users',
|
||||||
subtitle: '6 users',
|
subtitle: 'Loading...',
|
||||||
clickable: true
|
clickable: () => {
|
||||||
|
const tab = new AppBlockedUsersTab(this.slider);
|
||||||
|
tab.peerIds = blockedPeerIds;
|
||||||
|
tab.open();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
blockedUsersRow.freezed = true;
|
||||||
|
|
||||||
let passwordState: AccountPassword;
|
let passwordState: AccountPassword;
|
||||||
const twoFactorRowOptions = {
|
const twoFactorRowOptions = {
|
||||||
@ -75,6 +83,12 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
|||||||
section.content.append(blockedUsersRow.container, twoFactorRow.container, activeSessionRow.container);
|
section.content.append(blockedUsersRow.container, twoFactorRow.container, activeSessionRow.container);
|
||||||
this.scrollable.append(section.container);
|
this.scrollable.append(section.container);
|
||||||
|
|
||||||
|
appUsersManager.getBlocked().then(res => {
|
||||||
|
blockedUsersRow.freezed = false;
|
||||||
|
blockedUsersRow.subtitle.innerText = res.count + ' ' + (res.count !== 1 ? 'users' : 'user');
|
||||||
|
blockedPeerIds = res.peerIds;
|
||||||
|
});
|
||||||
|
|
||||||
passwordManager.getState().then(state => {
|
passwordManager.getState().then(state => {
|
||||||
passwordState = state;
|
passwordState = state;
|
||||||
twoFactorRow.subtitle.innerText = state.pFlags.has_password ? 'On' : 'Off';
|
twoFactorRow.subtitle.innerText = state.pFlags.has_password ? 'On' : 'Off';
|
||||||
@ -87,7 +101,7 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
|||||||
apiManager.invokeApi('account.getAuthorizations').then(auths => {
|
apiManager.invokeApi('account.getAuthorizations').then(auths => {
|
||||||
activeSessionRow.freezed = false;
|
activeSessionRow.freezed = false;
|
||||||
authorizations = auths.authorizations;
|
authorizations = auths.authorizations;
|
||||||
activeSessionRow.subtitle.innerText = authorizations.length + ' ' + (authorizations.length > 1 ? 'devices' : 'device');
|
activeSessionRow.subtitle.innerText = authorizations.length + ' ' + (authorizations.length !== 1 ? 'devices' : 'device');
|
||||||
console.log('auths', auths);
|
console.log('auths', auths);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import EventListenerBase from "../helpers/eventListenerBase";
|
import EventListenerBase from "../helpers/eventListenerBase";
|
||||||
|
import ListenerSetter from "../helpers/listenerSetter";
|
||||||
import ButtonIcon from "./buttonIcon";
|
import ButtonIcon from "./buttonIcon";
|
||||||
import Scrollable from "./scrollable";
|
import Scrollable from "./scrollable";
|
||||||
import SidebarSlider from "./slider";
|
import SidebarSlider from "./slider";
|
||||||
@ -26,6 +27,7 @@ export default class SliderSuperTab implements SliderTab {
|
|||||||
|
|
||||||
public slider: SidebarSlider;
|
public slider: SidebarSlider;
|
||||||
public destroyable: boolean;
|
public destroyable: boolean;
|
||||||
|
public listenerSetter: ListenerSetter;
|
||||||
|
|
||||||
constructor(slider: SidebarSlider, destroyable?: boolean) {
|
constructor(slider: SidebarSlider, destroyable?: boolean) {
|
||||||
this._constructor(slider, destroyable);
|
this._constructor(slider, destroyable);
|
||||||
@ -56,6 +58,8 @@ export default class SliderSuperTab implements SliderTab {
|
|||||||
this.container.append(this.header, this.content);
|
this.container.append(this.header, this.content);
|
||||||
|
|
||||||
this.slider.addTab(this);
|
this.slider.addTab(this);
|
||||||
|
|
||||||
|
this.listenerSetter = new ListenerSetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
@ -83,6 +87,10 @@ export default class SliderSuperTab implements SliderTab {
|
|||||||
this.slider.tabs.delete(this);
|
this.slider.tabs.delete(this);
|
||||||
this.container.remove();
|
this.container.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.listenerSetter) {
|
||||||
|
this.listenerSetter.removeAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,48 @@
|
|||||||
|
//import { MOUNT_CLASS_TO } from "../config/debug";
|
||||||
import type { ArgumentTypes, SuperReturnType } from "../types";
|
import type { ArgumentTypes, SuperReturnType } from "../types";
|
||||||
|
|
||||||
|
// class EventSystem {
|
||||||
|
// wm: WeakMap<any, Record<any, Set<any>>> = new WeakMap();
|
||||||
|
|
||||||
|
// add(target: any, event: any, listener: any) {
|
||||||
|
// let listeners = this.wm.get(target);
|
||||||
|
// if (listeners === undefined) {
|
||||||
|
// listeners = {};
|
||||||
|
// }
|
||||||
|
// let listenersForEvent = listeners[event];
|
||||||
|
// if (listenersForEvent === undefined) {
|
||||||
|
// listenersForEvent = new Set();
|
||||||
|
// }
|
||||||
|
// listenersForEvent.add(listener);
|
||||||
|
// listeners[event] = listenersForEvent;
|
||||||
|
// //target.addEventListener(event, listener);
|
||||||
|
// this.wm.set(target, listeners);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// remove(target: any, event: any, listener: any) {
|
||||||
|
// let listeners = this.wm.get(target);
|
||||||
|
// if (!listeners) return;
|
||||||
|
// let listenersForEvent = listeners[event];
|
||||||
|
// if (!listenersForEvent) return;
|
||||||
|
// listenersForEvent.delete(listener);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// /* fire(target, event) {
|
||||||
|
// let listeners = this.wm.get(target);
|
||||||
|
// if (!listeners) return;
|
||||||
|
// let listenersForEvent = listeners[event];
|
||||||
|
// if (!listenersForEvent) return;
|
||||||
|
// for (let handler of handlers) {
|
||||||
|
// setTimeout(handler, 0, event, target); // we use a setTimeout here because we want event triggering to be asynchronous.
|
||||||
|
// }
|
||||||
|
// }; */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// console.log = () => {};
|
||||||
|
|
||||||
|
// const e = new EventSystem();
|
||||||
|
// MOUNT_CLASS_TO && (MOUNT_CLASS_TO.e = e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Better not to remove listeners during setting
|
* Better not to remove listeners during setting
|
||||||
* Should add listener callback only once
|
* Should add listener callback only once
|
||||||
@ -34,12 +77,14 @@ export default class EventListenerBase<Listeners extends {[name: string]: Functi
|
|||||||
}
|
}
|
||||||
|
|
||||||
(this.listeners[name] ?? (this.listeners[name] = [])).push({callback, once});
|
(this.listeners[name] ?? (this.listeners[name] = [])).push({callback, once});
|
||||||
|
//e.add(this, name, {callback, once});
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeListener(name: keyof Listeners, callback: Listeners[typeof name]) {
|
public removeListener(name: keyof Listeners, callback: Listeners[typeof name]) {
|
||||||
if(this.listeners[name]) {
|
if(this.listeners[name]) {
|
||||||
this.listeners[name].findAndSplice(l => l.callback === callback);
|
this.listeners[name].findAndSplice(l => l.callback === callback);
|
||||||
}
|
}
|
||||||
|
//e.remove(this, name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// * must be protected, but who cares
|
// * must be protected, but who cares
|
||||||
@ -49,12 +94,16 @@ export default class EventListenerBase<Listeners extends {[name: string]: Functi
|
|||||||
}
|
}
|
||||||
|
|
||||||
const arr: Array<SuperReturnType<Listeners[typeof name]>> = [];
|
const arr: Array<SuperReturnType<Listeners[typeof name]>> = [];
|
||||||
|
|
||||||
|
/* let a = e.wm.get(this)[name];
|
||||||
|
if(!a) return arr;
|
||||||
|
const listeners = [...a]; */
|
||||||
const listeners = this.listeners[name];
|
const listeners = this.listeners[name];
|
||||||
if(listeners) {
|
if(listeners) {
|
||||||
// ! this one will guarantee execution even if delete another listener during setting
|
// ! this one will guarantee execution even if delete another listener during setting
|
||||||
const left = listeners.slice();
|
const left = listeners.slice();
|
||||||
left.forEach(listener => {
|
left.forEach((listener: any) => {
|
||||||
const index = listeners.findIndex(l => l.callback === listener.callback);
|
const index = listeners.findIndex((l: any) => l.callback === listener.callback);
|
||||||
if(index === -1) {
|
if(index === -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6,23 +6,23 @@ export type ListenerCallback = (...args: any[]) => any;
|
|||||||
export default class ListenerSetter {
|
export default class ListenerSetter {
|
||||||
private listeners: Set<Listener> = new Set();
|
private listeners: Set<Listener> = new Set();
|
||||||
|
|
||||||
public add = (element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) => {
|
public add(element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) {
|
||||||
const listener = {element, event, callback, options};
|
const listener = {element, event, callback, options};
|
||||||
this.addManual(listener);
|
this.addManual(listener);
|
||||||
return listener;
|
return listener;
|
||||||
};
|
}
|
||||||
|
|
||||||
public addManual = (listener: Listener) => {
|
public addManual(listener: Listener) {
|
||||||
listener.element.addEventListener(listener.event, listener.callback, listener.options);
|
listener.element.addEventListener(listener.event, listener.callback, listener.options);
|
||||||
this.listeners.add(listener);
|
this.listeners.add(listener);
|
||||||
};
|
}
|
||||||
|
|
||||||
public remove = (listener: Listener) => {
|
public remove(listener: Listener) {
|
||||||
listener.element.removeEventListener(listener.event, listener.callback, listener.options);
|
listener.element.removeEventListener(listener.event, listener.callback, listener.options);
|
||||||
this.listeners.delete(listener);
|
this.listeners.delete(listener);
|
||||||
};
|
}
|
||||||
|
|
||||||
public removeManual = (element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) => {
|
public removeManual(element: ListenerElement, event: ListenerEvent, callback: ListenerCallback, options?: ListenerOptions) {
|
||||||
let listener: Listener;
|
let listener: Listener;
|
||||||
for(const _listener of this.listeners) {
|
for(const _listener of this.listeners) {
|
||||||
if(_listener.element === element && _listener.event === event && _listener.callback === callback && _listener.options === options) {
|
if(_listener.element === element && _listener.event === event && _listener.callback === callback && _listener.options === options) {
|
||||||
@ -34,11 +34,11 @@ export default class ListenerSetter {
|
|||||||
if(listener) {
|
if(listener) {
|
||||||
this.remove(listener);
|
this.remove(listener);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
public removeAll = () => {
|
public removeAll() {
|
||||||
this.listeners.forEach(listener => {
|
this.listeners.forEach(listener => {
|
||||||
this.remove(listener);
|
this.remove(listener);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
import { isObject } from "../../helpers/object";
|
import { isObject } from "../../helpers/object";
|
||||||
import { DialogPeer, InputDialogPeer, InputPeer, Peer } from "../../layer";
|
import { DialogPeer, InputDialogPeer, InputPeer, Peer, Update } from "../../layer";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from "../rootScope";
|
import rootScope from "../rootScope";
|
||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
@ -24,6 +24,18 @@ const DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];
|
|||||||
|
|
||||||
export type PeerType = 'channel' | 'chat' | 'megagroup' | 'group' | 'saved';
|
export type PeerType = 'channel' | 'chat' | 'megagroup' | 'group' | 'saved';
|
||||||
export class AppPeersManager {
|
export class AppPeersManager {
|
||||||
|
constructor() {
|
||||||
|
rootScope.on('apiUpdate', (e) => {
|
||||||
|
const update = e as Update;
|
||||||
|
//console.log('on apiUpdate', update);
|
||||||
|
switch(update._) {
|
||||||
|
case 'updatePeerBlocked': {
|
||||||
|
rootScope.broadcast('peer_block', {peerId: this.getPeerId(update.peer_id), blocked: update.blocked});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
/* public savePeerInstance(peerId: number, instance: any) {
|
/* public savePeerInstance(peerId: number, instance: any) {
|
||||||
if(peerId < 0) appChatsManager.saveApiChat(instance);
|
if(peerId < 0) appChatsManager.saveApiChat(instance);
|
||||||
else appUsersManager.saveApiUser(instance);
|
else appUsersManager.saveApiUser(instance);
|
||||||
@ -113,13 +125,13 @@ export class AppPeersManager {
|
|||||||
: appChatsManager.getChat(-peerId)
|
: appChatsManager.getChat(-peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPeerId(peerString: any/* Peer | number | string */): number {
|
public getPeerId(peerId: any/* Peer | number | string */): number {
|
||||||
if(typeof(peerString) === 'number') return peerString;
|
if(typeof(peerId) === 'number') return peerId;
|
||||||
else if(isObject(peerString)) return peerString.user_id ? peerString.user_id : -(peerString.channel_id || peerString.chat_id);
|
else if(isObject(peerId)) return peerId.user_id ? peerId.user_id : -(peerId.channel_id || peerId.chat_id);
|
||||||
else if(!peerString) return 0;
|
else if(!peerId) return 0;
|
||||||
|
|
||||||
const isUser = peerString.charAt(0) === 'u';
|
const isUser = peerId.charAt(0) === 'u';
|
||||||
const peerParams = peerString.substr(1).split('_');
|
const peerParams = peerId.substr(1).split('_');
|
||||||
|
|
||||||
return isUser ? peerParams[0] : -peerParams[0] || 0;
|
return isUser ? peerParams[0] : -peerParams[0] || 0;
|
||||||
}
|
}
|
||||||
|
@ -84,17 +84,6 @@ export class AppUsersManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* // @ts-ignore
|
|
||||||
case 'updateUserBlocked': {
|
|
||||||
const id = (update as any).user_id;
|
|
||||||
const blocked: boolean = (update as any).blocked;
|
|
||||||
|
|
||||||
const user = this.getUser(id);
|
|
||||||
if(user) {
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* case 'updateContactLink':
|
/* case 'updateContactLink':
|
||||||
this.onContactUpdated(update.user_id, update.my_link._ === 'contactLinkContact');
|
this.onContactUpdated(update.user_id, update.my_link._ === 'contactLinkContact');
|
||||||
break; */
|
break; */
|
||||||
@ -225,6 +214,25 @@ export class AppUsersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toggleBlock(peerId: number, block: boolean) {
|
||||||
|
return apiManager.invokeApi(block ? 'contacts.block' : 'contacts.unblock', {
|
||||||
|
id: appPeersManager.getInputPeerById(peerId)
|
||||||
|
}).then(value => {
|
||||||
|
if(value) {
|
||||||
|
apiUpdatesManager.processUpdateMessage({
|
||||||
|
_: 'updateShort',
|
||||||
|
update: {
|
||||||
|
_: 'updatePeerBlocked',
|
||||||
|
peer_id: appPeersManager.getOutputPeer(peerId),
|
||||||
|
blocked: block
|
||||||
|
} as Update.updatePeerBlocked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public testSelfSearch(query: string) {
|
public testSelfSearch(query: string) {
|
||||||
const user = this.getSelf();
|
const user = this.getSelf();
|
||||||
const index = searchIndexManager.createIndex();
|
const index = searchIndexManager.createIndex();
|
||||||
@ -633,6 +641,18 @@ export class AppUsersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getBlocked(offset = 0, limit = 0) {
|
||||||
|
return apiManager.invokeApi('contacts.getBlocked', {offset, limit}).then(contactsBlocked => {
|
||||||
|
this.saveApiUsers(contactsBlocked.users);
|
||||||
|
appChatsManager.saveApiChats(contactsBlocked.chats);
|
||||||
|
const count = contactsBlocked._ === 'contacts.blocked' ? contactsBlocked.users.length + contactsBlocked.chats.length : contactsBlocked.count;
|
||||||
|
|
||||||
|
const peerIds = contactsBlocked.users.map(u => u.id).concat(contactsBlocked.chats.map(c => -c.id));
|
||||||
|
|
||||||
|
return {count, peerIds};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* public searchContacts(query: string, limit = 20) {
|
/* public searchContacts(query: string, limit = 20) {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.getContacts(query),
|
this.getContacts(query),
|
||||||
|
@ -20,6 +20,7 @@ type BroadcastEvents = {
|
|||||||
'peer_pinned_messages': {peerId: number, mids?: number[], pinned?: boolean, unpinAll?: true},
|
'peer_pinned_messages': {peerId: number, mids?: number[], pinned?: boolean, unpinAll?: true},
|
||||||
'peer_pinned_hidden': {peerId: number, maxId: number},
|
'peer_pinned_hidden': {peerId: number, maxId: number},
|
||||||
'peer_typings': {peerId: number, typings: UserTyping[]},
|
'peer_typings': {peerId: number, typings: UserTyping[]},
|
||||||
|
'peer_block': {peerId: number, blocked: boolean},
|
||||||
|
|
||||||
'filter_delete': MyDialogFilter,
|
'filter_delete': MyDialogFilter,
|
||||||
'filter_update': MyDialogFilter,
|
'filter_update': MyDialogFilter,
|
||||||
@ -125,11 +126,11 @@ class RootScope extends EventListenerBase<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public broadcast = <T extends keyof BroadcastEvents>(name: T, detail?: BroadcastEvents[T]) => {
|
public broadcast = <T extends keyof BroadcastEvents>(name: T, detail?: BroadcastEvents[T]) => {
|
||||||
/* if(DEBUG) {
|
//if(DEBUG) {
|
||||||
if(name !== 'user_update') {
|
if(name !== 'user_update') {
|
||||||
console.debug('Broadcasting ' + name + ' event, with args:', detail);
|
console.debug('Broadcasting ' + name + ' event, with args:', detail);
|
||||||
}
|
}
|
||||||
} */
|
//}
|
||||||
|
|
||||||
this.setListenerResult(name, detail);
|
this.setListenerResult(name, detail);
|
||||||
};
|
};
|
||||||
|
@ -1030,6 +1030,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blocked-users-container {
|
||||||
|
.sidebar-left-section-caption {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.range-setting-selector {
|
.range-setting-selector {
|
||||||
padding: 1rem .875rem;
|
padding: 1rem .875rem;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user