diff --git a/src/components/appSelectPeers.ts b/src/components/appSelectPeers.ts index 6494adb8..a877317a 100644 --- a/src/components/appSelectPeers.ts +++ b/src/components/appSelectPeers.ts @@ -217,7 +217,7 @@ export default class AppSelectPeers { if(this.chatRightsAction) { dialogs = dialogs.filter(d => { - return (d.peerId > 0 && (this.chatRightsAction !== 'send' || appUsersManager.canSendToUser(d.peerId))) || appChatsManager.hasRights(-d.peerId, this.chatRightsAction); + return (d.peerId > 0 && (this.chatRightsAction !== 'send_messages' || appUsersManager.canSendToUser(d.peerId))) || appChatsManager.hasRights(-d.peerId, this.chatRightsAction); }); } diff --git a/src/components/chat/contextMenu.ts b/src/components/chat/contextMenu.ts index ca331a27..8de912b6 100644 --- a/src/components/chat/contextMenu.ts +++ b/src/components/chat/contextMenu.ts @@ -178,7 +178,7 @@ export default class ChatContextMenu { icon: 'reply', text: 'Reply', onClick: this.onReplyClick, - verify: () => (this.peerId > 0 || this.appChatsManager.hasRights(-this.peerId, 'send')) && + verify: () => (this.peerId > 0 || this.appChatsManager.hasRights(-this.peerId, 'send_messages')) && !this.message.pFlags.is_outgoing && !!this.chat.input.messageInput && this.chat.type !== 'scheduled'/* , diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index ae3ba178..fb4a5480 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -273,7 +273,7 @@ export default class ChatInput { this.willAttachType = 'media'; this.fileInput.click(); }, - verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send', 'send_media') + verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send_media') }, { icon: 'document', text: 'Document', @@ -283,14 +283,14 @@ export default class ChatInput { this.willAttachType = 'document'; this.fileInput.click(); }, - verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send', 'send_media') + verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send_media') }, { icon: 'poll', text: 'Poll', onClick: () => { new PopupCreatePoll(this.chat).show(); }, - verify: (peerId: number) => peerId < 0 && this.appChatsManager.hasRights(peerId, 'send', 'send_polls') + verify: (peerId: number) => peerId < 0 && this.appChatsManager.hasRights(peerId, 'send_polls') }]; this.attachMenu = ButtonMenuToggle({noRipple: true, listenerSetter: this.listenerSetter}, 'top-left', this.attachMenuButtons); @@ -971,7 +971,7 @@ export default class ChatInput { if(this.stickersHelper && rootScope.settings.stickers.suggest && - (this.chat.peerId > 0 || this.appChatsManager.hasRights(this.chat.peerId, 'send', 'send_stickers'))) { + (this.chat.peerId > 0 || this.appChatsManager.hasRights(this.chat.peerId, 'send_stickers'))) { let emoticon = ''; if(entities.length && entities[0]._ === 'messageEntityEmoji') { const entity = entities[0]; @@ -1076,7 +1076,7 @@ export default class ChatInput { this.sendMessage(); } } else { - if(this.chat.peerId < 0 && !this.appChatsManager.hasRights(this.chat.peerId, 'send', 'send_media')) { + if(this.chat.peerId < 0 && !this.appChatsManager.hasRights(this.chat.peerId, 'send_media')) { toast(POSTING_MEDIA_NOT_ALLOWED); return; } @@ -1327,7 +1327,7 @@ export default class ChatInput { document = this.appDocsManager.getDoc(document); const flag = document.type === 'sticker' ? 'send_stickers' : (document.type === 'gif' ? 'send_gifs' : 'send_media'); - if(this.chat.peerId < 0 && !this.appChatsManager.hasRights(this.chat.peerId, 'send', flag)) { + if(this.chat.peerId < 0 && !this.appChatsManager.hasRights(this.chat.peerId, flag)) { toast(POSTING_MEDIA_NOT_ALLOWED); return; } diff --git a/src/components/checkboxField.ts b/src/components/checkboxField.ts index 2b02d209..c9ab7177 100644 --- a/src/components/checkboxField.ts +++ b/src/components/checkboxField.ts @@ -13,10 +13,15 @@ export default class CheckboxField { stateKey?: string, disabled?: boolean, checked?: boolean, + restriction?: boolean } = {}) { const label = this.label = document.createElement('label'); label.classList.add('checkbox-field'); + if(options.restriction) { + label.classList.add('checkbox-field-restriction'); + } + if(options.round) { label.classList.add('checkbox-field-round'); } diff --git a/src/components/emoticonsDropdown/index.ts b/src/components/emoticonsDropdown/index.ts index c7a37a55..dd8354e2 100644 --- a/src/components/emoticonsDropdown/index.ts +++ b/src/components/emoticonsDropdown/index.ts @@ -199,10 +199,10 @@ export class EmoticonsDropdown { const children = this.tabsEl.children; const tabsElements = Array.from(children) as HTMLElement[]; - const canSendStickers = peerId > 0 || appChatsManager.hasRights(peerId, 'send', 'send_stickers'); + const canSendStickers = peerId > 0 || appChatsManager.hasRights(peerId, 'send_stickers'); tabsElements[2].toggleAttribute('disabled', !canSendStickers); - const canSendGifs = peerId > 0 || appChatsManager.hasRights(peerId, 'send', 'send_gifs'); + const canSendGifs = peerId > 0 || appChatsManager.hasRights(peerId, 'send_gifs'); tabsElements[3].toggleAttribute('disabled', !canSendGifs); const active = this.tabsEl.querySelector('.active'); diff --git a/src/components/popups/deleteMessages.ts b/src/components/popups/deleteMessages.ts index 6568e321..41d8268b 100644 --- a/src/components/popups/deleteMessages.ts +++ b/src/components/popups/deleteMessages.ts @@ -46,7 +46,7 @@ export default class PopupDeleteMessages { } else { const chat = appChatsManager.getChat(-peerId); - const hasRights = appChatsManager.hasRights(-peerId, 'deleteRevoke'); + const hasRights = appChatsManager.hasRights(-peerId, 'delete_messages'); if(chat._ === 'chat') { const canRevoke = hasRights ? mids.slice() : mids.filter(mid => { const message = appMessagesManager.getMessageByPeer(peerId, mid); diff --git a/src/components/popups/forward.ts b/src/components/popups/forward.ts index dbc4f261..c9e5c374 100644 --- a/src/components/popups/forward.ts +++ b/src/components/popups/forward.ts @@ -18,7 +18,7 @@ export default class PopupForward extends PopupPickUser { }, onClose, placeholder: 'Forward to...', - chatRightsAction: 'send' + chatRightsAction: 'send_messages' }); } } diff --git a/src/components/sidebarRight/tabs/editGroup.ts b/src/components/sidebarRight/tabs/editGroup.ts index 7f7e3c11..921c0953 100644 --- a/src/components/sidebarRight/tabs/editGroup.ts +++ b/src/components/sidebarRight/tabs/editGroup.ts @@ -5,7 +5,7 @@ import { SettingSection } from "../../sidebarLeft"; import Row from "../../row"; import CheckboxField from "../../checkboxField"; import Button from "../../button"; -import appChatsManager from "../../../lib/appManagers/appChatsManager"; +import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager"; import appProfileManager from "../../../lib/appManagers/appProfileManager"; import { attachClickEvent, toggleDisability } from "../../../helpers/dom"; import { ChatFull } from "../../../layer"; @@ -13,12 +13,13 @@ import PopupPeer from "../../popups/peer"; import { addCancelButton } from "../../popups"; import AppGroupTypeTab from "./groupType"; import rootScope from "../../../lib/rootScope"; +import AppGroupPermissionsTab from "./groupPermissions"; export default class AppEditGroupTab extends SliderSuperTab { private groupNameInputField: InputField; private descriptionInputField: InputField; private editPeer: EditPeer; - public peerId: number; + public chatId: number; protected async _init() { // * cleanup prev @@ -28,7 +29,7 @@ export default class AppEditGroupTab extends SliderSuperTab { this.container.classList.add('edit-peer-container', 'edit-group-container'); this.title.innerHTML = 'Edit'; - const chatFull = await appProfileManager.getChatFull(-this.peerId, true); + const chatFull = await appProfileManager.getChatFull(this.chatId, true); { const section = new SettingSection({noDelimiter: true}); @@ -48,7 +49,7 @@ export default class AppEditGroupTab extends SliderSuperTab { maxLength: 255 }); - const chat = appChatsManager.getChat(-this.peerId); + const chat = appChatsManager.getChat(this.chatId); this.groupNameInputField.setOriginalValue(chat.title); @@ -59,7 +60,7 @@ export default class AppEditGroupTab extends SliderSuperTab { inputFields.push(this.groupNameInputField, this.descriptionInputField); this.editPeer = new EditPeer({ - peerId: this.peerId, + peerId: -this.chatId, inputFields, listenerSetter: this.listenerSetter }); @@ -67,12 +68,12 @@ export default class AppEditGroupTab extends SliderSuperTab { section.content.append(this.editPeer.avatarEdit.container, inputWrapper); - if(appChatsManager.hasRights(-this.peerId, 'change_type')) { + if(appChatsManager.hasRights(this.chatId, 'change_type')) { const groupTypeRow = new Row({ title: 'Group Type', clickable: () => { const tab = new AppGroupTypeTab(this.slider); - tab.peerId = this.peerId; + tab.peerId = -this.chatId; tab.chatFull = chatFull; tab.open(); @@ -89,15 +90,40 @@ export default class AppEditGroupTab extends SliderSuperTab { section.content.append(groupTypeRow.container); } - if(appChatsManager.hasRights(-this.peerId, 'change_permissions')) { + if(appChatsManager.hasRights(this.chatId, 'change_permissions')) { + const flags = [ + 'send_messages', + 'send_media', + 'send_stickers', + 'send_polls', + 'embed_links', + 'invite_users', + 'pin_messages', + 'change_info' + ] as ChatRights[]; + const permissionsRow = new Row({ title: 'Permissions', - subtitle: '8/8', + clickable: () => { + const tab = new AppGroupPermissionsTab(this.slider); + tab.chatId = this.chatId; + tab.open(); + }, icon: 'permissions', - clickable: true }); + const setPermissionsLength = () => { + permissionsRow.subtitle.innerHTML = flags.reduce((acc, f) => acc + +appChatsManager.hasRights(this.chatId, f, 0), 0) + '/' + flags.length; + }; + + setPermissionsLength(); section.content.append(permissionsRow.container); + + this.listenerSetter.add(rootScope, 'chat_update', (chatId) => { + if(this.chatId === chatId) { + setPermissionsLength(); + } + }); } const administratorsRow = new Row({ @@ -116,7 +142,7 @@ export default class AppEditGroupTab extends SliderSuperTab { let promises: Promise[] = []; - const id = -this.peerId; + const id = this.chatId; if(this.groupNameInputField.isValid()) { promises.push(appChatsManager.editTitle(id, this.groupNameInputField.value)); } @@ -152,12 +178,12 @@ export default class AppEditGroupTab extends SliderSuperTab { section.content.append(membersRow.container); - if(appChatsManager.hasRights(-this.peerId, 'change_permissions')) { + if(appChatsManager.hasRights(this.chatId, '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) { + if(appChatsManager.isChannel(this.chatId) && !(chatFull as ChatFull.channelFull).pFlags.hidden_prehistory) { showChatHistoryCheckboxField.checked = true; } @@ -167,14 +193,14 @@ export default class AppEditGroupTab extends SliderSuperTab { this.scrollable.append(section.container); } - if(appChatsManager.isChannel(-this.peerId) && appChatsManager.hasRights(-this.peerId, 'delete_chat')) { + if(appChatsManager.isChannel(this.chatId) && appChatsManager.hasRights(this.chatId, 'delete_chat')) { const section = new SettingSection({}); const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'Delete Group'}); attachClickEvent(btnDelete, () => { new PopupPeer('popup-delete-group', { - peerId: this.peerId, + 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.`, buttons: addCancelButton([{ @@ -182,7 +208,7 @@ export default class AppEditGroupTab extends SliderSuperTab { callback: () => { toggleDisability([btnDelete], true); - appChatsManager.deleteChannel(-this.peerId).then(() => { + appChatsManager.deleteChannel(this.chatId).then(() => { this.close(); }, () => { toggleDisability([btnDelete], false); @@ -200,8 +226,8 @@ export default class AppEditGroupTab extends SliderSuperTab { // ! this one will fire earlier than tab's closeAfterTimeout (destroy) event and listeners will be erased, so destroy won't fire this.listenerSetter.add(rootScope, 'dialog_migrate', ({migrateFrom, migrateTo}) => { - if(this.peerId === migrateFrom) { - this.peerId = migrateTo; + if(-this.chatId === migrateFrom) { + this.chatId = -migrateTo; this._init(); } }); diff --git a/src/components/sidebarRight/tabs/forward.ts b/src/components/sidebarRight/tabs/forward.ts index e1d7c200..11c313dc 100644 --- a/src/components/sidebarRight/tabs/forward.ts +++ b/src/components/sidebarRight/tabs/forward.ts @@ -89,7 +89,7 @@ export default class AppForwardTab implements SliderTab { }); document.body.classList.add('is-forward-active'); }, - chatRightsAction: 'send' + chatRightsAction: 'send_messages' }); } } diff --git a/src/components/sidebarRight/tabs/groupPermissions.ts b/src/components/sidebarRight/tabs/groupPermissions.ts new file mode 100644 index 00000000..68fc955b --- /dev/null +++ b/src/components/sidebarRight/tabs/groupPermissions.ts @@ -0,0 +1,129 @@ +import ListenerSetter from "../../../helpers/listenerSetter"; +import { Chat, ChatBannedRights } from "../../../layer"; +import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager"; +import CheckboxField from "../../checkboxField"; +import Row from "../../row"; +import { SettingSection } from "../../sidebarLeft"; +import { SliderSuperTabEventable } from "../../sliderTab"; + +export default class AppGroupPermissionsTab extends SliderSuperTabEventable { + public chatId: number; + + protected init() { + this.container.classList.add('edit-peer-container', 'group-permissions-container'); + this.title.innerHTML = 'Permissions'; + + class ChatPermissions { + private v: Array<{ + flags: ChatRights[], + text: string, + checkboxField?: CheckboxField + }>; + private toggleWith: Partial<{[chatRight in ChatRights]: ChatRights[]}>; + + constructor(options: { + chatId: number, + listenerSetter: ListenerSetter, + appendTo: HTMLElement, + userId: number + }) { + this.v = [ + {flags: ['send_messages'], text: 'Send Messages'}, + {flags: ['send_media'], text: 'Send Media'}, + {flags: ['send_stickers', 'send_gifs'], text: 'Send Stickers & GIFs'}, + {flags: ['send_polls'], text: 'Send Polls'}, + {flags: ['embed_links'], text: 'Send Links'}, + {flags: ['invite_users'], text: 'Add Users'}, + {flags: ['pin_messages'], text: 'Pin Messages'}, + {flags: ['change_info'], text: 'Change Chat Info'} + ]; + + this.toggleWith = { + 'send_messages': ['send_media', 'send_stickers', 'send_polls', 'embed_links'] + }; + + for(const info of this.v) { + const mainFlag = info.flags[0]; + info.checkboxField = new CheckboxField({ + text: info.text, + checked: appChatsManager.hasRights(options.chatId, mainFlag, options.userId), + restriction: true + }); + + 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; + } + } + + { + const section = new SettingSection({ + name: 'What can members of this group do?', + }); + + const p = new ChatPermissions({ + chatId: this.chatId, + listenerSetter: this.listenerSetter, + appendTo: section.content, + userId: 0 + }); + + this.eventListener.addEventListener('destroy', () => { + appChatsManager.editChatDefaultBannedRights(this.chatId, p.takeOut()); + }); + + this.scrollable.append(section.container); + } + + { + const section = new SettingSection({ + name: 'Exceptions' + }); + + const removedUsersRow = new Row({ + title: 'Removed Users', + subtitle: 'No removed users', + icon: 'deleteuser', + clickable: true + }); + + section.content.append(removedUsersRow.container); + + const c = section.generateContentElement(); + c.classList.add('chatlist-container'); + + + this.scrollable.append(section.container); + } + } +} diff --git a/src/components/sidebarRight/tabs/sharedMedia.ts b/src/components/sidebarRight/tabs/sharedMedia.ts index 36fea822..96bedd51 100644 --- a/src/components/sidebarRight/tabs/sharedMedia.ts +++ b/src/components/sidebarRight/tabs/sharedMedia.ts @@ -143,7 +143,12 @@ export default class AppSharedMediaTab implements SliderTab { } if(tab) { - tab.peerId = this.peerId; + if(tab instanceof AppEditGroupTab) { + tab.chatId = -this.peerId; + } else { + tab.peerId = this.peerId; + } + tab.open(); } }); diff --git a/src/lib/appManagers/appChatsManager.ts b/src/lib/appManagers/appChatsManager.ts index 74e381c1..2db13a9d 100644 --- a/src/lib/appManagers/appChatsManager.ts +++ b/src/lib/appManagers/appChatsManager.ts @@ -1,6 +1,6 @@ import { MOUNT_CLASS_TO } from "../../config/debug"; import { numberThousandSplitter } from "../../helpers/number"; -import { isObject, safeReplaceObject, copy } from "../../helpers/object"; +import { isObject, safeReplaceObject, copy, deepEqual } from "../../helpers/object"; import { Chat, ChatAdminRights, ChatBannedRights, ChatFull, ChatParticipants, InputChannel, InputChatPhoto, InputFile, InputPeer, SendMessageAction, Update, Updates } from "../../layer"; import apiManager from '../mtproto/mtprotoworker'; import { RichTextProcessor } from "../richtextprocessor"; @@ -14,7 +14,7 @@ import appUsersManager from "./appUsersManager"; export type Channel = Chat.channel; -export type ChatRights = 'send' | 'change_info' | 'change_permissions' | 'change_type' | 'pin_messages' | 'deleteRevoke' | 'delete_chat'; +export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags'] | 'change_type' | 'change_permissions' | 'delete_chat'; export type UserTyping = Partial<{userId: number, action: SendMessageAction, timeout: number}>; @@ -30,15 +30,26 @@ export class AppChatsManager { public typingsInPeer: {[peerId: number]: UserTyping[]} = {}; constructor() { - rootScope.on('apiUpdate', (e) => { + rootScope.on('apiUpdate', (update) => { // console.log('on apiUpdate', update) - const update = e; switch(update._) { - case 'updateChannel': + case 'updateChannel': { const channelId = update.channel_id; //console.log('updateChannel:', update); - rootScope.broadcast('channel_settings', {channelId: channelId}); + rootScope.broadcast('channel_settings', {channelId}); break; + } + + case 'updateChatDefaultBannedRights': { + const chatId = -appPeersManager.getPeerId(update.peer); + const chat: Chat = this.getChat(chatId); + if(chat._ !== 'chatEmpty') { + (chat as Chat.chat).default_banned_rights = update.default_banned_rights; + rootScope.broadcast('chat_update', chatId); + } + + break; + } case 'updateUserTyping': case 'updateChatUserTyping': { @@ -171,7 +182,7 @@ export class AppChatsManager { return this.chats[id] || {_: 'chatEmpty', id, deleted: true, access_hash: '', pFlags: {}/* this.channelAccess[id] */}; } - public hasRights(id: number, action: ChatRights, flag?: keyof ChatBannedRights['pFlags']) { + public hasRights(id: number, action: ChatRights, userId?: number) { const chat: Chat = this.getChat(id); if(chat._ === 'chatEmpty') return false; @@ -182,11 +193,15 @@ export class AppChatsManager { return false; } - if(chat.pFlags.creator) { + if(userId !== undefined && appUsersManager.getSelf().id === userId) { + userId = undefined; + } + + if(chat.pFlags.creator && userId === undefined) { return true; } - const rights = chat.admin_rights || (chat as Chat.channel).banned_rights || chat.default_banned_rights; + const rights = (userId === undefined && (chat.admin_rights || (chat as Chat.channel).banned_rights)) || chat.default_banned_rights; if(!rights) { return false; } @@ -195,9 +210,15 @@ export class AppChatsManager { if(rights) myFlags = rights.pFlags as any; switch(action) { - // good - case 'send': { - if(flag && myFlags[flag]) { + case 'embed_links': + case 'send_games': + case 'send_gifs': + case 'send_inline': + case 'send_media': + case 'send_messages': + case 'send_polls': + case 'send_stickers': { + if(rights._ === 'chatBannedRights' && myFlags[action]) { return false; } @@ -211,7 +232,7 @@ export class AppChatsManager { } // * revoke foreign messages - case 'deleteRevoke': { + case 'delete_messages': { return !!myFlags.delete_messages; } @@ -219,6 +240,7 @@ export class AppChatsManager { return rights._ === 'chatAdminRights' ? myFlags[action] || !!myFlags.post_messages : !myFlags[action]; } + case 'invite_users': case 'change_info': { return rights._ === 'chatAdminRights' ? myFlags[action] : !myFlags[action]; } @@ -237,6 +259,20 @@ export class AppChatsManager { return true; } + public editChatDefaultBannedRights(id: number, banned_rights: ChatBannedRights) { + const chat: Chat.chat = this.getChat(id); + if(chat.default_banned_rights) { + if(chat.default_banned_rights.until_date === banned_rights.until_date && deepEqual(chat.default_banned_rights.pFlags, banned_rights.pFlags)) { + return Promise.resolve(); + } + } + + return apiManager.invokeApi('messages.editChatDefaultBannedRights', { + peer: appPeersManager.getInputPeerById(-id), + banned_rights + }).then(this.onChatUpdated.bind(this, id)); + } + /* public resolveUsername(username: string) { return this.usernames[username] || 0; } */ diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index fbfd5a94..779e2d3a 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -516,7 +516,7 @@ export class AppImManager { private canDrag() { const peerId = this.chat?.peerId; - return !(!peerId || rootScope.overlayIsActive || (peerId < 0 && !appChatsManager.hasRights(peerId, 'send', 'send_media'))); + return !(!peerId || rootScope.overlayIsActive || (peerId < 0 && !appChatsManager.hasRights(peerId, 'send_media'))); } private onDocumentPaste = (e: ClipboardEvent | DragEvent, attachType?: 'media' | 'document') => { diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index b92ae944..7c78b602 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -2816,7 +2816,7 @@ export class AppMessagesManager { message.peerId > 0 || message.fromId === rootScope.myId || appChatsManager.getChat(message.peerId)._ === 'chat' - || appChatsManager.hasRights(message.peerId, 'deleteRevoke') + || appChatsManager.hasRights(message.peerId, 'delete_messages') ); } @@ -4551,7 +4551,7 @@ export class AppMessagesManager { public canWriteToPeer(peerId: number) { if(peerId < 0) { const isChannel = appPeersManager.isChannel(peerId); - const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send'); + const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send_messages'); return !isChannel || hasRights; } else { return appUsersManager.canSendToUser(peerId); diff --git a/src/lib/appManagers/appPeersManager.ts b/src/lib/appManagers/appPeersManager.ts index f2772dd0..6db6f870 100644 --- a/src/lib/appManagers/appPeersManager.ts +++ b/src/lib/appManagers/appPeersManager.ts @@ -125,15 +125,15 @@ export class AppPeersManager { : appChatsManager.getChat(-peerId) } - public getPeerId(peerId: any/* Peer | number | string */): number { + public getPeerId(peerId: Peer | InputPeer | number | string): number { if(typeof(peerId) === 'number') return peerId; - else if(isObject(peerId)) return peerId.user_id ? peerId.user_id : -(peerId.channel_id || peerId.chat_id); + else if(isObject(peerId)) return (peerId as Peer.peerUser).user_id || -((peerId as Peer.peerChannel).channel_id || (peerId as Peer.peerChat).chat_id); else if(!peerId) return 0; - const isUser = peerId.charAt(0) === 'u'; - const peerParams = peerId.substr(1).split('_'); + const isUser = (peerId as string).charAt(0) === 'u'; + const peerParams = (peerId as string).substr(1).split('_'); - return isUser ? peerParams[0] : -peerParams[0] || 0; + return isUser ? +peerParams[0] : -peerParams[0] || 0; } public getDialogPeer(peerId: number): DialogPeer { diff --git a/src/scss/partials/_checkbox.scss b/src/scss/partials/_checkbox.scss index 00d0d5b4..40e3d84d 100644 --- a/src/scss/partials/_checkbox.scss +++ b/src/scss/partials/_checkbox.scss @@ -228,4 +228,43 @@ cursor: default; opacity: .25; } -} \ No newline at end of file +} + +.checkbox-field-restriction { + .checkbox-box { + &-border { + display: none; + } + + &-background { + transform: none !important; + transition: background-color .2s !important; + } + + &-check use { + visibility: visible !important; + stroke-dasharray: 24.19, 24.19 !important; + transform: rotate(0) translateY(0); + transition: stroke-dashoffset .2s ease-in-out, transform .2s ease-in-out !important; + } + } +} + +.checkbox-field-restriction [type="checkbox"] { + &:not(:checked) + .checkbox-box { + .checkbox-box-check { + use { + transform: rotate(45deg) translateY(-10px); + stroke-dashoffset: 35.5; + //stroke-dashoffset: -13; + + /* stroke-dashoffset: 24; + stroke-dasharray: 12.095, 24.19 !important; */ + } + } + + .checkbox-box-background { + background-color: $color-red; + } + } +} diff --git a/src/scss/partials/_leftSidebar.scss b/src/scss/partials/_leftSidebar.scss index 51fb5646..35466609 100644 --- a/src/scss/partials/_leftSidebar.scss +++ b/src/scss/partials/_leftSidebar.scss @@ -871,7 +871,7 @@ .checkbox-field { display: flex; align-items: center; - height: 54px; + height: 3.5rem; margin: 0 1.0625rem; padding: 0; }