diff --git a/ui/src/personal/HelpMsg.js b/ui/src/personal/HelpMsg.js new file mode 100644 index 000000000..d95eec1b6 --- /dev/null +++ b/ui/src/personal/HelpMsg.js @@ -0,0 +1,8 @@ +import HelpOutlineIcon from '@material-ui/icons/HelpOutline' + +export const HelpMsg = ({ caption }) => ( + <> + +    {caption} + +) diff --git a/ui/src/personal/NotificationsToggle.js b/ui/src/personal/NotificationsToggle.js new file mode 100644 index 000000000..f9b424fb7 --- /dev/null +++ b/ui/src/personal/NotificationsToggle.js @@ -0,0 +1,64 @@ +import { useNotify, useTranslate } from 'react-admin' +import { useDispatch, useSelector } from 'react-redux' +import { setNotificationsState } from '../actions' +import { + FormControl, + FormControlLabel, + FormHelperText, + Switch, +} from '@material-ui/core' + +export const NotificationsToggle = () => { + const translate = useTranslate() + const dispatch = useDispatch() + const notify = useNotify() + const currentSetting = useSelector((state) => state.settings.notifications) + const notAvailable = !('Notification' in window) || !window.isSecureContext + + if ( + (currentSetting && Notification.permission !== 'granted') || + notAvailable + ) { + dispatch(setNotificationsState(false)) + } + + const toggleNotifications = (event) => { + if (currentSetting && !event.target.checked) { + dispatch(setNotificationsState(false)) + } else { + if (Notification.permission === 'denied') { + notify(translate('message.notifications_blocked'), 'warning') + } else { + Notification.requestPermission().then((permission) => { + dispatch(setNotificationsState(permission === 'granted')) + }) + } + } + } + + return ( + + + } + label={ + + {translate('menu.personal.options.desktop_notifications')} + + } + /> + {notAvailable && ( + + {translate('message.notifications_not_available')} + + )} + + ) +} diff --git a/ui/src/personal/Personal.js b/ui/src/personal/Personal.js index 114cf49fb..1a1925886 100644 --- a/ui/src/personal/Personal.js +++ b/ui/src/personal/Personal.js @@ -1,196 +1,15 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { - Card, - FormControl, - FormHelperText, - FormControlLabel, - Switch, -} from '@material-ui/core' -import { - SelectInput, - SimpleForm, - Title, - useLocale, - useNotify, - useSetLocale, - useTranslate, -} from 'react-admin' +import { SimpleForm, Title, useTranslate } from 'react-admin' +import { Card } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' -import HelpOutlineIcon from '@material-ui/icons/HelpOutline' -import { changeTheme, setNotificationsState } from '../actions' -import themes from '../themes' -import { docsUrl } from '../utils' -import { useGetLanguageChoices } from '../i18n' -import albumLists, { defaultAlbumList } from '../album/albumLists' -import { AUTO_THEME_ID } from '../consts' +import { SelectLanguage } from './SelectLanguage' +import { SelectTheme } from './SelectTheme' +import { SelectDefaultView } from './SelectDefaultView' +import { NotificationsToggle } from './NotificationsToggle' const useStyles = makeStyles({ root: { marginTop: '1em' }, }) -const helpKey = '_help' - -function openInNewTab(url) { - const win = window.open(url, '_blank') - win.focus() -} - -const HelpMsg = ({ caption }) => ( - <> - -    {caption} - -) - -const SelectLanguage = (props) => { - const translate = useTranslate() - const setLocale = useSetLocale() - const locale = useLocale() - const { choices } = useGetLanguageChoices() - - choices.push({ - id: helpKey, - name: , - }) - - return ( - { - if (event.target.value === helpKey) { - openInNewTab(docsUrl('/docs/developers/translations/')) - return - } - setLocale(event.target.value).then(() => { - localStorage.setItem('locale', event.target.value) - }) - }} - /> - ) -} - -const SelectTheme = (props) => { - const translate = useTranslate() - const dispatch = useDispatch() - const currentTheme = useSelector((state) => state.theme) - const themeChoices = [ - { - id: AUTO_THEME_ID, - name: 'Auto', - }, - ] - themeChoices.push( - ...Object.keys(themes).map((key) => { - return { id: key, name: themes[key].themeName } - }) - ) - themeChoices.push({ - id: helpKey, - name: , - }) - return ( - { - if (event.target.value === helpKey) { - openInNewTab(docsUrl('/docs/developers/creating-themes/')) - return - } - dispatch(changeTheme(event.target.value)) - }} - /> - ) -} - -const SelectDefaultView = (props) => { - const translate = useTranslate() - const current = localStorage.getItem('defaultView') || defaultAlbumList - const choices = Object.keys(albumLists).map((type) => ({ - id: type, - name: translate(`resources.album.lists.${type}`), - })) - - return ( - { - localStorage.setItem('defaultView', event.target.value) - }} - /> - ) -} - -const NotificationsToggle = () => { - const translate = useTranslate() - const dispatch = useDispatch() - const notify = useNotify() - const currentSetting = useSelector((state) => state.settings.notifications) - const notAvailable = !('Notification' in window) || !window.isSecureContext - - if ( - (currentSetting && Notification.permission !== 'granted') || - notAvailable - ) { - dispatch(setNotificationsState(false)) - } - - const toggleNotifications = (event) => { - if (currentSetting && !event.target.checked) { - dispatch(setNotificationsState(false)) - } else { - if (Notification.permission === 'denied') { - notify(translate('message.notifications_blocked'), 'warning') - } else { - Notification.requestPermission().then((permission) => { - dispatch(setNotificationsState(permission === 'granted')) - }) - } - } - } - - return ( - - - } - label={ - - {translate('menu.personal.options.desktop_notifications')} - - } - /> - {notAvailable && ( - - {translate('message.notifications_not_available')} - - )} - - ) -} - const Personal = () => { const translate = useTranslate() const classes = useStyles() diff --git a/ui/src/personal/SelectDefaultView.js b/ui/src/personal/SelectDefaultView.js new file mode 100644 index 000000000..71c87305c --- /dev/null +++ b/ui/src/personal/SelectDefaultView.js @@ -0,0 +1,25 @@ +import { SelectInput, useTranslate } from 'react-admin' +import albumLists, { defaultAlbumList } from '../album/albumLists' + +export const SelectDefaultView = (props) => { + const translate = useTranslate() + const current = localStorage.getItem('defaultView') || defaultAlbumList + const choices = Object.keys(albumLists).map((type) => ({ + id: type, + name: translate(`resources.album.lists.${type}`), + })) + + return ( + { + localStorage.setItem('defaultView', event.target.value) + }} + /> + ) +} diff --git a/ui/src/personal/SelectLanguage.js b/ui/src/personal/SelectLanguage.js new file mode 100644 index 000000000..700d902e1 --- /dev/null +++ b/ui/src/personal/SelectLanguage.js @@ -0,0 +1,38 @@ +import { SelectInput, useLocale, useSetLocale, useTranslate } from 'react-admin' +import { useGetLanguageChoices } from '../i18n' +import { HelpMsg } from './HelpMsg' +import { docsUrl, openInNewTab } from '../utils' + +const helpKey = '_help' + +export const SelectLanguage = (props) => { + const translate = useTranslate() + const setLocale = useSetLocale() + const locale = useLocale() + const { choices } = useGetLanguageChoices() + + choices.push({ + id: helpKey, + name: , + }) + + return ( + { + if (event.target.value === helpKey) { + openInNewTab(docsUrl('/docs/developers/translations/')) + return + } + setLocale(event.target.value).then(() => { + localStorage.setItem('locale', event.target.value) + }) + }} + /> + ) +} diff --git a/ui/src/personal/SelectTheme.js b/ui/src/personal/SelectTheme.js new file mode 100644 index 000000000..e69d996ff --- /dev/null +++ b/ui/src/personal/SelectTheme.js @@ -0,0 +1,47 @@ +import { SelectInput, useTranslate } from 'react-admin' +import { useDispatch, useSelector } from 'react-redux' +import { AUTO_THEME_ID } from '../consts' +import themes from '../themes' +import { HelpMsg } from './HelpMsg' +import { docsUrl, openInNewTab } from '../utils' +import { changeTheme } from '../actions' + +const helpKey = '_help' + +export const SelectTheme = (props) => { + const translate = useTranslate() + const dispatch = useDispatch() + const currentTheme = useSelector((state) => state.theme) + const themeChoices = [ + { + id: AUTO_THEME_ID, + name: 'Auto', + }, + ] + themeChoices.push( + ...Object.keys(themes).map((key) => { + return { id: key, name: themes[key].themeName } + }) + ) + themeChoices.push({ + id: helpKey, + name: , + }) + return ( + { + if (event.target.value === helpKey) { + openInNewTab(docsUrl('/docs/developers/creating-themes/')) + return + } + dispatch(changeTheme(event.target.value)) + }} + /> + ) +} diff --git a/ui/src/utils/index.js b/ui/src/utils/index.js index a5248211a..da366f14e 100644 --- a/ui/src/utils/index.js +++ b/ui/src/utils/index.js @@ -2,3 +2,4 @@ export * from './baseUrl' export * from './docsUrl' export * from './formatters' export * from './notifications' +export * from './openInNewTab' diff --git a/ui/src/utils/openInNewTab.js b/ui/src/utils/openInNewTab.js new file mode 100644 index 000000000..b5ad35612 --- /dev/null +++ b/ui/src/utils/openInNewTab.js @@ -0,0 +1,4 @@ +export const openInNewTab = (url) => { + const win = window.open(url, '_blank') + win.focus() +}