From acaf80d94e6bc89ec8842aaf1b0535226e832a1a Mon Sep 17 00:00:00 2001 From: Daniel Shleifman Date: Sun, 19 Jun 2022 19:14:36 +0300 Subject: [PATCH] pwa footer toggles modals --- web/src/components/About/index.jsx | 10 +++++--- web/src/components/Add/AddDialog.jsx | 14 ++++------- web/src/components/CloseServer.jsx | 11 +++++---- web/src/components/Donate/DonateDialog.jsx | 8 ++++--- .../components/Settings/SettingsDialog.jsx | 13 ++++------ web/src/components/TorrentCard/index.jsx | 3 +-- web/src/style/CustomMaterialUiStyles.js | 5 +++- .../utils/useOnStandaloneAppOutsideClick.jsx | 24 +++++++++++++++++++ 8 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 web/src/utils/useOnStandaloneAppOutsideClick.jsx diff --git a/web/src/components/About/index.jsx b/web/src/components/About/index.jsx index 3b309c2..4b8445c 100644 --- a/web/src/components/About/index.jsx +++ b/web/src/components/About/index.jsx @@ -9,6 +9,7 @@ import { useMediaQuery } from '@material-ui/core' import { echoHost } from 'utils/Hosts' import { StyledDialog, StyledMenuButtonWrapper } from 'style/CustomMaterialUiStyles' import { isStandaloneApp } from 'utils/Utils' +import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' import LinkComponent from './LinkComponent' import { DialogWrapper, HeaderSection, ThanksSection, Section, FooterSection } from './style' @@ -22,6 +23,9 @@ export default function AboutDialog() { axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data)) }, []) + const onClose = () => setOpen(false) + const ref = useOnStandaloneAppOutsideClick(onClose) + return ( <> setOpen(true)}> @@ -43,11 +47,11 @@ export default function AboutDialog() { setOpen(false)} + onClose={onClose} aria-labelledby='form-dialog-title' fullScreen={fullScreen} maxWidth='xl' - hideBackdrop={isStandaloneApp} + ref={ref} > @@ -83,7 +87,7 @@ export default function AboutDialog() { - diff --git a/web/src/components/Add/AddDialog.jsx b/web/src/components/Add/AddDialog.jsx index fd94446..2469e2b 100644 --- a/web/src/components/Add/AddDialog.jsx +++ b/web/src/components/Add/AddDialog.jsx @@ -9,10 +9,11 @@ import { useMediaQuery } from '@material-ui/core' import CircularProgress from '@material-ui/core/CircularProgress' import usePreviousState from 'utils/usePreviousState' import { useQuery } from 'react-query' -import { getTorrents, isStandaloneApp } from 'utils/Utils' +import { getTorrents } from 'utils/Utils' import parseTorrent from 'parse-torrent' import { ButtonWrapper } from 'style/DialogStyles' import { StyledDialog, StyledHeader } from 'style/CustomMaterialUiStyles' +import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' import { checkImageURL, getMoviePosters, checkTorrentSource, parseTorrentTitle } from './helpers' import { Content } from './style' @@ -46,6 +47,8 @@ export default function AddDialog({ const [isCustomTitleEnabled, setIsCustomTitleEnabled] = useState(false) const [currentSourceHash, setCurrentSourceHash] = useState() + const ref = useOnStandaloneAppOutsideClick(handleClose) + const { data: torrents } = useQuery('torrents', getTorrents, { retry: 1, refetchInterval: 1000 }) useEffect(() => { @@ -223,14 +226,7 @@ export default function AddDialog({ } return ( - + {t(isEditMode ? 'EditTorrent' : 'AddNewTorrent')} diff --git a/web/src/components/CloseServer.jsx b/web/src/components/CloseServer.jsx index 184e921..b9d5e55 100644 --- a/web/src/components/CloseServer.jsx +++ b/web/src/components/CloseServer.jsx @@ -1,10 +1,11 @@ import { useState } from 'react' -import { Button, Dialog, DialogActions, DialogTitle, ListItemIcon, ListItemText } from '@material-ui/core' +import { Button, DialogActions, DialogTitle, ListItemIcon, ListItemText } from '@material-ui/core' +import { StyledDialog, StyledMenuButtonWrapper } from 'style/CustomMaterialUiStyles' import { PowerSettingsNew as PowerSettingsNewIcon } from '@material-ui/icons' import { shutdownHost } from 'utils/Hosts' import { useTranslation } from 'react-i18next' import { isStandaloneApp } from 'utils/Utils' -import { StyledMenuButtonWrapper } from 'style/CustomMaterialUiStyles' +import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' export default function CloseServer({ isOffline, isLoading }) { const { t } = useTranslation() @@ -12,6 +13,8 @@ export default function CloseServer({ isOffline, isLoading }) { const closeDialog = () => setOpen(false) const openDialog = () => setOpen(true) + const ref = useOnStandaloneAppOutsideClick(closeDialog) + return ( <> @@ -31,7 +34,7 @@ export default function CloseServer({ isOffline, isLoading }) { )} - + {t('CloseServer?')} - + ) } diff --git a/web/src/components/Donate/DonateDialog.jsx b/web/src/components/Donate/DonateDialog.jsx index dba1c58..d362ae9 100644 --- a/web/src/components/Donate/DonateDialog.jsx +++ b/web/src/components/Donate/DonateDialog.jsx @@ -1,5 +1,4 @@ import ListItem from '@material-ui/core/ListItem' -import Dialog from '@material-ui/core/Dialog' import DialogTitle from '@material-ui/core/DialogTitle' import DialogContent from '@material-ui/core/DialogContent' import DialogActions from '@material-ui/core/DialogActions' @@ -7,15 +6,18 @@ import List from '@material-ui/core/List' import ButtonGroup from '@material-ui/core/ButtonGroup' import Button from '@material-ui/core/Button' import { useTranslation } from 'react-i18next' +import { StyledDialog } from 'style/CustomMaterialUiStyles' +import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' const donateFrame = '' export default function DonateDialog({ onClose }) { const { t } = useTranslation() + const ref = useOnStandaloneAppOutsideClick(onClose) return ( - + {t('Donate')} @@ -38,6 +40,6 @@ export default function DonateDialog({ onClose }) { Ok - + ) } diff --git a/web/src/components/Settings/SettingsDialog.jsx b/web/src/components/Settings/SettingsDialog.jsx index a8bd425..885e1e8 100644 --- a/web/src/components/Settings/SettingsDialog.jsx +++ b/web/src/components/Settings/SettingsDialog.jsx @@ -11,7 +11,7 @@ import Tab from '@material-ui/core/Tab' import SwipeableViews from 'react-swipeable-views' import CircularProgress from '@material-ui/core/CircularProgress' import { StyledDialog } from 'style/CustomMaterialUiStyles' -import { isStandaloneApp } from 'utils/Utils' +import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' import { SettingsHeader, FooterSection, Content } from './style' import defaultSettings from './defaultSettings' @@ -37,6 +37,8 @@ export default function SettingsDialog({ handleClose }) { }) }, []) + const ref = useOnStandaloneAppOutsideClick(handleClose) + const handleSave = () => { handleClose() const sets = JSON.parse(JSON.stringify(settings)) @@ -83,14 +85,7 @@ export default function SettingsDialog({ handleClose }) { const handleChangeIndex = index => setSelectedTab(index) return ( - +
{t('SettingsDialog.Settings')}
{ fullWidth maxWidth='xl' TransitionComponent={Transition} - hideBackdrop={isStandaloneApp} >
diff --git a/web/src/style/CustomMaterialUiStyles.js b/web/src/style/CustomMaterialUiStyles.js index 962c845..99f81a4 100644 --- a/web/src/style/CustomMaterialUiStyles.js +++ b/web/src/style/CustomMaterialUiStyles.js @@ -3,6 +3,7 @@ import Dialog from '@material-ui/core/Dialog' import { pwaFooterHeight } from 'components/App/PWAFooter/style' import styled from 'styled-components' import { Header } from 'style/DialogStyles' +import { isStandaloneApp } from 'utils/Utils' export const StyledMenuButtonWrapper = styled(ListItem).attrs({ button: true })` @media screen and (display-mode: standalone) { @@ -16,7 +17,9 @@ export const StyledMenuButtonWrapper = styled(ListItem).attrs({ button: true })` } ` -export const StyledDialog = styled(Dialog)` +export const StyledDialog = styled(Dialog).attrs({ + ...(isStandaloneApp && { hideBackdrop: true, transitionDuration: 0 }), +})` @media screen and (display-mode: standalone) { margin-bottom: ${pwaFooterHeight}px; diff --git a/web/src/utils/useOnStandaloneAppOutsideClick.jsx b/web/src/utils/useOnStandaloneAppOutsideClick.jsx new file mode 100644 index 0000000..a59ac43 --- /dev/null +++ b/web/src/utils/useOnStandaloneAppOutsideClick.jsx @@ -0,0 +1,24 @@ +import { useEffect, useRef } from 'react' +import { isStandaloneApp } from 'utils/Utils' + +export default function useOnStandaloneAppOutsideClick(onClickOutside) { + const ref = useRef() + + useEffect(() => { + if (!isStandaloneApp) return + + const handleClickOutside = event => { + if (ref.current && !ref.current.contains(event.target)) { + onClickOutside && onClickOutside() + } + } + + document.addEventListener('click', handleClickOutside, true) + + return () => { + document.removeEventListener('click', handleClickOutside, true) + } + }) + + return ref +}