diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb new file mode 100644 index 00000000..dfe388a4 --- /dev/null +++ b/app/controllers/activity_pubs_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Gestiona acciones de moderación +class ActivityPubsController < ApplicationController + ActivityPub.events.each do |event| + define_method(event) do + activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") + + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end + + def action_on_several + + end + + private + + def activity_pub + @activity_pub ||= site.activity_pubs.find(params[:activity_pub_id]) + end +end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index b52c2a76..95fa3bf3 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -9,6 +9,9 @@ # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} class ActivityPub < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = %i[remove] belongs_to :instance belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index c6f8bfc0..1fc1a42a 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -3,6 +3,9 @@ # Mantiene la relación entre Site y Actor class ActorModeration < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = [] belongs_to :site belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' @@ -19,13 +22,6 @@ class ActorModeration < ApplicationRecord self.update_all(aasm_state: 'paused', updated_at: Time.now) end - # Todos los eventos de la máquina de estados - # - # @return [Array] - def self.events - aasm.events.map(&:name) - end - aasm do state :paused, initial: true state :allowed diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb new file mode 100644 index 00000000..79250ea9 --- /dev/null +++ b/app/models/concerns/aasm_events_concern.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module AasmEventsConcern + extend ActiveSupport::Concern + + included do + # Todos los eventos de la máquina de estados + # + # @return [Array] + def self.events + aasm.events.map(&:name) - self::IGNORED_EVENTS + end + end +end diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 677b88f1..a950ad5a 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,6 +1,7 @@ -# Componente Botón general Moderación - local_assigns[:method] ||= 'patch' +- local_assigns[:class] ||= 'btn-secondary' - local_assigns[:class] = "btn #{local_assigns[:class]}" -# @todo path es obligatorio diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 8b8d7268..285eefdb 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,8 +1,8 @@ -# Componente Botonera de Comentarios -- btn_class = 'btn-secondary py-1 px-2' -= render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file +.d-flex.flex-row + - ActivityPub.events.each do |event| + = render 'components/btn_base', + text: t(".text_#{event}"), + path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), + disabled: !activity_pub.public_send(:"may_#{event}?") diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 29888ef7..ffaf76cf 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,11 +1,16 @@ --# Componente Comentario +-# + Componente Comentario + + @param profile [Hash] + @param comment [Hash] + @param activity_pub [ActivityPub] - in_reply_to = text_plain comment['inReplyTo'] -- summary = text_plain(comment['summary']) +- summary = text_plain comment['summary'] .row.no-gutters .col-1 - = render 'components/checkbox', id: comment['id'] + = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' } .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 @@ -25,3 +30,4 @@ = sanitize comment['content'] - else = sanitize comment['content'] + = render 'components/comments_btn_box', activity_pub: activity_pub diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 4fe84652..97f77e3c 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,14 @@ -.row.no-gutters.pt-2 - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'select-all-comments' - .col-md-9 - -# Filtros - = render 'components/comments_filters' +%form{ action: site_activity_pubs_action_on_several_path, method: :post, data: { controller: 'select-all' } } + .row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'select-all-comments' + .col-md-9 + -# Filtros + = render 'components/comments_filters' -- moderation_queue.each do |activity_pub| - %hr - = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content - - -# Botones moderación - .d-flex.justify-content-center - = render 'components/comments_btn_box', comment: activity_pub.object.content + - if moderation_queue.count.zero? + %h4= t('moderation_queue.nothing') + - moderation_queue.each do |activity_pub| + - cache [activity_pub, activity_pub.object, activity_pub.actor] do + %hr + = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub diff --git a/config/locales/en.yml b/config/locales/en.yml index 6d5baf5a..f69d60b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -93,8 +93,8 @@ en: title: Block lists comments_btn_box: text_pause: Pause + text_approve: Approve text_reject: Reject - text_accept: Accept text_reply: Reply text_report: Report instances_btn_box: diff --git a/config/locales/es.yml b/config/locales/es.yml index 13534822..a0aaa4d6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -92,10 +92,9 @@ es: block_lists: title: Listas de bloqueo comments_btn_box: - text_pause: Pausa + text_pause: Pausar + text_approve: Aceptar text_reject: Rechazar - text_accept: Aceptar Publicación - text_reply: Responder text_report: Reportar instances_btn_box: text_check: Moderar caso por caso diff --git a/config/routes.rb b/config/routes.rb index 9d825a3c..8809767b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -82,6 +82,14 @@ Rails.application.routes.draw do patch :actor_moderations_action_on_several, to: 'actor_moderations#action_on_several' + resources :activity_pub, only: [] do + ActivityPub.events.each do |event| + patch event, to: "activity_pubs##{event}" + end + end + + patch :activity_pubs_action_on_several, to: 'activity_pubs#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do