Compare commits
1 Commits
no-dm-opti
...
feature/ke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
307a8dfad0 |
@@ -1,36 +1,21 @@
|
||||
version: "2"
|
||||
checks:
|
||||
argument-count:
|
||||
enabled: false
|
||||
complex-logic:
|
||||
enabled: false
|
||||
file-lines:
|
||||
enabled: false
|
||||
method-complexity:
|
||||
enabled: false
|
||||
method-count:
|
||||
enabled: false
|
||||
method-lines:
|
||||
enabled: false
|
||||
nested-control-flow:
|
||||
enabled: false
|
||||
return-statements:
|
||||
enabled: false
|
||||
similar-code:
|
||||
enabled: false
|
||||
identical-code:
|
||||
enabled: false
|
||||
plugins:
|
||||
engines:
|
||||
brakeman:
|
||||
enabled: true
|
||||
bundler-audit:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: false
|
||||
eslint:
|
||||
enabled: true
|
||||
rubocop:
|
||||
enabled: true
|
||||
scss-lint:
|
||||
enabled: true
|
||||
exclude_patterns:
|
||||
ratings:
|
||||
paths:
|
||||
- "**.rb"
|
||||
- "**.js"
|
||||
- "**.scss"
|
||||
exclude_paths:
|
||||
- spec/
|
||||
- vendor/asset
|
||||
|
||||
3
.gitmodules
vendored
@@ -0,0 +1,3 @@
|
||||
[submodule "app/javascript/themes/mastodon-go"]
|
||||
path = app/javascript/themes/mastodon-go
|
||||
url = https://github.com/marrus-sh/mastodon-go
|
||||
|
||||
@@ -27,14 +27,11 @@ addons:
|
||||
apt:
|
||||
sources:
|
||||
- trusty-media
|
||||
- sourceline: deb https://dl.yarnpkg.com/debian/ stable main
|
||||
key_url: https://dl.yarnpkg.com/debian/pubkey.gpg
|
||||
packages:
|
||||
- ffmpeg
|
||||
- libicu-dev
|
||||
- libprotobuf-dev
|
||||
- protobuf-compiler
|
||||
- yarn
|
||||
- libicu-dev
|
||||
|
||||
rvm:
|
||||
- 2.3.4
|
||||
@@ -45,6 +42,7 @@ services:
|
||||
|
||||
install:
|
||||
- nvm install
|
||||
- npm install -g yarn
|
||||
- bundle install --path=vendor/bundle --without development production --retry=3 --jobs=16
|
||||
- yarn install
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at beatrix.bitrot@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eugen@zeonfederated.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ ENV UID=991 GID=991 \
|
||||
RAILS_SERVE_STATIC_FILES=true \
|
||||
RAILS_ENV=production NODE_ENV=production
|
||||
|
||||
ARG YARN_VERSION=1.3.2
|
||||
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
||||
ARG YARN_VERSION=1.1.0
|
||||
ARG YARN_DOWNLOAD_SHA256=171c1f9ee93c488c0d774ac6e9c72649047c3f896277d88d0f805266519430f3
|
||||
ARG LIBICONV_VERSION=1.15
|
||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
||||
|
||||
|
||||
1
Gemfile
@@ -49,6 +49,7 @@ gem 'oj', '~> 3.3'
|
||||
gem 'ostatus2', '~> 2.0'
|
||||
gem 'ox', '~> 2.8'
|
||||
gem 'pundit', '~> 1.1'
|
||||
gem 'rabl', '~> 0.13'
|
||||
gem 'rack-attack', '~> 5.0'
|
||||
gem 'rack-cors', '~> 0.4', require: 'rack/cors'
|
||||
gem 'rack-timeout', '~> 0.4'
|
||||
|
||||
90
Gemfile.lock
@@ -24,11 +24,11 @@ GEM
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_model_serializers (0.10.7)
|
||||
active_model_serializers (0.10.6)
|
||||
actionpack (>= 4.1, < 6)
|
||||
activemodel (>= 4.1, < 6)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
||||
active_record_query_trace (1.5.4)
|
||||
activejob (5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
@@ -83,15 +83,15 @@ GEM
|
||||
capistrano-bundler (1.3.0)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-rails (1.3.1)
|
||||
capistrano-rails (1.3.0)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rbenv (2.1.3)
|
||||
capistrano-rbenv (2.1.2)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.3)
|
||||
capistrano-yarn (2.0.2)
|
||||
capistrano (~> 3.0)
|
||||
capybara (2.16.1)
|
||||
capybara (2.15.4)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (>= 1.3.3)
|
||||
@@ -113,7 +113,7 @@ GEM
|
||||
connection_pool (2.2.1)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.3)
|
||||
crass (1.0.2)
|
||||
debug_inspector (0.0.3)
|
||||
devise (4.3.0)
|
||||
bcrypt (~> 3.0)
|
||||
@@ -121,11 +121,11 @@ GEM
|
||||
railties (>= 4.1.0, < 5.2)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (3.0.2)
|
||||
activesupport (< 5.2)
|
||||
devise-two-factor (3.0.0)
|
||||
activesupport
|
||||
attr_encrypted (>= 1.3, < 4, != 2)
|
||||
devise (~> 4.0)
|
||||
railties (< 5.2)
|
||||
railties
|
||||
rotp (~> 2.0)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
@@ -184,7 +184,7 @@ GEM
|
||||
http (~> 2.2)
|
||||
nokogiri (~> 1.8)
|
||||
oj (~> 3.0)
|
||||
hamlit (2.8.5)
|
||||
hamlit (2.8.4)
|
||||
temple (>= 0.8.0)
|
||||
thor
|
||||
tilt
|
||||
@@ -196,7 +196,7 @@ GEM
|
||||
hamster (3.0.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
hashdiff (0.3.7)
|
||||
highline (1.7.10)
|
||||
highline (1.7.8)
|
||||
hiredis (0.6.1)
|
||||
hkdf (0.3.0)
|
||||
htmlentities (4.3.4)
|
||||
@@ -213,9 +213,9 @@ GEM
|
||||
httplog (0.99.7)
|
||||
colorize
|
||||
rack
|
||||
i18n (0.9.1)
|
||||
i18n (0.9.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (0.9.19)
|
||||
i18n-tasks (0.9.18)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
easy_translate (>= 0.5.0)
|
||||
@@ -236,8 +236,8 @@ GEM
|
||||
json-ld (~> 2.1, >= 2.1.5)
|
||||
multi_json (~> 1.11)
|
||||
rdf (~> 2.2)
|
||||
jsonapi-renderer (0.2.0)
|
||||
jwt (2.1.0)
|
||||
jsonapi-renderer (0.1.3)
|
||||
jwt (1.5.6)
|
||||
kaminari (1.1.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
@@ -267,8 +267,8 @@ GEM
|
||||
loofah (2.1.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.0)
|
||||
mini_mime (>= 0.1.1)
|
||||
mail (2.6.6)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mario-redis-lock (1.2.0)
|
||||
redis (~> 3, >= 3.0.5)
|
||||
method_source (0.9.0)
|
||||
@@ -279,7 +279,7 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.2)
|
||||
mini_mime (1.0.0)
|
||||
mini_mime (0.1.4)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.10.3)
|
||||
msgpack (1.1.0)
|
||||
@@ -305,7 +305,7 @@ GEM
|
||||
http (~> 2.0)
|
||||
nokogiri (~> 1.6)
|
||||
openssl (~> 2.0)
|
||||
ox (2.8.2)
|
||||
ox (2.8.1)
|
||||
paperclip (5.1.0)
|
||||
activemodel (>= 4.2.0)
|
||||
activesupport (>= 4.2.0)
|
||||
@@ -316,24 +316,26 @@ GEM
|
||||
av (~> 0.9.0)
|
||||
paperclip (>= 2.5.2)
|
||||
parallel (1.12.0)
|
||||
parallel_tests (2.19.0)
|
||||
parallel_tests (2.17.0)
|
||||
parallel
|
||||
parser (2.4.0.2)
|
||||
ast (~> 2.3)
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
pg (0.21.0)
|
||||
pghero (1.7.0)
|
||||
activerecord
|
||||
pkg-config (1.2.8)
|
||||
powerpack (0.1.1)
|
||||
pry (0.11.3)
|
||||
pry (0.11.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-rails (0.3.6)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (3.0.1)
|
||||
puma (3.11.0)
|
||||
public_suffix (3.0.0)
|
||||
puma (3.10.0)
|
||||
pundit (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
rabl (0.13.1)
|
||||
activesupport (>= 2.3.14)
|
||||
rack (2.0.3)
|
||||
rack-attack (5.0.1)
|
||||
rack
|
||||
@@ -342,7 +344,7 @@ GEM
|
||||
rack
|
||||
rack-proxy (0.6.2)
|
||||
rack
|
||||
rack-test (0.8.2)
|
||||
rack-test (0.7.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-timeout (0.4.2)
|
||||
rails (5.1.4)
|
||||
@@ -379,11 +381,8 @@ GEM
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
rake (12.3.0)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
rdf (2.2.12)
|
||||
rake (12.2.1)
|
||||
rdf (2.2.11)
|
||||
hamster (~> 3.0)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdf-normalize (0.3.2)
|
||||
@@ -396,8 +395,8 @@ GEM
|
||||
redis-activesupport (5.0.4)
|
||||
activesupport (>= 3, < 6)
|
||||
redis-store (>= 1.3, < 2)
|
||||
redis-namespace (1.6.0)
|
||||
redis (>= 3.0.4)
|
||||
redis-namespace (1.5.3)
|
||||
redis (~> 3.0, >= 3.0.4)
|
||||
redis-rack (2.0.3)
|
||||
rack (>= 1.5, < 3)
|
||||
redis-store (>= 1.2, < 2)
|
||||
@@ -422,7 +421,7 @@ GEM
|
||||
rspec-mocks (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-rails (3.7.2)
|
||||
rspec-rails (3.7.1)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
@@ -450,14 +449,10 @@ GEM
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.4.4)
|
||||
nokogumbo (~> 1.4.1)
|
||||
sass (3.5.3)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
scss_lint (0.56.0)
|
||||
sass (3.4.25)
|
||||
scss_lint (0.55.0)
|
||||
rake (>= 0.9, < 13)
|
||||
sass (~> 3.5.3)
|
||||
sass (~> 3.4.20)
|
||||
sidekiq (5.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
@@ -491,7 +486,7 @@ GEM
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sshkit (1.15.1)
|
||||
sshkit (1.14.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
statsd-ruby (1.2.1)
|
||||
@@ -519,7 +514,7 @@ GEM
|
||||
uniform_notifier (1.10.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webmock (3.1.1)
|
||||
webmock (3.1.0)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
@@ -527,12 +522,12 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 4.2)
|
||||
webpush (0.3.3)
|
||||
webpush (0.3.2)
|
||||
hkdf (~> 0.2)
|
||||
jwt (~> 2.0)
|
||||
jwt
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.2)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
@@ -604,6 +599,7 @@ DEPENDENCIES
|
||||
pry-rails (~> 0.3)
|
||||
puma (~> 3.10)
|
||||
pundit (~> 1.1)
|
||||
rabl (~> 0.13)
|
||||
rack-attack (~> 5.0)
|
||||
rack-cors (~> 0.4)
|
||||
rack-timeout (~> 0.4)
|
||||
@@ -642,4 +638,4 @@ RUBY VERSION
|
||||
ruby 2.4.2p198
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.0
|
||||
1.15.4
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AboutController < ApplicationController
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_instance_presenter, only: [:show, :more, :terms]
|
||||
|
||||
@@ -22,10 +21,6 @@ class AboutController < ApplicationController
|
||||
|
||||
helper_method :new_user
|
||||
|
||||
def set_pack
|
||||
use_pack action_name == 'show' ? 'about' : 'common'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
@@ -7,7 +7,6 @@ class AccountsController < ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
@pinned_statuses = []
|
||||
|
||||
if current_account && @account.blocking?(current_account)
|
||||
|
||||
@@ -21,7 +21,7 @@ module Admin
|
||||
|
||||
def destroy
|
||||
authorize @account_moderation_note, :destroy?
|
||||
@account_moderation_note.destroy!
|
||||
@account_moderation_note.destroy
|
||||
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.destroyed_msg')
|
||||
end
|
||||
|
||||
|
||||
@@ -32,21 +32,18 @@ module Admin
|
||||
def memorialize
|
||||
authorize @account, :memorialize?
|
||||
@account.memorialize!
|
||||
log_action :memorialize, @account
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def enable
|
||||
authorize @account.user, :enable?
|
||||
@account.user.enable!
|
||||
log_action :enable, @account.user
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize @account.user, :disable?
|
||||
@account.user.disable!
|
||||
log_action :disable, @account.user
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class ActionLogsController < BaseController
|
||||
def index
|
||||
@action_logs = Admin::ActionLog.page(params[:page])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,15 +3,9 @@
|
||||
module Admin
|
||||
class BaseController < ApplicationController
|
||||
include Authorization
|
||||
include AccountableConcern
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :require_staff!
|
||||
before_action :set_pack
|
||||
|
||||
def set_pack
|
||||
use_pack 'admin'
|
||||
end
|
||||
layout 'admin'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,6 @@ module Admin
|
||||
def create
|
||||
authorize @user, :confirm?
|
||||
@user.confirm!
|
||||
log_action :confirm, @user
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ module Admin
|
||||
@custom_emoji = CustomEmoji.new(resource_params)
|
||||
|
||||
if @custom_emoji.save
|
||||
log_action :create, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.created_msg')
|
||||
else
|
||||
render :new
|
||||
@@ -31,7 +30,6 @@ module Admin
|
||||
authorize @custom_emoji, :update?
|
||||
|
||||
if @custom_emoji.update(resource_params)
|
||||
log_action :update, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.updated_msg')
|
||||
else
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.update_failed_msg')
|
||||
@@ -40,8 +38,7 @@ module Admin
|
||||
|
||||
def destroy
|
||||
authorize @custom_emoji, :destroy?
|
||||
@custom_emoji.destroy!
|
||||
log_action :destroy, @custom_emoji
|
||||
@custom_emoji.destroy
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.destroyed_msg')
|
||||
end
|
||||
|
||||
@@ -52,7 +49,6 @@ module Admin
|
||||
emoji.image = @custom_emoji.image
|
||||
|
||||
if emoji.save
|
||||
log_action :create, emoji
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.copied_msg')
|
||||
else
|
||||
flash[:alert] = I18n.t('admin.custom_emojis.copy_failed_msg')
|
||||
@@ -64,14 +60,12 @@ module Admin
|
||||
def enable
|
||||
authorize @custom_emoji, :enable?
|
||||
@custom_emoji.update!(disabled: false)
|
||||
log_action :enable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.enabled_msg')
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize @custom_emoji, :disable?
|
||||
@custom_emoji.update!(disabled: true)
|
||||
log_action :disable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.disabled_msg')
|
||||
end
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ module Admin
|
||||
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
log_action :create, @domain_block
|
||||
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg')
|
||||
else
|
||||
render :new
|
||||
@@ -35,7 +34,6 @@ module Admin
|
||||
def destroy
|
||||
authorize @domain_block, :destroy?
|
||||
UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
|
||||
log_action :destroy, @domain_block
|
||||
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg')
|
||||
end
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ module Admin
|
||||
@email_domain_block = EmailDomainBlock.new(resource_params)
|
||||
|
||||
if @email_domain_block.save
|
||||
log_action :create, @email_domain_block
|
||||
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
|
||||
else
|
||||
render :new
|
||||
@@ -29,8 +28,7 @@ module Admin
|
||||
|
||||
def destroy
|
||||
authorize @email_domain_block, :destroy?
|
||||
@email_domain_block.destroy!
|
||||
log_action :destroy, @email_domain_block
|
||||
@email_domain_block.destroy
|
||||
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.destroyed_msg')
|
||||
end
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class InvitesController < BaseController
|
||||
def index
|
||||
authorize :invite, :index?
|
||||
|
||||
@invites = filtered_invites.includes(user: :account).page(params[:page])
|
||||
@invite = Invite.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :invite, :create?
|
||||
|
||||
@invite = Invite.new(resource_params)
|
||||
@invite.user = current_user
|
||||
|
||||
if @invite.save
|
||||
redirect_to admin_invites_path
|
||||
else
|
||||
@invites = Invite.page(params[:page])
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@invite = Invite.find(params[:id])
|
||||
authorize @invite, :destroy?
|
||||
@invite.expire!
|
||||
redirect_to admin_invites_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:invite).permit(:max_uses, :expires_in)
|
||||
end
|
||||
|
||||
def filtered_invites
|
||||
InviteFilter.new(filter_params).results
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.permit(:available, :expired)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,7 +8,7 @@ module Admin
|
||||
def create
|
||||
authorize :status, :update?
|
||||
|
||||
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
|
||||
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||
|
||||
redirect_to admin_report_path(@report)
|
||||
@@ -16,15 +16,13 @@ module Admin
|
||||
|
||||
def update
|
||||
authorize @status, :update?
|
||||
@status.update!(status_params)
|
||||
log_action :update, @status
|
||||
@status.update(status_params)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @status, :destroy?
|
||||
RemovalWorker.perform_async(@status.id)
|
||||
log_action :destroy, @status
|
||||
render json: @status
|
||||
end
|
||||
|
||||
|
||||
@@ -25,17 +25,12 @@ module Admin
|
||||
def process_report
|
||||
case params[:outcome].to_s
|
||||
when 'resolve'
|
||||
@report.update!(action_taken_by_current_attributes)
|
||||
log_action :resolve, @report
|
||||
@report.update(action_taken_by_current_attributes)
|
||||
when 'suspend'
|
||||
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||
log_action :resolve, @report
|
||||
log_action :suspend, @report.target_account
|
||||
resolve_all_target_account_reports
|
||||
when 'silence'
|
||||
@report.target_account.update!(silenced: true)
|
||||
log_action :resolve, @report
|
||||
log_action :silence, @report.target_account
|
||||
@report.target_account.update(silenced: true)
|
||||
resolve_all_target_account_reports
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
|
||||
@@ -7,7 +7,6 @@ module Admin
|
||||
def create
|
||||
authorize @user, :reset_password?
|
||||
@user.send_reset_password_instructions
|
||||
log_action :reset_password, @user
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -7,14 +7,12 @@ module Admin
|
||||
def promote
|
||||
authorize @user, :promote?
|
||||
@user.promote!
|
||||
log_action :promote, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
def demote
|
||||
authorize @user, :demote?
|
||||
@user.demote!
|
||||
log_action :demote, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ module Admin
|
||||
show_staff_badge
|
||||
bootstrap_timeline_accounts
|
||||
thumbnail
|
||||
min_invite_role
|
||||
).freeze
|
||||
|
||||
BOOLEAN_SETTINGS = %w(
|
||||
|
||||
@@ -6,15 +6,13 @@ module Admin
|
||||
|
||||
def create
|
||||
authorize @account, :silence?
|
||||
@account.update!(silenced: true)
|
||||
log_action :silence, @account
|
||||
@account.update(silenced: true)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @account, :unsilence?
|
||||
@account.update!(silenced: false)
|
||||
log_action :unsilence, @account
|
||||
@account.update(silenced: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ module Admin
|
||||
def create
|
||||
authorize :status, :update?
|
||||
|
||||
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
|
||||
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||
|
||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||
@@ -34,15 +34,13 @@ module Admin
|
||||
|
||||
def update
|
||||
authorize @status, :update?
|
||||
@status.update!(status_params)
|
||||
log_action :update, @status
|
||||
@status.update(status_params)
|
||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @status, :destroy?
|
||||
RemovalWorker.perform_async(@status.id)
|
||||
log_action :destroy, @status
|
||||
render json: @status
|
||||
end
|
||||
|
||||
|
||||
@@ -7,14 +7,12 @@ module Admin
|
||||
def create
|
||||
authorize @account, :suspend?
|
||||
Admin::SuspensionWorker.perform_async(@account.id)
|
||||
log_action :suspend, @account
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @account, :unsuspend?
|
||||
@account.unsuspend!
|
||||
log_action :unsuspend, @account
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ module Admin
|
||||
def destroy
|
||||
authorize @user, :disable_2fa?
|
||||
@user.disable_two_factor!
|
||||
log_action :disable_2fa, @user
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -17,13 +17,12 @@ class Api::V1::Accounts::SearchController < Api::BaseController
|
||||
AccountSearchService.new.call(
|
||||
params[:q],
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
current_account,
|
||||
resolve: truthy_param?(:resolve),
|
||||
following: truthy_param?(:following)
|
||||
resolving_search?,
|
||||
current_account
|
||||
)
|
||||
end
|
||||
|
||||
def truthy_param?(key)
|
||||
params[key] == 'true'
|
||||
def resolving_search?
|
||||
params[:resolve] == 'true'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,9 +13,11 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def follow
|
||||
FollowService.new.call(current_user.account, @account.acct, reblogs: params[:reblogs])
|
||||
reblogs_arg = { reblogs: params[:reblogs] }
|
||||
|
||||
FollowService.new.call(current_user.account, @account.acct, reblogs_arg)
|
||||
|
||||
options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: params[:reblogs] } }, requested_map: { @account.id => false } }
|
||||
options = @account.locked? ? {} : { following_map: { @account.id => reblogs_arg }, requested_map: { @account.id => false } }
|
||||
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
|
||||
end
|
||||
@@ -51,7 +53,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
@account = Account.find(params[:id])
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
def relationships(options = {})
|
||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
after_action :insert_pagination_headers, only: :show
|
||||
|
||||
def show
|
||||
@accounts = load_accounts
|
||||
@accounts = @list.accounts.paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
@@ -35,14 +35,6 @@ class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
@list = List.where(account: current_account).find(params[:list_id])
|
||||
end
|
||||
|
||||
def load_accounts
|
||||
if unlimited?
|
||||
@list.accounts.all
|
||||
else
|
||||
@list.accounts.paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
||||
end
|
||||
end
|
||||
|
||||
def list_accounts
|
||||
Account.find(account_ids)
|
||||
end
|
||||
@@ -60,16 +52,12 @@ class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def next_path
|
||||
return if unlimited?
|
||||
|
||||
if records_continue?
|
||||
api_v1_list_accounts_url pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
end
|
||||
|
||||
def prev_path
|
||||
return if unlimited?
|
||||
|
||||
unless @accounts.empty?
|
||||
api_v1_list_accounts_url pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
@@ -90,8 +78,4 @@ class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def unlimited?
|
||||
params[:limit] == '0'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,8 +12,8 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
helper_method :current_account
|
||||
helper_method :current_session
|
||||
helper_method :current_flavour
|
||||
helper_method :current_skin
|
||||
helper_method :current_theme
|
||||
helper_method :theme_data
|
||||
helper_method :single_user_mode?
|
||||
|
||||
rescue_from ActionController::RoutingError, with: :not_found
|
||||
@@ -54,73 +54,6 @@ class ApplicationController < ActionController::Base
|
||||
new_user_session_path
|
||||
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', skin),
|
||||
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
|
||||
|
||||
def forbidden
|
||||
@@ -151,14 +84,13 @@ class ApplicationController < ActionController::Base
|
||||
@current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
|
||||
end
|
||||
|
||||
def current_flavour
|
||||
return Setting.default_settings['flavour'] unless Themes.instance.flavours.include? current_user&.setting_flavour
|
||||
current_user.setting_flavour
|
||||
def current_theme
|
||||
return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme
|
||||
current_user.setting_theme
|
||||
end
|
||||
|
||||
def current_skin
|
||||
return 'default' unless Themes.instance.skins_for(current_flavour).include? current_user&.setting_skin
|
||||
current_user.setting_skin
|
||||
def theme_data
|
||||
Themes.instance.get(current_theme)
|
||||
end
|
||||
|
||||
def cache_collection(raw, klass)
|
||||
|
||||
@@ -2,17 +2,10 @@
|
||||
|
||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||
layout 'auth'
|
||||
before_action :set_pack
|
||||
|
||||
def show
|
||||
super do |user|
|
||||
BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
class Auth::PasswordsController < Devise::PasswordsController
|
||||
before_action :check_validity_of_reset_password_token, only: :edit
|
||||
before_action :set_pack
|
||||
|
||||
layout 'auth'
|
||||
|
||||
@@ -18,8 +17,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
|
||||
|
||||
@@ -5,7 +5,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
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_instance_presenter, only: [:new, :create, :update]
|
||||
|
||||
@@ -17,16 +16,13 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
def build_resource(hash = nil)
|
||||
super(hash)
|
||||
|
||||
resource.locale = I18n.locale
|
||||
resource.invite_code = params[:invite_code] if resource.invite_code.blank?
|
||||
|
||||
resource.locale = I18n.locale
|
||||
resource.build_account if resource.account.nil?
|
||||
end
|
||||
|
||||
def configure_sign_up_params
|
||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
||||
u.permit({ account_attributes: [:username] }, :email, :password, :password_confirmation, :invite_code)
|
||||
u.permit({ account_attributes: [:username] }, :email, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,27 +35,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
end
|
||||
|
||||
def check_enabled_registrations
|
||||
redirect_to root_path if single_user_mode? || !allowed_registrations?
|
||||
end
|
||||
|
||||
def allowed_registrations?
|
||||
Setting.open_registrations || (invite_code.present? && Invite.find_by(code: invite_code)&.valid_for_use?)
|
||||
end
|
||||
|
||||
def invite_code
|
||||
if params[:user]
|
||||
params[:user][:invite_code]
|
||||
else
|
||||
params[:invite_code]
|
||||
end
|
||||
redirect_to root_path if single_user_mode? || !Setting.open_registrations
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
@@ -9,7 +9,6 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
skip_before_action :check_suspension, only: [:destroy]
|
||||
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
||||
before_action :set_instance_presenter, only: [:new]
|
||||
before_action :set_pack
|
||||
|
||||
def create
|
||||
super do |resource|
|
||||
@@ -86,10 +85,6 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ class AuthorizeFollowsController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
|
||||
def show
|
||||
@account = located_account || render(:error)
|
||||
@@ -24,10 +23,6 @@ class AuthorizeFollowsController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'modal'
|
||||
end
|
||||
|
||||
def follow_attempt
|
||||
FollowService.new.call(current_account, acct_without_prefix)
|
||||
end
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module AccountableConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def log_action(action, target)
|
||||
Admin::ActionLog.create(account: current_account, action: action, target: target)
|
||||
end
|
||||
end
|
||||
@@ -7,9 +7,7 @@ class FollowerAccountsController < ApplicationController
|
||||
@follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account)
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
end
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
render json: collection_presenter,
|
||||
|
||||
@@ -7,9 +7,7 @@ class FollowingAccountsController < ApplicationController
|
||||
@follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account)
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
end
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
render json: collection_presenter,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
class HomeController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
before_action :set_initial_state_json
|
||||
|
||||
def index
|
||||
@@ -38,10 +37,6 @@ class HomeController < ApplicationController
|
||||
redirect_to(default_redirect_path)
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'home'
|
||||
end
|
||||
|
||||
def set_initial_state_json
|
||||
serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
|
||||
@initial_state_json = serializable_resource.to_json
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class InvitesController < ApplicationController
|
||||
include Authorization
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
|
||||
def index
|
||||
authorize :invite, :create?
|
||||
|
||||
@invites = Invite.where(user: current_user)
|
||||
@invite = Invite.new(expires_in: 1.day.to_i)
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :invite, :create?
|
||||
|
||||
@invite = Invite.new(resource_params)
|
||||
@invite.user = current_user
|
||||
|
||||
if @invite.save
|
||||
redirect_to invites_path
|
||||
else
|
||||
@invites = Invite.where(user: current_user)
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@invite = Invite.where(user: current_user).find(params[:id])
|
||||
authorize @invite, :destroy?
|
||||
@invite.expire!
|
||||
redirect_to invites_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'settings'
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:invite).permit(:max_uses, :expires_in)
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,6 @@ class RemoteFollowController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :set_account
|
||||
before_action :set_pack
|
||||
before_action :gone, if: :suspended_account?
|
||||
|
||||
def new
|
||||
@@ -32,10 +31,6 @@ class RemoteFollowController < ApplicationController
|
||||
{ acct: session[:remote_follow] }
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'modal'
|
||||
end
|
||||
|
||||
def set_account
|
||||
@account = Account.find_local!(params[:account_username])
|
||||
end
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ApplicationsController < Settings::BaseController
|
||||
class Settings::ApplicationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_application, only: [:show, :update, :destroy, :regenerate]
|
||||
before_action :prepare_scopes, only: [:create, :update]
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 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
|
||||
@@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::DeletesController < Settings::BaseController
|
||||
class Settings::DeletesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
prepend_before_action :check_enabled_deletion
|
||||
before_action :check_enabled_deletion
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@confirmation = Form::DeleteConfirmation.new
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ExportsController < Settings::BaseController
|
||||
class Settings::ExportsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@export = Export.new(current_account)
|
||||
end
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
require 'sidekiq-bulk'
|
||||
|
||||
class Settings::FollowerDomainsController < Settings::BaseController
|
||||
class Settings::FollowerDomainsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@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)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ImportsController < Settings::BaseController
|
||||
class Settings::ImportsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_account
|
||||
|
||||
def show
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::KeywordMutesController < Settings::BaseController
|
||||
class Settings::KeywordMutesController < ApplicationController
|
||||
include UserTrackingConcern
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :load_keyword_mute, only: [:edit, :update, :destroy]
|
||||
after_action :bust_feed_caches, only: [:create, :update, :destroy]
|
||||
|
||||
def index
|
||||
@keyword_mutes = paginated_keyword_mutes_for_account
|
||||
@@ -51,6 +57,12 @@ class Settings::KeywordMutesController < Settings::BaseController
|
||||
@keyword_mute = keyword_mutes_for_account.find(params[:id])
|
||||
end
|
||||
|
||||
def bust_feed_caches
|
||||
# FIXME: this key is really meant to be an implementation detail
|
||||
Redis.current.del("account:#{current_user.account_id}:regeneration")
|
||||
regenerate_feed!
|
||||
end
|
||||
|
||||
def keyword_mute_params
|
||||
params.require(:keyword_mute).permit(:keyword, :whole_word)
|
||||
end
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::MigrationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@migration = Form::Migration.new(account: current_account.moved_to_account)
|
||||
end
|
||||
|
||||
def update
|
||||
@migration = Form::Migration.new(resource_params)
|
||||
|
||||
if @migration.valid? && migration_account_changed?
|
||||
current_account.update!(moved_to_account: @migration.account)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
|
||||
redirect_to settings_migration_path, notice: I18n.t('migrations.updated_msg')
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:migration).permit(:acct)
|
||||
end
|
||||
|
||||
def migration_account_changed?
|
||||
current_account.moved_to_account_id != @migration.account&.id
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::NotificationsController < Settings::BaseController
|
||||
class Settings::NotificationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show; end
|
||||
|
||||
def update
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::PreferencesController < Settings::BaseController
|
||||
class Settings::PreferencesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show; end
|
||||
|
||||
def update
|
||||
@@ -38,8 +42,7 @@ class Settings::PreferencesController < Settings::BaseController
|
||||
:setting_reduce_motion,
|
||||
:setting_system_font_ui,
|
||||
:setting_noindex,
|
||||
:setting_flavour,
|
||||
:setting_skin,
|
||||
:setting_theme,
|
||||
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||
interactions: %i(must_be_follower must_be_following)
|
||||
)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ProfilesController < Settings::BaseController
|
||||
class Settings::ProfilesController < ApplicationController
|
||||
include ObfuscateFilename
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_account
|
||||
|
||||
obfuscate_filename [:account, :avatar]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Intentionally does not inherit from BaseController
|
||||
class Settings::SessionsController < ApplicationController
|
||||
before_action :set_session, only: :destroy
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Settings
|
||||
class TwoFactorAuthenticationsController < BaseController
|
||||
class TwoFactorAuthenticationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :verify_otp_required, only: [:create]
|
||||
|
||||
def show
|
||||
|
||||
@@ -4,7 +4,6 @@ class SharesController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
|
||||
def show
|
||||
@@ -25,10 +24,6 @@ class SharesController < ApplicationController
|
||||
}
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'share'
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'compose-standalone'
|
||||
end
|
||||
|
||||
@@ -14,7 +14,6 @@ class StatusesController < ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
@ancestors = @status.reply? ? cache_collection(@status.ancestors(current_account), Status) : []
|
||||
@descendants = cache_collection(@status.descendants(current_account), Status)
|
||||
|
||||
@@ -38,7 +37,6 @@ class StatusesController < ApplicationController
|
||||
end
|
||||
|
||||
def embed
|
||||
use_pack 'embed'
|
||||
response.headers['X-Frame-Options'] = 'ALLOWALL'
|
||||
render 'stream_entries/embed', layout: 'embedded'
|
||||
end
|
||||
|
||||
@@ -14,7 +14,6 @@ class StreamEntriesController < ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
@ancestors = @stream_entry.activity.reply? ? cache_collection(@stream_entry.activity.ancestors(current_account), Status) : []
|
||||
@descendants = cache_collection(@stream_entry.activity.descendants(current_account), Status)
|
||||
end
|
||||
|
||||
@@ -9,7 +9,6 @@ class TagsController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'about'
|
||||
serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
|
||||
@initial_state_json = serializable_resource.to_json
|
||||
end
|
||||
|
||||
@@ -6,10 +6,12 @@ module WellKnown
|
||||
|
||||
def show
|
||||
@account = Account.find_local!(username_from_resource)
|
||||
@canonical_account_uri = @account.to_webfinger_s
|
||||
@magic_key = pem_to_magic_key(@account.keypair.public_key)
|
||||
|
||||
respond_to do |format|
|
||||
format.any(:json, :html) do
|
||||
render json: @account, serializer: WebfingerSerializer, content_type: 'application/jrd+json'
|
||||
render formats: :json, content_type: 'application/jrd+json'
|
||||
end
|
||||
|
||||
format.xml do
|
||||
@@ -33,6 +35,21 @@ module WellKnown
|
||||
WebfingerResource.new(resource_user).username
|
||||
end
|
||||
|
||||
def pem_to_magic_key(public_key)
|
||||
modulus, exponent = [public_key.n, public_key.e].map do |component|
|
||||
result = []
|
||||
|
||||
until component.zero?
|
||||
result << [component % 256].pack('C')
|
||||
component >>= 8
|
||||
end
|
||||
|
||||
result.reverse.join
|
||||
end
|
||||
|
||||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
||||
end
|
||||
|
||||
def resource_param
|
||||
params.require(:resource)
|
||||
end
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin::ActionLogsHelper
|
||||
def log_target(log)
|
||||
if log.target
|
||||
linkable_log_target(log.target)
|
||||
else
|
||||
log_target_from_history(log.target_type, log.recorded_changes)
|
||||
end
|
||||
end
|
||||
|
||||
def linkable_log_target(record)
|
||||
case record.class.name
|
||||
when 'Account'
|
||||
link_to record.acct, admin_account_path(record.id)
|
||||
when 'User'
|
||||
link_to record.account.acct, admin_account_path(record.account_id)
|
||||
when 'CustomEmoji'
|
||||
record.shortcode
|
||||
when 'Report'
|
||||
link_to "##{record.id}", admin_report_path(record)
|
||||
when 'DomainBlock', 'EmailDomainBlock'
|
||||
link_to record.domain, "https://#{record.domain}"
|
||||
when 'Status'
|
||||
link_to record.account.acct, TagManager.instance.url_for(record)
|
||||
end
|
||||
end
|
||||
|
||||
def log_target_from_history(type, attributes)
|
||||
case type
|
||||
when 'CustomEmoji'
|
||||
attributes['shortcode']
|
||||
when 'DomainBlock', 'EmailDomainBlock'
|
||||
link_to attributes['domain'], "https://#{attributes['domain']}"
|
||||
when 'Status'
|
||||
tmp_status = Status.new(attributes)
|
||||
link_to tmp_status.account.acct, TagManager.instance.url_for(tmp_status)
|
||||
end
|
||||
end
|
||||
|
||||
def relevant_log_changes(log)
|
||||
if log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)
|
||||
log.recorded_changes.slice('domain')
|
||||
elsif log.target_type == 'CustomEmoji' && log.action == :update
|
||||
log.recorded_changes.slice('domain', 'visible_in_picker')
|
||||
elsif log.target_type == 'User' && [:promote, :demote].include?(log.action)
|
||||
log.recorded_changes.slice('moderator', 'admin')
|
||||
elsif log.target_type == 'DomainBlock'
|
||||
log.recorded_changes.slice('severity', 'reject_media')
|
||||
elsif log.target_type == 'Status' && log.action == :update
|
||||
log.recorded_changes.slice('sensitive')
|
||||
end
|
||||
end
|
||||
|
||||
def log_extra_attributes(hash)
|
||||
safe_join(hash.to_a.map { |key, value| safe_join([content_tag(:span, key, class: 'diff-key'), '=', log_change(value)]) }, ' ')
|
||||
end
|
||||
|
||||
def log_change(val)
|
||||
return content_tag(:span, val, class: 'diff-neutral') unless val.is_a?(Array)
|
||||
safe_join([content_tag(:span, val.first, class: 'diff-old'), content_tag(:span, val.last, class: 'diff-new')], '→')
|
||||
end
|
||||
|
||||
def icon_for_log(log)
|
||||
case log.target_type
|
||||
when 'Account', 'User'
|
||||
'user'
|
||||
when 'CustomEmoji'
|
||||
'file'
|
||||
when 'Report'
|
||||
'flag'
|
||||
when 'DomainBlock'
|
||||
'lock'
|
||||
when 'EmailDomainBlock'
|
||||
'envelope'
|
||||
when 'Status'
|
||||
'pencil'
|
||||
end
|
||||
end
|
||||
|
||||
def class_for_log_icon(log)
|
||||
case log.action
|
||||
when :enable, :unsuspend, :unsilence, :confirm, :promote, :resolve
|
||||
'positive'
|
||||
when :create
|
||||
opposite_verbs?(log) ? 'negative' : 'positive'
|
||||
when :update, :reset_password, :disable_2fa, :memorialize
|
||||
'neutral'
|
||||
when :demote, :silence, :disable, :suspend
|
||||
'negative'
|
||||
when :destroy
|
||||
opposite_verbs?(log) ? 'positive' : 'negative'
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def opposite_verbs?(log)
|
||||
%w(DomainBlock EmailDomainBlock).include?(log.target_type)
|
||||
end
|
||||
end
|
||||
@@ -3,9 +3,8 @@
|
||||
module Admin::FilterHelper
|
||||
ACCOUNT_FILTERS = %i(local remote by_domain silenced suspended recent username display_name email ip).freeze
|
||||
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
|
||||
INVITE_FILTER = %i(available expired).freeze
|
||||
|
||||
FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER
|
||||
FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS
|
||||
|
||||
def filter_link_to(text, link_to_params, link_class_params = link_to_params)
|
||||
new_url = filtered_url_for(link_to_params)
|
||||
@@ -13,7 +12,7 @@ module Admin::FilterHelper
|
||||
link_to text, new_url, class: filter_link_class(new_class)
|
||||
end
|
||||
|
||||
def table_link_to(icon, text, path, **options)
|
||||
def table_link_to(icon, text, path, options = {})
|
||||
link_to safe_join([fa_icon(icon), text]), path, options.merge(class: 'table-action-link')
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ module ApplicationHelper
|
||||
current_page?(path) ? 'active' : ''
|
||||
end
|
||||
|
||||
def active_link_to(label, path, **options)
|
||||
def active_link_to(label, path, options = {})
|
||||
link_to label, path, options.merge(class: active_nav_class(path))
|
||||
end
|
||||
|
||||
|
||||
@@ -9,24 +9,6 @@ module JsonLdHelper
|
||||
value.is_a?(Array) ? value.first : value
|
||||
end
|
||||
|
||||
# The url attribute can be a string, an array of strings, or an array of objects.
|
||||
# The objects could include a mimeType. Not-included mimeType means it's text/html.
|
||||
def url_to_href(value, preferred_type = nil)
|
||||
single_value = if value.is_a?(Array) && !value.first.is_a?(String)
|
||||
value.find { |link| preferred_type.nil? || ((link['mimeType'].presence || 'text/html') == preferred_type) }
|
||||
elsif value.is_a?(Array)
|
||||
value.first
|
||||
else
|
||||
value
|
||||
end
|
||||
|
||||
if single_value.nil? || single_value.is_a?(String)
|
||||
single_value
|
||||
else
|
||||
single_value['href']
|
||||
end
|
||||
end
|
||||
|
||||
def as_array(value)
|
||||
value.is_a?(Array) ? value : [value]
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ module RoutingHelper
|
||||
end
|
||||
end
|
||||
|
||||
def full_asset_url(source, **options)
|
||||
def full_asset_url(source, options = {})
|
||||
source = ActionController::Base.helpers.asset_url(source, options) unless use_storage?
|
||||
|
||||
URI.join(root_url, source).to_s
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// 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();
|
||||
@@ -1,23 +0,0 @@
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
// 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;
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
// 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();
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
# 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:
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
import Column from 'flavours/glitch/features/ui/components/column';
|
||||
import MissingIndicator from 'flavours/glitch/components/missing_indicator';
|
||||
|
||||
const GenericNotFound = () => (
|
||||
<Column>
|
||||
<MissingIndicator />
|
||||
</Column>
|
||||
);
|
||||
|
||||
export default GenericNotFound;
|
||||
@@ -1,93 +0,0 @@
|
||||
// Package imports.
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
// Our imports,
|
||||
import StatusContainer from 'flavours/glitch/containers/status_container';
|
||||
import NotificationFollow from './follow';
|
||||
|
||||
export default class Notification extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
notification: ImmutablePropTypes.map.isRequired,
|
||||
hidden: PropTypes.bool,
|
||||
onMoveUp: PropTypes.func.isRequired,
|
||||
onMoveDown: PropTypes.func.isRequired,
|
||||
onMention: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
render () {
|
||||
const {
|
||||
hidden,
|
||||
notification,
|
||||
onMoveDown,
|
||||
onMoveUp,
|
||||
onMention,
|
||||
} = this.props;
|
||||
|
||||
switch(notification.get('type')) {
|
||||
case 'follow':
|
||||
return (
|
||||
<NotificationFollow
|
||||
hidden={hidden}
|
||||
id={notification.get('id')}
|
||||
account={notification.get('account')}
|
||||
notification={notification}
|
||||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
/>
|
||||
);
|
||||
case 'mention':
|
||||
return (
|
||||
<StatusContainer
|
||||
containerId={notification.get('id')}
|
||||
hidden={hidden}
|
||||
id={notification.get('status')}
|
||||
notification={notification}
|
||||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
withDismiss
|
||||
/>
|
||||
);
|
||||
case 'favourite':
|
||||
return (
|
||||
<StatusContainer
|
||||
containerId={notification.get('id')}
|
||||
hidden={hidden}
|
||||
id={notification.get('status')}
|
||||
account={notification.get('account')}
|
||||
prepend='favourite'
|
||||
muted
|
||||
notification={notification}
|
||||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
withDismiss
|
||||
/>
|
||||
);
|
||||
case 'reblog':
|
||||
return (
|
||||
<StatusContainer
|
||||
containerId={notification.get('id')}
|
||||
hidden={hidden}
|
||||
id={notification.get('status')}
|
||||
account={notification.get('account')}
|
||||
prepend='reblog'
|
||||
muted
|
||||
notification={notification}
|
||||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
withDismiss
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from 'react';
|
||||
import ComposeFormContainer from 'flavours/glitch/features/compose/containers/compose_form_container';
|
||||
import NotificationsContainer from 'flavours/glitch/features/ui/containers/notifications_container';
|
||||
import LoadingBarContainer from 'flavours/glitch/features/ui/containers/loading_bar_container';
|
||||
import ModalContainer from 'flavours/glitch/features/ui/containers/modal_container';
|
||||
|
||||
export default class Compose extends React.PureComponent {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<ComposeFormContainer />
|
||||
<NotificationsContainer />
|
||||
<ModalContainer />
|
||||
<LoadingBarContainer className='loading-bar' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import loadPolyfills from 'flavours/glitch/util/load_polyfills';
|
||||
|
||||
function loaded() {
|
||||
const TimelineContainer = require('flavours/glitch/containers/timeline_container').default;
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const mountNode = document.getElementById('mastodon-timeline');
|
||||
|
||||
if (mountNode !== null) {
|
||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
||||
ReactDOM.render(<TimelineContainer {...props} />, mountNode);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const ready = require('flavours/glitch/util/ready').default;
|
||||
ready(loaded);
|
||||
}
|
||||
|
||||
loadPolyfills().then(main).catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
import 'flavours/glitch/styles/index.scss';
|
||||
@@ -1,7 +0,0 @@
|
||||
import loadPolyfills from 'flavours/glitch/util/load_polyfills';
|
||||
|
||||
loadPolyfills().then(() => {
|
||||
require('flavours/glitch/util/main').default();
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
@@ -1,75 +0,0 @@
|
||||
import loadPolyfills from 'flavours/glitch/util/load_polyfills';
|
||||
import ready from 'flavours/glitch/util/ready';
|
||||
|
||||
function main() {
|
||||
const IntlRelativeFormat = require('intl-relativeformat').default;
|
||||
const emojify = require('flavours/glitch/util/emoji').default;
|
||||
const { getLocale } = require('locales');
|
||||
const { localeData } = getLocale();
|
||||
const VideoContainer = require('flavours/glitch/containers/video_container').default;
|
||||
const MediaGalleryContainer = require('flavours/glitch/containers/media_gallery_container').default;
|
||||
const CardContainer = require('flavours/glitch/containers/card_container').default;
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
|
||||
localeData.forEach(IntlRelativeFormat.__addLocaleData);
|
||||
|
||||
ready(() => {
|
||||
const locale = document.documentElement.lang;
|
||||
|
||||
const dateTimeFormat = new Intl.DateTimeFormat(locale, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
});
|
||||
|
||||
const relativeFormat = new IntlRelativeFormat(locale);
|
||||
|
||||
[].forEach.call(document.querySelectorAll('.emojify'), (content) => {
|
||||
content.innerHTML = emojify(content.innerHTML);
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('time.formatted'), (content) => {
|
||||
const datetime = new Date(content.getAttribute('datetime'));
|
||||
const formattedDate = dateTimeFormat.format(datetime);
|
||||
|
||||
content.title = formattedDate;
|
||||
content.textContent = formattedDate;
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
|
||||
const datetime = new Date(content.getAttribute('datetime'));
|
||||
|
||||
content.title = dateTimeFormat.format(datetime);
|
||||
content.textContent = relativeFormat.format(datetime);
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
|
||||
content.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
window.open(e.target.href, 'mastodon-intent', 'width=400,height=400,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||
});
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('[data-component="Video"]'), (content) => {
|
||||
const props = JSON.parse(content.getAttribute('data-props'));
|
||||
ReactDOM.render(<VideoContainer locale={locale} {...props} />, content);
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('[data-component="MediaGallery"]'), (content) => {
|
||||
const props = JSON.parse(content.getAttribute('data-props'));
|
||||
ReactDOM.render(<MediaGalleryContainer locale={locale} {...props} />, content);
|
||||
});
|
||||
|
||||
[].forEach.call(document.querySelectorAll('[data-component="Card"]'), (content) => {
|
||||
const props = JSON.parse(content.getAttribute('data-props'));
|
||||
ReactDOM.render(<CardContainer locale={locale} {...props} />, content);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadPolyfills().then(main).catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import loadPolyfills from 'flavours/glitch/util/load_polyfills';
|
||||
|
||||
function loaded() {
|
||||
const ComposeContainer = require('flavours/glitch/containers/compose_container').default;
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const mountNode = document.getElementById('mastodon-compose');
|
||||
|
||||
if (mountNode !== null) {
|
||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
||||
ReactDOM.render(<ComposeContainer {...props} />, mountNode);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const ready = require('flavours/glitch/util/ready').default;
|
||||
ready(loaded);
|
||||
}
|
||||
|
||||
loadPolyfills().then(main).catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
# (REQUIRED) The location of the pack files.
|
||||
pack:
|
||||
about: packs/about.js
|
||||
admin:
|
||||
auth:
|
||||
common:
|
||||
filename: packs/common.js
|
||||
stylesheet: true
|
||||
embed: packs/public.js
|
||||
error:
|
||||
home:
|
||||
filename: packs/home.js
|
||||
preload:
|
||||
- flavours/glitch/async/getting_started
|
||||
- flavours/glitch/async/compose
|
||||
- flavours/glitch/async/home_timeline
|
||||
- flavours/glitch/async/notifications
|
||||
stylesheet: true
|
||||
modal:
|
||||
public: packs/public.js
|
||||
settings:
|
||||
share: packs/share.js
|
||||
|
||||
# (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
|
||||
|
||||
# (OPTIONAL) By default the theme will fallback to the default theme
|
||||
# if a particular pack is not provided. You can specify different
|
||||
# fallbacks here, or disable fallback behaviours altogether by
|
||||
# specifying a `null` value.
|
||||
fallback:
|
||||
@@ -1,115 +0,0 @@
|
||||
export function EmojiPicker () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/emoji_picker" */'flavours/glitch/util/emoji/emoji_picker');
|
||||
}
|
||||
|
||||
export function Compose () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/compose" */'flavours/glitch/features/compose');
|
||||
}
|
||||
|
||||
export function Notifications () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/notifications" */'flavours/glitch/features/notifications');
|
||||
}
|
||||
|
||||
export function HomeTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/home_timeline" */'flavours/glitch/features/home_timeline');
|
||||
}
|
||||
|
||||
export function PublicTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/public_timeline" */'flavours/glitch/features/public_timeline');
|
||||
}
|
||||
|
||||
export function CommunityTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/community_timeline" */'flavours/glitch/features/community_timeline');
|
||||
}
|
||||
|
||||
export function HashtagTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/hashtag_timeline" */'flavours/glitch/features/hashtag_timeline');
|
||||
}
|
||||
|
||||
export function DirectTimeline() {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/direct_timeline" */'flavours/glitch/features/direct_timeline');
|
||||
}
|
||||
|
||||
export function Status () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/status" */'flavours/glitch/features/status');
|
||||
}
|
||||
|
||||
export function GettingStarted () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/getting_started" */'flavours/glitch/features/getting_started');
|
||||
}
|
||||
|
||||
export function PinnedStatuses () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/pinned_statuses" */'flavours/glitch/features/pinned_statuses');
|
||||
}
|
||||
|
||||
export function AccountTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_timeline" */'flavours/glitch/features/account_timeline');
|
||||
}
|
||||
|
||||
export function AccountGallery () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_gallery" */'flavours/glitch/features/account_gallery');
|
||||
}
|
||||
|
||||
export function Followers () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/followers" */'flavours/glitch/features/followers');
|
||||
}
|
||||
|
||||
export function Following () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/following" */'flavours/glitch/features/following');
|
||||
}
|
||||
|
||||
export function Reblogs () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/reblogs" */'flavours/glitch/features/reblogs');
|
||||
}
|
||||
|
||||
export function Favourites () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourites" */'flavours/glitch/features/favourites');
|
||||
}
|
||||
|
||||
export function FollowRequests () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/follow_requests" */'flavours/glitch/features/follow_requests');
|
||||
}
|
||||
|
||||
export function GenericNotFound () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/generic_not_found" */'flavours/glitch/features/generic_not_found');
|
||||
}
|
||||
|
||||
export function FavouritedStatuses () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourited_statuses" */'flavours/glitch/features/favourited_statuses');
|
||||
}
|
||||
|
||||
export function Blocks () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/blocks" */'flavours/glitch/features/blocks');
|
||||
}
|
||||
|
||||
export function Mutes () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mutes" */'flavours/glitch/features/mutes');
|
||||
}
|
||||
|
||||
export function OnboardingModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/onboarding_modal" */'flavours/glitch/features/ui/components/onboarding_modal');
|
||||
}
|
||||
|
||||
export function MuteModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mute_modal" */'flavours/glitch/features/ui/components/mute_modal');
|
||||
}
|
||||
|
||||
export function ReportModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/report_modal" */'flavours/glitch/features/ui/components/report_modal');
|
||||
}
|
||||
|
||||
export function SettingsModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/settings_modal" */'flavours/glitch/features/local_settings');
|
||||
}
|
||||
|
||||
export function MediaGallery () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/media_gallery" */'flavours/glitch/components/media_gallery');
|
||||
}
|
||||
|
||||
export function Video () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/video" */'flavours/glitch/features/video');
|
||||
}
|
||||
|
||||
export function EmbedModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/embed_modal" */'flavours/glitch/features/ui/components/embed_modal');
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# (REQUIRED) The location of the pack files inside `pack_directory`.
|
||||
pack:
|
||||
about: about.js
|
||||
admin:
|
||||
auth:
|
||||
common:
|
||||
filename: common.js
|
||||
stylesheet: true
|
||||
embed: public.js
|
||||
error:
|
||||
home:
|
||||
filename: application.js
|
||||
preload:
|
||||
- features/getting_started
|
||||
- features/compose
|
||||
- features/home_timeline
|
||||
- features/notifications
|
||||
modal:
|
||||
public: public.js
|
||||
settings:
|
||||
share: share.js
|
||||
|
||||
# (OPTIONAL) The directory which contains the pack files.
|
||||
# Defaults to the theme directory (`app/javascript/themes/[theme]`),
|
||||
# but in the case of the vanilla Mastodon theme the pack files are
|
||||
# somewhere else.
|
||||
pack_directory: app/javascript/packs
|
||||
|
||||
# (OPTIONAL) By default the theme will fallback to the default theme
|
||||
# if a particular pack is not provided. You can specify different
|
||||
# fallbacks here, or disable fallback behaviours altogether by
|
||||
# specifying a `null` value.
|
||||
fallback:
|
||||
@@ -32,8 +32,6 @@
|
||||
"status.collapse": "Collapse",
|
||||
"status.uncollapse": "Uncollapse",
|
||||
|
||||
"home.column_settings.show_direct": "Show DMs",
|
||||
|
||||
"notification.markForDeletion": "Mark for deletion",
|
||||
"notifications.clear": "Clear all my notifications",
|
||||
"notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"getting_started.open_source_notice": "Glitchsoc jest wolnym i otwartoźródłowym forkiem oprogramowania {Mastodon}. Możesz współtworzyć projekt lub zgłaszać błędy na GitHubie pod adresem {github}.",
|
||||
"layout.auto": "Automatyczny",
|
||||
"layout.current_is": "Twój obecny układ to:",
|
||||
"layout.desktop": "Desktopowy",
|
||||
"layout.mobile": "Mobilny",
|
||||
"navigation_bar.app_settings": "Ustawienia aplikacji",
|
||||
"getting_started.onboarding": "Rozejrzyj się",
|
||||
"onboarding.page_one.federation": "{domain} jest 'instancją' Mastodona. Mastodon to sieć działających niezależnie serwerów tworzących jedną sieć społecznościową. Te serwery nazywane są instancjami.",
|
||||
"onboarding.page_one.welcome": "Witamy na {domain}!",
|
||||
"onboarding.page_six.github": "{domain} jest oparty na Glitchsoc. Glitchsoc jest {forkiem} {Mastodon}a kompatybilnym z każdym klientem i aplikacją Mastodona. Glitchsoc jest całkowicie wolnym i otwartoźródłowym oprogramowaniem. Możesz zgłaszać błędy i sugestie funkcji oraz współtworzyć projekt na {github}.",
|
||||
"settings.auto_collapse": "Automatyczne zwijanie",
|
||||
"settings.auto_collapse_all": "Wszystko",
|
||||
"settings.auto_collapse_lengthy": "Długie wpisy",
|
||||
"settings.auto_collapse_media": "Wpisy z zawartością multimedialną",
|
||||
"settings.auto_collapse_notifications": "Powiadomienia",
|
||||
"settings.auto_collapse_reblogs": "Podbicia",
|
||||
"settings.auto_collapse_replies": "Odpowiedzi",
|
||||
"settings.close": "Zamknij",
|
||||
"settings.collapsed_statuses": "Zwijanie wpisów",
|
||||
"settings.enable_collapsed": "Włącz zwijanie wpisów",
|
||||
"settings.general": "Ogólne",
|
||||
"settings.image_backgrounds": "Obrazy w tle",
|
||||
"settings.image_backgrounds_media": "Wyświetlaj zawartość multimedialną zwiniętych wpisów",
|
||||
"settings.image_backgrounds_users": "Nadaj tło zwiniętym wpisom",
|
||||
"settings.media": "Zawartość multimedialna",
|
||||
"settings.media_letterbox": "Letterbox media",
|
||||
"settings.media_fullwidth": "Podgląd zawartości multimedialnej o pełnej szerokości",
|
||||
"settings.preferences": "Preferencje użyytkownika",
|
||||
"settings.wide_view": "Szeroki widok (tylko w trybie desktopowym)",
|
||||
"settings.navbar_under": "Pasek nawigacji na dole (tylko w trybie mobilnym)",
|
||||
"status.collapse": "Zwiń",
|
||||
"status.uncollapse": "Rozwiń",
|
||||
|
||||
"notification.markForDeletion": "Oznacz do usunięcia",
|
||||
"notifications.clear": "Wyczyść wszystkie powiadomienia",
|
||||
"notifications.marked_clear_confirmation": "Czy na pewno chcesz bezpowrtonie usunąć wszystkie powiadomienia?",
|
||||
"notifications.marked_clear": "Usuń zaznaczone powiadomienia",
|
||||
|
||||
"notification_purge.btn_all": "Zaznacz\nwszystkie",
|
||||
"notification_purge.btn_none": "Odznacz\nwszystkie",
|
||||
"notification_purge.btn_invert": "Odwróć\nzaznaczenie",
|
||||
"notification_purge.btn_apply": "Usuń\nzaznaczone"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 356 B |
|
Before Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 599 B |
|
Before Width: | Height: | Size: 383 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 337 B |
|
Before Width: | Height: | Size: 688 B |
|
Before Width: | Height: | Size: 639 B |
|
Before Width: | Height: | Size: 263 B |
@@ -1,9 +0,0 @@
|
||||
let theLocale;
|
||||
|
||||
export function setLocale(locale) {
|
||||
theLocale = locale;
|
||||
}
|
||||
|
||||
export function getLocale() {
|
||||
return theLocale;
|
||||
}
|
||||
@@ -105,13 +105,12 @@ export function fetchAccountFail(id, error) {
|
||||
};
|
||||
};
|
||||
|
||||
export function followAccount(id, reblogs = true) {
|
||||
export function followAccount(id) {
|
||||
return (dispatch, getState) => {
|
||||
const alreadyFollowing = getState().getIn(['relationships', id, 'following']);
|
||||
dispatch(followAccountRequest(id));
|
||||
|
||||
api(getState).post(`/api/v1/accounts/${id}/follow`, { reblogs }).then(response => {
|
||||
dispatch(followAccountSuccess(response.data, alreadyFollowing));
|
||||
api(getState).post(`/api/v1/accounts/${id}/follow`).then(response => {
|
||||
dispatch(followAccountSuccess(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(followAccountFail(error));
|
||||
});
|
||||
@@ -137,11 +136,10 @@ export function followAccountRequest(id) {
|
||||
};
|
||||
};
|
||||
|
||||
export function followAccountSuccess(relationship, alreadyFollowing) {
|
||||
export function followAccountSuccess(relationship) {
|
||||
return {
|
||||
type: ACCOUNT_FOLLOW_SUCCESS,
|
||||
relationship,
|
||||
alreadyFollowing,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
import api from '../api';
|
||||
|
||||
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
|
||||
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS';
|
||||
export const LIST_FETCH_FAIL = 'LIST_FETCH_FAIL';
|
||||
|
||||
export const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST';
|
||||
export const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS';
|
||||
export const LISTS_FETCH_FAIL = 'LISTS_FETCH_FAIL';
|
||||
|
||||
export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE';
|
||||
export const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET';
|
||||
export const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP';
|
||||
|
||||
export const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST';
|
||||
export const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS';
|
||||
export const LIST_CREATE_FAIL = 'LIST_CREATE_FAIL';
|
||||
|
||||
export const LIST_UPDATE_REQUEST = 'LIST_UPDATE_REQUEST';
|
||||
export const LIST_UPDATE_SUCCESS = 'LIST_UPDATE_SUCCESS';
|
||||
export const LIST_UPDATE_FAIL = 'LIST_UPDATE_FAIL';
|
||||
|
||||
export const LIST_DELETE_REQUEST = 'LIST_DELETE_REQUEST';
|
||||
export const LIST_DELETE_SUCCESS = 'LIST_DELETE_SUCCESS';
|
||||
export const LIST_DELETE_FAIL = 'LIST_DELETE_FAIL';
|
||||
|
||||
export const LIST_ACCOUNTS_FETCH_REQUEST = 'LIST_ACCOUNTS_FETCH_REQUEST';
|
||||
export const LIST_ACCOUNTS_FETCH_SUCCESS = 'LIST_ACCOUNTS_FETCH_SUCCESS';
|
||||
export const LIST_ACCOUNTS_FETCH_FAIL = 'LIST_ACCOUNTS_FETCH_FAIL';
|
||||
|
||||
export const LIST_EDITOR_SUGGESTIONS_CHANGE = 'LIST_EDITOR_SUGGESTIONS_CHANGE';
|
||||
export const LIST_EDITOR_SUGGESTIONS_READY = 'LIST_EDITOR_SUGGESTIONS_READY';
|
||||
export const LIST_EDITOR_SUGGESTIONS_CLEAR = 'LIST_EDITOR_SUGGESTIONS_CLEAR';
|
||||
|
||||
export const LIST_EDITOR_ADD_REQUEST = 'LIST_EDITOR_ADD_REQUEST';
|
||||
export const LIST_EDITOR_ADD_SUCCESS = 'LIST_EDITOR_ADD_SUCCESS';
|
||||
export const LIST_EDITOR_ADD_FAIL = 'LIST_EDITOR_ADD_FAIL';
|
||||
|
||||
export const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST';
|
||||
export const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS';
|
||||
export const LIST_EDITOR_REMOVE_FAIL = 'LIST_EDITOR_REMOVE_FAIL';
|
||||
|
||||
export const fetchList = id => (dispatch, getState) => {
|
||||
if (getState().getIn(['lists', id])) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(fetchListRequest(id));
|
||||
|
||||
api(getState).get(`/api/v1/lists/${id}`)
|
||||
.then(({ data }) => dispatch(fetchListSuccess(data)))
|
||||
.catch(err => dispatch(fetchListFail(id, err)));
|
||||
};
|
||||
|
||||
export const fetchListRequest = id => ({
|
||||
type: LIST_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const fetchListSuccess = list => ({
|
||||
type: LIST_FETCH_SUCCESS,
|
||||
list,
|
||||
});
|
||||
|
||||
export const fetchListFail = (id, error) => ({
|
||||
type: LIST_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
|
||||
export const fetchLists = () => (dispatch, getState) => {
|
||||
dispatch(fetchListsRequest());
|
||||
|
||||
api(getState).get('/api/v1/lists')
|
||||
.then(({ data }) => dispatch(fetchListsSuccess(data)))
|
||||
.catch(err => dispatch(fetchListsFail(err)));
|
||||
};
|
||||
|
||||
export const fetchListsRequest = () => ({
|
||||
type: LISTS_FETCH_REQUEST,
|
||||
});
|
||||
|
||||
export const fetchListsSuccess = lists => ({
|
||||
type: LISTS_FETCH_SUCCESS,
|
||||
lists,
|
||||
});
|
||||
|
||||
export const fetchListsFail = error => ({
|
||||
type: LISTS_FETCH_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const submitListEditor = shouldReset => (dispatch, getState) => {
|
||||
const listId = getState().getIn(['listEditor', 'listId']);
|
||||
const title = getState().getIn(['listEditor', 'title']);
|
||||
|
||||
if (listId === null) {
|
||||
dispatch(createList(title, shouldReset));
|
||||
} else {
|
||||
dispatch(updateList(listId, title, shouldReset));
|
||||
}
|
||||
};
|
||||
|
||||
export const setupListEditor = listId => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: LIST_EDITOR_SETUP,
|
||||
list: getState().getIn(['lists', listId]),
|
||||
});
|
||||
|
||||
dispatch(fetchListAccounts(listId));
|
||||
};
|
||||
|
||||
export const changeListEditorTitle = value => ({
|
||||
type: LIST_EDITOR_TITLE_CHANGE,
|
||||
value,
|
||||
});
|
||||
|
||||
export const createList = (title, shouldReset) => (dispatch, getState) => {
|
||||
dispatch(createListRequest());
|
||||
|
||||
api(getState).post('/api/v1/lists', { title }).then(({ data }) => {
|
||||
dispatch(createListSuccess(data));
|
||||
|
||||
if (shouldReset) {
|
||||
dispatch(resetListEditor());
|
||||
}
|
||||
}).catch(err => dispatch(createListFail(err)));
|
||||
};
|
||||
|
||||
export const createListRequest = () => ({
|
||||
type: LIST_CREATE_REQUEST,
|
||||
});
|
||||
|
||||
export const createListSuccess = list => ({
|
||||
type: LIST_CREATE_SUCCESS,
|
||||
list,
|
||||
});
|
||||
|
||||
export const createListFail = error => ({
|
||||
type: LIST_CREATE_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const updateList = (id, title, shouldReset) => (dispatch, getState) => {
|
||||
dispatch(updateListRequest(id));
|
||||
|
||||
api(getState).put(`/api/v1/lists/${id}`, { title }).then(({ data }) => {
|
||||
dispatch(updateListSuccess(data));
|
||||
|
||||
if (shouldReset) {
|
||||
dispatch(resetListEditor());
|
||||
}
|
||||
}).catch(err => dispatch(updateListFail(id, err)));
|
||||
};
|
||||
|
||||
export const updateListRequest = id => ({
|
||||
type: LIST_UPDATE_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const updateListSuccess = list => ({
|
||||
type: LIST_UPDATE_SUCCESS,
|
||||
list,
|
||||
});
|
||||
|
||||
export const updateListFail = (id, error) => ({
|
||||
type: LIST_UPDATE_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
|
||||
export const resetListEditor = () => ({
|
||||
type: LIST_EDITOR_RESET,
|
||||
});
|
||||
|
||||
export const deleteList = id => (dispatch, getState) => {
|
||||
dispatch(deleteListRequest(id));
|
||||
|
||||
api(getState).delete(`/api/v1/lists/${id}`)
|
||||
.then(() => dispatch(deleteListSuccess(id)))
|
||||
.catch(err => dispatch(deleteListFail(id, err)));
|
||||
};
|
||||
|
||||
export const deleteListRequest = id => ({
|
||||
type: LIST_DELETE_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const deleteListSuccess = id => ({
|
||||
type: LIST_DELETE_SUCCESS,
|
||||
id,
|
||||
});
|
||||
|
||||
export const deleteListFail = (id, error) => ({
|
||||
type: LIST_DELETE_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
|
||||
export const fetchListAccounts = listId => (dispatch, getState) => {
|
||||
dispatch(fetchListAccountsRequest(listId));
|
||||
|
||||
api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } })
|
||||
.then(({ data }) => dispatch(fetchListAccountsSuccess(listId, data)))
|
||||
.catch(err => dispatch(fetchListAccountsFail(listId, err)));
|
||||
};
|
||||
|
||||
export const fetchListAccountsRequest = id => ({
|
||||
type: LIST_ACCOUNTS_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const fetchListAccountsSuccess = (id, accounts, next) => ({
|
||||
type: LIST_ACCOUNTS_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
next,
|
||||
});
|
||||
|
||||
export const fetchListAccountsFail = (id, error) => ({
|
||||
type: LIST_ACCOUNTS_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
|
||||
export const fetchListSuggestions = q => (dispatch, getState) => {
|
||||
const params = {
|
||||
q,
|
||||
resolve: false,
|
||||
limit: 4,
|
||||
following: true,
|
||||
};
|
||||
|
||||
api(getState).get('/api/v1/accounts/search', { params })
|
||||
.then(({ data }) => dispatch(fetchListSuggestionsReady(q, data)));
|
||||
};
|
||||
|
||||
export const fetchListSuggestionsReady = (query, accounts) => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_READY,
|
||||
query,
|
||||
accounts,
|
||||
});
|
||||
|
||||
export const clearListSuggestions = () => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_CLEAR,
|
||||
});
|
||||
|
||||
export const changeListSuggestions = value => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_CHANGE,
|
||||
value,
|
||||
});
|
||||
|
||||
export const addToListEditor = accountId => (dispatch, getState) => {
|
||||
dispatch(addToList(getState().getIn(['listEditor', 'listId']), accountId));
|
||||
};
|
||||
|
||||
export const addToList = (listId, accountId) => (dispatch, getState) => {
|
||||
dispatch(addToListRequest(listId, accountId));
|
||||
|
||||
api(getState).post(`/api/v1/lists/${listId}/accounts`, { account_ids: [accountId] })
|
||||
.then(() => dispatch(addToListSuccess(listId, accountId)))
|
||||
.catch(err => dispatch(addToListFail(listId, accountId, err)));
|
||||
};
|
||||
|
||||
export const addToListRequest = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_ADD_REQUEST,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
|
||||
export const addToListSuccess = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_ADD_SUCCESS,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
|
||||
export const addToListFail = (listId, accountId, error) => ({
|
||||
type: LIST_EDITOR_ADD_FAIL,
|
||||
listId,
|
||||
accountId,
|
||||
error,
|
||||
});
|
||||
|
||||
export const removeFromListEditor = accountId => (dispatch, getState) => {
|
||||
dispatch(removeFromList(getState().getIn(['listEditor', 'listId']), accountId));
|
||||
};
|
||||
|
||||
export const removeFromList = (listId, accountId) => (dispatch, getState) => {
|
||||
dispatch(removeFromListRequest(listId, accountId));
|
||||
|
||||
api(getState).delete(`/api/v1/lists/${listId}/accounts`, { params: { account_ids: [accountId] } })
|
||||
.then(() => dispatch(removeFromListSuccess(listId, accountId)))
|
||||
.catch(err => dispatch(removeFromListFail(listId, accountId, err)));
|
||||
};
|
||||
|
||||
export const removeFromListRequest = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_REMOVE_REQUEST,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
|
||||
export const removeFromListSuccess = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_REMOVE_SUCCESS,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
|
||||
export const removeFromListFail = (listId, accountId, error) => ({
|
||||
type: LIST_EDITOR_REMOVE_FAIL,
|
||||
listId,
|
||||
accountId,
|
||||
error,
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import api, { getLinks } from '../api';
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { openModal } from './modal';
|
||||
import { openModal } from '../../mastodon/actions/modal';
|
||||
|
||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
|
||||
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';
|
||||
@@ -100,4 +100,4 @@ export function toggleHideNotifications() {
|
||||
return dispatch => {
|
||||
dispatch({ type: MUTES_TOGGLE_HIDE_NOTIFICATIONS });
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -51,4 +51,3 @@ export const connectCommunityStream = () => connectTimelineStream('community', '
|
||||
export const connectMediaStream = () => connectTimelineStream('community', 'public:local');
|
||||
export const connectPublicStream = () => connectTimelineStream('public', 'public');
|
||||
export const connectHashtagStream = (tag) => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
|
||||
export const connectListStream = (id) => connectTimelineStream(`list:${id}`, `list&list=${id}`);
|
||||
|
||||