Browse Source

Group default permissions

master
Eduard Kuzmenko 4 years ago
parent
commit
9b88c32db0
  1. 2
      src/components/appSelectPeers.ts
  2. 2
      src/components/chat/contextMenu.ts
  3. 12
      src/components/chat/input.ts
  4. 5
      src/components/checkboxField.ts
  5. 4
      src/components/emoticonsDropdown/index.ts
  6. 2
      src/components/popups/deleteMessages.ts
  7. 2
      src/components/popups/forward.ts
  8. 62
      src/components/sidebarRight/tabs/editGroup.ts
  9. 2
      src/components/sidebarRight/tabs/forward.ts
  10. 129
      src/components/sidebarRight/tabs/groupPermissions.ts
  11. 5
      src/components/sidebarRight/tabs/sharedMedia.ts
  12. 62
      src/lib/appManagers/appChatsManager.ts
  13. 2
      src/lib/appManagers/appImManager.ts
  14. 4
      src/lib/appManagers/appMessagesManager.ts
  15. 10
      src/lib/appManagers/appPeersManager.ts
  16. 39
      src/scss/partials/_checkbox.scss
  17. 2
      src/scss/partials/_leftSidebar.scss

2
src/components/appSelectPeers.ts

@ -217,7 +217,7 @@ export default class AppSelectPeers {
if(this.chatRightsAction) { if(this.chatRightsAction) {
dialogs = dialogs.filter(d => { 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);
}); });
} }

2
src/components/chat/contextMenu.ts

@ -178,7 +178,7 @@ export default class ChatContextMenu {
icon: 'reply', icon: 'reply',
text: 'Reply', text: 'Reply',
onClick: this.onReplyClick, 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.message.pFlags.is_outgoing &&
!!this.chat.input.messageInput && !!this.chat.input.messageInput &&
this.chat.type !== 'scheduled'/* , this.chat.type !== 'scheduled'/* ,

12
src/components/chat/input.ts

@ -273,7 +273,7 @@ export default class ChatInput {
this.willAttachType = 'media'; this.willAttachType = 'media';
this.fileInput.click(); 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', icon: 'document',
text: 'Document', text: 'Document',
@ -283,14 +283,14 @@ export default class ChatInput {
this.willAttachType = 'document'; this.willAttachType = 'document';
this.fileInput.click(); 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', icon: 'poll',
text: 'Poll', text: 'Poll',
onClick: () => { onClick: () => {
new PopupCreatePoll(this.chat).show(); 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); this.attachMenu = ButtonMenuToggle({noRipple: true, listenerSetter: this.listenerSetter}, 'top-left', this.attachMenuButtons);
@ -971,7 +971,7 @@ export default class ChatInput {
if(this.stickersHelper && if(this.stickersHelper &&
rootScope.settings.stickers.suggest && 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 = ''; let emoticon = '';
if(entities.length && entities[0]._ === 'messageEntityEmoji') { if(entities.length && entities[0]._ === 'messageEntityEmoji') {
const entity = entities[0]; const entity = entities[0];
@ -1076,7 +1076,7 @@ export default class ChatInput {
this.sendMessage(); this.sendMessage();
} }
} else { } 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); toast(POSTING_MEDIA_NOT_ALLOWED);
return; return;
} }
@ -1327,7 +1327,7 @@ export default class ChatInput {
document = this.appDocsManager.getDoc(document); document = this.appDocsManager.getDoc(document);
const flag = document.type === 'sticker' ? 'send_stickers' : (document.type === 'gif' ? 'send_gifs' : 'send_media'); 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); toast(POSTING_MEDIA_NOT_ALLOWED);
return; return;
} }

5
src/components/checkboxField.ts

@ -13,10 +13,15 @@ export default class CheckboxField {
stateKey?: string, stateKey?: string,
disabled?: boolean, disabled?: boolean,
checked?: boolean, checked?: boolean,
restriction?: boolean
} = {}) { } = {}) {
const label = this.label = document.createElement('label'); const label = this.label = document.createElement('label');
label.classList.add('checkbox-field'); label.classList.add('checkbox-field');
if(options.restriction) {
label.classList.add('checkbox-field-restriction');
}
if(options.round) { if(options.round) {
label.classList.add('checkbox-field-round'); label.classList.add('checkbox-field-round');
} }

4
src/components/emoticonsDropdown/index.ts

@ -199,10 +199,10 @@ export class EmoticonsDropdown {
const children = this.tabsEl.children; const children = this.tabsEl.children;
const tabsElements = Array.from(children) as HTMLElement[]; 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); 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); tabsElements[3].toggleAttribute('disabled', !canSendGifs);
const active = this.tabsEl.querySelector('.active'); const active = this.tabsEl.querySelector('.active');

2
src/components/popups/deleteMessages.ts

@ -46,7 +46,7 @@ export default class PopupDeleteMessages {
} else { } else {
const chat = appChatsManager.getChat(-peerId); const chat = appChatsManager.getChat(-peerId);
const hasRights = appChatsManager.hasRights(-peerId, 'deleteRevoke'); const hasRights = appChatsManager.hasRights(-peerId, 'delete_messages');
if(chat._ === 'chat') { if(chat._ === 'chat') {
const canRevoke = hasRights ? mids.slice() : mids.filter(mid => { const canRevoke = hasRights ? mids.slice() : mids.filter(mid => {
const message = appMessagesManager.getMessageByPeer(peerId, mid); const message = appMessagesManager.getMessageByPeer(peerId, mid);

2
src/components/popups/forward.ts

@ -18,7 +18,7 @@ export default class PopupForward extends PopupPickUser {
}, },
onClose, onClose,
placeholder: 'Forward to...', placeholder: 'Forward to...',
chatRightsAction: 'send' chatRightsAction: 'send_messages'
}); });
} }
} }

62
src/components/sidebarRight/tabs/editGroup.ts

@ -5,7 +5,7 @@ import { SettingSection } from "../../sidebarLeft";
import Row from "../../row"; import Row from "../../row";
import CheckboxField from "../../checkboxField"; import CheckboxField from "../../checkboxField";
import Button from "../../button"; import Button from "../../button";
import appChatsManager from "../../../lib/appManagers/appChatsManager"; import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager";
import appProfileManager from "../../../lib/appManagers/appProfileManager"; import appProfileManager from "../../../lib/appManagers/appProfileManager";
import { attachClickEvent, toggleDisability } from "../../../helpers/dom"; import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import { ChatFull } from "../../../layer"; import { ChatFull } from "../../../layer";
@ -13,12 +13,13 @@ import PopupPeer from "../../popups/peer";
import { addCancelButton } from "../../popups"; import { addCancelButton } from "../../popups";
import AppGroupTypeTab from "./groupType"; import AppGroupTypeTab from "./groupType";
import rootScope from "../../../lib/rootScope"; import rootScope from "../../../lib/rootScope";
import AppGroupPermissionsTab from "./groupPermissions";
export default class AppEditGroupTab extends SliderSuperTab { export default class AppEditGroupTab extends SliderSuperTab {
private groupNameInputField: InputField; private groupNameInputField: InputField;
private descriptionInputField: InputField; private descriptionInputField: InputField;
private editPeer: EditPeer; private editPeer: EditPeer;
public peerId: number; public chatId: number;
protected async _init() { protected async _init() {
// * cleanup prev // * cleanup prev
@ -28,7 +29,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
this.container.classList.add('edit-peer-container', 'edit-group-container'); this.container.classList.add('edit-peer-container', 'edit-group-container');
this.title.innerHTML = 'Edit'; 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}); const section = new SettingSection({noDelimiter: true});
@ -48,7 +49,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
maxLength: 255 maxLength: 255
}); });
const chat = appChatsManager.getChat(-this.peerId); const chat = appChatsManager.getChat(this.chatId);
this.groupNameInputField.setOriginalValue(chat.title); this.groupNameInputField.setOriginalValue(chat.title);
@ -59,7 +60,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
inputFields.push(this.groupNameInputField, this.descriptionInputField); inputFields.push(this.groupNameInputField, this.descriptionInputField);
this.editPeer = new EditPeer({ this.editPeer = new EditPeer({
peerId: this.peerId, peerId: -this.chatId,
inputFields, inputFields,
listenerSetter: this.listenerSetter listenerSetter: this.listenerSetter
}); });
@ -67,12 +68,12 @@ export default class AppEditGroupTab extends SliderSuperTab {
section.content.append(this.editPeer.avatarEdit.container, inputWrapper); 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({ const groupTypeRow = new Row({
title: 'Group Type', title: 'Group Type',
clickable: () => { clickable: () => {
const tab = new AppGroupTypeTab(this.slider); const tab = new AppGroupTypeTab(this.slider);
tab.peerId = this.peerId; tab.peerId = -this.chatId;
tab.chatFull = chatFull; tab.chatFull = chatFull;
tab.open(); tab.open();
@ -89,15 +90,40 @@ export default class AppEditGroupTab extends SliderSuperTab {
section.content.append(groupTypeRow.container); 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({ const permissionsRow = new Row({
title: 'Permissions', title: 'Permissions',
subtitle: '8/8', clickable: () => {
const tab = new AppGroupPermissionsTab(this.slider);
tab.chatId = this.chatId;
tab.open();
},
icon: 'permissions', 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); section.content.append(permissionsRow.container);
this.listenerSetter.add(rootScope, 'chat_update', (chatId) => {
if(this.chatId === chatId) {
setPermissionsLength();
}
});
} }
const administratorsRow = new Row({ const administratorsRow = new Row({
@ -116,7 +142,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
const id = -this.peerId; const id = this.chatId;
if(this.groupNameInputField.isValid()) { if(this.groupNameInputField.isValid()) {
promises.push(appChatsManager.editTitle(id, this.groupNameInputField.value)); promises.push(appChatsManager.editTitle(id, this.groupNameInputField.value));
} }
@ -152,12 +178,12 @@ export default class AppEditGroupTab extends SliderSuperTab {
section.content.append(membersRow.container); section.content.append(membersRow.container);
if(appChatsManager.hasRights(-this.peerId, 'change_permissions')) { if(appChatsManager.hasRights(this.chatId, 'change_permissions')) {
const showChatHistoryCheckboxField = new CheckboxField({ const showChatHistoryCheckboxField = new CheckboxField({
text: 'Show chat history for new members' 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; showChatHistoryCheckboxField.checked = true;
} }
@ -167,14 +193,14 @@ export default class AppEditGroupTab extends SliderSuperTab {
this.scrollable.append(section.container); 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 section = new SettingSection({});
const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'Delete Group'}); const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'Delete Group'});
attachClickEvent(btnDelete, () => { attachClickEvent(btnDelete, () => {
new PopupPeer('popup-delete-group', { new PopupPeer('popup-delete-group', {
peerId: this.peerId, peerId: -this.chatId,
title: 'Delete Group?', title: 'Delete Group?',
description: `Are you sure you want to delete this group? All members will be removed, and all messages will be lost.`, description: `Are you sure you want to delete this group? All members will be removed, and all messages will be lost.`,
buttons: addCancelButton([{ buttons: addCancelButton([{
@ -182,7 +208,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
callback: () => { callback: () => {
toggleDisability([btnDelete], true); toggleDisability([btnDelete], true);
appChatsManager.deleteChannel(-this.peerId).then(() => { appChatsManager.deleteChannel(this.chatId).then(() => {
this.close(); this.close();
}, () => { }, () => {
toggleDisability([btnDelete], false); 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 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}) => { this.listenerSetter.add(rootScope, 'dialog_migrate', ({migrateFrom, migrateTo}) => {
if(this.peerId === migrateFrom) { if(-this.chatId === migrateFrom) {
this.peerId = migrateTo; this.chatId = -migrateTo;
this._init(); this._init();
} }
}); });

2
src/components/sidebarRight/tabs/forward.ts

@ -89,7 +89,7 @@ export default class AppForwardTab implements SliderTab {
}); });
document.body.classList.add('is-forward-active'); document.body.classList.add('is-forward-active');
}, },
chatRightsAction: 'send' chatRightsAction: 'send_messages'
}); });
} }
} }

129
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);
}
}
}

5
src/components/sidebarRight/tabs/sharedMedia.ts

@ -143,7 +143,12 @@ export default class AppSharedMediaTab implements SliderTab {
} }
if(tab) { if(tab) {
if(tab instanceof AppEditGroupTab) {
tab.chatId = -this.peerId;
} else {
tab.peerId = this.peerId; tab.peerId = this.peerId;
}
tab.open(); tab.open();
} }
}); });

62
src/lib/appManagers/appChatsManager.ts

@ -1,6 +1,6 @@
import { MOUNT_CLASS_TO } from "../../config/debug"; import { MOUNT_CLASS_TO } from "../../config/debug";
import { numberThousandSplitter } from "../../helpers/number"; 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 { Chat, ChatAdminRights, ChatBannedRights, ChatFull, ChatParticipants, InputChannel, InputChatPhoto, InputFile, InputPeer, SendMessageAction, Update, Updates } from "../../layer";
import apiManager from '../mtproto/mtprotoworker'; import apiManager from '../mtproto/mtprotoworker';
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
@ -14,7 +14,7 @@ import appUsersManager from "./appUsersManager";
export type Channel = Chat.channel; 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}>; export type UserTyping = Partial<{userId: number, action: SendMessageAction, timeout: number}>;
@ -30,15 +30,26 @@ export class AppChatsManager {
public typingsInPeer: {[peerId: number]: UserTyping[]} = {}; public typingsInPeer: {[peerId: number]: UserTyping[]} = {};
constructor() { constructor() {
rootScope.on('apiUpdate', (e) => { rootScope.on('apiUpdate', (update) => {
// console.log('on apiUpdate', update) // console.log('on apiUpdate', update)
const update = e;
switch(update._) { switch(update._) {
case 'updateChannel': case 'updateChannel': {
const channelId = update.channel_id; const channelId = update.channel_id;
//console.log('updateChannel:', update); //console.log('updateChannel:', update);
rootScope.broadcast('channel_settings', {channelId: channelId}); rootScope.broadcast('channel_settings', {channelId});
break; 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 'updateUserTyping':
case 'updateChatUserTyping': { case 'updateChatUserTyping': {
@ -171,7 +182,7 @@ export class AppChatsManager {
return this.chats[id] || {_: 'chatEmpty', id, deleted: true, access_hash: '', pFlags: {}/* this.channelAccess[id] */}; 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); const chat: Chat = this.getChat(id);
if(chat._ === 'chatEmpty') return false; if(chat._ === 'chatEmpty') return false;
@ -182,11 +193,15 @@ export class AppChatsManager {
return false; return false;
} }
if(chat.pFlags.creator) { if(userId !== undefined && appUsersManager.getSelf().id === userId) {
userId = undefined;
}
if(chat.pFlags.creator && userId === undefined) {
return true; 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) { if(!rights) {
return false; return false;
} }
@ -195,9 +210,15 @@ export class AppChatsManager {
if(rights) myFlags = rights.pFlags as any; if(rights) myFlags = rights.pFlags as any;
switch(action) { switch(action) {
// good case 'embed_links':
case 'send': { case 'send_games':
if(flag && myFlags[flag]) { 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; return false;
} }
@ -211,7 +232,7 @@ export class AppChatsManager {
} }
// * revoke foreign messages // * revoke foreign messages
case 'deleteRevoke': { case 'delete_messages': {
return !!myFlags.delete_messages; return !!myFlags.delete_messages;
} }
@ -219,6 +240,7 @@ export class AppChatsManager {
return rights._ === 'chatAdminRights' ? myFlags[action] || !!myFlags.post_messages : !myFlags[action]; return rights._ === 'chatAdminRights' ? myFlags[action] || !!myFlags.post_messages : !myFlags[action];
} }
case 'invite_users':
case 'change_info': { case 'change_info': {
return rights._ === 'chatAdminRights' ? myFlags[action] : !myFlags[action]; return rights._ === 'chatAdminRights' ? myFlags[action] : !myFlags[action];
} }
@ -237,6 +259,20 @@ export class AppChatsManager {
return true; 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) { /* public resolveUsername(username: string) {
return this.usernames[username] || 0; return this.usernames[username] || 0;
} */ } */

2
src/lib/appManagers/appImManager.ts

@ -516,7 +516,7 @@ export class AppImManager {
private canDrag() { private canDrag() {
const peerId = this.chat?.peerId; 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') => { private onDocumentPaste = (e: ClipboardEvent | DragEvent, attachType?: 'media' | 'document') => {

4
src/lib/appManagers/appMessagesManager.ts

@ -2816,7 +2816,7 @@ export class AppMessagesManager {
message.peerId > 0 message.peerId > 0
|| message.fromId === rootScope.myId || message.fromId === rootScope.myId
|| appChatsManager.getChat(message.peerId)._ === 'chat' || 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) { public canWriteToPeer(peerId: number) {
if(peerId < 0) { if(peerId < 0) {
const isChannel = appPeersManager.isChannel(peerId); const isChannel = appPeersManager.isChannel(peerId);
const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send'); const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send_messages');
return !isChannel || hasRights; return !isChannel || hasRights;
} else { } else {
return appUsersManager.canSendToUser(peerId); return appUsersManager.canSendToUser(peerId);

10
src/lib/appManagers/appPeersManager.ts

@ -125,15 +125,15 @@ export class AppPeersManager {
: appChatsManager.getChat(-peerId) : 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; 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; else if(!peerId) return 0;
const isUser = peerId.charAt(0) === 'u'; const isUser = (peerId as string).charAt(0) === 'u';
const peerParams = peerId.substr(1).split('_'); 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 { public getDialogPeer(peerId: number): DialogPeer {

39
src/scss/partials/_checkbox.scss

@ -229,3 +229,42 @@
opacity: .25; opacity: .25;
} }
} }
.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;
}
}
}

2
src/scss/partials/_leftSidebar.scss

@ -871,7 +871,7 @@
.checkbox-field { .checkbox-field {
display: flex; display: flex;
align-items: center; align-items: center;
height: 54px; height: 3.5rem;
margin: 0 1.0625rem; margin: 0 1.0625rem;
padding: 0; padding: 0;
} }

Loading…
Cancel
Save