From 774dcce5280fb35c1f4025c80f4f8261bc8b6ba1 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Sat, 13 Mar 2021 16:24:00 +0400 Subject: [PATCH] Edit channel & group respect rights --- .../sidebarRight/tabs/editChannel.ts | 156 ++++++++++-------- src/components/sidebarRight/tabs/editGroup.ts | 56 ++++--- .../sidebarRight/tabs/sharedMedia.ts | 17 +- src/lib/appManagers/appChatsManager.ts | 72 +++----- src/lib/appManagers/appPeersManager.ts | 2 +- 5 files changed, 166 insertions(+), 137 deletions(-) diff --git a/src/components/sidebarRight/tabs/editChannel.ts b/src/components/sidebarRight/tabs/editChannel.ts index 93ac9a4a..79bc2548 100644 --- a/src/components/sidebarRight/tabs/editChannel.ts +++ b/src/components/sidebarRight/tabs/editChannel.ts @@ -25,85 +25,109 @@ export default class AppEditChannelTab extends SliderSuperTab { { const section = new SettingSection({noDelimiter: true}); - const inputFields: InputField[] = []; - const inputWrapper = document.createElement('div'); - inputWrapper.classList.add('input-wrapper'); - - this.nameInputField = new InputField({ - label: 'Name', - name: 'channel-name', - maxLength: 255 - }); - this.descriptionInputField = new InputField({ - label: 'Description', - name: 'channel-description', - maxLength: 255 - }); - - this.nameInputField.setOriginalValue(appChatsManager.getChat(-this.peerId).title); + if(appChatsManager.hasRights(-this.peerId, 'change_info')) { + const inputFields: InputField[] = []; - this.descriptionInputField.setOriginalValue(chatFull.about); + const inputWrapper = document.createElement('div'); + inputWrapper.classList.add('input-wrapper'); + + this.nameInputField = new InputField({ + label: 'Name', + name: 'channel-name', + maxLength: 255 + }); + this.descriptionInputField = new InputField({ + label: 'Description', + name: 'channel-description', + maxLength: 255 + }); + + this.nameInputField.setOriginalValue(appChatsManager.getChat(-this.peerId).title); - inputWrapper.append(this.nameInputField.container, this.descriptionInputField.container); - - inputFields.push(this.nameInputField, this.descriptionInputField); + this.descriptionInputField.setOriginalValue(chatFull.about); - this.editPeer = new EditPeer({ - peerId: this.peerId, - inputFields, - listenerSetter: this.listenerSetter - }); - this.content.append(this.editPeer.nextBtn); + inputWrapper.append(this.nameInputField.container, this.descriptionInputField.container); + + inputFields.push(this.nameInputField, this.descriptionInputField); - const groupTypeRow = new Row({ - title: 'Channel Type', - subtitle: 'Private', - clickable: true, - icon: 'lock' - }); + this.editPeer = new EditPeer({ + peerId: this.peerId, + inputFields, + listenerSetter: this.listenerSetter + }); + this.content.append(this.editPeer.nextBtn); + + section.content.append(this.editPeer.avatarEdit.container, inputWrapper); + + attachClickEvent(this.editPeer.nextBtn, () => { + this.editPeer.nextBtn.disabled = true; + + let promises: Promise[] = []; + + const id = -this.peerId; + if(this.nameInputField.isValid()) { + promises.push(appChatsManager.editTitle(id, this.nameInputField.value)); + } + + if(this.descriptionInputField.isValid()) { + promises.push(appChatsManager.editAbout(id, this.descriptionInputField.value)); + } + + if(this.editPeer.uploadAvatar) { + promises.push(this.editPeer.uploadAvatar().then(inputFile => { + return appChatsManager.editPhoto(id, inputFile); + })); + } + + Promise.race(promises).finally(() => { + this.editPeer.nextBtn.removeAttribute('disabled'); + this.close(); + }); + }, {listenerSetter: this.listenerSetter}); + } + + if(appChatsManager.hasRights(-this.peerId, 'change_type')) { + const channelTypeRow = new Row({ + title: 'Channel Type', + subtitle: 'Private', + clickable: true, + icon: 'lock' + }); + + section.content.append(channelTypeRow.container); + } + + if(appChatsManager.hasRights(-this.peerId, 'change_info')) { + const discussionRow = new Row({ + title: 'Discussion', + subtitle: 'Add', + clickable: true, + icon: 'message' + }); + + section.content.append(discussionRow.container); + } const administratorsRow = new Row({ title: 'Administrators', - subtitle: '5', + subtitle: '' + chatFull.admins_count, icon: 'admin', clickable: true }); - const signMessagesCheckboxField = new CheckboxField({ - text: 'Sign Messages', - checked: false - }); + section.content.append(administratorsRow.container); + + if(appChatsManager.hasRights(-this.peerId, 'change_info')) { + const signMessagesCheckboxField = new CheckboxField({ + text: 'Sign Messages', + checked: false + }); - section.content.append(this.editPeer.avatarEdit.container, inputWrapper, groupTypeRow.container, administratorsRow.container, signMessagesCheckboxField.label); + section.content.append(signMessagesCheckboxField.label); + } this.scrollable.append(section.container); - - attachClickEvent(this.editPeer.nextBtn, () => { - this.editPeer.nextBtn.disabled = true; - - let promises: Promise[] = []; - - const id = -this.peerId; - if(this.nameInputField.isValid()) { - promises.push(appChatsManager.editTitle(id, this.nameInputField.value)); - } - - if(this.descriptionInputField.isValid()) { - promises.push(appChatsManager.editAbout(id, this.descriptionInputField.value)); - } - - if(this.editPeer.uploadAvatar) { - promises.push(this.editPeer.uploadAvatar().then(inputFile => { - return appChatsManager.editPhoto(id, inputFile); - })); - } - - Promise.race(promises).finally(() => { - this.editPeer.nextBtn.removeAttribute('disabled'); - this.close(); - }); - }, {listenerSetter: this.listenerSetter}); } { @@ -123,7 +147,7 @@ export default class AppEditChannelTab extends SliderSuperTab { this.scrollable.append(section.container); } - { + if(appChatsManager.hasRights(-this.peerId, 'delete_chat')) { const section = new SettingSection({ }); @@ -133,7 +157,7 @@ export default class AppEditChannelTab extends SliderSuperTab { attachClickEvent(btnDelete, () => { new PopupPeer('popup-delete-channel', { peerId: this.peerId, - title: 'Delete Group?', + title: 'Delete Channel?', description: `Are you sure you want to delete this channel? All subscribers will be removed and all messages will be lost.`, buttons: addCancelButton([{ text: 'DELETE', diff --git a/src/components/sidebarRight/tabs/editGroup.ts b/src/components/sidebarRight/tabs/editGroup.ts index 126964f0..52db7c9a 100644 --- a/src/components/sidebarRight/tabs/editGroup.ts +++ b/src/components/sidebarRight/tabs/editGroup.ts @@ -57,21 +57,29 @@ export default class AppEditGroupTab extends SliderSuperTab { }); this.content.append(this.editPeer.nextBtn); - //section.content.append(this.editPeer.avatarEdit.container, inputWrapper); + section.content.append(this.editPeer.avatarEdit.container, inputWrapper); + + if(appChatsManager.hasRights(-this.peerId, 'change_type')) { + const groupTypeRow = new Row({ + title: 'Group Type', + subtitle: 'Private', + clickable: true, + icon: 'lock' + }); + + section.content.append(groupTypeRow.container); + } - const groupTypeRow = new Row({ - title: 'Group Type', - subtitle: 'Private', - clickable: true, - icon: 'lock' - }); + if(appChatsManager.hasRights(-this.peerId, 'change_permissions')) { + const permissionsRow = new Row({ + title: 'Permissions', + subtitle: '8/8', + icon: 'permissions', + clickable: true + }); - const permissionsRow = new Row({ - title: 'Permissions', - subtitle: '8/8', - icon: 'permissions', - clickable: true - }); + section.content.append(permissionsRow.container); + } const administratorsRow = new Row({ title: 'Administrators', @@ -80,7 +88,7 @@ export default class AppEditGroupTab extends SliderSuperTab { clickable: true }); - section.content.append(this.editPeer.avatarEdit.container, inputWrapper, groupTypeRow.container, permissionsRow.container, administratorsRow.container); + section.content.append(administratorsRow.container); this.scrollable.append(section.container); @@ -123,20 +131,24 @@ export default class AppEditGroupTab extends SliderSuperTab { clickable: true }); - const showChatHistoryCheckboxField = new CheckboxField({ - text: 'Show chat history for new members' - }); + section.content.append(membersRow.container); - if(appChatsManager.isChannel(-this.peerId) && !(chatFull as ChatFull.channelFull).pFlags.hidden_prehistory) { - showChatHistoryCheckboxField.value = true; + if(appChatsManager.hasRights(-this.peerId, 'change_permissions')) { + const showChatHistoryCheckboxField = new CheckboxField({ + text: 'Show chat history for new members' + }); + + if(appChatsManager.isChannel(-this.peerId) && !(chatFull as ChatFull.channelFull).pFlags.hidden_prehistory) { + showChatHistoryCheckboxField.value = true; + } + + section.content.append(showChatHistoryCheckboxField.label); } - section.content.append(membersRow.container, showChatHistoryCheckboxField.label); - this.scrollable.append(section.container); } - if(appChatsManager.isChannel(-this.peerId)) { + if(appChatsManager.isChannel(-this.peerId) && appChatsManager.hasRights(-this.peerId, 'delete_chat')) { const section = new SettingSection({}); const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'Delete Group'}); diff --git a/src/components/sidebarRight/tabs/sharedMedia.ts b/src/components/sidebarRight/tabs/sharedMedia.ts index aa6f5829..36fea822 100644 --- a/src/components/sidebarRight/tabs/sharedMedia.ts +++ b/src/components/sidebarRight/tabs/sharedMedia.ts @@ -19,6 +19,8 @@ import AppEditGroupTab from "./editGroup"; import PeerTitle from "../../peerTitle"; import AppEditChannelTab from "./editChannel"; import AppEditContactTab from "./editContact"; +import appChatsManager from "../../../lib/appManagers/appChatsManager"; +import { Chat } from "../../../layer"; let setText = (text: string, el: HTMLDivElement) => { window.requestAnimationFrame(() => { @@ -207,7 +209,7 @@ export default class AppSharedMediaTab implements SliderTab { const peerId = this.peerId; if(needClear) { - this.profileElements.subtitle.innerHTML = ''; + this.profileElements.subtitle.innerHTML = '‎'; // ! HERE U CAN FIND WHITESPACE } appImManager.getPeerStatus(this.peerId).then((subtitle) => { @@ -215,7 +217,7 @@ export default class AppSharedMediaTab implements SliderTab { return; } - this.profileElements.subtitle.innerHTML = subtitle; + this.profileElements.subtitle.innerHTML = subtitle || ''; }); }; @@ -368,7 +370,16 @@ export default class AppSharedMediaTab implements SliderTab { dialog: true }).element); - this.editBtn.style.display = ''; + if(peerId > 0) { + if(peerId !== rootScope.myId && appUsersManager.isContact(peerId)) { + this.editBtn.style.display = ''; + } + } else { + const chat: Chat = appChatsManager.getChat(-peerId); + if(chat._ === 'chat' || (chat as Chat.channel).admin_rights) { + this.editBtn.style.display = ''; + } + } this.setPeerStatus(true); } diff --git a/src/lib/appManagers/appChatsManager.ts b/src/lib/appManagers/appChatsManager.ts index 49569bd9..a1757392 100644 --- a/src/lib/appManagers/appChatsManager.ts +++ b/src/lib/appManagers/appChatsManager.ts @@ -14,7 +14,7 @@ import appUsersManager from "./appUsersManager"; export type Channel = Chat.channel; -export type ChatRights = 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin' | 'deleteRevoke' | 'delete'; +export type ChatRights = 'send' | 'change_info' | 'change_permissions' | 'change_type' | 'pin_messages' | 'deleteRevoke' | 'delete_chat'; export type UserTyping = Partial<{userId: number, action: SendMessageAction, timeout: number}>; @@ -172,13 +172,13 @@ export class AppChatsManager { } public hasRights(id: number, action: ChatRights, flag?: keyof ChatBannedRights['pFlags']) { - const chat = this.getChat(id); + const chat: Chat = this.getChat(id); if(chat._ === 'chatEmpty') return false; if(chat._ === 'chatForbidden' || chat._ === 'channelForbidden' || - chat.pFlags.kicked || - (chat.pFlags.left && !chat.pFlags.megagroup)) { + (chat as Chat.chat).pFlags.kicked || + (chat.pFlags.left && !(chat as Chat.channel).pFlags.megagroup)) { return false; } @@ -186,19 +186,23 @@ export class AppChatsManager { return true; } - const rights = chat.admin_rights || chat.banned_rights || chat.default_banned_rights; - let myFlags: {[flag in keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags']]: true}; - if(rights) myFlags = rights.pFlags; + const rights = chat.admin_rights || (chat as Chat.channel).banned_rights || chat.default_banned_rights; + if(!rights) { + return false; + } + + let myFlags: Partial<{[flag in keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags']]: true}> = {}; + if(rights) myFlags = rights.pFlags as any; switch(action) { // good case 'send': { - if(flag && myFlags && myFlags[flag]) { + if(flag && myFlags[flag]) { return false; } if(chat._ === 'channel') { - if((!chat.pFlags.megagroup && !myFlags?.post_messages)) { + if((!chat.pFlags.megagroup && !myFlags.post_messages)) { return false; } } @@ -206,49 +210,27 @@ export class AppChatsManager { break; } - // good + // * revoke foreign messages case 'deleteRevoke': { - if(chat._ === 'channel') { - return !!myFlags?.delete_messages; - } else if(!chat.pFlags.admin) { - return false; - } - - break; + return !!myFlags.delete_messages; } - // good - case 'pin': { - if(chat._ === 'channel') { - return chat.admin_rights ? !!myFlags.pin_messages || !!myFlags.post_messages : myFlags && !myFlags.pin_messages; - } else { - if(myFlags?.pin_messages && !chat.pFlags.admin) { - return false; - } - } + case 'pin_messages': { + return rights._ === 'chatAdminRights' ? myFlags[action] || !!myFlags.post_messages : !myFlags[action]; + } - break; + case 'change_info': { + return rights._ === 'chatAdminRights' ? myFlags[action] : !myFlags[action]; } - case 'edit_title': - case 'edit_photo': - case 'invite': { - if(chat._ === 'channel') { - if(chat.pFlags.megagroup) { - if(!(action === 'invite' && chat.pFlags.democracy)) { - return false; - } - } else { - return false; - } - } else { - if(chat.pFlags.admins_enabled && - !chat.pFlags.admin) { - return false; - } - } + // * only creator can do that + case 'change_type': + case 'delete_chat': { + return false; + } - break; + case 'change_permissions': { + return rights._ === 'chatAdminRights' && myFlags['ban_users']; } } diff --git a/src/lib/appManagers/appPeersManager.ts b/src/lib/appManagers/appPeersManager.ts index d980d235..f2772dd0 100644 --- a/src/lib/appManagers/appPeersManager.ts +++ b/src/lib/appManagers/appPeersManager.ts @@ -42,7 +42,7 @@ export class AppPeersManager { } */ public canPinMessage(peerId: number) { - return peerId > 0 || appChatsManager.hasRights(-peerId, 'pin'); + return peerId > 0 || appChatsManager.hasRights(-peerId, 'pin_messages'); } public getPeerPhoto(peerId: number) {