diff --git a/src/components/File.tsx b/src/components/File.tsx index f62c024..fb46fe6 100644 --- a/src/components/File.tsx +++ b/src/components/File.tsx @@ -106,11 +106,18 @@ export default function File({ const handleCopy = () => { clipboard.copy(`${window.location.protocol}//${window.location.host}${image.url}`); setOpen(false); - showNotification({ - title: 'Copied to clipboard', - message: '', - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: '', + icon: , + }); }; const handleFavorite = async () => { diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 38800c9..cde093d 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -4,8 +4,10 @@ import { Box, Burger, Button, + Group, Header, Image, + Input, MediaQuery, Menu, Navbar, @@ -214,13 +216,29 @@ export default function Layout({ children, props }) { labels: { confirm: 'Copy', cancel: 'Cancel' }, onConfirm: async () => { clipboard.copy(token); - - showNotification({ - title: 'Token Copied', - message: 'Your token has been copied to your clipboard.', - color: 'green', - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: ( + + Zipline is unable to copy to clipboard due to security reasons. However, you can still copy + the token manually. +
+ + Your token is: + e.target.select()} type='text' value={token} /> + +
+ ), + color: 'red', + }); + else + showNotification({ + title: 'Token Copied', + message: 'Your token has been copied to your clipboard.', + color: 'green', + icon: , + }); modals.closeAll(); }, diff --git a/src/components/pages/Dashboard/index.tsx b/src/components/pages/Dashboard/index.tsx index 998b5ee..166eac5 100644 --- a/src/components/pages/Dashboard/index.tsx +++ b/src/components/pages/Dashboard/index.tsx @@ -52,15 +52,22 @@ export default function Dashboard({ disableMediaPreview, exifEnabled }) { const copyImage = async ({ original }) => { clipboard.copy(`${window.location.protocol}//${window.location.host}${original.url}`); - showNotification({ - title: 'Copied to clipboard', - message: ( - {`${window.location.protocol}//${window.location.host}${original.url}`} - ), - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: ( + {`${window.location.protocol}//${window.location.host}${original.url}`} + ), + icon: , + }); }; const viewImage = async ({ original }) => { diff --git a/src/components/pages/Folders/index.tsx b/src/components/pages/Folders/index.tsx index 54b4c2a..0ca71d4 100644 --- a/src/components/pages/Folders/index.tsx +++ b/src/components/pages/Folders/index.tsx @@ -165,16 +165,23 @@ export default function Folders({ disableMediaPreview, exifEnabled }) { aria-label='copy link' onClick={() => { clipboard.copy(`${window.location.origin}/folder/${folder.id}`); - showNotification({ - title: 'Copied folder link', - message: ( - <> - Copied folder link to clipboard - - ), - color: 'green', - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied folder link', + message: ( + <> + Copied folder link to clipboard + + ), + color: 'green', + icon: , + }); }} > diff --git a/src/components/pages/Invites.tsx b/src/components/pages/Invites.tsx index ff3028e..c61bae1 100644 --- a/src/components/pages/Invites.tsx +++ b/src/components/pages/Invites.tsx @@ -158,11 +158,18 @@ export default function Invites() { const handleCopy = async (invite) => { clipboard.copy(`${window.location.protocol}//${window.location.host}/auth/register?code=${invite.code}`); - showNotification({ - title: 'Copied to clipboard', - message: '', - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: '', + icon: , + }); }; const updateInvites = async () => { diff --git a/src/components/pages/Manage/TotpModal.tsx b/src/components/pages/Manage/TotpModal.tsx index 5096a69..f4f44f0 100644 --- a/src/components/pages/Manage/TotpModal.tsx +++ b/src/components/pages/Manage/TotpModal.tsx @@ -1,5 +1,6 @@ import { Button, Center, Image, Modal, NumberInput, Text, Title } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; +import { useForm } from '@mantine/form'; import { CheckIcon, CrossIcon } from 'components/icons'; import useFetch from 'hooks/useFetch'; import { useEffect, useState } from 'react'; @@ -10,6 +11,7 @@ export function TotpModal({ opened, onClose, deleteTotp, setTotpEnabled }) { const [disabled, setDisabled] = useState(false); const [code, setCode] = useState(undefined); const [error, setError] = useState(''); + const form = useForm(); useEffect(() => { (async () => { @@ -114,28 +116,35 @@ export function TotpModal({ opened, onClose, deleteTotp, setTotpEnabled }) { )} - setCode(e)} - error={error} - /> - - + setCode(e)} + data-autofocus + error={error} + /> + + + ); } diff --git a/src/components/pages/MetadataView.tsx b/src/components/pages/MetadataView.tsx index af9f5b4..f64553e 100644 --- a/src/components/pages/MetadataView.tsx +++ b/src/components/pages/MetadataView.tsx @@ -27,11 +27,18 @@ export default function MetadataView({ fileId }) { const copy = (value) => { clipboard.copy(value); - showNotification({ - title: 'Copied to clipboard', - message: value, - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: value, + icon: , + }); }; const searchValue = (value) => { diff --git a/src/components/pages/Upload/File.tsx b/src/components/pages/Upload/File.tsx index d91f2d4..650cf0f 100644 --- a/src/components/pages/Upload/File.tsx +++ b/src/components/pages/Upload/File.tsx @@ -128,6 +128,12 @@ export default function File({ chunks: chunks_config }) { setTimeout(() => setProgress(0), 1000); clipboard.copy(json.files[0]); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); } ready = true; diff --git a/src/components/pages/Upload/showFilesModal.tsx b/src/components/pages/Upload/showFilesModal.tsx index dfc0261..17330a5 100644 --- a/src/components/pages/Upload/showFilesModal.tsx +++ b/src/components/pages/Upload/showFilesModal.tsx @@ -7,11 +7,18 @@ export default function showFilesModal(clipboard, modals, files: string[]) { const open = (idx: number) => window.open(files[idx], '_blank'); const copy = (idx: number) => { clipboard.copy(files[idx]); - showNotification({ - title: 'Copied to clipboard', - message: {files[idx]}, - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: {files[idx]}, + icon: , + }); }; modals.openModal({ diff --git a/src/components/pages/Urls/URLCard.tsx b/src/components/pages/Urls/URLCard.tsx index add8415..5668dbe 100644 --- a/src/components/pages/Urls/URLCard.tsx +++ b/src/components/pages/Urls/URLCard.tsx @@ -14,11 +14,18 @@ export default function URLCard({ url }: { url: URLResponse }) { const copyURL = (u) => { clipboard.copy(`${window.location.protocol}//${window.location.host}${u.url}`); - showNotification({ - title: 'Copied to clipboard', - message: '', - icon: , - }); + if (!navigator.clipboard) + showNotification({ + title: 'Unable to copy to clipboard', + message: 'Zipline is unable to copy to clipboard due to security reasons.', + color: 'red', + }); + else + showNotification({ + title: 'Copied to clipboard', + message: '', + icon: , + }); }; const deleteURL = async (u) => { diff --git a/src/pages/auth/login.tsx b/src/pages/auth/login.tsx index c82723e..890facd 100644 --- a/src/pages/auth/login.tsx +++ b/src/pages/auth/login.tsx @@ -98,28 +98,24 @@ export default function Login({ title, user_registration, oauth_registration, oa title={Two-Factor Authentication Required} size='lg' > - setCode(e)} - error={error} - /> +
onSubmit(form.values))}> + setCode(e)} + data-autofocus + error={error} + /> - + +