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