diff --git a/client/src/javascript/components/modals/settings-modal/SettingsModal.tsx b/client/src/javascript/components/modals/settings-modal/SettingsModal.tsx index 08ac7d60..d01e1b7f 100644 --- a/client/src/javascript/components/modals/settings-modal/SettingsModal.tsx +++ b/client/src/javascript/components/modals/settings-modal/SettingsModal.tsx @@ -1,5 +1,6 @@ -import {Component} from 'react'; -import {injectIntl, WrappedComponentProps} from 'react-intl'; +import {FC, useState} from 'react'; +import {useIntl} from 'react-intl'; +import {useMediaQuery} from '@react-hook/media-query'; import type {ClientSettings} from '@shared/types/ClientSettings'; import type {FloodSettings} from '@shared/types/FloodSettings'; @@ -17,165 +18,135 @@ import SettingActions from '../../../actions/SettingActions'; import UITab from './UITab'; import UIStore from '../../../stores/UIStore'; -import type {ModalAction} from '../../../stores/UIStore'; +const SettingsModal: FC = () => { + const intl = useIntl(); + const isSmallScreen = useMediaQuery('(max-width: 720px)'); -interface SettingsModalStates { - isSavingSettings: boolean; - changedClientSettings: Partial; - changedFloodSettings: Partial; -} + const [changedClientSettings, setChangedClientSettings] = useState>({}); + const [changedFloodSettings, setChangedFloodSettings] = useState>({}); + const [isSavingSettings, setSavingSettings] = useState(false); -class SettingsModal extends Component { - constructor(props: WrappedComponentProps) { - super(props); - - this.state = { - isSavingSettings: false, - changedClientSettings: {}, - changedFloodSettings: {}, - }; - } - - getActions(): Array { - return [ - { - clickHandler: null, - content: this.props.intl.formatMessage({ - id: 'button.cancel', - }), - triggerDismiss: true, - type: 'tertiary', - }, - { - clickHandler: this.handleSaveSettingsClick, - isLoading: this.state.isSavingSettings, - content: this.props.intl.formatMessage({ - id: 'button.save', - }), - triggerDismiss: false, - type: 'primary', - }, - ]; - } - - handleSaveSettingsClick = () => { - this.setState({isSavingSettings: true}, () => { - Promise.all([ - SettingActions.saveSettings(this.state.changedFloodSettings, { - alert: true, - }), - ClientActions.saveSettings(this.state.changedClientSettings, { - alert: true, - }), - ]).then(() => { - this.setState({isSavingSettings: false}); - UIStore.dismissModal(); - }); + const handleClientSettingsChange = (changedSettings: Partial) => { + setChangedClientSettings({ + ...changedClientSettings, + ...changedSettings, }); }; - handleFloodSettingsChange = (changedSettings: Partial) => { - this.setState((state) => { - const changedFloodSettings = { - ...state.changedFloodSettings, - ...changedSettings, - }; - - return {changedFloodSettings}; + const handleFloodSettingsChange = (changedSettings: Partial) => { + setChangedFloodSettings({ + ...changedFloodSettings, + ...changedSettings, }); }; - handleClientSettingsChange = (changedSettings: Partial) => { - this.setState((state) => { - const changedClientSettings = { - ...state.changedClientSettings, - ...changedSettings, - }; - - return {changedClientSettings}; - }); + const tabs = { + bandwidth: { + content: BandwidthTab, + props: { + onClientSettingsChange: handleClientSettingsChange, + onSettingsChange: handleFloodSettingsChange, + }, + label: intl.formatMessage({ + id: 'settings.tabs.bandwidth', + }), + }, + connectivity: { + content: ConnectivityTab, + props: { + onClientSettingsChange: handleClientSettingsChange, + }, + label: intl.formatMessage({ + id: 'settings.tabs.connectivity', + }), + }, + resources: { + content: ResourcesTab, + props: { + onClientSettingsChange: handleClientSettingsChange, + }, + label: intl.formatMessage({ + id: 'settings.tabs.resources', + }), + }, + ...(ConfigStore.authMethod !== 'none' + ? { + authentication: { + content: AuthTab, + label: intl.formatMessage({ + id: 'settings.tabs.authentication', + }), + }, + } + : {}), + ui: { + content: UITab, + label: intl.formatMessage({ + id: 'settings.tabs.userinterface', + }), + props: { + onSettingsChange: handleFloodSettingsChange, + }, + }, + diskusage: { + content: DiskUsageTab, + label: intl.formatMessage({ + id: 'settings.tabs.diskusage', + }), + props: { + onSettingsChange: handleFloodSettingsChange, + }, + }, + about: { + content: AboutTab, + label: intl.formatMessage({ + id: 'settings.tabs.about', + }), + }, }; - render() { - const {intl} = this.props; - - const tabs = { - bandwidth: { - content: BandwidthTab, - props: { - onClientSettingsChange: this.handleClientSettingsChange, - onSettingsChange: this.handleFloodSettingsChange, + return ( + { + setSavingSettings(true); + Promise.all([ + SettingActions.saveSettings(changedFloodSettings, { + alert: true, }), - }, - } - : {}), - ui: { - content: UITab, - label: intl.formatMessage({ - id: 'settings.tabs.userinterface', - }), - props: { - onSettingsChange: this.handleFloodSettingsChange, + ClientActions.saveSettings(changedClientSettings, { + alert: true, + }), + ]).then(() => { + setSavingSettings(false); + UIStore.dismissModal(); + }); + }, + isLoading: isSavingSettings, + content: intl.formatMessage({ + id: 'button.save', + }), + triggerDismiss: false, + type: 'primary', }, - }, - diskusage: { - content: DiskUsageTab, - label: intl.formatMessage({ - id: 'settings.tabs.diskusage', - }), - props: { - onSettingsChange: this.handleFloodSettingsChange, - }, - }, - about: { - content: AboutTab, - label: intl.formatMessage({ - id: 'settings.tabs.about', - }), - }, - }; + ]} + size="large" + heading={intl.formatMessage({ + id: 'settings.tabs.heading', + })} + orientation={isSmallScreen ? 'horizontal' : 'vertical'} + tabs={tabs} + /> + ); +}; - return ( - - ); - } -} - -export default injectIntl(SettingsModal); +export default SettingsModal; diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.tsx b/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.tsx index fa44af87..72a9e1fb 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.tsx +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.tsx @@ -1,4 +1,5 @@ import {useIntl} from 'react-intl'; +import {useMediaQuery} from '@react-hook/media-query'; import * as React from 'react'; import Modal from '../Modal'; @@ -11,6 +12,7 @@ import TorrentTrackers from './TorrentTrackers'; const TorrentDetailsModal: React.FC = () => { const intl = useIntl(); + const isSmallScreen = useMediaQuery('(max-width: 720px)'); const tabs = { 'torrent-details': { @@ -43,6 +45,7 @@ const TorrentDetailsModal: React.FC = () => { label: intl.formatMessage({ id: 'torrents.details.mediainfo', }), + modalContentClasses: 'modal__content--nested-scroll', }, }; @@ -51,8 +54,8 @@ const TorrentDetailsModal: React.FC = () => { heading={} size="large" tabs={tabs} - orientation={window.matchMedia('(max-width: 720px)').matches ? 'horizontal' : 'vertical'} - {...(window.matchMedia('(max-width: 720px)').matches ? [] : {tabsInBody: true})} + orientation={isSmallScreen ? 'horizontal' : 'vertical'} + tabsInBody={!isSmallScreen} /> ); }; diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.tsx b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.tsx index 1df6f7e0..9bee2b0e 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.tsx +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.tsx @@ -103,14 +103,6 @@ class TorrentMediainfo extends Component - - - ); - } - if (this.fetchMediainfoError) { return (
@@ -129,25 +121,31 @@ class TorrentMediainfo extends Component +
- + {this.isFetchingMediainfo ? ( + + ) : ( + + )}
- - - + {this.isFetchingMediainfo || ( + + + + )}
{this.mediainfo}
diff --git a/client/src/sass/components/_mediainfo.scss b/client/src/sass/components/_mediainfo.scss index 161263e3..90af8941 100644 --- a/client/src/sass/components/_mediainfo.scss +++ b/client/src/sass/components/_mediainfo.scss @@ -1,6 +1,7 @@ .mediainfo { display: flex; flex-direction: column; + overflow: auto; &__toolbar { display: flex; @@ -34,6 +35,6 @@ &__output { flex: 1 1 auto; - overflow: auto; + width: max-content; } }