Merge pull request #229 from glitch-soc/glitch-theme

Advanced Next-Level Flavours And Skins For Mastodon™
This commit is contained in:
beatrix 2017-12-06 17:44:07 -05:00 committed by GitHub
commit 81b0145759
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
387 changed files with 2930 additions and 936 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "app/javascript/themes/mastodon-go"]
path = app/javascript/themes/mastodon-go
url = https://github.com/marrus-sh/mastodon-go

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class AboutController < ApplicationController class AboutController < ApplicationController
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_instance_presenter, only: [:show, :more, :terms] before_action :set_instance_presenter, only: [:show, :more, :terms]
@ -21,6 +22,10 @@ class AboutController < ApplicationController
helper_method :new_user helper_method :new_user
def set_pack
use_pack action_name == 'show' ? 'about' : 'common'
end
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end

View File

@ -7,6 +7,7 @@ class AccountsController < ApplicationController
def show def show
respond_to do |format| respond_to do |format|
format.html do format.html do
use_pack 'public'
@pinned_statuses = [] @pinned_statuses = []
if current_account && @account.blocking?(current_account) if current_account && @account.blocking?(current_account)

View File

@ -5,8 +5,13 @@ module Admin
include Authorization include Authorization
include AccountableConcern include AccountableConcern
before_action :require_staff!
layout 'admin' layout 'admin'
before_action :require_staff!
before_action :set_pack
def set_pack
use_pack 'admin'
end
end end
end end

View File

@ -12,8 +12,8 @@ class ApplicationController < ActionController::Base
helper_method :current_account helper_method :current_account
helper_method :current_session helper_method :current_session
helper_method :current_theme helper_method :current_flavour
helper_method :theme_data helper_method :current_skin
helper_method :single_user_mode? helper_method :single_user_mode?
rescue_from ActionController::RoutingError, with: :not_found rescue_from ActionController::RoutingError, with: :not_found
@ -54,6 +54,73 @@ class ApplicationController < ActionController::Base
new_user_session_path new_user_session_path
end end
def pack(data, pack_name, skin = 'default')
return nil unless pack?(data, pack_name)
pack_data = {
common: pack_name == 'common' ? nil : resolve_pack(data['name'] ? Themes.instance.flavour(current_flavour) : Themes.instance.core, 'common'),
flavour: data['name'],
pack: pack_name,
preload: nil,
skin: nil,
}
if data['pack'][pack_name].is_a?(Hash)
pack_data[:common] = nil if data['pack'][pack_name]['use_common'] == false
pack_data[:pack] = nil unless data['pack'][pack_name]['filename']
if data['pack'][pack_name]['preload']
pack_data[:preload] = [data['pack'][pack_name]['preload']] if data['pack'][pack_name]['preload'].is_a?(String)
pack_data[:preload] = data['pack'][pack_name]['preload'] if data['pack'][pack_name]['preload'].is_a?(Array)
end
if skin != 'default' && data['skin'][skin]
pack_data[:skin] = skin if data['skin'][skin].include?(pack_name)
else # default skin
pack_data[:skin] = 'default' if data['pack'][pack_name]['stylesheet']
end
end
pack_data
end
def pack?(data, pack_name)
if data['pack'].is_a?(Hash) && data['pack'].key?(pack_name)
return true if data['pack'][pack_name].is_a?(String) || data['pack'][pack_name].is_a?(Hash)
end
false
end
def nil_pack(data, pack_name, skin = 'default')
{
common: pack_name == 'common' ? nil : resolve_pack(data['name'] ? Themes.instance.flavour(current_flavour) : Themes.instance.core, 'common', skin),
flavour: data['name'],
pack: nil,
preload: nil,
skin: nil,
}
end
def resolve_pack(data, pack_name, skin = 'default')
result = pack(data, pack_name, skin)
unless result
if data['name'] && data.key?('fallback')
if data['fallback'].nil?
return nil_pack(data, pack_name, skin)
elsif data['fallback'].is_a?(String) && Themes.instance.flavour(data['fallback'])
return resolve_pack(Themes.instance.flavour(data['fallback']), pack_name, skin)
elsif data['fallback'].is_a?(Array)
data['fallback'].each do |fallback|
return resolve_pack(Themes.instance.flavour(fallback), pack_name, skin) if Themes.instance.flavour(fallback)
end
end
return nil_pack(data, pack_name, skin)
end
return data.key?('name') && data['name'] != Setting.default_settings['flavour'] ? resolve_pack(Themes.instance.flavour(Setting.default_settings['flavour']), pack_name, skin) : nil_pack(data, pack_name, skin)
end
result
end
def use_pack(pack_name)
@core = resolve_pack(Themes.instance.core, pack_name)
@theme = resolve_pack(Themes.instance.flavour(current_flavour), pack_name, current_skin)
end
protected protected
def forbidden def forbidden
@ -84,13 +151,14 @@ class ApplicationController < ActionController::Base
@current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id']) @current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
end end
def current_theme def current_flavour
return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme return Setting.default_settings['flavour'] unless Themes.instance.flavours.include? current_user&.setting_flavour
current_user.setting_theme current_user.setting_flavour
end end
def theme_data def current_skin
Themes.instance.get(current_theme) return 'default' unless Themes.instance.skins_for(current_flavour).include? current_user&.setting_skin
current_user.setting_skin
end end
def cache_collection(raw, klass) def cache_collection(raw, klass)

View File

@ -2,10 +2,17 @@
class Auth::ConfirmationsController < Devise::ConfirmationsController class Auth::ConfirmationsController < Devise::ConfirmationsController
layout 'auth' layout 'auth'
before_action :set_pack
def show def show
super do |user| super do |user|
BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty? BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
end end
end end
private
def set_pack
use_pack 'auth'
end
end end

View File

@ -2,6 +2,7 @@
class Auth::PasswordsController < Devise::PasswordsController class Auth::PasswordsController < Devise::PasswordsController
before_action :check_validity_of_reset_password_token, only: :edit before_action :check_validity_of_reset_password_token, only: :edit
before_action :set_pack
layout 'auth' layout 'auth'
@ -17,4 +18,8 @@ class Auth::PasswordsController < Devise::PasswordsController
def reset_password_token_is_valid? def reset_password_token_is_valid?
resource_class.with_reset_password_token(params[:reset_password_token]).present? resource_class.with_reset_password_token(params[:reset_password_token]).present?
end end
def set_pack
use_pack 'auth'
end
end end

View File

@ -5,6 +5,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
before_action :check_enabled_registrations, only: [:new, :create] before_action :check_enabled_registrations, only: [:new, :create]
before_action :configure_sign_up_params, only: [:create] before_action :configure_sign_up_params, only: [:create]
before_action :set_pack
before_action :set_sessions, only: [:edit, :update] before_action :set_sessions, only: [:edit, :update]
before_action :set_instance_presenter, only: [:new, :create, :update] before_action :set_instance_presenter, only: [:new, :create, :update]
@ -55,6 +56,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController
private private
def set_pack
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
end
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end

View File

@ -9,6 +9,7 @@ class Auth::SessionsController < Devise::SessionsController
skip_before_action :check_suspension, only: [:destroy] skip_before_action :check_suspension, only: [:destroy]
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
before_action :set_instance_presenter, only: [:new] before_action :set_instance_presenter, only: [:new]
before_action :set_pack
def create def create
super do |resource| super do |resource|
@ -85,6 +86,10 @@ class Auth::SessionsController < Devise::SessionsController
private private
def set_pack
use_pack 'auth'
end
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end

View File

@ -4,6 +4,7 @@ class AuthorizeFollowsController < ApplicationController
layout 'modal' layout 'modal'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
def show def show
@account = located_account || render(:error) @account = located_account || render(:error)
@ -23,6 +24,10 @@ class AuthorizeFollowsController < ApplicationController
private private
def set_pack
use_pack 'modal'
end
def follow_attempt def follow_attempt
FollowService.new.call(current_account, acct_without_prefix) FollowService.new.call(current_account, acct_without_prefix)
end end

View File

@ -7,7 +7,9 @@ class FollowerAccountsController < ApplicationController
@follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account) @follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account)
respond_to do |format| respond_to do |format|
format.html format.html do
use_pack 'public'
end
format.json do format.json do
render json: collection_presenter, render json: collection_presenter,

View File

@ -7,7 +7,9 @@ class FollowingAccountsController < ApplicationController
@follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account) @follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account)
respond_to do |format| respond_to do |format|
format.html format.html do
use_pack 'public'
end
format.json do format.json do
render json: collection_presenter, render json: collection_presenter,

View File

@ -2,6 +2,7 @@
class HomeController < ApplicationController class HomeController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
before_action :set_initial_state_json before_action :set_initial_state_json
def index def index
@ -37,6 +38,10 @@ class HomeController < ApplicationController
redirect_to(default_redirect_path) redirect_to(default_redirect_path)
end end
def set_pack
use_pack 'home'
end
def set_initial_state_json def set_initial_state_json
serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer) serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
@initial_state_json = serializable_resource.to_json @initial_state_json = serializable_resource.to_json

View File

@ -4,6 +4,7 @@ class RemoteFollowController < ApplicationController
layout 'modal' layout 'modal'
before_action :set_account before_action :set_account
before_action :set_pack
before_action :gone, if: :suspended_account? before_action :gone, if: :suspended_account?
def new def new
@ -31,6 +32,10 @@ class RemoteFollowController < ApplicationController
{ acct: session[:remote_follow] } { acct: session[:remote_follow] }
end end
def set_pack
use_pack 'modal'
end
def set_account def set_account
@account = Account.find_local!(params[:account_username]) @account = Account.find_local!(params[:account_username])
end end

View File

@ -1,9 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::ApplicationsController < ApplicationController class Settings::ApplicationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_application, only: [:show, :update, :destroy, :regenerate] before_action :set_application, only: [:show, :update, :destroy, :regenerate]
before_action :prepare_scopes, only: [:create, :update] before_action :prepare_scopes, only: [:create, :update]

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
class Settings::BaseController < ApplicationController
layout 'admin'
before_action :authenticate_user!
before_action :set_pack
def set_pack
use_pack 'settings'
end
end

View File

@ -1,10 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::DeletesController < ApplicationController class Settings::DeletesController < Settings::BaseController
layout 'admin'
before_action :check_enabled_deletion prepend_before_action :check_enabled_deletion
before_action :authenticate_user!
def show def show
@confirmation = Form::DeleteConfirmation.new @confirmation = Form::DeleteConfirmation.new

View File

@ -1,10 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::ExportsController < ApplicationController class Settings::ExportsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show def show
@export = Export.new(current_account) @export = Export.new(current_account)
end end

View File

@ -2,11 +2,7 @@
require 'sidekiq-bulk' require 'sidekiq-bulk'
class Settings::FollowerDomainsController < ApplicationController class Settings::FollowerDomainsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show def show
@account = current_account @account = current_account
@domains = current_account.followers.reorder('MIN(follows.id) DESC').group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10) @domains = current_account.followers.reorder('MIN(follows.id) DESC').group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)

View File

@ -1,9 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::ImportsController < ApplicationController class Settings::ImportsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_account before_action :set_account
def show def show

View File

@ -1,9 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::KeywordMutesController < ApplicationController class Settings::KeywordMutesController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :load_keyword_mute, only: [:edit, :update, :destroy] before_action :load_keyword_mute, only: [:edit, :update, :destroy]
def index def index

View File

@ -1,10 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::NotificationsController < ApplicationController class Settings::NotificationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show; end def show; end
def update def update

View File

@ -1,10 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::PreferencesController < ApplicationController class Settings::PreferencesController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show; end def show; end
def update def update
@ -42,7 +38,8 @@ class Settings::PreferencesController < ApplicationController
:setting_reduce_motion, :setting_reduce_motion,
:setting_system_font_ui, :setting_system_font_ui,
:setting_noindex, :setting_noindex,
:setting_theme, :setting_flavour,
:setting_skin,
notification_emails: %i(follow follow_request reblog favourite mention digest), notification_emails: %i(follow follow_request reblog favourite mention digest),
interactions: %i(must_be_follower must_be_following) interactions: %i(must_be_follower must_be_following)
) )

View File

@ -1,11 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::ProfilesController < ApplicationController class Settings::ProfilesController < Settings::BaseController
include ObfuscateFilename include ObfuscateFilename
layout 'admin'
before_action :authenticate_user!
before_action :set_account before_action :set_account
obfuscate_filename [:account, :avatar] obfuscate_filename [:account, :avatar]

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# Intentionally does not inherit from BaseController
class Settings::SessionsController < ApplicationController class Settings::SessionsController < ApplicationController
before_action :set_session, only: :destroy before_action :set_session, only: :destroy

View File

@ -1,10 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module Settings module Settings
class TwoFactorAuthenticationsController < ApplicationController class TwoFactorAuthenticationsController < BaseController
layout 'admin'
before_action :authenticate_user!
before_action :verify_otp_required, only: [:create] before_action :verify_otp_required, only: [:create]
def show def show

View File

@ -4,6 +4,7 @@ class SharesController < ApplicationController
layout 'modal' layout 'modal'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
def show def show
@ -24,6 +25,10 @@ class SharesController < ApplicationController
} }
end end
def set_pack
use_pack 'share'
end
def set_body_classes def set_body_classes
@body_classes = 'compose-standalone' @body_classes = 'compose-standalone'
end end

View File

@ -14,6 +14,7 @@ class StatusesController < ApplicationController
def show def show
respond_to do |format| respond_to do |format|
format.html do format.html do
use_pack 'public'
@ancestors = @status.reply? ? cache_collection(@status.ancestors(current_account), Status) : [] @ancestors = @status.reply? ? cache_collection(@status.ancestors(current_account), Status) : []
@descendants = cache_collection(@status.descendants(current_account), Status) @descendants = cache_collection(@status.descendants(current_account), Status)
@ -37,6 +38,7 @@ class StatusesController < ApplicationController
end end
def embed def embed
use_pack 'embed'
response.headers['X-Frame-Options'] = 'ALLOWALL' response.headers['X-Frame-Options'] = 'ALLOWALL'
render 'stream_entries/embed', layout: 'embedded' render 'stream_entries/embed', layout: 'embedded'
end end

View File

@ -14,6 +14,7 @@ class StreamEntriesController < ApplicationController
def show def show
respond_to do |format| respond_to do |format|
format.html do format.html do
use_pack 'public'
@ancestors = @stream_entry.activity.reply? ? cache_collection(@stream_entry.activity.ancestors(current_account), Status) : [] @ancestors = @stream_entry.activity.reply? ? cache_collection(@stream_entry.activity.ancestors(current_account), Status) : []
@descendants = cache_collection(@stream_entry.activity.descendants(current_account), Status) @descendants = cache_collection(@stream_entry.activity.descendants(current_account), Status)
end end

View File

@ -9,6 +9,7 @@ class TagsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
use_pack 'about'
serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer) serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
@initial_state_json = serializable_resource.to_json @initial_state_json = serializable_resource.to_json
end end

View File

@ -1,3 +1,5 @@
// This file will be loaded on admin pages, regardless of theme.
import { delegate } from 'rails-ujs'; import { delegate } from 'rails-ujs';
function handleDeleteStatus(event) { function handleDeleteStatus(event) {

View File

@ -0,0 +1,8 @@
// This file will be loaded on all pages, regardless of theme.
import { start } from 'rails-ujs';
import 'font-awesome/css/font-awesome.css';
require.context('../images/', true);
start();

View File

@ -0,0 +1,23 @@
// This file will be loaded on embed pages, regardless of theme.
window.addEventListener('message', e => {
const data = e.data || {};
if (!window.parent || data.type !== 'setHeight') {
return;
}
function setEmbedHeight () {
window.parent.postMessage({
type: 'setHeight',
id: data.id,
height: document.getElementsByTagName('html')[0].scrollHeight,
}, '*');
};
if (['interactive', 'complete'].includes(document.readyState)) {
setEmbedHeight();
} else {
document.addEventListener('DOMContentLoaded', setEmbedHeight);
}
});

View File

@ -0,0 +1,25 @@
// This file will be loaded on public pages, regardless of theme.
const { delegate } = require('rails-ujs');
delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
if (button !== 0) {
return true;
}
window.location.href = target.href;
return false;
});
delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
const contentEl = target.parentNode.parentNode.querySelector('.e-content');
if (contentEl.style.display === 'block') {
contentEl.style.display = 'none';
target.parentNode.style.marginBottom = 0;
} else {
contentEl.style.display = 'block';
target.parentNode.style.marginBottom = null;
}
return false;
});

View File

@ -0,0 +1,43 @@
// This file will be loaded on settings pages, regardless of theme.
const { length } = require('stringz');
const { delegate } = require('rails-ujs');
import { processBio } from 'flavours/glitch/util/bio_metadata';
delegate(document, '.account_display_name', 'input', ({ target }) => {
const nameCounter = document.querySelector('.name-counter');
if (nameCounter) {
nameCounter.textContent = 30 - length(target.value);
}
});
delegate(document, '.account_note', 'input', ({ target }) => {
const noteCounter = document.querySelector('.note-counter');
if (noteCounter) {
const noteWithoutMetadata = processBio(target.value).text;
noteCounter.textContent = 500 - length(noteWithoutMetadata);
}
});
delegate(document, '#account_avatar', 'change', ({ target }) => {
const avatar = document.querySelector('.card.compact .avatar img');
const [file] = target.files || [];
const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
avatar.src = url;
});
delegate(document, '#account_header', 'change', ({ target }) => {
const header = document.querySelector('.card.compact');
const [file] = target.files || [];
const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
header.style.backgroundImage = `url(${url})`;
});
delegate(document, '#user_setting_flavour, #user_setting_skin', 'change', ({ target }) => {
target.form.submit();
});

View File

@ -0,0 +1,16 @@
# These packs will be loaded on every appropriate page, regardless of
# theme.
pack:
about:
admin: admin.js
auth:
common:
filename: common.js
stylesheet: true
embed: embed.js
error:
home:
modal:
public: public.js
settings: settings.js
share:

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST'; export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS'; export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
import { fetchRelationships } from './accounts'; import { fetchRelationships } from './accounts';
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST'; export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';

View File

@ -1,4 +1,4 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
export const STATUS_CARD_FETCH_REQUEST = 'STATUS_CARD_FETCH_REQUEST'; export const STATUS_CARD_FETCH_REQUEST = 'STATUS_CARD_FETCH_REQUEST';
export const STATUS_CARD_FETCH_SUCCESS = 'STATUS_CARD_FETCH_SUCCESS'; export const STATUS_CARD_FETCH_SUCCESS = 'STATUS_CARD_FETCH_SUCCESS';

View File

@ -1,6 +1,6 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import { search as emojiSearch } from 'themes/glitch/util/emoji/emoji_mart_search_light'; import { search as emojiSearch } from 'flavours/glitch/util/emoji/emoji_mart_search_light';
import { useEmoji } from './emojis'; import { useEmoji } from './emojis';
import { import {

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
export const DOMAIN_BLOCK_REQUEST = 'DOMAIN_BLOCK_REQUEST'; export const DOMAIN_BLOCK_REQUEST = 'DOMAIN_BLOCK_REQUEST';
export const DOMAIN_BLOCK_SUCCESS = 'DOMAIN_BLOCK_SUCCESS'; export const DOMAIN_BLOCK_SUCCESS = 'DOMAIN_BLOCK_SUCCESS';

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST'; export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS'; export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';

View File

@ -1,4 +1,4 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
export const REBLOG_REQUEST = 'REBLOG_REQUEST'; export const REBLOG_REQUEST = 'REBLOG_REQUEST';
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS'; export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';

View File

@ -1,6 +1,6 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
import { fetchRelationships } from './accounts'; import { fetchRelationships } from './accounts';
import { openModal } from 'themes/glitch/actions/modal'; import { openModal } from 'flavours/glitch/actions/modal';
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST'; export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS'; export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import IntlMessageFormat from 'intl-messageformat'; import IntlMessageFormat from 'intl-messageformat';
import { fetchRelationships } from './accounts'; import { fetchRelationships } from './accounts';

View File

@ -1,10 +1,10 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST'; export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST';
export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS'; export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS';
export const PINNED_STATUSES_FETCH_FAIL = 'PINNED_STATUSES_FETCH_FAIL'; export const PINNED_STATUSES_FETCH_FAIL = 'PINNED_STATUSES_FETCH_FAIL';
import { me } from 'themes/glitch/util/initial_state'; import { me } from 'flavours/glitch/util/initial_state';
export function fetchPinnedStatuses() { export function fetchPinnedStatuses() {
return (dispatch, getState) => { return (dispatch, getState) => {

View File

@ -1,4 +1,4 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
import { openModal, closeModal } from './modal'; import { openModal, closeModal } from './modal';
export const REPORT_INIT = 'REPORT_INIT'; export const REPORT_INIT = 'REPORT_INIT';

View File

@ -1,4 +1,4 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
export const SEARCH_CHANGE = 'SEARCH_CHANGE'; export const SEARCH_CHANGE = 'SEARCH_CHANGE';
export const SEARCH_CLEAR = 'SEARCH_CLEAR'; export const SEARCH_CLEAR = 'SEARCH_CLEAR';

View File

@ -1,4 +1,4 @@
import api from 'themes/glitch/util/api'; import api from 'flavours/glitch/util/api';
import { deleteFromTimelines } from './timelines'; import { deleteFromTimelines } from './timelines';
import { fetchStatusCard } from './cards'; import { fetchStatusCard } from './cards';

View File

@ -1,4 +1,4 @@
import { connectStream } from 'themes/glitch/util/stream'; import { connectStream } from 'flavours/glitch/util/stream';
import { import {
updateTimeline, updateTimeline,
deleteFromTimelines, deleteFromTimelines,

View File

@ -1,4 +1,4 @@
import api, { getLinks } from 'themes/glitch/util/api'; import api, { getLinks } from 'flavours/glitch/util/api';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';

View File

@ -7,7 +7,7 @@ import Permalink from './permalink';
import IconButton from './icon_button'; import IconButton from './icon_button';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { me } from 'themes/glitch/util/initial_state'; import { me } from 'flavours/glitch/util/initial_state';
const messages = defineMessages({ const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' }, follow: { id: 'account.follow', defaultMessage: 'Follow' },

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import unicodeMapping from 'themes/glitch/util/emoji/emoji_unicode_mapping_light'; import unicodeMapping from 'flavours/glitch/util/emoji/emoji_unicode_mapping_light';
const assetHost = process.env.CDN_HOST || ''; const assetHost = process.env.CDN_HOST || '';

View File

@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import AutosuggestAccountContainer from 'themes/glitch/features/compose/containers/autosuggest_account_container'; import AutosuggestAccountContainer from 'flavours/glitch/features/compose/containers/autosuggest_account_container';
import AutosuggestEmoji from './autosuggest_emoji'; import AutosuggestEmoji from './autosuggest_emoji';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { isRtl } from 'themes/glitch/util/rtl'; import { isRtl } from 'flavours/glitch/util/rtl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import Textarea from 'react-textarea-autosize'; import Textarea from 'react-textarea-autosize';
import classNames from 'classnames'; import classNames from 'classnames';

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import Motion from 'themes/glitch/util/optional_motion'; import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import detectPassiveEvents from 'detect-passive-events'; import detectPassiveEvents from 'detect-passive-events';
import { scrollTop } from 'themes/glitch/util/scroll'; import { scrollTop } from 'flavours/glitch/util/scroll';
export default class Column extends React.PureComponent { export default class Column extends React.PureComponent {

View File

@ -4,8 +4,7 @@ import classNames from 'classnames';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
// Glitch imports import NotificationPurgeButtonsContainer from 'flavours/glitch/containers/notification_purge_buttons_container';
import NotificationPurgeButtonsContainer from 'themes/glitch/containers/notification_purge_buttons_container';
const messages = defineMessages({ const messages = defineMessages({
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from './icon_button'; import IconButton from './icon_button';
import Overlay from 'react-overlays/lib/Overlay'; import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'themes/glitch/util/optional_motion'; import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import detectPassiveEvents from 'detect-passive-events'; import detectPassiveEvents from 'detect-passive-events';

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import Motion from 'themes/glitch/util/optional_motion'; import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import scheduleIdleTask from 'themes/glitch/util/schedule_idle_task'; import scheduleIdleTask from 'flavours/glitch/util/schedule_idle_task';
import getRectFromEntry from 'themes/glitch/util/get_rect_from_entry'; import getRectFromEntry from 'flavours/glitch/util/get_rect_from_entry';
import { is } from 'immutable'; import { is } from 'immutable';
// Diff these props in the "rendered" state // Diff these props in the "rendered" state

View File

@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
import { is } from 'immutable'; import { is } from 'immutable';
import IconButton from './icon_button'; import IconButton from './icon_button';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { isIOS } from 'themes/glitch/util/is_mobile'; import { isIOS } from 'flavours/glitch/util/is_mobile';
import classNames from 'classnames'; import classNames from 'classnames';
import { autoPlayGif } from 'themes/glitch/util/initial_state'; import { autoPlayGif } from 'flavours/glitch/util/initial_state';
const messages = defineMessages({ const messages = defineMessages({
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }, toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },

View File

@ -1,13 +1,13 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { ScrollContainer } from 'react-router-scroll-4'; import { ScrollContainer } from 'react-router-scroll-4';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import IntersectionObserverArticleContainer from 'themes/glitch/containers/intersection_observer_article_container'; import IntersectionObserverArticleContainer from 'flavours/glitch/containers/intersection_observer_article_container';
import LoadMore from './load_more'; import LoadMore from './load_more';
import IntersectionObserverWrapper from 'themes/glitch/util/intersection_observer_wrapper'; import IntersectionObserverWrapper from 'flavours/glitch/util/intersection_observer_wrapper';
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import classNames from 'classnames'; import classNames from 'classnames';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'themes/glitch/util/fullscreen'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'flavours/glitch/util/fullscreen';
export default class ScrollableList extends PureComponent { export default class ScrollableList extends PureComponent {

View File

@ -6,9 +6,9 @@ import StatusHeader from './status_header';
import StatusContent from './status_content'; import StatusContent from './status_content';
import StatusActionBar from './status_action_bar'; import StatusActionBar from './status_action_bar';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { MediaGallery, Video } from 'themes/glitch/util/async-components'; import { MediaGallery, Video } from 'flavours/glitch/util/async-components';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import NotificationOverlayContainer from 'themes/glitch/features/notifications/containers/overlay_container'; import NotificationOverlayContainer from 'flavours/glitch/features/notifications/containers/overlay_container';
import classNames from 'classnames'; import classNames from 'classnames';
// We use the component (and not the container) since we do not want // We use the component (and not the container) since we do not want

View File

@ -1,14 +1,11 @@
// THIS FILE EXISTS FOR UPSTREAM COMPATIBILITY & SHOULDN'T BE USED !!
// SEE INSTEAD : glitch/components/status/action_bar
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import IconButton from './icon_button'; import IconButton from './icon_button';
import DropdownMenuContainer from 'themes/glitch/containers/dropdown_menu_container'; import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { me } from 'themes/glitch/util/initial_state'; import { me } from 'flavours/glitch/util/initial_state';
import RelativeTimestamp from './relative_timestamp'; import RelativeTimestamp from './relative_timestamp';
const messages = defineMessages({ const messages = defineMessages({

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { isRtl } from 'themes/glitch/util/rtl'; import { isRtl } from 'flavours/glitch/util/rtl';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Permalink from './permalink'; import Permalink from './permalink';
import classnames from 'classnames'; import classnames from 'classnames';

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import StatusContainer from 'themes/glitch/containers/status_container'; import StatusContainer from 'flavours/glitch/containers/status_container';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import ScrollableList from './scrollable_list'; import ScrollableList from './scrollable_list';

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { makeGetAccount } from 'themes/glitch/selectors'; import { makeGetAccount } from 'flavours/glitch/selectors';
import Account from 'themes/glitch/components/account'; import Account from 'flavours/glitch/components/account';
import { import {
followAccount, followAccount,
unfollowAccount, unfollowAccount,
@ -10,10 +10,10 @@ import {
unblockAccount, unblockAccount,
muteAccount, muteAccount,
unmuteAccount, unmuteAccount,
} from 'themes/glitch/actions/accounts'; } from 'flavours/glitch/actions/accounts';
import { openModal } from 'themes/glitch/actions/modal'; import { openModal } from 'flavours/glitch/actions/modal';
import { initMuteModal } from 'themes/glitch/actions/mutes'; import { initMuteModal } from 'flavours/glitch/actions/mutes';
import { unfollowModal } from 'themes/glitch/util/initial_state'; import { unfollowModal } from 'flavours/glitch/util/initial_state';
const messages = defineMessages({ const messages = defineMessages({
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' }, unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Card from 'themes/glitch/features/status/components/card'; import Card from 'flavours/glitch/features/status/components/card';
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
export default class CardContainer extends React.PureComponent { export default class CardContainer extends React.PureComponent {

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import configureStore from 'themes/glitch/store/configureStore'; import configureStore from 'flavours/glitch/store/configureStore';
import { hydrateStore } from 'themes/glitch/actions/store'; import { hydrateStore } from 'flavours/glitch/actions/store';
import { IntlProvider, addLocaleData } from 'react-intl'; import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from 'mastodon/locales'; import { getLocale } from 'mastodon/locales';
import Compose from 'themes/glitch/features/standalone/compose'; import Compose from 'flavours/glitch/features/standalone/compose';
import initialState from 'themes/glitch/util/initial_state'; import initialState from 'flavours/glitch/util/initial_state';
const { localeData, messages } = getLocale(); const { localeData, messages } = getLocale();
addLocaleData(localeData); addLocaleData(localeData);

View File

@ -1,7 +1,7 @@
import { openModal, closeModal } from 'themes/glitch/actions/modal'; import { openModal, closeModal } from 'flavours/glitch/actions/modal';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import DropdownMenu from 'themes/glitch/components/dropdown_menu'; import DropdownMenu from 'flavours/glitch/components/dropdown_menu';
import { isUserTouching } from 'themes/glitch/util/is_mobile'; import { isUserTouching } from 'flavours/glitch/util/is_mobile';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
isModalOpen: state.get('modal').modalType === 'ACTIONS', isModalOpen: state.get('modal').modalType === 'ACTIONS',

View File

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import IntersectionObserverArticle from 'themes/glitch/components/intersection_observer_article'; import IntersectionObserverArticle from 'flavours/glitch/components/intersection_observer_article';
import { setHeight } from 'themes/glitch/actions/height_cache'; import { setHeight } from 'flavours/glitch/actions/height_cache';
const makeMapStateToProps = (state, props) => ({ const makeMapStateToProps = (state, props) => ({
cachedHeight: state.getIn(['height_cache', props.saveHeightKey, props.id]), cachedHeight: state.getIn(['height_cache', props.saveHeightKey, props.id]),

Some files were not shown because too many files have changed in this diff Show More