about summary refs log tree commit diff
path: root/app/javascript/glitch/components/settings
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/glitch/components/settings')
-rw-r--r--app/javascript/glitch/components/settings/index.js221
-rw-r--r--app/javascript/glitch/components/settings/item.js79
2 files changed, 300 insertions, 0 deletions
diff --git a/app/javascript/glitch/components/settings/index.js b/app/javascript/glitch/components/settings/index.js
new file mode 100644
index 000000000..afe7e9a87
--- /dev/null
+++ b/app/javascript/glitch/components/settings/index.js
@@ -0,0 +1,221 @@
+//  Package imports  //
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
+
+//  Our imports  //
+import SettingsItem from './item';
+
+const messages = defineMessages({
+  layout_auto: {  id: 'layout.auto', defaultMessage: 'Auto' },
+  layout_desktop: { id: 'layout.desktop', defaultMessage: 'Desktop' },
+  layout_mobile: { id: 'layout.single', defaultMessage: 'Mobile' },
+});
+
+@injectIntl
+export default class Settings extends React.PureComponent {
+
+  static propTypes = {
+    settings: ImmutablePropTypes.map.isRequired,
+    toggleSetting: PropTypes.func.isRequired,
+    changeSetting: PropTypes.func.isRequired,
+    onClose: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  state = {
+    currentIndex: 0,
+  };
+
+  General = () => {
+    const { intl } = this.props;
+    return (
+      <div>
+        <h1><FormattedMessage id='settings.general' defaultMessage='General' /></h1>
+        <SettingsItem
+          settings={this.props.settings}
+          item={['layout']}
+          id='mastodon-settings--layout'
+          options={[
+            { value: 'auto', message: intl.formatMessage(messages.layout_auto) },
+            { value: 'multiple', message: intl.formatMessage(messages.layout_desktop) },
+            { value: 'single', message: intl.formatMessage(messages.layout_mobile) },
+          ]}
+          onChange={this.props.changeSetting}
+        >
+          <FormattedMessage id='settings.layout' defaultMessage='Layout:' />
+        </SettingsItem>
+
+        <SettingsItem
+          settings={this.props.settings}
+          item={['stretch']}
+          id='mastodon-settings--stretch'
+          onChange={this.props.toggleSetting}
+        >
+          <FormattedMessage id='settings.wide_view' defaultMessage='Wide view (Desktop mode only)' />
+        </SettingsItem>
+
+      </div>
+    );
+  }
+
+  CollapsedStatuses = () => {
+    return (
+      <div>
+        <h1><FormattedMessage id='settings.collapsed_statuses' defaultMessage='Collapsed toots' /></h1>
+        <SettingsItem
+          settings={this.props.settings}
+          item={['collapsed', 'enabled']}
+          id='mastodon-settings--collapsed-enabled'
+          onChange={this.props.toggleSetting}
+        >
+          <FormattedMessage id='settings.enable_collapsed' defaultMessage='Enable collapsed toots' />
+        </SettingsItem>
+        <section>
+          <h2><FormattedMessage id='settings.auto_collapse' defaultMessage='Automatic collapsing' /></h2>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'auto', 'all']}
+            id='mastodon-settings--collapsed-auto-all'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_all' defaultMessage='Everything' />
+          </SettingsItem>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'auto', 'notifications']}
+            id='mastodon-settings--collapsed-auto-notifications'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_notifications' defaultMessage='Notifications' />
+          </SettingsItem>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'auto', 'lengthy']}
+            id='mastodon-settings--collapsed-auto-lengthy'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_lengthy' defaultMessage='Lengthy toots' />
+          </SettingsItem>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'auto', 'replies']}
+            id='mastodon-settings--collapsed-auto-replies'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_replies' defaultMessage='Replies' />
+          </SettingsItem>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'auto', 'media']}
+            id='mastodon-settings--collapsed-auto-media'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_media' defaultMessage='Toots with media' />
+          </SettingsItem>
+        </section>
+        <section>
+          <h2><FormattedMessage id='settings.image_backgrounds' defaultMessage='Image backgrounds' /></h2>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'backgrounds', 'user_backgrounds']}
+            id='mastodon-settings--collapsed-user-backgrouns'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.image_backgrounds_users' defaultMessage='Give collapsed toots an image background' />
+          </SettingsItem>
+          <SettingsItem
+            settings={this.props.settings}
+            item={['collapsed', 'backgrounds', 'preview_images']}
+            id='mastodon-settings--collapsed-preview-images'
+            onChange={this.props.toggleSetting}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.image_backgrounds_media' defaultMessage='Preview collapsed toot media' />
+          </SettingsItem>
+        </section>
+      </div>
+    );
+  }
+
+  Media = () => {
+    return (
+      <div>
+        <h1><FormattedMessage id='settings.media' defaultMessage='Media' /></h1>
+        <SettingsItem
+          settings={this.props.settings}
+          item={['media', 'letterbox']}
+          id='mastodon-settings--media-letterbox'
+          onChange={this.props.toggleSetting}
+        >
+          <FormattedMessage id='settings.media_letterbox' defaultMessage='Letterbox media' />
+        </SettingsItem>
+        <SettingsItem
+          settings={this.props.settings}
+          item={['media', 'fullwidth']}
+          id='mastodon-settings--media-fullwidth'
+          onChange={this.props.toggleSetting}
+        >
+          <FormattedMessage id='settings.media_fullwidth' defaultMessage='Full-width media previews' />
+        </SettingsItem>
+      </div>
+    );
+  }
+
+  navigateTo = (e) =>
+    this.setState({ currentIndex: +e.currentTarget.getAttribute('data-mastodon-navigation_index') });
+
+  render () {
+
+    const { General, CollapsedStatuses, Media, navigateTo } = this;
+    const { onClose } = this.props;
+    const { currentIndex } = this.state;
+
+    return (
+      <div className='modal-root__modal settings-modal'>
+
+        <nav className='settings-modal__navigation'>
+          <a onClick={navigateTo} role='button' data-mastodon-navigation_index='0' tabIndex='0' className={`settings-modal__navigation-item${currentIndex === 0 ? ' active' : ''}`}>
+            <FormattedMessage id='settings.general' defaultMessage='General' />
+          </a>
+          <a onClick={navigateTo} role='button' data-mastodon-navigation_index='1' tabIndex='0' className={`settings-modal__navigation-item${currentIndex === 1 ? ' active' : ''}`}>
+            <FormattedMessage id='settings.collapsed_statuses' defaultMessage='Collapsed toots' />
+          </a>
+          <a onClick={navigateTo} role='button' data-mastodon-navigation_index='2' tabIndex='0' className={`settings-modal__navigation-item${currentIndex === 2 ? ' active' : ''}`}>
+            <FormattedMessage id='settings.media' defaultMessage='Media' />
+          </a>
+          <a href='/settings/preferences' className='settings-modal__navigation-item'>
+            <i className='fa fa-fw fa-cog' /> <FormattedMessage id='settings.preferences' defaultMessage='User preferences' />
+          </a>
+          <a onClick={onClose} role='button' tabIndex='0' className='settings-modal__navigation-close'>
+            <FormattedMessage id='settings.close' defaultMessage='Close' />
+          </a>
+
+        </nav>
+
+        <div className='settings-modal__content'>
+          {
+            [
+              <General />,
+              <CollapsedStatuses />,
+              <Media />,
+            ][currentIndex] || <General />
+          }
+        </div>
+
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/glitch/components/settings/item.js b/app/javascript/glitch/components/settings/item.js
new file mode 100644
index 000000000..4c67cc2ac
--- /dev/null
+++ b/app/javascript/glitch/components/settings/item.js
@@ -0,0 +1,79 @@
+//  Package imports  //
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+
+export default class SettingsItem extends React.PureComponent {
+
+  static propTypes = {
+    settings: ImmutablePropTypes.map.isRequired,
+    item: PropTypes.array.isRequired,
+    id: PropTypes.string.isRequired,
+    options: PropTypes.arrayOf(PropTypes.shape({
+      value: PropTypes.string.isRequired,
+      message: PropTypes.object.isRequired,
+    })),
+    dependsOn: PropTypes.array,
+    dependsOnNot: PropTypes.array,
+    children: PropTypes.element.isRequired,
+    onChange: PropTypes.func.isRequired,
+  };
+
+  handleChange = (e) => {
+    const { item, onChange } = this.props;
+    onChange(item, e);
+  }
+
+  render () {
+    const { settings, item, id, options, children, dependsOn, dependsOnNot } = this.props;
+    let enabled = true;
+
+    if (dependsOn) {
+      for (let i = 0; i < dependsOn.length; i++) {
+        enabled = enabled && settings.getIn(dependsOn[i]);
+      }
+    }
+    if (dependsOnNot) {
+      for (let i = 0; i < dependsOnNot.length; i++) {
+        enabled = enabled && !settings.getIn(dependsOnNot[i]);
+      }
+    }
+
+    if (options && options.length > 0) {
+      const currentValue = settings.getIn(item);
+      const optionElems = options && options.length > 0 && options.map((opt) => (
+        <option key={opt.value} selected={currentValue === opt.value} value={opt.value} >
+          {opt.message}
+        </option>
+      ));
+      return (
+        <label htmlFor={id}>
+          <p>{children}</p>
+          <p>
+            <select
+              id={id}
+              disabled={!enabled}
+              onBlur={this.handleChange}
+            >
+              {optionElems}
+            </select>
+          </p>
+        </label>
+      );
+    } else {
+      return (
+        <label htmlFor={id}>
+          <input
+            id={id}
+            type='checkbox'
+            checked={settings.getIn(item)}
+            onChange={this.handleChange}
+            disabled={!enabled}
+          />
+          {children}
+        </label>
+      );
+    }
+  }
+
+}