Restrict sending messages to left megagroup
This commit is contained in:
parent
06d92091f2
commit
094ec4c858
@ -133,7 +133,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
|
||||
buttonsDiv.classList.add(MEDIA_VIEWER_CLASSNAME + '-buttons');
|
||||
|
||||
topButtons.concat(['download', 'close']).forEach(name => {
|
||||
const button = ButtonIcon(name);
|
||||
const button = ButtonIcon(name, {noRipple: name === 'close' || undefined});
|
||||
this.buttons[name] = button;
|
||||
buttonsDiv.append(button);
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ import { AppChatsManager } from "../../lib/appManagers/appChatsManager";
|
||||
import ListenerSetter from "../../helpers/listenerSetter";
|
||||
import PollElement from "../poll";
|
||||
import AudioElement from "../audio";
|
||||
import { Message, MessageEntity, MessageReplyHeader } from "../../layer";
|
||||
import { Message, MessageEntity, MessageReplyHeader, Update } from "../../layer";
|
||||
import { REPLIES_PEER_ID } from "../../lib/mtproto/mtproto_config";
|
||||
import { FocusDirection } from "../../helpers/fastSmoothScroll";
|
||||
import useHeavyAnimationCheck, { getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation } from "../../hooks/useHeavyAnimationCheck";
|
||||
@ -408,7 +408,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
this.listenerSetter.add(this.bubblesContainer, 'dblclick', (e) => {
|
||||
if(this.chat.selection.isSelecting || !this.appMessagesManager.canWriteToPeer(this.peerId)) {
|
||||
if(this.chat.selection.isSelecting || !this.appMessagesManager.canWriteToPeer(this.peerId, this.chat.threadId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -502,6 +502,19 @@ export default class ChatBubbles {
|
||||
}
|
||||
});
|
||||
|
||||
this.listenerSetter.add(rootScope, 'chat_update', (e) => {
|
||||
const chatId: number = e;
|
||||
if(this.peerId === -chatId) {
|
||||
const hadRights = this.chatInner.classList.contains('has-rights');
|
||||
const hasRights = this.appMessagesManager.canWriteToPeer(this.peerId, this.chat.threadId);
|
||||
|
||||
if(hadRights !== hasRights) {
|
||||
this.finishPeerChange();
|
||||
this.chat.input.updateMessageInput();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.unreadedObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.isIntersecting) {
|
||||
@ -1748,7 +1761,7 @@ export default class ChatBubbles {
|
||||
public finishPeerChange() {
|
||||
const peerId = this.peerId;
|
||||
const isChannel = this.appPeersManager.isChannel(peerId);
|
||||
const canWrite = this.appMessagesManager.canWriteToPeer(peerId);
|
||||
const canWrite = this.appMessagesManager.canWriteToPeer(peerId, this.chat.threadId);
|
||||
|
||||
this.chatInner.classList.toggle('has-rights', canWrite);
|
||||
this.bubblesContainer.classList.toggle('is-chat-input-hidden', !canWrite);
|
||||
|
@ -35,9 +35,9 @@ export default class ChatContextMenu {
|
||||
private isTargetAGroupedItem: boolean;
|
||||
private isTextSelected: boolean;
|
||||
private isAnchorTarget: boolean;
|
||||
public peerId: number;
|
||||
public mid: number;
|
||||
public message: any;
|
||||
private peerId: number;
|
||||
private mid: number;
|
||||
private message: any;
|
||||
|
||||
constructor(private attachTo: HTMLElement, private chat: Chat, private appMessagesManager: AppMessagesManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appPollsManager: AppPollsManager) {
|
||||
const onContextMenu = (e: MouseEvent | Touch | TouchEvent) => {
|
||||
@ -190,7 +190,7 @@ export default class ChatContextMenu {
|
||||
icon: 'reply',
|
||||
text: 'Reply',
|
||||
onClick: this.onReplyClick,
|
||||
verify: () => this.appMessagesManager.canWriteToPeer(this.peerId) &&
|
||||
verify: () => this.appMessagesManager.canWriteToPeer(this.peerId, this.chat.threadId) &&
|
||||
!this.message.pFlags.is_outgoing &&
|
||||
!!this.chat.input.messageInput &&
|
||||
this.chat.type !== 'scheduled'/* ,
|
||||
|
@ -692,31 +692,7 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
if(this.messageInput) {
|
||||
const canWrite = this.appMessagesManager.canWriteToPeer(peerId);
|
||||
this.chatInput.classList.add('no-transition');
|
||||
this.chatInput.classList.toggle('is-hidden', !canWrite);
|
||||
void this.chatInput.offsetLeft; // reflow
|
||||
this.chatInput.classList.remove('no-transition');
|
||||
|
||||
const visible = this.attachMenuButtons.filter(button => {
|
||||
const good = button.verify(peerId);
|
||||
button.element.classList.toggle('hide', !good);
|
||||
return good;
|
||||
});
|
||||
|
||||
if(!canWrite) {
|
||||
this.messageInput.removeAttribute('contenteditable');
|
||||
} else {
|
||||
this.messageInput.setAttribute('contenteditable', 'true');
|
||||
this.setDraft(undefined, false);
|
||||
|
||||
if(!this.messageInput.innerHTML) {
|
||||
this.messageInputField.onFakeInput();
|
||||
}
|
||||
}
|
||||
|
||||
this.attachMenu.toggleAttribute('disabled', !visible.length);
|
||||
this.updateSendBtn();
|
||||
this.updateMessageInput();
|
||||
} else if(this.pinnedControlBtn) {
|
||||
if(this.appPeersManager.canPinMessage(this.chat.peerId)) {
|
||||
this.pinnedControlBtn.append(i18n('Chat.Input.UnpinAll'));
|
||||
@ -728,6 +704,34 @@ export default class ChatInput {
|
||||
}
|
||||
}
|
||||
|
||||
public updateMessageInput() {
|
||||
const canWrite = this.appMessagesManager.canWriteToPeer(this.chat.peerId, this.chat.threadId);
|
||||
this.chatInput.classList.add('no-transition');
|
||||
this.chatInput.classList.toggle('is-hidden', !canWrite);
|
||||
void this.chatInput.offsetLeft; // reflow
|
||||
this.chatInput.classList.remove('no-transition');
|
||||
|
||||
const visible = this.attachMenuButtons.filter(button => {
|
||||
const good = button.verify(this.chat.peerId);
|
||||
button.element.classList.toggle('hide', !good);
|
||||
return good;
|
||||
});
|
||||
|
||||
if(!canWrite) {
|
||||
this.messageInput.removeAttribute('contenteditable');
|
||||
} else {
|
||||
this.messageInput.setAttribute('contenteditable', 'true');
|
||||
this.setDraft(undefined, false);
|
||||
|
||||
if(!this.messageInput.innerHTML) {
|
||||
this.messageInputField.onFakeInput();
|
||||
}
|
||||
}
|
||||
|
||||
this.attachMenu.toggleAttribute('disabled', !visible.length);
|
||||
this.updateSendBtn();
|
||||
}
|
||||
|
||||
private attachMessageInputField() {
|
||||
const oldInputField = this.messageInputField;
|
||||
this.messageInputField = new InputField({
|
||||
|
@ -289,9 +289,9 @@ export default class ChatTopbar {
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
this.listenerSetter.add(rootScope, 'chat_update', (e) => {
|
||||
const peerId: number = e;
|
||||
if(this.peerId === -peerId) {
|
||||
const chat = this.appChatsManager.getChat(peerId) as Channel/* | Chat */;
|
||||
const chatId: number = e;
|
||||
if(this.peerId === -chatId) {
|
||||
const chat = this.appChatsManager.getChat(chatId) as Channel/* | Chat */;
|
||||
|
||||
this.btnJoin.classList.toggle('hide', !(chat as Channel)?.pFlags?.left);
|
||||
this.setUtilsWidth();
|
||||
|
@ -24,9 +24,13 @@ export default class PopupDeleteDialog {
|
||||
}; */
|
||||
|
||||
const callbackLeave = (checked: PopupPeerButtonCallbackCheckboxes) => {
|
||||
const promise = appChatsManager.leave(-peerId).then(() => {
|
||||
return appMessagesManager.flushHistory(-peerId);
|
||||
});
|
||||
let promise = appChatsManager.leave(-peerId);
|
||||
|
||||
if(checkboxes && checked[checkboxes[0].text]) {
|
||||
promise = promise.then(() => {
|
||||
return appMessagesManager.flushHistory(peerId);
|
||||
}) as any;
|
||||
}
|
||||
|
||||
onSelect && onSelect(promise);
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ const App = {
|
||||
id: 1025907,
|
||||
hash: '452b0359b988148995f22ff0f4229750',
|
||||
version: '0.5.3',
|
||||
langPackVersion: '0.1.6',
|
||||
langPackVersion: '0.1.7',
|
||||
langPack: 'macos',
|
||||
langPackCode: 'en',
|
||||
domains: [] as string[],
|
||||
|
@ -417,6 +417,7 @@ const lang = {
|
||||
"Online": "online",
|
||||
"MessageScheduleSend": "Send Now",
|
||||
"MessageScheduleEditTime": "Reschedule",
|
||||
"YouLeft": "You left this group",
|
||||
|
||||
// * macos
|
||||
"AccountSettings.Filters": "Chat Folders",
|
||||
|
@ -44,11 +44,11 @@ export class AppChatsManager {
|
||||
|
||||
constructor() {
|
||||
rootScope.addMultipleEventsListeners({
|
||||
updateChannel: (update) => {
|
||||
/* updateChannel: (update) => {
|
||||
const channelId = update.channel_id;
|
||||
//console.log('updateChannel:', update);
|
||||
rootScope.broadcast('channel_settings', {channelId});
|
||||
},
|
||||
}, */
|
||||
|
||||
updateChannelParticipant: (update) => {
|
||||
apiManagerProxy.clearCache('channels.getParticipants', (params) => {
|
||||
@ -268,7 +268,7 @@ export class AppChatsManager {
|
||||
return rights;
|
||||
}
|
||||
|
||||
public hasRights(id: number, action: ChatRights, rights?: ChatAdminRights | ChatBannedRights) {
|
||||
public hasRights(id: number, action: ChatRights, rights?: ChatAdminRights | ChatBannedRights, isThread?: boolean) {
|
||||
const chat: Chat = this.getChat(id);
|
||||
if(chat._ === 'chatEmpty') return false;
|
||||
|
||||
@ -285,14 +285,16 @@ export class AppChatsManager {
|
||||
|
||||
if(!rights) {
|
||||
rights = chat.admin_rights || (chat as Chat.channel).banned_rights || chat.default_banned_rights;
|
||||
}
|
||||
|
||||
if(!rights) {
|
||||
return false;
|
||||
|
||||
if(!rights) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let myFlags: Partial<{[flag in keyof ChatBannedRights['pFlags'] | keyof ChatAdminRights['pFlags']]: true}> = {};
|
||||
if(rights) myFlags = rights.pFlags as any;
|
||||
if(rights) {
|
||||
myFlags = rights.pFlags as any;
|
||||
}
|
||||
|
||||
switch(action) {
|
||||
case 'embed_links':
|
||||
@ -303,12 +305,16 @@ export class AppChatsManager {
|
||||
case 'send_messages':
|
||||
case 'send_polls':
|
||||
case 'send_stickers': {
|
||||
if(!isThread && chat.pFlags.left) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rights._ === 'chatBannedRights' && myFlags[action]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(chat._ === 'channel') {
|
||||
if((!chat.pFlags.megagroup && !myFlags.post_messages)) {
|
||||
if(!chat.pFlags.megagroup && !myFlags.post_messages) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -375,7 +381,6 @@ export class AppChatsManager {
|
||||
} */
|
||||
|
||||
public isChannel(id: number) {
|
||||
if(id < 0) id = -id;
|
||||
const chat = this.chats[id];
|
||||
return chat && (chat._ === 'channel' || chat._ === 'channelForbidden')/* || this.channelAccess[id] */;
|
||||
}
|
||||
@ -409,7 +414,6 @@ export class AppChatsManager {
|
||||
}
|
||||
|
||||
public getChannelInput(id: number): InputChannel {
|
||||
if(id < 0) id = -id;
|
||||
const chat: Chat = this.getChat(id);
|
||||
if(chat._ === 'chatEmpty' || !(chat as Chat.channel).access_hash) {
|
||||
return {
|
||||
|
@ -183,7 +183,7 @@ export class AppMessagesManager {
|
||||
}} = {};
|
||||
|
||||
private reloadConversationsPromise: Promise<void>;
|
||||
private reloadConversationsPeers: number[] = [];
|
||||
private reloadConversationsPeers: Set<number> = new Set();
|
||||
|
||||
public log = logger('MESSAGES', LogTypes.Error | LogTypes.Debug | LogTypes.Log | LogTypes.Warn);
|
||||
|
||||
@ -1883,8 +1883,8 @@ export class AppMessagesManager {
|
||||
|
||||
public reloadConversation(peerId: number | number[]) {
|
||||
[].concat(peerId).forEach(peerId => {
|
||||
if(!this.reloadConversationsPeers.includes(peerId)) {
|
||||
this.reloadConversationsPeers.push(peerId);
|
||||
if(!this.reloadConversationsPeers.has(peerId)) {
|
||||
this.reloadConversationsPeers.add(peerId);
|
||||
//this.log('will reloadConversation', peerId);
|
||||
}
|
||||
});
|
||||
@ -1892,8 +1892,8 @@ export class AppMessagesManager {
|
||||
if(this.reloadConversationsPromise) return this.reloadConversationsPromise;
|
||||
return this.reloadConversationsPromise = new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
const peers = this.reloadConversationsPeers.map(peerId => appPeersManager.getInputDialogPeerById(peerId));
|
||||
this.reloadConversationsPeers.length = 0;
|
||||
const peers = Array.from(this.reloadConversationsPeers).map(peerId => appPeersManager.getInputDialogPeerById(peerId));
|
||||
this.reloadConversationsPeers.clear();
|
||||
|
||||
apiManager.invokeApi('messages.getPeerDialogs', {peers}).then((result) => {
|
||||
this.dialogsStorage.applyDialogs(result);
|
||||
@ -1947,7 +1947,7 @@ export class AppMessagesManager {
|
||||
_: 'updateChannelAvailableMessages',
|
||||
channel_id: channelId,
|
||||
available_min_id: maxId
|
||||
}
|
||||
} as Update.updateChannelAvailableMessages
|
||||
});
|
||||
|
||||
return true;
|
||||
@ -2297,6 +2297,7 @@ export class AppMessagesManager {
|
||||
if(message.action) {
|
||||
let migrateFrom: number;
|
||||
let migrateTo: number;
|
||||
const suffix = message.fromId === appUsersManager.getSelf().id ? 'You' : '';
|
||||
switch(message.action._) {
|
||||
//case 'messageActionChannelEditPhoto':
|
||||
case 'messageActionChatEditPhoto':
|
||||
@ -2332,7 +2333,6 @@ export class AppMessagesManager {
|
||||
if(message.action.users.length === 1) {
|
||||
message.action.user_id = message.action.users[0];
|
||||
if(message.fromId === message.action.user_id) {
|
||||
let suffix = message.fromId === appUsersManager.getSelf().id ? 'You' : '';
|
||||
if(isChannel) {
|
||||
message.action._ = 'messageActionChatJoined' + suffix;
|
||||
} else {
|
||||
@ -2346,7 +2346,7 @@ export class AppMessagesManager {
|
||||
|
||||
case 'messageActionChatDeleteUser':
|
||||
if(message.fromId === message.action.user_id) {
|
||||
message.action._ = 'messageActionChatLeave';
|
||||
message.action._ = 'messageActionChatLeave' + suffix;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4029,19 +4029,19 @@ export class AppMessagesManager {
|
||||
private onUpdateChannel = (update: Update.updateChannel) => {
|
||||
const channelId: number = update.channel_id;
|
||||
const peerId = -channelId;
|
||||
const channel = appChatsManager.getChat(channelId);
|
||||
const channel: Chat.channel = appChatsManager.getChat(channelId);
|
||||
|
||||
const needDialog = channel._ === 'channel' && appChatsManager.isInChat(channelId);
|
||||
const dialog = this.getDialogOnly(peerId);
|
||||
|
||||
const canViewHistory = channel._ === 'channel' && (channel.username || !channel.pFlags.left && !channel.pFlags.kicked);
|
||||
const needDialog = appChatsManager.isInChat(channelId);
|
||||
|
||||
const canViewHistory = !!channel.username || !channel.pFlags.left;
|
||||
const hasHistory = this.historiesStorage[peerId] !== undefined;
|
||||
|
||||
|
||||
if(canViewHistory !== hasHistory) {
|
||||
delete this.historiesStorage[peerId];
|
||||
rootScope.broadcast('history_forbidden', peerId);
|
||||
}
|
||||
|
||||
|
||||
const dialog = this.getDialogOnly(peerId);
|
||||
if(!!dialog !== needDialog) {
|
||||
if(needDialog) {
|
||||
this.reloadConversation(-channelId);
|
||||
@ -4299,10 +4299,10 @@ export class AppMessagesManager {
|
||||
}, settings);
|
||||
}
|
||||
|
||||
public canWriteToPeer(peerId: number) {
|
||||
public canWriteToPeer(peerId: number, threadId?: number) {
|
||||
if(peerId < 0) {
|
||||
const isChannel = appPeersManager.isChannel(peerId);
|
||||
const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send_messages');
|
||||
const hasRights = isChannel && appChatsManager.hasRights(-peerId, 'send_messages', undefined, !!threadId);
|
||||
return !isChannel || hasRights;
|
||||
} else {
|
||||
return appUsersManager.canSendToUser(peerId);
|
||||
|
@ -369,7 +369,7 @@ export class AppStateManager extends EventListenerBase<{
|
||||
|
||||
public keepPeerSingle(peerId: number, type: string) {
|
||||
const existsPeerId = this.singlePeerMap.get(type);
|
||||
if(existsPeerId && existsPeerId !== peerId) {
|
||||
if(existsPeerId && existsPeerId !== peerId && this.neededPeers.has(existsPeerId)) {
|
||||
const set = this.neededPeers.get(existsPeerId);
|
||||
set.delete(type);
|
||||
|
||||
|
@ -28,6 +28,7 @@ export const langPack: {[actionType: string]: LangPackKey} = {
|
||||
"messageActionChatAddUser": "ActionAddUser",
|
||||
"messageActionChatAddUsers": "ActionAddUser",
|
||||
"messageActionChatLeave": "ActionLeftUser",
|
||||
"messageActionChatLeaveYou": "YouLeft",
|
||||
"messageActionChatDeleteUser": "ActionKickUser",
|
||||
"messageActionChatJoinedByLink": "ActionInviteUser",
|
||||
"messageActionPinMessage": "ActionPinnedNoText",
|
||||
|
@ -83,7 +83,7 @@ export type BroadcastEvents = {
|
||||
'chat_full_update': number,
|
||||
'poll_update': {poll: Poll, results: PollResults},
|
||||
'chat_update': number,
|
||||
'channel_settings': {channelId: number},
|
||||
//'channel_settings': {channelId: number},
|
||||
'webpage_updated': {id: string, msgs: number[]},
|
||||
|
||||
'download_progress': any,
|
||||
|
@ -11,13 +11,13 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 1rem;
|
||||
min-height: 56px;
|
||||
min-height: 3.5rem;
|
||||
flex: 0 0 auto;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding: 7.5px 8px;
|
||||
padding: 0 .5rem;
|
||||
}
|
||||
|
||||
/* //position: sticky !important;
|
||||
@ -28,8 +28,8 @@
|
||||
&__title {
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
padding-left: 24px;
|
||||
font-size: 20px;
|
||||
padding-left: 1.5rem;
|
||||
font-size: 1.25rem;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
@ -40,8 +40,8 @@
|
||||
|
||||
&-close-button {
|
||||
overflow: inherit !important;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
&-content {
|
||||
|
@ -14,7 +14,7 @@
|
||||
z-index: 3;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
margin: 0;
|
||||
padding: 2.5rem;
|
||||
padding: 1.875rem;
|
||||
box-shadow: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
@ -70,21 +70,9 @@
|
||||
}
|
||||
|
||||
&-close {
|
||||
cursor: pointer;
|
||||
color: var(--secondary-text-color);
|
||||
z-index: 3;
|
||||
text-align: center;
|
||||
justify-self: center;
|
||||
line-height: 1;
|
||||
//transition: color .2s;
|
||||
|
||||
body.animation-level-0 & {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/* @include hover() {
|
||||
color: #000;
|
||||
} */
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&-header {
|
||||
|
Loading…
x
Reference in New Issue
Block a user