~cytrogen/masto-fe

ba53e0335cf5834d74700df5a06981d8ee0b1e71 — tobi 1 year, 4 months ago e83af75
[feature] Add theme selector to app settings
M app/javascript/flavours/glitch/containers/mastodon.jsx => app/javascript/flavours/glitch/containers/mastodon.jsx +13 -9
@@ 19,6 19,8 @@ import initialState, { title as siteTitle } from 'flavours/glitch/initial_state'
import { IntlProvider } from 'flavours/glitch/locales';
import { store } from 'flavours/glitch/store';

import { ThemeComponent } from './theme_component';

const title = process.env.NODE_ENV === 'production' ? siteTitle : `${siteTitle} (Dev)`;

const hydrateAction = hydrateStore(initialState);


@@ 79,15 81,17 @@ export default class Mastodon extends PureComponent {
    return (
      <IntlProvider>
        <ReduxProvider store={store}>
          <ErrorBoundary>
            <Router>
              <ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}>
                <Route path='/' component={UI} />
              </ScrollContext>
            </Router>

            <Helmet defaultTitle={title} titleTemplate={`%s - ${title}`} />
          </ErrorBoundary>
          <ThemeComponent>
            <ErrorBoundary>
              <Router>
                <ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}>
                  <Route path='/' component={UI} />
                </ScrollContext>
              </Router>

              <Helmet defaultTitle={title} titleTemplate={`%s - ${title}`} />
            </ErrorBoundary>
          </ThemeComponent>
        </ReduxProvider>
      </IntlProvider>
    );

A app/javascript/flavours/glitch/containers/theme_component.jsx => app/javascript/flavours/glitch/containers/theme_component.jsx +36 -0
@@ 0,0 1,36 @@
import PropTypes from 'prop-types';
import React from 'react';

import { useAppSelector } from 'flavours/glitch/store';

const ThemeComponent = ({ children }) => {
  const theme = useAppSelector(
    (state) => state.getIn(['local_settings', 'theme']) ?? 'mastodon-light',
  );

  let href;
  switch (true) {
  case theme === 'mastodon':
    href = '';
    break;
  case theme === 'mastodon-light':
    href = '/packs/css/skins/glitch/mastodon-light/common.css';
    break;
  case theme === 'contrast':
    href = '/packs/css/skins/glitch/contrast/common.css';
    break;
  }

  return (
    <>
      {href !== '' ? <link rel='stylesheet' media='all' href={href} /> : null}
      {children}
    </>
  );
};

ThemeComponent.propTypes = {
  children: PropTypes.node,
};

export { ThemeComponent };

M app/javascript/flavours/glitch/features/local_settings/page/index.jsx => app/javascript/flavours/glitch/features/local_settings/page/index.jsx +13 -0
@@ 54,6 54,19 @@ class LocalSettingsPage extends PureComponent {
        <h1><FormattedMessage id='settings.general' defaultMessage='General' /></h1>
        <LocalSettingsPageItem
          settings={settings}
          item={['theme']}
          id='mastodon-settings--theme'
          options={[
            { value: 'mastodon-light', message: 'Light' },
            { value: 'mastodon', message: 'Dark' },
            { value: 'contrast', message: 'High contrast' },
          ]}
          onChange={onChange}
        >
          <FormattedMessage id='settings.theme' defaultMessage='Theme' />
        </LocalSettingsPageItem>
        <LocalSettingsPageItem
          settings={settings}
          item={['show_reply_count']}
          id='mastodon-settings--reply-count'
          onChange={onChange}

M app/javascript/flavours/glitch/reducers/local_settings.js => app/javascript/flavours/glitch/reducers/local_settings.js +1 -0
@@ 62,6 62,7 @@ const initialState = ImmutableMap({
    media:      true,
    visibility: true,
  }),
  theme: 'mastodon-light',
});

const hydrate = (state, localSettings) => state.mergeDeep(localSettings);