Cloud Folders: Save folder info on link share or copy (#3316)

This commit is contained in:
Alexander Zinchuk 2023-07-05 13:13:41 +02:00
parent 56b37a0d2f
commit 4e43602146
2 changed files with 23 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import React, { memo, useCallback, useMemo } from '../../lib/teact/teact'; import React, { memo, useMemo } from '../../lib/teact/teact';
import { getActions } from '../../global'; import { getActions } from '../../global';
import type { FC } from '../../lib/teact/teact'; import type { FC } from '../../lib/teact/teact';
@ -7,6 +7,7 @@ import { copyTextToClipboard } from '../../util/clipboard';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useLastCallback from '../../hooks/useLastCallback';
import DropdownMenu from '../ui/DropdownMenu'; import DropdownMenu from '../ui/DropdownMenu';
import MenuItem from '../ui/MenuItem'; import MenuItem from '../ui/MenuItem';
@ -32,20 +33,21 @@ const InviteLink: FC<OwnProps> = ({
const { isMobile } = useAppLayout(); const { isMobile } = useAppLayout();
const copyLink = useCallback((link: string) => { const copyLink = useLastCallback((link: string) => {
copyTextToClipboard(link); copyTextToClipboard(link);
showNotification({ showNotification({
message: lang('LinkCopied'), message: lang('LinkCopied'),
}); });
}, [lang]); });
const handleCopyPrimaryClicked = useCallback(() => { const handleCopyPrimaryClicked = useLastCallback(() => {
if (isDisabled) return;
copyLink(inviteLink); copyLink(inviteLink);
}, [copyLink, inviteLink]); });
const handleShare = useCallback(() => { const handleShare = useLastCallback(() => {
openChatWithDraft({ text: inviteLink }); openChatWithDraft({ text: inviteLink });
}, [inviteLink]); });
const PrimaryLinkMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => { const PrimaryLinkMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => {
return ({ onTrigger, isOpen }) => ( return ({ onTrigger, isOpen }) => (
@ -80,7 +82,7 @@ const InviteLink: FC<OwnProps> = ({
trigger={PrimaryLinkMenuButton} trigger={PrimaryLinkMenuButton}
positionX="right" positionX="right"
> >
<MenuItem icon="copy" onClick={handleCopyPrimaryClicked}>{lang('Copy')}</MenuItem> <MenuItem icon="copy" onClick={handleCopyPrimaryClicked} disabled={isDisabled}>{lang('Copy')}</MenuItem>
{onRevoke && ( {onRevoke && (
<MenuItem icon="delete" onClick={onRevoke} destructive>{lang('RevokeButton')}</MenuItem> <MenuItem icon="delete" onClick={onRevoke} destructive>{lang('RevokeButton')}</MenuItem>
)} )}

View File

@ -1,5 +1,5 @@
import React, { import React, {
memo, useCallback, useEffect, useMemo, useRef, useState, memo, useEffect, useMemo, useRef, useState,
} from '../../../../lib/teact/teact'; } from '../../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../../global'; import { getActions, getGlobal, withGlobal } from '../../../../global';
@ -18,6 +18,7 @@ import { isChatChannel, isUserBot } from '../../../../global/helpers';
import useLang from '../../../../hooks/useLang'; import useLang from '../../../../hooks/useLang';
import useHistoryBack from '../../../../hooks/useHistoryBack'; import useHistoryBack from '../../../../hooks/useHistoryBack';
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
import useLastCallback from '../../../../hooks/useLastCallback';
import AnimatedIcon from '../../../common/AnimatedIcon'; import AnimatedIcon from '../../../common/AnimatedIcon';
import InviteLink from '../../../common/InviteLink'; import InviteLink from '../../../common/InviteLink';
@ -75,12 +76,12 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
} }
}, [folderId, isActive, url]); }, [folderId, isActive, url]);
const handleRevoke = useCallback(() => { const handleRevoke = useLastCallback(() => {
if (!url || !folderId) return; if (!url || !folderId) return;
deleteChatlistInvite({ folderId, url }); deleteChatlistInvite({ folderId, url });
onReset(); onReset();
}, [folderId, onReset, url]); });
const itemIds = useMemo(() => { const itemIds = useMemo(() => {
return (includedChatIds || []).concat(pinnedChatIds || []); return (includedChatIds || []).concat(pinnedChatIds || []);
@ -107,7 +108,7 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
} }
}, [url, unlockedIds, peerIds]); }, [url, unlockedIds, peerIds]);
const handleClickDisabled = useCallback((id: string) => { const handleClickDisabled = useLastCallback((id: string) => {
const global = getGlobal(); const global = getGlobal();
const user = selectUser(global, id); const user = selectUser(global, id);
const chat = selectChat(global, id); const chat = selectChat(global, id);
@ -128,17 +129,17 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
message: lang('FolderLinkScreen.AlertTextUnavailablePublicGroup'), message: lang('FolderLinkScreen.AlertTextUnavailablePublicGroup'),
}); });
} }
}, [lang]); });
const handleSelectedIdsChange = useCallback((ids: string[]) => { const handleSelectedIdsChange = useLastCallback((ids: string[]) => {
setSelectedIds(ids); setSelectedIds(ids);
setIsTouched(true); setIsTouched(true);
}, []); });
const handleSubmit = useCallback(() => { const handleSubmit = useLastCallback(() => {
if (!folderId || !url) return; if (!folderId || !url || !isTouched) return;
editChatlistInvite({ folderId, peerIds: selectedIds, url }); editChatlistInvite({ folderId, peerIds: selectedIds, url });
}, [folderId, selectedIds, url]); });
const chatsCount = selectedIds.length; const chatsCount = selectedIds.length;
const isDisabled = !chatsCount || isLoading; const isDisabled = !chatsCount || isLoading;
@ -159,9 +160,9 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
</div> </div>
<InviteLink <InviteLink
inviteLink={isLoading ? lang('Loading') : url!} inviteLink={!url ? lang('Loading') : url}
onRevoke={handleRevoke} onRevoke={handleRevoke}
isDisabled={isDisabled} isDisabled={!chatsCount || isTouched}
/> />
<div className="settings-item settings-item-chatlist"> <div className="settings-item settings-item-chatlist">