about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/settings/preferences_controller.rb1
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/item/style.scss2
-rw-r--r--app/javascript/glitch/components/local_settings/navigation/style.scss2
-rw-r--r--app/javascript/glitch/components/local_settings/page/item/style.scss2
-rw-r--r--app/javascript/glitch/components/local_settings/page/style.scss2
-rw-r--r--app/javascript/glitch/components/local_settings/style.scss2
-rw-r--r--app/javascript/packs/application.js2
-rw-r--r--app/javascript/packs/frontends/mastodon.js16
-rw-r--r--app/javascript/styles/custom.scss1
-rw-r--r--app/javascript/themes/default/theme.yml9
-rw-r--r--app/javascript/themes/spin/pack.js2
-rw-r--r--app/javascript/themes/spin/style.scss14
-rw-r--r--app/javascript/themes/spin/theme.yml2
-rw-r--r--app/lib/themes.rb23
-rw-r--r--app/lib/user_settings_decorator.rb5
-rw-r--r--app/models/user.rb4
-rw-r--r--app/views/home/index.html.haml4
-rw-r--r--app/views/settings/preferences/show.html.haml2
19 files changed, 76 insertions, 25 deletions
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,