about summary refs log tree commit diff
path: root/app/javascript/glitch/components/local_settings
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/glitch/components/local_settings')
-rw-r--r--app/javascript/glitch/components/local_settings/container.js24
-rw-r--r--app/javascript/glitch/components/local_settings/index.js50
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/index.js74
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/item/index.js69
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/item/style.scss27
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/style.scss10
-rw-r--r--app/javascript/glitch/components/local_settings/page/index.js183
-rw-r--r--app/javascript/glitch/components/local_settings/page/item/index.js90
-rw-r--r--app/javascript/glitch/components/local_settings/page/item/style.scss7
-rw-r--r--app/javascript/glitch/components/local_settings/page/style.scss9
-rw-r--r--app/javascript/glitch/components/local_settings/style.scss34
11 files changed, 577 insertions, 0 deletions
diff --git a/app/javascript/glitch/components/local_settings/container.js b/app/javascript/glitch/components/local_settings/container.js
new file mode 100644
index 000000000..6c202a4e7
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/container.js
@@ -0,0 +1,24 @@
+//  Package imports  //
+import { connect } from 'react-redux';
+
+//  Mastodon imports  //
+import { closeModal } from 'mastodon/actions/modal';
+
+//  Our imports  //
+import { changeLocalSetting } from 'glitch/actions/local_settings';
+import LocalSettings from '.';
+
+const mapStateToProps = state => ({
+  settings: state.get('local_settings'),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onChange (setting, value) {
+    dispatch(changeLocalSetting(setting, value));
+  },
+  onClose () {
+    dispatch(closeModal());
+  },
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(LocalSettings);
diff --git a/app/javascript/glitch/components/local_settings/index.js b/app/javascript/glitch/components/local_settings/index.js
new file mode 100644
index 000000000..7f7b93de4
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/index.js
@@ -0,0 +1,50 @@
+//  Package imports
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+
+//  Our imports
+import LocalSettingsPage from './page';
+import LocalSettingsNavigation from './navigation';
+
+//  Stylesheet imports
+import './style';
+
+export default class LocalSettings extends React.PureComponent {
+
+  static propTypes = {
+    onChange: PropTypes.func.isRequired,
+    onClose: PropTypes.func.isRequired,
+    settings: ImmutablePropTypes.map.isRequired,
+  };
+
+  state = {
+    currentIndex: 0,
+  };
+
+  navigateTo = (index) =>
+    this.setState({ currentIndex: +index });
+
+  render () {
+
+    const { navigateTo } = this;
+    const { onChange, onClose, settings } = this.props;
+    const { currentIndex } = this.state;
+
+    return (
+      <div className='glitch modal-root__modal local-settings'>
+        <LocalSettingsNavigation
+          index={currentIndex}
+          onClose={onClose}
+          onNavigate={navigateTo}
+        />
+        <LocalSettingsPage
+          index={currentIndex}
+          onChange={onChange}
+          settings={settings}
+        />
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/glitch/components/local_settings/navigation/index.js b/app/javascript/glitch/components/local_settings/navigation/index.js
new file mode 100644
index 000000000..1f72cc824
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/navigation/index.js
@@ -0,0 +1,74 @@
+//  Package imports
+import React from 'react';
+import PropTypes from 'prop-types';
+import { injectIntl, defineMessages } from 'react-intl';
+
+//  Our imports
+import LocalSettingsNavigationItem from './item';
+
+//  Stylesheet imports
+import './style';
+
+//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+const messages = defineMessages({
+  general: {  id: 'settings.general', defaultMessage: 'General' },
+  collapsed: { id: 'settings.collapsed_statuses', defaultMessage: 'Collapsed toots' },
+  media: { id: 'settings.media', defaultMessage: 'Media' },
+  preferences: { id: 'settings.preferences', defaultMessage: 'Preferences' },
+  close: { id: 'settings.close', defaultMessage: 'Close' },
+});
+
+@injectIntl
+export default class LocalSettingsNavigation extends React.PureComponent {
+
+  static propTypes = {
+    index      : PropTypes.number,
+    intl       : PropTypes.object.isRequired,
+    onClose    : PropTypes.func.isRequired,
+    onNavigate : PropTypes.func.isRequired,
+  };
+
+  render () {
+
+    const { index, intl, onClose, onNavigate } = this.props;
+
+    return (
+      <nav className='glitch local-settings__navigation'>
+        <LocalSettingsNavigationItem
+          active={index === 0}
+          index={0}
+          onNavigate={onNavigate}
+          title={intl.formatMessage(messages.general)}
+        />
+        <LocalSettingsNavigationItem
+          active={index === 1}
+          index={1}
+          onNavigate={onNavigate}
+          title={intl.formatMessage(messages.collapsed)}
+        />
+        <LocalSettingsNavigationItem
+          active={index === 2}
+          index={2}
+          onNavigate={onNavigate}
+          title={intl.formatMessage(messages.media)}
+        />
+        <LocalSettingsNavigationItem
+          active={index === 3}
+          href='/settings/preferences'
+          index={3}
+          icon='cog'
+          title={intl.formatMessage(messages.preferences)}
+        />
+        <LocalSettingsNavigationItem
+          active={index === 4}
+          className='close'
+          index={4}
+          onNavigate={onClose}
+          title={intl.formatMessage(messages.close)}
+        />
+      </nav>
+    );
+  }
+
+}
diff --git a/app/javascript/glitch/components/local_settings/navigation/item/index.js b/app/javascript/glitch/components/local_settings/navigation/item/index.js
new file mode 100644
index 000000000..1676aa404
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/navigation/item/index.js
@@ -0,0 +1,69 @@
+//  Package imports
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+
+//  Stylesheet imports
+import './style';
+
+//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+export default class LocalSettingsPage extends React.PureComponent {
+
+  static propTypes = {
+    active: PropTypes.bool,
+    className: PropTypes.string,
+    href: PropTypes.string,
+    icon: PropTypes.string,
+    index: PropTypes.number.isRequired,
+    onNavigate: PropTypes.func,
+    title: PropTypes.string,
+  };
+
+  handleClick = (e) => {
+    const { index, onNavigate } = this.props;
+    if (onNavigate) {
+      onNavigate(index);
+      e.preventDefault();
+    }
+  }
+
+  render () {
+    const { handleClick } = this;
+    const {
+      active,
+      className,
+      href,
+      icon,
+      onNavigate,
+      title,
+    } = this.props;
+
+    const finalClassName = classNames('glitch', 'local-settings__navigation__item', {
+      active,
+    }, className);
+
+    const iconElem = icon ? <i className={`fa fa-fw fa-${icon}`} /> : null;
+
+    if (href) return (
+      <a
+        href={href}
+        className={finalClassName}
+      >
+        {iconElem} {title}
+      </a>
+    );
+    else if (onNavigate) return (
+      <a
+        onClick={handleClick}
+        role='button'
+        tabIndex='0'
+        className={finalClassName}
+      >
+        {iconElem} {title}
+      </a>
+    );
+    else return null;
+  }
+
+}
diff --git a/app/javascript/glitch/components/local_settings/navigation/item/style.scss b/app/javascript/glitch/components/local_settings/navigation/item/style.scss
new file mode 100644
index 000000000..505c86912
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/navigation/item/style.scss
@@ -0,0 +1,27 @@
+@import 'variables';
+
+.glitch.local-settings__navigation__item {
+  display: block;
+  padding: 15px 20px;
+  color: inherit;
+  background: $primary-text-color;
+  border-bottom: 1px $ui-primary-color solid;
+  cursor: pointer;
+  text-decoration: none;
+  outline: none;
+  transition: background .3s;
+
+  &:hover {
+    background: $ui-secondary-color;
+  }
+
+  &.active {
+    background: $ui-highlight-color;
+    color: $primary-text-color;
+  }
+
+  &.close, &.close:hover {
+    background: $error-value-color;
+    color: $primary-text-color;
+  }
+}
diff --git a/app/javascript/glitch/components/local_settings/navigation/style.scss b/app/javascript/glitch/components/local_settings/navigation/style.scss
new file mode 100644
index 000000000..1cc39e3e9
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/navigation/style.scss
@@ -0,0 +1,10 @@
+@import 'variables';
+
+.glitch.local-settings__navigation {
+  background: $primary-text-color;
+  color: $ui-base-color;
+  width: 200px;
+  font-size: 15px;
+  line-height: 20px;
+  overflow-y: auto;
+}
diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js
new file mode 100644
index 000000000..cb041c0b8
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/page/index.js
@@ -0,0 +1,183 @@
+//  Package imports
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
+
+//  Our imports
+import LocalSettingsPageItem from './item';
+
+//  Stylesheet imports
+import './style';
+
+//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+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 LocalSettingsPage extends React.PureComponent {
+
+  static propTypes = {
+    index    : PropTypes.number,
+    intl     : PropTypes.object.isRequired,
+    onChange : PropTypes.func.isRequired,
+    settings : ImmutablePropTypes.map.isRequired,
+  };
+
+  pages = [
+    ({ intl, onChange, settings }) => (
+      <div className='glitch local-settings__page general'>
+        <h1><FormattedMessage id='settings.general' defaultMessage='General' /></h1>
+        <LocalSettingsPageItem
+          settings={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={onChange}
+        >
+          <FormattedMessage id='settings.layout' defaultMessage='Layout:' />
+        </LocalSettingsPageItem>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['stretch']}
+          id='mastodon-settings--stretch'
+          onChange={onChange}
+        >
+          <FormattedMessage id='settings.wide_view' defaultMessage='Wide view (Desktop mode only)' />
+        </LocalSettingsPageItem>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['navbar_under']}
+          id='mastodon-settings--navbar_under'
+          onChange={onChange}
+        >
+          <FormattedMessage id='settings.navbar_under' defaultMessage='Navbar at the bottom (Mobile only)' />
+        </LocalSettingsPageItem>
+      </div>
+    ),
+    ({ onChange, settings }) => (
+      <div className='glitch local-settings__page collapsed'>
+        <h1><FormattedMessage id='settings.collapsed_statuses' defaultMessage='Collapsed toots' /></h1>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['collapsed', 'enabled']}
+          id='mastodon-settings--collapsed-enabled'
+          onChange={onChange}
+        >
+          <FormattedMessage id='settings.enable_collapsed' defaultMessage='Enable collapsed toots' />
+        </LocalSettingsPageItem>
+        <section>
+          <h2><FormattedMessage id='settings.auto_collapse' defaultMessage='Automatic collapsing' /></h2>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'auto', 'all']}
+            id='mastodon-settings--collapsed-auto-all'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_all' defaultMessage='Everything' />
+          </LocalSettingsPageItem>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'auto', 'notifications']}
+            id='mastodon-settings--collapsed-auto-notifications'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_notifications' defaultMessage='Notifications' />
+          </LocalSettingsPageItem>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'auto', 'lengthy']}
+            id='mastodon-settings--collapsed-auto-lengthy'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_lengthy' defaultMessage='Lengthy toots' />
+          </LocalSettingsPageItem>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'auto', 'replies']}
+            id='mastodon-settings--collapsed-auto-replies'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_replies' defaultMessage='Replies' />
+          </LocalSettingsPageItem>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'auto', 'media']}
+            id='mastodon-settings--collapsed-auto-media'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+            dependsOnNot={[['collapsed', 'auto', 'all']]}
+          >
+            <FormattedMessage id='settings.auto_collapse_media' defaultMessage='Toots with media' />
+          </LocalSettingsPageItem>
+        </section>
+        <section>
+          <h2><FormattedMessage id='settings.image_backgrounds' defaultMessage='Image backgrounds' /></h2>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'backgrounds', 'user_backgrounds']}
+            id='mastodon-settings--collapsed-user-backgrouns'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.image_backgrounds_users' defaultMessage='Give collapsed toots an image background' />
+          </LocalSettingsPageItem>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['collapsed', 'backgrounds', 'preview_images']}
+            id='mastodon-settings--collapsed-preview-images'
+            onChange={onChange}
+            dependsOn={[['collapsed', 'enabled']]}
+          >
+            <FormattedMessage id='settings.image_backgrounds_media' defaultMessage='Preview collapsed toot media' />
+          </LocalSettingsPageItem>
+        </section>
+      </div>
+    ),
+    ({ onChange, settings }) => (
+      <div className='glitch local-settings__page media'>
+        <h1><FormattedMessage id='settings.media' defaultMessage='Media' /></h1>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['media', 'letterbox']}
+          id='mastodon-settings--media-letterbox'
+          onChange={onChange}
+        >
+          <FormattedMessage id='settings.media_letterbox' defaultMessage='Letterbox media' />
+        </LocalSettingsPageItem>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['media', 'fullwidth']}
+          id='mastodon-settings--media-fullwidth'
+          onChange={onChange}
+        >
+          <FormattedMessage id='settings.media_fullwidth' defaultMessage='Full-width media previews' />
+        </LocalSettingsPageItem>
+      </div>
+    ),
+  ];
+
+  render () {
+    const { pages } = this;
+    const { index, intl, onChange, settings } = this.props;
+    const CurrentPage = pages[index] || pages[0];
+
+    return <CurrentPage intl={intl} onChange={onChange} settings={settings} />;
+  }
+
+}
diff --git a/app/javascript/glitch/components/local_settings/page/item/index.js b/app/javascript/glitch/components/local_settings/page/item/index.js
new file mode 100644
index 000000000..326c7eeb0
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/page/item/index.js
@@ -0,0 +1,90 @@
+//  Package imports
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+
+//  Stylesheet imports
+import './style';
+
+//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+export default class LocalSettingsPageItem extends React.PureComponent {
+
+  static propTypes = {
+    children: PropTypes.element.isRequired,
+    dependsOn: PropTypes.array,
+    dependsOnNot: PropTypes.array,
+    id: PropTypes.string.isRequired,
+    item: PropTypes.array.isRequired,
+    onChange: PropTypes.func.isRequired,
+    options: PropTypes.arrayOf(PropTypes.shape({
+      value: PropTypes.string.isRequired,
+      message: PropTypes.string.isRequired,
+    })),
+    settings: ImmutablePropTypes.map.isRequired,
+  };
+
+  handleChange = e => {
+    const { target } = e;
+    const { item, onChange, options } = this.props;
+    if (options && options.length > 0) onChange(item, target.value);
+    else onChange(item, target.checked);
+  }
+
+  render () {
+    const { handleChange } = this;
+    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}
+          value={opt.value}
+        >
+          {opt.message}
+        </option>
+      ));
+      return (
+        <label className='glitch local-settings__page__item' htmlFor={id}>
+          <p>{children}</p>
+          <p>
+            <select
+              id={id}
+              disabled={!enabled}
+              onBlur={handleChange}
+              onChange={handleChange}
+              value={currentValue}
+            >
+              {optionElems}
+            </select>
+          </p>
+        </label>
+      );
+    } else return (
+      <label className='glitch local-settings__page__item' htmlFor={id}>
+        <input
+          id={id}
+          type='checkbox'
+          checked={settings.getIn(item)}
+          onChange={handleChange}
+          disabled={!enabled}
+        />
+        {children}
+      </label>
+    );
+  }
+
+}
diff --git a/app/javascript/glitch/components/local_settings/page/item/style.scss b/app/javascript/glitch/components/local_settings/page/item/style.scss
new file mode 100644
index 000000000..e614030c0
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/page/item/style.scss
@@ -0,0 +1,7 @@
+@import 'variables';
+
+.glitch.local-settings__page__item {
+  select {
+    margin-bottom: 5px;
+  }
+}
diff --git a/app/javascript/glitch/components/local_settings/page/style.scss b/app/javascript/glitch/components/local_settings/page/style.scss
new file mode 100644
index 000000000..7269056c3
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/page/style.scss
@@ -0,0 +1,9 @@
+@import 'variables';
+
+.glitch.local-settings__page {
+  display: block;
+  flex: auto;
+  padding: 15px 20px 15px 20px;
+  width: 360px;
+  overflow-y: auto;
+}
diff --git a/app/javascript/glitch/components/local_settings/style.scss b/app/javascript/glitch/components/local_settings/style.scss
new file mode 100644
index 000000000..6f7fcbaa4
--- /dev/null
+++ b/app/javascript/glitch/components/local_settings/style.scss
@@ -0,0 +1,34 @@
+@import 'variables';
+
+.glitch.local-settings {
+  position: relative;
+  display: flex;
+  flex-direction: row;
+  background: $ui-secondary-color;
+  color: $ui-base-color;
+  border-radius: 8px;
+  height: 80vh;
+  width: 80vw;
+  max-width: 740px;
+  max-height: 450px;
+  overflow: hidden;
+
+  label {
+    display: block;
+  }
+
+  h1 {
+    font-size: 18px;
+    font-weight: 500;
+    line-height: 24px;
+    margin-bottom: 20px;
+  }
+
+  h2 {
+    font-size: 15px;
+    font-weight: 500;
+    line-height: 20px;
+    margin-top: 20px;
+    margin-bottom: 10px;
+  }
+}