Add tabs in AddTorrent modal

This commit is contained in:
John Furrow
2016-02-15 13:14:38 -08:00
parent 96e008d725
commit ce94ac35d1
15 changed files with 501 additions and 161 deletions

View File

@@ -33,6 +33,9 @@
} }
} }
&.is-fulfilled {
background: $textbox--fulfilled--background;
}
} }
.button { .button {
@@ -89,14 +92,14 @@
&__label { &__label {
color: $form--label--foreground; color: $form--label--foreground;
display: block; display: block;
margin-bottom: 0.1em; font-size: 0.8em;
margin-bottom: 0.5em;
} }
&__row { &__row {
& + .form__row { & + .form__row {
margin-top: 20px; margin-top: $spacing-unit;
} }
} }
} }

View File

@@ -8,7 +8,7 @@
cursor: pointer; cursor: pointer;
height: 16px; height: 16px;
outline: none; outline: none;
margin-right: 8px; margin-right: 6px;
padding: 0; padding: 0;
position: relative; position: relative;
transition: background 0.25s, box-shadow 0.25s; transition: background 0.25s, box-shadow 0.25s;

View File

@@ -1,3 +1,7 @@
$modal--border-radius: 3px;
$modal-content--padding--horizontal: $spacing-unit;
$modal-content--padding--vertical: $modal-content--padding--horizontal * 1/2;
.modal { .modal {
background: $modal--overlay; background: $modal--overlay;
height: 100%; height: 100%;
@@ -8,21 +12,78 @@
width: 100%; width: 100%;
z-index: 100; z-index: 100;
&__header {
background: $modal--heading--background;
border-radius: $modal--border-radius $modal--border-radius 0 0;
box-shadow: inset 0 -1px 0 $modal--heading--border;
color: $modal--heading--foreground;
flex: 0 0 auto;
font-size: 1.1em;
font-weight: 400;
padding: $modal-content--padding--vertical $modal-content--padding--horizontal 0 $modal-content--padding--horizontal;
}
&__tabs {
color: $modal--tab--foreground;
font-size: 0.7em;
margin: 0 $spacing-unit * -1/5;
.modal {
&__tab {
cursor: pointer;
display: inline-block;
margin-right: $spacing-unit * 1/4;
padding: $spacing-unit * 1/5;
position: relative;
&:after {
bottom: 0;
content: '';
height: 1px;
left: 0;
position: absolute;
right: 0;
transition: background 0.25s;
}
&:last-child {
margin-right: 0;
}
&.is-active {
color: $modal--tab--foreground--active;
font-weight: 600;
&:after {
background: $modal--tab--border--active;
}
}
}
}
}
&__content { &__content {
flex: 1 1 auto;
overflow: auto;
padding: $modal-content--padding--vertical $modal-content--padding--horizontal;
&__wrapper {
background: $modal--background; background: $modal--background;
border-radius: 5px; border-radius: $modal--border-radius;
box-shadow: box-shadow:
0 0 0 1px $modal--content--border, 0 0 0 1px $modal--content--border,
0 0 35px $modal--content--shadow; 0 0 35px $modal--content--shadow;
display: flex;
flex-direction: column;
left: 50%; left: 50%;
max-height: 80%; max-height: 80%;
max-width: 80%; max-width: 80%;
overflow: auto;
padding: 30px;
position: absolute; position: absolute;
top: 10%; top: 10%;
transform: translate(-50%, 0); transform: translate(-50%, 0);
width: 500px; width: 500px;
}
&--align-center { &--align-center {
text-align: center; text-align: center;
@@ -31,6 +92,7 @@
&__footer { &__footer {
margin-top: $spacing-unit; margin-top: $spacing-unit;
padding: 0 0 $modal-content--padding--vertical 0;
} }
&__button-group { &__button-group {
@@ -44,13 +106,6 @@
} }
} }
&__header {
color: $modal--header--foreground;
font-size: 1.1em;
font-weight: 400;
margin-bottom: 20px;
}
&__animation-enter { &__animation-enter {
opacity: 0; opacity: 0;
} }

View File

@@ -20,4 +20,14 @@
position: relative; position: relative;
} }
} }
.form {
&__row {
& + .form__row {
margin-top: $spacing-unit * 1/2;
}
}
}
} }

View File

@@ -10,14 +10,15 @@ $main-content--background: #e9eef2;
$header--foreground: #313436; $header--foreground: #313436;
// form elements // form elements
$form--label--foreground: #53718a; $form--label--foreground: #abbac7;
$textbox--background: rgba($main-content--background, 0.3); $textbox--background: #e9eff5;
$textbox--foreground: $foreground; $textbox--foreground: #53718a;
$textbox--placeholder: #abbac7; $textbox--placeholder: #abbac7;
$textbox--border: $main-content--background; $textbox--border: #d6e2ea;
$textbox--active--background: $textbox--background; $textbox--fulfilled--background: #fdfefe;
$textbox--active--border: $main-content--background; $textbox--active--background: #fdfefe;
$textbox--active--border: desaturate(darken($textbox--border, 5%), 5%);
$textbox--active--foreground: $blue; $textbox--active--foreground: $blue;
$textbox--active--placeholder: $textbox--placeholder; $textbox--active--placeholder: $textbox--placeholder;
@@ -138,7 +139,7 @@ $torrent-details--navigation--border: rgba(#040d13, 0.4);
$torrent-details--navigation--item--background--active: rgba(#349cf4, 0.07); $torrent-details--navigation--item--background--active: rgba(#349cf4, 0.07);
$torrent-details--navigation--item--foreground--active: #349cf4; $torrent-details--navigation--item--foreground--active: #349cf4;
$torrent-details--navigation--item--border--active: #349cf4; $torrent-details--navigation--item--border--active: #349cf4;
$torrent-details--navigation--background: transparent; // rgba(desaturate(#0c1b26, 15%), 0.1) $torrent-details--navigation--background: transparent;
$torrent-details--content--background: rgba(desaturate(#0c1b26, 15%), 0.4); $torrent-details--content--background: rgba(desaturate(#0c1b26, 15%), 0.4);
@@ -173,9 +174,14 @@ $dropdown--item--foreground--hover: darken($dropdown--foreground, 10%);
$dropdown--item--foreground--active: $blue; $dropdown--item--foreground--active: $blue;
// modal windows // modal windows
$modal--background: #fff; $modal--background: #f7fafc;
$modal--heading--background: #fff;
$modal--heading--foreground: $header--foreground;
$modal--heading--border: #dde7ed;
$modal--tab--foreground: #abbac7;
$modal--tab--foreground--active: $blue;
$modal--tab--border--active: $blue;
$modal--overlay: rgba($background, 0.5); $modal--overlay: rgba($background, 0.5);
$modal--header--foreground: $header--foreground;
$modal--content--border: rgba($background, 0.1); $modal--content--border: rgba($background, 0.1);
$modal--content--shadow: rgba($background, 0.3); $modal--content--shadow: rgba($background, 0.3);

View File

@@ -10,7 +10,6 @@ const METHODS_TO_BIND = [
]; ];
export default class TextboxRepeater extends React.Component { export default class TextboxRepeater extends React.Component {
constructor() { constructor() {
super(); super();
@@ -38,9 +37,13 @@ export default class TextboxRepeater extends React.Component {
); );
} }
let inputClasses = classnames('textbox', {
'is-fulfilled': textbox.value && textbox.value !== ''
});
return ( return (
<div className="textbox__wrapper form__row" key={index}> <div className="textbox__wrapper form__row" key={index}>
<input className="textbox" <input className={inputClasses}
onChange={this.handleTextboxChange.bind(textbox, index)} onChange={this.handleTextboxChange.bind(textbox, index)}
placeholder={this.props.placeholder} placeholder={this.props.placeholder}
value={textbox.value} value={textbox.value}
@@ -66,5 +69,4 @@ export default class TextboxRepeater extends React.Component {
</div> </div>
); );
} }
} }

View File

@@ -2,6 +2,8 @@ import _ from 'lodash';
import classnames from 'classnames'; import classnames from 'classnames';
import React from 'react'; import React from 'react';
import AddTorrentsByFile from './AddTorrentsByFile';
import AddTorrentsByURL from './AddTorrentsByURL';
import EventTypes from '../../constants/EventTypes'; import EventTypes from '../../constants/EventTypes';
import LoadingIndicatorDots from '../icons/LoadingIndicatorDots'; import LoadingIndicatorDots from '../icons/LoadingIndicatorDots';
import Modal from './Modal'; import Modal from './Modal';
@@ -11,16 +13,7 @@ import TorrentStore from '../../stores/TorrentStore';
import UIActions from '../../actions/UIActions'; import UIActions from '../../actions/UIActions';
import UIStore from '../../stores/UIStore'; import UIStore from '../../stores/UIStore';
const METHODS_TO_BIND = [ const METHODS_TO_BIND = ['onAddTorrentSuccess'];
'getContent',
'handleDestinationChange',
'handleUrlAdd',
'handleUrlChange',
'handleUrlRemove',
'handleAddTorrents',
'onAddTorrentSuccess',
'onLatestTorrentLocationChange'
];
export default class AddTorrents extends React.Component { export default class AddTorrents extends React.Component {
constructor() { constructor() {
@@ -39,18 +32,12 @@ export default class AddTorrents extends React.Component {
}); });
} }
componentWillMount() {
this.setState({destination: UIStore.getLatestTorrentLocation()});
}
componentDidMount() { componentDidMount() {
TorrentStore.listen(EventTypes.CLIENT_ADD_TORRENT_SUCCESS, this.onAddTorrentSuccess); TorrentStore.listen(EventTypes.CLIENT_ADD_TORRENT_SUCCESS, this.onAddTorrentSuccess);
UIStore.listen(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
} }
componentWillUnmount() { componentWillUnmount() {
TorrentStore.unlisten(EventTypes.CLIENT_ADD_TORRENT_SUCCESS, this.onAddTorrentSuccess); TorrentStore.unlisten(EventTypes.CLIENT_ADD_TORRENT_SUCCESS, this.onAddTorrentSuccess);
UIStore.unlisten(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
UIStore.fetchLatestTorrentLocation(); UIStore.fetchLatestTorrentLocation();
} }
@@ -69,10 +56,6 @@ export default class AddTorrents extends React.Component {
this.dismissModal(); this.dismissModal();
} }
onLatestTorrentLocationChange() {
this.setState({destination: UIStore.getLatestTorrentLocation()});
}
getActions() { getActions() {
let icon = null; let icon = null;
let primaryButtonText = 'Add Torrent'; let primaryButtonText = 'Add Torrent';
@@ -104,80 +87,27 @@ export default class AddTorrents extends React.Component {
]; ];
} }
getContent() { getAddByFileContent() {
let error = null; return <span>add by file</span>;
if (this.state.addTorrentsError) {
error = (
<div className="form__row">
{this.state.addTorrentsError}
</div>
);
}
return (
<div className="form">
{error}
<div className="form__row">
<TextboxRepeater placeholder="Torrent URL"
handleTextboxAdd={this.handleUrlAdd}
handleTextboxChange={this.handleUrlChange}
handleTextboxRemove={this.handleUrlRemove}
textboxes={this.state.urlTextboxes} />
</div>
<div className="form__row">
<input className="textbox"
onChange={this.handleDestinationChange}
placeholder="Destination"
value={this.state.destination}
type="text" />
</div>
</div>
);
}
handleAddTorrents() {
this.setState({isAddingTorrents: true});
let torrentUrls = _.map(this.state.urlTextboxes, 'value');
TorrentActions.addTorrents(torrentUrls, this.state.destination);
}
handleDestinationChange(event) {
this.setState({
destination: event.target.value
})
}
handleMenuWrapperClick(event) {
event.stopPropagation();
}
handleUrlRemove(index) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes.splice(index, 1);
this.setState({
urlTextboxes
});
}
handleUrlAdd(index) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes.splice(index + 1, 0, {value: null});
this.setState({urlTextboxes});
}
handleUrlChange(index, value) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes[index].value = value;
this.setState({urlTextboxes});
} }
render() { render() {
let tabs = {
'by-url': {
content: <AddTorrentsByURL />,
label: 'By URL'
},
'by-file': {
content: <AddTorrentsByFile />,
label: 'By File'
}
};
return ( return (
<Modal heading="Add Torrents" <Modal heading="Add Torrents"
content={this.getContent()}
actions={this.getActions()} actions={this.getActions()}
dismiss={this.dismissModal} /> dismiss={this.dismissModal}
tabs={tabs} />
); );
} }
} }

View File

@@ -0,0 +1,35 @@
import Dropzone from 'react-dropzone';
import React from 'react';
const METHODS_TO_BIND = ['handleOpenClick'];
export default class AddTorrents extends React.Component {
constructor() {
super();
this.state = {
files: null
};
METHODS_TO_BIND.forEach((method) => {
this[method] = this[method].bind(this);
});
}
handleFileDrop(files) {
this.setState({files});
}
render() {
return (
<div className="form">
<Dropzone className="form__dropzone dropzone" ref="dropzone" onDrop={this.handleFileDrop}>
Drop some files here,
<span className="dropzone__browse-button">
or click to browse.
</span>
</Dropzone>
</div>
);
}
}

View File

@@ -0,0 +1,132 @@
import _ from 'lodash';
import classnames from 'classnames';
import React from 'react';
import EventTypes from '../../constants/EventTypes';
import LoadingIndicatorDots from '../icons/LoadingIndicatorDots';
import Modal from './Modal';
import TextboxRepeater from '../forms/TextboxRepeater';
import TorrentActions from '../../actions/TorrentActions';
import TorrentStore from '../../stores/TorrentStore';
import UIActions from '../../actions/UIActions';
import UIStore from '../../stores/UIStore';
const METHODS_TO_BIND = [
'handleDestinationChange',
'handleUrlAdd',
'handleUrlChange',
'handleUrlRemove',
'handleAddTorrents',
'onLatestTorrentLocationChange'
];
export default class AddTorrents extends React.Component {
constructor() {
super();
this.state = {
addTorrentsError: null,
destination: null,
isAddingTorrents: false,
urlTextboxes: [{value: null}]
};
METHODS_TO_BIND.forEach((method) => {
this[method] = this[method].bind(this);
});
}
componentWillMount() {
this.setState({destination: UIStore.getLatestTorrentLocation()});
}
componentDidMount() {
UIStore.listen(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
}
componentWillUnmount() {
UIStore.unlisten(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
UIStore.fetchLatestTorrentLocation();
}
dismissModal() {
UIActions.dismissModal();
}
onAddTorrentError() {
this.setState({
addTorrentsError: 'There was an error, but I have no idea what happened!',
isAddingTorrents: false
});
}
onLatestTorrentLocationChange() {
this.setState({destination: UIStore.getLatestTorrentLocation()});
}
handleAddTorrents() {
this.setState({isAddingTorrents: true});
let torrentUrls = _.map(this.state.urlTextboxes, 'value');
TorrentActions.addTorrents(torrentUrls, this.state.destination);
}
handleDestinationChange(event) {
this.setState({destination: event.target.value});
}
handleUrlRemove(index) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes.splice(index, 1);
this.setState({urlTextboxes});
}
handleUrlAdd(index) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes.splice(index + 1, 0, {value: null});
this.setState({urlTextboxes});
}
handleUrlChange(index, value) {
let urlTextboxes = Object.assign([], this.state.urlTextboxes);
urlTextboxes[index].value = value;
this.setState({urlTextboxes});
}
render() {
let error = null;
if (this.state.addTorrentsError) {
error = (
<div className="form__row">
{this.state.addTorrentsError}
</div>
);
}
return (
<div className="form">
{error}
<div className="form__row">
<label className="form__label">
Torrents
</label>
<TextboxRepeater placeholder="Torrent URL"
handleTextboxAdd={this.handleUrlAdd}
handleTextboxChange={this.handleUrlChange}
handleTextboxRemove={this.handleUrlRemove}
textboxes={this.state.urlTextboxes} />
</div>
<div className="form__row">
<label className="form__label">
Destination
</label>
<input className="textbox"
onChange={this.handleDestinationChange}
placeholder="Destination"
value={this.state.destination}
type="text" />
</div>
</div>
);
}
}

View File

@@ -2,7 +2,32 @@ import _ from 'lodash';
import classnames from 'classnames'; import classnames from 'classnames';
import React from 'react'; import React from 'react';
import CustomScrollbars from '../ui/CustomScrollbars';
import ModalTabs from './ModalTabs';
const METHODS_TO_BIND = ['handleTabChange'];
export default class Modal extends React.Component { export default class Modal extends React.Component {
constructor() {
super();
this.state = {
activeTabId: null
};
METHODS_TO_BIND.forEach((method) => {
this[method] = this[method].bind(this);
});
}
getActiveTabId() {
if (this.state.activeTabId) {
return this.state.activeTabId;
}
return Object.keys(this.props.tabs)[0];
}
getModalButtons(actions) { getModalButtons(actions) {
let buttons = actions.map((action, index) => { let buttons = actions.map((action, index) => {
let classes = classnames('button', { let classes = classnames('button', {
@@ -37,24 +62,43 @@ export default class Modal extends React.Component {
} }
} }
handleTabChange(tab) {
this.setState({activeTabId: tab.id});
}
handleMenuWrapperClick(event) { handleMenuWrapperClick(event) {
event.stopPropagation(); event.stopPropagation();
} }
render() { render() {
let contentClasses = classnames('modal__content', let content = this.props.content;
`modal__content--align-${this.props.alignment}`); let contentClasses = classnames('modal__content__wrapper',
`modal--align-${this.props.alignment}`);
let tabs = null;
if (this.props.tabs) {
let activeTabId = this.getActiveTabId();
content = this.props.tabs[activeTabId].content;
tabs = (
<ModalTabs activeTabId={activeTabId} onTabChange={this.handleTabChange}
tabs={this.props.tabs} />
);
}
return ( return (
<div className={contentClasses} onClick={this.handleMenuWrapperClick}> <div className={contentClasses} onClick={this.handleMenuWrapperClick}>
<div className="modal__header">{this.props.heading}</div> <div className="modal__header">
<div className="modal__content__container"> {this.props.heading}
{this.props.content} {tabs}
</div> </div>
<div className="modal__content">
{content}
<div className="modal__footer"> <div className="modal__footer">
{this.getModalButtons(this.props.actions)} {this.getModalButtons(this.props.actions)}
</div> </div>
</div> </div>
</div>
); );
} }
} }

View File

@@ -0,0 +1,38 @@
import classnames from 'classnames';
import React from 'react';
export default class ModalTabs extends React.Component {
handleTabClick(tab) {
if (this.props.onTabChange) {
this.props.onTabChange(tab);
}
}
render() {
let tabs = Object.keys(this.props.tabs).map((tabId, index) => {
let currentTab = this.props.tabs[tabId];
currentTab.id = tabId;
let classes = classnames('modal__tab', {
'is-active': tabId === this.props.activeTabId
});
return (
<li className={classes} key={index}
onClick={this.handleTabClick.bind(this, currentTab)}>
{currentTab.label}
</li>
);
});
return (
<ul className="modal__tabs">
{tabs}
</ul>
);
}
}
ModalTabs.defaultProps = {
tabs: []
};

View File

@@ -38,6 +38,7 @@
"react-addons-css-transition-group": "^0.14.7", "react-addons-css-transition-group": "^0.14.7",
"react-custom-scrollbars": "^3.0.0", "react-custom-scrollbars": "^3.0.0",
"react-dom": "^0.14.7", "react-dom": "^0.14.7",
"react-dropzone": "^3.3.2",
"sax": "^0.6.1", "sax": "^0.6.1",
"serve-favicon": "~2.2.0", "serve-favicon": "~2.2.0",
"xmlbuilder": "^2.6.2", "xmlbuilder": "^2.6.2",

File diff suppressed because one or more lines are too long

View File

@@ -484,9 +484,9 @@ th {
outline: none; } outline: none; }
.textbox { .textbox {
background: rgba(233, 238, 242, 0.3); background: #e9eff5;
border-radius: 4px; border-radius: 4px;
border: 1px solid #e9eef2; border: 1px solid #d6e2ea;
color: #53718a; color: #53718a;
display: block; display: block;
font-size: 0.9em; font-size: 0.9em;
@@ -515,8 +515,8 @@ th {
-webkit-transition: color 0.25s; -webkit-transition: color 0.25s;
transition: color 0.25s; } transition: color 0.25s; }
.textbox:focus { .textbox:focus {
background: rgba(233, 238, 242, 0.3); background: #fdfefe;
border-color: #e9eef2; border-color: #c7d6df;
color: #258de5; } color: #258de5; }
.textbox:focus::-webkit-input-placeholder { .textbox:focus::-webkit-input-placeholder {
color: #abbac7; } color: #abbac7; }
@@ -526,6 +526,8 @@ th {
color: #abbac7; } color: #abbac7; }
.textbox:focus::placeholder { .textbox:focus::placeholder {
color: #abbac7; } color: #abbac7; }
.textbox.is-fulfilled {
background: #fdfefe; }
.button { .button {
background: transparent; background: transparent;
@@ -560,12 +562,13 @@ th {
background: #1a80d7; } background: #1a80d7; }
.form__label { .form__label {
color: #53718a; color: #abbac7;
display: block; display: block;
margin-bottom: 0.1em; } font-size: 0.8em;
margin-bottom: 0.5em; }
.form__row + .form__row { .form__row + .form__row {
margin-top: 20px; } margin-top: 25px; }
html, html,
body { body {
@@ -1140,7 +1143,7 @@ body {
cursor: pointer; cursor: pointer;
height: 16px; height: 16px;
outline: none; outline: none;
margin-right: 8px; margin-right: 6px;
padding: 0; padding: 0;
position: relative; position: relative;
-webkit-transition: background 0.25s, box-shadow 0.25s; -webkit-transition: background 0.25s, box-shadow 0.25s;
@@ -1267,15 +1270,67 @@ body {
transition: opacity 0.5s; transition: opacity 0.5s;
width: 100%; width: 100%;
z-index: 100; } z-index: 100; }
.modal__content { .modal__header {
background: #fff; background: #fff;
border-radius: 5px; border-radius: 3px 3px 0 0;
box-shadow: inset 0 -1px 0 #dde7ed;
color: #313436;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
font-size: 1.1em;
font-weight: 400;
padding: 12.5px 25px 0 25px; }
.modal__tabs {
color: #abbac7;
font-size: 0.7em;
margin: 0 -5px; }
.modal__tabs .modal__tab {
cursor: pointer;
display: inline-block;
margin-right: 6.25px;
padding: 5px;
position: relative; }
.modal__tabs .modal__tab:after {
bottom: 0;
content: '';
height: 1px;
left: 0;
position: absolute;
right: 0;
-webkit-transition: background 0.25s;
transition: background 0.25s; }
.modal__tabs .modal__tab:last-child {
margin-right: 0; }
.modal__tabs .modal__tab.is-active {
color: #258de5;
font-weight: 600; }
.modal__tabs .modal__tab.is-active:after {
background: #258de5; }
.modal__content {
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
overflow: auto;
padding: 12.5px 25px; }
.modal__content__wrapper {
background: #f7fafc;
border-radius: 3px;
box-shadow: 0 0 0 1px rgba(26, 47, 61, 0.1), 0 0 35px rgba(26, 47, 61, 0.3); box-shadow: 0 0 0 1px rgba(26, 47, 61, 0.1), 0 0 35px rgba(26, 47, 61, 0.3);
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
left: 50%; left: 50%;
max-height: 80%; max-height: 80%;
max-width: 80%; max-width: 80%;
overflow: auto;
padding: 30px;
position: absolute; position: absolute;
top: 10%; top: 10%;
-webkit-transform: translate(-50%, 0); -webkit-transform: translate(-50%, 0);
@@ -1284,16 +1339,12 @@ body {
.modal__content--align-center { .modal__content--align-center {
text-align: center; } text-align: center; }
.modal__footer { .modal__footer {
margin-top: 25px; } margin-top: 25px;
padding: 0 0 12.5px 0; }
.modal__button-group { .modal__button-group {
text-align: right; } text-align: right; }
.modal__button-group .button + .button { .modal__button-group .button + .button {
margin-left: 20px; } margin-left: 20px; }
.modal__header {
color: #313436;
font-size: 1.1em;
font-weight: 400;
margin-bottom: 20px; }
.modal__animation-enter { .modal__animation-enter {
opacity: 0; } opacity: 0; }
.modal__animation-enter-active { .modal__animation-enter-active {
@@ -1582,6 +1633,9 @@ body {
.textbox-repeater .textbox__wrapper { .textbox-repeater .textbox__wrapper {
position: relative; } position: relative; }
.textbox-repeater .form__row + .form__row {
margin-top: 12.5px; }
.application__panel--torrent-details { .application__panel--torrent-details {
background: #0e2231; } background: #0e2231; }

File diff suppressed because one or more lines are too long