From 7208edbd37a90e3b417c3846c7cc2ec099e1e0ba Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 28 Apr 2024 12:08:08 +0200 Subject: [PATCH] Replace `use_pack`, `layouts/theme` and `@theme` by new helpers Packs are now loaded from views, just like upstream, and are identified by their filenames. The definition of `theme.yml` has changed as such: - `pack_directory` is now required - `pack` is now unused - `signed_in_preload` has been introduced --- app/controllers/admin/base_controller.rb | 5 -- app/controllers/application_controller.rb | 10 +--- app/controllers/auth/challenges_controller.rb | 7 --- .../auth/confirmations_controller.rb | 5 -- app/controllers/auth/passwords_controller.rb | 5 -- .../auth/registrations_controller.rb | 5 -- app/controllers/auth/sessions_controller.rb | 5 -- app/controllers/auth/setup_controller.rb | 5 -- .../auth/two_factor_authentication_concern.rb | 2 - app/controllers/concerns/theming_concern.rb | 33 ++----------- .../concerns/web_app_controller_concern.rb | 5 -- app/controllers/disputes/base_controller.rb | 5 -- .../filters/statuses_controller.rb | 5 -- app/controllers/filters_controller.rb | 5 -- app/controllers/invites_controller.rb | 5 -- app/controllers/media_controller.rb | 5 -- .../oauth/authorizations_controller.rb | 5 -- .../authorized_applications_controller.rb | 5 -- app/controllers/redirect/base_controller.rb | 5 -- app/controllers/relationships_controller.rb | 5 -- app/controllers/settings/base_controller.rb | 5 -- .../settings/login_activities_controller.rb | 6 --- .../webauthn_credentials_controller.rb | 4 -- app/controllers/shares_controller.rb | 5 -- .../statuses_cleanup_controller.rb | 5 -- app/controllers/statuses_controller.rb | 1 - app/helpers/application_helper.rb | 15 ++++++ app/javascript/flavours/glitch/theme.yml | 49 ++++--------------- app/javascript/flavours/vanilla/theme.yml | 44 ++++------------- app/lib/themes.rb | 2 +- app/views/auth/sessions/two_factor.html.haml | 2 + app/views/auth/setup/show.html.haml | 2 + app/views/layouts/_theme.html.haml | 5 -- app/views/layouts/admin.html.haml | 2 + app/views/layouts/application.html.haml | 9 +--- app/views/layouts/auth.html.haml | 3 ++ app/views/layouts/embedded.html.haml | 9 +--- app/views/layouts/error.html.haml | 2 +- app/views/layouts/modal.html.haml | 3 ++ app/views/media/player.html.haml | 8 +-- app/views/relationships/show.html.haml | 3 ++ .../remote_interaction_helper/index.html.haml | 2 +- .../webauthn_credentials/new.html.haml | 2 + app/views/shared/_web_app.html.haml | 2 + app/views/shares/show.html.haml | 1 + config/webpack/configuration.js | 21 ++++---- config/webpack/shared.js | 32 +++++------- spec/views/statuses/show.html.haml_spec.rb | 2 +- 48 files changed, 88 insertions(+), 290 deletions(-) delete mode 100644 app/views/layouts/_theme.html.haml diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index a71bb61298..4b5afbe157 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -7,7 +7,6 @@ module Admin layout 'admin' - before_action :set_pack before_action :set_body_classes before_action :set_cache_headers @@ -19,10 +18,6 @@ module Admin @body_classes = 'admin' end - def set_pack - use_pack 'admin' - end - def set_cache_headers response.cache_control.replace(private: true, no_store: true) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cf953fcf2c..bd152dbb66 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -165,10 +165,7 @@ class ApplicationController < ActionController::Base def respond_with_error(code) respond_to do |format| - format.any do - use_pack 'error' - render "errors/#{code}", layout: 'error', status: code, formats: [:html] - end + format.any { render "errors/#{code}", layout: 'error', status: code, formats: [:html] } format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code } end end @@ -177,10 +174,7 @@ class ApplicationController < ActionController::Base return unless self_destruct? respond_to do |format| - format.any do - use_pack 'error' - render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html] - end + format.any { render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html] } format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 } end end diff --git a/app/controllers/auth/challenges_controller.rb b/app/controllers/auth/challenges_controller.rb index 1e585de189..7ede420b51 100644 --- a/app/controllers/auth/challenges_controller.rb +++ b/app/controllers/auth/challenges_controller.rb @@ -5,7 +5,6 @@ class Auth::ChallengesController < ApplicationController layout 'auth' - before_action :set_pack before_action :authenticate_user! skip_before_action :check_self_destruct! @@ -21,10 +20,4 @@ class Auth::ChallengesController < ApplicationController render_challenge end end - - private - - def set_pack - use_pack 'auth' - end end diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index 8b8a27d260..7ca7be5f8e 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -6,7 +6,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController layout 'auth' before_action :set_body_classes - before_action :set_pack before_action :set_confirmation_user!, only: [:show, :confirm_captcha] before_action :redirect_confirmed_user, if: :signed_in_confirmed_user? @@ -66,10 +65,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController @confirmation_user.nil? || @confirmation_user.confirmed? end - def set_pack - use_pack 'auth' - end - def redirect_confirmed_user redirect_to(current_user.approved? ? root_path : edit_user_registration_path) end diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb index f0d47bf774..de001f062b 100644 --- a/app/controllers/auth/passwords_controller.rb +++ b/app/controllers/auth/passwords_controller.rb @@ -3,7 +3,6 @@ class Auth::PasswordsController < Devise::PasswordsController skip_before_action :check_self_destruct! before_action :redirect_invalid_reset_token, only: :edit, unless: :reset_password_token_is_valid? - before_action :set_pack before_action :set_body_classes layout 'auth' @@ -32,8 +31,4 @@ class Auth::PasswordsController < Devise::PasswordsController def reset_password_token_is_valid? resource_class.with_reset_password_token(params[:reset_password_token]).present? end - - def set_pack - use_pack 'auth' - end end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 838869b2ee..acfc0af0d9 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -9,7 +9,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController before_action :set_invite, only: [:new, :create] before_action :check_enabled_registrations, only: [:new, :create] before_action :configure_sign_up_params, only: [:create] - before_action :set_pack before_action :set_sessions, only: [:edit, :update] before_action :set_strikes, only: [:edit, :update] before_action :set_body_classes, only: [:new, :create, :edit, :update] @@ -97,10 +96,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController private - def set_pack - use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth' - end - def set_body_classes @body_classes = %w(edit update).include?(action_name) ? 'admin' : 'lighter' end diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index 67d369b859..6ed7b2baac 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -12,7 +12,6 @@ class Auth::SessionsController < Devise::SessionsController skip_before_action :require_functional! skip_before_action :update_user_sign_in - prepend_before_action :set_pack prepend_before_action :check_suspicious!, only: [:create] include Auth::TwoFactorAuthenticationConcern @@ -104,10 +103,6 @@ class Auth::SessionsController < Devise::SessionsController private - def set_pack - use_pack 'auth' - end - def set_body_classes @body_classes = 'lighter' end diff --git a/app/controllers/auth/setup_controller.rb b/app/controllers/auth/setup_controller.rb index 8edca4d01b..40916d2887 100644 --- a/app/controllers/auth/setup_controller.rb +++ b/app/controllers/auth/setup_controller.rb @@ -3,7 +3,6 @@ class Auth::SetupController < ApplicationController layout 'auth' - before_action :set_pack before_action :authenticate_user! before_action :require_unconfirmed_or_pending! before_action :set_body_classes @@ -43,8 +42,4 @@ class Auth::SetupController < ApplicationController def user_params params.require(:user).permit(:email) end - - def set_pack - use_pack 'sign_up' - end end diff --git a/app/controllers/concerns/auth/two_factor_authentication_concern.rb b/app/controllers/concerns/auth/two_factor_authentication_concern.rb index edcdd2990f..404164751a 100644 --- a/app/controllers/concerns/auth/two_factor_authentication_concern.rb +++ b/app/controllers/concerns/auth/two_factor_authentication_concern.rb @@ -83,8 +83,6 @@ module Auth::TwoFactorAuthenticationConcern def prompt_for_two_factor(user) register_attempt_in_session(user) - use_pack 'auth' - @body_classes = 'lighter' @webauthn_enabled = user.webauthn_enabled? @scheme_type = if user.webauthn_enabled? && user_params[:otp_attempt].blank? diff --git a/app/controllers/concerns/theming_concern.rb b/app/controllers/concerns/theming_concern.rb index 7da04e1531..ebdaf54c05 100644 --- a/app/controllers/concerns/theming_concern.rb +++ b/app/controllers/concerns/theming_concern.rb @@ -3,19 +3,17 @@ module ThemingConcern extend ActiveSupport::Concern - def use_pack(pack_name) - @theme = resolve_pack(Themes.instance.flavour(current_flavour), pack_name) - end - private def current_flavour - [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } + @current_flavour ||= [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } end def current_skin - skins = Themes.instance.skins_for(current_flavour) - [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } + @current_skin ||= begin + skins = Themes.instance.skins_for(current_flavour) + [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } + end end def current_theme @@ -23,25 +21,4 @@ module ThemingConcern # for the sole purpose of pointing to the appropriate stylesheet pack "skins/#{current_flavour}/#{current_skin}" end - - def resolve_pack(data, pack_name) - pack_data = { - flavour: data['name'], - pack: nil, - preload: 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'] - - preloads = data['pack'][pack_name]['preload'] - pack_data[:preload] = [preloads] if preloads.is_a?(String) - pack_data[:preload] = preloads if preloads.is_a?(Array) - - pack_data - end end diff --git a/app/controllers/concerns/web_app_controller_concern.rb b/app/controllers/concerns/web_app_controller_concern.rb index d20643e66c..24cccf1667 100644 --- a/app/controllers/concerns/web_app_controller_concern.rb +++ b/app/controllers/concerns/web_app_controller_concern.rb @@ -7,7 +7,6 @@ module WebAppControllerConcern vary_by 'Accept, Accept-Language, Cookie' before_action :redirect_unauthenticated_to_permalinks! - before_action :set_pack before_action :set_app_body_class end @@ -37,8 +36,4 @@ module WebAppControllerConcern end end end - - def set_pack - use_pack 'application' - end end diff --git a/app/controllers/disputes/base_controller.rb b/app/controllers/disputes/base_controller.rb index f51f44c620..1054f3db80 100644 --- a/app/controllers/disputes/base_controller.rb +++ b/app/controllers/disputes/base_controller.rb @@ -9,15 +9,10 @@ class Disputes::BaseController < ApplicationController before_action :set_body_classes before_action :authenticate_user! - before_action :set_pack before_action :set_cache_headers private - def set_pack - use_pack 'admin' - end - def set_body_classes @body_classes = 'admin' end diff --git a/app/controllers/filters/statuses_controller.rb b/app/controllers/filters/statuses_controller.rb index 97206c7eda..94993f938b 100644 --- a/app/controllers/filters/statuses_controller.rb +++ b/app/controllers/filters/statuses_controller.rb @@ -6,7 +6,6 @@ class Filters::StatusesController < ApplicationController before_action :authenticate_user! before_action :set_filter before_action :set_status_filters - before_action :set_pack before_action :set_body_classes before_action :set_cache_headers @@ -27,10 +26,6 @@ class Filters::StatusesController < ApplicationController private - def set_pack - use_pack 'admin' - end - def set_filter @filter = current_account.custom_filters.find(params[:filter_id]) end diff --git a/app/controllers/filters_controller.rb b/app/controllers/filters_controller.rb index 1b19269b23..bd9964426b 100644 --- a/app/controllers/filters_controller.rb +++ b/app/controllers/filters_controller.rb @@ -5,7 +5,6 @@ class FiltersController < ApplicationController before_action :authenticate_user! before_action :set_filter, only: [:edit, :update, :destroy] - before_action :set_pack before_action :set_body_classes before_action :set_cache_headers @@ -45,10 +44,6 @@ class FiltersController < ApplicationController private - def set_pack - use_pack 'settings' - end - def set_filter @filter = current_account.custom_filters.find(params[:id]) end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 2db4bc5cbd..9bc5164d59 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -6,7 +6,6 @@ class InvitesController < ApplicationController layout 'admin' before_action :authenticate_user! - before_action :set_pack before_action :set_body_classes before_action :set_cache_headers @@ -40,10 +39,6 @@ class InvitesController < ApplicationController private - def set_pack - use_pack 'settings' - end - def invites current_user.invites.order(id: :desc) end diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb index 4c028dbef0..53eee40012 100644 --- a/app/controllers/media_controller.rb +++ b/app/controllers/media_controller.rb @@ -10,7 +10,6 @@ class MediaController < ApplicationController before_action :verify_permitted_status! before_action :check_playable, only: :player before_action :allow_iframing, only: :player - before_action :set_pack, only: :player content_security_policy only: :player do |policy| policy.frame_ancestors(false) @@ -48,8 +47,4 @@ class MediaController < ApplicationController def allow_iframing response.headers.delete('X-Frame-Options') end - - def set_pack - use_pack 'public' - end end diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index 62fc9c1b0d..66e774425d 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -5,7 +5,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController before_action :store_current_location before_action :authenticate_resource_owner! - before_action :set_pack before_action :set_cache_headers content_security_policy do |p| @@ -20,10 +19,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController store_location_for(:user, request.url) end - def set_pack - use_pack 'auth' - end - def render_success if skip_authorization? || (matching_token? && !truthy_param?('force_login')) redirect_or_render authorize_response diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb index 778912c948..8440df6b7e 100644 --- a/app/controllers/oauth/authorized_applications_controller.rb +++ b/app/controllers/oauth/authorized_applications_controller.rb @@ -5,7 +5,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio before_action :store_current_location before_action :authenticate_resource_owner! - before_action :set_pack before_action :require_not_suspended!, only: :destroy before_action :set_body_classes before_action :set_cache_headers @@ -31,10 +30,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio store_location_for(:user, request.url) end - def set_pack - use_pack 'settings' - end - def require_not_suspended! forbidden if current_account.unavailable? end diff --git a/app/controllers/redirect/base_controller.rb b/app/controllers/redirect/base_controller.rb index ce55cfc53a..90894ec1ed 100644 --- a/app/controllers/redirect/base_controller.rb +++ b/app/controllers/redirect/base_controller.rb @@ -3,7 +3,6 @@ class Redirect::BaseController < ApplicationController vary_by 'Accept-Language' - before_action :set_pack before_action :set_resource before_action :set_app_body_class @@ -22,8 +21,4 @@ class Redirect::BaseController < ApplicationController def set_resource raise NotImplementedError end - - def set_pack - use_pack 'public' - end end diff --git a/app/controllers/relationships_controller.rb b/app/controllers/relationships_controller.rb index e6e7c24752..dd794f3199 100644 --- a/app/controllers/relationships_controller.rb +++ b/app/controllers/relationships_controller.rb @@ -5,7 +5,6 @@ class RelationshipsController < ApplicationController before_action :authenticate_user! before_action :set_accounts, only: :show - before_action :set_pack before_action :set_relationships, only: :show before_action :set_body_classes before_action :set_cache_headers @@ -73,10 +72,6 @@ class RelationshipsController < ApplicationController @body_classes = 'admin' end - def set_pack - use_pack 'admin' - end - def set_cache_headers response.cache_control.replace(private: true, no_store: true) end diff --git a/app/controllers/settings/base_controller.rb b/app/controllers/settings/base_controller.rb index 4d3d6e6a1b..f15140aa2b 100644 --- a/app/controllers/settings/base_controller.rb +++ b/app/controllers/settings/base_controller.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Settings::BaseController < ApplicationController - before_action :set_pack layout 'admin' before_action :authenticate_user! @@ -10,10 +9,6 @@ class Settings::BaseController < ApplicationController private - def set_pack - use_pack 'settings' - end - def set_body_classes @body_classes = 'admin' end diff --git a/app/controllers/settings/login_activities_controller.rb b/app/controllers/settings/login_activities_controller.rb index 018fc7e950..50e2d70cb9 100644 --- a/app/controllers/settings/login_activities_controller.rb +++ b/app/controllers/settings/login_activities_controller.rb @@ -7,10 +7,4 @@ class Settings::LoginActivitiesController < Settings::BaseController def index @login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page]) end - - private - - def set_pack - use_pack 'settings' - end end diff --git a/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb b/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb index aed5af6e79..9714d54f95 100644 --- a/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb +++ b/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb @@ -85,10 +85,6 @@ module Settings private - def set_pack - use_pack 'auth' - end - def redirect_invalid_otp flash[:error] = t('webauthn_credentials.otp_required') redirect_to settings_two_factor_authentication_methods_path diff --git a/app/controllers/shares_controller.rb b/app/controllers/shares_controller.rb index e13e7e8b65..6546b84978 100644 --- a/app/controllers/shares_controller.rb +++ b/app/controllers/shares_controller.rb @@ -4,17 +4,12 @@ class SharesController < ApplicationController layout 'modal' before_action :authenticate_user! - before_action :set_pack before_action :set_body_classes def show; end private - def set_pack - use_pack 'share' - end - def set_body_classes @body_classes = 'modal-layout compose-standalone' end diff --git a/app/controllers/statuses_cleanup_controller.rb b/app/controllers/statuses_cleanup_controller.rb index 88cf26d74d..4a3fc10ca4 100644 --- a/app/controllers/statuses_cleanup_controller.rb +++ b/app/controllers/statuses_cleanup_controller.rb @@ -6,7 +6,6 @@ class StatusesCleanupController < ApplicationController before_action :authenticate_user! before_action :set_policy before_action :set_body_classes - before_action :set_pack before_action :set_cache_headers def show; end @@ -27,10 +26,6 @@ class StatusesCleanupController < ApplicationController private - def set_pack - use_pack 'settings' - end - def set_policy @policy = current_account.statuses_cleanup_policy || current_account.build_statuses_cleanup_policy(enabled: false) end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 7f9127d3a6..db7eddd78b 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -41,7 +41,6 @@ class StatusesController < ApplicationController end def embed - use_pack 'public' return not_found if @status.hidden? || @status.reblog? expires_in 180, public: true diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 233c242e4a..62c0e78d23 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -233,6 +233,21 @@ module ApplicationHelper EmojiFormatter.new(html, custom_emojis, other_options.merge(animate: prefers_autoplay?)).to_s end + # glitch-soc addition to handle the multiple flavors + def preload_locale_pack + supported_locales = Themes.instance.flavour(current_flavour)['locales'] + preload_pack_asset "locales/#{current_flavour}/#{I18n.locale}-json.js" if supported_locales.include?(I18n.locale.to_s) + end + + def flavoured_javascript_pack_tag(pack_name, **options) + javascript_pack_tag("flavours/#{current_flavour}/#{pack_name}", **options) + end + + def preload_signed_in_js_packs + preload_files = Themes.instance.flavour(current_flavour)&.fetch('signed_in_preload', nil) || [] + safe_join(preload_files.map { |entry| preload_pack_asset entry }) + end + private def storage_host_var diff --git a/app/javascript/flavours/glitch/theme.yml b/app/javascript/flavours/glitch/theme.yml index 99a31cb663..ca18fd7b86 100644 --- a/app/javascript/flavours/glitch/theme.yml +++ b/app/javascript/flavours/glitch/theme.yml @@ -1,32 +1,12 @@ -# (REQUIRED) The location of the pack files. -pack: - admin: - - admin.tsx - - public.tsx - auth: - - public.tsx - - two_factor_authentication.js - common: - filename: common.js - stylesheet: true - error: error.js - application: - filename: application.js - preload: - - flavours/glitch/async/compose - - flavours/glitch/async/home_timeline - - flavours/glitch/async/notifications - inert: - filename: inert.js - stylesheet: true - mailer: - filename: mailer.js - stylesheet: true - public: public.tsx - settings: public.tsx - sign_up: sign_up.js - share: share.jsx - remote_interaction_helper: remote_interaction_helper.ts +# (REQUIRED) The directory which contains the entry point files. +pack_directory: app/javascript/flavours/glitch/packs + +# (OPTIONAL) Define files to be preloaded when a logged-in user is +# visiting the main web app. +signed_in_preload: + - flavours/glitch/async/compose.js + - flavours/glitch/async/home_timeline.js + - flavours/glitch/async/notifications.js # (OPTIONAL) The directory which contains localization files for # the flavour, relative to this directory. The contents of this @@ -40,14 +20,3 @@ inherit_locales: vanilla # (OPTIONAL) A file to use as the preview screenshot for the flavour, # or an array thereof. These are the full path from `app/javascript/`. screenshot: flavours/glitch/images/glitch-preview.png - -# (OPTIONAL) The directory which contains the pack files. -# Defaults to this directory (`app/javascript/flavour/[flavour]`), -# but in the case of the vanilla Mastodon flavour the pack files are -# somewhere else. -pack_directory: app/javascript/flavours/glitch/packs -# (OPTIONAL) The directory which contains the pack files. -# Defaults to the theme directory (`app/javascript/themes/[theme]`), -# which should be sufficient for like 99% of use-cases lol. - -# pack_directory: app/javascript/packs diff --git a/app/javascript/flavours/vanilla/theme.yml b/app/javascript/flavours/vanilla/theme.yml index 61ee528f96..d155324beb 100644 --- a/app/javascript/flavours/vanilla/theme.yml +++ b/app/javascript/flavours/vanilla/theme.yml @@ -1,32 +1,12 @@ -# (REQUIRED) The location of the pack files inside `pack_directory`. -pack: - admin: - - admin.tsx - - public.tsx - auth: - - public.tsx - - two_factor_authentication.js - common: - filename: common.js - stylesheet: true - error: error.js - application: - filename: application.js - preload: - - features/compose - - features/home_timeline - - features/notifications - inert: - filename: inert.js - stylesheet: true - mailer: - filename: mailer.js - stylesheet: true - public: public.tsx - settings: public.tsx - sign_up: sign_up.js - share: share.jsx - remote_interaction_helper: remote_interaction_helper.ts +# (REQUIRED) The directory which contains the pack files. +pack_directory: app/javascript/packs + +# (OPTIONAL) Define files to be preloaded when a logged-in user is +# visiting the main web app. +signed_in_preload: + - features/compose.js + - features/home_timeline.js + - features/notifications.js # (OPTIONAL) The directory which contains localization files for # the flavour, relative to this directory. @@ -35,9 +15,3 @@ locales: ../../mastodon/locales # (OPTIONAL) A file to use as the preview screenshot for the flavour, # or an array thereof. These are the full path from `app/javascript/`. screenshot: images/screenshot.png - -# (OPTIONAL) The directory which contains the pack files. -# Defaults to this directory (`app/javascript/flavour/[flavour]`), -# but in the case of the vanilla Mastodon flavour the pack files are -# somewhere else. -pack_directory: app/javascript/packs diff --git a/app/lib/themes.rb b/app/lib/themes.rb index b379e139e9..89730c9b31 100644 --- a/app/lib/themes.rb +++ b/app/lib/themes.rb @@ -11,7 +11,7 @@ class Themes Rails.root.glob('app/javascript/flavours/*/theme.yml') do |pathname| data = YAML.load_file(pathname) - next unless data['pack'] + next unless data['pack_directory'] dir = pathname.dirname name = dir.basename.to_s diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml index 0892101b57..63c8b0a2cb 100644 --- a/app/views/auth/sessions/two_factor.html.haml +++ b/app/views/auth/sessions/two_factor.html.haml @@ -1,6 +1,8 @@ - content_for :page_title do = t('auth.login') += flavoured_javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous' + - if webauthn_enabled? = render partial: 'auth/sessions/two_factor/webauthn_form', locals: { hidden: @scheme_type != 'webauthn' } diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index 097e3416e2..6ba219e729 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -1,6 +1,8 @@ - content_for :page_title do = t('auth.setup.title') += flavoured_javascript_pack_tag 'sign_up', crossorigin: 'anonymous' + = simple_form_for(@user, url: auth_setup_path) do |f| = render 'auth/shared/progress', stage: 'confirm' diff --git a/app/views/layouts/_theme.html.haml b/app/views/layouts/_theme.html.haml deleted file mode 100644 index fd493bf899..0000000000 --- a/app/views/layouts/_theme.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -- 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/admin.html.haml b/app/views/layouts/admin.html.haml index 3048e0e6ad..a95d5caef5 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -1,5 +1,7 @@ - content_for :header_tags do = render_initial_state + = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' + = flavoured_javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous' - content_for :content do .admin-wrapper diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 8734f7e7d4..4fe314eb4b 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -33,11 +33,7 @@ = stylesheet_pack_tag 'flavours/vanilla/inert', media: 'all', id: 'inert-style' = javascript_pack_tag 'common', crossorigin: 'anonymous' - - if @theme - - if @theme[:supported_locales].include? I18n.locale.to_s - = preload_pack_asset "locales/#{@theme[:flavour]}/#{I18n.locale}-json.js" - - elsif @theme[:supported_locales].include? 'en' - = preload_pack_asset "locales/#{@theme[:flavour]}/en-json.js" + = preload_locale_pack = csrf_meta_tags unless skip_csrf_meta_tags? %meta{ name: 'style-nonce', content: request.content_security_policy_nonce } @@ -45,9 +41,6 @@ = yield :header_tags - -# These must come after :header_tags to ensure our initial state has been defined. - = render partial: 'layouts/theme', object: @theme - %body{ class: body_classes } = content_for?(:content) ? yield(:content) : yield diff --git a/app/views/layouts/auth.html.haml b/app/views/layouts/auth.html.haml index 34f6b38ec8..efd2569d77 100644 --- a/app/views/layouts/auth.html.haml +++ b/app/views/layouts/auth.html.haml @@ -1,3 +1,6 @@ +- content_for :header_tags do + = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' + - content_for :content do .container-alt .logo-container diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml index 19df497533..e8764567d1 100644 --- a/app/views/layouts/embedded.html.haml +++ b/app/views/layouts/embedded.html.haml @@ -14,14 +14,9 @@ = 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' = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous' - - if @theme - - if @theme[:supported_locales].include? I18n.locale.to_s - = preload_pack_asset "locales/#{@theme[:flavour]}/#{I18n.locale}-json.js" - - elsif @theme[:supported_locales].include? 'en' - = preload_pack_asset "locales/#{@theme[:flavour]}/en-json.js" - = preload_pack_asset "locale/#{I18n.locale}-json.js" + = preload_locale_pack = render_initial_state - = render partial: 'layouts/theme', object: @theme + = flavoured_javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' %body.embed = yield diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml index 49224daa83..7ad2ad3d69 100644 --- a/app/views/layouts/error.html.haml +++ b/app/views/layouts/error.html.haml @@ -8,7 +8,7 @@ = 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' = javascript_pack_tag 'common', crossorigin: 'anonymous' - = render partial: 'layouts/theme', object: @theme || { pack: 'error', flavour: 'glitch', common: { pack: 'common', flavour: 'glitch', skin: 'default' } } + = flavoured_javascript_pack_tag 'error', crossorigin: 'anonymous' %body.error .dialog .dialog__illustration diff --git a/app/views/layouts/modal.html.haml b/app/views/layouts/modal.html.haml index 5d08d78489..8d5b158eb5 100644 --- a/app/views/layouts/modal.html.haml +++ b/app/views/layouts/modal.html.haml @@ -1,3 +1,6 @@ +- content_for :header_tags do + = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' + - content_for :content do - if user_signed_in? && !@hide_header .account-header diff --git a/app/views/media/player.html.haml b/app/views/media/player.html.haml index 9a0c420fc3..c5ba8680a0 100644 --- a/app/views/media/player.html.haml +++ b/app/views/media/player.html.haml @@ -1,12 +1,6 @@ - content_for :header_tags do = render_initial_state - = javascript_pack_tag 'common', crossorigin: 'anonymous' - - if @theme - - if @theme[:supported_locales].include? I18n.locale.to_s - = preload_pack_asset "locales/#{@theme[:flavour]}/#{I18n.locale}-json.js" - - elsif @theme[:supported_locales].include? 'en' - = preload_pack_asset "locales/#{@theme[:flavour]}/en-json.js" - = render partial: 'layouts/theme', object: @theme + = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' :ruby meta = @media_attachment.file.meta || {} diff --git a/app/views/relationships/show.html.haml b/app/views/relationships/show.html.haml index 6b87bef2ec..066f5d17fb 100644 --- a/app/views/relationships/show.html.haml +++ b/app/views/relationships/show.html.haml @@ -1,6 +1,9 @@ - content_for :page_title do = t('settings.relationships') +- content_for :header_tags do + = flavoured_javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous' + .filters .filter-subset %strong= t 'relationships.relationship' diff --git a/app/views/remote_interaction_helper/index.html.haml b/app/views/remote_interaction_helper/index.html.haml index 84a48bf057..e67fe6b6b7 100644 --- a/app/views/remote_interaction_helper/index.html.haml +++ b/app/views/remote_interaction_helper/index.html.haml @@ -1,4 +1,4 @@ - content_for :header_tags do %meta{ name: 'robots', content: 'noindex' }/ - = javascript_pack_tag 'flavours/vanilla/remote_interaction_helper', crossorigin: 'anonymous' + = flavoured_javascript_pack_tag 'remote_interaction_helper', crossorigin: 'anonymous' diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml index 5ec0247577..444cf6ae74 100644 --- a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml +++ b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml @@ -12,3 +12,5 @@ .actions = f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit + += flavoured_javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous' diff --git a/app/views/shared/_web_app.html.haml b/app/views/shared/_web_app.html.haml index b53c25e77c..cb9f7f4cfd 100644 --- a/app/views/shared/_web_app.html.haml +++ b/app/views/shared/_web_app.html.haml @@ -1,10 +1,12 @@ - content_for :header_tags do - if user_signed_in? + = preload_signed_in_js_packs %meta{ name: 'initialPath', content: request.path } %meta{ name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key } = render_initial_state + = flavoured_javascript_pack_tag 'application', crossorigin: 'anonymous' .notranslate.app-holder#mastodon{ data: { props: Oj.dump(default_props) } } %noscript diff --git a/app/views/shares/show.html.haml b/app/views/shares/show.html.haml index 28910d3abd..350604527d 100644 --- a/app/views/shares/show.html.haml +++ b/app/views/shares/show.html.haml @@ -1,4 +1,5 @@ - content_for :header_tags do = render_initial_state + = flavoured_javascript_pack_tag 'share', crossorigin: 'anonymous' #mastodon-compose{ data: { props: Oj.dump(default_props) } } diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js index 7ec28158e7..c9a1fe268a 100644 --- a/config/webpack/configuration.js +++ b/config/webpack/configuration.js @@ -14,18 +14,15 @@ const skinFiles = glob.sync('app/javascript/skins/*/*'); const flavours = {}; flavourFiles.forEach((flavourFile) => { - const data = load(readFileSync(flavourFile), 'utf8'); - data.name = basename(dirname(flavourFile)); - data.skin = {}; - if (!data.pack_directory) { - data.pack_directory = dirname(flavourFile); - } - if (data.locales) { - data.locales = join(dirname(flavourFile), data.locales); - } - if (data.pack && typeof data.pack === 'object') { - flavours[data.name] = data; - } + const { locales, inherit_locales, pack_directory } = load(readFileSync(flavourFile), 'utf8'); + + flavours[basename(dirname(flavourFile))] = { + name: basename(dirname(flavourFile)), + locales: locales ? join(dirname(flavourFile), locales) : null, + inherit_locales, + pack_directory: pack_directory, + skin: {}, + }; }); skinFiles.forEach((skinFile) => { diff --git a/config/webpack/shared.js b/config/webpack/shared.js index 404dc23d6e..df61dff312 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -1,36 +1,26 @@ // Note: You must restart bin/webpack-dev-server for changes to take effect -const { resolve } = require('path'); +const { basename, dirname, join, relative, resolve } = require('path'); const CircularDependencyPlugin = require('circular-dependency-plugin'); +const { sync } = require('glob'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const extname = require('path-complete-extname'); const webpack = require('webpack'); const AssetsManifestPlugin = require('webpack-assets-manifest'); const { env, settings, flavours, output } = require('./configuration'); const rules = require('./rules'); -function reducePacks (data, into = {}) { - if (!data.pack) return into; +const extensionGlob = `**/*{${settings.extensions.join(',')}}*`; - for (const entry in data.pack) { - const pack = data.pack[entry]; - if (!pack) continue; +function reduceFlavourPacks(data, into = {}) { + const packPaths = sync(join(data.pack_directory, extensionGlob)); - let packFiles = []; - if (typeof pack === 'string') - packFiles = [pack]; - else if (Array.isArray(pack)) - packFiles = pack; - else - packFiles = [pack.filename]; - - if (packFiles) { - into[`flavours/${data.name}/${entry}`] = packFiles.map(packFile => resolve(data.pack_directory, packFile)); - } - } - - if (!data.name) return into; + packPaths.forEach((entry) => { + const namespace = relative(join(data.pack_directory), dirname(entry)); + into[`flavours/${data.name}/${join(namespace, basename(entry, extname(entry)))}`] = resolve(entry); + }); for (const skinName in data.skin) { const skin = data.skin[skinName]; @@ -43,7 +33,7 @@ function reducePacks (data, into = {}) { } const entries = Object.assign( - Object.values(flavours).reduce((map, data) => reducePacks(data, map), {}), + Object.values(flavours).reduce((map, data) => reduceFlavourPacks(data, map), {}), ); diff --git a/spec/views/statuses/show.html.haml_spec.rb b/spec/views/statuses/show.html.haml_spec.rb index 92ba678b6d..779fe6e5f4 100644 --- a/spec/views/statuses/show.html.haml_spec.rb +++ b/spec/views/statuses/show.html.haml_spec.rb @@ -4,7 +4,7 @@ require 'rails_helper' describe 'statuses/show.html.haml', :without_verify_partial_doubles do before do - allow(view).to receive_messages(api_oembed_url: '', site_title: 'example site', site_hostname: 'example.com', full_asset_url: '//asset.host/image.svg', current_account: nil, single_user_mode?: false) + allow(view).to receive_messages(api_oembed_url: '', site_title: 'example site', site_hostname: 'example.com', full_asset_url: '//asset.host/image.svg', current_flavour: 'glitch', current_account: nil, single_user_mode?: false) allow(view).to receive(:local_time) allow(view).to receive(:local_time_ago) assign(:instance_presenter, InstancePresenter.new)