Refactor `copyToClipboard`

This commit is contained in:
Piotr Rogowski 2022-07-18 20:43:01 +02:00
parent 96afc49da7
commit 31f146b650
No known key found for this signature in database
GPG Key ID: 4A842D702D9C6F8F
4 changed files with 28 additions and 27 deletions

View File

@ -4,7 +4,6 @@ import {
Input, Input,
Space, Space,
Table, Table,
Tooltip,
Typography, Typography,
} from 'antd'; } from 'antd';
import { ColumnsType } from 'antd/lib/table'; import { ColumnsType } from 'antd/lib/table';
@ -28,6 +27,10 @@ import { Routes } from '../routes';
import { buildFullUrl } from '../utils/url'; import { buildFullUrl } from '../utils/url';
import { aspirationMapper } from '../utils/tune/mappers'; import { aspirationMapper } from '../utils/tune/mappers';
import { TuneDbDocument } from '../types/dbData'; import { TuneDbDocument } from '../types/dbData';
import {
copyToClipboard,
isClipboardSupported,
} from '../utils/clipboard';
const { useBreakpoint } = Grid; const { useBreakpoint } = Grid;
@ -38,17 +41,8 @@ const Hub = () => {
const { searchTunes } = useDb(); const { searchTunes } = useDb();
const navigate = useNavigate(); const navigate = useNavigate();
const [dataSource, setDataSource] = useState<any>([]); const [dataSource, setDataSource] = useState<any>([]);
const [copied, setCopied] = useState(false);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const copyToClipboard = async (shareUrl: string) => {
if (navigator.clipboard) {
await navigator.clipboard.writeText(shareUrl);
setCopied(true);
setTimeout(() => setCopied(false), 1000);
}
};
const loadData = debounce(async (searchText?: string) => { const loadData = debounce(async (searchText?: string) => {
setIsLoading(true); setIsLoading(true);
const list = await searchTunes(searchText); const list = await searchTunes(searchText);
@ -153,9 +147,7 @@ const Hub = () => {
fixed: 'right', fixed: 'right',
render: (tuneId: string) => ( render: (tuneId: string) => (
<Space> <Space>
<Tooltip title={copied ? 'Copied!' : 'Copy URL'}> {isClipboardSupported && <Button icon={<CopyOutlined />} onClick={() => copyToClipboard(buildFullUrl([tunePath(tuneId)]))} />}
<Button icon={<CopyOutlined />} onClick={() => copyToClipboard(buildFullUrl([tunePath(tuneId)]))} />
</Tooltip>
<Button type="primary" icon={<ArrowRightOutlined />} onClick={() => navigate(tunePath(tuneId))} /> <Button type="primary" icon={<ArrowRightOutlined />} onClick={() => navigate(tunePath(tuneId))} />
</Space> </Space>
), ),

View File

@ -61,6 +61,7 @@ import {
TuneDbDocument, TuneDbDocument,
} from '../types/dbData'; } from '../types/dbData';
import { aspirationMapper } from '../utils/tune/mappers'; import { aspirationMapper } from '../utils/tune/mappers';
import { copyToClipboard } from '../utils/clipboard';
const { Item } = Form; const { Item } = Form;
@ -104,7 +105,6 @@ const UploadPage = () => {
const [tuneDocumentId, setTuneDocumentId] = useState<string>(); const [tuneDocumentId, setTuneDocumentId] = useState<string>();
const [isUserAuthorized, setIsUserAuthorized] = useState(false); const [isUserAuthorized, setIsUserAuthorized] = useState(false);
const [shareUrl, setShareUrl] = useState<string>(); const [shareUrl, setShareUrl] = useState<string>();
const [copied, setCopied] = useState(false);
const [isPublished, setIsPublished] = useState(false); const [isPublished, setIsPublished] = useState(false);
const [isEditMode, setIsEditMode] = useState(false); const [isEditMode, setIsEditMode] = useState(false);
const [readme, setReadme] = useState('# My Tune\n\ndescription'); const [readme, setReadme] = useState('# My Tune\n\ndescription');
@ -123,7 +123,7 @@ const UploadPage = () => {
const [toothLogFileIds, setToothLogFileIds] = useState<Map<string, string>>(new Map()); const [toothLogFileIds, setToothLogFileIds] = useState<Map<string, string>>(new Map());
const [customIniFileId, setCustomIniFileId] = useState<string | null>(null); const [customIniFileId, setCustomIniFileId] = useState<string | null>(null);
const hasNavigatorShare = navigator.share !== undefined; const shareSupported = 'share' in navigator;
const { currentUser } = useAuth(); const { currentUser } = useAuth();
const navigate = useNavigate(); const navigate = useNavigate();
const { removeFile, uploadFile, getFile } = useServerStorage(); const { removeFile, uploadFile, getFile } = useServerStorage();
@ -135,14 +135,6 @@ const UploadPage = () => {
tuneId: newTuneId!, tuneId: newTuneId!,
})); }));
const copyToClipboard = async () => {
if (navigator.clipboard) {
await navigator.clipboard.writeText(shareUrl!);
setCopied(true);
setTimeout(() => setCopied(false), 1000);
}
};
const genericError = (error: Error) => notification.error({ message: 'Error', description: error.message }); const genericError = (error: Error) => notification.error({ message: 'Error', description: error.message });
const publishTune = async (values: any) => { const publishTune = async (values: any) => {
@ -503,13 +495,13 @@ const UploadPage = () => {
<Divider>Publish & Share</Divider> <Divider>Publish & Share</Divider>
{isPublished && <Row> {isPublished && <Row>
<Input <Input
style={{ width: `calc(100% - ${hasNavigatorShare ? 65 : 35}px)` }} style={{ width: `calc(100% - ${shareSupported ? 65 : 35}px)` }}
value={shareUrl!} value={shareUrl!}
/> />
<Tooltip title={copied ? 'Copied!' : 'Copy URL'}> <Tooltip title="Copy URL">
<Button icon={<CopyOutlined />} onClick={copyToClipboard} /> <Button icon={<CopyOutlined />} onClick={() => copyToClipboard(shareUrl!)} />
</Tooltip> </Tooltip>
{hasNavigatorShare && ( {shareSupported && (
<Tooltip title="Share"> <Tooltip title="Share">
<Button <Button
icon={<ShareAltOutlined />} icon={<ShareAltOutlined />}

View File

@ -133,6 +133,11 @@ const databaseGenericError = (err: Error) => notification.error({
...baseOptions, ...baseOptions,
}); });
const copiedToClipboard = () => notification.success({
message: 'Copied to clipboard',
...baseOptions,
});
export { export {
emailNotVerified, emailNotVerified,
magicLinkSent, magicLinkSent,
@ -155,4 +160,5 @@ export {
passwordUpdateSuccess, passwordUpdateSuccess,
passwordUpdateFailed, passwordUpdateFailed,
databaseGenericError, databaseGenericError,
copiedToClipboard,
}; };

11
src/utils/clipboard.ts Normal file
View File

@ -0,0 +1,11 @@
import { copiedToClipboard } from '../pages/auth/notifications';
export const isClipboardSupported = 'clipboard' in navigator;
export const copyToClipboard = (text: string) => {
if (!isClipboardSupported) {
return;
}
navigator.clipboard.writeText(text).then(copiedToClipboard);
};