diff --git a/src/api/gramjs/methods/index.ts b/src/api/gramjs/methods/index.ts index 8872b55d2..7c02799b9 100644 --- a/src/api/gramjs/methods/index.ts +++ b/src/api/gramjs/methods/index.ts @@ -49,7 +49,7 @@ export { } from './symbols'; export { - checkChatUsername, setChatUsername, updatePrivateLink, + checkChatUsername, setChatUsername, updatePrivateLink, deactivateAllUsernames, fetchExportedChatInvites, editExportedChatInvite, exportChatInvite, deleteExportedChatInvite, deleteRevokedExportedChatInvites, fetchChatInviteImporters, hideChatJoinRequest, hideAllChatJoinRequests, hideChatReportPanel, diff --git a/src/api/gramjs/methods/management.ts b/src/api/gramjs/methods/management.ts index 8de28bae3..39baeb1e4 100644 --- a/src/api/gramjs/methods/management.ts +++ b/src/api/gramjs/methods/management.ts @@ -3,7 +3,7 @@ import { Api as GramJs } from '../../../lib/gramjs'; import { invokeRequest } from './client'; import { buildInputEntity, buildInputPeer } from '../gramjsBuilders'; import type { - ApiChat, ApiError, ApiUser, OnApiUpdate, + ApiChat, ApiError, ApiUser, ApiUsername, OnApiUpdate, } from '../../types'; import { USERNAME_PURCHASE_ERROR } from '../../../config'; @@ -52,12 +52,11 @@ export async function setChatUsername( username, })); - const usernames = chat.usernames - ? chat.usernames - .map((u) => (u.isEditable ? { ...u, username } : u)) - // User can remove username from chat when changing it type to private, so we need to filter out empty usernames - .filter((u) => u.username) - : [{ username, isEditable: true, isActive: true }]; + let usernames: ApiUsername[] = username ? [{ username, isEditable: true, isActive: true }] : []; + if (chat.usernames) { + // User can remove username from chat when changing it type to private, so we need to filter out empty usernames + usernames = usernames.concat(chat.usernames.filter((u) => u.username && !u.isEditable)); + } if (result) { onUpdate({ @@ -70,6 +69,29 @@ export async function setChatUsername( return result; } +export async function deactivateAllUsernames({ chat }: { chat: ApiChat }) { + const result = await invokeRequest(new GramJs.channels.DeactivateAllUsernames({ + channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel, + })); + + if (result) { + const usernames = chat.usernames + ? chat.usernames + .map((u) => ({ ...u, isActive: false })) + // User can remove username from chat when changing it type to private, so we need to filter out empty usernames + .filter((u) => u.username) + : undefined; + + onUpdate({ + '@type': 'updateChat', + id: chat.id, + chat: { usernames }, + }); + } + + return result; +} + export async function updatePrivateLink({ chat, usageLimit, expireDate, }: { diff --git a/src/components/common/ManageUsernames.tsx b/src/components/common/ManageUsernames.tsx index 95470bd94..e61152a1f 100644 --- a/src/components/common/ManageUsernames.tsx +++ b/src/components/common/ManageUsernames.tsx @@ -87,16 +87,20 @@ const ManageUsernames: FC = ({ }, []); const handleUsernameToggle = useCallback(() => { + if (!usernameForConfirm) { + return; + } + if (chatId) { toggleChatUsername({ chatId, - username: usernameForConfirm!.username, - isActive: !usernameForConfirm!.isActive, + username: usernameForConfirm.username, + isActive: !usernameForConfirm.isActive, }); } else { toggleUsername({ - username: usernameForConfirm!.username, - isActive: !usernameForConfirm!.isActive, + username: usernameForConfirm.username, + isActive: !usernameForConfirm.isActive, }); } closeConfirmUsernameDialog(); diff --git a/src/components/right/RightColumn.tsx b/src/components/right/RightColumn.tsx index c25d596d6..d97317ffb 100644 --- a/src/components/right/RightColumn.tsx +++ b/src/components/right/RightColumn.tsx @@ -293,7 +293,7 @@ const RightColumn: FC = ({ case RightColumnContent.Management: return ( = ({ }, [isPublic, openUsernameLostDialog, privacyType, updatePublicLink, editableUsername]); const handleMakeChannelPrivateConfirm = useCallback(() => { - updatePublicLink({ username: '' }); + updatePublicLink({ username: '', shouldDisableUsernames: true }); closeUsernameLostDialog(); }, [closeUsernameLostDialog, updatePublicLink]); @@ -177,7 +177,7 @@ const ManageChatPrivacyType: FC = ({ }]; const isLoading = progress === ManagementProgress.InProgress; - const shouldRenderUsernamesManage = privacyType === 'public' && chat.usernames && chat.usernames.length > 1; + const shouldRenderUsernamesManage = privacyType === 'public' && chat.usernames && chat.usernames.length > 0; function renderPurchaseLink() { const purchaseInfoLink = `${TME_LINK_PREFIX}${PURCHASE_USERNAME}`; diff --git a/src/global/actions/api/management.ts b/src/global/actions/api/management.ts index 890256d9b..d9bd84816 100644 --- a/src/global/actions/api/management.ts +++ b/src/global/actions/api/management.ts @@ -53,7 +53,7 @@ addActionHandler('checkPublicLink', async (global, actions, payload): Promise => { - const { username, tabId = getCurrentTabId() } = payload; + const { username, shouldDisableUsernames, tabId = getCurrentTabId() } = payload; const { chatId } = selectCurrentMessageList(global, tabId) || {}; if (!chatId) { @@ -69,6 +69,9 @@ addActionHandler('updatePublicLink', async (global, actions, payload): Promise = Bool; channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool; +channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool; channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates; channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates; channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics; diff --git a/src/lib/gramjs/tl/static/api.json b/src/lib/gramjs/tl/static/api.json index bab7cd0a1..1d62e3251 100644 --- a/src/lib/gramjs/tl/static/api.json +++ b/src/lib/gramjs/tl/static/api.json @@ -273,6 +273,7 @@ "messages.readMentions", "messages.getUnreadMentions", "help.getPremiumPromo", + "channels.deactivateAllUsernames", "channels.toggleForum", "channels.createForumTopic", "channels.getForumTopics",