Delete Chat Modal: Support safe leave basic group (#6759)
Co-authored-by: zubiden <19638254+zubiden@users.noreply.github.com>
This commit is contained in:
parent
ed638330d4
commit
aa44302ed4
@ -2679,6 +2679,7 @@
|
||||
"SettingsDataClearMediaDone" = "Media cache cleared";
|
||||
"LeaveGroupTitle" = "Leave {group}?";
|
||||
"LeaveGroupDescription" = "If you leave, **{nextOwner}** will become the new owner of **{group}** in 1 week.";
|
||||
"LeaveBasicGroupDescription" = "If you leave, **{nextOwner}** will immediately become the new owner of **{group}**.";
|
||||
"LeaveGroupAppointOwner" = "Appoint Another Owner";
|
||||
"LeaveGroupAdmins" = "GROUP ADMINS";
|
||||
"LeaveGroupMembers" = "GROUP MEMBERS";
|
||||
|
||||
@ -63,6 +63,7 @@ const DeleteChatModal = ({
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
leaveChannel,
|
||||
leaveBasicGroup,
|
||||
deleteHistory,
|
||||
deleteSavedHistory,
|
||||
deleteChannel,
|
||||
@ -114,8 +115,8 @@ const DeleteChatModal = ({
|
||||
leaveChannel({ chatId: chat.id });
|
||||
onClose();
|
||||
} else if (isBasicGroup && chat.isCreator) {
|
||||
deleteHistory({ chatId: chat.id, shouldDeleteForAll: false });
|
||||
deleteChatUser({ chatId: chat.id, userId: currentUserId! });
|
||||
leaveBasicGroup({ chatId: chat.id });
|
||||
onClose();
|
||||
} else {
|
||||
handleDeleteChat();
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { getActions, withGlobal } from '../../../global';
|
||||
import type { ApiChat, ApiChatFullInfo, ApiPeer } from '../../../api/types';
|
||||
import type { GlobalState, TabState } from '../../../global/types';
|
||||
|
||||
import { isChatBasicGroup } from '../../../global/helpers';
|
||||
import { getPeerTitle } from '../../../global/helpers/peers';
|
||||
import { selectChat, selectChatFullInfo, selectPeer } from '../../../global/selectors';
|
||||
|
||||
@ -46,7 +47,7 @@ const LeaveGroupModal = ({
|
||||
chatFullInfo,
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
closeLeaveGroupModal, leaveChannel, loadMoreMembers, loadFullChat,
|
||||
closeLeaveGroupModal, leaveChannel, leaveBasicGroup, loadMoreMembers, loadFullChat,
|
||||
transferChatOwnership, verifyTransferOwnership, openTwoFaCheckModal,
|
||||
} = getActions();
|
||||
const lang = useLang();
|
||||
@ -58,6 +59,7 @@ const LeaveGroupModal = ({
|
||||
|
||||
const isOpen = Boolean(modal);
|
||||
const renderingChat = useCurrentOrPrev(chat);
|
||||
const isBasicGroup = renderingChat && isChatBasicGroup(renderingChat);
|
||||
const renderingCurrentUser = useCurrentOrPrev(currentUser);
|
||||
|
||||
useEffect(() => {
|
||||
@ -171,15 +173,17 @@ const LeaveGroupModal = ({
|
||||
const chatId = modal?.chatId;
|
||||
if (!chatId) return;
|
||||
|
||||
const leaveAction = isBasicGroup ? leaveBasicGroup : leaveChannel;
|
||||
|
||||
if (isOwnerChanged && newOwnerId) {
|
||||
transferChatOwnership({
|
||||
chatId,
|
||||
userId: newOwnerId,
|
||||
password,
|
||||
onSuccess: () => leaveChannel({ chatId, shouldSkipOwnershipCheck: true }),
|
||||
onSuccess: () => leaveAction({ chatId, shouldSkipOwnershipCheck: true }),
|
||||
});
|
||||
} else {
|
||||
leaveChannel({ chatId, shouldSkipOwnershipCheck: true });
|
||||
leaveAction({ chatId, shouldSkipOwnershipCheck: true });
|
||||
}
|
||||
closeLeaveGroupModal();
|
||||
});
|
||||
@ -220,7 +224,7 @@ const LeaveGroupModal = ({
|
||||
)}
|
||||
<h3>{lang('LeaveGroupTitle', { group: chatTitle })}</h3>
|
||||
<p>
|
||||
{lang('LeaveGroupDescription', {
|
||||
{lang(isBasicGroup ? 'LeaveBasicGroupDescription' : 'LeaveGroupDescription', {
|
||||
nextOwner: newOwnerName,
|
||||
group: chatTitle,
|
||||
}, {
|
||||
|
||||
@ -57,7 +57,7 @@ import {
|
||||
isUserBot,
|
||||
} from '../../helpers';
|
||||
import {
|
||||
addActionHandler, getGlobal, setGlobal,
|
||||
addActionHandler, getActions, getGlobal, setGlobal,
|
||||
} from '../../index';
|
||||
import {
|
||||
addChatListIds,
|
||||
@ -888,6 +888,56 @@ addActionHandler('deleteChat', (global, actions, payload): ActionReturnType => {
|
||||
void callApi('deleteChat', { chatId: chat.id });
|
||||
});
|
||||
|
||||
async function checkFutureCreatorAndOpenModal(
|
||||
chat: ApiChat,
|
||||
shouldSkipOwnershipCheck: boolean | undefined,
|
||||
tabId: number,
|
||||
): Promise<boolean> {
|
||||
if (shouldSkipOwnershipCheck || !chat.isCreator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const futureCreator = await callApi('fetchFutureCreatorAfterLeave', { chat });
|
||||
if (!futureCreator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const global = getGlobal();
|
||||
const hasPassword = global.settings.byKey.hasPassword;
|
||||
const actions = getActions();
|
||||
if (!hasPassword) {
|
||||
actions.openTwoFaCheckModal({ tabId });
|
||||
return true;
|
||||
}
|
||||
|
||||
actions.openLeaveGroupModal({ chatId: chat.id, nextOwnerId: futureCreator.id, tabId });
|
||||
return true;
|
||||
}
|
||||
|
||||
function cleanupAfterLeave(chatId: string, tabId: number) {
|
||||
let global = getGlobal();
|
||||
global = leaveChat(global, chatId);
|
||||
setGlobal(global);
|
||||
|
||||
if (selectCurrentMessageList(global, tabId)?.chatId === chatId) {
|
||||
getActions().openChat({ id: undefined, tabId });
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
const chatMessages = selectChatMessages(global, chatId);
|
||||
if (!chatMessages) {
|
||||
return;
|
||||
}
|
||||
|
||||
const localMessageIds = Object.keys(chatMessages).map(Number).filter(isLocalMessageId);
|
||||
if (!localMessageIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = deleteChatMessages(global, chatId, localMessageIds);
|
||||
setGlobal(global);
|
||||
}
|
||||
|
||||
addActionHandler('leaveChannel', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId, shouldSkipOwnershipCheck, tabId = getCurrentTabId() } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
@ -895,35 +945,39 @@ addActionHandler('leaveChannel', async (global, actions, payload): Promise<void>
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shouldSkipOwnershipCheck && chat.isCreator) {
|
||||
const futureCreator = await callApi('fetchFutureCreatorAfterLeave', { chat });
|
||||
if (futureCreator) {
|
||||
global = getGlobal();
|
||||
const hasPassword = global.settings.byKey.hasPassword;
|
||||
if (!hasPassword) {
|
||||
actions.openTwoFaCheckModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
actions.openLeaveGroupModal({ chatId, nextOwnerId: futureCreator.id, tabId });
|
||||
return;
|
||||
}
|
||||
const isModalOpen = await checkFutureCreatorAndOpenModal(chat, shouldSkipOwnershipCheck, tabId);
|
||||
if (isModalOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = leaveChat(global, chatId);
|
||||
setGlobal(global);
|
||||
|
||||
if (selectCurrentMessageList(global, tabId)?.chatId === chatId) {
|
||||
actions.openChat({ id: undefined, tabId });
|
||||
}
|
||||
|
||||
await callApi('leaveChannel', { chat });
|
||||
|
||||
cleanupAfterLeave(chatId, tabId);
|
||||
});
|
||||
|
||||
addActionHandler('leaveBasicGroup', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId, shouldSkipOwnershipCheck, tabId = getCurrentTabId() } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
const currentUserId = global.currentUserId;
|
||||
if (!chat || !currentUserId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isModalOpen = await checkFutureCreatorAndOpenModal(chat, shouldSkipOwnershipCheck, tabId);
|
||||
if (isModalOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
actions.deleteHistory({ chatId, shouldDeleteForAll: false, tabId });
|
||||
|
||||
global = getGlobal();
|
||||
const chatMessages = selectChatMessages(global, chatId);
|
||||
const localMessageIds = Object.keys(chatMessages).map(Number).filter(isLocalMessageId);
|
||||
global = deleteChatMessages(global, chatId, localMessageIds);
|
||||
setGlobal(global);
|
||||
const user = selectUser(global, currentUserId);
|
||||
if (user) {
|
||||
await callApi('deleteChatUser', { chat, user, shouldRevokeHistory: false });
|
||||
}
|
||||
|
||||
cleanupAfterLeave(chatId, tabId);
|
||||
});
|
||||
|
||||
addActionHandler('verifyTransferOwnership', async (global, actions, payload): Promise<void> => {
|
||||
@ -973,8 +1027,7 @@ addActionHandler('transferChatOwnership', async (global, actions, payload): Prom
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
const user = selectUser(global, userId);
|
||||
|
||||
if (!chat || !user) {
|
||||
if (!chat || !user?.accessHash) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -405,6 +405,10 @@ export interface ActionPayloads {
|
||||
chatId: string;
|
||||
shouldSkipOwnershipCheck?: boolean;
|
||||
} & WithTabId;
|
||||
leaveBasicGroup: {
|
||||
chatId: string;
|
||||
shouldSkipOwnershipCheck?: boolean;
|
||||
} & WithTabId;
|
||||
deleteChannel: { chatId: string } & WithTabId;
|
||||
toggleChatPinned: {
|
||||
id: string;
|
||||
|
||||
4
src/types/language.d.ts
vendored
4
src/types/language.d.ts
vendored
@ -3493,6 +3493,10 @@ export interface LangPairWithVariables<V = LangVariable> {
|
||||
'nextOwner': V;
|
||||
'group': V;
|
||||
};
|
||||
'LeaveBasicGroupDescription': {
|
||||
'nextOwner': V;
|
||||
'group': V;
|
||||
};
|
||||
'LeaveGroupJoinedDate': {
|
||||
'date': V;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user