mirror of
https://github.com/zoriya/flood.git
synced 2026-06-04 03:27:15 +00:00
TorrentMediainfo: allow horizontal scrolling
This commit is contained in:
@@ -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<ClientSettings>;
|
||||
changedFloodSettings: Partial<FloodSettings>;
|
||||
}
|
||||
const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});
|
||||
const [changedFloodSettings, setChangedFloodSettings] = useState<Partial<FloodSettings>>({});
|
||||
const [isSavingSettings, setSavingSettings] = useState<boolean>(false);
|
||||
|
||||
class SettingsModal extends Component<WrappedComponentProps, SettingsModalStates> {
|
||||
constructor(props: WrappedComponentProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isSavingSettings: false,
|
||||
changedClientSettings: {},
|
||||
changedFloodSettings: {},
|
||||
};
|
||||
}
|
||||
|
||||
getActions(): Array<ModalAction> {
|
||||
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<ClientSettings>) => {
|
||||
setChangedClientSettings({
|
||||
...changedClientSettings,
|
||||
...changedSettings,
|
||||
});
|
||||
};
|
||||
|
||||
handleFloodSettingsChange = (changedSettings: Partial<FloodSettings>) => {
|
||||
this.setState((state) => {
|
||||
const changedFloodSettings = {
|
||||
...state.changedFloodSettings,
|
||||
...changedSettings,
|
||||
};
|
||||
|
||||
return {changedFloodSettings};
|
||||
const handleFloodSettingsChange = (changedSettings: Partial<FloodSettings>) => {
|
||||
setChangedFloodSettings({
|
||||
...changedFloodSettings,
|
||||
...changedSettings,
|
||||
});
|
||||
};
|
||||
|
||||
handleClientSettingsChange = (changedSettings: Partial<ClientSettings>) => {
|
||||
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 (
|
||||
<Modal
|
||||
actions={[
|
||||
{
|
||||
clickHandler: null,
|
||||
content: intl.formatMessage({
|
||||
id: 'button.cancel',
|
||||
}),
|
||||
triggerDismiss: true,
|
||||
type: 'tertiary',
|
||||
},
|
||||
label: intl.formatMessage({
|
||||
id: 'settings.tabs.bandwidth',
|
||||
}),
|
||||
},
|
||||
connectivity: {
|
||||
content: ConnectivityTab,
|
||||
props: {
|
||||
onClientSettingsChange: this.handleClientSettingsChange,
|
||||
},
|
||||
label: intl.formatMessage({
|
||||
id: 'settings.tabs.connectivity',
|
||||
}),
|
||||
},
|
||||
resources: {
|
||||
content: ResourcesTab,
|
||||
props: {
|
||||
onClientSettingsChange: this.handleClientSettingsChange,
|
||||
},
|
||||
label: intl.formatMessage({
|
||||
id: 'settings.tabs.resources',
|
||||
}),
|
||||
},
|
||||
...(ConfigStore.authMethod !== 'none'
|
||||
? {
|
||||
authentication: {
|
||||
content: AuthTab,
|
||||
label: intl.formatMessage({
|
||||
id: 'settings.tabs.authentication',
|
||||
{
|
||||
clickHandler: () => {
|
||||
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 (
|
||||
<Modal
|
||||
actions={this.getActions()}
|
||||
size="large"
|
||||
heading={this.props.intl.formatMessage({
|
||||
id: 'settings.tabs.heading',
|
||||
})}
|
||||
orientation={window.matchMedia('(max-width: 720px)').matches ? 'horizontal' : 'vertical'}
|
||||
tabs={tabs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(SettingsModal);
|
||||
export default SettingsModal;
|
||||
|
||||
+5
-2
@@ -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={<TorrentHeading key="torrent-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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+20
-22
@@ -103,14 +103,6 @@ class TorrentMediainfo extends Component<WrappedComponentProps, TorrentMediainfo
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.isFetchingMediainfo) {
|
||||
return (
|
||||
<div className="torrent-details__section mediainfo">
|
||||
<FormattedMessage id={MESSAGES.fetching.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.fetchMediainfoError) {
|
||||
return (
|
||||
<div className="torrent-details__section mediainfo">
|
||||
@@ -129,25 +121,31 @@ class TorrentMediainfo extends Component<WrappedComponentProps, TorrentMediainfo
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="torrent-details__section mediainfo">
|
||||
<div className="torrent-details__section mediainfo modal__content--nested-scroll__content">
|
||||
<div className="mediainfo__toolbar">
|
||||
<div className="mediainfo__toolbar__item">
|
||||
<span className="torrent-details__table__heading--tertiary">
|
||||
<FormattedMessage id={MESSAGES.heading.id} />
|
||||
{this.isFetchingMediainfo ? (
|
||||
<FormattedMessage id={MESSAGES.fetching.id} />
|
||||
) : (
|
||||
<FormattedMessage id={MESSAGES.heading.id} />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<Tooltip
|
||||
content={tooltipText}
|
||||
onMouseLeave={this.handleCopyButtonMouseLeave}
|
||||
wrapperClassName="tooltip__wrapper mediainfo__toolbar__item">
|
||||
<Button
|
||||
priority="tertiary"
|
||||
buttonRef={(ref) => {
|
||||
this.copyButtonRef = ref;
|
||||
}}>
|
||||
<ClipboardIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{this.isFetchingMediainfo || (
|
||||
<Tooltip
|
||||
content={tooltipText}
|
||||
onMouseLeave={this.handleCopyButtonMouseLeave}
|
||||
wrapperClassName="tooltip__wrapper mediainfo__toolbar__item">
|
||||
<Button
|
||||
priority="tertiary"
|
||||
buttonRef={(ref) => {
|
||||
this.copyButtonRef = ref;
|
||||
}}>
|
||||
<ClipboardIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
<pre className="mediainfo__output">{this.mediainfo}</pre>
|
||||
</div>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user