From 38e39c9366d16ccb6536b4de5164e76684ff500b Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 12 Aug 2018 04:59:23 +0900 Subject: Weblate translations (2018-08-12) (#8171) * Translated using Weblate (Japanese) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * Translated using Weblate (Japanese) Currently translated at 98.5% (657 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Japanese) Currently translated at 98.5% (657 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Japanese) Currently translated at 99.8% (666 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Czech) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/cs/ * Translated using Weblate (Czech) Currently translated at 98.5% (657 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/cs/ * Translated using Weblate (Czech) Currently translated at 99.8% (666 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (2 of 2 strings) Translation: Mastodon/Activerecord Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/activerecord/cs/ * Translated using Weblate (Czech) Currently translated at 61.2% (38 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/cs/ * Translated using Weblate (Ukrainian) Currently translated at 51.2% (42 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/uk/ * Translated using Weblate (Czech) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/cs/ * Translated using Weblate (Galician) Currently translated at 99.8% (666 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (666 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Dutch) Currently translated at 100.0% (667 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Ukrainian) Currently translated at 99.6% (306 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/uk/ * Translated using Weblate (Czech) Currently translated at 67.0% (55 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/cs/ * Translated using Weblate (Ukrainian) Currently translated at 97.0% (647 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/uk/ * Translated using Weblate (Ukrainian) Currently translated at 97.1% (648 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/uk/ * Translated using Weblate (Czech) Currently translated at 100.0% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/cs/ * Translated using Weblate (Czech) Currently translated at 18.3% (18 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/cs/ * Translated using Weblate (Danish) Currently translated at 79.3% (529 of 667 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/da/ * Translated using Weblate (Czech) Currently translated at 61.2% (60 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/cs/ * Translated using Weblate (Occitan) Currently translated at 99.7% (667 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/oc/ * Translated using Weblate (German) Currently translated at 96.5% (646 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Japanese) Currently translated at 99.7% (667 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Czech) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/cs/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/ * Translated using Weblate (Corsican) Currently translated at 99.3% (305 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/co/ * Translated using Weblate (Corsican) Currently translated at 92.2% (617 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/co/ * Translated using Weblate (Telugu) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/te/ * Translated using Weblate (Arabic) Currently translated at 91.4% (75 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/ * Translated using Weblate (Arabic) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/ * Translated using Weblate (Arabic) Currently translated at 92.9% (622 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Danish) Currently translated at 92.8% (91 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/da/ * Translated using Weblate (Greek) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Danish) Currently translated at 82.0% (549 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/da/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Korean) Currently translated at 98.2% (657 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/ * Translated using Weblate (Korean) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/ * Translated using Weblate (German) Currently translated at 97.7% (654 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Corsican) Currently translated at 98.5% (659 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/co/ * Translated using Weblate (French) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Basque) Currently translated at 96.2% (644 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eu/ * Translated using Weblate (Basque) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/eu/ * Translated using Weblate (Basque) Currently translated at 90.2% (74 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eu/ * Translated using Weblate (Basque) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eu/ * Translated using Weblate (Czech) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (2 of 2 strings) Translation: Mastodon/Activerecord Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/activerecord/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/cs/ * Translated using Weblate (Czech) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/cs/ * Translated using Weblate (Asturian) Currently translated at 29.8% (200 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ast/ * Translated using Weblate (Greek) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Czech) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/cs/ * Translated using Weblate (German) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/de/ * Translated using Weblate (Greek) Currently translated at 100.0% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/el/ * Translated using Weblate (German) Currently translated at 96.3% (79 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (German) Currently translated at 99.7% (667 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (German) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/de/ * Translated using Weblate (German) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/de/ * Translated using Weblate (French) Currently translated at 100.0% (98 of 98 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fr/ * Translated using Weblate (German) Currently translated at 97.5% (80 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (French) Currently translated at 100.0% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/ * Translated using Weblate (French) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (German) Currently translated at 98.7% (81 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (German) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (German) Currently translated at 98.7% (81 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (German) Currently translated at 98.7% (82 of 82 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (French) Currently translated at 97.4% (652 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (German) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Japanese) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (German) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Dutch) Currently translated at 100.0% (669 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (German) Currently translated at 99.8% (668 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Danish) Currently translated at 85.0% (569 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/da/ * Translated using Weblate (Czech) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/cs/ * Translated using Weblate (Dutch) Currently translated at 100.0% (307 of 307 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (669 of 669 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * yarn manage:translations * i18n-tasks normalize && i18n-tasks remove-unused --- app/javascript/mastodon/locales/cs.json | 2 +- app/javascript/mastodon/locales/nl.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 6efb99381..e93baf750 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -252,7 +252,7 @@ "search_results.hashtags": "Hashtagy", "search_results.statuses": "Tooty", "search_results.total": "{count, number} {count, plural, one {výsledek} other {výsledků}}", - "standalone.public_title": "Nahlédnout dovnitř...", + "standalone.public_title": "Nahlédněte dovnitř...", "status.block": "Zablokovat uživatele @{name}", "status.cancel_reblog_private": "Zrušit boost", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 5c6d18e1d..c19598a21 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -139,7 +139,7 @@ "keyboard_shortcuts.hotkey": "Sneltoets", "keyboard_shortcuts.legend": "om deze legenda te tonen", "keyboard_shortcuts.mention": "om de auteur te vermelden", - "keyboard_shortcuts.profile": "to open author's profile", + "keyboard_shortcuts.profile": "om het gebruikersprofiel te openen", "keyboard_shortcuts.reply": "om te reageren", "keyboard_shortcuts.search": "om het zoekvak te focussen", "keyboard_shortcuts.toggle_hidden": "om tekst achter een waarschuwing (CW) te tonen/verbergen", -- cgit From 39e361a56d849a027ed12df69122a369bc6ff39d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 12 Aug 2018 18:16:26 +0200 Subject: Expect relays to answer with accept/reject (#8179) --- app/lib/activitypub/activity/accept.rb | 14 ++++++++++++++ app/lib/activitypub/activity/reject.rb | 14 ++++++++++++++ app/models/relay.rb | 12 ++++++++---- db/migrate/20180812123222_change_relays_enabled.rb | 19 +++++++++++++++++++ db/schema.rb | 5 ++--- 5 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20180812123222_change_relays_enabled.rb (limited to 'app') diff --git a/app/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb index bd90c9019..7e60b2c00 100644 --- a/app/lib/activitypub/activity/accept.rb +++ b/app/lib/activitypub/activity/accept.rb @@ -11,6 +11,8 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity private def accept_follow + return accept_follow_for_relay if relay_follow? + target_account = account_from_uri(target_uri) return if target_account.nil? || !target_account.local? @@ -19,6 +21,18 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity follow_request&.authorize! end + def accept_follow_for_relay + relay.update!(state: :accepted) + end + + def relay + @relay ||= Relay.find_by(follow_activity_id: object_uri) + end + + def relay_follow? + relay.present? + end + def target_uri @target_uri ||= value_or_id(@object['actor']) end diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb index 28d472883..d81b157de 100644 --- a/app/lib/activitypub/activity/reject.rb +++ b/app/lib/activitypub/activity/reject.rb @@ -11,6 +11,8 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity private def reject_follow + return reject_follow_for_relay if relay_follow? + target_account = account_from_uri(target_uri) return if target_account.nil? || !target_account.local? @@ -21,6 +23,18 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity UnfollowService.new.call(target_account, @account) if target_account.following?(@account) end + def reject_follow_for_relay + relay.update!(state: :rejected) + end + + def relay + @relay ||= Relay.find_by(follow_activity_id: object_uri) + end + + def relay_follow? + relay.present? + end + def target_uri @target_uri ||= value_or_id(@object['actor']) end diff --git a/app/models/relay.rb b/app/models/relay.rb index 76143bb27..75cb060b2 100644 --- a/app/models/relay.rb +++ b/app/models/relay.rb @@ -5,10 +5,10 @@ # # id :bigint(8) not null, primary key # inbox_url :string default(""), not null -# enabled :boolean default(FALSE), not null # follow_activity_id :string # created_at :datetime not null # updated_at :datetime not null +# state :integer default("idle"), not null # class Relay < ApplicationRecord @@ -16,24 +16,28 @@ class Relay < ApplicationRecord validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url? - scope :enabled, -> { where(enabled: true) } + enum state: [:idle, :pending, :accepted, :rejected] + + scope :enabled, -> { accepted } before_destroy :ensure_disabled + alias enabled? accepted? + def enable! activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) payload = Oj.dump(follow_activity(activity_id)) + update!(state: :pending, follow_activity_id: activity_id) ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) - update(enabled: true, follow_activity_id: activity_id) end def disable! activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) payload = Oj.dump(unfollow_activity(activity_id)) + update!(state: :idle, follow_activity_id: nil) ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) - update(enabled: false, follow_activity_id: nil) end private diff --git a/db/migrate/20180812123222_change_relays_enabled.rb b/db/migrate/20180812123222_change_relays_enabled.rb new file mode 100644 index 000000000..c4fd8179b --- /dev/null +++ b/db/migrate/20180812123222_change_relays_enabled.rb @@ -0,0 +1,19 @@ +class ChangeRelaysEnabled < ActiveRecord::Migration[5.2] + def up + # The relays table is supposed to be very small, + # single-digit number of rows, so this should be fine + safety_assured do + add_column :relays, :state, :integer, default: 0, null: false + + # At the time of this migration, no relays reject anyone, so if + # there are enabled ones, they are accepted + execute 'UPDATE relays SET state = 2 WHERE enabled = true' + remove_column :relays, :enabled + end + end + + def down + remove_column :relays, :state + add_column :relays, :enabled, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 46ee42714..edb5a023c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_08_08_175627) do +ActiveRecord::Schema.define(version: 2018_08_12_123222) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -383,11 +383,10 @@ ActiveRecord::Schema.define(version: 2018_08_08_175627) do create_table "relays", force: :cascade do |t| t.string "inbox_url", default: "", null: false - t.boolean "enabled", default: false, null: false t.string "follow_activity_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["enabled"], name: "index_relays_on_enabled" + t.integer "state", default: 0, null: false end create_table "report_notes", force: :cascade do |t| -- cgit From b7091c6c0fe057f7469a97f138c3e2451d95a28f Mon Sep 17 00:00:00 2001 From: Evgeny Petrov Date: Mon, 13 Aug 2018 00:11:40 +0300 Subject: Added endorse strings, fixed footer 'developers' string (#8183) --- app/javascript/mastodon/locales/ru.json | 4 ++-- config/locales/ru.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 0f2a26e76..0e8586903 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -7,7 +7,7 @@ "account.disclaimer_full": "Нижеуказанная информация может не полностью отражать профиль пользователя.", "account.domain_blocked": "Домен скрыт", "account.edit_profile": "Изменить профиль", - "account.endorse": "Feature on profile", + "account.endorse": "Рекомендовать в профиле", "account.follow": "Подписаться", "account.followers": "Подписаны", "account.follows": "Подписки", @@ -27,7 +27,7 @@ "account.show_reblogs": "Показывать продвижения от @{name}", "account.unblock": "Разблокировать", "account.unblock_domain": "Разблокировать {domain}", - "account.unendorse": "Don't feature on profile", + "account.unendorse": "Не рекомендовать в профиле", "account.unfollow": "Отписаться", "account.unmute": "Снять глушение", "account.unmute_notifications": "Показывать уведомления от @{name}", diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 9d5c3184b..44e41eaf6 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -544,7 +544,7 @@ ru: unlocked_warning_html: Кто угодно может подписаться на Вас и получить доступ к просмотру Ваших приватных статусов. %{lock_link}, чтобы получить возможность рассматривать и вручную подтверждать запросы о подписке. unlocked_warning_title: Ваш аккаунт не закрыт для подписки footer: - developers: Разработчики + developers: Разработчикам more: Ещё… resources: Ссылки generic: -- cgit From 8e111b753a3411b258cdb008c9a53bad696f4df1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 14 Aug 2018 19:19:32 +0200 Subject: Move status counters to separate table, count replies (#8104) * Move status counters to separate table, count replies * Migration to remove old counter columns from statuses table * Fix schema file --- app/models/favourite.rb | 13 +--- app/models/status.rb | 72 +++++++++++++++++----- app/models/status_stat.rb | 17 +++++ app/serializers/rest/status_serializer.rb | 3 +- db/migrate/20180812162710_create_status_stats.rb | 12 ++++ db/migrate/20180812173710_copy_status_stats.rb | 19 ++++++ .../20180813113448_copy_status_stats_cleanup.rb | 12 ++++ db/schema.rb | 15 ++++- spec/fabricators/status_stat_fabricator.rb | 6 ++ spec/models/status_stat_spec.rb | 5 ++ 10 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 app/models/status_stat.rb create mode 100644 db/migrate/20180812162710_create_status_stats.rb create mode 100644 db/migrate/20180812173710_copy_status_stats.rb create mode 100644 db/post_migrate/20180813113448_copy_status_stats_cleanup.rb create mode 100644 spec/fabricators/status_stat_fabricator.rb create mode 100644 spec/models/status_stat_spec.rb (limited to 'app') diff --git a/app/models/favourite.rb b/app/models/favourite.rb index 0fce82f6f..ce7a6a336 100644 --- a/app/models/favourite.rb +++ b/app/models/favourite.rb @@ -32,20 +32,11 @@ class Favourite < ApplicationRecord private def increment_cache_counters - if association(:status).loaded? - status.update_attribute(:favourites_count, status.favourites_count + 1) - else - Status.where(id: status_id).update_all('favourites_count = COALESCE(favourites_count, 0) + 1') - end + status.increment_count!(:favourites_count) end def decrement_cache_counters return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?) - - if association(:status).loaded? - status.update_attribute(:favourites_count, [status.favourites_count - 1, 0].max) - else - Status.where(id: status_id).update_all('favourites_count = GREATEST(COALESCE(favourites_count, 0) - 1, 0)') - end + status.decrement_count!(:favourites_count) end end diff --git a/app/models/status.rb b/app/models/status.rb index e7dd0df29..1c87f2566 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -15,8 +15,6 @@ # visibility :integer default("public"), not null # spoiler_text :text default(""), not null # reply :boolean default(FALSE), not null -# favourites_count :integer default(0), not null -# reblogs_count :integer default(0), not null # language :string # conversation_id :bigint(8) # local :boolean @@ -26,6 +24,8 @@ # class Status < ApplicationRecord + self.cache_versioning = false + include Paginable include Streamable include Cacheable @@ -59,6 +59,7 @@ class Status < ApplicationRecord has_one :notification, as: :activity, dependent: :destroy has_one :stream_entry, as: :activity, inverse_of: :status + has_one :status_stat, inverse_of: :status validates :uri, uniqueness: true, presence: true, unless: :local? validates :text, presence: true, unless: -> { with_media? || reblog? } @@ -81,7 +82,25 @@ class Status < ApplicationRecord scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) } scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) } - cache_associated :account, :application, :media_attachments, :conversation, :tags, :stream_entry, mentions: :account, reblog: [:account, :application, :stream_entry, :tags, :media_attachments, :conversation, mentions: :account], thread: :account + cache_associated :account, + :application, + :media_attachments, + :conversation, + :status_stat, + :tags, + :stream_entry, + mentions: :account, + reblog: [ + :account, + :application, + :stream_entry, + :tags, + :media_attachments, + :conversation, + :status_stat, + mentions: :account, + ], + thread: :account delegate :domain, to: :account, prefix: true @@ -175,6 +194,26 @@ class Status < ApplicationRecord @marked_for_mass_destruction end + def replies_count + status_stat&.replies_count || 0 + end + + def reblogs_count + status_stat&.reblogs_count || 0 + end + + def favourites_count + status_stat&.favourites_count || 0 + end + + def increment_count!(key) + update_status_stat!(key => public_send(key) + 1) + end + + def decrement_count!(key) + update_status_stat!(key => [public_send(key) - 1, 0].max) + end + after_create :increment_counter_caches after_destroy :decrement_counter_caches @@ -190,6 +229,10 @@ class Status < ApplicationRecord before_validation :set_local class << self + def cache_ids + left_outer_joins(:status_stat).select('statuses.id, greatest(statuses.updated_at, status_stats.updated_at) AS updated_at') + end + def in_chosen_languages(account) where(language: nil).or where(language: account.chosen_languages) end @@ -352,6 +395,11 @@ class Status < ApplicationRecord private + def update_status_stat!(attrs) + record = status_stat || build_status_stat + record.update(attrs) + end + def store_uri update_attribute(:uri, ActivityPub::TagManager.instance.uri_for(self)) if uri.nil? end @@ -408,13 +456,8 @@ class Status < ApplicationRecord Account.where(id: account_id).update_all('statuses_count = COALESCE(statuses_count, 0) + 1') end - return unless reblog? - - if association(:reblog).loaded? - reblog.update_attribute(:reblogs_count, reblog.reblogs_count + 1) - else - Status.where(id: reblog_of_id).update_all('reblogs_count = COALESCE(reblogs_count, 0) + 1') - end + thread.increment_count!(:replies_count) if in_reply_to_id.present? + reblog.increment_count!(:reblogs_count) if reblog? end def decrement_counter_caches @@ -426,12 +469,7 @@ class Status < ApplicationRecord Account.where(id: account_id).update_all('statuses_count = GREATEST(COALESCE(statuses_count, 0) - 1, 0)') end - return unless reblog? - - if association(:reblog).loaded? - reblog.update_attribute(:reblogs_count, [reblog.reblogs_count - 1, 0].max) - else - Status.where(id: reblog_of_id).update_all('reblogs_count = GREATEST(COALESCE(reblogs_count, 0) - 1, 0)') - end + thread.decrement_count!(:replies_count) if in_reply_to_id.present? + reblog.decrement_count!(:reblogs_count) if reblog? end end diff --git a/app/models/status_stat.rb b/app/models/status_stat.rb new file mode 100644 index 000000000..9d358776b --- /dev/null +++ b/app/models/status_stat.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# == Schema Information +# +# Table name: status_stats +# +# id :bigint(8) not null, primary key +# status_id :bigint(8) not null +# replies_count :bigint(8) default(0), not null +# reblogs_count :bigint(8) default(0), not null +# favourites_count :bigint(8) default(0), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class StatusStat < ApplicationRecord + belongs_to :status, inverse_of: :status_stat +end diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index fe3dc9bfc..61423f961 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -3,7 +3,8 @@ 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 + :uri, :content, :url, :replies_count, :reblogs_count, + :favourites_count attribute :favourited, if: :current_user? attribute :reblogged, if: :current_user? diff --git a/db/migrate/20180812162710_create_status_stats.rb b/db/migrate/20180812162710_create_status_stats.rb new file mode 100644 index 000000000..d4da36fe7 --- /dev/null +++ b/db/migrate/20180812162710_create_status_stats.rb @@ -0,0 +1,12 @@ +class CreateStatusStats < ActiveRecord::Migration[5.2] + def change + create_table :status_stats do |t| + t.belongs_to :status, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true } + t.bigint :replies_count, null: false, default: 0 + t.bigint :reblogs_count, null: false, default: 0 + t.bigint :favourites_count, null: false, default: 0 + + t.timestamps + end + end +end diff --git a/db/migrate/20180812173710_copy_status_stats.rb b/db/migrate/20180812173710_copy_status_stats.rb new file mode 100644 index 000000000..6ecccc0ae --- /dev/null +++ b/db/migrate/20180812173710_copy_status_stats.rb @@ -0,0 +1,19 @@ +class CopyStatusStats < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def up + safety_assured do + execute <<-SQL.squish + INSERT INTO status_stats (status_id, reblogs_count, favourites_count) + SELECT id, reblogs_count, favourites_count + FROM statuses + ON CONFLICT (status_id) DO UPDATE + SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count + SQL + end + end + + def down + # Nothing + end +end diff --git a/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb b/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb new file mode 100644 index 000000000..f3ae772c7 --- /dev/null +++ b/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class CopyStatusStatsCleanup < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def change + safety_assured do + remove_column :statuses, :reblogs_count, :integer, default: 0, null: false + remove_column :statuses, :favourites_count, :integer, default: 0, null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index edb5a023c..2cf7b849a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_08_12_123222) do +ActiveRecord::Schema.define(version: 2018_08_13_113448) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -456,6 +456,16 @@ ActiveRecord::Schema.define(version: 2018_08_12_123222) do t.index ["account_id", "status_id"], name: "index_status_pins_on_account_id_and_status_id", unique: true end + create_table "status_stats", force: :cascade do |t| + t.bigint "status_id", null: false + t.bigint "replies_count", default: 0, null: false + t.bigint "reblogs_count", default: 0, null: false + t.bigint "favourites_count", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true + end + create_table "statuses", id: :bigint, default: -> { "timestamp_id('statuses'::text)" }, force: :cascade do |t| t.string "uri" t.text "text", default: "", null: false @@ -468,8 +478,6 @@ ActiveRecord::Schema.define(version: 2018_08_12_123222) do t.integer "visibility", default: 0, null: false t.text "spoiler_text", default: "", null: false t.boolean "reply", default: false, null: false - t.integer "favourites_count", default: 0, null: false - t.integer "reblogs_count", default: 0, null: false t.string "language" t.bigint "conversation_id" t.boolean "local" @@ -630,6 +638,7 @@ ActiveRecord::Schema.define(version: 2018_08_12_123222) do add_foreign_key "session_activations", "users", name: "fk_e5fda67334", on_delete: :cascade add_foreign_key "status_pins", "accounts", name: "fk_d4cb435b62", on_delete: :cascade add_foreign_key "status_pins", "statuses", on_delete: :cascade + add_foreign_key "status_stats", "statuses", on_delete: :cascade add_foreign_key "statuses", "accounts", column: "in_reply_to_account_id", name: "fk_c7fa917661", on_delete: :nullify add_foreign_key "statuses", "accounts", name: "fk_9bda1543f7", on_delete: :cascade add_foreign_key "statuses", "statuses", column: "in_reply_to_id", on_delete: :nullify diff --git a/spec/fabricators/status_stat_fabricator.rb b/spec/fabricators/status_stat_fabricator.rb new file mode 100644 index 000000000..9c67fd404 --- /dev/null +++ b/spec/fabricators/status_stat_fabricator.rb @@ -0,0 +1,6 @@ +Fabricator(:status_stat) do + status_id nil + replies_count "" + reblogs_count "" + favourites_count "" +end diff --git a/spec/models/status_stat_spec.rb b/spec/models/status_stat_spec.rb new file mode 100644 index 000000000..5e9351aff --- /dev/null +++ b/spec/models/status_stat_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe StatusStat, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end -- cgit From ec2c516ab865ea63b5e7bc4405d0141d377e3e12 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 14 Aug 2018 21:51:17 +0200 Subject: Various fixes regarding the video position slider (#8201) * Prevent default event handling when clicking on the video position slider This prevents accidental text selection when clicking on the position slider. * Fix bug when clicking on video position slider before starting the video * Slightly more aggressive video preloading - Preload video metadata if the video is loaded in detailed view, as it is likely to get played, and metadata is useful for seeking in the video. - Preload video data if it's fullscreen as it is extremely likely to get played right after being put in fullscreen (although those are two steps). - Preload video data if the user has clicked the position slider, as the video will play as soon as the mouse button is released, and video metadata is needed to properly seek into the video. --- app/javascript/mastodon/features/video/index.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js index 47a165e16..55ea32acb 100644 --- a/app/javascript/mastodon/features/video/index.js +++ b/app/javascript/mastodon/features/video/index.js @@ -158,6 +158,9 @@ export default class Video extends React.PureComponent { this.setState({ dragging: true }); this.video.pause(); this.handleMouseMove(e); + + e.preventDefault(); + e.stopPropagation(); } handleMouseUp = () => { @@ -174,8 +177,10 @@ export default class Video extends React.PureComponent { const { x } = getPointerPosition(this.seek, e); const currentTime = Math.floor(this.video.duration * x); - this.video.currentTime = currentTime; - this.setState({ currentTime }); + if (!isNaN(currentTime)) { + this.video.currentTime = currentTime; + this.setState({ currentTime }); + } }, 60); togglePlay = () => { @@ -281,6 +286,15 @@ export default class Video extends React.PureComponent { playerStyle.height = height; } + let preload; + if (startTime || fullscreen || dragging) { + preload = 'auto'; + } else if (detailed) { + preload = 'metadata'; + } else { + preload = 'none'; + } + return (
Date: Tue, 14 Aug 2018 21:56:17 +0200 Subject: Show exact number of followers/statuses on export page/in tooltip (#8199) * Show exact number of followers/statuses on export page/in tooltip * Fix tests --- .../mastodon/features/account/components/action_bar.js | 6 +++--- app/models/export.rb | 10 +++++++++- app/views/accounts/_header.html.haml | 6 +++--- app/views/settings/exports/show.html.haml | 14 +++++++++++--- app/views/settings/imports/show.html.haml | 11 +++++++---- spec/models/export_spec.rb | 6 +++--- 6 files changed, 36 insertions(+), 17 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js index 43b4811e1..bc6f86628 100644 --- a/app/javascript/mastodon/features/account/components/action_bar.js +++ b/app/javascript/mastodon/features/account/components/action_bar.js @@ -147,17 +147,17 @@ export default class ActionBar extends React.PureComponent {
- + {shortNumberFormat(account.get('statuses_count'))} - + {shortNumberFormat(account.get('following_count'))} - + {shortNumberFormat(account.get('followers_count'))} diff --git a/app/models/export.rb b/app/models/export.rb index f0d5dd255..0eeac0dc0 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -24,8 +24,16 @@ class Export account.media_attachments.sum(:file_file_size) end + def total_statuses + account.statuses_count + end + def total_follows - account.following.count + account.following_count + end + + def total_followers + account.followers_count end def total_blocks diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index d3b9893c4..caf03bd7c 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -14,17 +14,17 @@ .public-account-header__tabs__tabs .details-counters .counter{ class: active_nav_class(short_account_url(account)) } - = link_to short_account_url(account), class: 'u-url u-uid' do + = link_to short_account_url(account), class: 'u-url u-uid', title: number_with_delimiter(account.statuses_count) do %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true %span.counter-label= t('accounts.posts') .counter{ class: active_nav_class(account_following_index_url(account)) } - = link_to account_following_index_url(account) do + = link_to account_following_index_url(account), title: number_with_delimiter(account.following_count) do %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true %span.counter-label= t('accounts.following') .counter{ class: active_nav_class(account_followers_url(account)) } - = link_to account_followers_url(account) do + = link_to account_followers_url(account), title: number_with_delimiter(account.followers_count) do %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true %span.counter-label= t('accounts.followers') .spacer diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index 30cd26914..ef2d2b894 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -8,17 +8,25 @@ %th= t('exports.storage') %td= number_to_human_size @export.total_storage %td + %tr + %th= t('accounts.statuses') + %td= number_with_delimiter @export.total_statuses + %td %tr %th= t('exports.follows') - %td= number_to_human @export.total_follows + %td= number_with_delimiter @export.total_follows %td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv) + %tr + %th= t('accounts.followers') + %td= number_with_delimiter @export.total_followers + %td %tr %th= t('exports.blocks') - %td= number_to_human @export.total_blocks + %td= number_with_delimiter @export.total_blocks %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv) %tr %th= t('exports.mutes') - %td= number_to_human @export.total_mutes + %td= number_with_delimiter @export.total_mutes %td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv) %p.muted-hint= t('exports.archive_takeout.hint_html') diff --git a/app/views/settings/imports/show.html.haml b/app/views/settings/imports/show.html.haml index 991dd4e94..2b43cb134 100644 --- a/app/views/settings/imports/show.html.haml +++ b/app/views/settings/imports/show.html.haml @@ -1,11 +1,14 @@ - content_for :page_title do = t('settings.import') -%p.hint= t('imports.preface') - = simple_form_for @import, url: settings_import_path do |f| - = f.input :type, collection: Import.types.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' - = f.input :data, wrapper: :with_label, hint: t('simple_form.hints.imports.data') + %p.hint= t('imports.preface') + + .field-group + = f.input :type, collection: Import.types.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + + .field-group + = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data') .actions = f.button :button, t('imports.upload'), type: :submit diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb index 6daa46145..277dcc526 100644 --- a/spec/models/export_spec.rb +++ b/spec/models/export_spec.rb @@ -48,17 +48,17 @@ describe Export do describe 'total_follows' do it 'returns the total number of the followed accounts' do target_accounts.each(&account.method(:follow!)) - expect(Export.new(account).total_follows).to eq 2 + expect(Export.new(account.reload).total_follows).to eq 2 end it 'returns the total number of the blocked accounts' do target_accounts.each(&account.method(:block!)) - expect(Export.new(account).total_blocks).to eq 2 + expect(Export.new(account.reload).total_blocks).to eq 2 end it 'returns the total number of the muted accounts' do target_accounts.each(&account.method(:mute!)) - expect(Export.new(account).total_mutes).to eq 2 + expect(Export.new(account.reload).total_mutes).to eq 2 end end end -- cgit From 4df9cabb22cbed8f9cd8af45325ecdcc7c72d6cb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 15 Aug 2018 19:29:52 +0200 Subject: Display replies count in web UI (#8181) --- .../mastodon/components/status_action_bar.js | 12 +++++++++++- app/javascript/styles/mastodon/components.scss | 20 ++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 0ae21e3f0..c799d4e98 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -32,6 +32,16 @@ const messages = defineMessages({ embed: { id: 'status.embed', defaultMessage: 'Embed' }, }); +const obfuscatedCount = count => { + if (count < 0) { + return 0; + } else if (count <= 1) { + return count; + } else { + return '1+'; + } +}; + @injectIntl export default class StatusActionBar extends ImmutablePureComponent { @@ -194,7 +204,7 @@ export default class StatusActionBar extends ImmutablePureComponent { return (
- +
{obfuscatedCount(status.get('replies_count'))}
{shareButton} diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 708a6868a..931f1aa0d 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -921,15 +921,31 @@ align-items: center; display: flex; margin-top: 8px; + + &__counter { + display: inline-flex; + margin-right: 11px; + align-items: center; + + .status__action-bar-button { + margin-right: 4px; + } + + &__label { + display: inline-block; + width: 14px; + font-size: 12px; + font-weight: 500; + color: $action-button-color; + } + } } .status__action-bar-button { - float: left; margin-right: 18px; } .status__action-bar-dropdown { - float: left; height: 23.15px; width: 23.15px; } -- cgit From af912fb308cffe98f52e155484c4c6b0a62efceb Mon Sep 17 00:00:00 2001 From: ThibG Date: Wed, 15 Aug 2018 19:33:36 +0200 Subject: Allow accessing local private/DM messages by URL (#8196) * Allow accessing local private/DM messages by URL (Provided the user pasting the URL is authorized to see the toot, obviously) * Fix SearchServiceSpec tests --- app/services/resolve_url_service.rb | 10 ++++++++-- app/services/search_service.rb | 2 +- spec/services/search_service_spec.rb | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb index a068c1ed8..1db1917e2 100644 --- a/app/services/resolve_url_service.rb +++ b/app/services/resolve_url_service.rb @@ -2,11 +2,13 @@ class ResolveURLService < BaseService include JsonLdHelper + include Authorization attr_reader :url - def call(url) + def call(url, on_behalf_of: nil) @url = url + @on_behalf_of = on_behalf_of return process_local_url if local_url? @@ -84,6 +86,10 @@ class ResolveURLService < BaseService def check_local_status(status) return if status.nil? - status if status.public_visibility? || status.unlisted_visibility? + authorize_with @on_behalf_of, status, :show? + status + rescue Mastodon::NotPermittedError + # Do not disclose the existence of status the user is not authorized to see + nil end end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 5bb395942..cc1fcb52f 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -53,7 +53,7 @@ class SearchService < BaseService end def url_resource - @_url_resource ||= ResolveURLService.new.call(query) + @_url_resource ||= ResolveURLService.new.call(query, on_behalf_of: @account) end def url_resource_symbol diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index 673de5233..671080f1d 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -29,7 +29,7 @@ describe SearchService, type: :service do allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, 10) - expect(service).to have_received(:call).with(@query) + expect(service).to have_received(:call).with(@query, on_behalf_of: nil) expect(results).to eq empty_results end end @@ -41,7 +41,7 @@ describe SearchService, type: :service do allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, 10) - expect(service).to have_received(:call).with(@query) + expect(service).to have_received(:call).with(@query, on_behalf_of: nil) expect(results).to eq empty_results.merge(accounts: [account]) end end @@ -53,7 +53,7 @@ describe SearchService, type: :service do allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, 10) - expect(service).to have_received(:call).with(@query) + expect(service).to have_received(:call).with(@query, on_behalf_of: nil) expect(results).to eq empty_results.merge(statuses: [status]) end end -- cgit From 625b5a567bb94a557572176357cd2381ac17a06d Mon Sep 17 00:00:00 2001 From: ThibG Date: Wed, 15 Aug 2018 19:38:56 +0200 Subject: Get rid of the Content Warning rainbows (#8129) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Disable the animated rainbow text when the “Reduce motion” setting is set * Get rid of the Content Warning rainbows * Revert to default color for CWs in admin view Since that colorscheme is apparently broken for some colorblind people. * Use HTML5's details and summary for statuses with CWs in admin interface --- app/javascript/styles/mastodon/tables.scss | 16 ++++------------ app/views/admin/reports/_status.html.haml | 12 +++++++----- 2 files changed, 11 insertions(+), 17 deletions(-) (limited to 'app') diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index e54c55947..c2206cf55 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -1,9 +1,3 @@ -@keyframes Swag { - 0% { background-position: 0% 0%; } - 50% { background-position: 100% 0%; } - 100% { background-position: 200% 0%; } -} - .table { width: 100%; max-width: 100%; @@ -191,14 +185,12 @@ a.table-action-link { .status__content { padding-top: 0; + summary { + display: list-item; + } + strong { font-weight: 700; - background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet,orange , yellow, green, cyan, blue, violet); - background-size: 200% 100%; - -webkit-background-clip: text; - background-clip: text; - color: transparent; - animation: Swag 2s linear 0s infinite; } } } diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 5e174f312..5b410ec84 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -3,11 +3,13 @@ = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id .batch-table__row__content .status__content>< - - unless status.proper.spoiler_text.blank? - %p>< - %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)} - - = Formatter.instance.format(status.proper, custom_emojify: true) + - if status.proper.spoiler_text.blank? + = Formatter.instance.format(status.proper, custom_emojify: true) + - else + %details< + %summary>< + %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)} + = Formatter.instance.format(status.proper, custom_emojify: true) - unless status.proper.media_attachments.empty? - if status.proper.media_attachments.first.video? -- cgit From be0b372a22347fcad9d4e4e4199e9f59caa5f901 Mon Sep 17 00:00:00 2001 From: ThibG Date: Wed, 15 Aug 2018 23:38:31 +0200 Subject: Fix admin.js starting rails-ujs twice (fixes #8168) (#8213) --- app/javascript/packs/admin.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'app') diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js index b151b4af0..5dbcc03d3 100644 --- a/app/javascript/packs/admin.js +++ b/app/javascript/packs/admin.js @@ -1,7 +1,4 @@ import { delegate } from 'rails-ujs'; -import { start } from '../mastodon/common'; - -start(); function handleDeleteStatus(event) { const [data] = event.detail; -- cgit From d78474264da0bd51e021c5f04311515e10ac828e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 16 Aug 2018 14:21:52 +0200 Subject: Update reply counters only if the reply is public/unlisted (#8211) --- app/models/status.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/status.rb b/app/models/status.rb index 1c87f2566..2eed33659 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -456,8 +456,8 @@ class Status < ApplicationRecord Account.where(id: account_id).update_all('statuses_count = COALESCE(statuses_count, 0) + 1') end - thread.increment_count!(:replies_count) if in_reply_to_id.present? reblog.increment_count!(:reblogs_count) if reblog? + thread.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?) end def decrement_counter_caches @@ -469,7 +469,7 @@ class Status < ApplicationRecord Account.where(id: account_id).update_all('statuses_count = GREATEST(COALESCE(statuses_count, 0) - 1, 0)') end - thread.decrement_count!(:replies_count) if in_reply_to_id.present? reblog.decrement_count!(:reblogs_count) if reblog? + thread.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?) end end -- cgit From c98681c358c1f32f044992d2fe97f2e7843c83d1 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 16 Aug 2018 20:02:52 +0200 Subject: Do not error out when performing admin actions on no statuses (#8220) Fixes the other issue with #8168 --- app/controllers/admin/statuses_controller.rb | 4 ++++ config/locales/en.yml | 1 + 2 files changed, 5 insertions(+) (limited to 'app') diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb index 382bfc4a2..a69f12084 100644 --- a/app/controllers/admin/statuses_controller.rb +++ b/app/controllers/admin/statuses_controller.rb @@ -28,6 +28,10 @@ module Admin @form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button)) flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save + redirect_to admin_account_statuses_path(@account.id, current_params) + rescue ActionController::ParameterMissing + flash[:alert] = I18n.t('admin.statuses.no_status_selected') + redirect_to admin_account_statuses_path(@account.id, current_params) end diff --git a/config/locales/en.yml b/config/locales/en.yml index a5e4ab75d..9c2800433 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -401,6 +401,7 @@ en: media: title: Media no_media: No media + no_status_selected: No statuses were changed as none were selected title: Account statuses with_media: With media subscriptions: -- cgit From 106fa28a00ae9b336c05a25b800b9897bd61820d Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 16 Aug 2018 20:05:26 +0200 Subject: Prevent actions log from crashing when displaying deleted status (fixes #8133) (#8219) --- app/helpers/admin/action_logs_helper.rb | 6 +++++- config/locales/en.yml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index 4c663211e..85bd30304 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -34,7 +34,11 @@ module Admin::ActionLogsHelper link_to attributes['domain'], "https://#{attributes['domain']}" when 'Status' tmp_status = Status.new(attributes) - link_to tmp_status.account&.acct || "##{tmp_status.account_id}", TagManager.instance.url_for(tmp_status) + if tmp_status.account + link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id) + else + I18n.t('admin.action_logs.deleted_status') + end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9c2800433..cc24a02cf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -184,6 +184,7 @@ en: unsuspend_account: "%{name} unsuspended %{target}'s account" update_custom_emoji: "%{name} updated emoji %{target}" update_status: "%{name} updated status by %{target}" + deleted_status: "(deleted status)" title: Audit log custom_emojis: by_domain: Domain -- cgit From 4601a58ac24f2c97ba4934445da694ca18308b81 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 17 Aug 2018 14:07:38 +0200 Subject: Defer scrollIntoView after DOM is drawn (fixes #8239) (#8242) --- app/javascript/mastodon/features/status/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 89387ca43..0ffeaa4dc 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -355,7 +355,9 @@ export default class Status extends ImmutablePureComponent { if (status && ancestorsIds && ancestorsIds.size > 0) { const element = this.node.querySelectorAll('.focusable')[ancestorsIds.size - 1]; - element.scrollIntoView(true); + window.requestAnimationFrame(() => { + element.scrollIntoView(true); + }); this._scrolledIntoView = true; } } -- cgit From 1ee675d68bfd2034183a03408a2377c338dfac41 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 17 Aug 2018 14:08:17 +0200 Subject: Use correct activity id in Accept when receiving duplicate Follow (fixes #8218) (#8244) --- app/lib/activitypub/activity/follow.rb | 2 +- app/services/authorize_follow_service.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb index 826dcf18e..c45832648 100644 --- a/app/lib/activitypub/activity/follow.rb +++ b/app/lib/activitypub/activity/follow.rb @@ -13,7 +13,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity # Fast-forward repeat follow requests if @account.following?(target_account) - AuthorizeFollowService.new.call(@account, target_account, skip_follow_request: true) + AuthorizeFollowService.new.call(@account, target_account, skip_follow_request: true, follow_request_uri: @json['id']) return end diff --git a/app/services/authorize_follow_service.rb b/app/services/authorize_follow_service.rb index f47d488f1..1674239df 100644 --- a/app/services/authorize_follow_service.rb +++ b/app/services/authorize_follow_service.rb @@ -3,7 +3,7 @@ class AuthorizeFollowService < BaseService def call(source_account, target_account, **options) if options[:skip_follow_request] - follow_request = FollowRequest.new(account: source_account, target_account: target_account) + follow_request = FollowRequest.new(account: source_account, target_account: target_account, uri: options[:follow_request_uri]) else follow_request = FollowRequest.find_by!(account: source_account, target_account: target_account) follow_request.authorize! -- cgit From 59f7f4c923494bb8dd6f2881a1610c7b51240d9c Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 17 Aug 2018 16:24:56 +0200 Subject: Implement Undo { Accept { Follow } } (fixes #8234) (#8245) * Add Follow#revoke_request! * Implement Undo { Accept { Follow } } (fixes #8234) --- app/lib/activitypub/activity/undo.rb | 6 ++++++ app/models/follow.rb | 5 +++++ spec/lib/activitypub/activity/undo_spec.rb | 26 ++++++++++++++++++++++++++ spec/models/follow_spec.rb | 16 ++++++++++++++++ 4 files changed, 53 insertions(+) (limited to 'app') diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb index cbed417c4..64c2be7d9 100644 --- a/app/lib/activitypub/activity/undo.rb +++ b/app/lib/activitypub/activity/undo.rb @@ -5,6 +5,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity case @object['type'] when 'Announce' undo_announce + when 'Accept' + undo_accept when 'Follow' undo_follow when 'Like' @@ -27,6 +29,10 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity end end + def undo_accept + ::Follow.find_by(target_account: @account, uri: target_uri)&.revoke_request! + end + def undo_follow target_account = account_from_uri(target_uri) diff --git a/app/models/follow.rb b/app/models/follow.rb index 3fce14b9a..714f4e898 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -32,6 +32,11 @@ class Follow < ApplicationRecord false # Force uri_for to use uri attribute end + def revoke_request! + FollowRequest.create!(account: account, target_account: target_account, show_reblogs: show_reblogs, uri: uri) + destroy! + end + before_validation :set_uri, only: :create after_destroy :remove_endorsements diff --git a/spec/lib/activitypub/activity/undo_spec.rb b/spec/lib/activitypub/activity/undo_spec.rb index e01c5e03e..9545e1f46 100644 --- a/spec/lib/activitypub/activity/undo_spec.rb +++ b/spec/lib/activitypub/activity/undo_spec.rb @@ -52,6 +52,32 @@ RSpec.describe ActivityPub::Activity::Undo do end end + context 'with Accept' do + let(:recipient) { Fabricate(:account) } + let(:object_json) do + { + id: 'bar', + type: 'Accept', + actor: ActivityPub::TagManager.instance.uri_for(sender), + object: 'follow-to-revoke', + } + end + + before do + recipient.follow!(sender, uri: 'follow-to-revoke') + end + + it 'deletes follow from recipient to sender' do + subject.perform + expect(recipient.following?(sender)).to be false + end + + it 'creates a follow request from recipient to sender' do + subject.perform + expect(recipient.requested?(sender)).to be true + end + end + context 'with Block' do let(:recipient) { Fabricate(:account) } diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index 43175d852..f221973b6 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -37,4 +37,20 @@ RSpec.describe Follow, type: :model do expect(a[1]).to eq follow0 end end + + describe 'revoke_request!' do + let(:follow) { Fabricate(:follow, account: account, target_account: target_account) } + let(:account) { Fabricate(:account) } + let(:target_account) { Fabricate(:account) } + + it 'revokes the follow relation' do + follow.revoke_request! + expect(account.following?(target_account)).to be false + end + + it 'creates a follow request' do + follow.revoke_request! + expect(account.requested?(target_account)).to be true + end + end end -- cgit