334 lines
12 KiB
TypeScript
334 lines
12 KiB
TypeScript
/*
|
|
* https://github.com/morethanwords/tweb
|
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
|
*/
|
|
|
|
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
|
|
import findUpTag from "../../../helpers/dom/findUpTag";
|
|
import replaceContent from "../../../helpers/dom/replaceContent";
|
|
import ListenerSetter from "../../../helpers/listenerSetter";
|
|
import ScrollableLoader from "../../../helpers/scrollableLoader";
|
|
import { ChannelParticipant, Chat, ChatBannedRights, Update } from "../../../layer";
|
|
import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager";
|
|
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
|
import appPeersManager from "../../../lib/appManagers/appPeersManager";
|
|
import appProfileManager from "../../../lib/appManagers/appProfileManager";
|
|
import I18n, { i18n, join, LangPackKey } from "../../../lib/langPack";
|
|
import rootScope from "../../../lib/rootScope";
|
|
import CheckboxField from "../../checkboxField";
|
|
import PopupPickUser from "../../popups/pickUser";
|
|
import Row from "../../row";
|
|
import { SettingSection } from "../../sidebarLeft";
|
|
import { SliderSuperTabEventable } from "../../sliderTab";
|
|
import { toast } from "../../toast";
|
|
import AppUserPermissionsTab from "./userPermissions";
|
|
|
|
export class ChatPermissions {
|
|
public v: Array<{
|
|
flags: ChatRights[],
|
|
text: LangPackKey,
|
|
exceptionText: LangPackKey,
|
|
checkboxField?: CheckboxField,
|
|
}>;
|
|
private toggleWith: Partial<{[chatRight in ChatRights]: ChatRights[]}>;
|
|
|
|
constructor(options: {
|
|
chatId: ChatId,
|
|
listenerSetter: ListenerSetter,
|
|
appendTo: HTMLElement,
|
|
participant?: ChannelParticipant.channelParticipantBanned
|
|
}) {
|
|
this.v = [
|
|
{flags: ['send_messages'], text: 'UserRestrictionsSend', exceptionText: 'UserRestrictionsNoSend'},
|
|
{flags: ['send_media'], text: 'UserRestrictionsSendMedia', exceptionText: 'UserRestrictionsNoSendMedia'},
|
|
{flags: ['send_stickers', 'send_gifs'], text: 'UserRestrictionsSendStickers', exceptionText: 'UserRestrictionsNoSendStickers'},
|
|
{flags: ['send_polls'], text: 'UserRestrictionsSendPolls', exceptionText: 'UserRestrictionsNoSendPolls'},
|
|
{flags: ['embed_links'], text: 'UserRestrictionsEmbedLinks', exceptionText: 'UserRestrictionsNoEmbedLinks'},
|
|
{flags: ['invite_users'], text: 'UserRestrictionsInviteUsers', exceptionText: 'UserRestrictionsNoInviteUsers'},
|
|
{flags: ['pin_messages'], text: 'UserRestrictionsPinMessages', exceptionText: 'UserRestrictionsNoPinMessages'},
|
|
{flags: ['change_info'], text: 'UserRestrictionsChangeInfo', exceptionText: 'UserRestrictionsNoChangeInfo'}
|
|
];
|
|
|
|
this.toggleWith = {
|
|
'send_messages': ['send_media', 'send_stickers', 'send_polls', 'embed_links']
|
|
};
|
|
|
|
const chat: Chat.chat = appChatsManager.getChat(options.chatId);
|
|
const defaultBannedRights = chat.default_banned_rights;
|
|
const rights = options.participant ? appChatsManager.combineParticipantBannedRights(options.chatId, options.participant.banned_rights) : defaultBannedRights;
|
|
|
|
for(const info of this.v) {
|
|
const mainFlag = info.flags[0];
|
|
info.checkboxField = new CheckboxField({
|
|
text: info.text,
|
|
checked: appChatsManager.hasRights(options.chatId, mainFlag, rights),
|
|
restriction: true,
|
|
withRipple: true
|
|
});
|
|
|
|
// @ts-ignore
|
|
if(options.participant && defaultBannedRights.pFlags[mainFlag]) {
|
|
info.checkboxField.input.disabled = true;
|
|
|
|
/* options.listenerSetter.add(info.checkboxField.input)('change', (e) => {
|
|
if(!e.isTrusted) {
|
|
return;
|
|
}
|
|
|
|
cancelEvent(e);
|
|
toast('This option is disabled for all members in Group Permissions.');
|
|
info.checkboxField.checked = false;
|
|
}); */
|
|
|
|
attachClickEvent(info.checkboxField.label, (e) => {
|
|
toast(I18n.format('UserRestrictionsDisabled', true));
|
|
}, {listenerSetter: options.listenerSetter});
|
|
}
|
|
|
|
if(this.toggleWith[mainFlag]) {
|
|
options.listenerSetter.add(info.checkboxField.input)('change', () => {
|
|
if(!info.checkboxField.checked) {
|
|
const other = this.v.filter(i => this.toggleWith[mainFlag].includes(i.flags[0]));
|
|
other.forEach(info => {
|
|
info.checkboxField.checked = false;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
options.appendTo.append(info.checkboxField.label);
|
|
}
|
|
}
|
|
|
|
public takeOut() {
|
|
const rights: ChatBannedRights = {
|
|
_: 'chatBannedRights',
|
|
until_date: 0x7FFFFFFF,
|
|
pFlags: {}
|
|
};
|
|
|
|
for(const info of this.v) {
|
|
const banned = !info.checkboxField.checked;
|
|
if(banned) {
|
|
info.flags.forEach(flag => {
|
|
// @ts-ignore
|
|
rights.pFlags[flag] = true;
|
|
});
|
|
}
|
|
}
|
|
|
|
return rights;
|
|
}
|
|
}
|
|
|
|
export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
|
public chatId: ChatId;
|
|
|
|
protected async init() {
|
|
this.container.classList.add('edit-peer-container', 'group-permissions-container');
|
|
this.setTitle('ChannelPermissions');
|
|
|
|
let chatPermissions: ChatPermissions;
|
|
{
|
|
const section = new SettingSection({
|
|
name: 'ChannelPermissionsHeader',
|
|
});
|
|
|
|
chatPermissions = new ChatPermissions({
|
|
chatId: this.chatId,
|
|
listenerSetter: this.listenerSetter,
|
|
appendTo: section.content,
|
|
});
|
|
|
|
this.eventListener.addEventListener('destroy', () => {
|
|
appChatsManager.editChatDefaultBannedRights(this.chatId, chatPermissions.takeOut());
|
|
}, {once: true});
|
|
|
|
this.scrollable.append(section.container);
|
|
}
|
|
|
|
{
|
|
const section = new SettingSection({
|
|
name: 'PrivacyExceptions'
|
|
});
|
|
|
|
const addExceptionRow = new Row({
|
|
titleLangKey: 'ChannelAddException',
|
|
subtitleLangKey: 'Loading',
|
|
icon: 'adduser',
|
|
clickable: () => {
|
|
new PopupPickUser({
|
|
peerTypes: ['channelParticipants'],
|
|
onSelect: (peerId) => {
|
|
setTimeout(() => {
|
|
openPermissions(peerId);
|
|
}, 0);
|
|
},
|
|
placeholder: 'ExceptionModal.Search.Placeholder',
|
|
peerId: -this.chatId,
|
|
});
|
|
}
|
|
});
|
|
|
|
const openPermissions = async(peerId: PeerId) => {
|
|
let participant: AppUserPermissionsTab['participant'];
|
|
try {
|
|
participant = await appProfileManager.getChannelParticipant(this.chatId, peerId) as any;
|
|
} catch(err) {
|
|
toast('User is no longer participant');
|
|
return;
|
|
}
|
|
|
|
const tab = new AppUserPermissionsTab(this.slider);
|
|
tab.participant = participant;
|
|
tab.chatId = this.chatId;
|
|
tab.userId = peerId;
|
|
tab.open();
|
|
};
|
|
|
|
section.content.append(addExceptionRow.container);
|
|
|
|
/* const removedUsersRow = new Row({
|
|
titleLangKey: 'ChannelBlockedUsers',
|
|
subtitleLangKey: 'NoBlockedUsers',
|
|
icon: 'deleteuser',
|
|
clickable: true
|
|
});
|
|
|
|
section.content.append(removedUsersRow.container); */
|
|
|
|
const c = section.generateContentElement();
|
|
c.classList.add('chatlist-container');
|
|
|
|
const list = appDialogsManager.createChatList({new: true});
|
|
c.append(list);
|
|
|
|
attachClickEvent(list, (e) => {
|
|
const target = findUpTag(e.target, 'LI');
|
|
if(!target) return;
|
|
|
|
const peerId = target.dataset.peerId.toPeerId();
|
|
openPermissions(peerId);
|
|
}, {listenerSetter: this.listenerSetter});
|
|
|
|
const setSubtitle = (li: Element, participant: ChannelParticipant.channelParticipantBanned) => {
|
|
const bannedRights = participant.banned_rights;//appChatsManager.combineParticipantBannedRights(this.chatId, participant.banned_rights);
|
|
const defaultBannedRights = (appChatsManager.getChat(this.chatId) as Chat.channel).default_banned_rights;
|
|
//const combinedRights = appChatsManager.combineParticipantBannedRights(this.chatId, bannedRights);
|
|
|
|
const cantWhat: LangPackKey[] = []/* , canWhat: LangPackKey[] = [] */;
|
|
chatPermissions.v.forEach(info => {
|
|
const mainFlag = info.flags[0];
|
|
// @ts-ignore
|
|
if(bannedRights.pFlags[mainFlag] && !defaultBannedRights.pFlags[mainFlag]) {
|
|
cantWhat.push(info.exceptionText);
|
|
// @ts-ignore
|
|
}/* else if(!combinedRights.pFlags[mainFlag]) {
|
|
canWhat.push(info.exceptionText);
|
|
} */
|
|
});
|
|
|
|
const el = li.querySelector('.user-last-message') as HTMLElement;
|
|
|
|
if(cantWhat.length) {
|
|
el.innerHTML = '';
|
|
el.append(...join(cantWhat.map(t => i18n(t)), false));
|
|
}/* else if(canWhat.length) {
|
|
str = 'Can ' + canWhat.join(canWhat.length === 2 ? ' and ' : ', ');
|
|
} */
|
|
|
|
el.classList.toggle('hide', !cantWhat.length);
|
|
};
|
|
|
|
const add = (participant: ChannelParticipant.channelParticipantBanned, append: boolean) => {
|
|
const {dom} = appDialogsManager.addDialogNew({
|
|
dialog: appPeersManager.getPeerId(participant.peer),
|
|
container: list,
|
|
drawStatus: false,
|
|
rippleEnabled: true,
|
|
avatarSize: 48,
|
|
append
|
|
});
|
|
|
|
setSubtitle(dom.listEl, participant);
|
|
|
|
//dom.titleSpan.innerHTML = 'Chinaza Akachi';
|
|
//dom.lastMessageSpan.innerHTML = 'Can Add Users and Pin Messages';
|
|
};
|
|
|
|
this.listenerSetter.add(rootScope)('updateChannelParticipant', (update: Update.updateChannelParticipant) => {
|
|
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) {
|
|
add(update.new_participant as ChannelParticipant.channelParticipantBanned, false);
|
|
} else {
|
|
setSubtitle(li, update.new_participant as ChannelParticipant.channelParticipantBanned);
|
|
}
|
|
|
|
if(update.prev_participant?._ !== 'channelParticipantBanned') {
|
|
++exceptionsCount;
|
|
}
|
|
} else {
|
|
if(li) {
|
|
li.remove();
|
|
}
|
|
|
|
if(update.prev_participant?._ === 'channelParticipantBanned') {
|
|
--exceptionsCount;
|
|
}
|
|
}
|
|
|
|
setLength();
|
|
});
|
|
|
|
const setLength = () => {
|
|
replaceContent(addExceptionRow.subtitle, i18n(exceptionsCount ? 'Permissions.ExceptionsCount' : 'Permissions.NoExceptions', [exceptionsCount]));
|
|
};
|
|
|
|
let exceptionsCount = 0;
|
|
let loader: ScrollableLoader;
|
|
const setLoader = () => {
|
|
const LOAD_COUNT = 50;
|
|
loader = new ScrollableLoader({
|
|
scrollable: this.scrollable,
|
|
getPromise: () => {
|
|
return appProfileManager.getChannelParticipants(this.chatId, {_: 'channelParticipantsBanned', q: ''}, LOAD_COUNT, list.childElementCount).then(res => {
|
|
for(const participant of res.participants) {
|
|
add(participant as ChannelParticipant.channelParticipantBanned, true);
|
|
}
|
|
|
|
exceptionsCount = res.count;
|
|
setLength();
|
|
|
|
return res.participants.length < LOAD_COUNT || res.count === list.childElementCount;
|
|
});
|
|
}
|
|
});
|
|
|
|
return loader.load();
|
|
};
|
|
|
|
this.scrollable.append(section.container);
|
|
|
|
if(appChatsManager.isChannel(this.chatId)) {
|
|
await setLoader();
|
|
} else {
|
|
setLength();
|
|
|
|
this.listenerSetter.add(rootScope)('dialog_migrate', ({migrateFrom, migrateTo}) => {
|
|
if(this.chatId === migrateFrom) {
|
|
this.chatId = migrateTo;
|
|
setLoader();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
onOpenAfterTimeout() {
|
|
this.scrollable.onScroll();
|
|
}
|
|
}
|