Ban user
Reset user permissions
This commit is contained in:
parent
5f00fb9a87
commit
ba275c961c
@ -69,17 +69,10 @@ export default class AppSelectPeers {
|
||||
rippleEnabled?: boolean,
|
||||
avatarSize?: AppSelectPeers['avatarSize'],
|
||||
}) {
|
||||
for(let i in options) {
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
Object.assign(this, options);
|
||||
|
||||
this.container.classList.add('selector');
|
||||
|
||||
this.peerType.forEach(type => {
|
||||
this.tempIds[type] = 0;
|
||||
});
|
||||
|
||||
let needSwitchList = false;
|
||||
const f = (this.renderResultsFunc || this.renderResults).bind(this);
|
||||
this.renderResultsFunc = (peerIds: number[]) => {
|
||||
@ -220,6 +213,14 @@ export default class AppSelectPeers {
|
||||
}
|
||||
}
|
||||
|
||||
private getTempId(type: keyof AppSelectPeers['tempIds']) {
|
||||
if(this.tempIds[type] === undefined) {
|
||||
this.tempIds[type] = 0;
|
||||
}
|
||||
|
||||
return ++this.tempIds[type];
|
||||
}
|
||||
|
||||
private async getMoreDialogs(): Promise<any> {
|
||||
if(this.promise) return this.promise;
|
||||
|
||||
@ -230,8 +231,7 @@ export default class AppSelectPeers {
|
||||
// в десктопе - сначала без группы, потом архивные, потом контакты без сообщений
|
||||
const pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
|
||||
|
||||
const tempId = ++this.tempIds.dialogs;
|
||||
|
||||
const tempId = this.getTempId('dialogs');
|
||||
this.promise = appMessagesManager.getConversations(this.query, this.offsetIndex, pageCount, this.folderId);
|
||||
const value = await this.promise;
|
||||
this.promise = null;
|
||||
@ -292,7 +292,7 @@ export default class AppSelectPeers {
|
||||
|
||||
this.promise = Promise.all(promises);
|
||||
this.cachedContacts = (await this.promise)[0].slice(); */
|
||||
const tempId = ++this.tempIds.contacts;
|
||||
const tempId = this.getTempId('contacts');
|
||||
this.promise = appUsersManager.getContacts(this.query);
|
||||
this.cachedContacts = (await this.promise).slice();
|
||||
if(this.tempIds.contacts !== tempId) {
|
||||
@ -328,7 +328,7 @@ export default class AppSelectPeers {
|
||||
|
||||
const pageCount = 50; // same as in group permissions to use cache
|
||||
|
||||
const tempId = ++this.tempIds.channelParticipants;
|
||||
const tempId = this.getTempId('channelParticipants');
|
||||
const promise = appProfileManager.getChannelParticipants(-this.peerId, {_: 'channelParticipantsSearch', q: this.query}, pageCount, this.list.childElementCount);
|
||||
const participants = await promise;
|
||||
if(this.tempIds.channelParticipants !== tempId) {
|
||||
|
@ -23,10 +23,7 @@ export default class EditPeer {
|
||||
listenerSetter: ListenerSetter,
|
||||
doNotEditAvatar?: boolean,
|
||||
}) {
|
||||
for(let i in options) {
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
Object.assign(this, options);
|
||||
|
||||
this.nextBtn = Button('btn-circle btn-corner tgico-check');
|
||||
|
||||
|
@ -34,10 +34,7 @@ export default class ProgressivePreloader {
|
||||
attachMethod: ProgressivePreloader['attachMethod']
|
||||
}>) {
|
||||
if(options) {
|
||||
for(let i in options) {
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
Object.assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ import RadioField from "./radioField";
|
||||
import { ripple } from "./ripple";
|
||||
import { SliderSuperTab } from "./slider";
|
||||
import RadioForm from "./radioForm";
|
||||
import { attachClickEvent, cancelEvent } from "../helpers/dom";
|
||||
|
||||
export default class Row {
|
||||
public container: HTMLElement;
|
||||
@ -26,7 +25,7 @@ export default class Row {
|
||||
clickable: boolean | ((e: Event) => void),
|
||||
navigationTab: SliderSuperTab
|
||||
}> = {}) {
|
||||
this.container = document.createElement('div');
|
||||
this.container = document.createElement(options.radioField || options.checkboxField ? 'label' : 'div');
|
||||
this.container.classList.add('row');
|
||||
|
||||
this.subtitle = document.createElement('div');
|
||||
@ -56,18 +55,6 @@ export default class Row {
|
||||
|
||||
const i = options.radioField || options.checkboxField;
|
||||
i.label.classList.add('disable-hover');
|
||||
|
||||
if(options.radioField) {
|
||||
attachClickEvent(this.container, (e) => {
|
||||
cancelEvent(e);
|
||||
i.checked = true;
|
||||
});
|
||||
} else {
|
||||
attachClickEvent(this.container, (e) => {
|
||||
cancelEvent(e);
|
||||
i.checked = !i.checked;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if(options.title) {
|
||||
let c: HTMLElement;
|
||||
|
@ -59,15 +59,14 @@ export default class AppActiveSessionsTab extends SliderSuperTab {
|
||||
text: 'TERMINATE',
|
||||
isDanger: true,
|
||||
callback: () => {
|
||||
const b = [btnTerminate];
|
||||
toggleDisability(b, true);
|
||||
const toggle = toggleDisability([btnTerminate], true);
|
||||
apiManager.invokeApi('auth.resetAuthorizations').then(value => {
|
||||
//toggleDisability([btnTerminate], false);
|
||||
btnTerminate.remove();
|
||||
otherSection.container.remove();
|
||||
this.privacyTab.updateActiveSessions();
|
||||
}, onError).finally(() => {
|
||||
toggleDisability(b, false);
|
||||
toggle();
|
||||
});
|
||||
}
|
||||
}], {
|
||||
|
@ -162,12 +162,12 @@ export default class AppEditChannelTab extends SliderSuperTab {
|
||||
buttons: addCancelButton([{
|
||||
text: 'DELETE',
|
||||
callback: () => {
|
||||
toggleDisability([btnDelete], true);
|
||||
const toggle = toggleDisability([btnDelete], true);
|
||||
|
||||
appChatsManager.deleteChannel(-this.peerId).then(() => {
|
||||
this.close();
|
||||
}, () => {
|
||||
toggleDisability([btnDelete], false);
|
||||
toggle();
|
||||
});
|
||||
},
|
||||
isDanger: true
|
||||
|
@ -135,12 +135,12 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
buttons: addCancelButton([{
|
||||
text: 'DELETE',
|
||||
callback: () => {
|
||||
toggleDisability([btnDelete], true);
|
||||
const toggle = toggleDisability([btnDelete], true);
|
||||
|
||||
appUsersManager.deleteContacts([this.peerId]).then(() => {
|
||||
this.close();
|
||||
}, () => {
|
||||
toggleDisability([btnDelete], false);
|
||||
toggle();
|
||||
});
|
||||
},
|
||||
isDanger: true
|
||||
|
@ -207,12 +207,12 @@ export default class AppEditGroupTab extends SliderSuperTab {
|
||||
buttons: addCancelButton([{
|
||||
text: 'DELETE',
|
||||
callback: () => {
|
||||
toggleDisability([btnDelete], true);
|
||||
const toggle = toggleDisability([btnDelete], true);
|
||||
|
||||
appChatsManager.deleteChannel(this.chatId).then(() => {
|
||||
this.close();
|
||||
}, () => {
|
||||
toggleDisability([btnDelete], false);
|
||||
toggle();
|
||||
});
|
||||
},
|
||||
isDanger: true
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { attachClickEvent, cancelEvent, findUpTag } from "../../../helpers/dom";
|
||||
import { attachClickEvent, findUpTag } from "../../../helpers/dom";
|
||||
import ListenerSetter from "../../../helpers/listenerSetter";
|
||||
import ScrollableLoader from "../../../helpers/listLoader";
|
||||
import { ChannelParticipant, Chat, ChatBannedRights, Update } from "../../../layer";
|
||||
import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager";
|
||||
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||
import appProfileManager from "../../../lib/appManagers/appProfileManager";
|
||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||
import rootScope from "../../../lib/rootScope";
|
||||
import CheckboxField from "../../checkboxField";
|
||||
import PopupPickUser from "../../popups/pickUser";
|
||||
@ -115,7 +114,7 @@ export class ChatPermissions {
|
||||
export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
||||
public chatId: number;
|
||||
|
||||
protected init() {
|
||||
protected async init() {
|
||||
this.container.classList.add('edit-peer-container', 'group-permissions-container');
|
||||
this.title.innerHTML = 'Permissions';
|
||||
|
||||
@ -165,10 +164,6 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
||||
let participant: AppUserPermissionsTab['participant'];
|
||||
try {
|
||||
participant = await appProfileManager.getChannelParticipant(this.chatId, peerId) as any;
|
||||
|
||||
if(participant._ !== 'channelParticipantBanned') {
|
||||
participant = undefined;
|
||||
}
|
||||
} catch(err) {
|
||||
toast('User is no longer participant');
|
||||
return;
|
||||
@ -255,7 +250,7 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
||||
|
||||
this.listenerSetter.add(rootScope, 'apiUpdate', (update: Update) => {
|
||||
if(update._ === 'updateChannelParticipant') {
|
||||
const needAdd = update.new_participant?._ === 'channelParticipantBanned';
|
||||
const needAdd = update.new_participant?._ === 'channelParticipantBanned' && !update.new_participant.banned_rights.pFlags.view_messages;
|
||||
const li = list.querySelector(`[data-peer-id="${update.user_id}"]`);
|
||||
if(needAdd) {
|
||||
if(!li) {
|
||||
@ -304,6 +299,8 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
||||
});
|
||||
|
||||
this.scrollable.append(section.container);
|
||||
|
||||
await loader.load();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,10 +75,10 @@ export default class AppGroupTypeTab extends SliderSuperTabEventable {
|
||||
new PopupConfirmAction('revoke-link', [{
|
||||
text: 'OK',
|
||||
callback: () => {
|
||||
toggleDisability([btnRevoke], true);
|
||||
const toggle = toggleDisability([btnRevoke], true);
|
||||
|
||||
appProfileManager.getChatInviteLink(-this.peerId, true).then(link => {
|
||||
toggleDisability([btnRevoke], false);
|
||||
toggle();
|
||||
linkRow.title.innerHTML = link;
|
||||
//revoked = true;
|
||||
//onChange();
|
||||
|
@ -1,17 +1,19 @@
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
|
||||
import { deepEqual } from "../../../helpers/object";
|
||||
import { ChannelParticipant } from "../../../layer";
|
||||
import appChatsManager from "../../../lib/appManagers/appChatsManager";
|
||||
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||
import appProfileManager from "../../../lib/appManagers/appProfileManager";
|
||||
import appPeersManager from "../../../lib/appManagers/appPeersManager";
|
||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||
import Button from "../../button";
|
||||
import { addCancelButton } from "../../popups";
|
||||
import PopupPeer from "../../popups/peer";
|
||||
import { SettingSection } from "../../sidebarLeft";
|
||||
import { SliderSuperTabEventable } from "../../sliderTab";
|
||||
import { ChatPermissions } from "./groupPermissions";
|
||||
|
||||
export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
||||
public participant: ChannelParticipant.channelParticipantBanned;
|
||||
public participant: ChannelParticipant;
|
||||
public chatId: number;
|
||||
public userId: number;
|
||||
|
||||
@ -19,6 +21,8 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
||||
this.container.classList.add('edit-peer-container', 'user-permissions-container');
|
||||
this.title.innerHTML = 'User Permissions';
|
||||
|
||||
let destroyListener: () => void;
|
||||
|
||||
{
|
||||
const section = new SettingSection({
|
||||
name: 'What can this user do?',
|
||||
@ -45,18 +49,20 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
||||
chatId: this.chatId,
|
||||
listenerSetter: this.listenerSetter,
|
||||
appendTo: section.content,
|
||||
participant: this.participant
|
||||
participant: this.participant._ === 'channelParticipantBanned' ? this.participant : undefined
|
||||
});
|
||||
|
||||
this.eventListener.addEventListener('destroy', () => {
|
||||
destroyListener = () => {
|
||||
//appChatsManager.editChatDefaultBannedRights(this.chatId, p.takeOut());
|
||||
const rights = p.takeOut();
|
||||
if(deepEqual(this.participant.banned_rights.pFlags, rights.pFlags)) {
|
||||
if(this.participant._ === 'channelParticipantBanned' && deepEqual(this.participant.banned_rights.pFlags, rights.pFlags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
appChatsManager.editBanned(this.chatId, this.participant, rights);
|
||||
});
|
||||
};
|
||||
|
||||
this.eventListener.addEventListener('destroy', destroyListener);
|
||||
|
||||
this.scrollable.append(section.container);
|
||||
}
|
||||
@ -64,27 +70,44 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
||||
{
|
||||
const section = new SettingSection({});
|
||||
|
||||
if(this.participant._ === 'channelParticipantBanned') {
|
||||
const btnDeleteException = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'Delete Exception'});
|
||||
|
||||
attachClickEvent(btnDeleteException, () => {
|
||||
const toggle = toggleDisability([btnDeleteException], true);
|
||||
appChatsManager.clearChannelParticipantBannedRights(this.chatId, this.participant).then(() => {
|
||||
this.eventListener.removeEventListener('destroy', destroyListener);
|
||||
this.close();
|
||||
}, () => {
|
||||
toggle();
|
||||
});
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
section.content.append(btnDeleteException);
|
||||
}
|
||||
|
||||
const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'deleteuser', text: 'Ban and Remove From Group'});
|
||||
|
||||
attachClickEvent(btnDelete, () => {
|
||||
/* new PopupPeer('popup-delete-group', {
|
||||
new PopupPeer('popup-group-kick-user', {
|
||||
peerId: -this.chatId,
|
||||
title: 'Delete Group?',
|
||||
description: `Are you sure you want to delete this group? All members will be removed, and all messages will be lost.`,
|
||||
title: 'Ban User?',
|
||||
description: `Are you sure you want to ban <b>${appPeersManager.getPeerTitle(this.userId)}</b>`,
|
||||
buttons: addCancelButton([{
|
||||
text: 'DELETE',
|
||||
text: 'BAN',
|
||||
callback: () => {
|
||||
toggleDisability([btnDelete], true);
|
||||
const toggle = toggleDisability([btnDelete], true);
|
||||
|
||||
appChatsManager.deleteChannel(this.chatId).then(() => {
|
||||
appChatsManager.kickFromChannel(this.chatId, this.participant).then(() => {
|
||||
this.eventListener.removeEventListener('destroy', destroyListener);
|
||||
this.close();
|
||||
}, () => {
|
||||
toggleDisability([btnDelete], false);
|
||||
toggle();
|
||||
});
|
||||
},
|
||||
isDanger: true
|
||||
}])
|
||||
}).show(); */
|
||||
}).show();
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
section.content.append(btnDelete);
|
||||
|
@ -24,10 +24,7 @@ export default class SidebarSlider {
|
||||
canHideFirst?: SidebarSlider['canHideFirst'],
|
||||
navigationType: SidebarSlider['navigationType']
|
||||
}) {
|
||||
for(const i in options) {
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
Object.assign(this, options);
|
||||
|
||||
if(!this.tabs) {
|
||||
this.tabs = new Map();
|
||||
|
@ -791,6 +791,8 @@ export function toggleDisability(elements: HTMLElement[], disable: boolean) {
|
||||
} else {
|
||||
elements.forEach(el => el.removeAttribute('disabled'));
|
||||
}
|
||||
|
||||
return () => toggleDisability(elements, !disable);
|
||||
}
|
||||
|
||||
export function canFocus(isFirstInput: boolean) {
|
||||
|
@ -1,28 +1,46 @@
|
||||
import Scrollable from "../components/scrollable";
|
||||
|
||||
export default class ScrollableLoader {
|
||||
public loading = false;
|
||||
private scrollable: Scrollable;
|
||||
private getPromise: () => Promise<any>;
|
||||
private promise: Promise<any>;
|
||||
private loaded = false;
|
||||
|
||||
constructor(options: {
|
||||
scrollable: Scrollable,
|
||||
getPromise: () => Promise<any>
|
||||
scrollable: ScrollableLoader['scrollable'],
|
||||
getPromise: ScrollableLoader['getPromise']
|
||||
}) {
|
||||
let loading = false;
|
||||
Object.assign(this, options);
|
||||
|
||||
options.scrollable.onScrolledBottom = () => {
|
||||
if(loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
options.getPromise().then(done => {
|
||||
loading = false;
|
||||
|
||||
if(done) {
|
||||
options.scrollable.onScrolledBottom = null;
|
||||
} else {
|
||||
options.scrollable.checkForTriggers();
|
||||
}
|
||||
}, () => {
|
||||
loading = false;
|
||||
});
|
||||
this.load();
|
||||
};
|
||||
}
|
||||
|
||||
public load() {
|
||||
if(this.loaded) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if(this.loading) {
|
||||
return this.promise;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.promise = this.getPromise().then(done => {
|
||||
this.loading = false;
|
||||
this.promise = undefined;
|
||||
|
||||
if(done) {
|
||||
this.loaded = true;
|
||||
this.scrollable.onScrolledBottom = null;
|
||||
} else {
|
||||
this.scrollable.checkForTriggers();
|
||||
}
|
||||
}, () => {
|
||||
this.promise = undefined;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -698,10 +698,21 @@ export class AppChatsManager {
|
||||
});
|
||||
}
|
||||
|
||||
public kickFromChannel(id: number, userId: number) {
|
||||
return this.editBanned(id, userId, {
|
||||
public clearChannelParticipantBannedRights(id: number, participant: number | ChannelParticipant) {
|
||||
return this.editBanned(id, participant, {
|
||||
_: 'chatBannedRights',
|
||||
until_date: 0
|
||||
until_date: 0,
|
||||
pFlags: {}
|
||||
});
|
||||
}
|
||||
|
||||
public kickFromChannel(id: number, participant: number | ChannelParticipant) {
|
||||
return this.editBanned(id, participant, {
|
||||
_: 'chatBannedRights',
|
||||
until_date: 0,
|
||||
pFlags: {
|
||||
view_messages: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -817,6 +817,10 @@ export class AppDialogsManager {
|
||||
this.sliceTimeout = window.setTimeout(() => {
|
||||
this.sliceTimeout = undefined;
|
||||
|
||||
if(!this.chatList.childElementCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* const observer = new IntersectionObserver((entries) => {
|
||||
const
|
||||
});
|
||||
@ -828,9 +832,10 @@ export class AppDialogsManager {
|
||||
//const scrollTopWas = this.scroll.scrollTop;
|
||||
|
||||
const rect = this.scroll.container.getBoundingClientRect();
|
||||
const rectX = this.chatList.firstElementChild.getBoundingClientRect();
|
||||
const children = Array.from(this.scroll.splitUp.children) as HTMLElement[];
|
||||
const firstElement = findUpTag(document.elementFromPoint(Math.ceil(rect.x), Math.ceil(rect.y + 1)), 'LI') as HTMLElement;
|
||||
const lastElement = findUpTag(document.elementFromPoint(Math.ceil(rect.x), Math.floor(rect.y + rect.height - 1)), 'LI') as HTMLElement;
|
||||
const firstElement = findUpTag(document.elementFromPoint(Math.ceil(rectX.x), Math.ceil(rect.y + 1)), 'LI') as HTMLElement;
|
||||
const lastElement = findUpTag(document.elementFromPoint(Math.ceil(rectX.x), Math.floor(rect.y + rect.height - 1)), 'LI') as HTMLElement;
|
||||
|
||||
//alert('got element:' + rect.y);
|
||||
|
||||
|
@ -2644,7 +2644,7 @@ export class AppMessagesManager {
|
||||
case 'messageActionChatAddUser': {
|
||||
const users: number[] = (action as MessageAction.messageActionChatAddUser).users || [(action as MessageAction.messageActionChatDeleteUser).user_id];
|
||||
|
||||
l = langPack[_].replace('{}', users.map((userId: number) => getNameDivHTML(userId)).join(', '));
|
||||
l = langPack[_].replace('{}', users.map((userId: number) => getNameDivHTML(userId).trim()).join(', '));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,7 @@ export default class IDBStorage {
|
||||
public storeName: string;
|
||||
|
||||
constructor(options: IDBOptions) {
|
||||
for(let i in options) {
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
Object.assign(this, options);
|
||||
|
||||
this.openDatabase(true);
|
||||
}
|
||||
|
@ -775,13 +775,7 @@
|
||||
}
|
||||
|
||||
.sidebar-left-section {
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
padding: 0 0 .5rem;
|
||||
}
|
||||
|
||||
// * supernew and correct layout
|
||||
|
Loading…
x
Reference in New Issue
Block a user