diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings
index 865740426..172201b03 100644
--- a/src/assets/localization/fallback.strings
+++ b/src/assets/localization/fallback.strings
@@ -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";
diff --git a/src/components/common/DeleteChatModal.tsx b/src/components/common/DeleteChatModal.tsx
index 08cdfee6a..89c3ec638 100644
--- a/src/components/common/DeleteChatModal.tsx
+++ b/src/components/common/DeleteChatModal.tsx
@@ -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();
}
diff --git a/src/components/modals/leaveGroup/LeaveGroupModal.tsx b/src/components/modals/leaveGroup/LeaveGroupModal.tsx
index 82c8aac1f..99e67697a 100644
--- a/src/components/modals/leaveGroup/LeaveGroupModal.tsx
+++ b/src/components/modals/leaveGroup/LeaveGroupModal.tsx
@@ -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 = ({
)}
{lang('LeaveGroupTitle', { group: chatTitle })}
- {lang('LeaveGroupDescription', {
+ {lang(isBasicGroup ? 'LeaveBasicGroupDescription' : 'LeaveGroupDescription', {
nextOwner: newOwnerName,
group: chatTitle,
}, {
diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts
index 1c97620be..5b1f0d4a6 100644
--- a/src/global/actions/api/chats.ts
+++ b/src/global/actions/api/chats.ts
@@ -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 {
+ 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 => {
const { chatId, shouldSkipOwnershipCheck, tabId = getCurrentTabId() } = payload;
const chat = selectChat(global, chatId);
@@ -895,35 +945,39 @@ addActionHandler('leaveChannel', async (global, actions, payload): Promise
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 => {
+ 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 => {
@@ -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;
}
diff --git a/src/global/types/actions.ts b/src/global/types/actions.ts
index fb8af6fd8..d2e2c76aa 100644
--- a/src/global/types/actions.ts
+++ b/src/global/types/actions.ts
@@ -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;
diff --git a/src/types/language.d.ts b/src/types/language.d.ts
index 6bad2cca3..83a2d6e3e 100644
--- a/src/types/language.d.ts
+++ b/src/types/language.d.ts
@@ -3493,6 +3493,10 @@ export interface LangPairWithVariables {
'nextOwner': V;
'group': V;
};
+ 'LeaveBasicGroupDescription': {
+ 'nextOwner': V;
+ 'group': V;
+ };
'LeaveGroupJoinedDate': {
'date': V;
};