diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c76110dba7..cf953fcf2c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -19,6 +19,7 @@ class ApplicationController < ActionController::Base helper_method :current_session helper_method :current_flavour helper_method :current_skin + helper_method :current_theme helper_method :single_user_mode? helper_method :use_seamless_external_login? helper_method :omniauth_only? diff --git a/app/controllers/concerns/theming_concern.rb b/app/controllers/concerns/theming_concern.rb index 9ef436ba8a..7da04e1531 100644 --- a/app/controllers/concerns/theming_concern.rb +++ b/app/controllers/concerns/theming_concern.rb @@ -4,7 +4,7 @@ module ThemingConcern extend ActiveSupport::Concern def use_pack(pack_name) - @theme = resolve_pack_with_common(Themes.instance.flavour(current_flavour), pack_name, current_skin) + @theme = resolve_pack(Themes.instance.flavour(current_flavour), pack_name) end private @@ -18,29 +18,22 @@ module ThemingConcern [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } end - def valid_pack_data?(data, pack_name) - data['pack'].is_a?(Hash) && data['pack'][pack_name].present? + def current_theme + # NOTE: this is slightly different from upstream, as it's a derived value used + # for the sole purpose of pointing to the appropriate stylesheet pack + "skins/#{current_flavour}/#{current_skin}" end - def nil_pack(data) - { + def resolve_pack(data, pack_name) + pack_data = { flavour: data['name'], pack: nil, preload: nil, - skin: nil, - supported_locales: data['locales'], - } - end - - def pack(data, pack_name, skin) - pack_data = { - flavour: data['name'], - pack: pack_name, - preload: nil, - skin: nil, supported_locales: data['locales'], } + return pack_data unless data['pack'].is_a?(Hash) && data['pack'][pack_name].present? + pack_data[:pack] = pack_name return pack_data unless data['pack'][pack_name].is_a?(Hash) pack_data[:pack] = nil unless data['pack'][pack_name]['filename'] @@ -49,22 +42,6 @@ module ThemingConcern pack_data[:preload] = [preloads] if preloads.is_a?(String) pack_data[:preload] = preloads if preloads.is_a?(Array) - if skin != 'default' && data['skin'][skin] - pack_data[:skin] = skin if data['skin'][skin].include?(pack_name) - elsif data['pack'][pack_name]['stylesheet'] - pack_data[:skin] = 'default' - end - pack_data end - - def resolve_pack(data, pack_name, skin) - pack(data, pack_name, skin) if valid_pack_data?(data, pack_name) - end - - def resolve_pack_with_common(data, pack_name, skin = 'default') - result = resolve_pack(data, pack_name, skin) || nil_pack(data) - result[:common] = resolve_pack(data, 'common', skin) - result - end end diff --git a/app/javascript/flavours/glitch/common.js b/app/javascript/flavours/glitch/common.js new file mode 100644 index 0000000000..40a324a59b --- /dev/null +++ b/app/javascript/flavours/glitch/common.js @@ -0,0 +1,12 @@ +import Rails from '@rails/ujs'; +import 'font-awesome/css/font-awesome.css'; + +export function start() { + require.context('@/images/', true); + + try { + Rails.start(); + } catch (e) { + // If called twice + } +} diff --git a/app/javascript/flavours/glitch/packs/application.js b/app/javascript/flavours/glitch/packs/application.js index 842430354d..336a250f54 100644 --- a/app/javascript/flavours/glitch/packs/application.js +++ b/app/javascript/flavours/glitch/packs/application.js @@ -1,8 +1,12 @@ import 'packs/public-path'; + +import { start } from 'flavours/glitch/common'; import { loadLocale } from 'flavours/glitch/locales'; import main from "flavours/glitch/main"; import { loadPolyfills } from 'flavours/glitch/polyfills'; +start(); + loadPolyfills() .then(loadLocale) .then(main) diff --git a/app/javascript/flavours/glitch/packs/common.js b/app/javascript/flavours/glitch/packs/common.js index 48e414909d..79467fc493 100644 --- a/app/javascript/flavours/glitch/packs/common.js +++ b/app/javascript/flavours/glitch/packs/common.js @@ -1,9 +1,8 @@ +/* This file is a hack to have something more reliable than the upstream `common` tag + that is implicitly generated as the common chunk through webpack's `splitChunks` config */ + import 'packs/public-path'; import 'font-awesome/css/font-awesome.css'; -import Rails from '@rails/ujs'; -import 'flavours/glitch/styles/index.scss'; -Rails.start(); - -// This ensures that webpack compiles our images. +// This is a hack to ensures that webpack compiles our images. require.context('../images', true); diff --git a/app/javascript/flavours/glitch/packs/public.tsx b/app/javascript/flavours/glitch/packs/public.tsx index db6edfdc98..6087f7b7c1 100644 --- a/app/javascript/flavours/glitch/packs/public.tsx +++ b/app/javascript/flavours/glitch/packs/public.tsx @@ -10,6 +10,7 @@ import Rails from '@rails/ujs'; import axios from 'axios'; import { throttle } from 'lodash'; +import { start } from 'flavours/glitch/common'; import { timeAgoString } from 'flavours/glitch/components/relative_timestamp'; import emojify from 'flavours/glitch/features/emoji/emoji'; import loadKeyboardExtensions from 'flavours/glitch/load_keyboard_extensions'; @@ -19,6 +20,8 @@ import ready from 'flavours/glitch/ready'; import 'cocoon-js-vanilla'; +start(); + const messages = defineMessages({ usernameTaken: { id: 'username.taken', diff --git a/app/javascript/flavours/glitch/packs/share.jsx b/app/javascript/flavours/glitch/packs/share.jsx index 7a4e333653..3d938f5b2a 100644 --- a/app/javascript/flavours/glitch/packs/share.jsx +++ b/app/javascript/flavours/glitch/packs/share.jsx @@ -1,10 +1,13 @@ import 'packs/public-path'; import { createRoot } from 'react-dom/client'; +import { start } from 'flavours/glitch/common'; import ComposeContainer from 'flavours/glitch/containers/compose_container'; import { loadPolyfills } from 'flavours/glitch/polyfills'; import ready from 'flavours/glitch/ready'; +start(); + function loaded() { const mountNode = document.getElementById('mastodon-compose'); diff --git a/app/javascript/packs/common.js b/app/javascript/packs/common.js index 9a889937c4..489041458f 100644 --- a/app/javascript/packs/common.js +++ b/app/javascript/packs/common.js @@ -1,5 +1,5 @@ +/* This file is a hack to have something more reliable than the upstream `common` tag + that is implicitly generated as the common chunk through webpack's `splitChunks` config */ + import './public-path'; import 'font-awesome/css/font-awesome.css'; -import 'styles/application.scss'; - -require.context('../images/', true); diff --git a/app/javascript/skins/glitch/default/common.scss b/app/javascript/skins/glitch/default/common.scss new file mode 100644 index 0000000000..d2f673fde8 --- /dev/null +++ b/app/javascript/skins/glitch/default/common.scss @@ -0,0 +1 @@ +@import 'flavours/glitch/styles/index'; diff --git a/app/javascript/skins/vanilla/default/common.scss b/app/javascript/skins/vanilla/default/common.scss new file mode 100644 index 0000000000..71ac01180a --- /dev/null +++ b/app/javascript/skins/vanilla/default/common.scss @@ -0,0 +1 @@ +@import 'styles/application'; diff --git a/app/lib/themes.rb b/app/lib/themes.rb index d7097e62c0..b379e139e9 100644 --- a/app/lib/themes.rb +++ b/app/lib/themes.rb @@ -7,7 +7,8 @@ class Themes include Singleton def initialize - result = {} + @flavours = {} + Rails.root.glob('app/javascript/flavours/*/theme.yml') do |pathname| data = YAML.load_file(pathname) next unless data['pack'] @@ -35,42 +36,34 @@ class Themes data['name'] = name data['locales'] = locales data['screenshot'] = screenshots - data['skin'] = { 'default' => [] } - result[name] = data + data['skins'] = [] + @flavours[name] = data end Rails.root.glob('app/javascript/skins/*/*') do |pathname| ext = pathname.extname.to_s skin = pathname.basename.to_s name = pathname.dirname.basename.to_s - next unless result[name] + next unless @flavours[name] if pathname.directory? - pack = [] - pathname.glob('*.{css,scss}') do |sheet| - pack.push(sheet.basename(sheet.extname).to_s) - end + @flavours[name]['skins'] << skin if pathname.glob('{common,index,application}.{css,scss}').any? elsif /^\.s?css$/i.match?(ext) - skin = pathname.basename(ext).to_s - pack = ['common'] + @flavours[name]['skins'] << pathname.basename(ext).to_s end - - result[name]['skin'][skin] = pack if skin != 'default' end - - @conf = result end def flavour(name) - @conf[name] + @flavours[name] end def flavours - @conf.keys + @flavours.keys end def skins_for(name) - @conf[name]['skin'].keys + @flavours[name]['skins'] end def flavours_and_skins diff --git a/app/views/layouts/_theme.html.haml b/app/views/layouts/_theme.html.haml index 7c21da3246..fd493bf899 100644 --- a/app/views/layouts/_theme.html.haml +++ b/app/views/layouts/_theme.html.haml @@ -1,12 +1,5 @@ -- if theme - = render partial: 'layouts/theme', object: theme[:common] if theme[:pack] != 'common' && theme[:common] - - if theme[:pack] - - pack_path = "flavours/#{theme[:flavour]}/#{theme[:pack]}" - = javascript_pack_tag pack_path, crossorigin: 'anonymous' - - if theme[:skin] - - if !theme[:flavour] || theme[:skin] == 'default' - = stylesheet_pack_tag pack_path, media: 'all', crossorigin: 'anonymous' - - else - = stylesheet_pack_tag "skins/#{theme[:flavour]}/#{theme[:skin]}/#{theme[:pack]}", media: 'all', crossorigin: 'anonymous' - - theme[:preload]&.each do |link| - %link{ href: asset_pack_path("#{link}.js"), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/ +- if theme && theme[:pack] + - pack_path = "flavours/#{theme[:flavour]}/#{theme[:pack]}" + = javascript_pack_tag pack_path, crossorigin: 'anonymous' + - theme[:preload]&.each do |link| + %link{ href: asset_pack_path("#{link}.js"), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/ diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index b1b705669c..8734f7e7d4 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -26,11 +26,13 @@ %title= html_title - = javascript_pack_tag 'common', crossorigin: 'anonymous' + = stylesheet_pack_tag 'flavours/vanilla/common', media: 'all', crossorigin: 'anonymous' # upstream uses `common` but that's implicitly defined + = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous' -# Needed for the wicg-inert polyfill. It needs to be on it's own