5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-22 21:46:22 +00:00

Merge remote-tracking branch 'refs/remotes/origin/issue-14966' into issue-14966

This commit is contained in:
maki 2024-02-06 13:59:03 -03:00
commit d0441f6e7c
22 changed files with 329 additions and 64 deletions

View file

@ -36,25 +36,7 @@ class ApplicationController < ActionController::Base
activity['attributedTo'] = @remote_profile
end
end
# parámetros de botones:
# text: [texto del botón]
# class: [clases css]
# href: [href del botón]
def botoneras_moderation_queue
# botones de comentarios
@comment_btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''],
[t('moderation_queue.button_box.text_reject'), 'btn-primary', ''],
[t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''],
[t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''],
[t('moderation_queue.button_box.text_report'), 'btn-danger', '']]
#botones de remote_profile (cuentas)
@profile_btn_params = [[t('moderation_queue.profile_button_box.text_deny'), 'btn-outline-info', ''],
[t('moderation_queue.profile_button_box.text_allow'), 'btn-success', 'https://sutty.nl/'],
[t('moderation_queue.profile_button_box.text_report'), 'btn-outline-danger', 'https://sutty.nl/']]
end
def notify_unconfirmed_email
return unless current_usuarie
return if current_usuarie.confirmed?

View file

@ -9,13 +9,11 @@ class ModerationQueueController < ApplicationController
@moderation_queue.each do |activity|
activity['attributedTo'] = @remote_profile
end
botoneras_moderation_queue
end
# Perfil remoto de usuarie
def remote_profile
@remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml')))
botoneras_moderation_queue
end
# todon.nl está usando /api/v2/instance

View file

@ -83,7 +83,6 @@ class PostsController < ApplicationController
breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact
breadcrumb 'posts.edit', ''
dummy_data
botoneras_moderation_queue
end
def update

View file

@ -0,0 +1,63 @@
module ModerationQueueHelper
# parámetros de botones:
# text: [texto del botón]
# class: [clases css]
# href: [href del botón]
def botoneras_moderation_queue
# botones de comentarios
@btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''],
[t('moderation_queue.button_box.text_reject'), 'btn-primary', ''],
[t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''],
[t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''],
[t('moderation_queue.button_box.text_report'), 'btn-danger', '']]
#botones de remote_profile (cuentas)
@profile_btn_params = [[t('moderation_queue.profile_button_box.text_approve'), 'btn-success', ''],
[t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''],
[t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''],
[t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']]
#botones de instances (instancias)
@instances_btn_params = [[t('moderation_queue.instances_button_box.text_check'), 'btn-outline-success', ''],
[t('moderation_queue.instances_button_box.text_allow'), 'btn-success', ''],
[t('moderation_queue.instances_button_box.text_deny'), 'btn-danger', '']]
end
# parámetros de filtros:
# text: [texto del botón]
# href: [href del botón]
def filtros_moderation_queue
#filtros de comentarios
@comment_filter_params = {
t('moderation_queue.filter_box.text_checked') =>
[
[t('moderation_queue.filter_box.submenu_pause'), '/sutty.nl'],
[t('moderation_queue.filter_box.submenu_reject'), '#reject'],
[t('moderation_queue.filter_box.submenu_accept'),'#accept']
],
t('moderation_queue.filter_box.text_show') =>
[
[t('moderation_queue.filter_box.submenu_pause'), '#pause'],
[t('moderation_queue.filter_box.submenu_reject'), '#reject'],
[t('moderation_queue.filter_box.submenu_accept'),'#accept'],
[t('moderation_queue.filter_box.submenu_report'), '#report']
]
}
#filtros de instancias
@instances_filter_params = {
t('moderation_queue.filter_box.text_checked') =>
[
[t('moderation_queue.filter_box.submenu_case'), '#case_by_case'],
[t('moderation_queue.filter_box.submenu_allow'), '#allow'],
[t('moderation_queue.filter_box.submenu_reject'),'#reject']
],
t('moderation_queue.filter_box.text_show') =>
[
[t('moderation_queue.filter_box.submenu_allow'), '#allow'],
[t('moderation_queue.filter_box.submenu_reject'), '#reject']
]
}
end
end

View file

@ -0,0 +1,106 @@
import { Controller } from "stimulus";
// https://getbootstrap.com/docs/4.6/components/dropdowns/#single-button
export default class extends Controller {
static targets = ["dropdown", "button", "item"];
// Al iniciar el controlador
connect() {
// Llevar la cuenta del item con foco
this.data.set("item", -1);
// Gestionar las teclas
this.keydownEvent = this.keydown.bind(this);
this.element.addEventListener("keydown", this.keydownEvent);
// Gestionar el foco
this.focusinEvent = this.focusin.bind(this);
}
// Al eliminar el controlador (al pasar a otra página)
disconnect() {
// Eliminar la gestión de teclas
this.element.removeEventListener("keydown", this.keydownEvent);
// Eliminar la gestión del foco
document.removeEventListener("focusin", this.focusinEvent);
}
// Mostrar u ocultar
toggle(event) {
(this.buttonTarget.ariaExpanded === "false") ? this.show() : this.hide();
}
// Mostrar
show() {
this.buttonTarget.ariaExpanded = "true";
this.element.classList.add("show");
this.dropdownTarget.classList.add("show");
// Activar la gestión del foco
document.addEventListener("focusin", this.focusinEvent);
}
// Ocultar
hide() {
this.buttonTarget.ariaExpanded = "false";
this.element.classList.remove("show");
this.dropdownTarget.classList.remove("show");
// Volver al inicio el foco de items
this.data.set("item", -1);
// Desactivar la gestión del foco
document.removeEventListener("focusin", this.focusinEvent);
}
// Gestionar el foco
focusin(event) {
const item = this.itemTargets.find(x => x === event.target);
// Si el foco se coloca sobre elementos del controlador, no hacer
// nada
if (event.target === this.buttonTarget || item) {
// Si es un item, el comportamiento de las flechas verticales y el
// Tab tiene que ser igual
if (item) this.data.set("item", this.itemTargets.indexOf(item));
return;
}
// De lo contrario, ocultar
this.hide();
}
// Gestionar las teclas
keydown(event) {
const initial = parseInt(this.data.get("item"));
let item = initial;
switch (event.keyCode) {
case 27:
// Esc cierra el menú y devuelve el foco
this.hide();
this.buttonTarget.focus();
break;
case 38:
// Moverse hacia arriba con tope en el primer item
if (item > -1) item--;
break;
case 40:
// Moverse hacia abajo con tope en el último ítem, si el
// dropdown estaba cerrado, abrirlo.
if (item === -1) this.show();
if (item <= this.itemTargets.length) item++;
break;
}
// Si cambió la posición del ítem, darle foco y actualizar el
// contador.
if (initial !== item) {
this.itemTargets[item]?.focus();
this.data.set("item", item);
}
}
}

View file

@ -0,0 +1,34 @@
-#
@param :text [String] Contenido del botón
@param :button_classes [Array] Clases para el botón
@param :dropdown_classes [Array] Clases para el listado
@yield Un bloque que renderiza components/dropdown_item
- button_classes = local_assigns[:button_classes]&.join(' ')
- dropdown_classes = local_assigns[:dropdown_classes]&.join(' ')
.btn-group{
data: {
controller: 'dropdown'
}
}
%button.btn.dropdown-toggle{
type: 'button',
class: button_classes,
data: {
toggle: 'true',
display: 'static',
action: 'dropdown#toggle',
target: 'dropdown.button'
},
aria: {
expanded: 'false'
}
}
= text
.dropdown-menu{
class: dropdown_classes,
data: {
target: 'dropdown.dropdown'
}
}
= yield

View file

@ -0,0 +1,4 @@
-#
@param :text [String] Contenido del link
@param :path [String] Link
= link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' }

View file

@ -1,6 +1,6 @@
-# Detail Cola de Moderación
%details.details.py-2
%summary
%summary
%h3.py-2.text-center= @summary
= yield
= yield

View file

@ -1,3 +1,16 @@
= render 'moderation_queue/comment_filter_box'
- @moderation_queue.each do |comment|
= render 'account', comment: comment, profile: @remote_profile
= render 'account', comment: comment, profile: @remote_profile
- filtros_moderation_queue
- botoneras_moderation_queue
.d-flex.py-2.justify-content-center
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'moderation_queue/button_box', btn_params: @profile_btn_params

View file

@ -0,0 +1,5 @@
.form-group
.d-flex.flex-column.mt-5
%textarea.red.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') }
%button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-primary' }= t('moderation_queue.instances.submit')

View file

@ -0,0 +1,5 @@
.flex
.card
.card-body
%input{ type: 'checkbox', value: '', class: 'ml-5' }
%h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists')

View file

@ -1,3 +1,3 @@
-# Componente Botón general Moderación
%a.btn.btn-lg.rounded.mx-2{role: "button", href: href, class: @class} #{text}
%a.btn.btn-lg.rounded.mx-2{role: 'button', href: href, class: @class} #{text}

View file

@ -1,6 +1,6 @@
-# Componente Botonera de Moderación
.d-flex.py-2.justify-content-center
- comment_btn_params.each do |btn|
.d-flex.py-4.justify-content-center
- btn_params.each do |btn|
- @class = btn[1]
= render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0]
= render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0]

View file

@ -2,17 +2,17 @@
.flex.mx-4.my-5
.row.no-gutters
.col-1
%input{type: "checkbox", id: ""}
%input{ type: 'checkbox', id: '' }
.col-10
.row.border.border-white
.col.col-1.border.border-white.mr-5
%p= comment['published'].to_datetime.strftime('%m/%d/%Y')
.col.border.border-white
%span.mr-2= t('.source_profile')
%a{:href => comment['attributedTo']}= profile['preferredUsername']
.row.border.border-white
%a{ href: comment['attributedTo'] }= profile['preferredUsername']
.row.border.border-white
%p.mr-3= t('.reply_to')
%span
%a{:href => comment['inReplyTo']}= comment['inReplyTo']
.row.border.border-white
%a{ href: comment['inReplyTo'] }= comment['inReplyTo']
.row.border.border-white
%p= sanitize comment['content']

View file

@ -1,6 +0,0 @@
-# Componente Caja de Filtros
.d-flex.py-2.justify-content-center
= render 'moderation_queue/filter_base', text: t('.text_checked')
= render 'moderation_queue/filter_base', text: t('.text_show')
= render 'moderation_queue/filter_base', text: t('.text_order')

View file

@ -1,5 +1,16 @@
= render 'moderation_queue/comment_filter_box'
- @moderation_queue.each do |comment|
- botoneras_moderation_queue
.d-flex.py-2.justify-content-center
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/'
- moderation_queue.each do |comment|
= render 'comment', comment: comment, profile: @remote_profile
= render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params
= render 'moderation_queue/button_box', btn_params: @btn_params

View file

@ -1,8 +0,0 @@
-# Componente Filtro
.dropdown.mx-4
%button#dropdownMenuButton.btn.btn-outline-secondary.dropdown-toggle{:type => "button", "data-toggle" => "dropdown", "aria-haspopup" => "true", "aria-expanded" => "false"}
%span #{text}
.dropdown-menu{"aria-labelledby" => "dropdownMenuButton"}
%a.dropdown-item{ href: '#' } Action
%a.dropdown-item{ href: '#' } Another action
%a.dropdown-item{ href: '#' } Something else here

View file

@ -1 +1,18 @@
= render 'moderation_queue/comment_filter_box'
- botoneras_moderation_queue
.d-flex.py-2.justify-content-center
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'moderation_queue/button_box', btn_params: @instances_btn_params
%h3.cyan.mt-5= t('moderation_queue.instances.title')
%p.pb-2= t('moderation_queue.instances.description')
= render 'moderation_queue/block_lists'
= render 'moderation_queue/block_instances_textarea'

View file

@ -1,5 +1,22 @@
-# Componente Remote_Profile
.flex.py-2.mx-2.text-center
%h4= t('.profile_name') + ': ' + remote_profile['name']
%h5= t('.profile_id') + ': ' + remote_profile['id']
- botoneras_moderation_queue
.d-flex.py-2.justify-content-center
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/'
%h4.my-2= t('.profile_name') + ': ' + remote_profile['name']
%h5= t('.profile_id') + ': ' + remote_profile['id']
%h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y')
= render 'moderation_queue/button_box', comment_btn_params: @profile_btn_params
%h5= t('.profile_summary') + ':'
%p= sanitize remote_profile['summary']
= render 'moderation_queue/button_box', btn_params: @profile_btn_params

View file

@ -2,13 +2,10 @@
.col-md-8
- @summary = t('moderation_queue.index.instances')
= render 'layouts/details', summary: @summary do
= render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue
= render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue
- @summary = t('moderation_queue.index.accounts')
= render 'layouts/details', summary: @summary do
= render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue
- @summary = t('moderation_queue.index.comments')
= render 'layouts/details', summary: @summary do
= render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue

View file

@ -1,7 +1,18 @@
.flex
%h3.text-center.py-2 Comentarios
= render 'moderation_queue/comment_filter_box'
- botoneras_moderation_queue
.d-flex.py-2.justify-content-center
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/'
= render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/'
- moderation_queue.each do |comment|
= render 'moderation_queue/comment', comment: comment, profile: @remote_profile
.row.d-flex.justify-content-center
= render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params
= render 'moderation_queue/button_box', btn_params: @btn_params

View file

@ -12,9 +12,11 @@ es:
profile_name: Nombre de la Cuenta
profile_id: ID
profile_published: Publicada
profile_summary: Resumen
profile_button_box:
text_deny: Bloquear que te siga
text_allow: Permitir que te siga
text_approve: Aprovar siempre
text_check: Revisar siempre
text_deny: Bloquear
text_report: Reportar
button_box:
text_pause: Pausa
@ -22,10 +24,25 @@ es:
text_accept: Aceptar Publicación
text_reply: Responder
text_report: Reportar
comment_filter_box:
text_order: Ordenar por
filter_box:
text_show: Ver
text_checked: Con los marcados
submenu_pause: Pausado
submenu_reject: Rechazado
submenu_accept: Aceptado
submenu_report: Reportado
submenu_case: Moderar caso por caso
submenu_allow: Permitir todo
instances_button_box:
text_check: Moderar caso por caso
text_allow: Permitir todo
text_deny: Bloquear instancia
instances:
title: Mis listas de bloqueo
description: Descripción de listas de bloqueo
block_lists: Listas de bloqueo
custom_block: Lista personalizada de bloqueo
submit: Guardar lista de bloqueo
dark: Oscuro
es: Castellano
en: English