From e11796432514afb49f3d891f805973a37f00fcf1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 26 Mar 2019 01:24:19 +0100 Subject: Change icons of features on admin dashboard to remove bias (#10366) Red crosses implied that it was bad/unexpected that certain features were not enabled. In reality, they are options, so showing a green or grey power-off icon is more appropriate. Add status of timeline preview as well Fix sample accounts changing too frequently due to wrong query Sample accounts are intended to be sorted by popularity --- app/helpers/admin/dashboard_helper.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 app/helpers/admin/dashboard_helper.rb (limited to 'app/helpers') diff --git a/app/helpers/admin/dashboard_helper.rb b/app/helpers/admin/dashboard_helper.rb new file mode 100644 index 000000000..4ee2cdef4 --- /dev/null +++ b/app/helpers/admin/dashboard_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Admin::DashboardHelper + def feature_hint(feature, enabled) + indicator = safe_join([enabled ? t('simple_form.yes') : t('simple_form.no'), fa_icon('power-off fw')], ' ') + class_names = enabled ? 'pull-right positive-hint' : 'pull-right neutral-hint' + + safe_join([feature, content_tag(:span, indicator, class: class_names)]) + end +end -- cgit From 08ec7435ce10fc74c257e089d6a2e909287e3daa Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 28 Mar 2019 02:16:01 +0100 Subject: Add order options to relationship manager UI (#10404) --- app/controllers/relationships_controller.rb | 9 +++++---- app/helpers/admin/filter_helper.rb | 2 +- app/views/relationships/show.html.haml | 7 +++++++ config/locales/en.yml | 2 ++ 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'app/helpers') diff --git a/app/controllers/relationships_controller.rb b/app/controllers/relationships_controller.rb index 84cb178a6..e6705c327 100644 --- a/app/controllers/relationships_controller.rb +++ b/app/controllers/relationships_controller.rb @@ -31,13 +31,14 @@ class RelationshipsController < ApplicationController def relationships_scope scope = begin if following_relationship? - current_account.following.joins(:account_stat) + current_account.following.eager_load(:account_stat).reorder(nil) else - current_account.followers.joins(:account_stat) + current_account.followers.eager_load(:account_stat).reorder(nil) end end - scope.merge!(Follow.recent) + scope.merge!(Follow.recent) if params[:order].blank? || params[:order] == 'recent' + scope.merge!(Account.by_recent_status) if params[:order] == 'active' scope.merge!(mutual_relationship_scope) if mutual_relationship? scope.merge!(moved_account_scope) if params[:status] == 'moved' scope.merge!(primary_account_scope) if params[:status] == 'primary' @@ -84,7 +85,7 @@ class RelationshipsController < ApplicationController end def current_params - params.slice(:page, :status, :relationship, :by_domain, :activity).permit(:page, :status, :relationship, :by_domain, :activity) + params.slice(:page, :status, :relationship, :by_domain, :activity, :order).permit(:page, :status, :relationship, :by_domain, :activity, :order) end def action_from_button diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb index 4fd36ef42..0bda25974 100644 --- a/app/helpers/admin/filter_helper.rb +++ b/app/helpers/admin/filter_helper.rb @@ -7,7 +7,7 @@ module Admin::FilterHelper CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze TAGS_FILTERS = %i(hidden).freeze INSTANCES_FILTERS = %i(limited by_domain).freeze - FOLLOWERS_FILTERS = %i(relationship status by_domain activity).freeze + FOLLOWERS_FILTERS = %i(relationship status by_domain activity order).freeze FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS + INSTANCES_FILTERS + FOLLOWERS_FILTERS diff --git a/app/views/relationships/show.html.haml b/app/views/relationships/show.html.haml index 63745119a..e6fff0ad6 100644 --- a/app/views/relationships/show.html.haml +++ b/app/views/relationships/show.html.haml @@ -25,11 +25,18 @@ %li= filter_link_to t('generic.all'), activity: nil %li= filter_link_to t('relationships.dormant'), activity: 'dormant' + .filter-subset + %strong= t 'generic.order_by' + %ul + %li= filter_link_to t('relationships.most_recent'), order: nil + %li= filter_link_to t('relationships.last_active'), order: 'active' + = form_for(@form, url: relationships_path, method: :patch) do |f| = hidden_field_tag :page, params[:page] || 1 = hidden_field_tag :relationship, params[:relationship] = hidden_field_tag :status, params[:status] = hidden_field_tag :activity, params[:activity] + = hidden_field_tag :order, params[:order] .batch-table .batch-table__toolbar diff --git a/config/locales/en.yml b/config/locales/en.yml index 42ba4e35e..d91e89d95 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -774,6 +774,8 @@ en: relationships: activity: Account activity dormant: Dormant + last_active: Last active + most_recent: Most recent moved: Moved mutual: Mutual primary: Primary -- cgit From f1bc90ab508cbdebc646324f87db48a9e80036f4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 28 Mar 2019 04:44:59 +0100 Subject: Rename :poll to :preloadable_poll and :owned_poll to :poll on Status (#10401) Also, fix some n+1 queries Resolve #10365 --- app/helpers/stream_entries_helper.rb | 4 ++-- app/lib/activitypub/activity/create.rb | 10 +++++----- app/lib/activitypub/activity/update.rb | 4 ++-- app/lib/formatter.rb | 4 ++-- app/models/notification.rb | 2 +- app/models/status.rb | 19 ++++++++++--------- app/serializers/activitypub/note_serializer.rb | 14 +++++++------- app/serializers/activitypub/update_poll_serializer.rb | 2 +- app/serializers/rest/status_serializer.rb | 2 +- app/services/post_status_service.rb | 2 +- app/views/stream_entries/_detailed_status.html.haml | 6 +++--- app/views/stream_entries/_simple_status.html.haml | 6 +++--- .../activitypub/distribute_poll_update_worker.rb | 4 ++-- config/locales/activerecord.en.yml | 5 +++-- spec/lib/activitypub/activity/create_spec.rb | 4 ++-- 15 files changed, 45 insertions(+), 43 deletions(-) (limited to 'app/helpers') diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index 8392afa73..4734e32a4 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -105,8 +105,8 @@ module StreamEntriesHelper end def poll_summary(status) - return unless status.poll - status.poll.options.map { |o| "[ ] #{o}" }.join("\n") + return unless status.preloadable_poll + status.preloadable_poll.options.map { |o| "[ ] #{o}" }.join("\n") end def status_description(status) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 8fe7b9138..dabdcbcf7 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -68,7 +68,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity thread: replied_to_status, conversation: conversation_from_uri(@object['conversation']), media_attachment_ids: process_attachments.take(4).map(&:id), - owned_poll: process_poll, + poll: process_poll, } end end @@ -240,11 +240,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def poll_vote? - return false if replied_to_status.nil? || replied_to_status.poll.nil? || !replied_to_status.local? || !replied_to_status.poll.options.include?(@object['name']) + return false if replied_to_status.nil? || replied_to_status.preloadable_poll.nil? || !replied_to_status.local? || !replied_to_status.preloadable_poll.options.include?(@object['name']) - unless replied_to_status.poll.expired? - replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']), uri: @object['id']) - ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.poll.hide_totals? + unless replied_to_status.preloadable_poll.expired? + replied_to_status.preloadable_poll.votes.create!(account: @account, choice: replied_to_status.preloadable_poll.options.index(@object['name']), uri: @object['id']) + ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.preloadable_poll.hide_totals? end true diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb index bc9a63f98..70035325b 100644 --- a/app/lib/activitypub/activity/update.rb +++ b/app/lib/activitypub/activity/update.rb @@ -23,8 +23,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity return reject_payload! if invalid_origin?(@object['id']) status = Status.find_by(uri: object_uri, account_id: @account.id) - return if status.nil? || status.poll.nil? + return if status.nil? || status.preloadable_poll.nil? - ActivityPub::ProcessPollService.new.call(status.poll, @object) + ActivityPub::ProcessPollService.new.call(status.preloadable_poll, @object) end end diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index aadf03b2a..59dfc9004 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -19,8 +19,8 @@ class Formatter raw_content = status.text - if options[:inline_poll_options] && status.poll - raw_content = raw_content + "\n\n" + status.poll.options.map { |title| "[ ] #{title}" }.join("\n") + if options[:inline_poll_options] && status.preloadable_poll + raw_content = raw_content + "\n\n" + status.preloadable_poll.options.map { |title| "[ ] #{title}" }.join("\n") end return '' if raw_content.blank? diff --git a/app/models/notification.rb b/app/models/notification.rb index 982136c05..300269e24 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -25,7 +25,7 @@ class Notification < ApplicationRecord poll: 'Poll', }.freeze - STATUS_INCLUDES = [:account, :application, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :media_attachments, :tags, active_mentions: :account]].freeze + STATUS_INCLUDES = [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account]].freeze belongs_to :account, optional: true belongs_to :from_account, class_name: 'Account', optional: true diff --git a/app/models/status.rb b/app/models/status.rb index d3fb83cca..8d31fd382 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -45,7 +45,7 @@ class Status < ApplicationRecord belongs_to :account, inverse_of: :statuses belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account', optional: true belongs_to :conversation, optional: true - belongs_to :poll, optional: true + belongs_to :preloadable_poll, class_name: 'Poll', foreign_key: 'poll_id', optional: true belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true @@ -63,7 +63,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 - has_one :owned_poll, class_name: 'Poll', inverse_of: :status, dependent: :destroy + has_one :poll, inverse_of: :status, dependent: :destroy validates :uri, uniqueness: true, presence: true, unless: :local? validates :text, presence: true, unless: -> { with_media? || reblog? } @@ -72,7 +72,7 @@ class Status < ApplicationRecord validates :reblog, uniqueness: { scope: :account }, if: :reblog? validates :visibility, exclusion: { in: %w(direct limited) }, if: :reblog? - accepts_nested_attributes_for :owned_poll + accepts_nested_attributes_for :poll default_scope { recent } @@ -107,7 +107,7 @@ class Status < ApplicationRecord :tags, :preview_cards, :stream_entry, - :poll, + :preloadable_poll, account: :account_stat, active_mentions: { account: :account_stat }, reblog: [ @@ -118,7 +118,7 @@ class Status < ApplicationRecord :media_attachments, :conversation, :status_stat, - :poll, + :preloadable_poll, account: :account_stat, active_mentions: { account: :account_stat }, ], @@ -214,10 +214,11 @@ class Status < ApplicationRecord def emojis return @emojis if defined?(@emojis) - fields = [spoiler_text, text] - fields += owned_poll.options unless owned_poll.nil? + + fields = [spoiler_text, text] + fields += preloadable_poll.options unless preloadable_poll.nil? + @emojis = CustomEmoji.from_text(fields.join(' '), account.domain) - @emojis end def mark_for_mass_destruction! @@ -453,7 +454,7 @@ class Status < ApplicationRecord end def set_poll_id - update_column(:poll_id, owned_poll.id) unless owned_poll.nil? + update_column(:poll_id, poll.id) unless poll.nil? end def set_visibility diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 0666bea5a..d11cfa59a 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -29,7 +29,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer end def type - object.poll ? 'Question' : 'Note' + object.preloadable_poll ? 'Question' : 'Note' end def summary @@ -125,29 +125,29 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer end def poll_options - object.poll.loaded_options + object.preloadable_poll.loaded_options end def poll_and_multiple? - object.poll&.multiple? + object.preloadable_poll&.multiple? end def poll_and_not_multiple? - object.poll && !object.poll.multiple? + object.preloadable_poll && !object.preloadable_poll.multiple? end def closed - object.poll.expires_at.iso8601 + object.preloadable_poll.expires_at.iso8601 end alias end_time closed def poll_and_expires? - object.poll&.expires_at&.present? + object.preloadable_poll&.expires_at&.present? end def poll_and_expired? - object.poll&.expired? + object.preloadable_poll&.expired? end class MediaAttachmentSerializer < ActivityPub::Serializer diff --git a/app/serializers/activitypub/update_poll_serializer.rb b/app/serializers/activitypub/update_poll_serializer.rb index a9a09747f..b894f309f 100644 --- a/app/serializers/activitypub/update_poll_serializer.rb +++ b/app/serializers/activitypub/update_poll_serializer.rb @@ -6,7 +6,7 @@ class ActivityPub::UpdatePollSerializer < ActivityPub::Serializer has_one :object, serializer: ActivityPub::NoteSerializer def id - [ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.poll.updated_at.to_i].join + [ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.preloadable_poll.updated_at.to_i].join end def type diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 30edf397b..106777b6e 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -21,7 +21,7 @@ class REST::StatusSerializer < ActiveModel::Serializer has_many :emojis, serializer: REST::CustomEmojiSerializer has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer - has_one :poll, serializer: REST::PollSerializer + has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer def id object.id.to_s diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 3f392a6e6..e7366c7e8 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -155,7 +155,7 @@ class PostStatusService < BaseService text: @text, media_attachments: @media || [], thread: @in_reply_to, - owned_poll_attributes: poll_attributes, + poll_attributes: poll_attributes, sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?, spoiler_text: @options[:spoiler_text] || '', visibility: @visibility, diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml index d18ecd37a..4459581d9 100644 --- a/app/views/stream_entries/_detailed_status.html.haml +++ b/app/views/stream_entries/_detailed_status.html.haml @@ -22,9 +22,9 @@ %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more') .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay) - - if status.poll - = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do - = render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay } + - if status.preloadable_poll + = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do + = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay } - elsif !status.media_attachments.empty? - if status.media_attachments.first.video? - video = status.media_attachments.first diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml index a499a8634..ba22c5340 100644 --- a/app/views/stream_entries/_simple_status.html.haml +++ b/app/views/stream_entries/_simple_status.html.haml @@ -26,9 +26,9 @@ %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more') .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay) - - if status.poll - = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do - = render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay } + - if status.preloadable_poll + = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do + = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay } - elsif !status.media_attachments.empty? - if status.media_attachments.first.video? - video = status.media_attachments.first diff --git a/app/workers/activitypub/distribute_poll_update_worker.rb b/app/workers/activitypub/distribute_poll_update_worker.rb index d60fde557..5eaca6fda 100644 --- a/app/workers/activitypub/distribute_poll_update_worker.rb +++ b/app/workers/activitypub/distribute_poll_update_worker.rb @@ -9,7 +9,7 @@ class ActivityPub::DistributePollUpdateWorker @status = Status.find(status_id) @account = @status.account - return unless @status.poll + return unless @status.preloadable_poll ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url| [payload, @account.id, inbox_url] @@ -29,7 +29,7 @@ class ActivityPub::DistributePollUpdateWorker def inboxes return @inboxes if defined?(@inboxes) - @inboxes = [@status.mentions, @status.reblogs, @status.poll.votes].flat_map do |relation| + @inboxes = [@status.mentions, @status.reblogs, @status.preloadable_poll.votes].flat_map do |relation| relation.includes(:account).map do |record| record.account.preferred_inbox_url if !record.account.local? && record.account.activitypub? end diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 561ce68b8..8533418cc 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -2,8 +2,9 @@ en: activerecord: attributes: - status: - owned_poll: Poll + poll: + expires_at: Deadline + options: Choices errors: models: account: diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 3a1463d95..412609de4 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -464,7 +464,7 @@ RSpec.describe ActivityPub::Activity::Create do context 'when a vote to a local poll' do let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) } - let!(:local_status) { Fabricate(:status, owned_poll: poll) } + let!(:local_status) { Fabricate(:status, poll: poll) } let(:object_json) do { @@ -489,7 +489,7 @@ RSpec.describe ActivityPub::Activity::Create do poll.save(validate: false) poll end - let!(:local_status) { Fabricate(:status, owned_poll: poll) } + let!(:local_status) { Fabricate(:status, poll: poll) } let(:object_json) do { -- cgit