From d2352246920800e491466d84b0146feb4d1d791f Mon Sep 17 00:00:00 2001 From: kibigo! Date: Wed, 19 Jul 2017 19:54:02 -0700 Subject: Restructured local settings internals --- .../glitch/components/local_settings/page/index.js | 175 +++++++++++++++++++++ .../components/local_settings/page/item/index.js | 90 +++++++++++ .../components/local_settings/page/item/style.scss | 7 + .../components/local_settings/page/style.scss | 9 ++ 4 files changed, 281 insertions(+) create mode 100644 app/javascript/glitch/components/local_settings/page/index.js create mode 100644 app/javascript/glitch/components/local_settings/page/item/index.js create mode 100644 app/javascript/glitch/components/local_settings/page/item/style.scss create mode 100644 app/javascript/glitch/components/local_settings/page/style.scss (limited to 'app/javascript/glitch/components/local_settings/page') 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..8635b604f --- /dev/null +++ b/app/javascript/glitch/components/local_settings/page/index.js @@ -0,0 +1,175 @@ +// 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 }) => ( +
+

+ + + + + + +
+ ), + ({ onChange, settings }) => ( +
+

+ + + +
+

+ + + + + + + + + + + + + + + +
+
+

+ + + + + + +
+
+ ), + ({ onChange, settings }) => ( +
+

+ + + + + + +
+ ), + ]; + + render () { + const { pages } = this; + const { index, intl, onChange, settings } = this.props; + const CurrentPage = pages[index] || pages[0]; + + return ; + } + +} 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) => ( + + )); + return ( + + ); + } else return ( + + ); + } + +} 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; +} -- cgit From 74a0cc6a119f64ff368945523260408323b364e8 Mon Sep 17 00:00:00 2001 From: Ondřej Hruška Date: Sat, 22 Jul 2017 19:51:34 +0200 Subject: Added settings toggle to move the navbar at the bottom in mobile view (#93) --- app/javascript/glitch/components/local_settings/page/index.js | 8 ++++++++ app/javascript/glitch/locales/en.json | 1 + app/javascript/glitch/reducers/local_settings.js | 1 + app/javascript/mastodon/features/ui/index.js | 7 +++++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js index 8635b604f..cb041c0b8 100644 --- a/app/javascript/glitch/components/local_settings/page/index.js +++ b/app/javascript/glitch/components/local_settings/page/index.js @@ -53,6 +53,14 @@ export default class LocalSettingsPage extends React.PureComponent { > + + + ), ({ onChange, settings }) => ( diff --git a/app/javascript/glitch/locales/en.json b/app/javascript/glitch/locales/en.json index d202d9c33..21616f556 100644 --- a/app/javascript/glitch/locales/en.json +++ b/app/javascript/glitch/locales/en.json @@ -26,6 +26,7 @@ "settings.media_fullwidth": "Full-width media previews", "settings.preferences": "User preferences", "settings.wide_view": "Wide view (Desktop mode only)", + "settings.navbar_under": "Navbar at the bottom (Mobile only)", "status.collapse": "Collapse", "status.uncollapse": "Uncollapse", "notification.markForDeletion": "Mark for deletion" diff --git a/app/javascript/glitch/reducers/local_settings.js b/app/javascript/glitch/reducers/local_settings.js index 35a8e065b..386d59ceb 100644 --- a/app/javascript/glitch/reducers/local_settings.js +++ b/app/javascript/glitch/reducers/local_settings.js @@ -51,6 +51,7 @@ These are only used if no previously-saved values exist. const initialState = ImmutableMap({ layout : 'auto', stretch : true, + navbar_under : false, collapsed : ImmutableMap({ enabled : true, auto : ImmutableMap({ diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 1edc7504c..bda32781c 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -45,6 +45,7 @@ const mapStateToProps = state => ({ systemFontUi: state.getIn(['meta', 'system_font_ui']), layout: state.getIn(['local_settings', 'layout']), isWide: state.getIn(['local_settings', 'stretch']), + navbarUnder: state.getIn(['local_settings', 'navbar_under']), isComposing: state.getIn(['compose', 'is_composing']), }); @@ -57,6 +58,7 @@ export default class UI extends React.PureComponent { layout: PropTypes.string, isWide: PropTypes.bool, systemFontUi: PropTypes.bool, + navbarUnder: PropTypes.bool, isComposing: PropTypes.bool, }; @@ -167,7 +169,7 @@ export default class UI extends React.PureComponent { render () { const { width, draggingOver } = this.state; - const { children, layout, isWide } = this.props; + const { children, layout, isWide, navbarUnder } = this.props; const columnsClass = layout => { switch (layout) { @@ -187,7 +189,7 @@ export default class UI extends React.PureComponent { return (
- + {navbarUnder ? null : ()} @@ -218,6 +220,7 @@ export default class UI extends React.PureComponent { + {navbarUnder ? () : null} -- cgit From 67f82775268f57be5506031e65e3155a2618bef9 Mon Sep 17 00:00:00 2001 From: Ondřej Hruška Date: Sat, 23 Sep 2017 23:11:02 +0200 Subject: Add secondary toot button (opt-in) (#153) Add secondary toot button + other toot button enhancements. Squashing so it's easy to revert if needed. --- .../glitch/components/local_settings/page/index.js | 19 +++++++ app/javascript/glitch/reducers/local_settings.js | 1 + .../features/compose/components/compose_form.js | 66 ++++++++++++++++++++-- .../compose/containers/compose_form_container.js | 7 ++- app/javascript/styles/components.scss | 18 ++++++ 5 files changed, 104 insertions(+), 7 deletions(-) (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js index cb041c0b8..338d86333 100644 --- a/app/javascript/glitch/components/local_settings/page/index.js +++ b/app/javascript/glitch/components/local_settings/page/index.js @@ -16,6 +16,7 @@ const messages = defineMessages({ layout_auto: { id: 'layout.auto', defaultMessage: 'Auto' }, layout_desktop: { id: 'layout.desktop', defaultMessage: 'Desktop' }, layout_mobile: { id: 'layout.single', defaultMessage: 'Mobile' }, + side_arm_none: { id: 'settings.side_arm.none', defaultMessage: 'None' }, }); @injectIntl @@ -61,6 +62,24 @@ export default class LocalSettingsPage extends React.PureComponent { > +
+

+ + + +
), ({ onChange, settings }) => ( diff --git a/app/javascript/glitch/reducers/local_settings.js b/app/javascript/glitch/reducers/local_settings.js index 386d59ceb..813e130ca 100644 --- a/app/javascript/glitch/reducers/local_settings.js +++ b/app/javascript/glitch/reducers/local_settings.js @@ -52,6 +52,7 @@ const initialState = ImmutableMap({ layout : 'auto', stretch : true, navbar_under : false, + side_arm : 'none', collapsed : ImmutableMap({ enabled : true, auto : ImmutableMap({ diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index f6b5cf0be..1d60ffe83 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -51,11 +51,13 @@ export default class ComposeForm extends ImmutablePureComponent { onSubmit: PropTypes.func.isRequired, onClearSuggestions: PropTypes.func.isRequired, onFetchSuggestions: PropTypes.func.isRequired, + onPrivacyChange: PropTypes.func.isRequired, onSuggestionSelected: PropTypes.func.isRequired, onChangeSpoilerText: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired, onPickEmoji: PropTypes.func.isRequired, showSearch: PropTypes.bool, + settings : ImmutablePropTypes.map.isRequired, }; static defaultProps = { @@ -72,6 +74,11 @@ export default class ComposeForm extends ImmutablePureComponent { } } + handleSubmit2 = () => { + this.props.onPrivacyChange(this.props.settings.get('side_arm')); + this.handleSubmit(); + } + handleSubmit = () => { if (this.props.text !== this.autosuggestTextarea.textarea.value) { // Something changed the text inside the textarea (e.g. browser extensions like Grammarly) @@ -157,13 +164,42 @@ export default class ComposeForm extends ImmutablePureComponent { const maybeEye = (this.props.advanced_options && this.props.advanced_options.do_not_federate) ? ' 👁️' : ''; const text = [this.props.spoiler_text, countableText(this.props.text), maybeEye].join(''); + const sideArmVisibility = this.props.settings.get('side_arm'); + let showSideArm = sideArmVisibility !== 'none'; + let publishText = ''; - if (this.props.privacy === 'private' || this.props.privacy === 'direct') { - publishText = {intl.formatMessage(messages.publish)}; - } else { - publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish); - } + const privacyIcons = { + none: '', + public: 'globe', + unlisted: 'unlock-alt', + private: 'lock', + direct: 'envelope', + }; + + publishText = ( + + { + (this.props.settings.get('stretch') || !showSideArm) ? + : + '' + } + {intl.formatMessage(messages.publish)} + + ); + + // side-arm + let publishText2 = ( + + ); + + const submitDisabled = disabled || this.props.is_uploading || length(text) > 500 || (text.length !== 0 && text.trim().length === 0); return (
@@ -215,7 +251,25 @@ export default class ComposeForm extends ImmutablePureComponent {
-
+
+ { + showSideArm ? +
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index 1911edbf9..4e8cd2279 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import ComposeForm from '../components/compose_form'; -import { uploadCompose } from '../../../actions/compose'; +import { changeComposeVisibility, uploadCompose } from '../../../actions/compose'; import { changeCompose, submitCompose, @@ -25,6 +25,7 @@ const mapStateToProps = state => ({ is_uploading: state.getIn(['compose', 'is_uploading']), me: state.getIn(['compose', 'me']), showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), + settings: state.get('local_settings'), }); const mapDispatchToProps = (dispatch) => ({ @@ -33,6 +34,10 @@ const mapDispatchToProps = (dispatch) => ({ dispatch(changeCompose(text)); }, + onPrivacyChange (value) { + dispatch(changeComposeVisibility(value)); + }, + onSubmit () { dispatch(submitCompose()); }, diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index f087adf9c..2639fd41e 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -421,6 +421,24 @@ .compose-form__publish-button-wrapper { overflow: hidden; padding-top: 10px; + white-space: nowrap; + display: flex; + + button { + text-overflow: unset; + } +} + +.compose-form__publish__side-arm { + padding: 0 !important; + width: 4em; + text-align: center; + opacity: .8; + margin-right: 2px; +} + +.compose-form__publish__primary { + padding: 0 10px !important; } .emojione { -- cgit From 86e617a839bd4eb45ace52ab226a4e93bb184ff0 Mon Sep 17 00:00:00 2001 From: kibigo! Date: Mon, 25 Sep 2017 19:24:32 -0700 Subject: Better themeing support!! --- app/controllers/application_controller.rb | 6 ++++ app/controllers/settings/preferences_controller.rb | 1 + .../local_settings/navigation/item/style.scss | 2 +- .../local_settings/navigation/style.scss | 2 +- .../components/local_settings/page/item/style.scss | 2 +- .../components/local_settings/page/style.scss | 2 +- .../glitch/components/local_settings/style.scss | 2 +- app/javascript/packs/application.js | 2 +- app/javascript/packs/frontends/mastodon.js | 16 ---------- app/javascript/styles/custom.scss | 1 - app/javascript/themes/default/theme.yml | 9 ++++++ app/javascript/themes/spin/pack.js | 2 ++ app/javascript/themes/spin/style.scss | 14 ++++++++ app/javascript/themes/spin/theme.yml | 2 ++ app/lib/themes.rb | 23 ++++++++++++++ app/lib/user_settings_decorator.rb | 5 +++ app/models/user.rb | 4 +++ app/views/home/index.html.haml | 4 +-- app/views/settings/preferences/show.html.haml | 2 ++ config/initializers/frontends.rb | 7 ---- config/locales/simple_form.en.yml | 2 ++ config/settings.yml | 1 + config/webpack/configuration.js | 17 +++++++++- config/webpack/loaders/sass.js | 2 +- config/webpack/shared.js | 37 ++++++++++++---------- 25 files changed, 117 insertions(+), 50 deletions(-) delete mode 100644 app/javascript/packs/frontends/mastodon.js delete mode 100644 app/javascript/styles/custom.scss create mode 100644 app/javascript/themes/default/theme.yml create mode 100644 app/javascript/themes/spin/pack.js create mode 100644 app/javascript/themes/spin/style.scss create mode 100644 app/javascript/themes/spin/theme.yml create mode 100644 app/lib/themes.rb delete mode 100644 config/initializers/frontends.rb (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0b40fb05b..d5eca6ffb 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,6 +12,7 @@ class ApplicationController < ActionController::Base helper_method :current_account helper_method :current_session + helper_method :current_theme helper_method :single_user_mode? rescue_from ActionController::RoutingError, with: :not_found @@ -77,6 +78,11 @@ class ApplicationController < ActionController::Base @current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id']) end + def current_theme + return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme + current_user.setting_theme + end + def cache_collection(raw, klass) return raw unless klass.respond_to?(:with_includes) diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index f107f2b16..207c7b324 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -41,6 +41,7 @@ class Settings::PreferencesController < ApplicationController :setting_auto_play_gif, :setting_system_font_ui, :setting_noindex, + :setting_theme, notification_emails: %i(follow follow_request reblog favourite mention digest), interactions: %i(must_be_follower must_be_following) ) diff --git a/app/javascript/glitch/components/local_settings/navigation/item/style.scss b/app/javascript/glitch/components/local_settings/navigation/item/style.scss index 505c86912..33d7d3744 100644 --- a/app/javascript/glitch/components/local_settings/navigation/item/style.scss +++ b/app/javascript/glitch/components/local_settings/navigation/item/style.scss @@ -1,4 +1,4 @@ -@import 'variables'; +@import 'styles/variables'; .glitch.local-settings__navigation__item { display: block; diff --git a/app/javascript/glitch/components/local_settings/navigation/style.scss b/app/javascript/glitch/components/local_settings/navigation/style.scss index 1cc39e3e9..a610a1212 100644 --- a/app/javascript/glitch/components/local_settings/navigation/style.scss +++ b/app/javascript/glitch/components/local_settings/navigation/style.scss @@ -1,4 +1,4 @@ -@import 'variables'; +@import 'styles/variables'; .glitch.local-settings__navigation { background: $primary-text-color; diff --git a/app/javascript/glitch/components/local_settings/page/item/style.scss b/app/javascript/glitch/components/local_settings/page/item/style.scss index e614030c0..da1941b99 100644 --- a/app/javascript/glitch/components/local_settings/page/item/style.scss +++ b/app/javascript/glitch/components/local_settings/page/item/style.scss @@ -1,4 +1,4 @@ -@import 'variables'; +@import 'styles/variables'; .glitch.local-settings__page__item { select { diff --git a/app/javascript/glitch/components/local_settings/page/style.scss b/app/javascript/glitch/components/local_settings/page/style.scss index 7269056c3..53c95ea40 100644 --- a/app/javascript/glitch/components/local_settings/page/style.scss +++ b/app/javascript/glitch/components/local_settings/page/style.scss @@ -1,4 +1,4 @@ -@import 'variables'; +@import 'styles/variables'; .glitch.local-settings__page { display: block; diff --git a/app/javascript/glitch/components/local_settings/style.scss b/app/javascript/glitch/components/local_settings/style.scss index 6f7fcbaa4..54fec47bd 100644 --- a/app/javascript/glitch/components/local_settings/style.scss +++ b/app/javascript/glitch/components/local_settings/style.scss @@ -1,4 +1,4 @@ -@import 'variables'; +@import 'styles/variables'; .glitch.local-settings { position: relative; diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index c06714dc1..aa94006c6 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -2,7 +2,7 @@ import loadPolyfills from '../mastodon/load_polyfills'; // import default stylesheet with variables require('font-awesome/css/font-awesome.css'); -require('mastodon-application-style'); +import 'styles/application'; require.context('../images/', true); diff --git a/app/javascript/packs/frontends/mastodon.js b/app/javascript/packs/frontends/mastodon.js deleted file mode 100644 index a983de36f..000000000 --- a/app/javascript/packs/frontends/mastodon.js +++ /dev/null @@ -1,16 +0,0 @@ -// This file replaces `app/javascript/packs/application.js` for use -// with multiple frontends. - -import loadPolyfills from '../../mastodon/load_polyfills'; - -// import default stylesheet with variables -require('font-awesome/css/font-awesome.css'); -require('mastodon-application-style'); - -require.context('../../images/', true); - -loadPolyfills().then(() => { - require('../../mastodon/main').default(); -}).catch(e => { - console.error(e); -}); diff --git a/app/javascript/styles/custom.scss b/app/javascript/styles/custom.scss deleted file mode 100644 index 97a981243..000000000 --- a/app/javascript/styles/custom.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'application'; diff --git a/app/javascript/themes/default/theme.yml b/app/javascript/themes/default/theme.yml new file mode 100644 index 000000000..6a7a872b4 --- /dev/null +++ b/app/javascript/themes/default/theme.yml @@ -0,0 +1,9 @@ +# (REQUIRED) Name must be unique across all installed themes. +name: default + +# (REQUIRED) The location of the pack file inside `pack_directory`. +pack: application.js + +# (OPTIONAL) The directory which contains the pack file. +# Defaults to the theme directory (`app/javascript/themes/[theme]`). +pack_directory: app/javascript/packs diff --git a/app/javascript/themes/spin/pack.js b/app/javascript/themes/spin/pack.js new file mode 100644 index 000000000..dab0e93a4 --- /dev/null +++ b/app/javascript/themes/spin/pack.js @@ -0,0 +1,2 @@ +import 'packs/application'; +import 'themes/spin/style'; diff --git a/app/javascript/themes/spin/style.scss b/app/javascript/themes/spin/style.scss new file mode 100644 index 000000000..1a9381fd0 --- /dev/null +++ b/app/javascript/themes/spin/style.scss @@ -0,0 +1,14 @@ +:root:root:root { + .button, .icon-button, .emoji-button, .account__avatar, .account__avatar-overlay { + animation: spin 4s linear infinite; + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/app/javascript/themes/spin/theme.yml b/app/javascript/themes/spin/theme.yml new file mode 100644 index 000000000..a684997dc --- /dev/null +++ b/app/javascript/themes/spin/theme.yml @@ -0,0 +1,2 @@ +name: spin +pack: pack.js \ No newline at end of file diff --git a/app/lib/themes.rb b/app/lib/themes.rb new file mode 100644 index 000000000..2dd188297 --- /dev/null +++ b/app/lib/themes.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'singleton' +require 'yaml' + +class Themes + include Singleton + + def initialize + result = Hash.new + Dir.glob(Rails.root.join('app', 'javascript', 'themes', '*', 'theme.yml')) do |path| + data = YAML.load_file(path) + if data['pack'] && data['name'] + result[data['name']] = data + end + end + @conf = result + end + + def names + @conf.keys + end +end diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 62046ed72..3b156b98c 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -25,6 +25,7 @@ class UserSettingsDecorator user.settings['auto_play_gif'] = auto_play_gif_preference user.settings['system_font_ui'] = system_font_ui_preference user.settings['noindex'] = noindex_preference + user.settings['theme'] = theme_preference end def merged_notification_emails @@ -67,6 +68,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_noindex' end + def theme_preference + settings['setting_theme'] + end + def boolean_cast_setting(key) settings[key] == '1' end diff --git a/app/models/user.rb b/app/models/user.rb index 5e548c1ef..3bf069a31 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -110,6 +110,10 @@ class User < ApplicationRecord settings.noindex end + def setting_theme + settings.theme + end + def token_for_app(a) return nil if a.nil? || a.owner != self Doorkeeper::AccessToken diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index a13d0702b..3b4219c56 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -2,8 +2,8 @@ %meta{name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key} %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) - = javascript_pack_tag "frontends/#{@frontend}", integrity: true, crossorigin: 'anonymous' - = stylesheet_pack_tag "frontends/#{@frontend}", integrity: true, media: 'all' + = javascript_pack_tag "themes/#{current_theme}", integrity: true, crossorigin: 'anonymous' + = stylesheet_pack_tag "themes/#{current_theme}", integrity: true, media: 'all' .app-holder#mastodon{ data: { props: Oj.dump(default_props) } } %noscript diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index f42f92508..5efd538e4 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -5,6 +5,8 @@ = render 'shared/error_messages', object: current_user .fields-group + = f.input :setting_theme, collection: Themes.instance.names, label_method: lambda { |theme| safe_join([I18n.t("themes.#{theme}", default: theme)])}, wrapper: :with_label, include_blank: false + = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, diff --git a/config/initializers/frontends.rb b/config/initializers/frontends.rb deleted file mode 100644 index 2cb68cc61..000000000 --- a/config/initializers/frontends.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Rails.application.configure do - frontends = [] - Rails.root.join('app', 'javascript', 'packs', 'frontends').each_child(false) { |f| frontends.push f.to_s } - config.x.available_frontends = frontends -end diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index fb8524a24..f9d4e2e52 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -13,6 +13,7 @@ en: one: 1 character left other: %{count} characters left setting_noindex: Affects your public profile and status pages + setting_theme: Affects how Mastodon looks when you're logged in from any device. imports: data: CSV file exported from another Mastodon instance sessions: @@ -44,6 +45,7 @@ en: setting_noindex: Opt-out of search engine indexing setting_system_font_ui: Use system's default font setting_unfollow_modal: Show confirmation dialog before unfollowing someone + setting_theme: Site theme severity: Severity type: Import type username: Username diff --git a/config/settings.yml b/config/settings.yml index 39dfb8f55..3cd3307f4 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -24,6 +24,7 @@ defaults: &defaults auto_play_gif: false system_font_ui: false noindex: false + theme: 'default' notification_emails: follow: false reblog: false diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js index 6ef484c3a..606eb97f1 100644 --- a/config/webpack/configuration.js +++ b/config/webpack/configuration.js @@ -1,13 +1,27 @@ // Common configuration for webpacker loaded from config/webpacker.yml -const { join, resolve } = require('path'); +const { dirname, join, resolve } = require('path'); const { env } = require('process'); const { safeLoad } = require('js-yaml'); const { readFileSync } = require('fs'); +const glob = require('glob'); const configPath = resolve('config', 'webpacker.yml'); const loadersDir = join(__dirname, 'loaders'); const settings = safeLoad(readFileSync(configPath), 'utf8')[env.NODE_ENV]; +const themeFiles = glob.sync('app/javascript/themes/*/theme.yml'); +const themes = {}; + +for (let i = 0; i < themeFiles.length; i++) { + const themeFile = themeFiles[i]; + const data = safeLoad(readFileSync(themeFile), 'utf8'); + if (!data.pack_directory) { + data.pack_directory = dirname(themeFile); + } + if (data.name && data.pack) { + themes[data.name] = data; + } +} function removeOuterSlashes(string) { return string.replace(/^\/*/, '').replace(/\/*$/, ''); @@ -29,6 +43,7 @@ const output = { module.exports = { settings, + themes, env, loadersDir, output, diff --git a/config/webpack/loaders/sass.js b/config/webpack/loaders/sass.js index 40e81b43b..96ad7abe8 100644 --- a/config/webpack/loaders/sass.js +++ b/config/webpack/loaders/sass.js @@ -9,7 +9,7 @@ module.exports = { { loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } }, { loader: 'postcss-loader', options: { sourceMap: true } }, 'resolve-url-loader', - { loader: 'sass-loader', options: { includePaths: ['app/javascript/styles'] } }, + { loader: 'sass-loader', options: { includePaths: ['app/javascript'] } }, ], }), }; diff --git a/config/webpack/shared.js b/config/webpack/shared.js index be1b49421..ab925b020 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -1,13 +1,12 @@ // Note: You must restart bin/webpack-dev-server for changes to take effect -const { existsSync } = require('fs'); const webpack = require('webpack'); const { basename, dirname, join, relative, resolve } = require('path'); const { sync } = require('glob'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const extname = require('path-complete-extname'); -const { env, settings, output, loadersDir } = require('./configuration.js'); +const { env, settings, themes, output, loadersDir } = require('./configuration.js'); const localePackPaths = require('./generateLocalePacks'); const extensionGlob = `**/*{${settings.extensions.join(',')}}*`; @@ -18,17 +17,27 @@ const entryPacks = [...packPaths, ...localePackPaths].filter(path => path !== jo const customApplicationStyle = resolve(join(settings.source_path, 'styles/custom.scss')); const originalApplicationStyle = resolve(join(settings.source_path, 'styles/application.scss')); +const themePaths = Object.keys(themes).reduce( + (themePaths, name) => { + themeData = themes[name]; + themePaths[`themes/${name}`] = resolve(themeData.pack_directory, themeData.pack); + return themePaths; + }, {} +); + module.exports = { - entry: entryPacks.reduce( - (map, entry) => { - const localMap = map; - let namespace = relative(join(entryPath), dirname(entry)); - if (namespace === join('..', '..', '..', 'tmp', 'packs')) { - namespace = ''; // generated by generateLocalePacks.js - } - localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry); - return localMap; - }, {} + entry: Object.assign( + entryPacks.reduce( + (map, entry) => { + const localMap = map; + let namespace = relative(join(entryPath), dirname(entry)); + if (namespace === join('..', '..', '..', 'tmp', 'packs')) { + namespace = ''; // generated by generateLocalePacks.js + } + localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry); + return localMap; + }, {} + ), themePaths ), output: { @@ -59,10 +68,6 @@ module.exports = { ], resolve: { - alias: { - 'mastodon-application-style': existsSync(customApplicationStyle) ? - customApplicationStyle : originalApplicationStyle, - }, extensions: settings.extensions, modules: [ resolve(settings.source_path), -- cgit From 37ff061d9bf0a91da6580960be01e3c6bc5e5c4c Mon Sep 17 00:00:00 2001 From: Ondřej Hruška Date: Mon, 16 Oct 2017 22:24:44 +0200 Subject: satisfy eslint and jest --- app/javascript/glitch/components/account/header.js | 2 +- app/javascript/glitch/components/local_settings/container.js | 4 ++-- app/javascript/glitch/components/local_settings/index.js | 2 +- app/javascript/glitch/components/local_settings/navigation/index.js | 2 +- .../glitch/components/local_settings/navigation/item/index.js | 2 +- app/javascript/glitch/components/local_settings/page/index.js | 2 +- app/javascript/glitch/components/local_settings/page/item/index.js | 2 +- .../mastodon/components/__tests__/__snapshots__/avatar-test.js.snap | 2 ++ .../components/__tests__/__snapshots__/avatar_overlay-test.js.snap | 2 ++ app/javascript/packs/application.js | 3 ++- app/javascript/themes/spin/pack.js | 4 ++-- 11 files changed, 16 insertions(+), 11 deletions(-) (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/javascript/glitch/components/account/header.js b/app/javascript/glitch/components/account/header.js index 6359c1775..f4a413aa3 100644 --- a/app/javascript/glitch/components/account/header.js +++ b/app/javascript/glitch/components/account/header.js @@ -48,7 +48,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; // Mastodon imports // -import emojify from 'mastodon/features/emoji/emoji'; +import emojify from '../../../mastodon/features/emoji/emoji'; import IconButton from '../../../mastodon/components/icon_button'; import Avatar from '../../../mastodon/components/avatar'; diff --git a/app/javascript/glitch/components/local_settings/container.js b/app/javascript/glitch/components/local_settings/container.js index 6c202a4e7..4569db99f 100644 --- a/app/javascript/glitch/components/local_settings/container.js +++ b/app/javascript/glitch/components/local_settings/container.js @@ -2,10 +2,10 @@ import { connect } from 'react-redux'; // Mastodon imports // -import { closeModal } from 'mastodon/actions/modal'; +import { closeModal } from '../../../mastodon/actions/modal'; // Our imports // -import { changeLocalSetting } from 'glitch/actions/local_settings'; +import { changeLocalSetting } from '../../../glitch/actions/local_settings'; import LocalSettings from '.'; const mapStateToProps = state => ({ diff --git a/app/javascript/glitch/components/local_settings/index.js b/app/javascript/glitch/components/local_settings/index.js index 7f7b93de4..ef711229a 100644 --- a/app/javascript/glitch/components/local_settings/index.js +++ b/app/javascript/glitch/components/local_settings/index.js @@ -8,7 +8,7 @@ import LocalSettingsPage from './page'; import LocalSettingsNavigation from './navigation'; // Stylesheet imports -import './style'; +import './style.scss'; export default class LocalSettings extends React.PureComponent { diff --git a/app/javascript/glitch/components/local_settings/navigation/index.js b/app/javascript/glitch/components/local_settings/navigation/index.js index 1f72cc824..fa35e83c7 100644 --- a/app/javascript/glitch/components/local_settings/navigation/index.js +++ b/app/javascript/glitch/components/local_settings/navigation/index.js @@ -7,7 +7,7 @@ import { injectIntl, defineMessages } from 'react-intl'; import LocalSettingsNavigationItem from './item'; // Stylesheet imports -import './style'; +import './style.scss'; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/app/javascript/glitch/components/local_settings/navigation/item/index.js b/app/javascript/glitch/components/local_settings/navigation/item/index.js index 1676aa404..a352d5fb2 100644 --- a/app/javascript/glitch/components/local_settings/navigation/item/index.js +++ b/app/javascript/glitch/components/local_settings/navigation/item/index.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; // Stylesheet imports -import './style'; +import './style.scss'; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js index 338d86333..366c113c0 100644 --- a/app/javascript/glitch/components/local_settings/page/index.js +++ b/app/javascript/glitch/components/local_settings/page/index.js @@ -8,7 +8,7 @@ import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; import LocalSettingsPageItem from './item'; // Stylesheet imports -import './style'; +import './style.scss'; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/app/javascript/glitch/components/local_settings/page/item/index.js b/app/javascript/glitch/components/local_settings/page/item/index.js index 326c7eeb0..37e28c084 100644 --- a/app/javascript/glitch/components/local_settings/page/item/index.js +++ b/app/javascript/glitch/components/local_settings/page/item/index.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; // Stylesheet imports -import './style'; +import './style.scss'; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap index 76ab3374a..4005c860f 100644 --- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap +++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap @@ -3,6 +3,7 @@ exports[` Autoplay renders a animated avatar 1`] = `
Autoplay renders a animated avatar 1`] = ` exports[` Still renders a still avatar 1`] = `
Date: Wed, 18 Oct 2017 11:52:34 -0500 Subject: Update stylesheet imports in glitch components. Commit 6e5471947438fc5883e72b8184663564ffadee28 moved the Mastodon variables and mixins deeper in the directory hierarchy; this commit brings the glitch components in line with that change. --- .../glitch/components/local_settings/navigation/item/style.scss | 2 +- app/javascript/glitch/components/local_settings/navigation/style.scss | 2 +- app/javascript/glitch/components/local_settings/page/item/style.scss | 2 +- app/javascript/glitch/components/local_settings/page/style.scss | 2 +- app/javascript/glitch/components/local_settings/style.scss | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/javascript/glitch/components/local_settings/navigation/item/style.scss b/app/javascript/glitch/components/local_settings/navigation/item/style.scss index 33d7d3744..7f7371993 100644 --- a/app/javascript/glitch/components/local_settings/navigation/item/style.scss +++ b/app/javascript/glitch/components/local_settings/navigation/item/style.scss @@ -1,4 +1,4 @@ -@import 'styles/variables'; +@import 'styles/mastodon/variables'; .glitch.local-settings__navigation__item { display: block; diff --git a/app/javascript/glitch/components/local_settings/navigation/style.scss b/app/javascript/glitch/components/local_settings/navigation/style.scss index a610a1212..0336f943b 100644 --- a/app/javascript/glitch/components/local_settings/navigation/style.scss +++ b/app/javascript/glitch/components/local_settings/navigation/style.scss @@ -1,4 +1,4 @@ -@import 'styles/variables'; +@import 'styles/mastodon/variables'; .glitch.local-settings__navigation { background: $primary-text-color; diff --git a/app/javascript/glitch/components/local_settings/page/item/style.scss b/app/javascript/glitch/components/local_settings/page/item/style.scss index da1941b99..b2d8f7185 100644 --- a/app/javascript/glitch/components/local_settings/page/item/style.scss +++ b/app/javascript/glitch/components/local_settings/page/item/style.scss @@ -1,4 +1,4 @@ -@import 'styles/variables'; +@import 'styles/mastodon/variables'; .glitch.local-settings__page__item { select { diff --git a/app/javascript/glitch/components/local_settings/page/style.scss b/app/javascript/glitch/components/local_settings/page/style.scss index 53c95ea40..e9eedcad0 100644 --- a/app/javascript/glitch/components/local_settings/page/style.scss +++ b/app/javascript/glitch/components/local_settings/page/style.scss @@ -1,4 +1,4 @@ -@import 'styles/variables'; +@import 'styles/mastodon/variables'; .glitch.local-settings__page { display: block; diff --git a/app/javascript/glitch/components/local_settings/style.scss b/app/javascript/glitch/components/local_settings/style.scss index 54fec47bd..765294607 100644 --- a/app/javascript/glitch/components/local_settings/style.scss +++ b/app/javascript/glitch/components/local_settings/style.scss @@ -1,4 +1,4 @@ -@import 'styles/variables'; +@import 'styles/mastodon/variables'; .glitch.local-settings { position: relative; -- cgit From e0298d66f8f807efe80cb01097b46e0ef33bd154 Mon Sep 17 00:00:00 2001 From: kibigo! Date: Sun, 5 Nov 2017 15:05:12 -0800 Subject: Autocollapse boosts option --- app/javascript/glitch/components/local_settings/page/index.js | 10 ++++++++++ app/javascript/glitch/components/status/index.js | 4 ++++ app/javascript/glitch/locales/en.json | 1 + app/javascript/glitch/reducers/local_settings.js | 1 + 4 files changed, 16 insertions(+) (limited to 'app/javascript/glitch/components/local_settings/page') diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js index 366c113c0..498230f7b 100644 --- a/app/javascript/glitch/components/local_settings/page/index.js +++ b/app/javascript/glitch/components/local_settings/page/index.js @@ -124,6 +124,16 @@ export default class LocalSettingsPage extends React.PureComponent { > + + + ( status.get('media_attachments').size && !muted ? 650 : 400 ) + ) || ( + autoCollapseSettings.get('reblogs') && + prepend === 'reblogged_by' ) || ( autoCollapseSettings.get('replies') && status.get('in_reply_to_id', null) !== null diff --git a/app/javascript/glitch/locales/en.json b/app/javascript/glitch/locales/en.json index 18e412356..69aa29108 100644 --- a/app/javascript/glitch/locales/en.json +++ b/app/javascript/glitch/locales/en.json @@ -14,6 +14,7 @@ "settings.auto_collapse_lengthy": "Lengthy toots", "settings.auto_collapse_media": "Toots with media", "settings.auto_collapse_notifications": "Notifications", + "settings.auto_collapse_reblogs": "Boosts", "settings.auto_collapse_replies": "Replies", "settings.close": "Close", "settings.collapsed_statuses": "Collapsed toots", diff --git a/app/javascript/glitch/reducers/local_settings.js b/app/javascript/glitch/reducers/local_settings.js index 813e130ca..03654fbe2 100644 --- a/app/javascript/glitch/reducers/local_settings.js +++ b/app/javascript/glitch/reducers/local_settings.js @@ -59,6 +59,7 @@ const initialState = ImmutableMap({ all : false, notifications : true, lengthy : true, + reblogs : false, replies : false, media : false, }), -- cgit