From 71bc75e6ac00050ff98609b3cbeb38a0db157e1f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 28 Jun 2017 17:43:48 +0200 Subject: Do not fail to create access token if superapp was never created (#3986) --- app/models/session_activation.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'app/models') diff --git a/app/models/session_activation.rb b/app/models/session_activation.rb index 02a918e8a..887e3e3bd 100644 --- a/app/models/session_activation.rb +++ b/app/models/session_activation.rb @@ -69,9 +69,7 @@ class SessionActivation < ApplicationRecord def assign_access_token superapp = Doorkeeper::Application.find_by(superapp: true) - return if superapp.nil? - - self.access_token = Doorkeeper::AccessToken.create!(application_id: superapp.id, + self.access_token = Doorkeeper::AccessToken.create!(application_id: superapp&.id, resource_owner_id: user_id, scopes: 'read write follow', expires_in: Doorkeeper.configuration.access_token_expires_in, -- cgit From 1273fbf86ea3bd906e687a33e1f62c99f100ecca Mon Sep 17 00:00:00 2001 From: abcang Date: Fri, 30 Jun 2017 20:38:36 +0900 Subject: Rescue Addressable::URI::InvalidURIError at Remotable (#4017) --- app/models/concerns/remotable.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 4a412ee3d..b0077ce96 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -26,8 +26,9 @@ module Remotable send("#{attachment_name}_file_name=", filename) self[attribute_name] = url if has_attribute?(attribute_name) - rescue HTTP::TimeoutError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError => e + rescue HTTP::TimeoutError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + nil end end end -- cgit From a6d02cff368d96178b0843ef021232d2187abbcd Mon Sep 17 00:00:00 2001 From: abcang Date: Mon, 3 Jul 2017 18:03:34 +0900 Subject: Rescue exceptions caused by FetchLinkCardService (#4045) --- app/models/concerns/remotable.rb | 8 ++++++-- app/services/fetch_link_card_service.rb | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index b0077ce96..08d4fc59c 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -10,7 +10,11 @@ module Remotable method_name = "#{attribute_name}=".to_sym define_method method_name do |url| - parsed_url = Addressable::URI.parse(url).normalize + begin + parsed_url = Addressable::URI.parse(url).normalize + rescue Addressable::URI::InvalidURIError + return + end return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[attribute_name] == url @@ -26,7 +30,7 @@ module Remotable send("#{attachment_name}_file_name=", filename) self[attribute_name] = url if has_attribute?(attribute_name) - rescue HTTP::TimeoutError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError => e + rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" nil end diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index c2df7b2f0..4ce221267 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -18,6 +18,8 @@ class FetchLinkCardService < BaseService return if res.code != 200 || res.mime_type != 'text/html' attempt_opengraph(card, url) unless attempt_oembed(card, url) + rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError + nil end private -- cgit From f85dbe83c8e982f9685fbc802031b74c7c319bc7 Mon Sep 17 00:00:00 2001 From: "Akihiko Odaki (@fn_aki@pawoo.net)" Date: Mon, 3 Jul 2017 20:17:27 +0900 Subject: Remove sort in Feed (#4050) In from_redis method, statuses retrieved from the database was mapped to the IDs retrieved from Redis. It was equivalent to order from high to low because those IDs are sorted in the same order. Statuses are ordered with the ID by default, so we do not have to reorder. Sorting statuses in the database is even faster since the IDs are indexed with B-tree. --- app/models/feed.rb | 3 +-- spec/models/feed_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'app/models') diff --git a/app/models/feed.rb b/app/models/feed.rb index 5125e51ff..beb4a8de3 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -20,8 +20,7 @@ class Feed max_id = '+inf' if max_id.blank? since_id = '-inf' if since_id.blank? unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:last).map(&:to_i) - status_map = Status.where(id: unhydrated).cache_ids.map { |s| [s.id, s] }.to_h - unhydrated.map { |id| status_map[id] }.compact + Status.where(id: unhydrated).cache_ids end def from_database(limit, max_id, since_id) diff --git a/spec/models/feed_spec.rb b/spec/models/feed_spec.rb index 1cdb3a783..1c377c17f 100644 --- a/spec/models/feed_spec.rb +++ b/spec/models/feed_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' RSpec.describe Feed, type: :model do describe '#get' do - it 'gets statuses with ids in the range, maintining the order from Redis' do + it 'gets statuses with ids in the range' do account = Fabricate(:account) Fabricate(:status, account: account, id: 1) Fabricate(:status, account: account, id: 2) -- cgit From a37cf9548c2772f5b8b7a976e4f90c0ed78a8722 Mon Sep 17 00:00:00 2001 From: "Akihiko Odaki (@fn_aki@pawoo.net)" Date: Thu, 6 Jul 2017 06:58:03 +0900 Subject: Explicitly require MIME::Types (#4083) --- Gemfile | 1 + Gemfile.lock | 1 + app/models/media_attachment.rb | 2 ++ 3 files changed, 4 insertions(+) (limited to 'app/models') diff --git a/Gemfile b/Gemfile index aecd82702..6ee884a17 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,7 @@ gem 'http_accept_language', '~> 2.1' gem 'httplog', '~> 0.99' gem 'kaminari', '~> 1.0' gem 'link_header', '~> 0.0' +gem 'mime-types', '~> 3.1' gem 'nokogiri', '~> 1.7' gem 'oj', '~> 3.0' gem 'ostatus2', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index dac6169d5..f0156529c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -516,6 +516,7 @@ DEPENDENCIES link_header (~> 0.0) lograge (~> 0.5) microformats2 (~> 3.0) + mime-types (~> 3.1) nokogiri (~> 1.7) oj (~> 3.0) ostatus2 (~> 2.0) diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 340109ab6..1e8c6d00a 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -18,6 +18,8 @@ # file_meta :json # +require 'mime/types' + class MediaAttachment < ApplicationRecord self.inheritance_column = nil -- cgit From 18d3fa953b5af8ab17cc93c33cb95cec37127712 Mon Sep 17 00:00:00 2001 From: Damien Erambert Date: Thu, 6 Jul 2017 13:39:56 -0700 Subject: Add a setting allowing the use of system's default font in Web UI (#4033) * add a system_font_ui setting on the server * Plug the system_font_ui on the front-end * add EN/FR locales for the new setting * put Roboto after all other fonts * remove trailing whitespace so CodeClimate is happy * fix user_spec.rb * correctly write user_spect this time * slightly better way of adding the classes * add comments to the system-font stack for clarification * use .system-font for the class instead * don't use multiple lines for comments * remove trailing whitespace * use the classnames module for consistency * use `mastodon-font-sans-serif` instead of Roboto directly --- app/controllers/settings/preferences_controller.rb | 1 + app/javascript/mastodon/features/ui/index.js | 14 ++++++++++++-- app/javascript/styles/basics.scss | 15 +++++++++++++++ app/lib/user_settings_decorator.rb | 5 +++++ app/models/user.rb | 4 ++++ app/views/home/initial_state.json.rabl | 1 + app/views/settings/preferences/show.html.haml | 1 + config/locales/simple_form.en.yml | 1 + config/locales/simple_form.fr.yml | 1 + config/settings.yml | 1 + spec/lib/user_settings_decorator_spec.rb | 7 +++++++ spec/models/user_spec.rb | 8 ++++++++ 12 files changed, 57 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 71f5a7c04..a15c26031 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -37,6 +37,7 @@ class Settings::PreferencesController < ApplicationController :setting_boost_modal, :setting_delete_modal, :setting_auto_play_gif, + :setting_system_font_ui, notification_emails: %i(follow follow_request reblog favourite mention digest), interactions: %i(must_be_follower must_be_following) ) diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 08d087da1..54e623d99 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -1,4 +1,5 @@ import React from 'react'; +import classNames from 'classnames'; import Switch from 'react-router-dom/Switch'; import Route from 'react-router-dom/Route'; import Redirect from 'react-router-dom/Redirect'; @@ -72,12 +73,17 @@ class WrappedRoute extends React.Component { } -@connect() +const mapStateToProps = state => ({ + systemFontUi: state.getIn(['meta', 'system_font_ui']), +}); + +@connect(mapStateToProps) export default class UI extends React.PureComponent { static propTypes = { dispatch: PropTypes.func.isRequired, children: PropTypes.node, + systemFontUi: PropTypes.bool, }; state = { @@ -176,8 +182,12 @@ export default class UI extends React.PureComponent { const { width, draggingOver } = this.state; const { children } = this.props; + const className = classNames('ui', { + 'system-font': this.props.systemFontUi, + }); + return ( -
+
diff --git a/app/javascript/styles/basics.scss b/app/javascript/styles/basics.scss index 0cb271ddd..4da698e81 100644 --- a/app/javascript/styles/basics.scss +++ b/app/javascript/styles/basics.scss @@ -63,3 +63,18 @@ button { align-items: center; justify-content: center; } + +.system-font { + // system-ui => standard property (Chrome/Android WebView 56+, Opera 43+, Safari 11+) + // -apple-system => Safari <11 specific + // BlinkMacSystemFont => Chrome <56 on macOS specific + // Segoe UI => Windows 7/8/10 + // Oxygen => KDE + // Ubuntu => Unity/Ubuntu + // Cantarell => GNOME + // Fira Sans => Firefox OS + // Droid Sans => Older Androids (<4.0) + // Helvetica Neue => Older macOS <10.11 + // mastodon-font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0) + font-family: system-ui, -apple-system,BlinkMacSystemFont, "Segoe UI","Oxygen", "Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",mastodon-font-sans-serif, sans-serif; +} diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index af264bbd5..9c0cb4545 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -21,6 +21,7 @@ class UserSettingsDecorator user.settings['boost_modal'] = boost_modal_preference user.settings['delete_modal'] = delete_modal_preference user.settings['auto_play_gif'] = auto_play_gif_preference + user.settings['system_font_ui'] = system_font_ui_preference end def merged_notification_emails @@ -43,6 +44,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_delete_modal' end + def system_font_ui_preference + boolean_cast_setting 'setting_system_font_ui' + end + def auto_play_gif_preference boolean_cast_setting 'setting_auto_play_gif' end diff --git a/app/models/user.rb b/app/models/user.rb index c31a0c644..e2bb3d0ed 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -91,6 +91,10 @@ class User < ApplicationRecord settings.auto_play_gif end + def setting_system_font_ui + settings.system_font_ui + end + def activate_session(request) session_activations.activate(session_id: SecureRandom.hex, user_agent: request.user_agent, diff --git a/app/views/home/initial_state.json.rabl b/app/views/home/initial_state.json.rabl index e305f8e7a..291ff806b 100644 --- a/app/views/home/initial_state.json.rabl +++ b/app/views/home/initial_state.json.rabl @@ -11,6 +11,7 @@ node(:meta) do boost_modal: current_account.user.setting_boost_modal, delete_modal: current_account.user.setting_delete_modal, auto_play_gif: current_account.user.setting_auto_play_gif, + system_font_ui: current_account.user.setting_system_font_ui, } end diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index 721ce6a21..26fbfdf82 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -44,6 +44,7 @@ .fields-group = f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label + = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 3e769fb96..d8d3b8a6f 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -38,6 +38,7 @@ en: setting_boost_modal: Show confirmation dialog before boosting setting_default_privacy: Post privacy setting_delete_modal: Show confirmation dialog before deleting a toot + setting_system_font_ui: Use system's default font severity: Severity type: Import type username: Username diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index ae4975143..446c56947 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -28,6 +28,7 @@ fr: password: Mot de passe setting_boost_modal: Afficher un dialogue de confirmation avant de partager setting_default_privacy: Confidentialité des statuts + setting_system_font_ui: Utiliser la police par défaut du système severity: Séverité type: Type d'import username: Identifiant diff --git a/config/settings.yml b/config/settings.yml index 5aea232e7..18b70b51f 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -19,6 +19,7 @@ defaults: &defaults boost_modal: false auto_play_gif: true delete_modal: true + system_font_ui: false notification_emails: follow: false reblog: false diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb index 66e42fa0e..e1ba56d97 100644 --- a/spec/lib/user_settings_decorator_spec.rb +++ b/spec/lib/user_settings_decorator_spec.rb @@ -48,5 +48,12 @@ describe UserSettingsDecorator do settings.update(values) expect(user.settings['auto_play_gif']).to eq false end + + it 'updates the user settings value for system font in UI' do + values = { 'setting_system_font_ui' => '0' } + + settings.update(values) + expect(user.settings['system_font_ui']).to eq false + end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a6df3fb26..2019ec0f6 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -184,6 +184,14 @@ RSpec.describe User, type: :model do expect(user.setting_auto_play_gif).to eq false end end + + describe '#setting_system_font_ui' do + it 'returns system font ui setting' do + user = Fabricate(:user) + user.settings[:system_font_ui] = false + expect(user.setting_system_font_ui).to eq false + end + end describe '#setting_boost_modal' do it 'returns boost modal setting' do -- cgit From 8b2cad56374b2dbb6e7a445e7917810935c45536 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 7 Jul 2017 04:02:06 +0200 Subject: Refactor JSON templates to be generated with ActiveModelSerializers instead of Rabl (#4090) --- Gemfile | 1 + Gemfile.lock | 9 +++ .../api/v1/accounts/credentials_controller.rb | 4 +- .../v1/accounts/follower_accounts_controller.rb | 2 +- .../v1/accounts/following_accounts_controller.rb | 2 +- .../api/v1/accounts/relationships_controller.rb | 11 ++- .../api/v1/accounts/search_controller.rb | 3 +- .../api/v1/accounts/statuses_controller.rb | 5 +- app/controllers/api/v1/accounts_controller.rb | 38 +++------ app/controllers/api/v1/apps_controller.rb | 1 + app/controllers/api/v1/blocks_controller.rb | 1 + app/controllers/api/v1/favourites_controller.rb | 5 +- .../api/v1/follow_requests_controller.rb | 1 + app/controllers/api/v1/follows_controller.rb | 2 +- app/controllers/api/v1/instances_controller.rb | 4 +- app/controllers/api/v1/media_controller.rb | 1 + app/controllers/api/v1/mutes_controller.rb | 1 + app/controllers/api/v1/notifications_controller.rb | 7 +- app/controllers/api/v1/reports_controller.rb | 3 +- app/controllers/api/v1/search_controller.rb | 3 +- .../statuses/favourited_by_accounts_controller.rb | 2 +- .../api/v1/statuses/favourites_controller.rb | 4 +- .../api/v1/statuses/mutes_controller.rb | 4 +- .../statuses/reblogged_by_accounts_controller.rb | 2 +- .../api/v1/statuses/reblogs_controller.rb | 4 +- app/controllers/api/v1/statuses_controller.rb | 16 ++-- .../api/v1/timelines/home_controller.rb | 6 +- .../api/v1/timelines/public_controller.rb | 6 +- app/controllers/api/v1/timelines/tag_controller.rb | 6 +- app/lib/inline_rabl_scope.rb | 17 ---- app/lib/inline_renderer.rb | 36 +++++++-- app/models/context.rb | 5 ++ app/models/search.rb | 5 ++ app/presenters/account_relationships_presenter.rb | 15 ++++ app/presenters/status_relationships_presenter.rb | 19 +++++ app/serializers/rest/account_serializer.rb | 33 ++++++++ app/serializers/rest/application_serializer.rb | 14 ++++ app/serializers/rest/context_serializer.rb | 6 ++ app/serializers/rest/instance_serializer.rb | 30 +++++++ .../rest/media_attachment_serializer.rb | 24 ++++++ app/serializers/rest/notification_serializer.rb | 12 +++ app/serializers/rest/preview_card_serializer.rb | 14 ++++ app/serializers/rest/relationship_serializer.rb | 30 +++++++ app/serializers/rest/report_serializer.rb | 5 ++ app/serializers/rest/search_serializer.rb | 12 +++ app/serializers/rest/status_serializer.rb | 93 ++++++++++++++++++++++ app/services/fan_out_on_write_service.rb | 2 +- app/services/notify_service.rb | 2 +- app/views/api/v1/accounts/index.rabl | 2 - app/views/api/v1/accounts/relationship.rabl | 9 --- app/views/api/v1/accounts/relationships/index.rabl | 2 - app/views/api/v1/accounts/show.rabl | 12 --- app/views/api/v1/accounts/statuses/index.rabl | 2 - app/views/api/v1/apps/create.rabl | 4 - app/views/api/v1/apps/show.rabl | 3 - app/views/api/v1/blocks/index.rabl | 2 - app/views/api/v1/favourites/index.rabl | 2 - app/views/api/v1/follow_requests/index.rabl | 2 - app/views/api/v1/follows/show.rabl | 2 - app/views/api/v1/instances/show.rabl | 10 --- app/views/api/v1/media/create.rabl | 7 -- app/views/api/v1/mutes/index.rabl | 2 - app/views/api/v1/notifications/index.rabl | 2 - app/views/api/v1/notifications/show.rabl | 11 --- app/views/api/v1/reports/index.rabl | 2 - app/views/api/v1/reports/show.rabl | 2 - app/views/api/v1/search/index.rabl | 13 --- app/views/api/v1/statuses/_media.rabl | 6 -- app/views/api/v1/statuses/_mention.rabl | 4 - app/views/api/v1/statuses/_show.rabl | 29 ------- app/views/api/v1/statuses/_tags.rabl | 2 - app/views/api/v1/statuses/accounts.rabl | 2 - app/views/api/v1/statuses/card.rabl | 7 -- app/views/api/v1/statuses/context.rabl | 9 --- app/views/api/v1/statuses/index.rabl | 2 - app/views/api/v1/statuses/show.rabl | 15 ---- app/views/api/v1/timelines/show.rabl | 2 - app/views/home/initial_state.json.rabl | 4 +- app/workers/push_update_worker.rb | 2 +- spec/lib/inline_rabl_scope_spec.rb | 23 ------ 80 files changed, 425 insertions(+), 301 deletions(-) delete mode 100644 app/lib/inline_rabl_scope.rb create mode 100644 app/models/context.rb create mode 100644 app/models/search.rb create mode 100644 app/presenters/account_relationships_presenter.rb create mode 100644 app/presenters/status_relationships_presenter.rb create mode 100644 app/serializers/rest/account_serializer.rb create mode 100644 app/serializers/rest/application_serializer.rb create mode 100644 app/serializers/rest/context_serializer.rb create mode 100644 app/serializers/rest/instance_serializer.rb create mode 100644 app/serializers/rest/media_attachment_serializer.rb create mode 100644 app/serializers/rest/notification_serializer.rb create mode 100644 app/serializers/rest/preview_card_serializer.rb create mode 100644 app/serializers/rest/relationship_serializer.rb create mode 100644 app/serializers/rest/report_serializer.rb create mode 100644 app/serializers/rest/search_serializer.rb create mode 100644 app/serializers/rest/status_serializer.rb delete mode 100644 app/views/api/v1/accounts/index.rabl delete mode 100644 app/views/api/v1/accounts/relationship.rabl delete mode 100644 app/views/api/v1/accounts/relationships/index.rabl delete mode 100644 app/views/api/v1/accounts/show.rabl delete mode 100644 app/views/api/v1/accounts/statuses/index.rabl delete mode 100644 app/views/api/v1/apps/create.rabl delete mode 100644 app/views/api/v1/apps/show.rabl delete mode 100644 app/views/api/v1/blocks/index.rabl delete mode 100644 app/views/api/v1/favourites/index.rabl delete mode 100644 app/views/api/v1/follow_requests/index.rabl delete mode 100644 app/views/api/v1/follows/show.rabl delete mode 100644 app/views/api/v1/instances/show.rabl delete mode 100644 app/views/api/v1/media/create.rabl delete mode 100644 app/views/api/v1/mutes/index.rabl delete mode 100644 app/views/api/v1/notifications/index.rabl delete mode 100644 app/views/api/v1/notifications/show.rabl delete mode 100644 app/views/api/v1/reports/index.rabl delete mode 100644 app/views/api/v1/reports/show.rabl delete mode 100644 app/views/api/v1/search/index.rabl delete mode 100644 app/views/api/v1/statuses/_media.rabl delete mode 100644 app/views/api/v1/statuses/_mention.rabl delete mode 100644 app/views/api/v1/statuses/_show.rabl delete mode 100644 app/views/api/v1/statuses/_tags.rabl delete mode 100644 app/views/api/v1/statuses/accounts.rabl delete mode 100644 app/views/api/v1/statuses/card.rabl delete mode 100644 app/views/api/v1/statuses/context.rabl delete mode 100644 app/views/api/v1/statuses/index.rabl delete mode 100644 app/views/api/v1/statuses/show.rabl delete mode 100644 app/views/api/v1/timelines/show.rabl delete mode 100644 spec/lib/inline_rabl_scope_spec.rb (limited to 'app/models') diff --git a/Gemfile b/Gemfile index 6ee884a17..95c74eef9 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ gem 'aws-sdk', '~> 2.9' gem 'paperclip', '~> 5.1' gem 'paperclip-av-transcoder', '~> 0.6' +gem 'active_model_serializers', '~> 0.10' gem 'addressable', '~> 2.5' gem 'bootsnap' gem 'browser' diff --git a/Gemfile.lock b/Gemfile.lock index f0156529c..71f83f736 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,6 +24,11 @@ GEM erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) + 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.2) active_record_query_trace (1.5.4) activejob (5.1.2) activesupport (= 5.1.2) @@ -101,6 +106,8 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) + case_transform (0.2) + activesupport chunky_png (1.3.8) cld3 (3.1.3) ffi (>= 1.1.0, < 1.10.0) @@ -200,6 +207,7 @@ GEM terminal-table (>= 1.5.1) jmespath (1.3.1) json (2.1.0) + jsonapi-renderer (0.1.2) kaminari (1.0.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.0.1) @@ -476,6 +484,7 @@ PLATFORMS ruby DEPENDENCIES + active_model_serializers (~> 0.10) active_record_query_trace (~> 1.5) addressable (~> 2.5) annotate (~> 2.7) diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index 1cf52ff10..8ee9a2416 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -6,13 +6,13 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController def show @account = current_account - render 'api/v1/accounts/show' + render json: @account, serializer: REST::AccountSerializer end def update current_account.update!(account_params) @account = current_account - render 'api/v1/accounts/show' + render json: @account, serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb index 81aae56d3..80b0bef40 100644 --- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb @@ -9,7 +9,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController def index @accounts = load_accounts - render 'api/v1/accounts/index' + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb index 63c6d54b2..55cffdf37 100644 --- a/app/controllers/api/v1/accounts/following_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb @@ -9,7 +9,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController def index @accounts = load_accounts - render 'api/v1/accounts/index' + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/accounts/relationships_controller.rb b/app/controllers/api/v1/accounts/relationships_controller.rb index cb923ab91..a88cf2021 100644 --- a/app/controllers/api/v1/accounts/relationships_controller.rb +++ b/app/controllers/api/v1/accounts/relationships_controller.rb @@ -8,16 +8,15 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController def index @accounts = Account.where(id: account_ids).select('id') - @following = Account.following_map(account_ids, current_user.account_id) - @followed_by = Account.followed_by_map(account_ids, current_user.account_id) - @blocking = Account.blocking_map(account_ids, current_user.account_id) - @muting = Account.muting_map(account_ids, current_user.account_id) - @requested = Account.requested_map(account_ids, current_user.account_id) - @domain_blocking = Account.domain_blocking_map(account_ids, current_user.account_id) + render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships end private + def relationships + AccountRelationshipsPresenter.new(@accounts, current_user.account_id) + end + def account_ids @_account_ids ||= Array(params[:id]).map(&:to_i) end diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb index c4a8f97f2..2a5cac547 100644 --- a/app/controllers/api/v1/accounts/search_controller.rb +++ b/app/controllers/api/v1/accounts/search_controller.rb @@ -8,8 +8,7 @@ class Api::V1::Accounts::SearchController < Api::BaseController def show @accounts = account_search - - render 'api/v1/accounts/index' + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb index 504ed8c07..d9ae5c089 100644 --- a/app/controllers/api/v1/accounts/statuses_controller.rb +++ b/app/controllers/api/v1/accounts/statuses_controller.rb @@ -9,6 +9,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController def index @statuses = load_statuses + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end private @@ -18,9 +19,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController end def load_statuses - cached_account_statuses.tap do |statuses| - set_maps(statuses) - end + cached_account_statuses end def cached_account_statuses diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 8fc0dd36f..f621aa245 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -8,49 +8,38 @@ class Api::V1::AccountsController < Api::BaseController respond_to :json - def show; end + def show + render json: @account, serializer: REST::AccountSerializer + end def follow FollowService.new.call(current_user.account, @account.acct) - set_relationship - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end def block BlockService.new.call(current_user.account, @account) - - @following = { @account.id => false } - @followed_by = { @account.id => false } - @blocking = { @account.id => true } - @requested = { @account.id => false } - @muting = { @account.id => current_account.muting?(@account.id) } - @domain_blocking = { @account.id => current_account.domain_blocking?(@account.domain) } - - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end def mute MuteService.new.call(current_user.account, @account) - set_relationship - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end def unfollow UnfollowService.new.call(current_user.account, @account) - set_relationship - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end def unblock UnblockService.new.call(current_user.account, @account) - set_relationship - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end def unmute UnmuteService.new.call(current_user.account, @account) - set_relationship - render :relationship + render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end private @@ -59,12 +48,7 @@ class Api::V1::AccountsController < Api::BaseController @account = Account.find(params[:id]) end - def set_relationship - @following = Account.following_map([@account.id], current_user.account_id) - @followed_by = Account.followed_by_map([@account.id], current_user.account_id) - @blocking = Account.blocking_map([@account.id], current_user.account_id) - @muting = Account.muting_map([@account.id], current_user.account_id) - @requested = Account.requested_map([@account.id], current_user.account_id) - @domain_blocking = Account.domain_blocking_map([@account.id], current_user.account_id) + def relationships + AccountRelationshipsPresenter.new([@account.id], current_user.account_id) end end diff --git a/app/controllers/api/v1/apps_controller.rb b/app/controllers/api/v1/apps_controller.rb index 98e908948..44a27b20a 100644 --- a/app/controllers/api/v1/apps_controller.rb +++ b/app/controllers/api/v1/apps_controller.rb @@ -5,6 +5,7 @@ class Api::V1::AppsController < Api::BaseController def create @app = Doorkeeper::Application.create!(application_options) + render json: @app, serializer: REST::ApplicationSerializer end private diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb index 1702953cf..a412e4341 100644 --- a/app/controllers/api/v1/blocks_controller.rb +++ b/app/controllers/api/v1/blocks_controller.rb @@ -9,6 +9,7 @@ class Api::V1::BlocksController < Api::BaseController def index @accounts = load_accounts + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb index fe0819a3f..92c0a62a9 100644 --- a/app/controllers/api/v1/favourites_controller.rb +++ b/app/controllers/api/v1/favourites_controller.rb @@ -9,14 +9,13 @@ class Api::V1::FavouritesController < Api::BaseController def index @statuses = load_statuses + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end private def load_statuses - cached_favourites.tap do |statuses| - set_maps(statuses) - end + cached_favourites end def cached_favourites diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb index eed22ef4f..b9f50d784 100644 --- a/app/controllers/api/v1/follow_requests_controller.rb +++ b/app/controllers/api/v1/follow_requests_controller.rb @@ -7,6 +7,7 @@ class Api::V1::FollowRequestsController < Api::BaseController def index @accounts = load_accounts + render json: @accounts, each_serializer: REST::AccountSerializer end def authorize diff --git a/app/controllers/api/v1/follows_controller.rb b/app/controllers/api/v1/follows_controller.rb index bcdb4e177..e01ae5c01 100644 --- a/app/controllers/api/v1/follows_controller.rb +++ b/app/controllers/api/v1/follows_controller.rb @@ -10,7 +10,7 @@ class Api::V1::FollowsController < Api::BaseController raise ActiveRecord::RecordNotFound if follow_params[:uri].blank? @account = FollowService.new.call(current_user.account, target_uri).try(:target_account) - render :show + render json: @account, serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb index ce2181879..1c6971c18 100644 --- a/app/controllers/api/v1/instances_controller.rb +++ b/app/controllers/api/v1/instances_controller.rb @@ -3,5 +3,7 @@ class Api::V1::InstancesController < Api::BaseController respond_to :json - def show; end + def show + render json: {}, serializer: REST::InstanceSerializer + end end diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index 25a331319..8a1992fca 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -11,6 +11,7 @@ class Api::V1::MediaController < Api::BaseController def create @media = current_account.media_attachments.create!(file: media_params[:file]) + render json: @media, serializer: REST::MediaAttachmentSerializer rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: file_type_error, status: 422 rescue Paperclip::Error diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb index 2a353df03..0c43cb943 100644 --- a/app/controllers/api/v1/mutes_controller.rb +++ b/app/controllers/api/v1/mutes_controller.rb @@ -9,6 +9,7 @@ class Api::V1::MutesController < Api::BaseController def index @accounts = load_accounts + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb index a28e99f2f..8910b77e9 100644 --- a/app/controllers/api/v1/notifications_controller.rb +++ b/app/controllers/api/v1/notifications_controller.rb @@ -11,11 +11,12 @@ class Api::V1::NotificationsController < Api::BaseController def index @notifications = load_notifications - set_maps_for_notification_target_statuses + render json: @notifications, each_serializer: REST::NotificationSerializer, relationships: StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id) end def show @notification = current_account.notifications.find(params[:id]) + render json: @notification, serializer: REST::NotificationSerializer end def clear @@ -46,10 +47,6 @@ class Api::V1::NotificationsController < Api::BaseController current_account.notifications.browserable(exclude_types) end - def set_maps_for_notification_target_statuses - set_maps target_statuses_from_notifications - end - def target_statuses_from_notifications @notifications.reject { |notification| notification.target_status.nil? }.map(&:target_status) end diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index 8e7070d07..9592cd4bd 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -9,6 +9,7 @@ class Api::V1::ReportsController < Api::BaseController def index @reports = current_account.reports + render json: @reports, each_serializer: REST::ReportSerializer end def create @@ -20,7 +21,7 @@ class Api::V1::ReportsController < Api::BaseController User.admins.includes(:account).each { |u| AdminMailer.new_report(u.account, @report).deliver_later } - render :show + render json: @report, serializer: REST::ReportSerializer end private diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 8b832148c..1353682ea 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -6,7 +6,8 @@ class Api::V1::SearchController < Api::BaseController respond_to :json def index - @search = OpenStruct.new(search_results) + @search = Search.new(search_results) + render json: @search, serializer: REST::SearchSerializer end private diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb index e58184939..f95cf9457 100644 --- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb @@ -11,7 +11,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController def index @accounts = load_accounts - render 'api/v1/statuses/accounts' + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/statuses/favourites_controller.rb b/app/controllers/api/v1/statuses/favourites_controller.rb index b6fb13cc0..4c4b0c160 100644 --- a/app/controllers/api/v1/statuses/favourites_controller.rb +++ b/app/controllers/api/v1/statuses/favourites_controller.rb @@ -10,7 +10,7 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController def create @status = favourited_status - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end def destroy @@ -19,7 +19,7 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController UnfavouriteWorker.perform_async(current_user.account_id, @status.id) - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end private diff --git a/app/controllers/api/v1/statuses/mutes_controller.rb b/app/controllers/api/v1/statuses/mutes_controller.rb index eab88f2ef..a4bf0acdd 100644 --- a/app/controllers/api/v1/statuses/mutes_controller.rb +++ b/app/controllers/api/v1/statuses/mutes_controller.rb @@ -14,14 +14,14 @@ class Api::V1::Statuses::MutesController < Api::BaseController current_account.mute_conversation!(@conversation) @mutes_map = { @conversation.id => true } - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end def destroy current_account.unmute_conversation!(@conversation) @mutes_map = { @conversation.id => false } - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end private diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb index 43593d3c5..175217e6e 100644 --- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb @@ -11,7 +11,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController def index @accounts = load_accounts - render 'api/v1/statuses/accounts' + render json: @accounts, each_serializer: REST::AccountSerializer end private diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb index ee9c5b3a6..f7f4b5a5c 100644 --- a/app/controllers/api/v1/statuses/reblogs_controller.rb +++ b/app/controllers/api/v1/statuses/reblogs_controller.rb @@ -10,7 +10,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController def create @status = ReblogService.new.call(current_user.account, status_for_reblog) - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end def destroy @@ -20,7 +20,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController authorize status_for_destroy, :unreblog? RemovalWorker.perform_async(status_for_destroy.id) - render 'api/v1/statuses/show' + render json: @status, serializer: REST::StatusSerializer end private diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 9aa1cbc4d..9c7124d0f 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -13,6 +13,7 @@ class Api::V1::StatusesController < Api::BaseController def show cached = Rails.cache.read(@status.cache_key) @status = cached unless cached.nil? + render json: @status, serializer: REST::StatusSerializer end def context @@ -21,15 +22,20 @@ class Api::V1::StatusesController < Api::BaseController loaded_ancestors = cache_collection(ancestors_results, Status) loaded_descendants = cache_collection(descendants_results, Status) - @context = OpenStruct.new(ancestors: loaded_ancestors, descendants: loaded_descendants) - statuses = [@status] + @context[:ancestors] + @context[:descendants] + @context = Context.new(ancestors: loaded_ancestors, descendants: loaded_descendants) + statuses = [@status] + @context.ancestors + @context.descendants - set_maps(statuses) + render json: @context, serializer: REST::ContextSerializer, relationships: StatusRelationshipsPresenter.new(statuses, current_user&.account_id) end def card @card = PreviewCard.find_by(status: @status) - render_empty if @card.nil? + + if @card.nil? + render_empty + else + render json: @card, serializer: REST::PreviewCardSerializer + end end def create @@ -43,7 +49,7 @@ class Api::V1::StatusesController < Api::BaseController application: doorkeeper_token.application, idempotency: request.headers['Idempotency-Key']) - render :show + render json: @status, serializer: REST::StatusSerializer end def destroy diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb index 511d2f65d..3dd27710c 100644 --- a/app/controllers/api/v1/timelines/home_controller.rb +++ b/app/controllers/api/v1/timelines/home_controller.rb @@ -9,15 +9,13 @@ class Api::V1::Timelines::HomeController < Api::BaseController def show @statuses = load_statuses - render 'api/v1/timelines/show' + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end private def load_statuses - cached_home_statuses.tap do |statuses| - set_maps(statuses) - end + cached_home_statuses end def cached_home_statuses diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 305451cc7..49887778e 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -7,15 +7,13 @@ class Api::V1::Timelines::PublicController < Api::BaseController def show @statuses = load_statuses - render 'api/v1/timelines/show' + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end private def load_statuses - cached_public_statuses.tap do |statuses| - set_maps(statuses) - end + cached_public_statuses end def cached_public_statuses diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb index 50afca7c7..08db04a39 100644 --- a/app/controllers/api/v1/timelines/tag_controller.rb +++ b/app/controllers/api/v1/timelines/tag_controller.rb @@ -8,7 +8,7 @@ class Api::V1::Timelines::TagController < Api::BaseController def show @statuses = load_statuses - render 'api/v1/timelines/show' + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end private @@ -18,9 +18,7 @@ class Api::V1::Timelines::TagController < Api::BaseController end def load_statuses - cached_tagged_statuses.tap do |statuses| - set_maps(statuses) - end + cached_tagged_statuses end def cached_tagged_statuses diff --git a/app/lib/inline_rabl_scope.rb b/app/lib/inline_rabl_scope.rb deleted file mode 100644 index 26adcb03a..000000000 --- a/app/lib/inline_rabl_scope.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -class InlineRablScope - include RoutingHelper - - def initialize(account) - @account = account - end - - def current_user - @account.try(:user) - end - - def current_account - @account - end -end diff --git a/app/lib/inline_renderer.rb b/app/lib/inline_renderer.rb index 8e04ad1d5..7cd9758ec 100644 --- a/app/lib/inline_renderer.rb +++ b/app/lib/inline_renderer.rb @@ -1,13 +1,33 @@ # frozen_string_literal: true class InlineRenderer - def self.render(status, current_account, template) - Rabl::Renderer.new( - template, - status, - view_path: 'app/views', - format: :json, - scope: InlineRablScope.new(current_account) - ).render + def initialize(object, current_account, template) + @object = object + @current_account = current_account + @template = template + end + + def render + case @template + when :status + serializer = REST::StatusSerializer + when :notification + serializer = REST::NotificationSerializer + else + return + end + + serializable_resource = ActiveModelSerializers::SerializableResource.new(@object, serializer: serializer, scope: current_user, scope_name: :current_user) + serializable_resource.as_json + end + + def self.render(object, current_account, template) + new(object, current_account, template).render + end + + private + + def current_user + @current_account&.user end end diff --git a/app/models/context.rb b/app/models/context.rb new file mode 100644 index 000000000..cc667999e --- /dev/null +++ b/app/models/context.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Context < ActiveModelSerializers::Model + attributes :ancestors, :descendants +end diff --git a/app/models/search.rb b/app/models/search.rb new file mode 100644 index 000000000..676c2a7f8 --- /dev/null +++ b/app/models/search.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Search < ActiveModelSerializers::Model + attributes :accounts, :statuses, :hashtags +end diff --git a/app/presenters/account_relationships_presenter.rb b/app/presenters/account_relationships_presenter.rb new file mode 100644 index 000000000..657807863 --- /dev/null +++ b/app/presenters/account_relationships_presenter.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AccountRelationshipsPresenter + attr_reader :following, :followed_by, :blocking, + :muting, :requested, :domain_blocking + + def initialize(account_ids, current_account_id) + @following = Account.following_map(account_ids, current_account_id) + @followed_by = Account.followed_by_map(account_ids, current_account_id) + @blocking = Account.blocking_map(account_ids, current_account_id) + @muting = Account.muting_map(account_ids, current_account_id) + @requested = Account.requested_map(account_ids, current_account_id) + @domain_blocking = Account.domain_blocking_map(account_ids, current_account_id) + end +end diff --git a/app/presenters/status_relationships_presenter.rb b/app/presenters/status_relationships_presenter.rb new file mode 100644 index 000000000..caf00791a --- /dev/null +++ b/app/presenters/status_relationships_presenter.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class StatusRelationshipsPresenter + attr_reader :reblogs_map, :favourites_map, :mutes_map + + def initialize(statuses, current_account_id = nil) + if current_account_id.nil? + @reblogs_map = {} + @favourites_map = {} + @mutes_map = {} + else + status_ids = statuses.compact.flat_map { |s| [s.id, s.reblog_of_id] }.uniq + conversation_ids = statuses.compact.map(&:conversation_id).compact.uniq + @reblogs_map = Status.reblogs_map(status_ids, current_account_id) + @favourites_map = Status.favourites_map(status_ids, current_account_id) + @mutes_map = Status.mutes_map(conversation_ids, current_account_id) + end + end +end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb new file mode 100644 index 000000000..012a4fd18 --- /dev/null +++ b/app/serializers/rest/account_serializer.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +class REST::AccountSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :id, :username, :acct, :display_name, :locked, :created_at, + :note, :url, :avatar, :avatar_static, :header, :header_static, + :followers_count, :following_count, :statuses_count + + def note + Formatter.instance.simplified_format(object) + end + + def url + TagManager.instance.url_for(object) + end + + def avatar + full_asset_url(object.avatar_original_url) + end + + def avatar_static + full_asset_url(object.avatar_static_url) + end + + def header + full_asset_url(object.header_original_url) + end + + def header_static + full_asset_url(object.header_static_url) + end +end diff --git a/app/serializers/rest/application_serializer.rb b/app/serializers/rest/application_serializer.rb new file mode 100644 index 000000000..868a62f1e --- /dev/null +++ b/app/serializers/rest/application_serializer.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class REST::ApplicationSerializer < ActiveModel::Serializer + attributes :id, :name, :website, :redirect_uri, + :client_id, :client_secret + + def client_id + object.uid + end + + def client_secret + object.secret + end +end diff --git a/app/serializers/rest/context_serializer.rb b/app/serializers/rest/context_serializer.rb new file mode 100644 index 000000000..44515c85d --- /dev/null +++ b/app/serializers/rest/context_serializer.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class REST::ContextSerializer < ActiveModel::Serializer + has_many :ancestors, serializer: REST::StatusSerializer + has_many :descendants, serializer: REST::StatusSerializer +end diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb new file mode 100644 index 000000000..8e32f9cb3 --- /dev/null +++ b/app/serializers/rest/instance_serializer.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class REST::InstanceSerializer < ActiveModel::Serializer + attributes :uri, :title, :description, :email, + :version, :urls + + def uri + Rails.configuration.x.local_domain + end + + def title + Setting.site_title + end + + def description + Setting.site_description + end + + def email + Setting.site_contact_email + end + + def version + Mastodon::Version.to_s + end + + def urls + { streaming_api: Rails.configuration.x.streaming_api_base_url } + end +end diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb new file mode 100644 index 000000000..9b07a686e --- /dev/null +++ b/app/serializers/rest/media_attachment_serializer.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class REST::MediaAttachmentSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :id, :type, :url, :preview_url, + :remote_url, :text_url, :meta + + def url + full_asset_url(object.file.url(:original)) + end + + def preview_url + full_asset_url(object.file.url(:small)) + end + + def text_url + medium_url(object.id) + end + + def meta + object.file.meta + end +end diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb new file mode 100644 index 000000000..97fadf32e --- /dev/null +++ b/app/serializers/rest/notification_serializer.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class REST::NotificationSerializer < ActiveModel::Serializer + attributes :id, :type, :created_at + + belongs_to :from_account, key: :account, serializer: REST::AccountSerializer + belongs_to :status, if: :status_type?, serializer: REST::StatusSerializer + + def status_type? + [:favourite, :reblog, :mention].include?(object.type) + end +end diff --git a/app/serializers/rest/preview_card_serializer.rb b/app/serializers/rest/preview_card_serializer.rb new file mode 100644 index 000000000..9c460332c --- /dev/null +++ b/app/serializers/rest/preview_card_serializer.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class REST::PreviewCardSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :url, :title, :description, :type, + :author_name, :author_url, :provider_name, + :provider_url, :html, :width, :height, + :image + + def image + object.image? ? full_asset_url(object.image.url(:original)) : nil + end +end diff --git a/app/serializers/rest/relationship_serializer.rb b/app/serializers/rest/relationship_serializer.rb new file mode 100644 index 000000000..1d431aa1b --- /dev/null +++ b/app/serializers/rest/relationship_serializer.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class REST::RelationshipSerializer < ActiveModel::Serializer + attributes :id, :following, :followed_by, :blocking, + :muting, :requested, :domain_blocking + + def following + instance_options[:relationships].following[object.id] || false + end + + def followed_by + instance_options[:relationships].followed_by[object.id] || false + end + + def blocking + instance_options[:relationships].blocking[object.id] || false + end + + def muting + instance_options[:relationships].muting[object.id] || false + end + + def requested + instance_options[:relationships].requested[object.id] || false + end + + def domain_blocking + instance_options[:relationships].domain_blocking[object.id] || false + end +end diff --git a/app/serializers/rest/report_serializer.rb b/app/serializers/rest/report_serializer.rb new file mode 100644 index 000000000..0c6bd6556 --- /dev/null +++ b/app/serializers/rest/report_serializer.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class REST::ReportSerializer < ActiveModel::Serializer + attributes :id, :action_taken +end diff --git a/app/serializers/rest/search_serializer.rb b/app/serializers/rest/search_serializer.rb new file mode 100644 index 000000000..157f543ae --- /dev/null +++ b/app/serializers/rest/search_serializer.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class REST::SearchSerializer < ActiveModel::Serializer + attributes :hashtags + + has_many :accounts, serializer: REST::AccountSerializer + has_many :statuses, serializer: REST::StatusSerializer + + def hashtags + object.hashtags.map(&:name) + end +end diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb new file mode 100644 index 000000000..246b12a90 --- /dev/null +++ b/app/serializers/rest/status_serializer.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +class REST::StatusSerializer < ActiveModel::Serializer + attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, + :sensitive, :spoiler_text, :visibility, :language, + :uri, :content, :url, :reblogs_count, :favourites_count + + attribute :favourited, if: :current_user? + attribute :reblogged, if: :current_user? + attribute :muted, if: :current_user? + + belongs_to :reblog, serializer: REST::StatusSerializer + belongs_to :application + belongs_to :account, serializer: REST::AccountSerializer + + has_many :media_attachments, serializer: REST::MediaAttachmentSerializer + has_many :mentions + has_many :tags + + def current_user? + !current_user.nil? + end + + def uri + TagManager.instance.uri_for(object) + end + + def content + Formatter.instance.format(object) + end + + def url + TagManager.instance.url_for(object) + end + + def favourited + if instance_options && instance_options[:relationships] + instance_options[:relationships].favourites_map[object.id] || false + else + current_user.account.favourited?(object) + end + end + + def reblogged + if instance_options && instance_options[:relationships] + instance_options[:relationships].reblogs_map[object.id] || false + else + current_user.account.reblogged?(object) + end + end + + def muted + if instance_options && instance_options[:relationships] + instance_options[:relationships].mutes_map[object.conversation_id] || false + else + current_user.account.muting_conversation?(object.conversation) + end + end + + class ApplicationSerializer < ActiveModel::Serializer + attributes :name, :website + end + + class MentionSerializer < ActiveModel::Serializer + attributes :id, :username, :url, :acct + + def id + object.account_id + end + + def username + object.account_username + end + + def url + TagManager.instance.url_for(object.account) + end + + def acct + object.account_acct + end + end + + class TagSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :name, :url + + def url + tag_url(object) + end + end +end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 3b74696d5..47a47a735 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -54,7 +54,7 @@ class FanOutOnWriteService < BaseService end def render_anonymous_payload(status) - @payload = InlineRenderer.render(status, nil, 'api/v1/statuses/show') + @payload = InlineRenderer.render(status, nil, :status) @payload = Oj.dump(event: :update, payload: @payload) end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 422d5f97e..407d385ea 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -60,7 +60,7 @@ class NotifyService < BaseService def create_notification @notification.save! return unless @notification.browserable? - Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, 'api/v1/notifications/show'))) + Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, :notification))) end def send_email diff --git a/app/views/api/v1/accounts/index.rabl b/app/views/api/v1/accounts/index.rabl deleted file mode 100644 index 9f3b13a53..000000000 --- a/app/views/api/v1/accounts/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/show' diff --git a/app/views/api/v1/accounts/relationship.rabl b/app/views/api/v1/accounts/relationship.rabl deleted file mode 100644 index 4f7763d9d..000000000 --- a/app/views/api/v1/accounts/relationship.rabl +++ /dev/null @@ -1,9 +0,0 @@ -object @account - -attribute :id -node(:following) { |account| @following[account.id] || false } -node(:followed_by) { |account| @followed_by[account.id] || false } -node(:blocking) { |account| @blocking[account.id] || false } -node(:muting) { |account| @muting[account.id] || false } -node(:requested) { |account| @requested[account.id] || false } -node(:domain_blocking) { |account| @domain_blocking[account.id] || false } diff --git a/app/views/api/v1/accounts/relationships/index.rabl b/app/views/api/v1/accounts/relationships/index.rabl deleted file mode 100644 index 022ea2ac4..000000000 --- a/app/views/api/v1/accounts/relationships/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/relationship' diff --git a/app/views/api/v1/accounts/show.rabl b/app/views/api/v1/accounts/show.rabl deleted file mode 100644 index 8826aa22d..000000000 --- a/app/views/api/v1/accounts/show.rabl +++ /dev/null @@ -1,12 +0,0 @@ -object @account - -attributes :id, :username, :acct, :display_name, :locked, :created_at - -node(:note) { |account| Formatter.instance.simplified_format(account) } -node(:url) { |account| TagManager.instance.url_for(account) } -node(:avatar) { |account| full_asset_url(account.avatar_original_url) } -node(:avatar_static) { |account| full_asset_url(account.avatar_static_url) } -node(:header) { |account| full_asset_url(account.header_original_url) } -node(:header_static) { |account| full_asset_url(account.header_static_url) } - -attributes :followers_count, :following_count, :statuses_count diff --git a/app/views/api/v1/accounts/statuses/index.rabl b/app/views/api/v1/accounts/statuses/index.rabl deleted file mode 100644 index 44d29d91b..000000000 --- a/app/views/api/v1/accounts/statuses/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @statuses -extends 'api/v1/statuses/show' diff --git a/app/views/api/v1/apps/create.rabl b/app/views/api/v1/apps/create.rabl deleted file mode 100644 index 1ff6469a4..000000000 --- a/app/views/api/v1/apps/create.rabl +++ /dev/null @@ -1,4 +0,0 @@ -object @app -attributes :id, :redirect_uri -node(:client_id) { |app| app.uid } -node(:client_secret) { |app| app.secret } diff --git a/app/views/api/v1/apps/show.rabl b/app/views/api/v1/apps/show.rabl deleted file mode 100644 index 6d9e607db..000000000 --- a/app/views/api/v1/apps/show.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @application - -attributes :name, :website diff --git a/app/views/api/v1/blocks/index.rabl b/app/views/api/v1/blocks/index.rabl deleted file mode 100644 index 9f3b13a53..000000000 --- a/app/views/api/v1/blocks/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/show' diff --git a/app/views/api/v1/favourites/index.rabl b/app/views/api/v1/favourites/index.rabl deleted file mode 100644 index 44d29d91b..000000000 --- a/app/views/api/v1/favourites/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @statuses -extends 'api/v1/statuses/show' diff --git a/app/views/api/v1/follow_requests/index.rabl b/app/views/api/v1/follow_requests/index.rabl deleted file mode 100644 index 9f3b13a53..000000000 --- a/app/views/api/v1/follow_requests/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/show' diff --git a/app/views/api/v1/follows/show.rabl b/app/views/api/v1/follows/show.rabl deleted file mode 100644 index e07106164..000000000 --- a/app/views/api/v1/follows/show.rabl +++ /dev/null @@ -1,2 +0,0 @@ -object @account -extends('api/v1/accounts/show') diff --git a/app/views/api/v1/instances/show.rabl b/app/views/api/v1/instances/show.rabl deleted file mode 100644 index 05fb65031..000000000 --- a/app/views/api/v1/instances/show.rabl +++ /dev/null @@ -1,10 +0,0 @@ -object false - -node(:uri) { site_hostname } -node(:title) { Setting.site_title } -node(:description) { Setting.site_description } -node(:email) { Setting.site_contact_email } -node(:version) { Mastodon::Version.to_s } -node :urls do - { :streaming_api => Rails.configuration.x.streaming_api_base_url } -end diff --git a/app/views/api/v1/media/create.rabl b/app/views/api/v1/media/create.rabl deleted file mode 100644 index 53c13bbda..000000000 --- a/app/views/api/v1/media/create.rabl +++ /dev/null @@ -1,7 +0,0 @@ -object @media -attribute :id, :type - -node(:url) { |media| full_asset_url(media.file.url(:original)) } -node(:preview_url) { |media| full_asset_url(media.file.url(:small)) } -node(:text_url) { |media| medium_url(media) } -node(:meta) { |media| media.file.meta } diff --git a/app/views/api/v1/mutes/index.rabl b/app/views/api/v1/mutes/index.rabl deleted file mode 100644 index 9f3b13a53..000000000 --- a/app/views/api/v1/mutes/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/show' diff --git a/app/views/api/v1/notifications/index.rabl b/app/views/api/v1/notifications/index.rabl deleted file mode 100644 index 6abc3da36..000000000 --- a/app/views/api/v1/notifications/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @notifications -extends 'api/v1/notifications/show' diff --git a/app/views/api/v1/notifications/show.rabl b/app/views/api/v1/notifications/show.rabl deleted file mode 100644 index ca34f2d5d..000000000 --- a/app/views/api/v1/notifications/show.rabl +++ /dev/null @@ -1,11 +0,0 @@ -object @notification - -attributes :id, :type, :created_at - -child from_account: :account do - extends 'api/v1/accounts/show' -end - -node(:status, if: lambda { |n| [:favourite, :reblog, :mention].include?(n.type) }) do |n| - partial 'api/v1/statuses/show', object: n.target_status -end diff --git a/app/views/api/v1/reports/index.rabl b/app/views/api/v1/reports/index.rabl deleted file mode 100644 index 4f0794027..000000000 --- a/app/views/api/v1/reports/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @reports -extends 'api/v1/reports/show' diff --git a/app/views/api/v1/reports/show.rabl b/app/views/api/v1/reports/show.rabl deleted file mode 100644 index 006db51e3..000000000 --- a/app/views/api/v1/reports/show.rabl +++ /dev/null @@ -1,2 +0,0 @@ -object @report -attributes :id, :action_taken diff --git a/app/views/api/v1/search/index.rabl b/app/views/api/v1/search/index.rabl deleted file mode 100644 index 8d1640f2d..000000000 --- a/app/views/api/v1/search/index.rabl +++ /dev/null @@ -1,13 +0,0 @@ -object @search - -child :accounts, object_root: false do - extends 'api/v1/accounts/show' -end - -node(:hashtags) do |search| - search.hashtags.map(&:name) -end - -child :statuses, object_root: false do - extends 'api/v1/statuses/show' -end diff --git a/app/views/api/v1/statuses/_media.rabl b/app/views/api/v1/statuses/_media.rabl deleted file mode 100644 index 07ac31888..000000000 --- a/app/views/api/v1/statuses/_media.rabl +++ /dev/null @@ -1,6 +0,0 @@ -attributes :id, :remote_url, :type - -node(:url) { |media| full_asset_url(media.file.url(:original)) } -node(:preview_url) { |media| full_asset_url(media.file.url(:small)) } -node(:text_url) { |media| media.local? ? medium_url(media) : nil } -node(:meta) { |media| media.file.meta } diff --git a/app/views/api/v1/statuses/_mention.rabl b/app/views/api/v1/statuses/_mention.rabl deleted file mode 100644 index 8c95fc9bd..000000000 --- a/app/views/api/v1/statuses/_mention.rabl +++ /dev/null @@ -1,4 +0,0 @@ -node(:url) { |mention| TagManager.instance.url_for(mention.account) } -node(:acct) { |mention| mention.account_acct } -node(:id) { |mention| mention.account_id } -node(:username) { |mention| mention.account_username } diff --git a/app/views/api/v1/statuses/_show.rabl b/app/views/api/v1/statuses/_show.rabl deleted file mode 100644 index fe3ec89ab..000000000 --- a/app/views/api/v1/statuses/_show.rabl +++ /dev/null @@ -1,29 +0,0 @@ -attributes :id, :created_at, :in_reply_to_id, - :in_reply_to_account_id, :sensitive, - :spoiler_text, :visibility, :language - -node(:uri) { |status| TagManager.instance.uri_for(status) } -node(:content) { |status| Formatter.instance.format(status) } -node(:url) { |status| TagManager.instance.url_for(status) } -node(:reblogs_count) { |status| defined?(@reblogs_counts_map) ? (@reblogs_counts_map[status.id] || 0) : status.reblogs_count } -node(:favourites_count) { |status| defined?(@favourites_counts_map) ? (@favourites_counts_map[status.id] || 0) : status.favourites_count } - -child :application do - extends 'api/v1/apps/show' -end - -child :account do - extends 'api/v1/accounts/show' -end - -child :media_attachments, object_root: false do - extends 'api/v1/statuses/_media' -end - -child :mentions, object_root: false do - extends 'api/v1/statuses/_mention' -end - -child :tags, object_root: false do - extends 'api/v1/statuses/_tags' -end diff --git a/app/views/api/v1/statuses/_tags.rabl b/app/views/api/v1/statuses/_tags.rabl deleted file mode 100644 index 25e7b0fac..000000000 --- a/app/views/api/v1/statuses/_tags.rabl +++ /dev/null @@ -1,2 +0,0 @@ -attribute :name -node(:url) { |tag| tag_url(tag) } diff --git a/app/views/api/v1/statuses/accounts.rabl b/app/views/api/v1/statuses/accounts.rabl deleted file mode 100644 index 9f3b13a53..000000000 --- a/app/views/api/v1/statuses/accounts.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @accounts -extends 'api/v1/accounts/show' diff --git a/app/views/api/v1/statuses/card.rabl b/app/views/api/v1/statuses/card.rabl deleted file mode 100644 index 5d8d7af3b..000000000 --- a/app/views/api/v1/statuses/card.rabl +++ /dev/null @@ -1,7 +0,0 @@ -object @card - -attributes :url, :title, :description, :type, - :author_name, :author_url, :provider_name, - :provider_url, :html, :width, :height - -node(:image) { |card| card.image? ? full_asset_url(card.image.url(:original)) : nil } diff --git a/app/views/api/v1/statuses/context.rabl b/app/views/api/v1/statuses/context.rabl deleted file mode 100644 index 0b62f26d5..000000000 --- a/app/views/api/v1/statuses/context.rabl +++ /dev/null @@ -1,9 +0,0 @@ -object @context - -node :ancestors do |context| - partial 'api/v1/statuses/index', object: context.ancestors -end - -node :descendants do |context| - partial 'api/v1/statuses/index', object: context.descendants -end diff --git a/app/views/api/v1/statuses/index.rabl b/app/views/api/v1/statuses/index.rabl deleted file mode 100644 index 0a0ed13c5..000000000 --- a/app/views/api/v1/statuses/index.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @statuses -extends('api/v1/statuses/show') diff --git a/app/views/api/v1/statuses/show.rabl b/app/views/api/v1/statuses/show.rabl deleted file mode 100644 index 4b33fb2c3..000000000 --- a/app/views/api/v1/statuses/show.rabl +++ /dev/null @@ -1,15 +0,0 @@ -object @status - -extends 'api/v1/statuses/_show' - -node(:favourited, if: proc { !current_account.nil? }) { |status| defined?(@favourites_map) ? @favourites_map[status.id] : current_account.favourited?(status) } -node(:reblogged, if: proc { !current_account.nil? }) { |status| defined?(@reblogs_map) ? @reblogs_map[status.id] : current_account.reblogged?(status) } -node(:muted, if: proc { !current_account.nil? }) { |status| defined?(@mutes_map) ? @mutes_map[status.conversation_id] : current_account.muting_conversation?(status.conversation) } - -child reblog: :reblog do - extends 'api/v1/statuses/_show' - - node(:favourited, if: proc { !current_account.nil? }) { |status| defined?(@favourites_map) ? @favourites_map[status.id] : current_account.favourited?(status) } - node(:reblogged, if: proc { !current_account.nil? }) { |status| defined?(@reblogs_map) ? @reblogs_map[status.id] : current_account.reblogged?(status) } - node(:muted, if: proc { !current_account.nil? }) { false } -end diff --git a/app/views/api/v1/timelines/show.rabl b/app/views/api/v1/timelines/show.rabl deleted file mode 100644 index 0a0ed13c5..000000000 --- a/app/views/api/v1/timelines/show.rabl +++ /dev/null @@ -1,2 +0,0 @@ -collection @statuses -extends('api/v1/statuses/show') diff --git a/app/views/home/initial_state.json.rabl b/app/views/home/initial_state.json.rabl index 291ff806b..c428a5a1f 100644 --- a/app/views/home/initial_state.json.rabl +++ b/app/views/home/initial_state.json.rabl @@ -24,8 +24,8 @@ end node(:accounts) do store = {} - store[current_account.id] = partial('api/v1/accounts/show', object: current_account) - store[@admin.id] = partial('api/v1/accounts/show', object: @admin) unless @admin.nil? + store[current_account.id] = ActiveModelSerializers::SerializableResource.new(current_account, serializer: REST::AccountSerializer) + store[@admin.id] = ActiveModelSerializers::SerializableResource.new(@admin, serializer: REST::AccountSerializer) unless @admin.nil? store end diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index fbcdcf634..697cbd6a6 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -6,7 +6,7 @@ class PushUpdateWorker def perform(account_id, status_id) account = Account.find(account_id) status = Status.find(status_id) - message = InlineRenderer.render(status, account, 'api/v1/statuses/show') + message = InlineRenderer.render(status, account, :status) Redis.current.publish("timeline:#{account.id}", Oj.dump(event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i)) rescue ActiveRecord::RecordNotFound diff --git a/spec/lib/inline_rabl_scope_spec.rb b/spec/lib/inline_rabl_scope_spec.rb deleted file mode 100644 index 3fff176e4..000000000 --- a/spec/lib/inline_rabl_scope_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe InlineRablScope do - describe '#current_account' do - it 'returns the given account' do - account = Fabricate(:account) - expect(InlineRablScope.new(account).current_account).to eq account - end - end - - describe '#current_user' do - it 'returns nil if the given account is nil' do - expect(InlineRablScope.new(nil).current_user).to eq nil - end - - it 'returns user of account if the given account is not nil' do - user = Fabricate(:user) - expect(InlineRablScope.new(user.account).current_user).to eq user - end - end -end -- cgit From 2b9721d1b38319d70bed98e76a0fe1d648780298 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Mon, 10 Jul 2017 21:00:32 +0900 Subject: Add setting a always mark media as sensitive (#4136) --- app/controllers/settings/preferences_controller.rb | 1 + app/javascript/mastodon/reducers/compose.js | 7 +++++++ app/lib/user_settings_decorator.rb | 5 +++++ app/models/user.rb | 4 ++++ app/serializers/initial_state_serializer.rb | 1 + app/serializers/rest/credential_account_serializer.rb | 1 + app/views/settings/preferences/show.html.haml | 2 ++ config/locales/simple_form.en.yml | 1 + spec/lib/user_settings_decorator_spec.rb | 7 +++++++ 9 files changed, 29 insertions(+) (limited to 'app/models') diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index a15c26031..cac5b0ba8 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -34,6 +34,7 @@ class Settings::PreferencesController < ApplicationController def user_settings_params params.require(:user).permit( :setting_default_privacy, + :setting_default_sensitive, :setting_boost_modal, :setting_delete_modal, :setting_auto_play_gif, diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index d0b47a85c..752377739 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -45,6 +45,7 @@ const initialState = Immutable.Map({ suggestions: Immutable.List(), me: null, default_privacy: 'public', + default_sensitive: false, resetFileKey: Math.floor((Math.random() * 0x10000)), idempotencyKey: null, }); @@ -75,6 +76,8 @@ function clearAll(state) { }; function appendMedia(state, media) { + const prevSize = state.get('media_attachments').size; + return state.withMutations(map => { map.update('media_attachments', list => list.push(media)); map.set('is_uploading', false); @@ -82,6 +85,10 @@ function appendMedia(state, media) { map.update('text', oldText => `${oldText.trim()} ${media.get('text_url')}`); map.set('focusDate', new Date()); map.set('idempotencyKey', uuid()); + + if (prevSize === 0 && state.get('default_sensitive')) { + map.set('sensitive', true); + } }); }; diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 9c0cb4545..e0e92b19d 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -18,6 +18,7 @@ class UserSettingsDecorator user.settings['notification_emails'] = merged_notification_emails user.settings['interactions'] = merged_interactions user.settings['default_privacy'] = default_privacy_preference + user.settings['default_sensitive'] = default_sensitive_preference user.settings['boost_modal'] = boost_modal_preference user.settings['delete_modal'] = delete_modal_preference user.settings['auto_play_gif'] = auto_play_gif_preference @@ -36,6 +37,10 @@ class UserSettingsDecorator settings['setting_default_privacy'] end + def default_sensitive_preference + boolean_cast_setting 'setting_default_sensitive' + end + def boost_modal_preference boolean_cast_setting 'setting_boost_modal' end diff --git a/app/models/user.rb b/app/models/user.rb index e2bb3d0ed..c80115a08 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -79,6 +79,10 @@ class User < ApplicationRecord settings.default_privacy || (account.locked? ? 'private' : 'public') end + def setting_default_sensitive + settings.default_sensitive + end + def setting_boost_modal settings.boost_modal end diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 84f9e23a6..49ff9e377 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -23,6 +23,7 @@ class InitialStateSerializer < ActiveModel::Serializer { me: object.current_account.id, default_privacy: object.current_account.user.setting_default_privacy, + default_sensitive: object.current_account.user.setting_default_sensitive, } end diff --git a/app/serializers/rest/credential_account_serializer.rb b/app/serializers/rest/credential_account_serializer.rb index 094b831c9..870d8b71f 100644 --- a/app/serializers/rest/credential_account_serializer.rb +++ b/app/serializers/rest/credential_account_serializer.rb @@ -7,6 +7,7 @@ class REST::CredentialAccountSerializer < REST::AccountSerializer user = object.user { privacy: user.setting_default_privacy, + sensitive: user.setting_default_sensitive, note: object.note, } end diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index 26fbfdf82..56a261ab6 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -24,6 +24,8 @@ = f.input :setting_default_privacy, collection: Status.visibilities.keys - ['direct'], wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), content_tag(:span, I18n.t("statuses.visibilities.#{visibility}_long"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label + .fields-group = f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff| = ff.input :follow, as: :boolean, wrapper: :with_label diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index d8d3b8a6f..fc5ab5ec8 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -37,6 +37,7 @@ en: setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting setting_default_privacy: Post privacy + setting_default_sensitive: Always mark media as sensitive setting_delete_modal: Show confirmation dialog before deleting a toot setting_system_font_ui: Use system's default font severity: Severity diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb index e1ba56d97..a67487779 100644 --- a/spec/lib/user_settings_decorator_spec.rb +++ b/spec/lib/user_settings_decorator_spec.rb @@ -28,6 +28,13 @@ describe UserSettingsDecorator do expect(user.settings['default_privacy']).to eq 'public' end + it 'updates the user settings value for sensitive' do + values = { 'setting_default_sensitive' => '1' } + + settings.update(values) + expect(user.settings['default_sensitive']).to eq true + end + it 'updates the user settings value for boost modal' do values = { 'setting_boost_modal' => '1' } -- cgit From e6c81a635b99dcec4f8fded00d9451cb876df822 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 11 Jul 2017 17:25:49 +0200 Subject: Fix #2848 - Rake task to redownload avatars/headers (#4156) Can be filtered by a specific domain Resolves #2292 --- app/controllers/admin/accounts_controller.rb | 4 ++-- app/models/concerns/remotable.rb | 14 ++++++++++++-- lib/tasks/mastodon.rake | 22 +++++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) (limited to 'app/models') diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb index ef2f8c4c2..7bceee2cd 100644 --- a/app/controllers/admin/accounts_controller.rb +++ b/app/controllers/admin/accounts_controller.rb @@ -22,8 +22,8 @@ module Admin end def redownload - @account.avatar = @account.avatar_remote_url - @account.header = @account.header_remote_url + @account.reset_avatar! + @account.reset_header! @account.save! redirect_to admin_account_path(@account.id) diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 08d4fc59c..b4f169649 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -6,8 +6,9 @@ module Remotable included do attachment_definitions.each_key do |attachment_name| - attribute_name = "#{attachment_name}_remote_url".to_sym - method_name = "#{attribute_name}=".to_sym + attribute_name = "#{attachment_name}_remote_url".to_sym + method_name = "#{attribute_name}=".to_sym + alt_method_name = "reset_#{attachment_name}!".to_sym define_method method_name do |url| begin @@ -35,6 +36,15 @@ module Remotable nil end end + + define_method alt_method_name do + url = self[attribute_name] + + return if url.blank? + + self[attribute_name] = '' + send(method_name, url) + end end end end diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index bd70937e4..b2b352858 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -74,7 +74,7 @@ namespace :mastodon do end namespace :media do - desc 'Removes media attachments that have not been assigned to any status for longer than a day' + desc 'Removes media attachments that have not been assigned to any status for longer than a day (deprecated)' task clear: :environment do # No-op # This task is now executed via sidekiq-scheduler @@ -100,6 +100,18 @@ namespace :mastodon do MediaAttachment.where(file_file_name: nil).where.not(type: :unknown).in_batches.update_all(type: :unknown) Rails.logger.debug 'Done!' end + + desc 'Redownload avatars/headers of remote users. Optionally limit to a particular domain with DOMAIN' + task redownload_avatars: :environment do + accounts = Account.remote + accounts = accounts.where(domain: ENV['DOMAIN']) if ENV['DOMAIN'].present? + + accounts.find_each do |account| + account.reset_avatar! + account.reset_header! + account.save + end + end end namespace :push do @@ -111,7 +123,7 @@ namespace :mastodon do end end - desc 'Re-subscribes to soon expiring PuSH subscriptions' + desc 'Re-subscribes to soon expiring PuSH subscriptions (deprecated)' task refresh: :environment do # No-op # This task is now executed via sidekiq-scheduler @@ -119,13 +131,13 @@ namespace :mastodon do end namespace :feeds do - desc 'Clear timelines of inactive users' + desc 'Clear timelines of inactive users (deprecated)' task clear: :environment do # No-op # This task is now executed via sidekiq-scheduler end - desc 'Clears all timelines' + desc 'Clear all timelines without regenerating them' task clear_all: :environment do Redis.current.keys('feed:*').each { |key| Redis.current.del(key) } end @@ -151,7 +163,7 @@ namespace :mastodon do end end - desc 'List all admin users' + desc 'List e-mails of all admin users' task admins: :environment do puts 'Admin user emails:' puts User.admins.map(&:email).join("\n") -- cgit From 056b5ed72f6d980bceeb49eb249b8365fe8fce66 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 12 Jul 2017 03:24:04 +0200 Subject: Improve UI of admin site settings (#4163) --- app/controllers/admin/settings_controller.rb | 6 +- app/javascript/styles/forms.scss | 87 +++++++++++++++------ app/models/form/admin_settings.rb | 29 +++++++ app/views/admin/settings/edit.html.haml | 88 +++++++--------------- config/initializers/simple_form.rb | 4 +- config/locales/ca.yml | 2 - config/locales/de.yml | 2 - config/locales/en.yml | 40 +++++----- config/locales/fa.yml | 2 - config/locales/fr.yml | 2 - config/locales/he.yml | 2 - config/locales/id.yml | 2 - config/locales/io.yml | 2 - config/locales/ja.yml | 2 - config/locales/ko.yml | 2 - config/locales/nl.yml | 2 - config/locales/no.yml | 2 - config/locales/oc.yml | 2 - config/locales/pl.yml | 8 +- config/locales/pt-BR.yml | 2 - config/locales/pt.yml | 2 - config/locales/ru.yml | 2 - config/locales/th.yml | 2 - config/locales/tr.yml | 2 - config/locales/uk.yml | 2 - config/locales/zh-CN.yml | 2 - config/locales/zh-HK.yml | 2 - config/locales/zh-TW.yml | 2 - spec/controllers/admin/settings_controller_spec.rb | 8 +- 29 files changed, 151 insertions(+), 161 deletions(-) create mode 100644 app/models/form/admin_settings.rb (limited to 'app/models') diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 29b590d7a..5985d6282 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -22,7 +22,7 @@ module Admin ).freeze def edit - @settings = Setting.all_as_records + @admin_settings = Form::AdminSettings.new end def update @@ -38,12 +38,12 @@ module Admin private def settings_params - params.permit(ADMIN_SETTINGS) + params.require(:form_admin_settings).permit(ADMIN_SETTINGS) end def value_for_update(key, value) if BOOLEAN_SETTINGS.include?(key) - value == 'true' + value == '1' else value end diff --git a/app/javascript/styles/forms.scss b/app/javascript/styles/forms.scss index e723b50ff..e1de36d55 100644 --- a/app/javascript/styles/forms.scss +++ b/app/javascript/styles/forms.scss @@ -57,10 +57,7 @@ code { } } - .input.file, - .input.select, - .input.radio_buttons, - .input.check_boxes { + .input.with_label { padding: 15px 0; margin-bottom: 0; @@ -71,6 +68,44 @@ code { display: block; padding-top: 5px; } + + &.boolean { + padding: initial; + margin-bottom: initial; + + .label_input > label { + font-family: inherit; + font-size: 14px; + color: $primary-text-color; + display: block; + width: auto; + } + + label.checkbox { + position: relative; + padding-left: 25px; + flex: 1 1 auto; + } + } + } + + .input.with_block_label { + & > label { + font-family: inherit; + font-size: 16px; + color: $primary-text-color; + display: block; + padding-top: 5px; + } + + .hint { + margin-bottom: 15px; + } + + li { + float: left; + width: 50%; + } } .fields-group { @@ -106,7 +141,7 @@ code { input[type=checkbox] { position: absolute; left: 0; - top: 1px; + top: 5px; margin: 0; } @@ -116,6 +151,29 @@ code { } } + .check_boxes { + .checkbox { + label { + font-family: inherit; + font-size: 14px; + color: $primary-text-color; + display: block; + width: auto; + position: relative; + padding-top: 5px; + padding-left: 25px; + flex: 1 1 auto; + } + + input[type=checkbox] { + position: absolute; + left: 0; + top: 5px; + margin: 0; + } + } + } + input[type=text], input[type=number], input[type=email], @@ -390,25 +448,6 @@ code { } } -.user_filtered_languages { - & > label { - font-family: inherit; - font-size: 16px; - color: $primary-text-color; - display: block; - padding-top: 5px; - } - - .hint { - margin-bottom: 15px; - } - - li { - float: left; - width: 50%; - } -} - .post-follow-actions { text-align: center; color: $ui-primary-color; diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb new file mode 100644 index 000000000..c3a04ba65 --- /dev/null +++ b/app/models/form/admin_settings.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class Form::AdminSettings + include ActiveModel::Model + + delegate( + :site_contact_username, + :site_contact_username=, + :site_contact_email, + :site_contact_email=, + :site_title, + :site_title=, + :site_description, + :site_description=, + :site_extended_description, + :site_extended_description=, + :site_terms, + :site_terms=, + :open_registrations, + :open_registrations=, + :closed_registrations_message, + :closed_registrations_message=, + :open_deletion, + :open_deletion=, + :timeline_preview, + :timeline_preview=, + to: Setting + ) +end diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index 59192530b..9f8a6640b 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -1,64 +1,32 @@ - content_for :page_title do = t('admin.settings.title') -= form_tag(admin_settings_path, method: :put, class: 'simple_form', style: 'max-width: 100%') do - %table.table - %thead - %tr - %th{ width: '40%' } - = t('admin.settings.setting') - %th - %tbody - %tr - %td - %strong= t('admin.settings.contact_information.label') - %td= text_field_tag :site_contact_username, @settings['site_contact_username'].value, place_holder: t('admin.settings.contact_information.username') - %tr - %td - %strong= t('admin.accounts.email') - %td= text_field_tag :site_contact_email, @settings['site_contact_email'].value, place_holder: t('admin.settings.contact_information.email') - %tr - %td - %strong= t('admin.settings.site_title') - %td= text_field_tag :site_title, @settings['site_title'].value - %tr - %td - %strong= t('admin.settings.site_description.title') - %p= t('admin.settings.site_description.desc_html') - %td= text_area_tag :site_description, @settings['site_description'].value, rows: 8 - %tr - %td - %strong= t('admin.settings.site_description_extended.title') - %p= t('admin.settings.site_description_extended.desc_html') - %td= text_area_tag :site_extended_description, @settings['site_extended_description'].value, rows: 8 - %tr - %td - %strong= t('admin.settings.site_terms.title') - %p= t('admin.settings.site_terms.desc_html') - %td= text_area_tag :site_terms, @settings['site_terms'].value, rows: 8 - %tr - %td - %strong= t('admin.settings.registrations.open.title') - %p= t('admin.settings.registrations.open.desc_html') - %td - = select_tag :open_registrations, options_for_select({ t('simple_form.no') => false, t('simple_form.yes') => true }, @settings['open_registrations'].value) - %tr - %td - %strong= t('admin.settings.registrations.closed_message.title') - %p= t('admin.settings.registrations.closed_message.desc_html') - %td= text_area_tag :closed_registrations_message, @settings['closed_registrations_message'].value, rows: 8 - %tr - %td - %strong= t('admin.settings.registrations.deletion.title') - %p= t('admin.settings.registrations.deletion.desc_html') - %td - = select_tag :open_deletion, options_for_select({ t('simple_form.no') => false, t('simple_form.yes') => true }, @settings['open_deletion'].value) - %tr - %td - %strong= t('admin.settings.timeline_preview.title') - %p= t('admin.settings.timeline_preview.desc_html') - %td - = select_tag :timeline_preview, options_for_select({ t('simple_form.no') => false, t('simple_form.yes') => true }, @settings['timeline_preview'].value) += simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f| + .fields-group + = f.input :site_title, placeholder: t('admin.settings.site_title') + = f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 8 } + = f.input :site_contact_username, placeholder: t('admin.settings.contact_information.username') + = f.input :site_contact_email, placeholder: t('admin.settings.contact_information.email') - .simple_form.actions - = button_tag t('generic.save_changes'), type: :submit, class: :btn + %hr/ + + .fields-group + = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html') + + .fields-group + = f.input :open_registrations, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.open.title'), hint: t('admin.settings.registrations.open.desc_html') + + .fields-group + = f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html') + + .fields-group + = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 } + + %hr/ + + .fields-group + = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } + = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 } + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index ca7531748..5983918cd 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -50,14 +50,14 @@ SimpleForm.setup do |config| # b.use :full_error, wrap_with: { tag: :span, class: :error } end - config.wrappers :with_label, class: :input, hint_class: :field_with_hint, error_class: :field_with_errors do |b| + config.wrappers :with_label, class: [:input, :with_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b| b.use :html5 b.use :label_input, wrap_with: { tag: :div, class: :label_input } b.use :hint, wrap_with: { tag: :span, class: :hint } b.use :error, wrap_with: { tag: :span, class: :error } end - config.wrappers :with_block_label, class: :input, hint_class: :field_with_hint, error_class: :field_with_errors do |b| + config.wrappers :with_block_label, class: [:input, :with_block_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b| b.use :html5 b.use :label b.use :hint, wrap_with: { tag: :span, class: :hint } diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 10c34498b..f63aee3e6 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -155,7 +155,6 @@ ca: settings: contact_information: email: Introduir una adreça de correu electrònic pùblica - label: Informació de contacte username: Introduir un nom d'usuari registrations: closed_message: @@ -163,7 +162,6 @@ ca: title: Missatge de registre tancat open: title: Registre obert - setting: Ajust site_description: desc_html: Es mostra com un paràgraf a la pàgina principal i s'utilitza com una etiqueta meta.
Pots utilitzar etiquetes HTML, en particular <a> i <em>. title: Descripció del lloc diff --git a/config/locales/de.yml b/config/locales/de.yml index 2bdb87708..b084aca31 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -129,7 +129,6 @@ de: settings: contact_information: email: Eine öffentliche E-Mail-Adresse angeben - label: Kontaktinformationen username: Einen Benutzernamen angeben registrations: closed_message: @@ -137,7 +136,6 @@ de: title: Nachricht über geschlossene Registrierung open: title: Offene Registrierung - setting: Einstellung site_description: desc_html: Wird als Absatz auf der Frontseite angezeigt und als Meta-Tag benutzt.
Du kannst HTML-Tags benutzen, insbesondere <a> und <em>. title: Seitenbeschreibung diff --git a/config/locales/en.yml b/config/locales/en.yml index e33dde038..c9b5d9ab8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -168,33 +168,31 @@ en: view: View settings: contact_information: - email: Enter a public e-mail address - label: Contact information - username: Enter a username + email: Business e-mail + username: Contact username registrations: closed_message: - desc_html: Displayed on frontpage when registrations are closed
You can use HTML tags + desc_html: Displayed on frontpage when registrations are closed. You can use HTML tags title: Closed registration message + deletion: + desc_html: Allow anyone to delete their account + title: Open account deletion open: desc_html: Allow anyone to create an account title: Open registration - deletion: - desc_html: Allow anyone to delete their account - title: Open deletion - timeline_preview: - desc_html: Display public timeline on landing page - title: Timeline preview - setting: Setting site_description: - desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.
You can use HTML tags, in particular <a> and <em>. - title: Site description + desc_html: Introductory paragraph on the frontpage and in meta tags. You can use HTML tags, in particular <a> and <em>. + title: Instance description site_description_extended: - desc_html: Displayed on extended information page
You can use HTML tags - title: Extended site description + desc_html: A good place for your code of conduct, rules, guidelines and other things that set your instance apart. You can use HTML tags + title: Custom extended information site_terms: - desc_html: Displayed on terms page
You can use HTML tags - title: Privacy policy - site_title: Site title + desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags + title: Custom terms of service + site_title: Instance name + timeline_preview: + desc_html: Display public timeline on landing page + title: Timeline preview title: Site Settings subscriptions: callback_url: Callback URL @@ -230,12 +228,12 @@ en: authorize_follow: error: Unfortunately, there was an error looking up the remote account follow: Follow - following: 'Success! You are now following:' follow_request: 'You have sent a follow request to:' + following: 'Success! You are now following:' post_follow: - web: Go to web - return: Return to the user's profile close: Or, you can just close this window. + return: Return to the user's profile + web: Go to web prompt_html: 'You (%{self}) have requested to follow:' title: Follow %{acct} datetime: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 6f0bd0839..ade76d670 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -141,7 +141,6 @@ fa: settings: contact_information: email: یک نشانی ایمیل عمومی وارد کنید - label: اطلاعات تماس username: یک نام کاربری وارد کنید registrations: closed_message: @@ -149,7 +148,6 @@ fa: title: پیغام برای فعال‌نبودن ثبت نام open: title: امکان ثبت نام - setting: تنظیمات site_description: desc_html: روی صفحهٔ اصلی نمایش می‌یابد و همچنین به عنوان تگ‌های HTML.
می‌توانید HTML بنویسید, به‌ویژه <a> و <em>. title: دربارهٔ سایت diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 9eeafaa6e..c2efd0c85 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -155,7 +155,6 @@ fr: settings: contact_information: email: Entrez une adresse courriel publique - label: Informations de contact username: Entrez un nom d’utilisateur⋅ice registrations: closed_message: @@ -163,7 +162,6 @@ fr: title: Message de fermeture des inscriptions open: title: Inscriptions - setting: Paramètre site_description: desc_html: Affichée sous la forme d’un paragraphe sur la page d’accueil et utilisée comme balise meta.
Vous pouvez utiliser des balises HTML, en particulier <a> et <em>. title: Description du site diff --git a/config/locales/he.yml b/config/locales/he.yml index 760ddac00..21f8f1dc4 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -149,7 +149,6 @@ he: settings: contact_information: email: נא להקליד כתובת דוא"ל פומבית - label: פרטי התקשרות username: נא להכניס שם משתמש registrations: closed_message: @@ -157,7 +156,6 @@ he: title: מסר סגירת הרשמות open: title: הרשמה פתוחה - setting: הגדרה site_description: desc_html: מוצג כפסקה על הדף הראשי ומשמש כתגית מטא.
ניתן להשתמש בתגיות HTML, ובמיוחד ב־<a> ו־<em>. title: תיאור האתר diff --git a/config/locales/id.yml b/config/locales/id.yml index 4bcd8f2ed..e3fe96331 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -140,7 +140,6 @@ id: settings: contact_information: email: Masukkan alamat email - label: Informasi kontak username: Masukkan nama pengguna registrations: closed_message: @@ -148,7 +147,6 @@ id: title: Pesan penutupan pendaftaran open: title: Pendaftaran terbuka - setting: Pengaturan site_description: desc_html: Ditampilkan sebagai sebuah paragraf di halaman depan dan digunakan sebagai tag meta.
Anda bisa menggunakan tag HTML, khususnya <a> dan <em>. title: Deskripsi situs diff --git a/config/locales/io.yml b/config/locales/io.yml index 8eb48c303..b587d4bc6 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -128,7 +128,6 @@ io: settings: contact_information: email: Enter a public e-mail address - label: Contact information username: Enter a username registrations: closed_message: @@ -136,7 +135,6 @@ io: title: Closed registration message open: title: Open registration - setting: Setting site_description: desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.
You can use HTML tags, in particular <a> and <em>. title: Site description diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 5b91aa75d..d57fe8da2 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -155,7 +155,6 @@ ja: settings: contact_information: email: 公開するメールアドレスを入力 - label: 連絡先情報 username: ユーザー名を入力 registrations: closed_message: @@ -163,7 +162,6 @@ ja: title: 新規登録停止時のメッセージ open: title: 新規登録を受け付ける - setting: 設定 site_description: desc_html: トップページへの表示と meta タグに使用されます。
HTMLタグ、特に<a><em>が利用可能です。 title: サイトの説明文 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index c8ad38d41..bafc19993 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -155,7 +155,6 @@ ko: settings: contact_information: email: 공개할 메일 주소를 입력 - label: 연락처 정보 username: 아이디를 입력 registrations: closed_message: @@ -163,7 +162,6 @@ ko: title: 신규 등록 정지 시 메시지 open: title: 신규 등록을 받음 - setting: 설정 site_description: desc_html: 탑 페이지와 meta 태그에 사용됩니다.
HTML 태그, 예를 들어<a> 태그와 <em> 태그를 사용할 수 있습니다. title: 사이트 설명 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 633061b06..dfc58f6b3 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -55,7 +55,6 @@ nl: settings: contact_information: email: Vul een openbaar gebruikt e-mailadres in - label: Contactgegevens username: Vul een gebruikersnaam in registrations: closed_message: @@ -63,7 +62,6 @@ nl: title: Bericht wanneer registratie is uitgeschakeld open: title: Open registratie - setting: Instelling site_description: desc_html: Dit wordt als een alinea op de voorpagina getoond en gebruikt als meta-tag in de paginabron.
Je kan HTML gebruiken, zoals <a> en <em>. title: Omschrijving Mastodon-server diff --git a/config/locales/no.yml b/config/locales/no.yml index 05714959d..004e1ff80 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -142,7 +142,6 @@ settings: contact_information: email: Skriv en offentlig e-postadresse - label: Kontaktinformasjon username: Skriv brukernavn registrations: closed_message: @@ -150,7 +149,6 @@ title: Melding for lukket registrering open: title: Åpen registrering - setting: Innstilling site_description: desc_html: Vises som et avsnitt på forsiden og brukes som en meta-tagg.
Du kan bruke HTML-tagger, spesielt <a> og <em>. title: Nettstedsbeskrivelse diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 30d5258a5..91a6ca791 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -149,7 +149,6 @@ oc: settings: contact_information: email: Picatz una adreça de corrièl - label: Informacions de contacte username: Picatz un nom d’utilizaire registrations: closed_message: @@ -157,7 +156,6 @@ oc: title: Messatge de barradura de las inscripcions open: title: Inscripcions - setting: Paramètre site_description: desc_html: Afichada jos la forma de paragrafe sus la pagina d’acuèlh e utilizada coma balisa meta.
Podètz utilizar de balisas HTML, coma <a> et <em>. title: Descripcion del site diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 018ff3c7b..c6588e846 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -155,7 +155,6 @@ pl: settings: contact_information: email: Wprowadź publiczny adres e-mail - label: Informacje kontaktowe username: Wprowadź nazwę użytkownika registrations: closed_message: @@ -163,7 +162,6 @@ pl: title: Wiadomość o nieaktywnej rejestracji open: title: Otwarta rejestracja - setting: Ustawienie site_description: desc_html: Wyświetlany jako nagłówek na stronie głównej oraz jako meta tag.
Możesz korzystać z tagów HTML, w szczególności z <a> i <em>. title: Opis strony @@ -208,12 +206,12 @@ pl: authorize_follow: error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd follow: Śledź - following: 'Pomyślnie! Od teraz śledzisz:' follow_request: 'Wysłano prośbę o pozwolenie na obserwację:' + following: 'Pomyślnie! Od teraz śledzisz:' post_follow: - web: Przejdź do sieci - return: Powróć do strony użytkownika close: Ewentualnie, możesz po prostu zamknąć tą stronę. + return: Powróć do strony użytkownika + web: Przejdź do sieci prompt_html: 'Ty (%{self}) chcesz śledzić:' title: Śledź %{acct} datetime: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index fb5e03c8c..355c20d05 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -141,7 +141,6 @@ pt-BR: settings: contact_information: email: Entre um endereço de email público - label: Informação de contato username: Entre com usuário registrations: closed_message: @@ -149,7 +148,6 @@ pt-BR: title: Mensagem de registro fechados open: title: Aberto para registro - setting: Preferências site_description: desc_html: Mostrar como parágrafo e usado como meta tag.
Vôce pode usar tags HTML, em particular <a> e <em>. title: Descrição do site diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 0f59185a7..40be8a6c5 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -136,7 +136,6 @@ pt: settings: contact_information: email: Inserir um endereço de email para tornar público - label: Informação de contacto username: Insira um nome de utilizador registrations: closed_message: @@ -144,7 +143,6 @@ pt: title: Mensagem de registos encerrados open: title: Aceitar novos registos - setting: Preferências site_description: desc_html: Mostrar como parágrafo na página inicial e usado como meta tag.
Podes usar tags HTML, em particular <a> e <em>. title: Descrição do site diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 414d39dd2..5cfc2b1ca 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -123,7 +123,6 @@ ru: settings: contact_information: email: Введите публичный e-mail - label: Контактная информация username: Введите имя пользователя registrations: closed_message: @@ -131,7 +130,6 @@ ru: title: Сообщение о закрытой регистрации open: title: Открыть регистрацию - setting: Настройка site_description: desc_html: Отображается в качестве параграфа на титульной странице и используется в качестве мета-тега.
Можно использовать HTML-теги, в особенности <a> и <em>. title: Описание сайта diff --git a/config/locales/th.yml b/config/locales/th.yml index a71252afe..263babdd0 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -142,7 +142,6 @@ th: settings: contact_information: email: กรอกที่อยู่อีเมล์สาธารณะ - label: ข้อมูลที่ติดต่อ username: กรอกชื่อผู้ใช้ registrations: closed_message: @@ -150,7 +149,6 @@ th: title: ปิดข้อความลงทะเบียน open: title: เปิดรับลงทะเบียน - setting: ตั้งค่า site_description: desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.
ใช้ HTML tags ได้, in particular <a> และ <em>. title: คำอธิบายไซต์ diff --git a/config/locales/tr.yml b/config/locales/tr.yml index a8927eaa8..e7864cc57 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -141,7 +141,6 @@ tr: settings: contact_information: email: Herkese açık e-posta adresiniz - label: İletişim bilgisi username: Bir kullanıcı adı giriniz registrations: closed_message: @@ -149,7 +148,6 @@ tr: title: Kayıt alımları kapatılma mesajı open: title: Kayıt alımları - setting: Ayar adı site_description: desc_html: Ana sayfada paragraf olarak görüntülenecek bilgidir.
Özellikle <a> ve <em> olmak suretiyle HTML etiketlerini kullanabilirsiniz. title: Site açıklaması diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 65f1aabf5..129fc5bb7 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -123,7 +123,6 @@ uk: settings: contact_information: email: Введіть публічний email - label: Контактна інформація username: Введіть ім'я користувача registrations: closed_message: @@ -131,7 +130,6 @@ uk: title: Повідомлення про закриту реєстрацію open: title: Відкрити реєстрацію - setting: Налаштування site_description: desc_html: Відображається у якості параграфа на титульній сторінці та використовується у якості мета-тега.
Можна використовувати HTML-теги, особливо <a> і <em>. title: Опис сайту diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index d5d1b672c..650d4bd15 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -148,7 +148,6 @@ zh-CN: settings: contact_information: email: 输入一个公开的电邮地址 - label: 联系数据 username: 输入用户名称 registrations: closed_message: @@ -156,7 +155,6 @@ zh-CN: title: 暂停注册消息 open: title: 开放注册 - setting: 设置 site_description: desc_html: 在首页显示,及在 meta 标签中用作网站介绍。
你可以在此使用 HTML 标签,尤其是<a><em>。 title: 本站介绍 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index aa9f27912..d2db78be1 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -141,7 +141,6 @@ zh-HK: settings: contact_information: email: 輸入一個公開的電郵地址 - label: 聯絡資料 username: 輸入用戶名稱 registrations: closed_message: @@ -149,7 +148,6 @@ zh-HK: title: 暫停註冊訊息 open: title: 開放註冊 - setting: 設定 site_description: desc_html: 在首頁顯示,及在 meta 標籤使用作網站介紹。
你可以在此使用 <a><em> 等 HTML 標籤。 title: 本站介紹 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 58caf7848..67aa2830f 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -102,7 +102,6 @@ zh-TW: settings: contact_information: email: 請輸入輸入一個公開電子信箱 - label: 聯絡資訊 username: 請輸入使用者名稱 registrations: closed_message: @@ -110,7 +109,6 @@ zh-TW: title: 關閉註冊訊息 open: title: 開放註冊 - setting: 設定 site_description: desc_html: 顯示在首頁並且作為 meta 標籤的短文。
可使用 HTML 標籤,包括 <a><em>。 title: 網站描述 diff --git a/spec/controllers/admin/settings_controller_spec.rb b/spec/controllers/admin/settings_controller_spec.rb index d9dde3c92..609bc762b 100644 --- a/spec/controllers/admin/settings_controller_spec.rb +++ b/spec/controllers/admin/settings_controller_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Admin::SettingsController, type: :controller do it 'cannot create a setting value for a non-admin key' do expect(Setting.new_setting_key).to be_blank - patch :update, params: { new_setting_key: 'New key value' } + patch :update, params: { form_admin_settings: { new_setting_key: 'New key value' } } expect(response).to redirect_to(edit_admin_settings_path) expect(Setting.new_setting_key).to be_nil @@ -40,7 +40,7 @@ RSpec.describe Admin::SettingsController, type: :controller do it 'creates a settings value that didnt exist before for eligible key' do expect(Setting.site_extended_description).to be_blank - patch :update, params: { site_extended_description: 'New key value' } + patch :update, params: { form_admin_settings: { site_extended_description: 'New key value' } } expect(response).to redirect_to(edit_admin_settings_path) expect(Setting.site_extended_description).to eq 'New key value' @@ -56,7 +56,7 @@ RSpec.describe Admin::SettingsController, type: :controller do it 'updates a settings value' do Setting.site_title = 'Original' - patch :update, params: { site_title: 'New title' } + patch :update, params: { form_admin_settings: { site_title: 'New title' } } expect(response).to redirect_to(edit_admin_settings_path) expect(Setting.site_title).to eq 'New title' @@ -72,7 +72,7 @@ RSpec.describe Admin::SettingsController, type: :controller do it 'typecasts open_registrations to boolean' do Setting.open_registrations = false - patch :update, params: { open_registrations: 'true' } + patch :update, params: { form_admin_settings: { open_registrations: '1' } } expect(response).to redirect_to(edit_admin_settings_path) expect(Setting.open_registrations).to eq true -- cgit