1
0
Fork 0
forked from gitea/nas

Merge branch 'kb_development' into kb_migration

This commit is contained in:
KMY 2023-02-28 15:33:59 +09:00
commit 1cc70b5d93
21 changed files with 211 additions and 19 deletions

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
module Admin
class MediaAttachmentsController < BaseController
def index
authorize :account, :index?
@media_attachments = filtered_attachments.page(params[:page])
@form = Form::MediaAttachmentsBatch.new
end
private
def filtered_attachments
MediaAttachment.local_attached.order(created_at: :desc)
end
end
end

View file

@ -10,7 +10,10 @@ class Api::V1::Statuses::EmojiReactionedByAccountsSlimController < Api::BaseCont
@accounts = load_emoji_reactions
# TODO for serialize hash object
render json: @accounts, each_serializer: REST::EmojiReactedBySlimSerializer
#render json: @accounts, each_serializer: REST::EmojiReactedBySlimSerializer
# Hide WIP api for hide account secret
not_found
end
private

View file

@ -106,6 +106,7 @@ class Status extends ImmutablePureComponent {
inUse: PropTypes.bool,
available: PropTypes.bool,
}),
withoutEmojiReactions: PropTypes.bool,
};
// Avoid checking props that are functions (and whose equality will always
@ -512,7 +513,7 @@ class Status extends ImmutablePureComponent {
const visibilityIcon = visibilityIconInfo[status.get('visibility')];
let emojiReactionsBar = null;
if (status.get('emoji_reactions')) {
if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) {
const emojiReactions = status.get('emoji_reactions');
emojiReactionsBar = <StatusEmojiReactionsBar emojiReactions={emojiReactions} status={status} onEmojiReact={this.props.onEmojiReact} onUnEmojiReact={this.props.onUnEmojiReact} />;
}

View file

@ -179,6 +179,7 @@ class Notification extends ImmutablePureComponent {
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
unread={this.props.unread}
withoutEmojiReactions={true}
/>
);
}
@ -209,6 +210,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>
@ -216,7 +218,6 @@ class Notification extends ImmutablePureComponent {
}
renderEmojiReaction (notification, link) {
console.dir(notification)
const { intl, unread } = this.props;
const emoji_reaction = notification.get('emoji_reaction');
@ -243,6 +244,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>
@ -275,6 +277,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>
@ -312,6 +315,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>
@ -349,6 +353,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>
@ -392,6 +397,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
withoutEmojiReactions={true}
/>
</div>
</HotKeys>

View file

@ -380,3 +380,14 @@
color: $gold-star;
}
}
.batch-table__row--attention .media-attachments-table {
.image {
max-width: 80%;
max-height: 200px;
}
.detailed-status__meta {
margin-top: 8px;
}
}

View file

@ -24,7 +24,7 @@
class CustomEmoji < ApplicationRecord
include Attachmentable
LIMIT = 256.kilobytes
LIMIT = 512.kilobytes
SHORTCODE_RE_FRAGMENT = '[a-zA-Z0-9_]{2,}'

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class Form::MediaAttachmentsBatch
include ActiveModel::Model
include Authorization
include AccountableConcern
include Payloadable
attr_accessor :query
def save
end
end

View file

@ -33,6 +33,7 @@ class MediaAttachment < ApplicationRecord
self.inheritance_column = nil
include Attachmentable
include RoutingHelper
enum type: { :image => 0, :gifv => 1, :video => 2, :unknown => 3, :audio => 4 }
enum processing: { :queued => 0, :in_progress => 1, :complete => 2, :failed => 3 }, _prefix: true
@ -208,6 +209,7 @@ class MediaAttachment < ApplicationRecord
scope :local, -> { where(remote_url: '') }
scope :remote, -> { where.not(remote_url: '') }
scope :cached, -> { remote.where.not(file_file_name: nil) }
scope :local_attached, -> { attached.where(remote_url: '') }
default_scope { order(id: :asc) }
@ -271,6 +273,10 @@ class MediaAttachment < ApplicationRecord
delay_processing? && attachment_name == :file
end
def url
full_asset_url(file.url(:original))
end
after_commit :enqueue_processing, on: :create
after_commit :reset_parent_cache, on: :update

View file

@ -11,7 +11,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
attributes :domain, :title, :version, :source_url, :description,
:usage, :thumbnail, :languages, :configuration,
:registrations
:registrations, :fedibird_capabilities
has_one :contact, serializer: ContactSerializer
has_many :rules, serializer: REST::RuleSerializer
@ -88,6 +88,17 @@ class REST::InstanceSerializer < ActiveModel::Serializer
}
end
# for third party apps
def fedibird_capabilities
capabilities = [
:emoji_reaction,
]
capabilities << :profile_search unless Chewy.enabled?
capabilities
end
private
def registrations_enabled?

View file

@ -6,7 +6,7 @@ class REST::NotificationSerializer < ActiveModel::Serializer
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
belongs_to :emoji_reaction, if: :emoji_reaction_type?, serializer: REST::EmojiReactionSerializer
belongs_to :emoji_reaction, if: :emoji_reaction_type?, serializer: REST::NotifyEmojiReactionSerializer
def id
object.id.to_s

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
class REST::NotifyEmojiReactionSerializer < ActiveModel::Serializer
include RoutingHelper
attributes :name
attribute :count, if: :count?
attribute :url, if: :custom_emoji?
attribute :static_url, if: :custom_emoji?
attribute :domain, if: :custom_emoji?
def count?
object.respond_to?(:count)
end
def custom_emoji?
object.respond_to?(:custom_emoji) && object.custom_emoji.present?
end
def account_ids?
object.respond_to?(:account_ids)
end
def url
full_asset_url(object.custom_emoji.image.url)
end
def static_url
full_asset_url(object.custom_emoji.image.url(:static))
end
def domain
object.custom_emoji.domain
end
end

View file

@ -6,7 +6,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
attributes :uri, :title, :short_description, :description, :email,
:version, :urls, :stats, :thumbnail,
:languages, :registrations, :approval_required, :invites_enabled,
:configuration
:configuration, :fedibird_capabilities
has_one :contact_account, serializer: REST::AccountSerializer
@ -98,6 +98,17 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
UserRole.everyone.can?(:invite_users)
end
# for third party apps
def fedibird_capabilities
capabilities = [
:emoji_reaction,
]
capabilities << :profile_search unless Chewy.enabled?
capabilities
end
private
def instance_presenter

View file

@ -197,7 +197,7 @@ class DeleteAccountService < BaseService
def purge_emoji_reactions!
@account.emoji_reactions.in_batches do |reactions|
reactions.each do |reaction|
reaction.status.refresh_emoji_reactions_grouped_by_name
reaction.status.refresh_emoji_reactions_grouped_by_name!
end
Chewy.strategy.current.update(StatusesIndex, reactions.pluck(:status_id)) if Chewy.enabled?
reactions.delete_all

View file

@ -5,16 +5,16 @@ class UnEmojiReactService < BaseService
include Payloadable
def call(account_id, status_id, emoji_reaction = nil)
@account_id = account_id
@account = Account.find(account_id)
@status = Status.find(status_id)
@status = Status.find(status_id)
if emoji_reaction
create_notification(emoji_reaction) if !@account.local? && @account.activitypub?
notify_to_followers(emoji_reaction) if @account.local?
emoji_reaction.destroy!
create_notification(emoji_reaction) if !@status.account.local? && @status.account.activitypub?
notify_to_followers(emoji_reaction) if @status.account.local?
write_stream(emoji_reaction)
else
bulk(@account, @status)
account = Account.find(account_id)
bulk(account, @status)
end
emoji_reaction
end
@ -22,17 +22,17 @@ class UnEmojiReactService < BaseService
private
def bulk(account, status)
EmojiReaction.where(account: account).where(status: status).tap do |emoji_reaction|
call(account, status, emoji_reaction)
EmojiReaction.where(account: account).where(status: status).each do |emoji_reaction|
call(account.id, status.id, emoji_reaction)
end
end
def create_notification(emoji_reaction)
ActivityPub::DeliveryWorker.perform_async(build_json(emoji_reaction), @account_id, @account.inbox_url)
ActivityPub::DeliveryWorker.perform_async(build_json(emoji_reaction), emoji_reaction.account_id, @status.account.inbox_url)
end
def notify_to_followers(emoji_reaction)
ActivityPub::RawDistributionWorker.perform_async(build_json(emoji_reaction), @account_id)
ActivityPub::RawDistributionWorker.perform_async(build_json(emoji_reaction), @status.account_id)
end
def write_stream(emoji_reaction)
@ -45,7 +45,7 @@ class UnEmojiReactService < BaseService
emoji_group = { 'name' => emoji_reaction.name, 'count' => 0, 'account_ids' => [], 'status_id' => @status.id.to_s }
emoji_group['domain'] = emoji_reaction.custom_emoji.domain if emoji_reaction.custom_emoji
end
FeedAnyJsonWorker.perform_async(render_emoji_reaction(emoji_group), @status.id, @account_id)
FeedAnyJsonWorker.perform_async(render_emoji_reaction(emoji_group), @status.id, emoji_reaction.account_id)
end
def build_json(emoji_reaction)

View file

@ -0,0 +1,30 @@
.batch-table__row{ class: ['batch-table__row--attention'] }
.batch-table__row__content.batch-table__row__content--unpadded
%table.media-attachments-table
%tbody
%tr
%td
%img{ src: media_attachment.url, class: 'image' }
.detailed-status__meta
- if media_attachment.status.application
= media_attachment.status.application.name
·
= link_to ActivityPub::TagManager.instance.url_for(media_attachment.status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
%time.formatted{ datetime: media_attachment.status.created_at.iso8601, title: l(media_attachment.status.created_at) }= l(media_attachment.status.created_at)
- if media_attachment.status.edited?
·
= link_to t('statuses.edited_at_html', date: content_tag(:time, l(media_attachment.status.edited_at), datetime: media_attachment.status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')), admin_account_status_path(status.account_id, status), class: 'detailed-status__datetime'
- if media_attachment.status.discarded?
·
%span.negative-hint= t('admin.statuses.deleted')
·
- if media_attachment.status.reblog?
= fa_icon('retweet fw')
= t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account))
- else
= fa_visibility_icon(media_attachment.status)
= t("statuses.visibilities.#{media_attachment.status.visibility}")
- if media_attachment.status.proper.sensitive?
·
= fa_icon('eye-slash fw')
= t('stream_entries.sensitive_content')

View file

@ -0,0 +1,30 @@
- content_for :page_title do
= t('admin.media_attachments.title')
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
= form_for(@form, url: admin_media_attachments_path) do |f|
= hidden_field_tag :page, params[:page] || 1
= hidden_field_tag :select_all_matching, '0'
- AccountFilter::KEYS.each do |key|
= hidden_field_tag key, params[key] if params[key].present?
.batch-table
.batch-table__toolbar
- if @media_attachments.total_count > @media_attachments.size
.batch-table__select-all
.not-selected.active
%span= t('generic.all_items_on_page_selected_html', count: @media_attachments.size)
%button{ type: 'button' }= t('generic.select_all_matching_items', count: @media_attachments.total_count)
.selected
%span= t('generic.all_matching_items_selected_html', count: @media_attachments.total_count)
%button{ type: 'button' }= t('generic.deselect')
.batch-table__body
- if @media_attachments.empty?
= nothing_here 'nothing-here--under-tabs'
- else
= render partial: 'media_attachment', collection: @media_attachments, locals: { f: f }
= paginate @media_attachments