From 9ce510223e224017eb9337549f73f86bf1303faa Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:37:37 -0300 Subject: [PATCH 001/227] =?UTF-8?q?feat:=20controladores=20e=20informaci?= =?UTF-8?q?=C3=B3n=20de=20prueba=20#14966?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moderation_queue_controller.rb | 375 ++++++++++++++++++ app/controllers/posts_controller.rb | 72 ++++ config/routes.rb | 4 + 3 files changed, 451 insertions(+) create mode 100644 app/controllers/moderation_queue_controller.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb new file mode 100644 index 00000000..1aef226f --- /dev/null +++ b/app/controllers/moderation_queue_controller.rb @@ -0,0 +1,375 @@ +# frozen_string_literal: true + +# Cola de moderación de ActivityPub +class ModerationQueueController < ApplicationController + # Cola de moderación viendo todo el sitio + def index + @moderation_queue = [ + +{"@context"=> + ["https://www.w3.org/ns/activitystreams", + {"ostatus"=>"http://ostatus.org#", + "atomUri"=>"ostatus:atomUri", + "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", + "conversation"=>"ostatus:conversation", + "sensitive"=>"as:sensitive", + "toot"=>"http://joinmastodon.org/ns#", + "votersCount"=>"toot:votersCount", + "Hashtag"=>"as:Hashtag"}], + "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "type"=>"Note", + "summary"=>nil, + "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "published"=>"2023-11-23T22:50:10Z", + "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", + "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], + "sensitive"=>false, + "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", + "content"=> + "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

", + "contentMap"=> + {"en"=> + "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

"}, + "attachment"=>[], + "tag"=> + [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], + "replies"=> + {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "type"=>"Collection", + "first"=> + {"type"=>"CollectionPage", + "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", + "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "items"=>[]}}}, +{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], + "type"=>"Note", + "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", + "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "published"=>"2023-12-04T21:53:05+00:00", + "updated"=>"2023-12-05T20:41:34+00:00", + "attributedTo"=>"https://sutty.nl/about.jsonld", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], + "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", + "sensitive"=>true, + "content"=> + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

Qué permite hacer

Qué se viene

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", + "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "contentMap"=> + {"es"=> + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

Qué permite hacer

Qué se viene

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n"}, + "attachment"=> + [{"type"=>"Document", + "mediaType"=>"image/png", + "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", + "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} + + + ] + end + + # Perfil remoto de usuarie + def remote_profile + @remote_profile = { + '@context' => + [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', + 'toot' => 'http://joinmastodon.org/ns#', + 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, + 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' }, + 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' }, + 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' }, + 'schema' => 'http://schema.org#', + 'PropertyValue' => 'schema:PropertyValue', + 'value' => 'schema:value', + 'discoverable' => 'toot:discoverable', + 'Device' => 'toot:Device', + 'Ed25519Signature' => 'toot:Ed25519Signature', + 'Ed25519Key' => 'toot:Ed25519Key', + 'Curve25519Key' => 'toot:Curve25519Key', + 'EncryptedMessage' => 'toot:EncryptedMessage', + 'publicKeyBase64' => 'toot:publicKeyBase64', + 'deviceId' => 'toot:deviceId', + 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, + 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, + 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, + 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, + 'messageFranking' => 'toot:messageFranking', + 'messageType' => 'toot:messageType', + 'cipherText' => 'toot:cipherText', + 'suspended' => 'toot:suspended', + 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } + } + ], + 'id' => 'https://mastodon.mauve.moe/users/mauve', + 'type' => 'Person', + 'following' => 'https://mastodon.mauve.moe/users/mauve/following', + 'followers' => 'https://mastodon.mauve.moe/users/mauve/followers', + 'inbox' => 'https://mastodon.mauve.moe/users/mauve/inbox', + 'outbox' => 'https://mastodon.mauve.moe/users/mauve/outbox', + 'featured' => 'https://mastodon.mauve.moe/users/mauve/collections/featured', + 'featuredTags' => 'https://mastodon.mauve.moe/users/mauve/collections/tags', + 'preferredUsername' => 'mauve', + 'name' => 'Mauve 👁💜', + 'summary' => + '

Occult Enby that's making local-first software with peer to peer protocols, mesh networks, and the web.

Also exploring what a local-first cyberspace might look like in my spare time.

', + 'url' => 'https://mastodon.mauve.moe/@mauve', + 'manuallyApprovesFollowers' => false, + 'discoverable' => true, + 'published' => '2022-04-25T00:00:00Z', + 'devices' => 'https://mastodon.mauve.moe/users/mauve/collections/devices', + 'alsoKnownAs' => ['https://infosec.exchange/users/RangerMauve'], + 'publicKey' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve#main-key', + 'owner' => 'https://mastodon.mauve.moe/users/mauve', + 'publicKeyPem' => + "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ\numIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng\n7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK\n75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq\nWUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D\nzAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf\nXwIDAQAB\n-----END PUBLIC KEY-----\n" }, + 'tag' => [], + 'attachment' => + [{ 'type' => 'PropertyValue', 'name' => 'Pronouns', 'value' => 'they/them/it' }, + { 'type' => 'PropertyValue', 'name' => 'Email', 'value' => 'mauve@mauve.moe' }, + { 'type' => 'PropertyValue', + 'name' => 'Matrix', + 'value' => + '@mauve:mauve.moe' }, + { 'type' => 'PropertyValue', 'name' => 'Github/Twitter', 'value' => '@RangerMauve' }], + 'endpoints' => { 'sharedInbox' => 'https://mastodon.mauve.moe/inbox' }, + 'icon' => + { 'type' => 'Image', + 'mediaType' => 'image/png', + 'url' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png' }, + 'image' => + { 'type' => 'Image', + 'mediaType' => 'image/png', + 'url' => 'https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png' } + } + end + + # todon.nl está usando /api/v2/instance + # mauve.moe usa /api/v1/instance + def instances + @instances = [ +{"domain"=>"todon.nl", + "title"=>"Todon.nl", + "version"=>"4.2.3", + "source_url"=>"https://github.com/mastodon/mastodon", + "description"=> + "Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.", + "usage"=>{"users"=>{"active_month"=>372}}, + "thumbnail"=> + {"url"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", + "blurhash"=>"UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE", + "versions"=> + {"@1x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", + "@2x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png"}}, + "languages"=>["en"], + "configuration"=> + {"urls"=>{"streaming"=>"wss://todon.nl", "status"=>"https://status.todon.eu"}, + "accounts"=>{"max_featured_tags"=>10}, + "statuses"=>{"max_characters"=>1312, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, + "media_attachments"=> + {"supported_mime_types"=> + ["image/jpeg", + "image/png", + "image/gif", + "image/heic", + "image/heif", + "image/webp", + "image/avif", + "video/webm", + "video/mp4", + "video/quicktime", + "video/ogg", + "audio/wave", + "audio/wav", + "audio/x-wav", + "audio/x-pn-wave", + "audio/vnd.wave", + "audio/ogg", + "audio/vorbis", + "audio/mpeg", + "audio/mp3", + "audio/webm", + "audio/flac", + "audio/aac", + "audio/m4a", + "audio/x-m4a", + "audio/mp4", + "audio/3gpp", + "video/x-ms-asf"], + "image_size_limit"=>16777216, + "image_matrix_limit"=>33177600, + "video_size_limit"=>103809024, + "video_frame_rate_limit"=>120, + "video_matrix_limit"=>8294400}, + "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}, + "translation"=>{"enabled"=>true}}, + "registrations"=> + {"enabled"=>false, + "approval_required"=>false, + "message"=> + "

¡No pasarán!

\n\n

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

\n\n\n\n

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

\n\n

It is temporary not possible to request on account on Todon.nl.

\n\n\n\n

Go to joinmastodon.org or FediDB Network to find another server.

\n", + "url"=>nil}, + "max_toot_chars"=>1312, + "contact"=> + {"email"=>"todon@posteo.eu", + "account"=> + {"id"=>"1", + "username"=>"admin", + "acct"=>"admin", + "display_name"=>"Admin 🤓 Todon.nl (mod)", + "locked"=>false, + "bot"=>false, + "discoverable"=>false, + "group"=>false, + "created_at"=>"2017-04-28T00:00:00.000Z", + "note"=> + "

This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

🚫 Don't follow this account when you are not on Todon.nl.

New? First read our 👩‍🏫 Todon 101 👩‍🎓 at https://wiki.todon.eu/todon/101

⚖️ For all our moderators go to https://wiki.todon.nl/todon/moderators

📝 Public toots from this account are in English.

🔕 Criticism is fine, but people who do false accusations are muted.

✉ todon@posteo.eu

#nobot

", + "url"=>"https://todon.nl/@admin", + "uri"=>"https://todon.nl/users/admin", + "avatar"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", + "avatar_static"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", + "header"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", + "header_static"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", + "followers_count"=>3164, + "following_count"=>8, + "statuses_count"=>724, + "last_status_at"=>"2024-01-12", + "noindex"=>true, + "emojis"=>[], + "roles"=>[{"id"=>"3", "name"=>"Admin", "color"=>"#595aff"}], + "fields"=> + [{"name"=>"📜 Terms of Service", + "value"=> + "https://wiki.todon.nl/todon/terms_en", + "verified_at"=>"2018-11-01T14:39:45.465+00:00"}, + {"name"=>"ℹ️ Wiki", + "value"=> + "https://wiki.todon.nl/todon/information", + "verified_at"=>"2018-11-01T14:40:54.679+00:00"}, + {"name"=>"📊 Status", + "value"=> + "https://status.todon.eu", + "verified_at"=>"2023-10-26T20:38:30.185+00:00"}, + {"name"=>"💳️ Donations", + "value"=> + "https://wiki.todon.eu/todon/donations", + "verified_at"=>"2022-11-02T00:06:31.865+00:00"}]}}, + "rules"=> + [{"id"=>"1", + "text"=> + "We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition)."}, + {"id"=>"2", + "text"=> + "We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc."}, + {"id"=>"4", "text"=>"Sexism, misogyny and hate against black women (misogynoir)."}, + {"id"=>"6", "text"=>"We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming."}, + {"id"=>"8", "text"=>"We do not accept harassment and trolling."}, + {"id"=>"10", "text"=>"We also do not accept other forms of hate speech."}, + {"id"=>"11", "text"=>"We do not accept (sexual) abuse of minors, adults and animals (also not virtual)."}, + {"id"=>"13", "text"=>"We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism."}, + {"id"=>"15", + "text"=> + "We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service)."}, + {"id"=>"16", "text"=>"We do not accept fascism, right-wing populism, and right-wing and religious extremism."}, + {"id"=>"17", + "text"=>"We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults."}, + {"id"=>"19", + "text"=> + "We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies)."}, + {"id"=>"20", "text"=>"We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals."}, + {"id"=>"21", + "text"=> + "We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy)."}, + {"id"=>"27", "text"=>"We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation."}, + {"id"=>"28", "text"=>"Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step."}]}, +{"uri"=>"mastodon.mauve.moe", + "title"=>"Mauvestodon", + "short_description"=>"Escape ship from centralized social media run by Mauve.", + "description"=>"Chat about random techie and anarchist stuff.", + "email"=>"contact@mauve.moe", + "version"=>"3.5.10", + "urls"=>{"streaming_api"=>"wss://mastodon.mauve.moe"}, + "stats"=>{"user_count"=>12, "status_count"=>3287, "domain_count"=>11625}, + "thumbnail"=>"https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png", + "languages"=>["en"], + "registrations"=>false, + "approval_required"=>false, + "invites_enabled"=>true, + "configuration"=> + {"statuses"=>{"max_characters"=>500, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, + "media_attachments"=> + {"supported_mime_types"=> + ["image/jpeg", + "image/png", + "image/gif", + "video/webm", + "video/mp4", + "video/quicktime", + "video/ogg", + "audio/wave", + "audio/wav", + "audio/x-wav", + "audio/x-pn-wave", + "audio/ogg", + "audio/vorbis", + "audio/mpeg", + "audio/mp3", + "audio/webm", + "audio/flac", + "audio/aac", + "audio/m4a", + "audio/x-m4a", + "audio/mp4", + "audio/3gpp", + "video/x-ms-asf"], + "image_size_limit"=>10485760, + "image_matrix_limit"=>16777216, + "video_size_limit"=>41943040, + "video_frame_rate_limit"=>60, + "video_matrix_limit"=>2304000}, + "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}}, + "contact_account"=> + {"id"=>"1", + "username"=>"admin", + "acct"=>"admin", + "display_name"=>"", + "locked"=>false, + "bot"=>false, + "discoverable"=>true, + "group"=>false, + "created_at"=>"2022-04-25T00:00:00.000Z", + "note"=>"", + "url"=>"https://mastodon.mauve.moe/@admin", + "avatar"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", + "avatar_static"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", + "header"=>"https://mastodon.mauve.moe/headers/original/missing.png", + "header_static"=>"https://mastodon.mauve.moe/headers/original/missing.png", + "followers_count"=>0, + "following_count"=>0, + "statuses_count"=>0, + "last_status_at"=>"2023-01-30", + "emojis"=>[], + "fields"=> + [{"name"=>"Alternatel Contact", + "value"=> + "@mauve", + "verified_at"=>nil}]}, + "rules"=>[]} + + + + ] + + end +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 057c3068..8b4d975f 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -81,6 +81,78 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' + + @moderation_queue = [ + +{"@context"=> + ["https://www.w3.org/ns/activitystreams", + {"ostatus"=>"http://ostatus.org#", + "atomUri"=>"ostatus:atomUri", + "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", + "conversation"=>"ostatus:conversation", + "sensitive"=>"as:sensitive", + "toot"=>"http://joinmastodon.org/ns#", + "votersCount"=>"toot:votersCount", + "Hashtag"=>"as:Hashtag"}], + "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "type"=>"Note", + "summary"=>nil, + "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "published"=>"2023-11-23T22:50:10Z", + "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", + "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], + "sensitive"=>false, + "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", + "content"=> + "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

", + "contentMap"=> + {"en"=> + "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

"}, + "attachment"=>[], + "tag"=> + [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], + "replies"=> + {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "type"=>"Collection", + "first"=> + {"type"=>"CollectionPage", + "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", + "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "items"=>[]}}}, +{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], + "type"=>"Note", + "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", + "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "published"=>"2023-12-04T21:53:05+00:00", + "updated"=>"2023-12-05T20:41:34+00:00", + "attributedTo"=>"https://sutty.nl/about.jsonld", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], + "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", + "sensitive"=>true, + "content"=> + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

Qué permite hacer

Qué se viene

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", + "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "contentMap"=> + {"es"=> + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

Qué permite hacer

Qué se viene

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n"}, + "attachment"=> + [{"type"=>"Document", + "mediaType"=>"image/png", + "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", + "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} + + + ] + + end def update diff --git a/config/routes.rb b/config/routes.rb index 635be07a..664a4ab3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -50,6 +50,10 @@ Rails.application.routes.draw do get 'collaborate', to: 'collaborations#collaborate' post 'collaborate', to: 'collaborations#accept_collaboration' + get 'moderation_queue', to: 'moderation_queue#index' + get 'remote_profile', to: 'moderation_queue#remote_profile' + get 'instances', to: 'moderation_queue#instances' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 6efae5f8f0448b68107e95092a15c8933c19c5b8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:37:56 -0300 Subject: [PATCH 002/227] feat: correr rubocop y haml-lint sobre los archivos --- Taskfile.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index c2d72472..735724f5 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -183,3 +183,15 @@ tasks: - "{{.HAINISH}} gem install bundler-audit" status: - "test -f ../hain/usr/bin/bundler-audit" + rubocop: + desc: "Ruby linting. Call with: go-task rubocop -- -A file.rb" + cmds: + - task: "bundle" + vars: + CLI_ARGS: "exec rubocop {{.CLI_ARGS}}" + haml-lint: + desc: "HAML linting. Call with: go-task haml-lint -- file.haml" + cmds: + - task: "bundle" + vars: + CLI_ARGS: "exec haml-lint {{.CLI_ARGS}}" From e20ef9dd21b75896849ee2279fc2fa2fc3043a2a Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:44:26 -0300 Subject: [PATCH 003/227] feat: no es necesario pasar los archivos como parametros --- .gitlab-ci.yml | 4 ++-- Taskfile.yaml | 12 ++++-------- bin/modified_files | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb2766d3..9718e770 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -85,7 +85,7 @@ rubocop: - *apk-add - *disable-hainish script: - - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" + - "go-task rubocop" haml: stage: "test" cache: @@ -96,4 +96,4 @@ haml: - *apk-add - *disable-hainish script: - - "./bin/modified_files | ./bin/with_extension haml | xargs -r go-task bundle -- exec haml-lint" + - "go-task haml-lint" diff --git a/Taskfile.yaml b/Taskfile.yaml index 735724f5..57fb0238 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -184,14 +184,10 @@ tasks: status: - "test -f ../hain/usr/bin/bundler-audit" rubocop: - desc: "Ruby linting. Call with: go-task rubocop -- -A file.rb" + desc: "Ruby linting" cmds: - - task: "bundle" - vars: - CLI_ARGS: "exec rubocop {{.CLI_ARGS}}" + - "./bin/modified_files | ./bin/with_extension rb | xargs -r {{.HAINISH}} bundle exec rubocop {{.CLI_ARGS}}" haml-lint: - desc: "HAML linting. Call with: go-task haml-lint -- file.haml" + desc: "HAML linting" cmds: - - task: "bundle" - vars: - CLI_ARGS: "exec haml-lint {{.CLI_ARGS}}" + - "./bin/modified_files | ./bin/with_extension haml | xargs -r {{.HAINISH}} bundle exec haml-lint {{.CLI_ARGS}}" diff --git a/bin/modified_files b/bin/modified_files index d26e71f3..4d06b4c5 100755 --- a/bin/modified_files +++ b/bin/modified_files @@ -1,7 +1,7 @@ #!/bin/sh set -e -test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" +CI_MERGE_REQUEST_DIFF_BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-origin/rails}" git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA} \ | grep -v "^D" \ From decbd2fb52a82f38dedf4e01f5e5d66075457115 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:44:49 -0300 Subject: [PATCH 004/227] chore: rubocop --- .../moderation_queue_controller.rb | 555 +++++++++--------- app/controllers/posts_controller.rb | 131 ++--- 2 files changed, 344 insertions(+), 342 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 1aef226f..6d58baf0 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,71 +6,70 @@ class ModerationQueueController < ApplicationController def index @moderation_queue = [ -{"@context"=> - ["https://www.w3.org/ns/activitystreams", - {"ostatus"=>"http://ostatus.org#", - "atomUri"=>"ostatus:atomUri", - "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", - "conversation"=>"ostatus:conversation", - "sensitive"=>"as:sensitive", - "toot"=>"http://joinmastodon.org/ns#", - "votersCount"=>"toot:votersCount", - "Hashtag"=>"as:Hashtag"}], - "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "type"=>"Note", - "summary"=>nil, - "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "published"=>"2023-11-23T22:50:10Z", - "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", - "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], - "sensitive"=>false, - "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", - "content"=> - "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

", - "contentMap"=> - {"en"=> - "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

"}, - "attachment"=>[], - "tag"=> - [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], - "replies"=> - {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "type"=>"Collection", - "first"=> - {"type"=>"CollectionPage", - "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", - "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "items"=>[]}}}, -{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], - "type"=>"Note", - "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", - "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "published"=>"2023-12-04T21:53:05+00:00", - "updated"=>"2023-12-05T20:41:34+00:00", - "attributedTo"=>"https://sutty.nl/about.jsonld", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], - "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", - "sensitive"=>true, - "content"=> - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", - "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "contentMap"=> - {"es"=> - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n"}, - "attachment"=> - [{"type"=>"Document", - "mediaType"=>"image/png", - "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", - "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} - + { '@context' => + ['https://www.w3.org/ns/activitystreams', + { 'ostatus' => 'http://ostatus.org#', + 'atomUri' => 'ostatus:atomUri', + 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', + 'conversation' => 'ostatus:conversation', + 'sensitive' => 'as:sensitive', + 'toot' => 'http://joinmastodon.org/ns#', + 'votersCount' => 'toot:votersCount', + 'Hashtag' => 'as:Hashtag' }], + 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'type' => 'Note', + 'summary' => nil, + 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'published' => '2023-11-23T22:50:10Z', + 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', + 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], + 'sensitive' => false, + 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', + 'content' => + '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

', + 'contentMap' => + { 'en' => + '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

' }, + 'attachment' => [], + 'tag' => + [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], + 'replies' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'type' => 'Collection', + 'first' => + { 'type' => 'CollectionPage', + 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', + 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'items' => [] } } }, + { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], + 'type' => 'Note', + 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', + 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'published' => '2023-12-04T21:53:05+00:00', + 'updated' => '2023-12-05T20:41:34+00:00', + 'attributedTo' => 'https://sutty.nl/about.jsonld', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], + 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', + 'sensitive' => true, + 'content' => + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", + 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'contentMap' => + { 'es' => + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n" }, + 'attachment' => + [{ 'type' => 'Document', + 'mediaType' => 'image/png', + 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', + 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } ] end @@ -159,217 +158,223 @@ class ModerationQueueController < ApplicationController # mauve.moe usa /api/v1/instance def instances @instances = [ -{"domain"=>"todon.nl", - "title"=>"Todon.nl", - "version"=>"4.2.3", - "source_url"=>"https://github.com/mastodon/mastodon", - "description"=> - "Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.", - "usage"=>{"users"=>{"active_month"=>372}}, - "thumbnail"=> - {"url"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", - "blurhash"=>"UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE", - "versions"=> - {"@1x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", - "@2x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png"}}, - "languages"=>["en"], - "configuration"=> - {"urls"=>{"streaming"=>"wss://todon.nl", "status"=>"https://status.todon.eu"}, - "accounts"=>{"max_featured_tags"=>10}, - "statuses"=>{"max_characters"=>1312, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, - "media_attachments"=> - {"supported_mime_types"=> - ["image/jpeg", - "image/png", - "image/gif", - "image/heic", - "image/heif", - "image/webp", - "image/avif", - "video/webm", - "video/mp4", - "video/quicktime", - "video/ogg", - "audio/wave", - "audio/wav", - "audio/x-wav", - "audio/x-pn-wave", - "audio/vnd.wave", - "audio/ogg", - "audio/vorbis", - "audio/mpeg", - "audio/mp3", - "audio/webm", - "audio/flac", - "audio/aac", - "audio/m4a", - "audio/x-m4a", - "audio/mp4", - "audio/3gpp", - "video/x-ms-asf"], - "image_size_limit"=>16777216, - "image_matrix_limit"=>33177600, - "video_size_limit"=>103809024, - "video_frame_rate_limit"=>120, - "video_matrix_limit"=>8294400}, - "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}, - "translation"=>{"enabled"=>true}}, - "registrations"=> - {"enabled"=>false, - "approval_required"=>false, - "message"=> - "

¡No pasarán!

\n\n

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

\n\n\n\n

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

\n\n

It is temporary not possible to request on account on Todon.nl.

\n\n\n\n

Go to joinmastodon.org or FediDB Network to find another server.

\n", - "url"=>nil}, - "max_toot_chars"=>1312, - "contact"=> - {"email"=>"todon@posteo.eu", - "account"=> - {"id"=>"1", - "username"=>"admin", - "acct"=>"admin", - "display_name"=>"Admin 🤓 Todon.nl (mod)", - "locked"=>false, - "bot"=>false, - "discoverable"=>false, - "group"=>false, - "created_at"=>"2017-04-28T00:00:00.000Z", - "note"=> - "

This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

🚫 Don't follow this account when you are not on Todon.nl.

New? First read our 👩‍🏫 Todon 101 👩‍🎓 at https://wiki.todon.eu/todon/101

⚖️ For all our moderators go to https://wiki.todon.nl/todon/moderators

📝 Public toots from this account are in English.

🔕 Criticism is fine, but people who do false accusations are muted.

✉ todon@posteo.eu

#nobot

", - "url"=>"https://todon.nl/@admin", - "uri"=>"https://todon.nl/users/admin", - "avatar"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", - "avatar_static"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", - "header"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", - "header_static"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", - "followers_count"=>3164, - "following_count"=>8, - "statuses_count"=>724, - "last_status_at"=>"2024-01-12", - "noindex"=>true, - "emojis"=>[], - "roles"=>[{"id"=>"3", "name"=>"Admin", "color"=>"#595aff"}], - "fields"=> - [{"name"=>"📜 Terms of Service", - "value"=> - "https://wiki.todon.nl/todon/terms_en", - "verified_at"=>"2018-11-01T14:39:45.465+00:00"}, - {"name"=>"ℹ️ Wiki", - "value"=> - "https://wiki.todon.nl/todon/information", - "verified_at"=>"2018-11-01T14:40:54.679+00:00"}, - {"name"=>"📊 Status", - "value"=> - "https://status.todon.eu", - "verified_at"=>"2023-10-26T20:38:30.185+00:00"}, - {"name"=>"💳️ Donations", - "value"=> - "https://wiki.todon.eu/todon/donations", - "verified_at"=>"2022-11-02T00:06:31.865+00:00"}]}}, - "rules"=> - [{"id"=>"1", - "text"=> - "We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition)."}, - {"id"=>"2", - "text"=> - "We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc."}, - {"id"=>"4", "text"=>"Sexism, misogyny and hate against black women (misogynoir)."}, - {"id"=>"6", "text"=>"We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming."}, - {"id"=>"8", "text"=>"We do not accept harassment and trolling."}, - {"id"=>"10", "text"=>"We also do not accept other forms of hate speech."}, - {"id"=>"11", "text"=>"We do not accept (sexual) abuse of minors, adults and animals (also not virtual)."}, - {"id"=>"13", "text"=>"We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism."}, - {"id"=>"15", - "text"=> - "We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service)."}, - {"id"=>"16", "text"=>"We do not accept fascism, right-wing populism, and right-wing and religious extremism."}, - {"id"=>"17", - "text"=>"We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults."}, - {"id"=>"19", - "text"=> - "We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies)."}, - {"id"=>"20", "text"=>"We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals."}, - {"id"=>"21", - "text"=> - "We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy)."}, - {"id"=>"27", "text"=>"We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation."}, - {"id"=>"28", "text"=>"Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step."}]}, -{"uri"=>"mastodon.mauve.moe", - "title"=>"Mauvestodon", - "short_description"=>"Escape ship from centralized social media run by Mauve.", - "description"=>"Chat about random techie and anarchist stuff.", - "email"=>"contact@mauve.moe", - "version"=>"3.5.10", - "urls"=>{"streaming_api"=>"wss://mastodon.mauve.moe"}, - "stats"=>{"user_count"=>12, "status_count"=>3287, "domain_count"=>11625}, - "thumbnail"=>"https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png", - "languages"=>["en"], - "registrations"=>false, - "approval_required"=>false, - "invites_enabled"=>true, - "configuration"=> - {"statuses"=>{"max_characters"=>500, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, - "media_attachments"=> - {"supported_mime_types"=> - ["image/jpeg", - "image/png", - "image/gif", - "video/webm", - "video/mp4", - "video/quicktime", - "video/ogg", - "audio/wave", - "audio/wav", - "audio/x-wav", - "audio/x-pn-wave", - "audio/ogg", - "audio/vorbis", - "audio/mpeg", - "audio/mp3", - "audio/webm", - "audio/flac", - "audio/aac", - "audio/m4a", - "audio/x-m4a", - "audio/mp4", - "audio/3gpp", - "video/x-ms-asf"], - "image_size_limit"=>10485760, - "image_matrix_limit"=>16777216, - "video_size_limit"=>41943040, - "video_frame_rate_limit"=>60, - "video_matrix_limit"=>2304000}, - "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}}, - "contact_account"=> - {"id"=>"1", - "username"=>"admin", - "acct"=>"admin", - "display_name"=>"", - "locked"=>false, - "bot"=>false, - "discoverable"=>true, - "group"=>false, - "created_at"=>"2022-04-25T00:00:00.000Z", - "note"=>"", - "url"=>"https://mastodon.mauve.moe/@admin", - "avatar"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", - "avatar_static"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", - "header"=>"https://mastodon.mauve.moe/headers/original/missing.png", - "header_static"=>"https://mastodon.mauve.moe/headers/original/missing.png", - "followers_count"=>0, - "following_count"=>0, - "statuses_count"=>0, - "last_status_at"=>"2023-01-30", - "emojis"=>[], - "fields"=> - [{"name"=>"Alternatel Contact", - "value"=> - "@mauve", - "verified_at"=>nil}]}, - "rules"=>[]} - - + { 'domain' => 'todon.nl', + 'title' => 'Todon.nl', + 'version' => '4.2.3', + 'source_url' => 'https://github.com/mastodon/mastodon', + 'description' => + 'Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.', + 'usage' => { 'users' => { 'active_month' => 372 } }, + 'thumbnail' => + { 'url' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', + 'blurhash' => 'UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE', + 'versions' => + { '@1x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', + '@2x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png' } }, + 'languages' => ['en'], + 'configuration' => + { 'urls' => { 'streaming' => 'wss://todon.nl', 'status' => 'https://status.todon.eu' }, + 'accounts' => { 'max_featured_tags' => 10 }, + 'statuses' => { 'max_characters' => 1312, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, + 'media_attachments' => + { 'supported_mime_types' => + ['image/jpeg', + 'image/png', + 'image/gif', + 'image/heic', + 'image/heif', + 'image/webp', + 'image/avif', + 'video/webm', + 'video/mp4', + 'video/quicktime', + 'video/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wave', + 'audio/vnd.wave', + 'audio/ogg', + 'audio/vorbis', + 'audio/mpeg', + 'audio/mp3', + 'audio/webm', + 'audio/flac', + 'audio/aac', + 'audio/m4a', + 'audio/x-m4a', + 'audio/mp4', + 'audio/3gpp', + 'video/x-ms-asf'], + 'image_size_limit' => 16_777_216, + 'image_matrix_limit' => 33_177_600, + 'video_size_limit' => 103_809_024, + 'video_frame_rate_limit' => 120, + 'video_matrix_limit' => 8_294_400 }, + 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, + 'max_expiration' => 2_629_746 }, + 'translation' => { 'enabled' => true } }, + 'registrations' => + { 'enabled' => false, + 'approval_required' => false, + 'message' => + "

¡No pasarán!

\n\n

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

\n\n\n\n

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

\n\n

It is temporary not possible to request on account on Todon.nl.

\n\n\n\n

Go to joinmastodon.org or FediDB Network to find another server.

\n", + 'url' => nil }, + 'max_toot_chars' => 1312, + 'contact' => + { 'email' => 'todon@posteo.eu', + 'account' => + { 'id' => '1', + 'username' => 'admin', + 'acct' => 'admin', + 'display_name' => 'Admin 🤓 Todon.nl (mod)', + 'locked' => false, + 'bot' => false, + 'discoverable' => false, + 'group' => false, + 'created_at' => '2017-04-28T00:00:00.000Z', + 'note' => + '

This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

🚫 Don't follow this account when you are not on Todon.nl.

New? First read our 👩‍🏫 Todon 101 👩‍🎓 at wiki.todon.eu/todon/101

⚖️ For all our moderators go to wiki.todon.nl/todon/moderators

📝 Public toots from this account are in English.

🔕 Criticism is fine, but people who do false accusations are muted.

✉ todon@posteo.eu

', + 'url' => 'https://todon.nl/@admin', + 'uri' => 'https://todon.nl/users/admin', + 'avatar' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', + 'avatar_static' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', + 'header' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', + 'header_static' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', + 'followers_count' => 3164, + 'following_count' => 8, + 'statuses_count' => 724, + 'last_status_at' => '2024-01-12', + 'noindex' => true, + 'emojis' => [], + 'roles' => [{ 'id' => '3', 'name' => 'Admin', 'color' => '#595aff' }], + 'fields' => + [{ 'name' => '📜 Terms of Service', + 'value' => + 'wiki.todon.nl/todon/terms_en', + 'verified_at' => '2018-11-01T14:39:45.465+00:00' }, + { 'name' => 'ℹ️ Wiki', + 'value' => + 'wiki.todon.nl/todon/informatio', + 'verified_at' => '2018-11-01T14:40:54.679+00:00' }, + { 'name' => '📊 Status', + 'value' => + 'status.todon.eu', + 'verified_at' => '2023-10-26T20:38:30.185+00:00' }, + { 'name' => '💳️ Donations', + 'value' => + 'wiki.todon.eu/todon/donations', + 'verified_at' => '2022-11-02T00:06:31.865+00:00' }] } }, + 'rules' => + [{ 'id' => '1', + 'text' => + 'We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition).' }, + { 'id' => '2', + 'text' => + 'We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc.' }, + { 'id' => '4', 'text' => 'Sexism, misogyny and hate against black women (misogynoir).' }, + { 'id' => '6', + 'text' => 'We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming.' }, + { 'id' => '8', 'text' => 'We do not accept harassment and trolling.' }, + { 'id' => '10', 'text' => 'We also do not accept other forms of hate speech.' }, + { 'id' => '11', + 'text' => 'We do not accept (sexual) abuse of minors, adults and animals (also not virtual).' }, + { 'id' => '13', + 'text' => 'We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism.' }, + { 'id' => '15', + 'text' => + 'We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service).' }, + { 'id' => '16', + 'text' => 'We do not accept fascism, right-wing populism, and right-wing and religious extremism.' }, + { 'id' => '17', + 'text' => 'We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults.' }, + { 'id' => '19', + 'text' => + 'We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies).' }, + { 'id' => '20', + 'text' => "We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals." }, + { 'id' => '21', + 'text' => + 'We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy).' }, + { 'id' => '27', + 'text' => "We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation." }, + { 'id' => '28', + 'text' => 'Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step.' }] }, + { 'uri' => 'mastodon.mauve.moe', + 'title' => 'Mauvestodon', + 'short_description' => 'Escape ship from centralized social media run by Mauve.', + 'description' => 'Chat about random techie and anarchist stuff.', + 'email' => 'contact@mauve.moe', + 'version' => '3.5.10', + 'urls' => { 'streaming_api' => 'wss://mastodon.mauve.moe' }, + 'stats' => { 'user_count' => 12, 'status_count' => 3287, 'domain_count' => 11_625 }, + 'thumbnail' => 'https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png', + 'languages' => ['en'], + 'registrations' => false, + 'approval_required' => false, + 'invites_enabled' => true, + 'configuration' => + { 'statuses' => { 'max_characters' => 500, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, + 'media_attachments' => + { 'supported_mime_types' => + ['image/jpeg', + 'image/png', + 'image/gif', + 'video/webm', + 'video/mp4', + 'video/quicktime', + 'video/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wave', + 'audio/ogg', + 'audio/vorbis', + 'audio/mpeg', + 'audio/mp3', + 'audio/webm', + 'audio/flac', + 'audio/aac', + 'audio/m4a', + 'audio/x-m4a', + 'audio/mp4', + 'audio/3gpp', + 'video/x-ms-asf'], + 'image_size_limit' => 10_485_760, + 'image_matrix_limit' => 16_777_216, + 'video_size_limit' => 41_943_040, + 'video_frame_rate_limit' => 60, + 'video_matrix_limit' => 2_304_000 }, + 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, + 'max_expiration' => 2_629_746 } }, + 'contact_account' => + { 'id' => '1', + 'username' => 'admin', + 'acct' => 'admin', + 'display_name' => '', + 'locked' => false, + 'bot' => false, + 'discoverable' => true, + 'group' => false, + 'created_at' => '2022-04-25T00:00:00.000Z', + 'note' => '', + 'url' => 'https://mastodon.mauve.moe/@admin', + 'avatar' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', + 'avatar_static' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', + 'header' => 'https://mastodon.mauve.moe/headers/original/missing.png', + 'header_static' => 'https://mastodon.mauve.moe/headers/original/missing.png', + 'followers_count' => 0, + 'following_count' => 0, + 'statuses_count' => 0, + 'last_status_at' => '2023-01-30', + 'emojis' => [], + 'fields' => + [{ 'name' => 'Alternatel Contact', + 'value' => + '@mauve', + 'verified_at' => nil }] }, + 'rules' => [] } ] - end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 8b4d975f..1bc94ec1 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -84,75 +84,72 @@ class PostsController < ApplicationController @moderation_queue = [ -{"@context"=> - ["https://www.w3.org/ns/activitystreams", - {"ostatus"=>"http://ostatus.org#", - "atomUri"=>"ostatus:atomUri", - "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", - "conversation"=>"ostatus:conversation", - "sensitive"=>"as:sensitive", - "toot"=>"http://joinmastodon.org/ns#", - "votersCount"=>"toot:votersCount", - "Hashtag"=>"as:Hashtag"}], - "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "type"=>"Note", - "summary"=>nil, - "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "published"=>"2023-11-23T22:50:10Z", - "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", - "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], - "sensitive"=>false, - "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", - "content"=> - "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

", - "contentMap"=> - {"en"=> - "

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

#P2P #ActivityPub #Fediverse

"}, - "attachment"=>[], - "tag"=> - [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], - "replies"=> - {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "type"=>"Collection", - "first"=> - {"type"=>"CollectionPage", - "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", - "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "items"=>[]}}}, -{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], - "type"=>"Note", - "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", - "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "published"=>"2023-12-04T21:53:05+00:00", - "updated"=>"2023-12-05T20:41:34+00:00", - "attributedTo"=>"https://sutty.nl/about.jsonld", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], - "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", - "sensitive"=>true, - "content"=> - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", - "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "contentMap"=> - {"es"=> - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n"}, - "attachment"=> - [{"type"=>"Document", - "mediaType"=>"image/png", - "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", - "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} - + { '@context' => + ['https://www.w3.org/ns/activitystreams', + { 'ostatus' => 'http://ostatus.org#', + 'atomUri' => 'ostatus:atomUri', + 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', + 'conversation' => 'ostatus:conversation', + 'sensitive' => 'as:sensitive', + 'toot' => 'http://joinmastodon.org/ns#', + 'votersCount' => 'toot:votersCount', + 'Hashtag' => 'as:Hashtag' }], + 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'type' => 'Note', + 'summary' => nil, + 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'published' => '2023-11-23T22:50:10Z', + 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', + 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], + 'sensitive' => false, + 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', + 'content' => + '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

', + 'contentMap' => + { 'en' => + '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

' }, + 'attachment' => [], + 'tag' => + [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], + 'replies' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'type' => 'Collection', + 'first' => + { 'type' => 'CollectionPage', + 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', + 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'items' => [] } } }, + { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], + 'type' => 'Note', + 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', + 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'published' => '2023-12-04T21:53:05+00:00', + 'updated' => '2023-12-05T20:41:34+00:00', + 'attributedTo' => 'https://sutty.nl/about.jsonld', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], + 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', + 'sensitive' => true, + 'content' => + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", + 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'contentMap' => + { 'es' => + "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n" }, + 'attachment' => + [{ 'type' => 'Document', + 'mediaType' => 'image/png', + 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', + 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } ] - - end def update From 2a2878e4696645aee6c22e2d9301cd69a614db39 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:55:15 -0300 Subject: [PATCH 005/227] =?UTF-8?q?refactor:=20cargar=20los=20datos=20desd?= =?UTF-8?q?e=20archivos=20m=C3=A1s=20legibles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moderation_queue_controller.rb | 366 +----------------- app/controllers/posts_controller.rb | 70 +--- db/seeds/instances.yaml | 285 ++++++++++++++ db/seeds/moderation_queue.yaml | 153 ++++++++ db/seeds/remote_profile.yaml | 106 +++++ 5 files changed, 548 insertions(+), 432 deletions(-) create mode 100644 db/seeds/instances.yaml create mode 100644 db/seeds/moderation_queue.yaml create mode 100644 db/seeds/remote_profile.yaml diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 6d58baf0..eb39dae6 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,377 +4,17 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - @moderation_queue = [ - - { '@context' => - ['https://www.w3.org/ns/activitystreams', - { 'ostatus' => 'http://ostatus.org#', - 'atomUri' => 'ostatus:atomUri', - 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', - 'conversation' => 'ostatus:conversation', - 'sensitive' => 'as:sensitive', - 'toot' => 'http://joinmastodon.org/ns#', - 'votersCount' => 'toot:votersCount', - 'Hashtag' => 'as:Hashtag' }], - 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'type' => 'Note', - 'summary' => nil, - 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'published' => '2023-11-23T22:50:10Z', - 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', - 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], - 'sensitive' => false, - 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', - 'content' => - '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

', - 'contentMap' => - { 'en' => - '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

' }, - 'attachment' => [], - 'tag' => - [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], - 'replies' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'type' => 'Collection', - 'first' => - { 'type' => 'CollectionPage', - 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', - 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'items' => [] } } }, - { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], - 'type' => 'Note', - 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', - 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'published' => '2023-12-04T21:53:05+00:00', - 'updated' => '2023-12-05T20:41:34+00:00', - 'attributedTo' => 'https://sutty.nl/about.jsonld', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], - 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', - 'sensitive' => true, - 'content' => - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", - 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'contentMap' => - { 'es' => - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n" }, - 'attachment' => - [{ 'type' => 'Document', - 'mediaType' => 'image/png', - 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', - 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } - - ] + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end # Perfil remoto de usuarie def remote_profile - @remote_profile = { - '@context' => - [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1', - { - 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', - 'toot' => 'http://joinmastodon.org/ns#', - 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, - 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' }, - 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' }, - 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' }, - 'schema' => 'http://schema.org#', - 'PropertyValue' => 'schema:PropertyValue', - 'value' => 'schema:value', - 'discoverable' => 'toot:discoverable', - 'Device' => 'toot:Device', - 'Ed25519Signature' => 'toot:Ed25519Signature', - 'Ed25519Key' => 'toot:Ed25519Key', - 'Curve25519Key' => 'toot:Curve25519Key', - 'EncryptedMessage' => 'toot:EncryptedMessage', - 'publicKeyBase64' => 'toot:publicKeyBase64', - 'deviceId' => 'toot:deviceId', - 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, - 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, - 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, - 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, - 'messageFranking' => 'toot:messageFranking', - 'messageType' => 'toot:messageType', - 'cipherText' => 'toot:cipherText', - 'suspended' => 'toot:suspended', - 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } - } - ], - 'id' => 'https://mastodon.mauve.moe/users/mauve', - 'type' => 'Person', - 'following' => 'https://mastodon.mauve.moe/users/mauve/following', - 'followers' => 'https://mastodon.mauve.moe/users/mauve/followers', - 'inbox' => 'https://mastodon.mauve.moe/users/mauve/inbox', - 'outbox' => 'https://mastodon.mauve.moe/users/mauve/outbox', - 'featured' => 'https://mastodon.mauve.moe/users/mauve/collections/featured', - 'featuredTags' => 'https://mastodon.mauve.moe/users/mauve/collections/tags', - 'preferredUsername' => 'mauve', - 'name' => 'Mauve 👁💜', - 'summary' => - '

Occult Enby that's making local-first software with peer to peer protocols, mesh networks, and the web.

Also exploring what a local-first cyberspace might look like in my spare time.

', - 'url' => 'https://mastodon.mauve.moe/@mauve', - 'manuallyApprovesFollowers' => false, - 'discoverable' => true, - 'published' => '2022-04-25T00:00:00Z', - 'devices' => 'https://mastodon.mauve.moe/users/mauve/collections/devices', - 'alsoKnownAs' => ['https://infosec.exchange/users/RangerMauve'], - 'publicKey' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve#main-key', - 'owner' => 'https://mastodon.mauve.moe/users/mauve', - 'publicKeyPem' => - "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ\numIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng\n7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK\n75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq\nWUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D\nzAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf\nXwIDAQAB\n-----END PUBLIC KEY-----\n" }, - 'tag' => [], - 'attachment' => - [{ 'type' => 'PropertyValue', 'name' => 'Pronouns', 'value' => 'they/them/it' }, - { 'type' => 'PropertyValue', 'name' => 'Email', 'value' => 'mauve@mauve.moe' }, - { 'type' => 'PropertyValue', - 'name' => 'Matrix', - 'value' => - '@mauve:mauve.moe' }, - { 'type' => 'PropertyValue', 'name' => 'Github/Twitter', 'value' => '@RangerMauve' }], - 'endpoints' => { 'sharedInbox' => 'https://mastodon.mauve.moe/inbox' }, - 'icon' => - { 'type' => 'Image', - 'mediaType' => 'image/png', - 'url' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png' }, - 'image' => - { 'type' => 'Image', - 'mediaType' => 'image/png', - 'url' => 'https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png' } - } + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances - @instances = [ - { 'domain' => 'todon.nl', - 'title' => 'Todon.nl', - 'version' => '4.2.3', - 'source_url' => 'https://github.com/mastodon/mastodon', - 'description' => - 'Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.', - 'usage' => { 'users' => { 'active_month' => 372 } }, - 'thumbnail' => - { 'url' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', - 'blurhash' => 'UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE', - 'versions' => - { '@1x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', - '@2x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png' } }, - 'languages' => ['en'], - 'configuration' => - { 'urls' => { 'streaming' => 'wss://todon.nl', 'status' => 'https://status.todon.eu' }, - 'accounts' => { 'max_featured_tags' => 10 }, - 'statuses' => { 'max_characters' => 1312, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, - 'media_attachments' => - { 'supported_mime_types' => - ['image/jpeg', - 'image/png', - 'image/gif', - 'image/heic', - 'image/heif', - 'image/webp', - 'image/avif', - 'video/webm', - 'video/mp4', - 'video/quicktime', - 'video/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wave', - 'audio/vnd.wave', - 'audio/ogg', - 'audio/vorbis', - 'audio/mpeg', - 'audio/mp3', - 'audio/webm', - 'audio/flac', - 'audio/aac', - 'audio/m4a', - 'audio/x-m4a', - 'audio/mp4', - 'audio/3gpp', - 'video/x-ms-asf'], - 'image_size_limit' => 16_777_216, - 'image_matrix_limit' => 33_177_600, - 'video_size_limit' => 103_809_024, - 'video_frame_rate_limit' => 120, - 'video_matrix_limit' => 8_294_400 }, - 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, - 'max_expiration' => 2_629_746 }, - 'translation' => { 'enabled' => true } }, - 'registrations' => - { 'enabled' => false, - 'approval_required' => false, - 'message' => - "

¡No pasarán!

\n\n

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

\n\n\n\n

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

\n\n

It is temporary not possible to request on account on Todon.nl.

\n\n\n\n

Go to joinmastodon.org or FediDB Network to find another server.

\n", - 'url' => nil }, - 'max_toot_chars' => 1312, - 'contact' => - { 'email' => 'todon@posteo.eu', - 'account' => - { 'id' => '1', - 'username' => 'admin', - 'acct' => 'admin', - 'display_name' => 'Admin 🤓 Todon.nl (mod)', - 'locked' => false, - 'bot' => false, - 'discoverable' => false, - 'group' => false, - 'created_at' => '2017-04-28T00:00:00.000Z', - 'note' => - '

This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

🚫 Don't follow this account when you are not on Todon.nl.

New? First read our 👩‍🏫 Todon 101 👩‍🎓 at wiki.todon.eu/todon/101

⚖️ For all our moderators go to wiki.todon.nl/todon/moderators

📝 Public toots from this account are in English.

🔕 Criticism is fine, but people who do false accusations are muted.

✉ todon@posteo.eu

', - 'url' => 'https://todon.nl/@admin', - 'uri' => 'https://todon.nl/users/admin', - 'avatar' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', - 'avatar_static' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', - 'header' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', - 'header_static' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', - 'followers_count' => 3164, - 'following_count' => 8, - 'statuses_count' => 724, - 'last_status_at' => '2024-01-12', - 'noindex' => true, - 'emojis' => [], - 'roles' => [{ 'id' => '3', 'name' => 'Admin', 'color' => '#595aff' }], - 'fields' => - [{ 'name' => '📜 Terms of Service', - 'value' => - 'wiki.todon.nl/todon/terms_en', - 'verified_at' => '2018-11-01T14:39:45.465+00:00' }, - { 'name' => 'ℹ️ Wiki', - 'value' => - 'wiki.todon.nl/todon/informatio', - 'verified_at' => '2018-11-01T14:40:54.679+00:00' }, - { 'name' => '📊 Status', - 'value' => - 'status.todon.eu', - 'verified_at' => '2023-10-26T20:38:30.185+00:00' }, - { 'name' => '💳️ Donations', - 'value' => - 'wiki.todon.eu/todon/donations', - 'verified_at' => '2022-11-02T00:06:31.865+00:00' }] } }, - 'rules' => - [{ 'id' => '1', - 'text' => - 'We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition).' }, - { 'id' => '2', - 'text' => - 'We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc.' }, - { 'id' => '4', 'text' => 'Sexism, misogyny and hate against black women (misogynoir).' }, - { 'id' => '6', - 'text' => 'We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming.' }, - { 'id' => '8', 'text' => 'We do not accept harassment and trolling.' }, - { 'id' => '10', 'text' => 'We also do not accept other forms of hate speech.' }, - { 'id' => '11', - 'text' => 'We do not accept (sexual) abuse of minors, adults and animals (also not virtual).' }, - { 'id' => '13', - 'text' => 'We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism.' }, - { 'id' => '15', - 'text' => - 'We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service).' }, - { 'id' => '16', - 'text' => 'We do not accept fascism, right-wing populism, and right-wing and religious extremism.' }, - { 'id' => '17', - 'text' => 'We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults.' }, - { 'id' => '19', - 'text' => - 'We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies).' }, - { 'id' => '20', - 'text' => "We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals." }, - { 'id' => '21', - 'text' => - 'We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy).' }, - { 'id' => '27', - 'text' => "We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation." }, - { 'id' => '28', - 'text' => 'Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step.' }] }, - { 'uri' => 'mastodon.mauve.moe', - 'title' => 'Mauvestodon', - 'short_description' => 'Escape ship from centralized social media run by Mauve.', - 'description' => 'Chat about random techie and anarchist stuff.', - 'email' => 'contact@mauve.moe', - 'version' => '3.5.10', - 'urls' => { 'streaming_api' => 'wss://mastodon.mauve.moe' }, - 'stats' => { 'user_count' => 12, 'status_count' => 3287, 'domain_count' => 11_625 }, - 'thumbnail' => 'https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png', - 'languages' => ['en'], - 'registrations' => false, - 'approval_required' => false, - 'invites_enabled' => true, - 'configuration' => - { 'statuses' => { 'max_characters' => 500, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, - 'media_attachments' => - { 'supported_mime_types' => - ['image/jpeg', - 'image/png', - 'image/gif', - 'video/webm', - 'video/mp4', - 'video/quicktime', - 'video/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wave', - 'audio/ogg', - 'audio/vorbis', - 'audio/mpeg', - 'audio/mp3', - 'audio/webm', - 'audio/flac', - 'audio/aac', - 'audio/m4a', - 'audio/x-m4a', - 'audio/mp4', - 'audio/3gpp', - 'video/x-ms-asf'], - 'image_size_limit' => 10_485_760, - 'image_matrix_limit' => 16_777_216, - 'video_size_limit' => 41_943_040, - 'video_frame_rate_limit' => 60, - 'video_matrix_limit' => 2_304_000 }, - 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, - 'max_expiration' => 2_629_746 } }, - 'contact_account' => - { 'id' => '1', - 'username' => 'admin', - 'acct' => 'admin', - 'display_name' => '', - 'locked' => false, - 'bot' => false, - 'discoverable' => true, - 'group' => false, - 'created_at' => '2022-04-25T00:00:00.000Z', - 'note' => '', - 'url' => 'https://mastodon.mauve.moe/@admin', - 'avatar' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', - 'avatar_static' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', - 'header' => 'https://mastodon.mauve.moe/headers/original/missing.png', - 'header_static' => 'https://mastodon.mauve.moe/headers/original/missing.png', - 'followers_count' => 0, - 'following_count' => 0, - 'statuses_count' => 0, - 'last_status_at' => '2023-01-30', - 'emojis' => [], - 'fields' => - [{ 'name' => 'Alternatel Contact', - 'value' => - '@mauve', - 'verified_at' => nil }] }, - 'rules' => [] } - - ] + @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 1bc94ec1..d572e052 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -38,6 +38,7 @@ class PostsController < ApplicationController @usuarie = site.usuarie? current_usuarie @site_stat = SiteStat.new(site) + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end def show @@ -81,75 +82,6 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' - - @moderation_queue = [ - - { '@context' => - ['https://www.w3.org/ns/activitystreams', - { 'ostatus' => 'http://ostatus.org#', - 'atomUri' => 'ostatus:atomUri', - 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', - 'conversation' => 'ostatus:conversation', - 'sensitive' => 'as:sensitive', - 'toot' => 'http://joinmastodon.org/ns#', - 'votersCount' => 'toot:votersCount', - 'Hashtag' => 'as:Hashtag' }], - 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'type' => 'Note', - 'summary' => nil, - 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'published' => '2023-11-23T22:50:10Z', - 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', - 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], - 'sensitive' => false, - 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', - 'content' => - '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

', - 'contentMap' => - { 'en' => - '

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

' }, - 'attachment' => [], - 'tag' => - [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], - 'replies' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'type' => 'Collection', - 'first' => - { 'type' => 'CollectionPage', - 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', - 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'items' => [] } } }, - { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], - 'type' => 'Note', - 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', - 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'published' => '2023-12-04T21:53:05+00:00', - 'updated' => '2023-12-05T20:41:34+00:00', - 'attributedTo' => 'https://sutty.nl/about.jsonld', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], - 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', - 'sensitive' => true, - 'content' => - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n", - 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'contentMap' => - { 'es' => - "

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    \n
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. \n
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. \n

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    \n
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • \n
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • \n
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • \n
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • \n
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • \n
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • \n

Qué permite hacer

    \n
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • \n
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • \n
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • \n
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • \n
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • \n

Qué se viene

    \n
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • \n
  • Incorporación de menciones desde el panel de Sutty.

  • \n
  • Mejoras en la interfaz general del panel.

  • \n
  • Nuevas implementaciones para una mejor moderación.

  • \n
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • \n
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • \n
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • \n
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • \n
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • \n
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • \n

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

\n" }, - 'attachment' => - [{ 'type' => 'Document', - 'mediaType' => 'image/png', - 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', - 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } - - ] end def update diff --git a/db/seeds/instances.yaml b/db/seeds/instances.yaml new file mode 100644 index 00000000..bf326832 --- /dev/null +++ b/db/seeds/instances.yaml @@ -0,0 +1,285 @@ +--- +- domain: todon.nl + title: Todon.nl + version: 4.2.3 + source_url: https://github.com/mastodon/mastodon + description: Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, + (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, + intersectionelen, veganisten, mensenrechten, enz. + usage: + users: + active_month: 372 + thumbnail: + url: https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png + blurhash: UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE + versions: + "@1x": https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png + "@2x": https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png + languages: + - en + configuration: + urls: + streaming: wss://todon.nl + status: https://status.todon.eu + accounts: + max_featured_tags: 10 + statuses: + max_characters: 1312 + max_media_attachments: 4 + characters_reserved_per_url: 23 + media_attachments: + supported_mime_types: + - image/jpeg + - image/png + - image/gif + - image/heic + - image/heif + - image/webp + - image/avif + - video/webm + - video/mp4 + - video/quicktime + - video/ogg + - audio/wave + - audio/wav + - audio/x-wav + - audio/x-pn-wave + - audio/vnd.wave + - audio/ogg + - audio/vorbis + - audio/mpeg + - audio/mp3 + - audio/webm + - audio/flac + - audio/aac + - audio/m4a + - audio/x-m4a + - audio/mp4 + - audio/3gpp + - video/x-ms-asf + image_size_limit: 16777216 + image_matrix_limit: 33177600 + video_size_limit: 103809024 + video_frame_rate_limit: 120 + video_matrix_limit: 8294400 + polls: + max_options: 4 + max_characters_per_option: 50 + min_expiration: 300 + max_expiration: 2629746 + translation: + enabled: true + registrations: + enabled: false + approval_required: false + message: | +

¡No pasarán!

+ +

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

+ + + +

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

+ +

It is temporary not possible to request on account on Todon.nl.

+ + + +

Go to joinmastodon.org or FediDB Network to find another server.

+ url: + max_toot_chars: 1312 + contact: + email: todon@posteo.eu + account: + id: '1' + username: admin + acct: admin + display_name: "Admin \U0001F913 Todon.nl (mod)" + locked: false + bot: false + discoverable: false + group: false + created_at: '2017-04-28T00:00:00.000Z' + note: "

This account is used for \U0001F399 Todon.nl announcements and ⚖️ + moderation.

\U0001F6AB Don't follow this account when you are not + on Todon.nl.

New? First read our \U0001F469‍\U0001F3EB Todon 101 \U0001F469‍\U0001F393 + at https://wiki.todon.eu/todon/101

⚖️ + For all our moderators go to https://wiki.todon.nl/todon/moderators

\U0001F4DD Public toots from this account + are in English.

\U0001F515 Criticism is fine, but people who do false + accusations are muted.

✉ todon@posteo.eu

#nobot

" + url: https://todon.nl/@admin + uri: https://todon.nl/users/admin + avatar: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png + avatar_static: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png + header: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png + header_static: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png + followers_count: 3164 + following_count: 8 + statuses_count: 724 + last_status_at: '2024-01-12' + noindex: true + emojis: [] + roles: + - id: '3' + name: Admin + color: "#595aff" + fields: + - name: "\U0001F4DC Terms of Service" + value: wiki.todon.nl/todon/terms_en + verified_at: '2018-11-01T14:39:45.465+00:00' + - name: ℹ️ Wiki + value: wiki.todon.nl/todon/informatio + verified_at: '2018-11-01T14:40:54.679+00:00' + - name: "\U0001F4CA Status" + value: status.todon.eu + verified_at: '2023-10-26T20:38:30.185+00:00' + - name: "\U0001F4B3️ Donations" + value: wiki.todon.eu/todon/donations + verified_at: '2022-11-02T00:06:31.865+00:00' + rules: + - id: '1' + text: We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, + apartheid and casteism - see our Terms of Service for our complete definition). + - id: '2' + text: We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, + non-binary people, intersexual people, queer people in general, etc. + - id: '4' + text: Sexism, misogyny and hate against black women (misogynoir). + - id: '6' + text: We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) + and body-shaming. + - id: '8' + text: We do not accept harassment and trolling. + - id: '10' + text: We also do not accept other forms of hate speech. + - id: '11' + text: We do not accept (sexual) abuse of minors, adults and animals (also not + virtual). + - id: '13' + text: We do not accept glorification of violence, calls for murder, death threats, + terrorism and militarism. + - id: '15' + text: We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms + and nationalism (above all nationalism of nation states, incl. flags/symbols + of those on Todon.*, see our Terms of Service). + - id: '16' + text: We do not accept fascism, right-wing populism, and right-wing and religious + extremism. + - id: '17' + text: We do not accept evangelisation and other forms of religious propaganda + [local only], and extreme sects and cults. + - id: '19' + text: We do not accept Marxist-Leninists, Stalinists, Maoists or other followers + of extreme authoritarian (so called) communist/socialist ideologies/regimes + (aka tankies). + - id: '20' + text: We do not accept capitalists, including so called 'anarcho-capitalists' + (aka ancaps) and neoliberals. + - id: '21' + text: We do not accept anthropogenic climate change denial, downplaying the climate + crisis, greenwashing and deceptive climate solutions (like nuclear energy). + - id: '27' + text: We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and + other forms of disinformation. + - id: '28' + text: Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain + in the final step. +- uri: mastodon.mauve.moe + title: Mauvestodon + short_description: Escape ship from centralized social media run by Mauve. + description: Chat about random techie and anarchist stuff. + email: contact@mauve.moe + version: 3.5.10 + urls: + streaming_api: wss://mastodon.mauve.moe + stats: + user_count: 12 + status_count: 3287 + domain_count: 11625 + thumbnail: https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png + languages: + - en + registrations: false + approval_required: false + invites_enabled: true + configuration: + statuses: + max_characters: 500 + max_media_attachments: 4 + characters_reserved_per_url: 23 + media_attachments: + supported_mime_types: + - image/jpeg + - image/png + - image/gif + - video/webm + - video/mp4 + - video/quicktime + - video/ogg + - audio/wave + - audio/wav + - audio/x-wav + - audio/x-pn-wave + - audio/ogg + - audio/vorbis + - audio/mpeg + - audio/mp3 + - audio/webm + - audio/flac + - audio/aac + - audio/m4a + - audio/x-m4a + - audio/mp4 + - audio/3gpp + - video/x-ms-asf + image_size_limit: 10485760 + image_matrix_limit: 16777216 + video_size_limit: 41943040 + video_frame_rate_limit: 60 + video_matrix_limit: 2304000 + polls: + max_options: 4 + max_characters_per_option: 50 + min_expiration: 300 + max_expiration: 2629746 + contact_account: + id: '1' + username: admin + acct: admin + display_name: '' + locked: false + bot: false + discoverable: true + group: false + created_at: '2022-04-25T00:00:00.000Z' + note: '' + url: https://mastodon.mauve.moe/@admin + avatar: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png + avatar_static: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png + header: https://mastodon.mauve.moe/headers/original/missing.png + header_static: https://mastodon.mauve.moe/headers/original/missing.png + followers_count: 0 + following_count: 0 + statuses_count: 0 + last_status_at: '2023-01-30' + emojis: [] + fields: + - name: Alternatel Contact + value: @mauve + verified_at: + rules: [] diff --git a/db/seeds/moderation_queue.yaml b/db/seeds/moderation_queue.yaml new file mode 100644 index 00000000..c7075c7e --- /dev/null +++ b/db/seeds/moderation_queue.yaml @@ -0,0 +1,153 @@ +--- +- "@context": + - https://www.w3.org/ns/activitystreams + - ostatus: http://ostatus.org# + atomUri: ostatus:atomUri + inReplyToAtomUri: ostatus:inReplyToAtomUri + conversation: ostatus:conversation + sensitive: as:sensitive + toot: http://joinmastodon.org/ns# + votersCount: toot:votersCount + Hashtag: as:Hashtag + id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 + type: Note + summary: + inReplyTo: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 + published: '2023-11-23T22:50:10Z' + url: https://mastodon.mauve.moe/@mauve/111462305634770041 + attributedTo: https://mastodon.mauve.moe/users/mauve + to: + - https://www.w3.org/ns/activitystreams#Public + cc: + - https://mastodon.mauve.moe/users/mauve/followers + - https://hypha.coop/about.jsonld + sensitive: false + atomUri: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 + inReplyToAtomUri: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 + conversation: tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation + content:

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

+

+ contentMap: + en:

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

+

+ attachment: [] + tag: + - type: Mention + href: https://hypha.coop/about.jsonld + name: "@dripline@hypha.coop" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/p2p + name: "#p2p" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/activitypub + name: "#activitypub" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/fediverse + name: "#fediverse" + replies: + id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies + type: Collection + first: + type: CollectionPage + next: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true + partOf: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies + items: [] +- "@context": + - https://www.w3.org/ns/activitystreams + - "@language": es + sensitive: as:sensitive + type: Note + id: https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/ + summary: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty + published: '2023-12-04T21:53:05+00:00' + updated: '2023-12-05T20:41:34+00:00' + attributedTo: https://sutty.nl/about.jsonld + to: + - https://www.w3.org/ns/activitystreams#Public + cc: + - https://social.distributed.press/v1/@sutty@sutty.nl/followers + inReplyTo: https://hypha.coop/dripline/announcing-dp-social-inbox/ + sensitive: true + content: | +

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    +
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. +
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. +

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    +
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • +
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • +
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • +
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • +
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • +
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • +

Qué permite hacer

    +
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • +
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • +
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • +
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • +
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • +

Qué se viene

    +
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • +
  • Incorporación de menciones desde el panel de Sutty.

  • +
  • Mejoras en la interfaz general del panel.

  • +
  • Nuevas implementaciones para una mejor moderación.

  • +
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • +
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • +
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • +
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • +
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • +
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • +

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

+ name: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty + contentMap: + es: | +

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    +
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. +
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. +

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    +
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • +
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • +
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • +
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • +
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • +
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • +

Qué permite hacer

    +
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • +
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • +
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • +
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • +
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • +

Qué se viene

    +
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • +
  • Incorporación de menciones desde el panel de Sutty.

  • +
  • Mejoras en la interfaz general del panel.

  • +
  • Nuevas implementaciones para una mejor moderación.

  • +
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • +
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • +
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • +
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • +
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • +
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • +

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

+ attachment: + - type: Document + mediaType: image/png + url: https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png + name: Botones de colores para activar la "Web Disribuida" y el "Fediverso". diff --git a/db/seeds/remote_profile.yaml b/db/seeds/remote_profile.yaml new file mode 100644 index 00000000..1a670d6b --- /dev/null +++ b/db/seeds/remote_profile.yaml @@ -0,0 +1,106 @@ +--- +"@context": +- https://www.w3.org/ns/activitystreams +- https://w3id.org/security/v1 +- manuallyApprovesFollowers: as:manuallyApprovesFollowers + toot: http://joinmastodon.org/ns# + featured: + "@id": toot:featured + "@type": "@id" + featuredTags: + "@id": toot:featuredTags + "@type": "@id" + alsoKnownAs: + "@id": as:alsoKnownAs + "@type": "@id" + movedTo: + "@id": as:movedTo + "@type": "@id" + schema: http://schema.org# + PropertyValue: schema:PropertyValue + value: schema:value + discoverable: toot:discoverable + Device: toot:Device + Ed25519Signature: toot:Ed25519Signature + Ed25519Key: toot:Ed25519Key + Curve25519Key: toot:Curve25519Key + EncryptedMessage: toot:EncryptedMessage + publicKeyBase64: toot:publicKeyBase64 + deviceId: toot:deviceId + claim: + "@type": "@id" + "@id": toot:claim + fingerprintKey: + "@type": "@id" + "@id": toot:fingerprintKey + identityKey: + "@type": "@id" + "@id": toot:identityKey + devices: + "@type": "@id" + "@id": toot:devices + messageFranking: toot:messageFranking + messageType: toot:messageType + cipherText: toot:cipherText + suspended: toot:suspended + focalPoint: + "@container": "@list" + "@id": toot:focalPoint +id: https://mastodon.mauve.moe/users/mauve +type: Person +following: https://mastodon.mauve.moe/users/mauve/following +followers: https://mastodon.mauve.moe/users/mauve/followers +inbox: https://mastodon.mauve.moe/users/mauve/inbox +outbox: https://mastodon.mauve.moe/users/mauve/outbox +featured: https://mastodon.mauve.moe/users/mauve/collections/featured +featuredTags: https://mastodon.mauve.moe/users/mauve/collections/tags +preferredUsername: mauve +name: "Mauve \U0001F441\U0001F49C" +summary: "

Occult Enby that's making local-first software with peer to peer + protocols, mesh networks, and the web.

Also exploring what a local-first + cyberspace might look like in my spare time.

" +url: https://mastodon.mauve.moe/@mauve +manuallyApprovesFollowers: false +discoverable: true +published: '2022-04-25T00:00:00Z' +devices: https://mastodon.mauve.moe/users/mauve/collections/devices +alsoKnownAs: +- https://infosec.exchange/users/RangerMauve +publicKey: + id: https://mastodon.mauve.moe/users/mauve#main-key + owner: https://mastodon.mauve.moe/users/mauve + publicKeyPem: | + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ + umIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng + 7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK + 75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq + WUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D + zAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf + XwIDAQAB + -----END PUBLIC KEY----- +tag: [] +attachment: +- type: PropertyValue + name: Pronouns + value: they/them/it +- type: PropertyValue + name: Email + value: mauve@mauve.moe +- type: PropertyValue + name: Matrix + value: @mauve:mauve.moe +- type: PropertyValue + name: Github/Twitter + value: "@RangerMauve" +endpoints: + sharedInbox: https://mastodon.mauve.moe/inbox +icon: + type: Image + mediaType: image/png + url: https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png +image: + type: Image + mediaType: image/png + url: https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png From 3a44c9629fd87952fe9347d6334bd0d8eb93a17e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 15:55:31 -0300 Subject: [PATCH 006/227] agregadas traducciones a posts/edit #15002 --- app/views/posts/edit.haml | 2 +- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index c792ac93..126b811e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,6 +1,6 @@ .row.justify-content-center .col-md-8 - = render 'layouts/details', summary: "Post" do + = render 'layouts/details', summary: t('.post') do = render 'posts/form', site: @site, post: @post = render 'layouts/details', summary: t('.moderation_queue') do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/config/locales/en.yml b/config/locales/en.yml index fc9d4894..5a1f31bc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -221,6 +221,10 @@ en: mutual_aid: Mutual aid contact_us: "Contact us" contact_us_href: "https://sutty.nl/en/#contact" + posts: + edit: + moderation_queue: Moderation Queue + post: Post collaborations: collaborate: submit: Register diff --git a/config/locales/es.yml b/config/locales/es.yml index 4bda4982..3b54fbba 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -221,6 +221,10 @@ es: mutual_aid: Ayuda mutua contact_us: "Contacto" contact_us_href: "https://sutty.nl/#contacto" + posts: + edit: + moderation_queue: Cola de moderación + post: Publicación collaborations: collaborate: submit: Registrarme From 49039c24b7ad16d5791ef606c80858ed7739db6a Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 16:12:04 -0300 Subject: [PATCH 007/227] =?UTF-8?q?agregada=20vista=20de=20remote=20profil?= =?UTF-8?q?e=20b=C3=A1sica=20#15003?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/remote_profile.haml | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/views/moderation_queue/remote_profile.haml diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml new file mode 100644 index 00000000..537ab91c --- /dev/null +++ b/app/views/moderation_queue/remote_profile.haml @@ -0,0 +1 @@ +%h1= @remote_profile['name'] \ No newline at end of file From ed0c237d60e1bdaa295c50c8bb08c885f1da6e04 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 16:14:02 -0300 Subject: [PATCH 008/227] agregada partial de details #15000 --- app/views/layouts/_details.haml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 app/views/layouts/_details.haml diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml new file mode 100644 index 00000000..9d6e04a1 --- /dev/null +++ b/app/views/layouts/_details.haml @@ -0,0 +1,4 @@ +%details + %summary= @summary + + = yield \ No newline at end of file From 4c902c8aaf58807c54522f6ba1a33061f034940f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 17 Jan 2024 16:39:20 -0300 Subject: [PATCH 009/227] feat: agregado clase details a application.scss #15000 --- app/assets/stylesheets/application.scss | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 7f62e658..7f7908ca 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -558,3 +558,31 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } +// details styles + +.details summary { + list-style: none; + cursor: default; + position: relative; + + &::after { + content: '▶'; + font-size: 2rem; + position: absolute; + left: 97%; + bottom: 46%; + transform: rotate(55deg); + color: $magenta + } + + &:focus { + background-color: #13FEFE; + color: black + } + } + +.details[open] > summary::after { + transform: rotate(90deg) translatey(-0.1em); + color: $magenta + } + \ No newline at end of file From f098de102eab41d817dc764e59cdbbb1aa367d47 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 17:16:52 -0300 Subject: [PATCH 010/227] feat: agregadas views de moderation_queue #15001 --- app/views/moderation_queue/index.haml | 2 ++ app/views/posts/_moderation_queue.haml | 0 2 files changed, 2 insertions(+) create mode 100644 app/views/moderation_queue/index.haml create mode 100644 app/views/posts/_moderation_queue.haml diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml new file mode 100644 index 00000000..ce5dda0f --- /dev/null +++ b/app/views/moderation_queue/index.haml @@ -0,0 +1,2 @@ +- @comments.each do |comment| + %h1= comment['id'] \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml new file mode 100644 index 00000000..e69de29b From ad8e5bc8115a908d31a964d357529ef4ce690d53 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 17 Jan 2024 17:37:02 -0300 Subject: [PATCH 011/227] fix: corregido edit in es.yml --- app/views/posts/index.haml | 2 +- app/views/posts/show.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 374f06ee..69fb2d8f 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -126,7 +126,7 @@ = post.order %td.text-nowrap - if @usuarie || policy(post).edit? - = link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' + = link_to t('posts.edit_post'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' - if @usuarie || policy(post).destroy? = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') } diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index 10900d67..ec191d87 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -2,7 +2,7 @@ .row.justify-content-center .col-md-8 %article.content.table-responsive-md - = link_to t('posts.edit'), + = link_to t('posts.edit_post'), edit_site_post_path(@site, @post.id), class: 'btn btn-secondary btn-block' From 5d26c6746e6160986e01c03d7bf2cfc7f2afb3db Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 17:37:53 -0300 Subject: [PATCH 012/227] fix: traducciones #15002 --- config/locales/en.yml | 12 +++++++----- config/locales/es.yml | 15 ++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5a1f31bc..4c03fd30 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,7 @@ en: + moderation_queue: + remote_profile: + user: Username dark: Dark dir: ltr en: English @@ -221,10 +224,6 @@ en: mutual_aid: Mutual aid contact_us: "Contact us" contact_us_href: "https://sutty.nl/en/#contact" - posts: - edit: - moderation_queue: Moderation Queue - post: Post collaborations: collaborate: submit: Register @@ -582,7 +581,10 @@ en: categories: 'Everything' index: search: 'Search' - edit: 'Edit' + edit_post: 'Edit' + edit: + moderation_queue: Moderation Queue + post: Post preview: btn: 'Preliminary version' alert: 'Not every article type has a preliminary version' diff --git a/config/locales/es.yml b/config/locales/es.yml index 3b54fbba..cc3590ad 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,7 @@ es: + moderation_queue: + remote_profile: + user: Nombre de usuario dark: Oscuro es: Castellano en: English @@ -221,10 +224,6 @@ es: mutual_aid: Ayuda mutua contact_us: "Contacto" contact_us_href: "https://sutty.nl/#contacto" - posts: - edit: - moderation_queue: Cola de moderación - post: Publicación collaborations: collaborate: submit: Registrarme @@ -524,6 +523,9 @@ es: en: 'inglés' ar: 'árabe' posts: + edit: + moderation_queue: Moderation Queue + post: Post prev: Página anterior next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. @@ -590,7 +592,10 @@ es: remove_filter_help: 'Quitar este filtro: %{filter}' index: search: 'Buscar' - edit: 'Editar' + edit_post: 'Editar' + edit: + moderation_queue: Cola de moderación + post: Publicación preview: btn: 'Versión preliminar' alert: 'No todos los tipos de artículos poseen vista preliminar :)' From 28ddaca35a972d797a60191abf66a159669a4248 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 19 Jan 2024 13:41:23 -0300 Subject: [PATCH 013/227] fix: corregido details de post edit --- app/assets/stylesheets/application.scss | 2 +- app/views/layouts/_details.haml | 8 ++++---- app/views/posts/edit.haml | 6 ++++-- config/locales/es.yml | 7 ++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 7f7908ca..b11be0de 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -570,7 +570,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); font-size: 2rem; position: absolute; left: 97%; - bottom: 46%; + bottom: 2%; transform: rotate(55deg); color: $magenta } diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 9d6e04a1..f950b097 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,4 +1,4 @@ -%details - %summary= @summary - - = yield \ No newline at end of file +%details.details.py-2 + %summary + %h3.py-2.text-center= @summary + = yield \ No newline at end of file diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 126b811e..488056a4 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,6 +1,8 @@ .row.justify-content-center .col-md-8 - = render 'layouts/details', summary: t('.post') do + - @summary = t('posts.edit.post') + = render 'layouts/details', summary: @summary do = render 'posts/form', site: @site, post: @post - = render 'layouts/details', summary: t('.moderation_queue') do + - @summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: @summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/config/locales/es.yml b/config/locales/es.yml index cc3590ad..1e4f870c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -524,8 +524,8 @@ es: ar: 'árabe' posts: edit: - moderation_queue: Moderation Queue - post: Post + moderation_queue: Cola de Moderación + post: Contenido prev: Página anterior next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. @@ -593,9 +593,6 @@ es: index: search: 'Buscar' edit_post: 'Editar' - edit: - moderation_queue: Cola de moderación - post: Publicación preview: btn: 'Versión preliminar' alert: 'No todos los tipos de artículos poseen vista preliminar :)' From ef7d9d2a1ee7b6fed274f869da2c20da95297915 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 19 Jan 2024 15:06:20 -0300 Subject: [PATCH 014/227] fix: eliminados espacios en blanco en varias lineas --- app/views/posts/edit.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 488056a4..5234f257 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,8 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.post') - = render 'layouts/details', summary: @summary do + - @summary = t('posts.edit.post') + = render 'layouts/details', summary: @summary do = render 'posts/form', site: @site, post: @post - - @summary = t('posts.edit.moderation_queue') + - @summary = t('posts.edit.moderation_queue') = render 'layouts/details', summary: @summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From d895b9c808fbf4f7977f45a6723e4367aa23c17f Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 14:17:24 -0300 Subject: [PATCH 015/227] feat: agregados componentes comentario, botonera y boton_base --- app/assets/stylesheets/application.scss | 4 ++++ app/views/layouts/_details.haml | 2 ++ app/views/moderation_queue/_btn_base.haml | 3 +++ app/views/moderation_queue/_button_box.haml | 14 ++++++++++++++ app/views/moderation_queue/_comment.haml | 4 ++++ app/views/posts/_moderation_queue.haml | 3 +++ config/locales/es.yml | 6 ++++++ 7 files changed, 36 insertions(+) create mode 100644 app/views/moderation_queue/_btn_base.haml create mode 100644 app/views/moderation_queue/_button_box.haml create mode 100644 app/views/moderation_queue/_comment.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index b11be0de..a4446532 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -585,4 +585,8 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); transform: rotate(90deg) translatey(-0.1em); color: $magenta } + +.bg-blue { + background-color: $azul; +} \ No newline at end of file diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index f950b097..4fe4d2af 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,3 +1,5 @@ +-# Detail Cola de Moderación + %details.details.py-2 %summary %h3.py-2.text-center= @summary diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml new file mode 100644 index 00000000..74e9516a --- /dev/null +++ b/app/views/moderation_queue/_btn_base.haml @@ -0,0 +1,3 @@ +-# Componente Botón general Moderación + +%a.btn.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml new file mode 100644 index 00000000..ea038e59 --- /dev/null +++ b/app/views/moderation_queue/_button_box.haml @@ -0,0 +1,14 @@ +-# Componente Botonera de Moderación + +.d-flex.py-2.justify-content-center + -# parámetros de botones + -# text, class, href + - @btn_box_params = [[t('.text_pause'), 'bg-outline-light', 'https://sutty.nl/'], + [t('.text_reject'), 'btn-outline-info blue', 'https://sutty.nl/'], + [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], + [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], + [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + + - @btn_box_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml new file mode 100644 index 00000000..051a84b0 --- /dev/null +++ b/app/views/moderation_queue/_comment.haml @@ -0,0 +1,4 @@ +-# Componente Comentario + +%p.py-2 Esta línea es donde irá el cuerpo del comentario += render 'moderation_queue/button_box' \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e69de29b..77df7353 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -0,0 +1,3 @@ +.flex + %h2.text-center Comentarios + = render 'moderation_queue/comment' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 1e4f870c..f9cd1b4f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2,6 +2,12 @@ es: moderation_queue: remote_profile: user: Nombre de usuario + button_box: + text_pause: Pausa + text_reject: Rechazar + text_accept: Aceptar Publicación + text_reply: Responder + text_report: Reportar dark: Oscuro es: Castellano en: English From 9fa45b01ac8e8afc29babcc462ab2719e010ca9b Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 15:35:19 -0300 Subject: [PATCH 016/227] =?UTF-8?q?feat:=20agregadas=20traducci=C3=B3n=20i?= =?UTF-8?q?ngl=C3=A9s=20botones=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 +++- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 6 +++--- config/locales/en.yml | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a4446532..c0a666ab 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -3,6 +3,7 @@ $white: white; $grey: grey; $cyan: #13fefe; $magenta: #f206f9; +$blue: blue; $colors: ( "black": $black, @@ -14,6 +15,7 @@ $colors: ( // Redefinir variables de Bootstrap $primary: $magenta; $secondary: $black; +$info: $blue; $jumbotron-bg: transparent; $enable-rounded: false; $form-feedback-valid-color: $black; @@ -589,4 +591,4 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); .bg-blue { background-color: $azul; } - \ No newline at end of file + diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 74e9516a..5f4561ef 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file +%a.btn.btn-lg.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index ea038e59..9a2f5947 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -1,10 +1,10 @@ -# Componente Botonera de Moderación -.d-flex.py-2.justify-content-center +.d-inline-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_pause'), 'bg-outline-light', 'https://sutty.nl/'], - [t('.text_reject'), 'btn-outline-info blue', 'https://sutty.nl/'], + - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], + [t('.text_reject'), 'btn-outline-info', 'https://sutty.nl/'], [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] diff --git a/config/locales/en.yml b/config/locales/en.yml index 4c03fd30..ef14f51f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2,6 +2,12 @@ en: moderation_queue: remote_profile: user: Username + button_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept Publication + text_reply: Reply + text_report: Report dark: Dark dir: ltr en: English From 45d98b316914db31f47c370b547ac5c31f641f74 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 16:05:57 -0300 Subject: [PATCH 017/227] fix: corregidas clases en botonera --- app/views/moderation_queue/_button_box.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index 9a2f5947..99744088 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Moderación -.d-inline-flex.py-2.justify-content-center +.d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], From 1edf052109c643bceb60aed6c1aaaf162a1e0779 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 17:38:32 -0300 Subject: [PATCH 018/227] fix: corregido padding en moderation_queue view --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 77df7353..4b405bbb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,3 +1,3 @@ .flex - %h2.text-center Comentarios + %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment' \ No newline at end of file From 9cb1e6fd36afc95f912e45f6323e6c0ade9c8c41 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 23 Jan 2024 16:29:11 -0300 Subject: [PATCH 019/227] =?UTF-8?q?feat:=20index=20de=20cola=20de=20modera?= =?UTF-8?q?ci=C3=B3n,=20con=20metadatos=20pero=20sin=20maquetar=20#15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 7 +++++++ app/views/moderation_queue/index.haml | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 051a84b0..f2fb3ac2 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,4 +1,11 @@ -# Componente Comentario %p.py-2 Esta línea es donde irá el cuerpo del comentario + + +.row + .col.col-1 + %p "hola" + .col + %p "chau" = render 'moderation_queue/button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index ce5dda0f..0881add2 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,2 +1,4 @@ -- @comments.each do |comment| - %h1= comment['id'] \ No newline at end of file +- @moderation_queue.each do |comment| + + = render 'comment', comment: comment +-# %h1= comment['id'] \ No newline at end of file From 2c7081a57f361c3e6f5479cd68d4659aaed62746 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 23 Jan 2024 17:04:38 -0300 Subject: [PATCH 020/227] feat: agregado componente remote_profile y botonera --- app/views/moderation_queue/_comment.haml | 2 +- .../{_button_box.haml => _comment_button_box.haml} | 0 app/views/moderation_queue/_profile_button_box.haml | 12 ++++++++++++ app/views/moderation_queue/_remote_profile.haml | 5 +++++ app/views/moderation_queue/remote_profile.haml | 4 +++- config/locales/es.yml | 11 +++++++++-- 6 files changed, 30 insertions(+), 4 deletions(-) rename app/views/moderation_queue/{_button_box.haml => _comment_button_box.haml} (100%) create mode 100644 app/views/moderation_queue/_profile_button_box.haml create mode 100644 app/views/moderation_queue/_remote_profile.haml diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 051a84b0..e43e8c42 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,4 +1,4 @@ -# Componente Comentario %p.py-2 Esta línea es donde irá el cuerpo del comentario -= render 'moderation_queue/button_box' \ No newline at end of file += render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml similarity index 100% rename from app/views/moderation_queue/_button_box.haml rename to app/views/moderation_queue/_comment_button_box.haml diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml new file mode 100644 index 00000000..d5852ffa --- /dev/null +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -0,0 +1,12 @@ +-# Componente Botonera de Profile + +.d-flex.py-2.justify-content-center + -# parámetros de botones + -# text, class, href + - @btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], + [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + + - @btn_box_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml new file mode 100644 index 00000000..3a18a24a --- /dev/null +++ b/app/views/moderation_queue/_remote_profile.haml @@ -0,0 +1,5 @@ +.flex.py-2.mx-2.text-center + %h4= t('.profile_name') + ": " + @remote_profile['name'] + %h5= t('.profile_id') + ": " + @remote_profile['id'] + %h5= t('.profile_published') + ": " + @remote_profile['published'] + = render 'moderation_queue/profile_button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 537ab91c..36613405 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1 +1,3 @@ -%h1= @remote_profile['name'] \ No newline at end of file +.flex + %h1.text-center= t('.profile') + = render 'moderation_queue/remote_profile' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index f9cd1b4f..0f5e314c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,8 +1,15 @@ es: moderation_queue: remote_profile: - user: Nombre de usuario - button_box: + profile: Cuentas + profile_name: Nombre de la Cuenta + profile_id: ID + profile_published: Publicada + profile_button_box: + text_deny: Bloquear que te siga + text_allow: Permitir que te siga + text_report: Reportar + comment_button_box: text_pause: Pausa text_reject: Rechazar text_accept: Aceptar Publicación From f78fb436817aa5546cc98ef120013ca291076064 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 23 Jan 2024 17:13:42 -0300 Subject: [PATCH 021/227] =?UTF-8?q?feat:=20esqueleto=20b=C3=A1sico=20maque?= =?UTF-8?q?tado=20de=20comentario=20para=20cola=20de=20moderaci=C3=B3n=20#?= =?UTF-8?q?15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index f2fb3ac2..766e4a22 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -3,9 +3,16 @@ %p.py-2 Esta línea es donde irá el cuerpo del comentario +.row.border.border-white + .col.col-1.border.border-white + %p= comment['published'] # falta parsear + .col.border.border-white + %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear +.row.border.border-white + %p= "En respuesta a: " + %span + %a{:href => comment['inReplyTo']}= comment['inReplyTo'] +.row.border.border-white + %p= comment['content'] #falta parsear .row - .col.col-1 - %p "hola" - .col - %p "chau" -= render 'moderation_queue/button_box' \ No newline at end of file + = render 'moderation_queue/button_box' \ No newline at end of file From d3e5434a00a703c7c749bbc3ac1e01ca4c1f3854 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 15:48:25 -0300 Subject: [PATCH 022/227] fix: agregadas traduccion y estilos a componente _comment --- app/views/moderation_queue/_comment.haml | 36 +++++++++++++----------- config/locales/es.yml | 3 ++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d412ce62..1093a26b 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,18 +1,20 @@ -# Componente Comentario - -%p.py-2 Esta línea es donde irá el cuerpo del comentario - - -.row.border.border-white - .col.col-1.border.border-white - %p= comment['published'] # falta parsear - .col.border.border-white - %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear -.row.border.border-white - %p= "En respuesta a: " - %span - %a{:href => comment['inReplyTo']}= comment['inReplyTo'] -.row.border.border-white - %p= comment['content'] #falta parsear -.row - = render 'moderation_queue/comment_button_box' +.flex.mx-4.my-5 + .row.no-gutters + .col-1 + %input{type: "checkbox", id: ""} + .col-10 + .row.border.border-white + .col.col-1.border.border-white.mr-2 + %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear + .col.border.border-white + %span.mr-3= t('.source_profile') + %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear + .row.border.border-white + %p.mr-3= t('.reply_to') + %span + %a{:href => comment['inReplyTo']}= comment['inReplyTo'] + .row.border.border-white + %p= comment['content'] #falta parsear + .row.d-flex.justify-content-center + = render 'moderation_queue/comment_button_box' diff --git a/config/locales/es.yml b/config/locales/es.yml index 0f5e314c..451d5fa4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,5 +1,8 @@ es: moderation_queue: + comment: + source_profile: Cuenta de Origen + reply_to: En respuesta a remote_profile: profile: Cuentas profile_name: Nombre de la Cuenta From f6a93b5bc21722d731cceef54a66c0bb17c2b222 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 16:15:20 -0300 Subject: [PATCH 023/227] fix: corregida llamada en _moderation_queue para mostrar comentarios en vista posts/edit --- app/controllers/posts_controller.rb | 1 + app/views/moderation_queue/_comment_button_box.haml | 8 ++++---- app/views/moderation_queue/index.haml | 1 - app/views/posts/_moderation_queue.haml | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index d572e052..12b3ab55 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -82,6 +82,7 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end def update diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index 99744088..13a9c8a3 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -4,10 +4,10 @@ -# parámetros de botones -# text, class, href - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], - [t('.text_reject'), 'btn-outline-info', 'https://sutty.nl/'], - [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], - [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], - [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + [t('.text_reject'), 'btn-outline-info', ''], + [t('.text_accept'), 'bg-blue white', ''], + [t('.text_reply'), 'btn-outline-dark', ''], + [t('.text_report'), 'btn-outline-danger', '']] - @btn_box_params.each do |btn| - @class = btn[1] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0881add2..0c693d26 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,4 +1,3 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment --# %h1= comment['id'] \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 4b405bbb..c754d51d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,3 +1,4 @@ .flex %h3.text-center.py-2 Comentarios - = render 'moderation_queue/comment' \ No newline at end of file + - @moderation_queue.each do |comment| + = render 'moderation_queue/comment', comment: comment \ No newline at end of file From 1eb2230b2afad89701923da7bd4fbe5cc021278d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 17:05:06 -0300 Subject: [PATCH 024/227] =?UTF-8?q?fix:=20corregida=20posici=C3=B3n=20de?= =?UTF-8?q?=20botonera=20de=20moderacion=20de=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 6 ++---- app/views/moderation_queue/index.haml | 1 + app/views/posts/_moderation_queue.haml | 4 +++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 1093a26b..639a6bae 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,10 +5,10 @@ %input{type: "checkbox", id: ""} .col-10 .row.border.border-white - .col.col-1.border.border-white.mr-2 + .col.col-1.border.border-white.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear .col.border.border-white - %span.mr-3= t('.source_profile') + %span.mr-2= t('.source_profile') %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear .row.border.border-white %p.mr-3= t('.reply_to') @@ -16,5 +16,3 @@ %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white %p= comment['content'] #falta parsear - .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0c693d26..63b36a3a 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment + = render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index c754d51d..2528224f 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,4 +1,6 @@ .flex %h3.text-center.py-2 Comentarios - @moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment \ No newline at end of file + = render 'moderation_queue/comment', comment: comment + .row.d-flex.justify-content-center + = render 'moderation_queue/comment_button_box' \ No newline at end of file From 9e8a83b70665885604b287bf025ebb8412b7a116 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 26 Jan 2024 15:15:48 -0300 Subject: [PATCH 025/227] fix: html de comentarios sanitizado #15039 --- app/views/moderation_queue/_comment.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 639a6bae..d66d1187 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -15,4 +15,4 @@ %span %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white - %p= comment['content'] #falta parsear + %p= sanitize comment['content'] #falta parsear From 5a6b0373a2dc095a7c9b608ef73b3731c276a583 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 26 Jan 2024 15:23:38 -0300 Subject: [PATCH 026/227] feat: agregado componente caja de filtros de comentarios y compo filtro_base --- app/views/moderation_queue/_comment.haml | 4 ++-- app/views/moderation_queue/_comment_filter_box.haml | 6 ++++++ app/views/moderation_queue/_filter_base.haml | 8 ++++++++ app/views/moderation_queue/index.haml | 1 + app/views/posts/_moderation_queue.haml | 1 + config/locales/es.yml | 4 ++++ 6 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 app/views/moderation_queue/_comment_filter_box.haml create mode 100644 app/views/moderation_queue/_filter_base.haml diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d66d1187..a3f2499c 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -6,7 +6,7 @@ .col-10 .row.border.border-white .col.col-1.border.border-white.mr-5 - %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear + %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col.border.border-white %span.mr-2= t('.source_profile') %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear @@ -15,4 +15,4 @@ %span %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white - %p= sanitize comment['content'] #falta parsear + %p= sanitize comment['content'] diff --git a/app/views/moderation_queue/_comment_filter_box.haml b/app/views/moderation_queue/_comment_filter_box.haml new file mode 100644 index 00000000..e9abe602 --- /dev/null +++ b/app/views/moderation_queue/_comment_filter_box.haml @@ -0,0 +1,6 @@ +-# 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') \ No newline at end of file diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml new file mode 100644 index 00000000..6b62b99d --- /dev/null +++ b/app/views/moderation_queue/_filter_base.haml @@ -0,0 +1,8 @@ +-# 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 diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 63b36a3a..dbc1297a 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,4 @@ += render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| = render 'comment', comment: comment diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2528224f..7daa0c8e 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,7 @@ .flex %h3.text-center.py-2 Comentarios - @moderation_queue.each do |comment| + = render 'moderation_queue/comment_filter_box' = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 451d5fa4..d579d55e 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -18,6 +18,10 @@ es: text_accept: Aceptar Publicación text_reply: Responder text_report: Reportar + comment_filter_box: + text_order: Ordenar por + text_show: Ver + text_checked: Con los marcados dark: Oscuro es: Castellano en: English From 4b67968d3b9888ffb50dc7b2f6de499a7780e6c9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 13:28:58 -0300 Subject: [PATCH 027/227] fix: corregido botonera de filtros en componente moderation_queue --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 7daa0c8e..80a8b11c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex %h3.text-center.py-2 Comentarios + = render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| - = render 'moderation_queue/comment_filter_box' = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' \ No newline at end of file From 2f803f9ea625b8f0f48b6c2e47c77058930f66a6 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 13:48:11 -0300 Subject: [PATCH 028/227] fix: corregidas lineas segun CI --- app/views/moderation_queue/_filter_base.haml | 6 +++--- app/views/moderation_queue/_profile_button_box.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 4 ++-- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 6b62b99d..0b63e59b 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -3,6 +3,6 @@ %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 + %a.dropdown-item{ href: '#' } Action + %a.dropdown-item{ href: '#' } Another action + %a.dropdown-item{ href: '#' } Something else here diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index d5852ffa..1201de05 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -9,4 +9,4 @@ - @btn_box_params.each do |btn| - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 3a18a24a..273b7bd8 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,5 @@ .flex.py-2.mx-2.text-center %h4= t('.profile_name') + ": " + @remote_profile['name'] %h5= t('.profile_id') + ": " + @remote_profile['id'] - %h5= t('.profile_published') + ": " + @remote_profile['published'] - = render 'moderation_queue/profile_button_box' \ No newline at end of file + %h5= t('.profile_published') + ": " + @remote_profile['published'].to_datetime.strftime('%m/%d/%Y') + = render 'moderation_queue/profile_button_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 36613405..d1d20f86 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex %h1.text-center= t('.profile') - = render 'moderation_queue/remote_profile' \ No newline at end of file + = render 'moderation_queue/remote_profile' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 80a8b11c..f1b0f7ce 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - @moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' \ No newline at end of file + = render 'moderation_queue/comment_button_box' From 957e79e682e83e57704e43e01d3407f46bbf5df4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 15:32:47 -0300 Subject: [PATCH 029/227] fix: corregidas variables en partials --- app/views/moderation_queue/_comment_button_box.haml | 4 ++-- app/views/moderation_queue/_profile_button_box.haml | 4 ++-- app/views/moderation_queue/_remote_profile.haml | 6 +++--- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index 13a9c8a3..a22f46d5 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -3,12 +3,12 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], + - btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], [t('.text_reject'), 'btn-outline-info', ''], [t('.text_accept'), 'bg-blue white', ''], [t('.text_reply'), 'btn-outline-dark', ''], [t('.text_report'), 'btn-outline-danger', '']] - - @btn_box_params.each do |btn| + - btn_box_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index 1201de05..9de64e12 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + - btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - @btn_box_params.each do |btn| + - btn_box_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 273b7bd8..b665dcf2 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,5 @@ .flex.py-2.mx-2.text-center - %h4= 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') + %h4= 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/profile_button_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index d1d20f86..3eab5e35 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex %h1.text-center= t('.profile') - = render 'moderation_queue/remote_profile' + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f1b0f7ce..513632cd 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment_filter_box' - - @moderation_queue.each do |comment| + - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' From 1b0fb009f49a02dd5c9ed68cf77a81b9ef5d41c7 Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 29 Jan 2024 16:35:53 -0300 Subject: [PATCH 030/227] =?UTF-8?q?feat:=20traer=20informaci=C3=B3n=20de?= =?UTF-8?q?=20perfil=20remoto=20vinculado=20al=20comentario=20#15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 4 ++++ app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/index.haml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index eb39dae6..4a65f136 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -5,6 +5,10 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + @moderation_queue.each do |activity| + activity['attributedTo'] = @remote_profile + end end # Perfil remoto de usuarie diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index a3f2499c..d443802d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -9,7 +9,7 @@ %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col.border.border-white %span.mr-2= t('.source_profile') - %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear + %a{:href => comment['attributedTo']}= profile['preferredUsername'] .row.border.border-white %p.mr-3= t('.reply_to') %span diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index dbc1297a..a3897417 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,5 @@ = render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| - = render 'comment', comment: comment + = render 'comment', comment: comment, profile: @remote_profile = render 'moderation_queue/comment_button_box' \ No newline at end of file From b7630844747b0fb0ec122e2597158ed99cd7093e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:41:12 -0300 Subject: [PATCH 031/227] feat: dummy data #15076 --- app/controllers/application_controller.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2746ab10..903d3642 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,6 +27,15 @@ class ApplicationController < ActionController::Base end private + # Traer datos de muestra de la cola de moderación + def dummy_data + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + @moderation_queue.each do |activity| + activity['attributedTo'] = @remote_profile + end + end def notify_unconfirmed_email return unless current_usuarie @@ -117,4 +126,5 @@ class ApplicationController < ActionController::Base sites_path end + end From b233a74f61ef522d7f4cd99e8ffba1dc8b2f02e7 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:47:19 -0300 Subject: [PATCH 032/227] =?UTF-8?q?fix:=20agregada=20dummy=5Fdata=20en=20e?= =?UTF-8?q?l=20m=C3=A9todo=20edit=20de=20posts=5Fcontroller=20#15076=20#15?= =?UTF-8?q?039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/posts_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 12b3ab55..8839de52 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -83,6 +83,7 @@ class PostsController < ApplicationController breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + dummy_data end def update From 836687651e1f922fe71847d5864158fb93a59e5e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:51:53 -0300 Subject: [PATCH 033/227] =?UTF-8?q?fix:=20c=C3=B3digo=20dem=C3=A1s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/posts_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 8839de52..5be56acc 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -82,7 +82,6 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) dummy_data end From 4f6464837ac8a0b8a446353ac4eacb80a1e39d2c Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:53:05 -0300 Subject: [PATCH 034/227] fix: a ver si esto arregla --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 513632cd..b861d67d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -2,6 +2,6 @@ %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment_filter_box' - moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment + = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' From 94a86eca9b61efc7c8b5327f0c08f1893a728c18 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 31 Jan 2024 17:10:34 -0300 Subject: [PATCH 035/227] fix: corregidos colores botonera de comentarios #15028 --- app/views/moderation_queue/_comment_button_box.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index a22f46d5..bd367e09 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], - [t('.text_reject'), 'btn-outline-info', ''], + - btn_box_params = [[t('.text_pause'), 'btn-secondary', ''], + [t('.text_reject'), 'btn-primary', ''], [t('.text_accept'), 'bg-blue white', ''], - [t('.text_reply'), 'btn-outline-dark', ''], + [t('.text_reply'), 'btn-outline-primary', ''], [t('.text_report'), 'btn-outline-danger', '']] - btn_box_params.each do |btn| From 819ed25e29a2559bcb2a541b3c46cb887e348fc4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 1 Feb 2024 12:02:40 -0300 Subject: [PATCH 036/227] fix: eliminadas botoneras de comentarios y remote_profile y unificadas en componente button_box #15028 --- app/controllers/application_controller.rb | 13 +++++++++++++ app/controllers/moderation_queue_controller.rb | 1 + app/controllers/posts_controller.rb | 1 + app/views/moderation_queue/_button_box.haml | 6 ++++++ .../moderation_queue/_comment_button_box.haml | 14 -------------- .../moderation_queue/_profile_button_box.haml | 4 ++-- app/views/moderation_queue/index.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- config/locales/es.yml | 2 +- 9 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 app/views/moderation_queue/_button_box.haml delete mode 100644 app/views/moderation_queue/_comment_button_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 903d3642..360a9b2d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,6 +37,19 @@ class ApplicationController < ActionController::Base 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', '']] + end + def notify_unconfirmed_email return unless current_usuarie return if current_usuarie.confirmed? diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 4a65f136..04a31389 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -9,6 +9,7 @@ class ModerationQueueController < ApplicationController @moderation_queue.each do |activity| activity['attributedTo'] = @remote_profile end + botoneras_moderation_queue end # Perfil remoto de usuarie diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5be56acc..36d17339 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -83,6 +83,7 @@ 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 diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml new file mode 100644 index 00000000..a56b2552 --- /dev/null +++ b/app/views/moderation_queue/_button_box.haml @@ -0,0 +1,6 @@ +-# Componente Botonera de Moderación + +.d-flex.py-2.justify-content-center + - comment_btn_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml deleted file mode 100644 index bd367e09..00000000 --- a/app/views/moderation_queue/_comment_button_box.haml +++ /dev/null @@ -1,14 +0,0 @@ --# Componente Botonera de Moderación - -.d-flex.py-2.justify-content-center - -# parámetros de botones - -# text, class, href - - btn_box_params = [[t('.text_pause'), 'btn-secondary', ''], - [t('.text_reject'), 'btn-primary', ''], - [t('.text_accept'), 'bg-blue white', ''], - [t('.text_reply'), 'btn-outline-primary', ''], - [t('.text_report'), 'btn-outline-danger', '']] - - - btn_box_params.each do |btn| - - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index 9de64e12..d15b6ed0 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + - comment_btn_params = [[t('.text_deny'), 'btn-outline-info', ''], [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - btn_box_params.each do |btn| + - comment_btn_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index a3897417..39ac74a3 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -2,4 +2,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/comment_button_box' \ No newline at end of file + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index b861d67d..e4eb422c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params diff --git a/config/locales/es.yml b/config/locales/es.yml index d579d55e..7850bcf7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -12,7 +12,7 @@ es: text_deny: Bloquear que te siga text_allow: Permitir que te siga text_report: Reportar - comment_button_box: + button_box: text_pause: Pausa text_reject: Rechazar text_accept: Aceptar Publicación From bbd5426da53c7d3677fcc72f17da0f74b42e519e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 1 Feb 2024 12:17:51 -0300 Subject: [PATCH 037/227] fix: eliminada botonera remote_profile_box para usar componente general button_box #15028 --- app/controllers/application_controller.rb | 7 ++++++- app/controllers/moderation_queue_controller.rb | 1 + app/views/moderation_queue/_profile_button_box.haml | 12 ------------ app/views/moderation_queue/_remote_profile.haml | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) delete mode 100644 app/views/moderation_queue/_profile_button_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 360a9b2d..bcbf0bc2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,7 +37,7 @@ class ApplicationController < ActionController::Base end end - # parámetros de botones + # parámetros de botones: # text: [texto del botón] # class: [clases css] # href: [href del botón] @@ -48,6 +48,11 @@ class ApplicationController < ActionController::Base [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 diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 04a31389..5141990e 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -15,6 +15,7 @@ class ModerationQueueController < ApplicationController # 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 diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml deleted file mode 100644 index d15b6ed0..00000000 --- a/app/views/moderation_queue/_profile_button_box.haml +++ /dev/null @@ -1,12 +0,0 @@ --# Componente Botonera de Profile - -.d-flex.py-2.justify-content-center - -# parámetros de botones - -# text, class, href - - comment_btn_params = [[t('.text_deny'), 'btn-outline-info', ''], - [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], - [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - - comment_btn_params.each do |btn| - - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index b665dcf2..a8d60c60 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -2,4 +2,4 @@ %h4= 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/profile_button_box' + = render 'moderation_queue/button_box', comment_btn_params: @profile_btn_params From e9552776af79f8608bed502eef779f609238a532 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:40:14 -0300 Subject: [PATCH 038/227] =?UTF-8?q?feat:=20pantalla=20de=20actividades=20d?= =?UTF-8?q?e=20moderaci=C3=B3n=20dividida=20en=20desplegables=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comments.haml | 5 +++++ app/views/moderation_queue/index.haml | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 app/views/moderation_queue/_comments.haml diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml new file mode 100644 index 00000000..39ac74a3 --- /dev/null +++ b/app/views/moderation_queue/_comments.haml @@ -0,0 +1,5 @@ += render 'moderation_queue/comment_filter_box' +- @moderation_queue.each do |comment| + + = render 'comment', comment: comment, profile: @remote_profile + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 39ac74a3..e2adb13b 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,8 @@ -= render 'moderation_queue/comment_filter_box' -- @moderation_queue.each do |comment| +.row.justify-content-center + .col-md-8 + - @summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: @summary do + = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue + + - = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file From 683062da02094a362a56bc13751065503b1d8237 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:47:40 -0300 Subject: [PATCH 039/227] =?UTF-8?q?feat:=20textos=20con=20traducciones=20p?= =?UTF-8?q?ara=20los=20t=C3=ADtulos=20de=20los=20details=20de=20actividade?= =?UTF-8?q?s=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 +- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index e2adb13b..8f4ed5fb 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,6 +1,6 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.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 diff --git a/config/locales/en.yml b/config/locales/en.yml index ef14f51f..9b8bb92b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,9 @@ en: moderation_queue: + index: + instances: Instances + accounts: Accounts + comments: Comments remote_profile: user: Username button_box: diff --git a/config/locales/es.yml b/config/locales/es.yml index 7850bcf7..ddf8f7f7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,5 +1,9 @@ es: moderation_queue: + index: + instances: Instancias + accounts: Cuentas + comments: Comentarios comment: source_profile: Cuenta de Origen reply_to: En respuesta a From a9efe78c0b93b44fed443c83a363d3e13b6fb60f Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:53:25 -0300 Subject: [PATCH 040/227] =?UTF-8?q?feat:=20aparecen=20todos=20los=20detail?= =?UTF-8?q?s=20en=20actividades=20de=20moderaci=C3=B3n,=20con=20los=20t?= =?UTF-8?q?=C3=ADtulos=20correspondientes,=20sin=20contenido=20(salvo=20co?= =?UTF-8?q?mentarios)=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_accounts.haml | 0 app/views/moderation_queue/_instances.haml | 0 app/views/moderation_queue/index.haml | 6 ++++++ 3 files changed, 6 insertions(+) create mode 100644 app/views/moderation_queue/_accounts.haml create mode 100644 app/views/moderation_queue/_instances.haml diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 8f4ed5fb..d89c30b4 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,11 @@ .row.justify-content-center .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 + - @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 From da1f7f775447e2d8f50dd9973628fb93353c308c Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 2 Feb 2024 14:45:25 -0300 Subject: [PATCH 041/227] fix: corregida botonera remote_profile #15080 --- app/controllers/application_controller.rb | 9 +++++---- app/views/moderation_queue/_button_box.haml | 4 ++-- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 10 +++++++--- app/views/posts/_moderation_queue.haml | 2 +- config/locales/es.yml | 6 ++++-- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bcbf0bc2..ba5dd4bd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -43,16 +43,17 @@ class ApplicationController < ActionController::Base # href: [href del botón] def botoneras_moderation_queue # botones de comentarios - @comment_btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], + @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/']] + @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', '']] end def notify_unconfirmed_email diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index a56b2552..46963b0f 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -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] \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 39ac74a3..fb83fbd9 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,4 +2,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file + = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index a8d60c60..94737a34 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,9 @@ +-# Componente Remote_Profile + .flex.py-2.mx-2.text-center - %h4= t('.profile_name') + ': ' + remote_profile['name'] - %h5= t('.profile_id') + ': ' + remote_profile['id'] + %h4.mb-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 diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e4eb422c..b259cf3e 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - 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 diff --git a/config/locales/es.yml b/config/locales/es.yml index ddf8f7f7..feca0897 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -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 From cfae99ca7b3a001c735a45ac207288d8f57f606d Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 2 Feb 2024 15:06:36 -0300 Subject: [PATCH 042/227] feat: agregada botonera instancias #15081 --- app/controllers/application_controller.rb | 5 +++++ config/locales/es.yml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ba5dd4bd..fd714a41 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -54,6 +54,11 @@ class ApplicationController < ActionController::Base [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 def notify_unconfirmed_email diff --git a/config/locales/es.yml b/config/locales/es.yml index feca0897..476d75b3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -28,6 +28,10 @@ es: text_order: Ordenar por text_show: Ver text_checked: Con los marcados + instances_button_box: + text_check: Moderar caso por caso + text_allow: Permitir todo + text_deny: Bloquear instancia dark: Oscuro es: Castellano en: English From 40346df76dd0c047dee905091a8223ec9d35f7a4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 12:22:23 -0300 Subject: [PATCH 043/227] fix: movidas arrays de parametros de botones y filtros a helper moderation_queue_helper.rb #15077 --- app/controllers/application_controller.rb | 26 +--------- .../moderation_queue_controller.rb | 2 - app/controllers/posts_controller.rb | 1 - app/helpers/moderation_queue_helper.rb | 47 +++++++++++++++++++ .../moderation_queue/_comment_filter_box.haml | 6 --- app/views/moderation_queue/_comments.haml | 4 +- app/views/moderation_queue/_filter_base.haml | 7 ++- app/views/moderation_queue/_filter_box.haml | 6 +++ .../moderation_queue/_remote_profile.haml | 1 + app/views/posts/_moderation_queue.haml | 4 +- config/locales/es.yml | 7 ++- 11 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 app/helpers/moderation_queue_helper.rb delete mode 100644 app/views/moderation_queue/_comment_filter_box.haml create mode 100644 app/views/moderation_queue/_filter_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fd714a41..f673ee83 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,31 +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 - @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 - + def notify_unconfirmed_email return unless current_usuarie return if current_usuarie.confirmed? diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 5141990e..4a65f136 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -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 diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 36d17339..5be56acc 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -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 diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb new file mode 100644 index 00000000..9c0a3ced --- /dev/null +++ b/app/helpers/moderation_queue_helper.rb @@ -0,0 +1,47 @@ +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 + @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'] + ] + } + end +end \ No newline at end of file diff --git a/app/views/moderation_queue/_comment_filter_box.haml b/app/views/moderation_queue/_comment_filter_box.haml deleted file mode 100644 index e9abe602..00000000 --- a/app/views/moderation_queue/_comment_filter_box.haml +++ /dev/null @@ -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') \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index fb83fbd9..217919bd 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,4 +1,6 @@ -= render 'moderation_queue/comment_filter_box' +- filtros_moderation_queue +- botoneras_moderation_queue += render 'moderation_queue/filter_box', filter_params: @comment_filter_params - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 0b63e59b..01d50641 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -1,8 +1,7 @@ -# 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} + %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 + - menu.each do |subm| + %a.dropdown-item{ href: subm[1] } subm[0] diff --git a/app/views/moderation_queue/_filter_box.haml b/app/views/moderation_queue/_filter_box.haml new file mode 100644 index 00000000..4ebef670 --- /dev/null +++ b/app/views/moderation_queue/_filter_box.haml @@ -0,0 +1,6 @@ +-# Componente Caja de Filtros + +.d-flex.py-2.justify-content-center + - filter_params.each do |filter, submenu| + = render 'moderation_queue/filter_base', text: filter, menu: submenu + diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 94737a34..548e2d5b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,6 +1,7 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center + - botoneras_moderation_queue %h4.mb-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') diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index b259cf3e..34af2ac6 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,8 @@ .flex %h3.text-center.py-2 Comentarios - = render 'moderation_queue/comment_filter_box' + - botoneras_moderation_queue + - filtros_moderation_queue + = render 'moderation_queue/filter_box', filter_params: @comment_filter_params - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center diff --git a/config/locales/es.yml b/config/locales/es.yml index 476d75b3..20696af0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -24,10 +24,13 @@ 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 instances_button_box: text_check: Moderar caso por caso text_allow: Permitir todo From c668c3ad3f735760fd05a9fce9a49af3c201d78a Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 12:30:13 -0300 Subject: [PATCH 044/227] fix: corregido submenu en partial filter_base #15079 --- app/views/moderation_queue/_filter_base.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 01d50641..67bb4b0c 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -4,4 +4,4 @@ %span= text .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} - menu.each do |subm| - %a.dropdown-item{ href: subm[1] } subm[0] + %a.dropdown-item{ href: subm[1] }= subm[0] From cfe90c531ea9be1429cf146db39df3ad0528c26e Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 13:03:29 -0300 Subject: [PATCH 045/227] feat: agregado filtros instancias #15083 --- app/helpers/moderation_queue_helper.rb | 16 ++++++++++++++++ app/views/moderation_queue/_accounts.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 6 ++++++ config/locales/es.yml | 2 ++ 4 files changed, 28 insertions(+) diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb index 9c0a3ced..16be2a51 100644 --- a/app/helpers/moderation_queue_helper.rb +++ b/app/helpers/moderation_queue_helper.rb @@ -28,6 +28,7 @@ module ModerationQueueHelper # 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') => [ @@ -43,5 +44,20 @@ module ModerationQueueHelper [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 \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e69de29b..8ee71e7f 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -0,0 +1,4 @@ +- filtros_moderation_queue +- botoneras_moderation_queue + += render 'moderation_queue/button_box', btn_params: @profile_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e69de29b..a814c1da 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -0,0 +1,6 @@ +- filtros_moderation_queue +- botoneras_moderation_queue + += render 'moderation_queue/filter_box', filter_params: @instances_filter_params + += render 'moderation_queue/button_box', btn_params: @instances_btn_params \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 20696af0..b4b7b1f4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -31,6 +31,8 @@ es: 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 From 600a87c5ec2d4d4b4af2f9d2c40505b75269bcc8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 13:13:06 -0300 Subject: [PATCH 046/227] feat: agregado filtros de cuentas #15102 --- app/views/moderation_queue/_accounts.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 8ee71e7f..ae87a9d7 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,4 +1,6 @@ - filtros_moderation_queue - botoneras_moderation_queue += render 'moderation_queue/filter_box', filter_params: @instances_filter_params + = render 'moderation_queue/button_box', btn_params: @profile_btn_params \ No newline at end of file From 58ee39828a4cf048642c931b9c6c9607b6ceecfe Mon Sep 17 00:00:00 2001 From: f Date: Mon, 5 Feb 2024 13:16:57 -0300 Subject: [PATCH 047/227] feat: dropdown #15097 implement #15097 --- .../controllers/dropdown_controller.js | 106 ++++++++++++++++++ app/views/components/_dropdown.haml | 34 ++++++ app/views/components/_dropdown_item.haml | 4 + 3 files changed, 144 insertions(+) create mode 100644 app/javascript/controllers/dropdown_controller.js create mode 100644 app/views/components/_dropdown.haml create mode 100644 app/views/components/_dropdown_item.haml diff --git a/app/javascript/controllers/dropdown_controller.js b/app/javascript/controllers/dropdown_controller.js new file mode 100644 index 00000000..e2b657fd --- /dev/null +++ b/app/javascript/controllers/dropdown_controller.js @@ -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); + } + } +} diff --git a/app/views/components/_dropdown.haml b/app/views/components/_dropdown.haml new file mode 100644 index 00000000..54ddcffb --- /dev/null +++ b/app/views/components/_dropdown.haml @@ -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 diff --git a/app/views/components/_dropdown_item.haml b/app/views/components/_dropdown_item.haml new file mode 100644 index 00000000..3f79403d --- /dev/null +++ b/app/views/components/_dropdown_item.haml @@ -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' } From f9952792987bd12ec81ab4542d5c7647b5c1121d Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 14:51:17 -0300 Subject: [PATCH 048/227] fix: corregidos filtros desplegables de comentarios, cuentas e instancias #15097 --- app/views/moderation_queue/_accounts.haml | 9 ++++++++- app/views/moderation_queue/_comments.haml | 13 +++++++++++-- app/views/moderation_queue/_filter_base.haml | 7 ------- app/views/moderation_queue/_filter_box.haml | 6 ------ app/views/moderation_queue/_instances.haml | 10 ++++++++-- app/views/moderation_queue/_remote_profile.haml | 14 +++++++++++++- app/views/posts/_moderation_queue.haml | 13 +++++++++++-- 7 files changed, 51 insertions(+), 21 deletions(-) delete mode 100644 app/views/moderation_queue/_filter_base.haml delete mode 100644 app/views/moderation_queue/_filter_box.haml diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index ae87a9d7..6a371eff 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,13 @@ - filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @instances_filter_params +.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 \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 217919bd..3daddf44 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,6 +1,15 @@ -- filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @comment_filter_params +.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 diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml deleted file mode 100644 index 67bb4b0c..00000000 --- a/app/views/moderation_queue/_filter_base.haml +++ /dev/null @@ -1,7 +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"} - - menu.each do |subm| - %a.dropdown-item{ href: subm[1] }= subm[0] diff --git a/app/views/moderation_queue/_filter_box.haml b/app/views/moderation_queue/_filter_box.haml deleted file mode 100644 index 4ebef670..00000000 --- a/app/views/moderation_queue/_filter_box.haml +++ /dev/null @@ -1,6 +0,0 @@ --# Componente Caja de Filtros - -.d-flex.py-2.justify-content-center - - filter_params.each do |filter, submenu| - = render 'moderation_queue/filter_base', text: filter, menu: submenu - diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a814c1da..15b933d6 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,12 @@ -- filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @instances_filter_params +.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 \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 548e2d5b..7256f41d 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -2,7 +2,19 @@ .flex.py-2.mx-2.text-center - botoneras_moderation_queue - %h4.mb-2= t('.profile_name') + ': ' + remote_profile['name'] + + .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') %h5= t('.profile_summary') + ':' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 34af2ac6..f805dfe8 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,8 +1,17 @@ .flex %h3.text-center.py-2 Comentarios - botoneras_moderation_queue - - filtros_moderation_queue - = render 'moderation_queue/filter_box', filter_params: @comment_filter_params + .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 From 6374a616d49f725f273da08bd44bbb7b5e209725 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 15:22:28 -0300 Subject: [PATCH 049/227] feat: agregado componente listas de bloqueo de instancias #15103 --- app/views/moderation_queue/_block_lists.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 6 +++++- config/locales/es.yml | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_block_lists.haml diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml new file mode 100644 index 00000000..186452fa --- /dev/null +++ b/app/views/moderation_queue/_block_lists.haml @@ -0,0 +1,4 @@ +.flex + .card + .card-body + %h4.text-center.red= t('moderation_queue.instances.block_lists') \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 15b933d6..57d4be34 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,4 +9,8 @@ = 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 \ No newline at end of file += 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' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index b4b7b1f4..6c608fff 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -37,6 +37,10 @@ es: 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 dark: Oscuro es: Castellano en: English From db0364522db129ca62451ef2d81a7f80017f50d6 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 15:39:53 -0300 Subject: [PATCH 050/227] fix: agregado checkbox a compo listas de bloqueo #15103 --- app/views/moderation_queue/_block_lists.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 186452fa..55dc56d7 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,4 +1,5 @@ .flex .card - .card-body - %h4.text-center.red= t('moderation_queue.instances.block_lists') \ No newline at end of file + .card-body + %input{type: 'checkbox', value: '', class: 'ml-5'} + %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file From b949855f08f6b2dfdc7fed3f0255eabfa2429f43 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 16:19:35 -0300 Subject: [PATCH 051/227] feat: creado componente lista personalizada de bloqueo de instancias #15104 --- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 3 ++- config/locales/es.yml | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_block_instances_textarea.haml diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml new file mode 100644 index 00000000..42001504 --- /dev/null +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -0,0 +1,4 @@ +.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') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 57d4be34..c03055fa 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -13,4 +13,5 @@ %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') -= render 'moderation_queue/block_lists' \ No newline at end of file += render 'moderation_queue/block_lists' += render 'moderation_queue/block_instances_textarea' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 6c608fff..96f068f3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -41,6 +41,8 @@ es: 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 From fc99ec79d3bd74d01084b25b3c25baa1b5ef2ca2 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 6 Feb 2024 12:57:42 -0300 Subject: [PATCH 052/227] fix: correciones de CI varias --- app/views/layouts/_details.haml | 4 ++-- .../moderation_queue/_block_instances_textarea.haml | 5 +++-- app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 2 +- app/views/moderation_queue/_comment.haml | 10 +++++----- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 2 +- app/views/moderation_queue/index.haml | 5 +---- app/views/posts/_moderation_queue.haml | 2 +- 11 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 4fe4d2af..1fe8d2ec 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,6 +1,6 @@ -# Detail Cola de Moderación %details.details.py-2 - %summary + %summary %h3.py-2.text-center= @summary - = yield \ No newline at end of file + = yield diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 42001504..22a63c39 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +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') + %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') + diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 55dc56d7..669d451a 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ .flex .card .card-body - %input{type: 'checkbox', value: '', class: 'ml-5'} + %input{ type: 'checkbox', value: '', class: 'ml-5' } %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 5f4561ef..0f9d7c08 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.btn-lg.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file +%a.btn.btn-lg.rounded.mx-2{role: 'button', href: href, class: @class} #{text} diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index 46963b0f..8971a780 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -3,4 +3,4 @@ .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] \ No newline at end of file + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d443802d..d3532734 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -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'] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 3daddf44..39c8cfae 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -10,7 +10,7 @@ = 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| +- moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c03055fa..811aeaec 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,4 +14,4 @@ %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' \ No newline at end of file += render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 7256f41d..b50d63e6 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -15,7 +15,7 @@ = 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_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index d89c30b4..1a9838de 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -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 - - - diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f805dfe8..34e30538 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -11,7 +11,7 @@ = 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 From 462d9a698eb69db27ec01bd1d4b2a36c119d9284 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 13:56:20 -0300 Subject: [PATCH 053/227] para pullear --- app/views/moderation_queue/_accounts.haml | 3 +++ app/views/moderation_queue/_instances.haml | 1 + 2 files changed, 4 insertions(+) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e69de29b..5250ae87 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -0,0 +1,3 @@ += render 'moderation_queue/comment_filter_box' +- @moderation_queue.each do |comment| + = render 'account', comment: comment, profile: @remote_profile \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e69de29b..e279f484 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -0,0 +1 @@ += render 'moderation_queue/comment_filter_box' From c8267c44e85369a9d1ac9319b3816bcc4fa69934 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 14:08:15 -0300 Subject: [PATCH 054/227] =?UTF-8?q?fix:=20error=20de=20merge=20y=20error?= =?UTF-8?q?=20de=20indentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 0 app/views/moderation_queue/_accounts.haml | 3 +-- app/views/moderation_queue/_instances.haml | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 app/views/moderation_queue/_account.haml diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 9300665b..26485119 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,5 @@ -= 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 diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1d083d27..811aeaec 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,4 +1,3 @@ -= render 'moderation_queue/comment_filter_box' - botoneras_moderation_queue .d-flex.py-2.justify-content-center From 6b0d2ded91f2dbbb7286457ae3b094af8d87a130 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 16:50:26 -0300 Subject: [PATCH 055/227] =?UTF-8?q?feat:=20apartado=20de=20cuentas=20dentr?= =?UTF-8?q?o=20de=20actividades=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 10 +++------- app/views/moderation_queue/_account.haml | 2 ++ app/views/moderation_queue/_accounts.haml | 5 ++--- config/locales/es.yml | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 4a65f136..eec0c70f 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,21 +4,17 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) - @moderation_queue.each do |activity| - activity['attributedTo'] = @remote_profile - end + dummy_data end # Perfil remoto de usuarie def remote_profile - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + dummy_data end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances - @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + dummy_data end end diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index e69de29b..751d0c0e 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -0,0 +1,2 @@ +%a{href: profile['id']}= profile['preferredUsername'] +%p= sanitize profile['summary'] \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 26485119..fcdfdce6 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,3 @@ -- @moderation_queue.each do |comment| - = render 'account', comment: comment, profile: @remote_profile -- filtros_moderation_queue - botoneras_moderation_queue .d-flex.py-2.justify-content-center @@ -12,4 +9,6 @@ = 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: '/' +- @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| + = render 'account', profile: remote_profile = render 'moderation_queue/button_box', btn_params: @profile_btn_params diff --git a/config/locales/es.yml b/config/locales/es.yml index 96f068f3..8828ee9f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -14,7 +14,7 @@ es: profile_published: Publicada profile_summary: Resumen profile_button_box: - text_approve: Aprovar siempre + text_approve: Aprobar siempre text_check: Revisar siempre text_deny: Bloquear text_report: Reportar From ab1186d08a12c4adc10c3cb3f1b548b70b6030b1 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 17:22:44 -0300 Subject: [PATCH 056/227] =?UTF-8?q?feat:=20apartado=20de=20instancias=20de?= =?UTF-8?q?ntro=20de=20actividades=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 11 +++++++++++ app/views/moderation_queue/_instances.haml | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_instance.haml diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml new file mode 100644 index 00000000..d3b56a03 --- /dev/null +++ b/app/views/moderation_queue/_instance.haml @@ -0,0 +1,11 @@ +- host = instance['domain'] +- host ||= instance['uri'] +- host = "https://#{host}" + + +%a{href: host}= instance['title'] +%p= instance['description'] +%span Users: +%span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 811aeaec..88a1e11c 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,7 +9,9 @@ = 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 +- @instances.each do |instance| + = render 'moderation_queue/instance', instance: instance + = 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') From f9a7d8d21ac031720d41fe0f6fce28475fc95304 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 17:27:07 -0300 Subject: [PATCH 057/227] =?UTF-8?q?feat:=20t=C3=ADtulo=20para=20actividade?= =?UTF-8?q?s=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 ++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 4 insertions(+) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 1a9838de..43b83b83 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,5 @@ +.row.justify-content-center.mb-5 + %h1= t('moderation_queue.index.title') .row.justify-content-center .col-md-8 - @summary = t('moderation_queue.index.instances') diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b8bb92b..9b06a78d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,6 +1,7 @@ en: moderation_queue: index: + title: Moderation instances: Instances accounts: Accounts comments: Comments diff --git a/config/locales/es.yml b/config/locales/es.yml index 8828ee9f..f1b5f2e5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,6 +1,7 @@ es: moderation_queue: index: + title: Actividades de moderación instances: Instancias accounts: Cuentas comments: Comentarios From dbdce703c3e40065e7b9588e44ec38420e990bfd Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 14:42:25 -0300 Subject: [PATCH 058/227] fix: corregidos botones en comentarios, instancias y cuentas #15028 --- app/helpers/moderation_queue_helper.rb | 63 ------------------- app/views/moderation_queue/_accounts.haml | 15 ++++- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 6 -- app/views/moderation_queue/_comments.haml | 16 ++++- app/views/moderation_queue/_instances.haml | 14 ++++- .../moderation_queue/_remote_profile.haml | 15 ++++- app/views/posts/_moderation_queue.haml | 17 ++++- 8 files changed, 64 insertions(+), 84 deletions(-) delete mode 100644 app/helpers/moderation_queue_helper.rb delete mode 100644 app/views/moderation_queue/_button_box.haml diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb deleted file mode 100644 index 16be2a51..00000000 --- a/app/helpers/moderation_queue_helper.rb +++ /dev/null @@ -1,63 +0,0 @@ -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 \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index fcdfdce6..825b77c2 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,4 @@ -- botoneras_moderation_queue - +-# Filtros .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: '/' @@ -11,4 +10,14 @@ - @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| = render 'account', profile: remote_profile -= render 'moderation_queue/button_box', btn_params: @profile_btn_params + +-# Botones de Moderación +.d-flex.py-4.justify-content-center + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 0f9d7c08..41349ec5 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.btn-lg.rounded.mx-2{role: 'button', href: href, class: @class} #{text} +%button.btn.btn-lg.rounded.mx-2{ href: href, class: @class } #{text} diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml deleted file mode 100644 index 8971a780..00000000 --- a/app/views/moderation_queue/_button_box.haml +++ /dev/null @@ -1,6 +0,0 @@ --# Componente Botonera de Moderación - -.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] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 39c8cfae..8bb11eec 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,4 +1,4 @@ -- botoneras_moderation_queue +-# Filtros .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: '/' @@ -13,4 +13,16 @@ - moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' + - @class = 'btn-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' + - @class = 'btn-outline-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 88a1e11c..7af106ee 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,4 @@ -- botoneras_moderation_queue - +-# Filtros .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: '/' @@ -11,7 +10,16 @@ - @instances.each do |instance| = render 'moderation_queue/instance', instance: instance - = render 'moderation_queue/button_box', btn_params: @instances_btn_params + + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index b50d63e6..a972b051 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,8 +1,7 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center - - botoneras_moderation_queue - + -# Filtros .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: '/' @@ -19,4 +18,14 @@ %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] - = render 'moderation_queue/button_box', btn_params: @profile_btn_params + +-# Botones de Moderación +.d-flex.py-4.justify-content-center + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 34e30538..e7bbfd22 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,6 @@ .flex %h3.text-center.py-2 Comentarios - - botoneras_moderation_queue + -# Filtros .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: '/' @@ -14,5 +14,16 @@ - 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', btn_params: @btn_params + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' + - @class = 'btn-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' + - @class = 'btn-outline-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' From 9ffd49aae2d116e6077341e20409b4f6a082590f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 15:03:48 -0300 Subject: [PATCH 059/227] fix: corregida vista remote_profile --- app/views/moderation_queue/_remote_profile.haml | 4 ++++ config/locales/es.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index a972b051..4a5e806f 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -19,6 +19,10 @@ %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] + = render 'moderation_queue/comments', moderation_queue: @moderation_queue + +%h3.text-center.pt-4= t('.profile') +%h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación .d-flex.py-4.justify-content-center - @class = 'btn-success' diff --git a/config/locales/es.yml b/config/locales/es.yml index f1b5f2e5..1127f357 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -9,7 +9,7 @@ es: source_profile: Cuenta de Origen reply_to: En respuesta a remote_profile: - profile: Cuentas + profile: Cuenta de Origen profile_name: Nombre de la Cuenta profile_id: ID profile_published: Publicada From 60950400086691f7cb38d3356baa25a773dfef2f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 15:06:04 -0300 Subject: [PATCH 060/227] fix: corregidos filtros vista remote_profile --- app/views/moderation_queue/_remote_profile.haml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 4a5e806f..6afa2ed0 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,17 +1,6 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center - -# Filtros - .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'] From d5bfbc578f9751d778695eb4c0c99b55fe6a4ba9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 17:12:00 -0300 Subject: [PATCH 061/227] fix: correcciones varias de CI --- app/views/moderation_queue/_accounts.haml | 3 ++- app/views/moderation_queue/_block_lists.haml | 6 +++--- app/views/moderation_queue/_instance.haml | 7 +++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 825b77c2..5c58f88b 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -8,7 +8,7 @@ = 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: '/' -- @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| +- @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| = render 'account', profile: remote_profile -# Botones de Moderación @@ -21,3 +21,4 @@ = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - @class = 'btn-danger' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' + \ No newline at end of file diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 669d451a..fdb3f044 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ -.flex - .card +.flex + .card .card-body %input{ type: 'checkbox', value: '', class: 'ml-5' } - %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file + %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index d3b56a03..80114985 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -2,10 +2,9 @@ - host ||= instance['uri'] - host = "https://#{host}" - -%a{href: host}= instance['title'] +%a{ href: host }= instance['title'] %p= instance['description'] %span Users: %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') From a32a3ce7db29636ba854eecea3d5bc18d22d41cc Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 17:59:57 -0300 Subject: [PATCH 062/227] fix: corregidos colores de botones y details --- app/assets/stylesheets/application.scss | 19 +++---------------- app/views/moderation_queue/_accounts.haml | 8 ++++---- .../_block_instances_textarea.haml | 2 +- app/views/moderation_queue/_comments.haml | 8 ++++---- app/views/moderation_queue/_instances.haml | 10 +++++----- .../moderation_queue/_remote_profile.haml | 8 ++++---- app/views/posts/_moderation_queue.haml | 8 ++++---- 7 files changed, 25 insertions(+), 38 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c0a666ab..836d647f 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -3,7 +3,6 @@ $white: white; $grey: grey; $cyan: #13fefe; $magenta: #f206f9; -$blue: blue; $colors: ( "black": $black, @@ -15,7 +14,6 @@ $colors: ( // Redefinir variables de Bootstrap $primary: $magenta; $secondary: $black; -$info: $blue; $jumbotron-bg: transparent; $enable-rounded: false; $form-feedback-valid-color: $black; @@ -569,26 +567,15 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); &::after { content: '▶'; - font-size: 2rem; + font-size: 1.7rem; position: absolute; left: 97%; - bottom: 2%; - transform: rotate(55deg); - color: $magenta - } - - &:focus { - background-color: #13FEFE; - color: black + bottom: 3%; + transform: rotate(58deg); } } .details[open] > summary::after { transform: rotate(90deg) translatey(-0.1em); - color: $magenta } -.bg-blue { - background-color: $azul; -} - diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5c58f88b..540d13a2 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -13,12 +13,12 @@ -# Botones de Moderación .d-flex.py-4.justify-content-center - - @class = 'btn-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-outline-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 22a63c39..4f294f0b 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +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') + %button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 8bb11eec..d7d300b7 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -18,11 +18,11 @@ .d-flex.py-4.justify-content-center - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-outline-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 7af106ee..ed5d2404 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,12 +14,12 @@ -# Botones moderación .d-flex.py-4.justify-content-center - - @class = 'btn-outline-success' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-success' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 6afa2ed0..755e96fd 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -14,11 +14,11 @@ %h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación .d-flex.py-4.justify-content-center - - @class = 'btn-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-outline-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e7bbfd22..f2acb818 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -19,11 +19,11 @@ .d-flex.py-4.justify-content-center - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-outline-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' From 33cf101b5953fa18c82047a30d1f8593ff6ff26a Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 14:41:50 -0300 Subject: [PATCH 063/227] =?UTF-8?q?fix:=20quitada=20alineaci=C3=B3n=20cent?= =?UTF-8?q?rada=20varios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 ++-- app/controllers/posts_controller.rb | 2 +- app/views/layouts/_details.haml | 2 +- app/views/moderation_queue/_accounts.haml | 7 ++----- .../moderation_queue/_block_instances_textarea.haml | 5 +++-- app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_comments.haml | 8 ++------ app/views/moderation_queue/_instances.haml | 12 +++++------- app/views/moderation_queue/_remote_profile.haml | 12 +++++------- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 6 +++--- 12 files changed, 27 insertions(+), 37 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 836d647f..5419bcdd 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -567,11 +567,11 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); &::after { content: '▶'; - font-size: 1.7rem; + font-size: 1.8rem; position: absolute; left: 97%; bottom: 3%; - transform: rotate(58deg); + transform: rotate(64deg); } } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5be56acc..99dc6f7d 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -38,7 +38,7 @@ class PostsController < ApplicationController @usuarie = site.usuarie? current_usuarie @site_stat = SiteStat.new(site) - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + dummy_data end def show diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 1fe8d2ec..ac1d7c82 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,5 @@ %details.details.py-2 %summary - %h3.py-2.text-center= @summary + %h3.py-2= @summary = yield diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 540d13a2..1885059e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = 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: '/' @@ -12,13 +12,10 @@ = render 'account', profile: remote_profile -# Botones de Moderación -.d-flex.py-4.justify-content-center +.d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 4f294f0b..34eb1e5d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,6 @@ .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-secondary' }= t('moderation_queue.instances.submit') + %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } + .d-flex.justify-content-end + %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index fdb3f044..577af12e 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -2,4 +2,4 @@ .card .card-body %input{ type: 'checkbox', value: '', class: 'ml-5' } - %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') + %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 41349ec5..7f6233cd 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.btn-lg.rounded.mx-2{ href: href, class: @class } #{text} +%button.btn.btn-lg.mx-2{ href: href, class: @class }= text diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d7d300b7..9a9c9454 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = 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: '/' @@ -15,14 +15,10 @@ = render 'comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4.justify-content-center + .d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index ed5d2404..38f4ad51 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = 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: '/' @@ -13,15 +13,13 @@ -# Botones moderación - .d-flex.py-4.justify-content-center - - @class = 'btn-secondary' + .d-flex.py-4 + - @class = 'btn btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' -%h3.cyan.mt-5= t('moderation_queue.instances.title') -%p.pb-2= t('moderation_queue.instances.description') +%h3.mt-5= t('moderation_queue.instances.title') +%p= t('moderation_queue.instances.description') = render 'moderation_queue/block_lists' = render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 755e96fd..965f8854 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,6 +1,6 @@ -# Componente Remote_Profile -.flex.py-2.mx-2.text-center +.flex.py-2.mx-2 %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] @@ -10,15 +10,13 @@ = render 'moderation_queue/comments', moderation_queue: @moderation_queue -%h3.text-center.pt-4= t('.profile') -%h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] +%h3.pt-4= t('.profile') +%h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] + -# Botones de Moderación -.d-flex.py-4.justify-content-center +.d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 3eab5e35..ed66a394 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex - %h1.text-center= t('.profile') + %h1= t('.profile') = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f2acb818..6db885bb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex - %h3.text-center.py-2 Comentarios + %h3.py-2 Comentarios -# Filtros - .d-flex.py-2.justify-content-center + .d-flex.py-2 = 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: '/' @@ -16,7 +16,7 @@ = render 'moderation_queue/comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4.justify-content-center + .d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - @class = 'btn-secondary' From ffc3f4a72aa9514e061799d6b33971eba87de8ae Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 15:02:09 -0300 Subject: [PATCH 064/227] fix: corregido texto de comentarios en componente moderation_queue --- app/views/posts/_moderation_queue.haml | 1 - config/locales/es.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 6db885bb..fa6adfef 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,5 +1,4 @@ .flex - %h3.py-2 Comentarios -# Filtros .d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do diff --git a/config/locales/es.yml b/config/locales/es.yml index 1127f357..fd1626e3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -566,7 +566,7 @@ es: ar: 'árabe' posts: edit: - moderation_queue: Cola de Moderación + moderation_queue: Comentarios post: Contenido prev: Página anterior next: Página siguiente From 47de966f69a4558980080a1c5c97d6b8857aa0df Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 17:59:10 -0300 Subject: [PATCH 065/227] fix: cambiadas variables globales por locales --- app/views/layouts/_details.haml | 2 +- app/views/moderation_queue/_comments.haml | 11 +---------- app/views/moderation_queue/index.haml | 14 +++++++------- app/views/posts/edit.haml | 8 ++++---- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index ac1d7c82..306986bf 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,5 @@ %details.details.py-2 %summary - %h3.py-2= @summary + %h3.py-2= summary = yield diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 9a9c9454..e4285326 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,5 @@ -# Filtros -.d-flex.py-2 - = 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: '/' += render 'moderation_queue/filter_box' - moderation_queue.each do |comment| diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 43b83b83..b361c085 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,13 +1,13 @@ .row.justify-content-center.mb-5 - %h1= t('moderation_queue.index.title') + %h1= t('.title') .row.justify-content-center .col-md-8 - - @summary = t('moderation_queue.index.instances') - = render 'layouts/details', summary: @summary do + - summary = t('.instances') + = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue - - @summary = t('moderation_queue.index.accounts') - = render 'layouts/details', summary: @summary do + - summary = t('.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 + - summary = t('.comments') + = render 'layouts/details', summary: summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 5234f257..2e46590e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,8 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.post') - = render 'layouts/details', summary: @summary do + - summary = t('posts.edit.post') + = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post - - @summary = t('posts.edit.moderation_queue') - = render 'layouts/details', summary: @summary do + - summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From 111f2d65030bae4ce010e26b09eac2bfdfe60c86 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 12:01:04 -0300 Subject: [PATCH 066/227] fix: creados componentes de filtros para comentarios, cuentas e instancias --- .../components/_comments_checked_submenu.haml | 3 ++ app/views/components/_comments_filters.haml | 6 +++ .../components/_comments_show_submenu.haml | 4 ++ .../_instances_checked_submenu.haml | 3 ++ app/views/components/_instances_filters.haml | 6 +++ .../components/_instances_show_submenu.haml | 2 + .../components/_profiles_checked_submenu.haml | 4 ++ app/views/components/_profiles_filters.haml | 6 +++ .../components/_profiles_show_submenu.haml | 3 ++ app/views/moderation_queue/_accounts.haml | 9 +--- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 10 +--- app/views/posts/_moderation_queue.haml | 11 +---- config/locales/es.yml | 47 +++++++++++++++---- 14 files changed, 79 insertions(+), 37 deletions(-) create mode 100644 app/views/components/_comments_checked_submenu.haml create mode 100644 app/views/components/_comments_filters.haml create mode 100644 app/views/components/_comments_show_submenu.haml create mode 100644 app/views/components/_instances_checked_submenu.haml create mode 100644 app/views/components/_instances_filters.haml create mode 100644 app/views/components/_instances_show_submenu.haml create mode 100644 app/views/components/_profiles_checked_submenu.haml create mode 100644 app/views/components/_profiles_filters.haml create mode 100644 app/views/components/_profiles_show_submenu.haml diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml new file mode 100644 index 00000000..4998e5c7 --- /dev/null +++ b/app/views/components/_comments_checked_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml new file mode 100644 index 00000000..7c453088 --- /dev/null +++ b/app/views/components/_comments_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/comments_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/comments_show_submenu' \ No newline at end of file diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml new file mode 100644 index 00000000..0308b926 --- /dev/null +++ b/app/views/components/_comments_show_submenu.haml @@ -0,0 +1,4 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_report'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml new file mode 100644 index 00000000..f0b76185 --- /dev/null +++ b/app/views/components/_instances_checked_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_case'), path: '/' += render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml new file mode 100644 index 00000000..213bb7c0 --- /dev/null +++ b/app/views/components/_instances_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/instances_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/comments_show_submenu' diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml new file mode 100644 index 00000000..1074cc3f --- /dev/null +++ b/app/views/components/_instances_show_submenu.haml @@ -0,0 +1,2 @@ += render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml new file mode 100644 index 00000000..8d8f8940 --- /dev/null +++ b/app/views/components/_profiles_checked_submenu.haml @@ -0,0 +1,4 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml new file mode 100644 index 00000000..0088afef --- /dev/null +++ b/app/views/components/_profiles_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/profiles_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/profiles_show_submenu' \ No newline at end of file diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml new file mode 100644 index 00000000..2ba949b1 --- /dev/null +++ b/app/views/components/_profiles_show_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 1885059e..e954d2f3 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,5 @@ -# Filtros -.d-flex.py-2 - = 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 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| = render 'account', profile: remote_profile diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index e4285326..c5f7ae5d 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ -# Filtros -= render 'moderation_queue/filter_box' += render 'components/comments_filters' - moderation_queue.each do |comment| diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 38f4ad51..e50a6e02 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,17 +1,9 @@ -# Filtros -.d-flex.py-2 - = 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 'components/instances_filters' - @instances.each do |instance| = render 'moderation_queue/instance', instance: instance - -# Botones moderación .d-flex.py-4 - @class = 'btn btn-secondary' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index fa6adfef..df17b1ff 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,15 +1,6 @@ .flex -# Filtros - .d-flex.py-2 - = 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: '/' + = render 'components/comments_filters' - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile diff --git a/config/locales/es.yml b/config/locales/es.yml index fd1626e3..7cd59cbf 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,39 @@ es: + components: + instances_filters: + text_show: Ver + text_checked: Con los marcados + instances_checked_submenu: + submenu_case: Moderar caso por caso + submenu_allow: Permitir todo + submenu_reject: Rechazado + instances_show_submenu: + submenu_allow: Permitido + submenu_reject: Rechazado + comments_filters: + text_show: Ver + text_checked: Con los marcados + comments_checked_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_reject: Rechazado + comments_show_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_report: Reportado + submenu_reject: Rechazado + profiles_filters: + text_show: Ver + text_checked: Con los marcados + profiles_checked_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_reject: Rechazado + submenu_block: Bloqueado + profiles_show_submenu: + submenu_accept: Aceptado + submenu_block: Bloqueado + submenu_reject: Rechazado moderation_queue: index: title: Actividades de moderación @@ -25,15 +60,6 @@ es: text_accept: Aceptar Publicación text_reply: Responder text_report: Reportar - 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 @@ -44,6 +70,9 @@ es: block_lists: Listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + comments_filter_box: + text_show: Ver + text_checked: Con los marcados dark: Oscuro es: Castellano en: English From 754538024efdde09cceaab35ea1680d3fe6d57c3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 13:17:00 -0300 Subject: [PATCH 067/227] feat: agregado componente checkbox --- app/views/components/_checkbox.haml | 2 ++ app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 app/views/components/_checkbox.haml diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml new file mode 100644 index 00000000..ccf22e84 --- /dev/null +++ b/app/views/components/_checkbox.haml @@ -0,0 +1,2 @@ +.custom-control.custom-checkbox + %input{ type: 'checkbox', id: '', class: '' } \ No newline at end of file diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 577af12e..14dd770e 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ .flex .card .card-body - %input{ type: 'checkbox', value: '', class: 'ml-5' } + = render 'components/checkbox' %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d3532734..463f47c7 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -2,7 +2,7 @@ .flex.mx-4.my-5 .row.no-gutters .col-1 - %input{ type: 'checkbox', id: '' } + = render 'components/checkbox' .col-10 .row.border.border-white .col.col-1.border.border-white.mr-5 From 31294ccbc7f3bba6e61d99b23fc762bdbd9bd333 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 14:15:11 -0300 Subject: [PATCH 068/227] fix: movido componente block_lists a app/views/components y corregido es.yml --- app/views/components/_block_lists.haml | 7 +++++++ app/views/moderation_queue/_block_lists.haml | 5 ----- app/views/moderation_queue/_instances.haml | 10 +++++----- config/locales/es.yml | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 app/views/components/_block_lists.haml delete mode 100644 app/views/moderation_queue/_block_lists.haml diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml new file mode 100644 index 00000000..7764dfa5 --- /dev/null +++ b/app/views/components/_block_lists.haml @@ -0,0 +1,7 @@ +-# Componente Listas de bloqueo de Instancias +.flex + .card + .card-body + .d-flex.flex-row + = render 'components/checkbox' + %h4.ml-5= t('.title') diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml deleted file mode 100644 index 14dd770e..00000000 --- a/app/views/moderation_queue/_block_lists.haml +++ /dev/null @@ -1,5 +0,0 @@ -.flex - .card - .card-body - = render 'components/checkbox' - %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e50a6e02..fc249e46 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -6,12 +6,12 @@ -# Botones moderación .d-flex.py-4 - - @class = 'btn btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' + - btn_class = 'btn btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: btn_class, href: '' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: btn_class, href: '' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: btn_class, href: '' %h3.mt-5= t('moderation_queue.instances.title') %p= t('moderation_queue.instances.description') -= render 'moderation_queue/block_lists' += render 'components/block_lists' = render 'moderation_queue/block_instances_textarea' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7cd59cbf..4aad1cc7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -34,6 +34,8 @@ es: submenu_accept: Aceptado submenu_block: Bloqueado submenu_reject: Rechazado + block_lists: + title: Listas de bloqueo moderation_queue: index: title: Actividades de moderación @@ -67,7 +69,6 @@ es: 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 comments_filter_box: From 3f288ab6e4a7806c29d472dd71f34d8d8265dd2f Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 14:45:12 -0300 Subject: [PATCH 069/227] fix: creados componentes botoneras de comentarios, instancias y cuentas, y movidos a app/views/components --- app/views/components/_btn_base.haml | 3 ++ app/views/components/_checkbox.haml | 3 +- app/views/components/_comments_btn_box.haml | 9 ++++++ app/views/components/_instances_btn_box.haml | 6 ++++ app/views/components/_profiles_btn_box.haml | 7 +++++ app/views/moderation_queue/_accounts.haml | 6 +--- app/views/moderation_queue/_btn_base.haml | 3 -- app/views/moderation_queue/_comments.haml | 8 +---- app/views/moderation_queue/_instances.haml | 7 ++--- .../moderation_queue/_remote_profile.haml | 7 +---- app/views/moderation_queue/index.haml | 6 ++-- app/views/posts/_moderation_queue.haml | 11 +------ app/views/posts/edit.haml | 4 +-- config/locales/es.yml | 30 +++++++++---------- 14 files changed, 53 insertions(+), 57 deletions(-) create mode 100644 app/views/components/_btn_base.haml create mode 100644 app/views/components/_comments_btn_box.haml create mode 100644 app/views/components/_instances_btn_box.haml create mode 100644 app/views/components/_profiles_btn_box.haml delete mode 100644 app/views/moderation_queue/_btn_base.haml diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml new file mode 100644 index 00000000..2985d646 --- /dev/null +++ b/app/views/components/_btn_base.haml @@ -0,0 +1,3 @@ +-# Componente Botón general Moderación + +%button.btn.btn-lg.mx-2{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index ccf22e84..33630780 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,2 +1,3 @@ +-# Componente Checkbox .custom-control.custom-checkbox - %input{ type: 'checkbox', id: '', class: '' } \ No newline at end of file + %input{ type: 'checkbox', id: '', class: '' } diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml new file mode 100644 index 00000000..aa755dcc --- /dev/null +++ b/app/views/components/_comments_btn_box.haml @@ -0,0 +1,9 @@ +-# Componente Botonera de Comentarios + +.d-flex.py-4 +- btn_class = 'btn-secondary' += 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 diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml new file mode 100644 index 00000000..854262c0 --- /dev/null +++ b/app/views/components/_instances_btn_box.haml @@ -0,0 +1,6 @@ +-# Componente botonera de moderación de Instancias + +- btn_class = 'btn btn-secondary' += render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_allow'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' \ No newline at end of file diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml new file mode 100644 index 00000000..2c63ce3a --- /dev/null +++ b/app/views/components/_profiles_btn_box.haml @@ -0,0 +1,7 @@ +-# Componente Botonera de Moderación de Cuentas (Remote_profile) + +- @class = 'btn-secondary' += render 'components/btn_base', text: t('.text_approve'), class: @class, href: '' += render 'components/btn_base', text: t('.text_check'), class: @class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: @class, href: '' += render 'components/btn_base', text: t('.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e954d2f3..e92c3a20 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -6,9 +6,5 @@ -# Botones de Moderación .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' + = render 'components/profiles_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml deleted file mode 100644 index 7f6233cd..00000000 --- a/app/views/moderation_queue/_btn_base.haml +++ /dev/null @@ -1,3 +0,0 @@ --# Componente Botón general Moderación - -%button.btn.btn-lg.mx-2{ href: href, class: @class }= text diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index c5f7ae5d..d5f2b3bd 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -6,10 +6,4 @@ = render 'comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file + = render 'components/comments_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index fc249e46..26caaeca 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,11 +5,8 @@ = render 'moderation_queue/instance', instance: instance -# Botones moderación - .d-flex.py-4 - - btn_class = 'btn btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: btn_class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: btn_class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: btn_class, href: '' + .d-flex.py-5 + = render 'components/instances_btn_box' %h3.mt-5= t('moderation_queue.instances.title') %p= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 965f8854..ab29ae4d 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -14,9 +14,4 @@ %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación -.d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' += render 'components/comments_btn_box' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index b361c085..eae3b5a5 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,7 +1,7 @@ -.row.justify-content-center.mb-5 +.row.mb-5 %h1= t('.title') -.row.justify-content-center - .col-md-8 +.row + .col-md-10 - summary = t('.instances') = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index df17b1ff..e4a9683c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -7,13 +7,4 @@ -# Botones moderación .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' + = render 'components/comments_btn_box' diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 2e46590e..a83c72af 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,5 +1,5 @@ -.row.justify-content-center - .col-md-8 +.row + .col-md-10 - summary = t('posts.edit.post') = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post diff --git a/config/locales/es.yml b/config/locales/es.yml index 4aad1cc7..868f8fc6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -36,6 +36,21 @@ es: submenu_reject: Rechazado block_lists: title: Listas de bloqueo + comments_btn_box: + text_pause: Pausa + text_reject: Rechazar + text_accept: Aceptar Publicación + text_reply: Responder + text_report: Reportar + instances_btn_box: + text_check: Moderar caso por caso + text_allow: Permitir todo + text_deny: Bloquear instancia + profiles_btn_box: + text_approve: Aprobar siempre + text_check: Revisar siempre + text_deny: Bloquear + text_report: Reportar moderation_queue: index: title: Actividades de moderación @@ -51,21 +66,6 @@ es: profile_id: ID profile_published: Publicada profile_summary: Resumen - profile_button_box: - text_approve: Aprobar siempre - text_check: Revisar siempre - text_deny: Bloquear - text_report: Reportar - button_box: - text_pause: Pausa - text_reject: Rechazar - text_accept: Aceptar Publicación - text_reply: Responder - text_report: Reportar - 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 From ba26b505e499f0c2e139c5778c53c0c10607978f Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 15:03:47 -0300 Subject: [PATCH 070/227] =?UTF-8?q?fix:=20corregidos=20m=C3=A1rgenes=20en?= =?UTF-8?q?=20vistas=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 27 ++++++++++--------- .../moderation_queue/remote_profile.haml | 7 ++--- app/views/posts/edit.haml | 4 +-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index eae3b5a5..982a41c8 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,13 +1,14 @@ -.row.mb-5 - %h1= t('.title') -.row - .col-md-10 - - summary = t('.instances') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue - - summary = t('.accounts') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue - - summary = t('.comments') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue +.row.justify-content-center + .col-md-8 + %h1= t('.title') + .row + .col + - summary = t('.instances') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + - summary = t('.accounts') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + - summary = t('.comments') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index ed66a394..ba0fc257 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,4 @@ -.flex - %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile +.row.justify-content-center + .col-md-8 + %h1= t('.profile') + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index a83c72af..2e46590e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,5 +1,5 @@ -.row - .col-md-10 +.row.justify-content-center + .col-md-8 - summary = t('posts.edit.post') = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post From 529711c47dbb823665a0f2685d0b7681792f3d9e Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 16:54:16 -0300 Subject: [PATCH 071/227] fix: corregido compo _remote_profile para hacerlo semantico con dl --- app/views/moderation_queue/_remote_profile.haml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index ab29ae4d..fae38dec 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,12 +1,18 @@ -# Componente Remote_Profile .flex.py-2.mx-2 + %dl + %dt= t('.profile_name') + %dd= remote_profile['name'] - %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') - %h5= t('.profile_summary') + ':' - %p= sanitize remote_profile['summary'] + %dt= t('.profile_id') + %dd= remote_profile['id'] + + %dt= t('.profile_published') + %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') + + %dt= t('.profile_summary') + %dd= remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue From faf3bf3fcf6e590c0984ef0819febc01119b2592 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 11:27:24 -0300 Subject: [PATCH 072/227] fix: corregido codigo de details en application.scss --- app/assets/stylesheets/application.scss | 27 ++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 5419bcdd..c05c49fe 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -559,7 +559,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } // details styles - +/* .details summary { list-style: none; cursor: default; @@ -578,4 +578,29 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); .details[open] > summary::after { transform: rotate(90deg) translatey(-0.1em); } +*/ + +.details { + summary { + list-style: none; + cursor: default; + position: relative; + } + summary::after { + content: '▶'; + font-size: 1.8rem; + position: absolute; + left: 97%; + bottom: 3%; + transform: rotate(64deg); + } +} + .details[open] { + & > summary { + &::after { + transform: rotate(90deg) translatey(-0.1em); + } + } + } + From 8bfdf3ed0a81fa5b332b2e53c0d7647325851a6a Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 11:29:00 -0300 Subject: [PATCH 073/227] fix: corregido cursor de apertura de details --- app/assets/stylesheets/application.scss | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c05c49fe..a411c124 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -559,26 +559,6 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } // details styles -/* -.details summary { - list-style: none; - cursor: default; - position: relative; - - &::after { - content: '▶'; - font-size: 1.8rem; - position: absolute; - left: 97%; - bottom: 3%; - transform: rotate(64deg); - } - } - -.details[open] > summary::after { - transform: rotate(90deg) translatey(-0.1em); - } -*/ .details { summary { @@ -592,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(64deg); + transform: rotate(60deg); } } .details[open] { From d829b5b4ae8b5a7d6fd6ecd9f9b1f7bb675b40b1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 12:02:06 -0300 Subject: [PATCH 074/227] feat: agregada traducciones en en.yml --- config/locales/en.yml | 71 +++++++++++++++++++++++++++++++++++++++---- config/locales/es.yml | 4 +-- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b06a78d..b1243091 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,18 +1,77 @@ en: + components: + instances_filters: + text_show: Show + text_checked: With the checked + instances_checked_submenu: + submenu_case: Check case by case + submenu_allow: Allow everything + submenu_reject: Reject + instances_show_submenu: + submenu_allow: Allow + submenu_reject: Reject + comments_filters: + text_show: Sho + text_checked: With the checked + comments_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + comments_show_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_report: Report + submenu_reject: Reject + profiles_filters: + text_show: Show + text_checked: With the checked + profiles_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + submenu_block: Block + profiles_show_submenu: + submenu_accept: Accept + submenu_block: Block + submenu_reject: Reject + block_lists: + title: Block lists + comments_btn_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept + text_reply: Reply + text_report: Report + instances_btn_box: + text_check: Check case by case + text_allow: Allow everything + text_deny: Block instance + profiles_btn_box: + text_approve: Always approve + text_check: Always check + text_deny: Block + text_report: Report moderation_queue: index: title: Moderation instances: Instances accounts: Accounts comments: Comments + comment: + source_profile: Source Profile + reply_to: Reply to remote_profile: user: Username - button_box: - text_pause: Pause - text_reject: Reject - text_accept: Accept Publication - text_reply: Reply - text_report: Report + profile: Profile + profile_name: Profile name + profile_id: ID + profile_published: Published + profile_summary: Summary + instances: + title: My block lists + description: Description + custom_block: Custom block lists + submit: Save block lists dark: Dark dir: ltr en: English diff --git a/config/locales/es.yml b/config/locales/es.yml index 868f8fc6..4b68f968 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -61,6 +61,7 @@ es: source_profile: Cuenta de Origen reply_to: En respuesta a remote_profile: + user: Nombre de usuario profile: Cuenta de Origen profile_name: Nombre de la Cuenta profile_id: ID @@ -71,9 +72,6 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo - comments_filter_box: - text_show: Ver - text_checked: Con los marcados dark: Oscuro es: Castellano en: English From fb19938361ca88216f7f94e74cb18e30213e08bf Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:38:34 -0300 Subject: [PATCH 075/227] fix: quitar bordes blancos de _comment.haml --- app/views/moderation_queue/_comment.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 463f47c7..26cfbe29 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,15 +4,15 @@ .col-1 = render 'components/checkbox' .col-10 - .row.border.border-white - .col.col-1.border.border-white.mr-5 + .row + .col.col-1.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') - .col.border.border-white + .col %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - .row.border.border-white + .row %p.mr-3= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row.border.border-white + .row %p= sanitize comment['content'] From 58012f662e84fd2e7b67498e22a23ebc91496cae Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:44:33 -0300 Subject: [PATCH 076/227] fix: row sin col --- app/views/moderation_queue/_comment.haml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 26cfbe29..5f50c996 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -11,8 +11,10 @@ %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row - %p.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + .col.p-0 + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row - %p= sanitize comment['content'] + .col.p-0 + %p= sanitize comment['content'] From fdc6ad95b82975ae59ca7f2ab6fa61142e22af58 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:51:27 -0300 Subject: [PATCH 077/227] fix: span sin p en _comment.haml --- app/views/moderation_queue/_comment.haml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 5f50c996..ed77d40f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -8,13 +8,15 @@ .col.col-1.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col - %span.mr-2= t('.source_profile') - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + %p + %span.mr-2= t('.source_profile') + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row .col.p-0 - %span.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + %p + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 %p= sanitize comment['content'] From 8dfa3860a5a6fcaae872bd627e16fe363dd88cc5 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:58:10 -0300 Subject: [PATCH 078/227] fix: span sin p y texto hardcodeado en _instance.haml --- app/views/moderation_queue/_instance.haml | 9 +++++---- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 80114985..6f0df926 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -4,7 +4,8 @@ %a{ href: host }= instance['title'] %p= instance['description'] -%span Users: -%span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') +%p + %span= t('.users') + %span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/config/locales/en.yml b/config/locales/en.yml index b1243091..5a8877fd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -72,6 +72,7 @@ en: description: Description custom_block: Custom block lists submit: Save block lists + users: "Users:" dark: Dark dir: ltr en: English diff --git a/config/locales/es.yml b/config/locales/es.yml index 4b68f968..bd20d3f0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -72,6 +72,7 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + users: "Usuaries:" dark: Oscuro es: Castellano en: English From 1deb4053a70142afc00b9c76a24561b15e84bb72 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 15:10:18 -0300 Subject: [PATCH 079/227] fix: condicional en En Respuesta A en _comment.haml --- app/views/moderation_queue/_comment.haml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index ed77d40f..2666d005 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -13,10 +13,11 @@ %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row .col.p-0 - %p - %span.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + - if comment['inReplyTo'] + %p + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 %p= sanitize comment['content'] From 2de756867685455218763a1fdbc09b65d72d51d3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 15:05:27 -0300 Subject: [PATCH 080/227] fix: corregido cuenta de origen de comentarios --- app/views/moderation_queue/_comments.haml | 3 +-- app/views/moderation_queue/_remote_profile.haml | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d5f2b3bd..76e08559 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,8 +2,7 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| - - = render 'comment', comment: comment, profile: @remote_profile + = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación = render 'components/comments_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index fae38dec..744d6445 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,12 +12,13 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= remote_profile['summary'] + %dd= sanitize remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue -%h3.pt-4= t('.profile') -%h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] +%dl.mt-5 + %dt= t('.profile_name') + %dd= remote_profile['name'] -# Botones de Moderación = render 'components/comments_btn_box' From d0e1d87c98fbc63eaa64272be1c26e6e59b15f8d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 15:14:11 -0300 Subject: [PATCH 081/227] fix: quitada sanitizacion en comentarios y remote_profile --- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 2666d005..213aa220 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -20,4 +20,4 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 - %p= sanitize comment['content'] + %p= comment['content'] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 744d6445..e8635cc6 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,7 +12,7 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= sanitize remote_profile['summary'] + %dd= remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 68b8aee1f22cf80707b67bb506ce78fae5411d2a Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:06:49 -0300 Subject: [PATCH 082/227] fix: quitada sanitizacion y quitado row extra --- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_block_instances_textarea.haml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 751d0c0e..01c1fbf9 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= sanitize profile['summary'] \ No newline at end of file +%p= profile['summary'] \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 34eb1e5d..339bd25c 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,6 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - .d-flex.justify-content-end - %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') - + %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') From 700e71ff97c5886283c6012366eb9318f44767d1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:15:57 -0300 Subject: [PATCH 083/227] fix: corregido details en application.scss --- app/assets/stylesheets/application.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a411c124..ef36c3be 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -574,13 +574,14 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); bottom: 3%; transform: rotate(60deg); } -} - .details[open] { + &[open] { & > summary { &::after { - transform: rotate(90deg) translatey(-0.1em); + transform: rotate(90deg); } } } +} + From f2724c27fb3e24616d376dd920d78dbec0048add Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:20:46 -0300 Subject: [PATCH 084/227] =?UTF-8?q?fix:=20corregidos=20par=C3=A1metros=20d?= =?UTF-8?q?e=20compo=20checkbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_checkbox.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 33630780..cbc5cb2d 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,3 @@ -# Componente Checkbox .custom-control.custom-checkbox - %input{ type: 'checkbox', id: '', class: '' } + %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } From 643139aaffb0bec5c833bd49649cd1b52cadaa86 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:24:06 -0300 Subject: [PATCH 085/227] fix: corregida indentacion en botones de comentarios --- app/views/components/_comments_btn_box.haml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index aa755dcc..0487c3db 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,9 +1,9 @@ -# Componente Botonera de Comentarios .d-flex.py-4 -- btn_class = 'btn-secondary' -= 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 + - btn_class = 'btn-secondary' + = 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 From e11de6c835091610513aec479c4d6771386bae8d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:27:05 -0300 Subject: [PATCH 086/227] fix: cambiada variable global por local en botonera de profiles --- app/views/components/_profiles_btn_box.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 2c63ce3a..06faa8a1 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,7 +1,7 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) -- @class = 'btn-secondary' -= render 'components/btn_base', text: t('.text_approve'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_check'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: @class, href: '' \ No newline at end of file +- btn_class = 'btn-secondary' += render 'components/btn_base', text: t('.text_approve'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file From 243a998451f793d1438aea514b9666ef78e26c7e Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 16:46:04 -0300 Subject: [PATCH 087/227] =?UTF-8?q?fix:=20row=20va=20dentro=20del=20if=20p?= =?UTF-8?q?ara=20no=20quedar=20vac=C3=ADa=20si=20false?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 2666d005..b92b3b11 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -11,9 +11,10 @@ %p %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - .row - .col.p-0 - - if comment['inReplyTo'] + + - if comment['inReplyTo'] + .row + .col.p-0 %p %span.mr-3= t('.reply_to') %span From 90b14ce2b2589fe80b1329bac314ac626f78ba37 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:07:36 -0300 Subject: [PATCH 088/227] fix: cambio de p por lead --- app/views/moderation_queue/_instances.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 26caaeca..c34bc022 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,6 +9,6 @@ = render 'components/instances_btn_box' %h3.mt-5= t('moderation_queue.instances.title') -%p= t('moderation_queue.instances.description') +%lead= t('moderation_queue.instances.description') = render 'components/block_lists' = render 'moderation_queue/block_instances_textarea' From e3cdafe2a6f7c68dae8813127ee4381ed3464ab9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 17:17:06 -0300 Subject: [PATCH 089/227] fix: corregida clase en compo textarea --- app/views/moderation_queue/_block_instances_textarea.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 339bd25c..0c0f55ca 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') + %button.col.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') From 78e478c00453c7e75ac7a321f4a7ec8fbc459100 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:18:38 -0300 Subject: [PATCH 090/227] =?UTF-8?q?fix:=20fecha=20con=20formato=20seg?= =?UTF-8?q?=C3=BAn=20idioma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 2 +- config/locales/en.yml | 49 ++++++++++++++++++++++++ config/locales/es.yml | 49 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index e525de8f..daf68290 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -6,7 +6,7 @@ .col-10 .row .col.col-1.mr-5 - %p= comment['published'].to_datetime.strftime('%m/%d/%Y') + %p= comment['published'].to_datetime.strftime(t('date.format')) .col %p %span.mr-2= t('.source_profile') diff --git a/config/locales/en.yml b/config/locales/en.yml index 5a8877fd..d6a15d4b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,53 @@ en: + date: + format: '%m/%d/%Y' + published_at: "Published at" + last_modified_at: "Last modification" + abbr_day_names: + - Mon + - Tue + - Wed + - Thu + - Fri + - Sat + - Sun + day_names: + - Monday + - Tuesday + - Wednesday + - Thursday + - Friday + - Saturday + - Sunday + abbr_month_names: + - Jan + - Feb + - Mar + - Apr + - May + - Jun + - Jul + - Aug + - Sep + - Oct + - Nov + - Dec + month_names: + - January + - February + - March + - April + - May + - June + - July + - August + - September + - October + - November + - December + time: + am: am + pm: pm components: instances_filters: text_show: Show diff --git a/config/locales/es.yml b/config/locales/es.yml index bd20d3f0..65df27bf 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,53 @@ es: + date: + format: '%d/%m/%Y' + published_at: "Publicado en" + last_modified_at: "Última modificación" + abbr_day_names: + - Lun + - Mar + - Mié + - Jue + - Vie + - Sáb + - Dom + day_names: + - Lunes + - Martes + - Miércoles + - Jueves + - Viernes + - Sábado + - Domingo + abbr_month_names: + - Ene + - Feb + - Mar + - Abr + - May + - Jun + - Jul + - Ago + - Sep + - Oct + - Nov + - Dic + month_names: + - Enero + - Febrero + - Marzo + - Abril + - Mayo + - Junio + - Julio + - Agosto + - Septiembre + - Octubre + - Noviembre + - Diciembre + time: + am: am + pm: pm components: instances_filters: text_show: Ver From 564dc060f0d2ee1f53c33be215bc9fcf72d1a3bf Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 17:24:25 -0300 Subject: [PATCH 091/227] fix: quitado flex de compo block_lists --- app/views/components/_block_lists.haml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 7764dfa5..7d9d741d 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,7 +1,6 @@ -# Componente Listas de bloqueo de Instancias -.flex - .card - .card-body - .d-flex.flex-row - = render 'components/checkbox' - %h4.ml-5= t('.title') +.card.mt-3 + .card-body + .d-flex.flex-row + = render 'components/checkbox' + %h4.ml-5= t('.title') From 476f0c005fc10224163442df3d369732676f5ab2 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:47:04 -0300 Subject: [PATCH 092/227] fix: remote profile asociado al comentario dentro de posts/_moderation_queue.haml --- app/views/posts/_moderation_queue.haml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e4a9683c..6921acbb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,10 +1,9 @@ -.flex - -# Filtros - = render 'components/comments_filters' +-# Filtros += render 'components/comments_filters' - - moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment, profile: @remote_profile +- moderation_queue.each do |comment| + = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] - -# Botones moderación - .d-flex.py-4 - = render 'components/comments_btn_box' + -# Botones moderación + .d-flex.py-4 + = render 'components/comments_btn_box' From 9634f758704887550b45980bd967e3fe9a8a6361 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:56:12 -0300 Subject: [PATCH 093/227] fix: html_safe en comentarios y descripciones --- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 01c1fbf9..28bba0e9 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= profile['summary'] \ No newline at end of file +%p= profile['summary'].html_safe \ No newline at end of file diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index daf68290..98679a9f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -21,4 +21,4 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 - %p= comment['content'] + %p= comment['content'].html_safe diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 6f0df926..eb5d6581 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -3,7 +3,7 @@ - host = "https://#{host}" %a{ href: host }= instance['title'] -%p= instance['description'] +%p= instance['description'].html_safe %p %span= t('.users') %span From e769c6ed5c36c4499989b8877d57a7126c005972 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 18:14:37 -0300 Subject: [PATCH 094/227] fix: responsive de moderation_queue/_comment.haml --- app/views/components/_checkbox.haml | 2 +- app/views/moderation_queue/_comment.haml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index cbc5cb2d..3444720e 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,3 @@ -# Componente Checkbox -.custom-control.custom-checkbox +.custom-control.custom-checkbox.p-0 %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 98679a9f..aa8d777d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,10 +4,10 @@ .col-1 = render 'components/checkbox' .col-10 - .row - .col.col-1.mr-5 + .row.no-gutters + .col.col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col + .col.col-8 %p %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] From e7595b86887764080dd60503b005dd1ea33534a7 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:33:28 -0300 Subject: [PATCH 095/227] =?UTF-8?q?fix:=20la=20descripci=C3=B3n=20ya=20tra?= =?UTF-8?q?=C3=ADa=20etiqueta=20p,=20redundancia=20borrada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 28bba0e9..85fe96d5 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= profile['summary'].html_safe \ No newline at end of file +=profile['summary'].html_safe \ No newline at end of file From 4114c1abe6cd4f4fa33c84f2f6d758ec338f6381 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:35:26 -0300 Subject: [PATCH 096/227] fix: p reemplazado por dl --- app/views/moderation_queue/_comment.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index aa8d777d..5b0f01a6 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -8,9 +8,10 @@ .col.col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) .col.col-8 - %p - %span.mr-2= t('.source_profile') - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + %dl + %dt.d-inline.mr-2= t('.source_profile') + %dd.d-inline + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - if comment['inReplyTo'] .row From 2c61f3baa2e2466179d7089a1a8abd2747049159 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:38:26 -0300 Subject: [PATCH 097/227] =?UTF-8?q?fix:=20comments=5Fbtn=5Fbox=20recibe=20?= =?UTF-8?q?comment=20como=20par=C3=A1metro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comments.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 76e08559..d51909a3 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -5,4 +5,4 @@ = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - = render 'components/comments_btn_box' \ No newline at end of file + = render 'components/comments_btn_box', comment: comment \ No newline at end of file From 9554ad1627b1167c140799202ac5c9081e5df885 Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 19 Feb 2024 13:57:39 -0300 Subject: [PATCH 098/227] fix: sintaxis --- app/views/moderation_queue/_comment.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 5b0f01a6..fea4570f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -3,23 +3,23 @@ .row.no-gutters .col-1 = render 'components/checkbox' - .col-10 + .col-11 .row.no-gutters - .col.col-4 + .col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col.col-8 + .col-8 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - if comment['inReplyTo'] - .row + .row.no-gutters .col.p-0 %p %span.mr-3= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row + .row.no-gutters .col.p-0 %p= comment['content'].html_safe From ecab598595130d8cd498161572902dd2cb1a57ca Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 19 Feb 2024 14:21:32 -0300 Subject: [PATCH 099/227] =?UTF-8?q?fix:=20no=20se=20ve=C3=ADan=20los=20bot?= =?UTF-8?q?ones=20en=20modo=20oscuro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/dark.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/stylesheets/dark.scss b/app/assets/stylesheets/dark.scss index 59e15180..f7f3a09d 100644 --- a/app/assets/stylesheets/dark.scss +++ b/app/assets/stylesheets/dark.scss @@ -8,6 +8,10 @@ $cyan: #13fefe; --color: #{$cyan}; } +.btn { + background-color: $white; +} + .btn-secondary { background-color: $white; color: $black; @@ -26,3 +30,5 @@ $cyan: #13fefe; box-shadow: 0 0 0 0.2rem $cyan; } } + + From 5ee9c49529c479625f3c1eee606d3ba3053a6421 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 20 Feb 2024 14:23:16 -0300 Subject: [PATCH 100/227] fix: corregidos botones y espacios en details de instancias --- app/views/components/_btn_base.haml | 2 +- app/views/components/_comments_btn_box.haml | 13 ++++++------- app/views/moderation_queue/_instance.haml | 19 ++++++++++++------- app/views/moderation_queue/_instances.haml | 3 ++- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 2985d646..ccc7ce35 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.btn-lg.mx-2{ href: href, class: local_assigns[:class] }= text +%button.btn.mx-2{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 0487c3db..7932068f 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,9 +1,8 @@ -# Componente Botonera de Comentarios -.d-flex.py-4 - - btn_class = 'btn-secondary' - = 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 +- btn_class = 'btn-secondary' += 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 diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index eb5d6581..74bda75b 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -2,10 +2,15 @@ - host ||= instance['uri'] - host = "https://#{host}" -%a{ href: host }= instance['title'] -%p= instance['description'].html_safe -%p - %span= t('.users') - %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox' + .col-11 + %h4 + %a{ href: host }= instance['title'] + %p= instance['description'].html_safe + %p + %span= t('.users') + %span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c34bc022..d19ef8ed 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,8 +5,9 @@ = render 'moderation_queue/instance', instance: instance -# Botones moderación - .d-flex.py-5 + .d-flex.pb-4 = render 'components/instances_btn_box' + %hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 6921acbb..2be35f7f 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -5,5 +5,5 @@ = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - .d-flex.py-4 + .d-flex = render 'components/comments_btn_box' From 9064325f7f8d52b98932a88afb14cd2cb7e8e2a3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:26:55 -0300 Subject: [PATCH 101/227] fix: flecha del details apunta donde tiene que apuntar --- app/assets/stylesheets/application.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index ef36c3be..f40af493 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -572,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(60deg); + transform: rotate(0deg); } &[open] { & > summary { From f968c60bdf554acf69c95d4791fd68c9636932c3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:29:48 -0300 Subject: [PATCH 102/227] =?UTF-8?q?fix:=20l=C3=ADneas=20de=20separaci?= =?UTF-8?q?=C3=B3n=20entre=20secciones=20de=20Actividades=20de=20moderaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 982a41c8..ab98ee30 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -6,9 +6,11 @@ - summary = t('.instances') = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + %hr - summary = t('.comments') = render 'layouts/details', summary: summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue From 195fdb56723fd1805deb97ac7962e8549b9cf42d Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:52:23 -0300 Subject: [PATCH 103/227] =?UTF-8?q?fix:=20que=20el=20separador=20entre=20d?= =?UTF-8?q?etails=20se=20vea=20en=20modo=20oscuro=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f40af493..054faee9 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -584,4 +584,6 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } - +hr { + border-bottom: 1px solid #dee2e6; +} \ No newline at end of file From 3d543a22fdf5d302c534388cdb49adcb1be50576 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:58:59 -0300 Subject: [PATCH 104/227] =?UTF-8?q?fix:=20la=20flecha=20del=20details=20te?= =?UTF-8?q?n=C3=ADa=20que=20apuntar=20para=20la=20izq=20ups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 054faee9..240e61a5 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -572,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(0deg); + transform: rotate(180deg); } &[open] { & > summary { From 5c2f2b9c614eacfc5b9cdaacdb96216d2be412cb Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 20 Feb 2024 15:12:42 -0300 Subject: [PATCH 105/227] =?UTF-8?q?fix:=20agregada=20l=C3=ADnea=20de=20sep?= =?UTF-8?q?araci=C3=B3n=20de=20tarjetas=20en=20compo=20accounts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 9 +++++++-- app/views/moderation_queue/_accounts.haml | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 85fe96d5..ab4fc4c7 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,7 @@ -%a{href: profile['id']}= profile['preferredUsername'] -=profile['summary'].html_safe \ No newline at end of file +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox' + .col-11 + %h4 + %a{href: profile['id']}= profile['preferredUsername'] + =profile['summary'].html_safe diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e92c3a20..9a6738bd 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -2,9 +2,10 @@ = render 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + %hr = render 'account', profile: remote_profile -# Botones de Moderación -.d-flex.py-4 +.d-flex.pb-4 = render 'components/profiles_btn_box' - \ No newline at end of file + From 71d0985a39dc9b5dc126b57f560f3c580864d7d3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 15:13:54 -0300 Subject: [PATCH 106/227] =?UTF-8?q?fix:=20bot=C3=B3n=20no=20deber=C3=ADa?= =?UTF-8?q?=20ocupar=20todo=20el=20ancho=20del=20div?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_block_instances_textarea.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 0c0f55ca..ff8f9286 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') + %button.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') From bd41144ecf5939fa5a11e5607f8ca2317744051e Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 15:41:49 -0300 Subject: [PATCH 107/227] fix: textarea --- app/views/components/_block_lists.haml | 2 +- app/views/moderation_queue/_block_instances_textarea.haml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 7d9d741d..8cdcd43b 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,5 +1,5 @@ -# Componente Listas de bloqueo de Instancias -.card.mt-3 +.card.mt-3.mb-3 .card-body .d-flex.flex-row = render 'components/checkbox' diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index ff8f9286..9b388a0d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,5 @@ .form-group - .d-flex.flex-column.mt-5 - %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') + = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') + = text_area_tag "custom_blocklist", nil, class: 'form-control' + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') + From 1fba54d80b3ae3e021c69e5a62f01174da63db33 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 13:50:29 -0300 Subject: [PATCH 108/227] fix: checkboxes --- app/controllers/application_controller.rb | 1 + app/views/components/_block_list.haml | 6 ++++++ app/views/components/_block_lists.haml | 8 ++------ app/views/components/_checkbox.haml | 5 +++-- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 6 +++--- app/views/moderation_queue/_instances.haml | 2 +- db/seeds/blocklists.yml | 5 +++++ 9 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 app/views/components/_block_list.haml create mode 100644 db/seeds/blocklists.yml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f673ee83..eca479fe 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,6 +32,7 @@ class ApplicationController < ActionController::Base @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + @blocklists= YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'blocklists.yml'))) @moderation_queue.each do |activity| activity['attributedTo'] = @remote_profile end diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml new file mode 100644 index 00000000..c2af3262 --- /dev/null +++ b/app/views/components/_block_list.haml @@ -0,0 +1,6 @@ +-# Componente Listas de bloqueo de Instancias +.card.mt-3.mb-3 + .card-body + .d-flex.flex-row + = render 'components/checkbox', id: blocklist["id"] do + %span.h4= blocklist["title"] diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 8cdcd43b..1e9cd76f 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,6 +1,2 @@ --# Componente Listas de bloqueo de Instancias -.card.mt-3.mb-3 - .card-body - .d-flex.flex-row - = render 'components/checkbox' - %h4.ml-5= t('.title') +- @blocklists.each do |blocklist| + = render 'components/block_list', blocklist: blocklist diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 3444720e..27f9a776 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,4 @@ -# Componente Checkbox -.custom-control.custom-checkbox.p-0 - %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } +.custom-control.custom-checkbox + %input.custom-control-input{ type: 'checkbox', id: id, name: id, class: local_assigns[:class] } + %label.custom-control-label{ for: id }= yield diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index ab4fc4c7..412f0aa7 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: profile['id'] .col-11 %h4 %a{href: profile['id']}= profile['preferredUsername'] diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index fea4570f..99059133 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -2,7 +2,7 @@ .flex.mx-4.my-5 .row.no-gutters .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters .col-4 diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 74bda75b..cff8a957 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,13 +1,13 @@ - host = instance['domain'] - host ||= instance['uri'] -- host = "https://#{host}" +- hosthttps = "https://#{host}" .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: host .col-11 %h4 - %a{ href: host }= instance['title'] + %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe %p %span= t('.users') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d19ef8ed..c51ba74f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -11,5 +11,5 @@ %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') -= render 'components/block_lists' += render 'components/block_lists', blocklists: @blocklists = render 'moderation_queue/block_instances_textarea' diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml new file mode 100644 index 00000000..d9f9dd6f --- /dev/null +++ b/db/seeds/blocklists.yml @@ -0,0 +1,5 @@ +--- +- id: gardenfence + title: Gardenfence +- id: lista + title: Lista From a7bd712a7c5725125ccbadcf0c075e71bd4f36fe Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:33:58 -0300 Subject: [PATCH 109/227] =?UTF-8?q?fix:=20tama=C3=B1o=20botones=20de=20mod?= =?UTF-8?q?eraci=C3=B3n=20de=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_btn_base.haml | 2 +- app/views/components/_comments_btn_box.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index ccc7ce35..7fa507ca 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.mx-2{ href: href, class: local_assigns[:class] }= text +%button.btn{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 7932068f..8b8d7268 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Comentarios -- btn_class = 'btn-secondary' +- 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: '' From e4e604f56d866b6d06e5479328330edf4e640894 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:34:46 -0300 Subject: [PATCH 110/227] =?UTF-8?q?fix:=20separadores=20en=20actividades?= =?UTF-8?q?=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 8 ++++---- app/views/moderation_queue/_comments.haml | 4 +++- app/views/moderation_queue/_instances.haml | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 99059133..7c77545a 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,13 +1,13 @@ -# Componente Comentario -.flex.mx-4.my-5 +.flex.mx-4.my-4 .row.no-gutters .col-1 = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-4 + .col-3 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col-8 + .col-9 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline @@ -17,7 +17,7 @@ .row.no-gutters .col.p-0 %p - %span.mr-3= t('.reply_to') + %span= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row.no-gutters diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d51909a3..b67fc71f 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,7 +2,9 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| + %hr = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - = render 'components/comments_btn_box', comment: comment \ No newline at end of file + .d-flex.justify-content-between + = render 'components/comments_btn_box', comment: comment \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c51ba74f..1accf60d 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -2,13 +2,14 @@ = render 'components/instances_filters' - @instances.each do |instance| + %hr = render 'moderation_queue/instance', instance: instance -# Botones moderación .d-flex.pb-4 = render 'components/instances_btn_box' - %hr +%hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') = render 'components/block_lists', blocklists: @blocklists From b489b713ac64df577ced3b937172c076be44c0f5 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:52:53 -0300 Subject: [PATCH 111/227] fix: faltaba poner la hora de los comentarios --- app/views/moderation_queue/_comment.haml | 8 +++++--- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 7c77545a..80446587 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,9 +5,11 @@ = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-3 - %p= comment['published'].to_datetime.strftime(t('date.format')) - .col-9 + .col-5.col-sm-3.col-lg-4 + %p + %span= comment['published'].to_datetime.strftime(t('date.format')) + %span= comment['published'].to_datetime.strftime(t('time.format')) + .col-7.col-sm-9.col-lg-8 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline diff --git a/config/locales/en.yml b/config/locales/en.yml index d6a15d4b..0d10b3db 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -48,6 +48,7 @@ en: time: am: am pm: pm + format: '%-I:%M %p' components: instances_filters: text_show: Show diff --git a/config/locales/es.yml b/config/locales/es.yml index 65df27bf..e277f76b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -48,6 +48,7 @@ es: time: am: am pm: pm + format: '%-H:%M' components: instances_filters: text_show: Ver From 1b8685b7ca978f4a1f45d40161d6080678eaa51a Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 18:01:10 -0300 Subject: [PATCH 112/227] fix: yaml roto --- app/views/moderation_queue/_comments.haml | 2 +- config/locales/en.yml | 102 +++++++++++----------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index b67fc71f..0e6ce334 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -6,5 +6,5 @@ = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - .d-flex.justify-content-between + .d-flex.justify-content-center = render 'components/comments_btn_box', comment: comment \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 0d10b3db..1b4f2d86 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,57 +50,57 @@ en: pm: pm format: '%-I:%M %p' components: - instances_filters: - text_show: Show - text_checked: With the checked - instances_checked_submenu: - submenu_case: Check case by case - submenu_allow: Allow everything - submenu_reject: Reject - instances_show_submenu: - submenu_allow: Allow - submenu_reject: Reject - comments_filters: - text_show: Sho - text_checked: With the checked - comments_checked_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject - comments_show_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_report: Report - submenu_reject: Reject - profiles_filters: - text_show: Show - text_checked: With the checked - profiles_checked_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject - submenu_block: Block - profiles_show_submenu: - submenu_accept: Accept - submenu_block: Block - submenu_reject: Reject - block_lists: - title: Block lists - comments_btn_box: - text_pause: Pause - text_reject: Reject - text_accept: Accept - text_reply: Reply - text_report: Report - instances_btn_box: - text_check: Check case by case - text_allow: Allow everything - text_deny: Block instance - profiles_btn_box: - text_approve: Always approve - text_check: Always check - text_deny: Block - text_report: Report + instances_filters: + text_show: Show + text_checked: With selected + instances_checked_submenu: + submenu_case: Check case by case + submenu_allow: Allow everything + submenu_reject: Reject + instances_show_submenu: + submenu_allow: Allow + submenu_reject: Reject + comments_filters: + text_show: Show + text_checked: With selected + comments_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + comments_show_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_report: Report + submenu_reject: Reject + profiles_filters: + text_show: Show + text_checked: With selected + profiles_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + submenu_block: Block + profiles_show_submenu: + submenu_accept: Accept + submenu_block: Block + submenu_reject: Reject + block_lists: + title: Block lists + comments_btn_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept + text_reply: Reply + text_report: Report + instances_btn_box: + text_check: Check case by case + text_allow: Allow everything + text_deny: Block instance + profiles_btn_box: + text_approve: Always approve + text_check: Always check + text_deny: Block + text_report: Report moderation_queue: index: title: Moderation From df88f80b300bd401547fb8f2a76203ff1736c20f Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 18:08:54 -0300 Subject: [PATCH 113/227] fix: comentario en un details si tiene summary --- app/views/moderation_queue/_comment.haml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 80446587..a066f845 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -24,4 +24,9 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row.no-gutters .col.p-0 - %p= comment['content'].html_safe + - if comment['summary'] + - summary = comment['summary'] + = render 'layouts/details', summary: summary do + %p= comment['content'].html_safe + - else + %p= comment['content'].html_safe From e62e26c87c17152979c244b771ce7a02dda7fcb9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 22 Feb 2024 15:36:42 -0300 Subject: [PATCH 114/227] fix: agregado checkbox general a comentarios --- app/views/moderation_queue/_comments.haml | 8 ++++++-- app/views/posts/_moderation_queue.haml | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 0e6ce334..41193ce1 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/comments_filters' +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/comments_filters' - moderation_queue.each do |comment| %hr diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2be35f7f..2ec6a07d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/comments_filters' +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/comments_filters' - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] From af1afe8f50c6e288474e4e1137179e3a682e5a8e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 22 Feb 2024 15:50:57 -0300 Subject: [PATCH 115/227] fix: agregado html_safe a summary en remote_profile --- app/views/moderation_queue/_remote_profile.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index e8635cc6..43474b80 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,7 +12,7 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= remote_profile['summary'] + %dd= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue @@ -21,4 +21,4 @@ %dd= remote_profile['name'] -# Botones de Moderación -= render 'components/comments_btn_box' += render 'components/profiles_btn_box' From 836e5d5935e675d46adf507353a4a6de4332f4bf Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:26:33 -0300 Subject: [PATCH 116/227] fix: las actividades pueden existir previamente --- .../api/v1/webhooks/social_inbox_controller.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 1ffc1596..8b8ba35f 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -132,12 +132,14 @@ module Api # # @return [ActivityPub::Activity] def activity - @activity ||= ActivityPub::Activity.type_from(original_activity).new(uri: original_activity[:id], - activity_pub: activity_pub).tap do |a| - a.content = original_activity.dup - a.content[:object] = object.uri - a.save! - end + @activity ||= + ActivityPub::Activity + .type_from(original_activity) + .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + a.content = original_activity.dup + a.content[:object] = object.uri + a.save! + end end # Actor, si no hay instancia, la crea en el momento From a51cb4dbddb0a984e2546edc807c4a7e897321e2 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:36:03 -0300 Subject: [PATCH 117/227] =?UTF-8?q?fix:=20copiar=20el=20contexto=20desde?= =?UTF-8?q?=20la=20acci=C3=B3n=20al=20objeto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 8b8ba35f..02c91813 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -171,7 +171,9 @@ module Api # @return [Hash,String] def original_object - @original_object ||= original_activity[:object].dup + @original_object ||= original_activity[:object].dup.tap do |o| + o[:@context] = original_activity[:@context].dup + end end end end From a4062c5f545a7f2bac4c5b909d83eaca037ea3ec Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:52:01 -0300 Subject: [PATCH 118/227] feat: eliminar un objeto elimina todas las actividades pendientes --- app/models/activity_pub/activity/delete.rb | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 351dd3cb..9e7daa16 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -3,10 +3,19 @@ class ActivityPub class Activity class Delete < ActivityPub::Activity - # Si estamos eliminando el objeto, tenemos que vaciar su contenido y - # cambiar el estado a borrado. + # Los Delete se refieren a objetos. Al eliminar un objeto, + # cancelamos todas las actividades que tienen relacionadas. + # + # XXX: La actividad tiene una firma, pero la implementación no + # está recomendada + # + # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! - activity_pub.remove! + ActivityPub.transaction do + ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object']))&.activity_pubs&.find_each(&:remove!) + + activity_pub.remove! + end end end end From 2c8dbc885c38d25037df28b1a99a1ce0991ff5fd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:53:56 -0300 Subject: [PATCH 119/227] fix: evitar advertencias --- app/controllers/application_controller.rb | 2 +- app/models/concerns/tienda.rb | 2 +- app/models/site.rb | 2 +- app/models/site/api.rb | 2 +- app/models/site/social_distributed_press.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2746ab10..3201b909 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,7 @@ # Forma de ingreso a Sutty class ApplicationController < ActionController::Base include ExceptionHandler - include Pundit + include Pundit::Authorization protect_from_forgery with: :null_session, prepend: true diff --git a/app/models/concerns/tienda.rb b/app/models/concerns/tienda.rb index cd09358e..86174c9a 100644 --- a/app/models/concerns/tienda.rb +++ b/app/models/concerns/tienda.rb @@ -5,7 +5,7 @@ module Tienda extend ActiveSupport::Concern included do - encrypts :tienda_api_key + has_encrypted :tienda_api_key def tienda? tienda_api_key.present? && tienda_url.present? diff --git a/app/models/site.rb b/app/models/site.rb index dd250e3d..a9cb3652 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -17,7 +17,7 @@ class Site < ApplicationRecord # tiene acceso pero los datos se guardan cifrados en el sitio. Esto # protege información privada en repositorios públicos, pero no la # protege de acceso al panel de Sutty! - encrypts :private_key + has_encrypted :private_key validates :name, uniqueness: true, hostname: { allow_root_label: true diff --git a/app/models/site/api.rb b/app/models/site/api.rb index 73f8e710..6c6f0ece 100644 --- a/app/models/site/api.rb +++ b/app/models/site/api.rb @@ -5,7 +5,7 @@ class Site extend ActiveSupport::Concern included do - encrypts :api_key + has_encrypted :api_key before_save :add_api_key_if_missing! # Genera mensajes secretos que podemos usar para la API de cada diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index c3abe06e..7ebdcb36 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -8,7 +8,7 @@ class Site extend ActiveSupport::Concern included do - encrypts :private_key_pem + has_encrypted :private_key_pem has_many :activity_pubs From e3aabf4b91e485ddfa90293fc71d1e41145fea7f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:54:31 -0300 Subject: [PATCH 120/227] feat: poder obtener el id desde un objeto --- app/models/activity_pub.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 217c15a1..e99fa1f4 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -18,6 +18,16 @@ class ActivityPub < ApplicationRecord validates :object_id, presence: true validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] } + # Encuentra la URI de un objeto + # + # @return [String, nil] + def self.uri_from_object(object) + case object + when String then object + when Hash then object['id'] + end + end + aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true From 77137f311cba52a54b0a028f18d7f009f011c9cb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:56:39 -0300 Subject: [PATCH 121/227] docs: recordar que tenemos que validar mejor --- app/models/activity_pub/activity/delete.rb | 2 ++ app/models/activity_pub/activity/undo.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 9e7daa16..f6ff6536 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -9,6 +9,8 @@ class ActivityPub # XXX: La actividad tiene una firma, pero la implementación no # está recomendada # + # @todo Validar que le Actor corresponda con los objetos. Esto ya + # lo haría la Social Inbox por nosotres. # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! ActivityPub.transaction do diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index 18fbff5e..ae78a0d3 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -15,6 +15,8 @@ class ActivityPub # Sin embargo, estas acciones nunca deberían llegar a nuestra # Inbox. # + # @todo Validar que le Actor corresponda con los objetos. Esto ya + # lo haría la Social Inbox por nosotres. # @see {https://github.com/hyphacoop/social.distributed.press/issues/43} def update_activity_pub_state! ActivityPub.transaction do From 2f19aae793b91447c3cc633456b19d8d0a35fa99 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 13:52:31 -0300 Subject: [PATCH 122/227] feat: agregado enlace a listas de bloquedo y quitado estilo en css --- app/assets/stylesheets/application.scss | 5 ----- app/views/components/_block_list.haml | 6 ++++-- db/seeds/blocklists.yml | 2 ++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 240e61a5..a24af4c8 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -582,8 +582,3 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } - - -hr { - border-bottom: 1px solid #dee2e6; -} \ No newline at end of file diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index c2af3262..36ca8144 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -2,5 +2,7 @@ .card.mt-3.mb-3 .card-body .d-flex.flex-row - = render 'components/checkbox', id: blocklist["id"] do - %span.h4= blocklist["title"] + = render 'components/checkbox', id: blocklist['id'] do + -#%span.h4= blocklist["title"] + %h4 + %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml index d9f9dd6f..54dfe6c9 100644 --- a/db/seeds/blocklists.yml +++ b/db/seeds/blocklists.yml @@ -1,5 +1,7 @@ --- - id: gardenfence title: Gardenfence + link: 'https://gardenfence.github.io/' - id: lista title: Lista + link: '#' From e632bd249b16b6e888f65a9e90c517dbbe424a39 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 14:47:24 -0300 Subject: [PATCH 123/227] fix: corregido compo comentario en cuenta de origen y fecha --- app/views/moderation_queue/_comment.haml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index a066f845..4836f03d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,16 +5,10 @@ = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-5.col-sm-3.col-lg-4 - %p - %span= comment['published'].to_datetime.strftime(t('date.format')) - %span= comment['published'].to_datetime.strftime(t('time.format')) - .col-7.col-sm-9.col-lg-8 - %dl - %dt.d-inline.mr-2= t('.source_profile') - %dd.d-inline - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - + .col.col-lg-10.d-inline-flex.justify-content-between + %h4 + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + = render 'layouts/time', time: comment['published'] - if comment['inReplyTo'] .row.no-gutters .col.p-0 @@ -30,3 +24,4 @@ %p= comment['content'].html_safe - else %p= comment['content'].html_safe + From ea6d794b572b48d3198275967927b74efbccb2be Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 14:57:07 -0300 Subject: [PATCH 124/227] fix: corregido checkbox general en comentarios, cuentas e instancias --- app/views/moderation_queue/_accounts.haml | 8 ++++++-- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 9a6738bd..5fa8638c 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/profiles_filters' +.row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| %hr diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 41193ce1..6fa8c0f4 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ .row.no-gutters.pt-2 - .col-1 + .col-1.d-flex.align-items-center = render 'components/checkbox', id: moderation_queue.first['id'] .col-11 -# Filtros diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1accf60d..cf67a473 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/instances_filters' +.row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/instances_filters' - @instances.each do |instance| %hr From f83642797922b32f316398e276533095180b2e35 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 11:09:57 -0300 Subject: [PATCH 125/227] =?UTF-8?q?feat:=20obtener=20informaci=C3=B3n=20so?= =?UTF-8?q?bre=20la=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 3 +++ app/jobs/activity_pub/instance_fetch_job.rb | 22 +++++++++++++++++++ app/models/social_inbox.rb | 8 +++---- 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 app/jobs/activity_pub/instance_fetch_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 02c91813..97ca58b5 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -150,6 +150,9 @@ module Api next if a.instance a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + a.save! end end diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb new file mode 100644 index 00000000..a5c07162 --- /dev/null +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class ActivityPub + # Obtiene o actualiza los datos de una instancia. + class InstanceFetchJob < ApplicationJob + def perform(site:, instance:) + %w[/api/v2/instance /api/v1/instance].each do |api| + uri = SocialInbox.generate_uri(instance.hostname) do |u| + u.path = api + end + + response = site.social_inbox.dereferencer.get(uri: uri) + + next unless response.ok? + + instance.update(content: response.parsed_response) + + break + end + end + end +end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 2f5e7eca..03612779 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -28,7 +28,7 @@ class SocialInbox end def actor_id - @actor_id ||= generate_uri do |uri| + @actor_id ||= SocialInbox.generate_uri(hostname) do |uri| uri.path = '/about.jsonld' end end @@ -61,7 +61,7 @@ class SocialInbox # @return [String] def public_key_url - @public_key_url ||= generate_uri do |uri| + @public_key_url ||= SocialInbox.generate_uri(hostname) do |uri| uri.path = '/about.jsonld' uri.fragment = 'main-key' end @@ -78,7 +78,7 @@ class SocialInbox # Genera una URI dentro de este sitio # # @return [String] - def generate_uri(&block) - @public_key_url ||= URI("https://#{hostname}").tap(&block).to_s + def self.generate_uri(hostname, &block) + URI("https://#{hostname}").tap(&block).to_s end end From 9e54d6311c0fbd9a7dfc34ab5b37460cf97b1021 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 12:46:55 -0300 Subject: [PATCH 126/227] =?UTF-8?q?feat:=20obtener=20informaci=C3=B3n=20de?= =?UTF-8?q?=20le=20actore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 2 ++ app/jobs/activity_pub/actor_fetch_job.rb | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 app/jobs/activity_pub/actor_fetch_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 97ca58b5..a5951716 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -154,6 +154,8 @@ module Api ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) a.save! + + ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb new file mode 100644 index 00000000..1c6f1735 --- /dev/null +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Obtiene o actualiza el contenido de un objeto, usando las credenciales +# del sitio. +# +# XXX: Esto usa las credenciales del sitio para volver el objeto +# disponible para todo el CMS. Asumimos que el objeto devuelto es el +# mismo para todo el mundo y las credenciales solo son para +# autenticación. +class ActivityPub + class ActorFetchJob < ApplicationJob + def perform(site:, actor:) + ActivityPub::Actor.transaction do + response = site.social_inbox.dereferencer.get(uri: actor.uri) + + # @todo Fallar cuando la respuesta no funcione? + return unless response.ok? + return if response.miss? && actor.content.present? + + actor.update(content: FastJsonparser.parse(response.body)) + end + end + end +end From a76c652f98e217a451a8b489586c3dc7500b8ef0 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 12:47:11 -0300 Subject: [PATCH 127/227] =?UTF-8?q?fix:=20permitir=20guardar=20le=20actore?= =?UTF-8?q?=20si=20la=20instancia=20ya=20exist=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/webhooks/social_inbox_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index a5951716..a1ff9677 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -147,11 +147,11 @@ module Api # @return [Actor] def actor @actor ||= ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| - next if a.instance + unless a.instance + a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - - ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + end a.save! From 380d484c00aa2b53d171c0c85bc21160482679d0 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 13:04:52 -0300 Subject: [PATCH 128/227] feat: poder encontrar instancias a partir de actividades --- app/controllers/moderation_queue_controller.rb | 6 ++++++ app/models/activity_pub/activity.rb | 1 + app/models/activity_pub/actor.rb | 1 + app/models/activity_pub/instance.rb | 4 ++++ app/models/activity_pub/object.rb | 7 +++++++ app/views/moderation_queue/_instance.haml | 18 +++++++----------- app/views/moderation_queue/_instances.haml | 2 +- .../20240223170317_add_actor_to_activities.rb | 18 ++++++++++++++++++ db/structure.sql | 6 ++++-- 9 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 db/migrate/20240223170317_add_actor_to_activities.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index eec0c70f..5f94e1f7 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -5,6 +5,12 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index dummy_data + + # @todo cambiar el estado por query + @activity_pubs = site.activity_pubs.where(aasm_state: 'paused') + @activities = ActivityPub::Activity.where(activity_pub_id: @activity_pubs.pluck(:id)) + @actors = ActivityPub::Actor.where(id: @activities.unscoped.distinct.pluck(:actor_id)) + @instances = ActivityPub::Instance.where(id: @actors.distinct.pluck(:instance_id)) end # Perfil remoto de usuarie diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index 5ee3d2d1..a220b831 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -16,6 +16,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :activity_pub + belongs_to :actor has_one :object, through: :activity_pub validates :activity_pub_id, presence: true diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index e79a596a..7a858a7e 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -11,5 +11,6 @@ class ActivityPub belongs_to :instance has_many :activity_pubs, as: :object + has_many :activities end end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index b13b8676..17bf183d 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -19,5 +19,9 @@ class ActivityPub state :allowed state :blocked end + + def uri + @uri ||= "https://#{hostname}/" + end end end diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 898d5375..c196160f 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -6,5 +6,12 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern has_many :activity_pubs, as: :object + + # Encontrar le Actor por su relación con el objeto + # + # @return [ActivityPub::Actor,nil] + def actor + ActivityPub::Actor.find_by(uri: content['actor']) + end end end diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index cff8a957..958a0199 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,16 +1,12 @@ -- host = instance['domain'] -- host ||= instance['uri'] -- hosthttps = "https://#{host}" - .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: host + = render 'components/checkbox', id: instance.hostname .col-11 - %h4 - %a{ href: hosthttps }= instance['title'] - %p= instance['description'].html_safe - %p + %h4 + %a{ href: instance.uri }= instance.content['title'] + %p= instance.content['description'].html_safe + %p %span= t('.users') %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') + = instance.content.dig('usage', 'users', 'active_month') + = instance.content.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1accf60d..e836d7e0 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -7,7 +7,7 @@ -# Botones moderación .d-flex.pb-4 - = render 'components/instances_btn_box' + = render 'components/instances_btn_box', instance: instance %hr %h3.mt-5= t('moderation_queue.instances.title') diff --git a/db/migrate/20240223170317_add_actor_to_activities.rb b/db/migrate/20240223170317_add_actor_to_activities.rb new file mode 100644 index 00000000..a546cd94 --- /dev/null +++ b/db/migrate/20240223170317_add_actor_to_activities.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Relaciona Actor con Activity +class AddActorToActivities < ActiveRecord::Migration[6.1] + def up + add_column :activity_pub_activities, :actor_id, :uuid, index: true + + ActivityPub::Activity.find_each do |activity| + actor = ActivityPub::Actor.find_by(uri: activity.content['actor']) + + activity.update(actor: actor) if actor.present? + end + end + + def down + remove_column :activity_pub_activities, :actor_id, :uuid, index: true + end +end diff --git a/db/structure.sql b/db/structure.sql index ee99e791..97e9ba36 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -484,7 +484,8 @@ CREATE TABLE public.activity_pub_activities ( activity_pub_id uuid NOT NULL, type character varying NOT NULL, uri character varying NOT NULL, - content jsonb DEFAULT '{}'::jsonb + content jsonb DEFAULT '{}'::jsonb, + actor_id uuid ); @@ -2472,6 +2473,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240219204011'), ('20240219204224'), ('20240220161414'), -('20240221184007'); +('20240221184007'), +('20240223170317'); From 64cef8a13e5532ad670378dd8dffd04ef9135dbf Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 10:39:00 -0300 Subject: [PATCH 129/227] feat: relacionar actividades con instancias de origen --- app/controllers/moderation_queue_controller.rb | 6 ++---- app/models/activity_pub.rb | 1 + ...226133022_add_instance_id_to_activity_pubs.rb | 16 ++++++++++++++++ db/structure.sql | 6 ++++-- 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 5f94e1f7..8920c717 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -7,10 +7,8 @@ class ModerationQueueController < ApplicationController dummy_data # @todo cambiar el estado por query - @activity_pubs = site.activity_pubs.where(aasm_state: 'paused') - @activities = ActivityPub::Activity.where(activity_pub_id: @activity_pubs.pluck(:id)) - @actors = ActivityPub::Actor.where(id: @activities.unscoped.distinct.pluck(:actor_id)) - @instances = ActivityPub::Instance.where(id: @actors.distinct.pluck(:instance_id)) + @activity_pubs = site.activity_pubs + @instances = ActivityPub::Instance.where(id: @activity_pubs.distinct.pluck(:instance_id)) end # Perfil remoto de usuarie diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index e99fa1f4..1afeee96 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -10,6 +10,7 @@ class ActivityPub < ApplicationRecord include AASM + belongs_to :instance belongs_to :site belongs_to :object, polymorphic: true has_many :activities diff --git a/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb b/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb new file mode 100644 index 00000000..710aacef --- /dev/null +++ b/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Relaciona instancias con sus actividades +class AddInstanceIdToActivityPubs < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :instance_id, :uuid, index: true + + ActivityPub.all.find_each do |activity_pub| + activity_pub.update(instance: activity_pub&.object&.actor&.instance) + end + end + + def down + remove_column :activity_pubs, :instance_id, :uuid, index: true + end +end diff --git a/db/structure.sql b/db/structure.sql index 97e9ba36..4fb11e5a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -541,7 +541,8 @@ CREATE TABLE public.activity_pubs ( site_id bigint NOT NULL, object_id uuid NOT NULL, object_type character varying NOT NULL, - aasm_state character varying NOT NULL + aasm_state character varying NOT NULL, + instance_id uuid ); @@ -2474,6 +2475,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240219204224'), ('20240220161414'), ('20240221184007'), -('20240223170317'); +('20240223170317'), +('20240226133022'); From dc11e6efc76a72a6d934f8eee13718b206531206 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 12:27:56 -0300 Subject: [PATCH 130/227] =?UTF-8?q?feat:=20cada=20sitio=20tiene=20un=20est?= =?UTF-8?q?ado=20de=20moderaci=C3=B3n=20para=20la=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 5 +- .../instance_moderations_controller.rb | 35 +++++++++ .../moderation_queue_controller.rb | 2 +- app/models/activity_pub/instance.rb | 1 + app/models/instance_moderation.rb | 27 +++++++ app/models/site/social_distributed_press.rb | 1 + app/policies/instance_moderation_policy.rb | 16 +++++ app/views/components/_btn_base.haml | 6 +- app/views/components/_instances_btn_box.haml | 6 +- app/views/moderation_queue/_instances.haml | 6 +- app/views/moderation_queue/index.haml | 2 +- config/routes.rb | 6 ++ ...240226134335_create_instance_moderation.rb | 26 +++++++ db/structure.sql | 72 ++++++++++++++++++- 14 files changed, 200 insertions(+), 11 deletions(-) create mode 100644 app/controllers/instance_moderations_controller.rb create mode 100644 app/models/instance_moderation.rb create mode 100644 app/policies/instance_moderation_policy.rb create mode 100644 db/migrate/20240226134335_create_instance_moderation.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index a1ff9677..12545915 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -142,7 +142,8 @@ module Api end end - # Actor, si no hay instancia, la crea en el momento + # Actor, si no hay instancia, la crea en el momento, junto con + # su estado de moderación. # # @return [Actor] def actor @@ -150,6 +151,8 @@ module Api unless a.instance a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + site.instance_moderations.find_or_create_by(instance: a.instance) + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb new file mode 100644 index 00000000..55f3c51b --- /dev/null +++ b/app/controllers/instance_moderations_controller.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# Actualiza la relación entre un sitio y una instancia +class InstanceModerationsController < ApplicationController + before_action :authorize_policy + + def pause + instance_moderation.pause! + + redirect_to site_moderation_queue_path + end + + def allow + instance_moderation.allow! + + redirect_to site_moderation_queue_path + end + + def block + instance_moderation.block! + + redirect_to site_moderation_queue_path + end + + private + + # @return [InstanceModeration] + def instance_moderation + @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) + end + + def authorize_policy + authorize instance_moderation + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 8920c717..d2123234 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -8,7 +8,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs - @instances = ActivityPub::Instance.where(id: @activity_pubs.distinct.pluck(:instance_id)) + @instance_moderations = site.instance_moderations end # Perfil remoto de usuarie diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 17bf183d..627ccb10 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -13,6 +13,7 @@ class ActivityPub has_many :activity_pubs has_many :actors + has_many :instance_moderations aasm do state :paused, initial: true diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb new file mode 100644 index 00000000..3c092958 --- /dev/null +++ b/app/models/instance_moderation.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# Mantiene el registro de relaciones entre sitios e instancias +class InstanceModeration < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :instance, class_name: 'ActivityPub::Instance' + + aasm do + state :paused, initial: true + state :allowed + state :blocked + + event :pause do + transitions from: %i[allowed blocked], to: :paused + end + + event :allow do + transitions from: %i[paused blocked], to: :allowed + end + + event :block do + transitions from: %i[paused allowed], to: :blocked + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 7ebdcb36..73b284bf 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -11,6 +11,7 @@ class Site has_encrypted :private_key_pem has_many :activity_pubs + has_many :instance_moderations before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb new file mode 100644 index 00000000..6b3157e8 --- /dev/null +++ b/app/policies/instance_moderation_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar instancias +InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do + def pause? + instance_moderation.site.usuarie? usuarie + end + + def allow? + pause? + end + + def block? + pause? + end +end diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 7fa507ca..677b88f1 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,7 @@ -# Componente Botón general Moderación -%button.btn{ href: href, class: local_assigns[:class] }= text +- local_assigns[:method] ||= 'patch' +- local_assigns[:class] = "btn #{local_assigns[:class]}" + +-# @todo path es obligatorio += button_to text, local_assigns[:path], **local_assigns diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml index 854262c0..74cad4a4 100644 --- a/app/views/components/_instances_btn_box.haml +++ b/app/views/components/_instances_btn_box.haml @@ -1,6 +1,6 @@ -# Componente botonera de moderación de Instancias - btn_class = 'btn btn-secondary' -= render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_allow'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' \ No newline at end of file += render 'components/btn_base', path: site_instance_moderation_pause_path(instance_moderation_id: instance_moderation), text: t('.text_check'), class: btn_class, disabled: !instance_moderation.may_pause? += render 'components/btn_base', path: site_instance_moderation_allow_path(instance_moderation_id: instance_moderation), text: t('.text_allow'), class: btn_class, disabled: !instance_moderation.may_allow? += render 'components/btn_base', path: site_instance_moderation_block_path(instance_moderation_id: instance_moderation), text: t('.text_deny'), class: btn_class, disabled: !instance_moderation.may_block? diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e836d7e0..318cddef 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,13 +1,13 @@ -# Filtros = render 'components/instances_filters' -- @instances.each do |instance| +- instance_moderations.each do |instance_moderation| %hr - = render 'moderation_queue/instance', instance: instance + = render 'moderation_queue/instance', instance: instance_moderation.instance -# Botones moderación .d-flex.pb-4 - = render 'components/instances_btn_box', instance: instance + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation %hr %h3.mt-5= t('moderation_queue.instances.title') diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index ab98ee30..0c937758 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -5,7 +5,7 @@ .col - summary = t('.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, instance_moderations: @instance_moderations %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do diff --git a/config/routes.rb b/config/routes.rb index ddc29994..b6250902 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,6 +62,12 @@ Rails.application.routes.draw do get 'remote_profile', to: 'moderation_queue#remote_profile' get 'instances', to: 'moderation_queue#instances' + resources :instance_moderations, only: [] do + patch :pause, to: 'instance_moderations#pause' + patch :allow, to: 'instance_moderations#allow' + patch :block, to: 'instance_moderations#block' + end + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do diff --git a/db/migrate/20240226134335_create_instance_moderation.rb b/db/migrate/20240226134335_create_instance_moderation.rb new file mode 100644 index 00000000..8b08e14e --- /dev/null +++ b/db/migrate/20240226134335_create_instance_moderation.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Como la instancia es única para todo el panel, necesitamos llevar +# registro de su relación con cada sitio por separado. +class CreateInstanceModeration < ActiveRecord::Migration[6.1] + def up + create_table :instance_moderations do |t| + t.timestamps + + t.belongs_to :site + t.uuid :instance_id, index: true + + t.string :aasm_state, null: false, default: 'paused' + + t.index %i[site_id instance_id], unique: true + end + + ActivityPub.all.find_each do |activity_pub| + InstanceModeration.find_or_create_by(site: activity_pub.site, instance: activity_pub.instance) + end + end + + def down + drop_table :instance_moderations + end +end diff --git a/db/structure.sql b/db/structure.sql index 4fb11e5a..c3896060 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -950,6 +950,39 @@ CREATE TABLE public.indexed_posts ( ); +-- +-- Name: instance_moderations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.instance_moderations ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + instance_id uuid, + aasm_state character varying DEFAULT 'paused'::character varying NOT NULL +); + + +-- +-- Name: instance_moderations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.instance_moderations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: instance_moderations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.instance_moderations_id_seq OWNED BY public.instance_moderations.id; + + -- -- Name: licencias; Type: TABLE; Schema: public; Owner: - -- @@ -1514,6 +1547,13 @@ ALTER TABLE ONLY public.designs ALTER COLUMN id SET DEFAULT nextval('public.desi ALTER TABLE ONLY public.distributed_press_publishers ALTER COLUMN id SET DEFAULT nextval('public.distributed_press_publishers_id_seq'::regclass); +-- +-- Name: instance_moderations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.instance_moderations ALTER COLUMN id SET DEFAULT nextval('public.instance_moderations_id_seq'::regclass); + + -- -- Name: licencias id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1774,6 +1814,14 @@ ALTER TABLE ONLY public.indexed_posts ADD CONSTRAINT indexed_posts_pkey PRIMARY KEY (id); +-- +-- Name: instance_moderations instance_moderations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.instance_moderations + ADD CONSTRAINT instance_moderations_pkey PRIMARY KEY (id); + + -- -- Name: licencias licencias_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2139,6 +2187,27 @@ CREATE INDEX index_indexed_posts_on_locale ON public.indexed_posts USING btree ( CREATE INDEX index_indexed_posts_on_site_id ON public.indexed_posts USING btree (site_id); +-- +-- Name: index_instance_moderations_on_instance_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_instance_moderations_on_instance_id ON public.instance_moderations USING btree (instance_id); + + +-- +-- Name: index_instance_moderations_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_instance_moderations_on_site_id ON public.instance_moderations USING btree (site_id); + + +-- +-- Name: index_instance_moderations_on_site_id_and_instance_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_instance_moderations_on_site_id_and_instance_id ON public.instance_moderations USING btree (site_id, instance_id); + + -- -- Name: index_licencias_on_name; Type: INDEX; Schema: public; Owner: - -- @@ -2476,6 +2545,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240220161414'), ('20240221184007'), ('20240223170317'), -('20240226133022'); +('20240226133022'), +('20240226134335'); From ffdcb5fae8b37187963182323076ddf048e149c9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:12:56 -0300 Subject: [PATCH 131/227] =?UTF-8?q?feat:=20poder=20cambiar=20el=20estado?= =?UTF-8?q?=20de=20moderaci=C3=B3n=20a=20instancias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/instance.rb | 6 ++++++ app/models/instance_moderation.rb | 30 ++++++++++++++++++++++++++--- app/models/social_inbox.rb | 12 ++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 627ccb10..42cd2695 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -15,12 +15,18 @@ class ActivityPub has_many :actors has_many :instance_moderations + # XXX: Mantenemos esto por si queremos bloquear una instancia a + # nivel general aasm do state :paused, initial: true state :allowed state :blocked end + def list_name + "@*@#{hostname}" + end + def uri @uri ||= "https://#{hostname}/" end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 3c092958..17b38fb7 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -13,15 +13,39 @@ class InstanceModeration < ApplicationRecord state :blocked event :pause do - transitions from: %i[allowed blocked], to: :paused + transitions from: %i[allowed blocked], to: :paused, guard: :pause_remotely! end event :allow do - transitions from: %i[paused blocked], to: :allowed + transitions from: %i[paused blocked], to: :allowed, guard: :allow_remotely! end event :block do - transitions from: %i[paused allowed], to: :blocked + transitions from: %i[paused allowed], to: :blocked, guard: :block_remotely! end end + + # Elimina la instancia de todas las listas + # + # @return [Boolean] + def pause_remotely! + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? + end + + # Deja de permitir la instancia + # + # @return [Boolean] + def block_remotely! + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && + site.social_inbox.blocklist.post(list: [instance.list_name]).ok? + end + + # Permite la instancia + # + # @return [Boolean] + def allow_remotely! + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + site.social_inbox.allowlist.post(list: [instance.list_name]).ok? + end end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 03612779..6677a320 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require 'distributed_press/v1/social/client' +require 'distributed_press/v1/social/allowlist' +require 'distributed_press/v1/social/blocklist' require 'distributed_press/v1/social/hook' require 'distributed_press/v1/social/inbox' require 'distributed_press/v1/social/dereferencer' @@ -59,6 +61,16 @@ class SocialInbox @hook ||= DistributedPress::V1::Social::Hook.new(client: client, actor: actor) end + # @return [DistributedPress::V1::Social::Allowlist] + def allowlist + @allowlist ||= DistributedPress::V1::Social::Allowlist.new(client: client, actor: actor) + end + + # @return [DistributedPress::V1::Social::Blocklist] + def blocklist + @blocklist ||= DistributedPress::V1::Social::Blocklist.new(client: client, actor: actor) + end + # @return [String] def public_key_url @public_key_url ||= SocialInbox.generate_uri(hostname) do |uri| From a1b5e385b0ff97a079d60fb689fa05757002269e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:50:03 -0300 Subject: [PATCH 132/227] fix: los guards se ejecutan todo el tiempo --- app/models/instance_moderation.rb | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 17b38fb7..735ec387 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -13,15 +13,27 @@ class InstanceModeration < ApplicationRecord state :blocked event :pause do - transitions from: %i[allowed blocked], to: :paused, guard: :pause_remotely! + transitions from: %i[allowed blocked], to: :paused + + before do + pause_remotely! + end end event :allow do - transitions from: %i[paused blocked], to: :allowed, guard: :allow_remotely! + transitions from: %i[paused blocked], to: :allowed + + before do + allow_remotely! + end end event :block do - transitions from: %i[paused allowed], to: :blocked, guard: :block_remotely! + transitions from: %i[paused allowed], to: :blocked + + before do + block_remotely! + end end end @@ -29,7 +41,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def pause_remotely! - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? end @@ -37,7 +50,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def block_remotely! - site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && site.social_inbox.blocklist.post(list: [instance.list_name]).ok? end @@ -45,7 +59,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def allow_remotely! - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.post(list: [instance.list_name]).ok? end end From cc7175ab997f2febd906022b9af6a69df7d7e057 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:51:33 -0300 Subject: [PATCH 133/227] feat: poder filtrar por estado de la instancia --- app/controllers/moderation_queue_controller.rb | 2 +- app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 5 +++-- app/views/moderation_queue/_instances.haml | 3 +++ config/locales/en.yml | 5 +++++ config/locales/es.yml | 6 ++++-- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index d2123234..8c030460 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -8,7 +8,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs - @instance_moderations = site.instance_moderations + @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) end # Perfil remoto de usuarie diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 213bb7c0..eac20d38 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -3,4 +3,4 @@ = render 'components/instances_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/comments_show_submenu' + = render 'components/instances_show_submenu' diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 1074cc3f..56206735 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,2 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file += render 'components/dropdown_item', text: t('.submenu_paused'), path: site_moderation_queue_path(state: 'paused') += render 'components/dropdown_item', text: t('.submenu_allowed'), path: site_moderation_queue_path(state: 'allowed') += render 'components/dropdown_item', text: t('.submenu_blocked'), path: site_moderation_queue_path(state: 'blocked') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 2303a061..4c55c439 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,6 +5,9 @@ -# Filtros = render 'components/instances_filters' +- if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') + - instance_moderations.each do |instance_moderation| %hr = render 'moderation_queue/instance', instance: instance_moderation.instance diff --git a/config/locales/en.yml b/config/locales/en.yml index 1b4f2d86..188b85c4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -60,6 +60,10 @@ en: instances_show_submenu: submenu_allow: Allow submenu_reject: Reject + instances_show_submenu: + submenu_paused: Moderated + submenu_allowed: Allowed + submenu_blocked: Blocked comments_filters: text_show: Show text_checked: With selected @@ -102,6 +106,7 @@ en: text_deny: Block text_report: Report moderation_queue: + nothing: "There's nothing for this filter" index: title: Moderation instances: Instances diff --git a/config/locales/es.yml b/config/locales/es.yml index e277f76b..d3651cb7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -58,8 +58,9 @@ es: submenu_allow: Permitir todo submenu_reject: Rechazado instances_show_submenu: - submenu_allow: Permitido - submenu_reject: Rechazado + submenu_paused: Pausadas + submenu_allowed: Permitidas + submenu_blocked: Bloqueadas comments_filters: text_show: Ver text_checked: Con los marcados @@ -102,6 +103,7 @@ es: text_deny: Bloquear text_report: Reportar moderation_queue: + nothing: 'No hay nada para este filtro' index: title: Actividades de moderación instances: Instancias From e78f71f25a5d6c1190b5efc4a8ede116e4b12800 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:52:02 -0300 Subject: [PATCH 134/227] fix: acciones --- app/views/components/_instances_checked_submenu.haml | 4 ++-- app/views/moderation_queue/_instances.haml | 5 +++-- config/locales/en.yml | 8 +++----- config/locales/es.yml | 5 +++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index f0b76185..9da642a7 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_case'), path: '/' += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' = render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 4c55c439..20501370 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,7 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2 .col-1.d-flex.align-items-center - = render 'components/checkbox', id: moderation_queue.first['id'] + = render 'components/checkbox', id: 'all' do + %span.sr-only= t('moderation_queue.everything') .col-11 -# Filtros = render 'components/instances_filters' diff --git a/config/locales/en.yml b/config/locales/en.yml index 188b85c4..9e40c433 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,12 +54,9 @@ en: text_show: Show text_checked: With selected instances_checked_submenu: - submenu_case: Check case by case - submenu_allow: Allow everything - submenu_reject: Reject - instances_show_submenu: + submenu_pause: Moderate submenu_allow: Allow - submenu_reject: Reject + submenu_block: Block instances_show_submenu: submenu_paused: Moderated submenu_allowed: Allowed @@ -106,6 +103,7 @@ en: text_deny: Block text_report: Report moderation_queue: + everything: 'Select all' nothing: "There's nothing for this filter" index: title: Moderation diff --git a/config/locales/es.yml b/config/locales/es.yml index d3651cb7..af75105b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -54,9 +54,9 @@ es: text_show: Ver text_checked: Con los marcados instances_checked_submenu: - submenu_case: Moderar caso por caso + submenu_pause: Moderar caso por caso submenu_allow: Permitir todo - submenu_reject: Rechazado + submenu_block: Rechazar todo instances_show_submenu: submenu_paused: Pausadas submenu_allowed: Permitidas @@ -103,6 +103,7 @@ es: text_deny: Bloquear text_report: Reportar moderation_queue: + everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' index: title: Actividades de moderación From 761d68604b9bbb1ce2a597d0717bd4121762f4e2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:03:18 -0300 Subject: [PATCH 135/227] feat: poder seleccionar todas las instancias --- .../controllers/select_all_controller.js | 11 +++++++ app/views/components/_checkbox.haml | 2 +- app/views/components/_select_all.haml | 4 +++ app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 33 ++++++++++--------- 5 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 app/javascript/controllers/select_all_controller.js create mode 100644 app/views/components/_select_all.haml diff --git a/app/javascript/controllers/select_all_controller.js b/app/javascript/controllers/select_all_controller.js new file mode 100644 index 00000000..7aca0f59 --- /dev/null +++ b/app/javascript/controllers/select_all_controller.js @@ -0,0 +1,11 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["toggle", "input"]; + + toggle(event = undefined) { + this.inputTargets.forEach(input => { + input.checked = this.toggleTarget.checked; + }); + } +} diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 27f9a776..1932df90 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,4 +1,4 @@ -# Componente Checkbox .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, name: id, class: local_assigns[:class] } + %input.custom-control-input{ type: 'checkbox', id: id, name: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_select_all.haml b/app/views/components/_select_all.haml new file mode 100644 index 00000000..2603dfd3 --- /dev/null +++ b/app/views/components/_select_all.haml @@ -0,0 +1,4 @@ +-# + @param id [String] += render 'components/checkbox', id: id, data: { action: 'select-all#toggle', target: 'select-all.toggle' } do + %span.sr-only= t('.label') diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 958a0199..327ea892 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname + = render 'components/checkbox', id: instance.hostname, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= instance.content['title'] diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 20501370..1540ae53 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,24 +1,25 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/checkbox', id: 'all' do - %span.sr-only= t('moderation_queue.everything') + = render 'components/select_all', id: 'instances' .col-11 -# Filtros = render 'components/instances_filters' -- if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') -- instance_moderations.each do |instance_moderation| - %hr - = render 'moderation_queue/instance', instance: instance_moderation.instance + - instance_moderations.each do |instance_moderation| + %hr + = render 'moderation_queue/instance', instance: instance_moderation.instance - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation -%hr -%h3.mt-5= t('moderation_queue.instances.title') -%lead= t('moderation_queue.instances.description') -= render 'components/block_lists', blocklists: @blocklists -= render 'moderation_queue/block_instances_textarea' + %hr + .col-12 + %h3.mt-5= t('moderation_queue.instances.title') + %lead= t('moderation_queue.instances.description') + = render 'components/block_lists', blocklists: @blocklists + = render 'moderation_queue/block_instances_textarea' From 9b2efaafac38cf7a52dacb63a15f5265d38c1990 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:37:34 -0300 Subject: [PATCH 136/227] =?UTF-8?q?feat:=20hacer=20una=20acci=C3=B3n=20con?= =?UTF-8?q?=20las=20seleccionadas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../instance_moderations_controller.rb | 23 ++++++++++- app/policies/instance_moderation_policy.rb | 6 +++ app/views/components/_checkbox.haml | 3 +- app/views/components/_dropdown_button.haml | 4 ++ .../_instances_checked_submenu.haml | 6 +-- app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 38 ++++++++++--------- config/routes.rb | 2 + 8 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 app/views/components/_dropdown_button.haml diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 55f3c51b..67a6be1d 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -2,7 +2,7 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController - before_action :authorize_policy + before_action :authorize_policy, except: %i[action_on_several] def pause instance_moderation.pause! @@ -22,6 +22,27 @@ class InstanceModerationsController < ApplicationController redirect_to site_moderation_queue_path end + def action_on_several + instance_moderations = site.instance_moderations.where(id: params[:instance_moderation]) + + authorize instance_moderations + + action = params[:instance_moderation_action].to_sym + method = :"#{action}!" + + InstanceModeration.transaction do + instance_moderations.find_each do |instance_moderation| + events = instance_moderation.aasm.events.map(&:name) + + next unless events.include? action + + instance_moderation.public_send(method) + end + end + + redirect_to site_moderation_queue_path + end + private # @return [InstanceModeration] diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index 6b3157e8..c07455b3 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -13,4 +13,10 @@ InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do def block? pause? end + + # En este paso tenemos varias instancias por moderar pero todas son + # del mismo sitio. + def action_on_several? + instance_moderation.first.site.usuarie? usuarie + end end diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 1932df90..596ff074 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,4 +1,5 @@ -# Componente Checkbox +- local_assigns[:name] ||= id .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, name: id, **local_assigns } + %input.custom-control-input{ type: 'checkbox', id: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml new file mode 100644 index 00000000..8b0c4684 --- /dev/null +++ b/app/views/components/_dropdown_button.haml @@ -0,0 +1,4 @@ +-# + @param name [String] + @param value [String] +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value }= text diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index 9da642a7..c3573ead 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' += render 'components/dropdown_button', text: t('.submenu_pause'), name: 'instance_moderation_action', value: 'pause' += render 'components/dropdown_button', text: t('.submenu_allow'), name: 'instance_moderation_action', value: 'allow' += render 'components/dropdown_button', text: t('.submenu_block'), name: 'instance_moderation_action', value: 'block' diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 327ea892..e7f74b7e 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname, data: { target: 'select-all.input' } + = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= instance.content['title'] diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1540ae53..129e1d41 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,24 +1,26 @@ -.row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'instances' - .col-11 - -# Filtros - = render 'components/instances_filters' +%section + %form{ action: site_instance_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'instances' + .col-11 + -# Filtros + = render 'components/instances_filters' - .col-12 - - if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') + + - instance_moderations.each do |instance_moderation| + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation - - instance_moderations.each do |instance_moderation| %hr - = render 'moderation_queue/instance', instance: instance_moderation.instance - - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation - - %hr - .col-12 + %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') = render 'components/block_lists', blocklists: @blocklists diff --git a/config/routes.rb b/config/routes.rb index b6250902..d9e2aca7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,6 +68,8 @@ Rails.application.routes.draw do patch :block, to: 'instance_moderations#block' end + patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From ca4b3360cde74d1f325861e98d5d056980b11800 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:38:00 -0300 Subject: [PATCH 137/227] fixup! feat: poder seleccionar todas las instancias --- app/processors/instance_moderation_processor.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/processors/instance_moderation_processor.rb diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb new file mode 100644 index 00000000..414901d6 --- /dev/null +++ b/app/processors/instance_moderation_processor.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Gestiona los filtros de InstanceModeration +class InstanceModerationProcessor < Rubanok::Processor + map :state, activate_always: true do |state: 'paused'| + raw.where(aasm_state: state) + end +end From 85cfed59fc8fa58fcfc3ba68c73bc03c727215b8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:14:44 -0300 Subject: [PATCH 138/227] =?UTF-8?q?fix:=20corregido=20posici=C3=B3n=20de?= =?UTF-8?q?=20sumary=20en=20details=20y=20boton=20de=20bloqueo=20de=20inst?= =?UTF-8?q?ancias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/_details.haml | 3 ++- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 306986bf..dd6ac5cf 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,6 @@ %details.details.py-2 %summary - %h3.py-2= summary + .col-11 + %h3.py-2= summary = yield diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 9b388a0d..a90704cc 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,5 @@ .form-group = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') = text_area_tag "custom_blocklist", nil, class: 'form-control' - %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') - + %p + %a.mt-3{ role: 'button', href: '', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') From 7837e2e85f1a15b546ba6121b2db57e41d460f1a Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:18:18 -0300 Subject: [PATCH 139/227] fix: corregido espacio en componente block_list --- app/views/components/_block_list.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 36ca8144..0d07a340 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -4,5 +4,5 @@ .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do -#%span.h4= blocklist["title"] - %h4 + %h4.m-0 %a{ href: blocklist['link'] }= blocklist['title'] From 570459fef3c6f424f46483c718320f529e728da5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:25:09 -0300 Subject: [PATCH 140/227] =?UTF-8?q?fix:=20corregido=20posici=C3=B3n=20de?= =?UTF-8?q?=20botones=20de=20moderaci=C3=B3n=20en=20details=20de=20Instanc?= =?UTF-8?q?ias=20y=20Cuentas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 4 ++++ app/views/moderation_queue/_accounts.haml | 3 --- app/views/moderation_queue/_instance.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 4 ---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 412f0aa7..2c929402 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -5,3 +5,7 @@ %h4 %a{href: profile['id']}= profile['preferredUsername'] =profile['summary'].html_safe + + -# Botones de Moderación + .d-flex.pb-4 + = render 'components/profiles_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5fa8638c..2d8e1420 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -9,7 +9,4 @@ %hr = render 'account', profile: remote_profile --# Botones de Moderación -.d-flex.pb-4 - = render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index cff8a957..889b6095 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -14,3 +14,7 @@ %span = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') + + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index cf67a473..72be522f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,10 +9,6 @@ %hr = render 'moderation_queue/instance', instance: instance - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box' - %hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') From f53ab113396b3e06544b39adf19b9012a865502a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 12:29:42 -0300 Subject: [PATCH 141/227] fixup! feat: poder seleccionar todas las instancias --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index 676b3673..d720a2d6 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,7 @@ gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' +gem 'rubanok' gem 'after_commit_everywhere', '~> 1.0' gem 'aasm' diff --git a/Gemfile.lock b/Gemfile.lock index 8ece3064..72a30af1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -488,6 +488,7 @@ GEM rexml (~> 3.2, >= 3.2.4) stream (~> 0.5.3) rouge (3.30.0) + rubanok (0.5.0) rubocop (1.42.0) json (~> 2.3) parallel (~> 1.10) @@ -679,6 +680,7 @@ DEPENDENCIES redis-rails rgl rollups! + rubanok rubocop-rails ruby-brs rubyzip From df6c04888244afd876a786834892b671baa1bb54 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 12:32:09 -0300 Subject: [PATCH 142/227] feat: fediblock --- app/models/activity_pub/fediblock.rb | 77 +++++++++++++++++++ app/models/activity_pub/instance.rb | 6 ++ .../20240227134845_create_fediblocks.rb | 26 +++++++ db/seeds.rb | 6 ++ db/seeds/activity_pub/fediblocks.yml | 16 ++++ db/structure.sql | 27 ++++++- 6 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 app/models/activity_pub/fediblock.rb create mode 100644 db/migrate/20240227134845_create_fediblocks.rb create mode 100644 db/seeds/activity_pub/fediblocks.yml diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb new file mode 100644 index 00000000..8d024f56 --- /dev/null +++ b/app/models/activity_pub/fediblock.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'httparty' + +# Listas de bloqueo y sus URLs de descarga +class ActivityPub + class Fediblock < ApplicationRecord + class Client + include ::HTTParty + + # @param url [String] + # @return [HTTParty::Response] + def get(url) + self.class.get(url, parser: csv_parser) + end + + # Procesa el CSV + # + # @return [Proc] + def csv_parser + @csv_parser ||= + begin + require 'csv' + + proc do |body, _| + CSV.parse(body, headers: true) + end + end + end + end + + class FediblockDownloadError < ::StandardError; end + + validates_presence_of :title, :url, :download_url, :format + validates_inclusion_of :format, in: %w[mastodon fediblock] + + HOSTNAME_HEADERS = { + 'mastodon' => '#domain', + 'fediblock' => 'domain' + } + + def client + @client ||= Client.new + end + + # Descarga la lista y crea las instancias con el estado necesario + def process! + response = client.get(download_url) + + raise FediblockDownloadError unless response.ok? + + Fediblock.transaction do + csv = response.parsed_response + process_csv! csv + + update(instances: csv.map { |r| r[hostname_header] }) + end + end + + private + + def hostname_header + HOSTNAME_HEADERS[format] + end + + # Crea o encuentra instancias que ya existían y las bloquea + # + # @param csv [CSV::Table] + def process_csv!(csv) + csv.each do |row| + ActivityPub::Instance.find_or_create_by(hostname: row[hostname_header]).tap do |i| + i.block! if i.may_block? + end + end + end + end +end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 42cd2695..749d98ac 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -21,6 +21,12 @@ class ActivityPub state :paused, initial: true state :allowed state :blocked + + # Al pasar una instancia a bloqueo, quiere decir que todos los + # sitios adoptan esta lista + event :block do + transitions from: %i[paused allowed], to: :blocked + end end def list_name diff --git a/db/migrate/20240227134845_create_fediblocks.rb b/db/migrate/20240227134845_create_fediblocks.rb new file mode 100644 index 00000000..03f65f7c --- /dev/null +++ b/db/migrate/20240227134845_create_fediblocks.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Las fediblocks son listas descargables de instancias bloqueadas. El +# formato hace una recomendación sobre suspensión o desfederación, pero +# nosotres bloqueamos todo. +class CreateFediblocks < ActiveRecord::Migration[6.1] + def up + create_table :activity_pub_fediblocks, id: :uuid do |t| + t.timestamps + + t.string :title, null: false + t.string :url, null: false + t.string :download_url, null: false + t.string :format, null: false + t.jsonb :instances, default: [] + end + + YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| + ActivityPub::Fediblock.create(**fediblock).process! + end + end + + def down + drop_table :activity_pub_fediblocks + end +end diff --git a/db/seeds.rb b/db/seeds.rb index b9ef96a1..8e8c291f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -27,3 +27,9 @@ if PrivacyPolicy.count.zero? PrivacyPolicy.new(**pp).save! end end + +YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| + ActivityPub::Fediblock.find_or_create_by(id: fediblock['id']).tap do |f| + f.update(**fediblock) + end +end diff --git a/db/seeds/activity_pub/fediblocks.yml b/db/seeds/activity_pub/fediblocks.yml new file mode 100644 index 00000000..c977f9bf --- /dev/null +++ b/db/seeds/activity_pub/fediblocks.yml @@ -0,0 +1,16 @@ +--- +- title: "Gardenfence" + url: "https://gardenfence.github.io/" + download_url: "https://github.com/gardenfence/blocklist/raw/main/gardenfence-fediblocksync.csv" + format: "fediblock" + id: "9046789a-5de8-4b16-beed-796060f8f3cc" +- title: "Oliphant Tier 0" + url: "https://writer.oliphant.social/oliphant/the-oliphant-social-blocklist" + download_url: "https://codeberg.org/oliphant/blocklists/raw/branch/main/blocklists/mastodon/tier0.csv" + format: "mastodon" + id: "fc1efcb8-7e68-4a76-ae9e-0c447752b12b" +- title: "The Bad Space (90%)" + url: "https://tweaking.thebad.space/exports" + download_url: "https://tweaking.thebad.space/exports/mastodon/90" + format: "fediblock" + id: "5dd6705a-c28f-4912-9456-07b0d4983108" diff --git a/db/structure.sql b/db/structure.sql index c3896060..241039d1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -502,6 +502,22 @@ CREATE TABLE public.activity_pub_actors ( ); +-- +-- Name: activity_pub_fediblocks; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_fediblocks ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + title character varying NOT NULL, + url character varying NOT NULL, + download_url character varying NOT NULL, + format character varying NOT NULL, + instances jsonb DEFAULT '[]'::jsonb +); + + -- -- Name: activity_pub_instances; Type: TABLE; Schema: public; Owner: - -- @@ -1694,6 +1710,14 @@ ALTER TABLE ONLY public.activity_pub_actors ADD CONSTRAINT activity_pub_actors_pkey PRIMARY KEY (id); +-- +-- Name: activity_pub_fediblocks activity_pub_fediblocks_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_fediblocks + ADD CONSTRAINT activity_pub_fediblocks_pkey PRIMARY KEY (id); + + -- -- Name: activity_pub_instances activity_pub_instances_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2546,6 +2570,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240221184007'), ('20240223170317'), ('20240226133022'), -('20240226134335'); +('20240226134335'), +('20240227134845'); From e728c09cc244b7a7a528d57b543fead8b74da312 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:35:25 -0300 Subject: [PATCH 143/227] =?UTF-8?q?fix:=20corregida=20traducci=C3=B3n=20de?= =?UTF-8?q?=20usuarios=20de=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 6 +++--- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 889b6095..3bfbde44 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -9,9 +9,9 @@ %h4 %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe - %p - %span= t('.users') - %span + %dl + %dt= t('.users') + %dd = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') diff --git a/config/locales/en.yml b/config/locales/en.yml index 1b4f2d86..51b1df4d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -122,6 +122,7 @@ en: description: Description custom_block: Custom block lists submit: Save block lists + instance: users: "Users:" dark: Dark dir: ltr diff --git a/config/locales/es.yml b/config/locales/es.yml index e277f76b..f4751c7a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -122,6 +122,7 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + instance: users: "Usuaries:" dark: Oscuro es: Castellano From ae0ca386c3102171e44fb9b0173350208ba7740e Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 13:07:51 -0300 Subject: [PATCH 144/227] fix: correciones varias en componente remote_profile --- app/views/moderation_queue/_remote_profile.haml | 10 +++++++--- config/locales/en.yml | 1 + config/locales/es.yml | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 43474b80..263f9c6b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -5,12 +5,16 @@ %dt= t('.profile_name') %dd= remote_profile['name'] + %dt= t('.preferred_name') + %dd= remote_profile['preferredUsername'] + %dt= t('.profile_id') - %dd= remote_profile['id'] + %dd + %a{ href: 'https://mastodon.mauve.moe/users/mauve' }= remote_profile['id'] %dt= t('.profile_published') - %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') - + %dd + = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') %dd= remote_profile['summary'].html_safe diff --git a/config/locales/en.yml b/config/locales/en.yml index 51b1df4d..9aa2c801 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -114,6 +114,7 @@ en: user: Username profile: Profile profile_name: Profile name + preferred_name: Name in Fediverse profile_id: ID profile_published: Published profile_summary: Summary diff --git a/config/locales/es.yml b/config/locales/es.yml index f4751c7a..e39b13c2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -114,9 +114,10 @@ es: user: Nombre de usuario profile: Cuenta de Origen profile_name: Nombre de la Cuenta + preferred_name: Nombre en el Fediverso profile_id: ID profile_published: Publicada - profile_summary: Resumen + profile_summary: Presentación instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo From 5a30da4232282d8fdb7483109b9c420d9dfbc674 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 13:14:25 -0300 Subject: [PATCH 145/227] =?UTF-8?q?fix:=20corregido=20parrafo=20en=20Prese?= =?UTF-8?q?ntaci=C3=B3n=20de=20componente=20Remote=5Fprofile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_remote_profile.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 263f9c6b..92cf8e96 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -16,7 +16,8 @@ %dd = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') - %dd= remote_profile['summary'].html_safe + %dd + %p= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 8654228edcd3d7b24562f0f62565662b99100373 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 13:25:40 -0300 Subject: [PATCH 146/227] =?UTF-8?q?feat:=20actualizar=20los=20fediblocks?= =?UTF-8?q?=20todos=20los=20d=C3=ADas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Procfile | 1 + app/jobs/activity_pub/fediblock_fetch_job.rb | 14 ++++++++++++++ lib/tasks/activity_pub.rake | 8 ++++++++ monit.conf | 5 +++++ 4 files changed, 28 insertions(+) create mode 100644 app/jobs/activity_pub/fediblock_fetch_job.rb create mode 100644 lib/tasks/activity_pub.rake diff --git a/Procfile b/Procfile index eab8a502..a74f613b 100644 --- a/Procfile +++ b/Procfile @@ -10,3 +10,4 @@ cleanup: bundle exec rake cleanup:everything emergency_cleanup: bundle exec rake cleanup:everything BEFORE=7 stats: bundle exec rake stats:process_all que: daemonize -c /srv/ -p /srv/tmp/que.pid -u rails /usr/local/bin/syslogize bundle exec que +fediblock: bundle exec rails activity_pub:fediblocks diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb new file mode 100644 index 00000000..d6cb4b83 --- /dev/null +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class ActivityPub + # Se encarga de mantener las listas de bloqueo actualizadas + class FediblockFetchJob < ApplicationJob + def perform + ActivityPub::Fediblock.find_each do |fediblock| + fediblock.process! + rescue ActivityPub::Fediblock::FediblockDownloadError => e + ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) + end + end + end +end diff --git a/lib/tasks/activity_pub.rake b/lib/tasks/activity_pub.rake new file mode 100644 index 00000000..08c0f980 --- /dev/null +++ b/lib/tasks/activity_pub.rake @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +namespace :activity_pub do + desc 'Update Fediblocks' + task fediblocks: :environment do |_, args| + ActivityPub::FediblockFetchJob.perform_later + end +end diff --git a/monit.conf b/monit.conf index accd0e28..2b7e50a8 100644 --- a/monit.conf +++ b/monit.conf @@ -9,6 +9,11 @@ check program distributed_press_tokens_renew every "0 3 * * *" if status != 0 then alert +check program fediblocks + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv fediblocks" as uid "rails" gid "www-data" + every "0 7 * * *" + if status != 0 then alert + check program access_logs with path "/srv/http/bin/access_logs" as uid "app" and gid "www-data" every "0 0 * * *" From ebdd95151e61bc90d646a7564c289ed67d326981 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 13:43:46 -0300 Subject: [PATCH 147/227] feat: relacionar sitios con fediblocks --- app/models/fediblock_state.rb | 72 +++++++++++++++++++ app/models/site/social_distributed_press.rb | 1 + .../20240227142019_create_fediblock_states.rb | 29 ++++++++ db/structure.sql | 46 +++++++++++- 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 app/models/fediblock_state.rb create mode 100644 db/migrate/20240227142019_create_fediblock_states.rb diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb new file mode 100644 index 00000000..8045e23e --- /dev/null +++ b/app/models/fediblock_state.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# Relación entre Fediblocks y Sites +class FediblockState < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :fediblock, class_name: 'ActivityPub::Fediblock' + + # El efecto secundario de esta máquina de estados es modificar el + # estado de moderación de cada instancia en el sitio. Nos salteamos + # los hooks de los eventos individuales. + aasm do + # Aunque queramos las listas habilitadas por defecto, tenemos que + # habilitarlas luego de crearlas para poder generar la lista de + # bloqueo en la Social Inbox. + state :disabled, initial: true + state :enabled + + event :enable do + transitions from: :disabled, to: :enabled + + before do + enable_remotely! + end + end + + # Al deshabilitar, las listas pasan a modo pausa. + # + # @todo No cambiar el estado si se habían habilitado manualmente, + # pero esto implica que tenemos que encontrar las que sí y quitarlas + # de list_names + event :disable do + transitions from: :enabled, to: :disabled + + before do + disable_remotely! + end + end + end + + private + + # Obtiene todos los IDs de instancias para poder obtener el estado de + # moderación en el sitio. + # + # @return [Array] + def instance_ids + ActivityPub::Instance.where(hostname: fediblock.instances).pluck(:id) + end + + # @return [Array] + def list_names + @list_names ||= fediblock.instances.map do |instance| + "@*@#{instance}" + end + end + + # Al deshabilitar, las instancias pasan a ser analizadas caso por caso + def disable_remotely! + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: list_names).ok? && + site.social_inbox.allowlist.delete(list: list_names).ok? + end + + # Al habilitar, se bloquean todas las instancias de la lista + def enable_remotely! + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.post(list: list_names).ok? && + site.social_inbox.allowlist.delete(list: list_names).ok? + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 73b284bf..e0d2d4f4 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -12,6 +12,7 @@ class Site has_many :activity_pubs has_many :instance_moderations + has_many :fediblock_states before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/db/migrate/20240227142019_create_fediblock_states.rb b/db/migrate/20240227142019_create_fediblock_states.rb new file mode 100644 index 00000000..c99cf63d --- /dev/null +++ b/db/migrate/20240227142019_create_fediblock_states.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# La relación entre sitios y fediblocks +class CreateFediblockStates < ActiveRecord::Migration[6.1] + def up + create_table :fediblock_states, id: :uuid do |t| + t.timestamps + + t.belongs_to :site + t.uuid :fediblock_id, index: true + t.string :aasm_state + + t.index %i[site_id fediblock_id], unique: true + end + + # Todas las listas están activas por defecto + DeploySocialDistributedPress.find_each do |deploy| + ActivityPub::Fediblock.find_each do |fediblock| + FediblockState.create(site: deploy.site, fediblock: fediblock, aasm_state: 'disabled').tap do |f| + f.enable! + end + end + end + end + + def down + drop_table :fediblock_states + end +end diff --git a/db/structure.sql b/db/structure.sql index 241039d1..ac897695 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -944,6 +944,20 @@ CREATE SEQUENCE public.distributed_press_publishers_id_seq ALTER SEQUENCE public.distributed_press_publishers_id_seq OWNED BY public.distributed_press_publishers.id; +-- +-- Name: fediblock_states; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.fediblock_states ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + fediblock_id uuid, + aasm_state character varying +); + + -- -- Name: indexed_posts; Type: TABLE; Schema: public; Owner: - -- @@ -1830,6 +1844,14 @@ ALTER TABLE ONLY public.distributed_press_publishers ADD CONSTRAINT distributed_press_publishers_pkey PRIMARY KEY (id); +-- +-- Name: fediblock_states fediblock_states_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.fediblock_states + ADD CONSTRAINT fediblock_states_pkey PRIMARY KEY (id); + + -- -- Name: indexed_posts indexed_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2176,6 +2198,27 @@ CREATE UNIQUE INDEX index_designs_on_gem ON public.designs USING btree (gem); CREATE UNIQUE INDEX index_designs_on_name ON public.designs USING btree (name); +-- +-- Name: index_fediblock_states_on_fediblock_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_fediblock_states_on_fediblock_id ON public.fediblock_states USING btree (fediblock_id); + + +-- +-- Name: index_fediblock_states_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_fediblock_states_on_site_id ON public.fediblock_states USING btree (site_id); + + +-- +-- Name: index_fediblock_states_on_site_id_and_fediblock_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_fediblock_states_on_site_id_and_fediblock_id ON public.fediblock_states USING btree (site_id, fediblock_id); + + -- -- Name: index_indexed_posts_on_front_matter; Type: INDEX; Schema: public; Owner: - -- @@ -2571,6 +2614,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240223170317'), ('20240226133022'), ('20240226134335'), -('20240227134845'); +('20240227134845'), +('20240227142019'); From c0b64fc3da31846c2e1e85c900d3b1d5e0323988 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 14:08:48 -0300 Subject: [PATCH 148/227] fix: corregido enlace a listas de bloqueo en compo block_list --- app/views/components/_block_list.haml | 4 ++-- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 0d07a340..5bc0e130 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -3,6 +3,6 @@ .card-body .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do - -#%span.h4= blocklist["title"] - %h4.m-0 + %span.h4= blocklist["title"] + %p %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index a90704cc..9b388a0d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,5 @@ .form-group = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') = text_area_tag "custom_blocklist", nil, class: 'form-control' - %p - %a.mt-3{ role: 'button', href: '', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') + From ec328d31b9e988c85d0b2c58c04f76e8dccee0a5 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 14:23:57 -0300 Subject: [PATCH 149/227] feat: cargar las fediblocks en la pantalla --- app/views/components/_block_list.haml | 6 +++--- app/views/components/_block_lists.haml | 4 ++-- app/views/moderation_queue/_instances.haml | 2 +- app/views/moderation_queue/index.haml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 5bc0e130..c70b40f8 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -2,7 +2,7 @@ .card.mt-3.mb-3 .card-body .d-flex.flex-row - = render 'components/checkbox', id: blocklist['id'] do - %span.h4= blocklist["title"] + = render 'components/checkbox', id: state.id, checked: state.enabled? do + %span.h4= blocklist.title %p - %a{ href: blocklist['link'] }= blocklist['title'] + %a{ href: blocklist.url }= t('.more') diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 1e9cd76f..b6dc0afa 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,2 +1,2 @@ -- @blocklists.each do |blocklist| - = render 'components/block_list', blocklist: blocklist +- blocklists.each do |blocklist| + = render 'components/block_list', blocklist: blocklist.fediblock, state: blocklist diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 6303d07c..a08c8b10 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -19,5 +19,5 @@ %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') - = render 'components/block_lists', blocklists: @blocklists + = render 'components/block_lists', blocklists: fediblock_states = render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0c937758..0fb1c968 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -5,7 +5,7 @@ .col - summary = t('.instances') = render 'layouts/details', summary: summary do - = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations + = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do From cda5fc1215c1613465047fe73fb3866244fff1d3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 14:37:07 -0300 Subject: [PATCH 150/227] fix: corregido enlace en block_list y texto en es.yml --- app/views/components/_block_list.haml | 3 ++- config/locales/es.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 5bc0e130..0c7a7b04 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -4,5 +4,6 @@ .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do %span.h4= blocklist["title"] - %p + + %p.mb-0 %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/config/locales/es.yml b/config/locales/es.yml index e39b13c2..7a2bfd85 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -122,7 +122,7 @@ es: title: Mis listas de bloqueo description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo - submit: Guardar lista de bloqueo + submit: Guardar listas de bloqueo instance: users: "Usuaries:" dark: Oscuro From 0dba9e550040f1cfb53778ee9f4f1de5c7aed406 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:05:16 -0300 Subject: [PATCH 151/227] =?UTF-8?q?fix:=20corregida=20alineaci=C3=B3n=20de?= =?UTF-8?q?=20checkbox=20general=20en=20details=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 44 +++++++++++------------ app/views/moderation_queue/_comments.haml | 2 +- app/views/posts/_moderation_queue.haml | 1 + 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 4836f03d..afd2a335 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,27 +1,27 @@ -# Componente Comentario -.flex.mx-4.my-4 - .row.no-gutters - .col-1 - = render 'components/checkbox', id: comment['id'] - .col-11 - .row.no-gutters - .col.col-lg-10.d-inline-flex.justify-content-between - %h4 - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'] - .row.no-gutters - .col.p-0 - %p - %span= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + +.row.no-gutters + .col-1 + = render 'components/checkbox', id: comment['id'] + .col-11 + .row.no-gutters + .col.col-lg-10.d-inline-flex.justify-content-between + %h4 + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + = render 'layouts/time', time: comment['published'] + - if comment['inReplyTo'] .row.no-gutters .col.p-0 - - if comment['summary'] - - summary = comment['summary'] - = render 'layouts/details', summary: summary do - %p= comment['content'].html_safe - - else + %p + %span= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + .row.no-gutters + .col.p-0 + - if comment['summary'] + - summary = comment['summary'] + = render 'layouts/details', summary: summary do %p= comment['content'].html_safe + - else + %p= comment['content'].html_safe diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 6fa8c0f4..eadfd78b 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,7 +1,7 @@ .row.no-gutters.pt-2 .col-1.d-flex.align-items-center = render 'components/checkbox', id: moderation_queue.first['id'] - .col-11 + .col-md-9 -# Filtros = render 'components/comments_filters' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2ec6a07d..a72e8abd 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -6,6 +6,7 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| + %hr = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación From bbbbad18a073e5931adad4b256599840297977d1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:21:31 -0300 Subject: [PATCH 152/227] fix: corregido margen en summary de compo details --- app/views/layouts/_details.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index dd6ac5cf..99ba4894 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,6 +2,7 @@ %details.details.py-2 %summary - .col-11 - %h3.py-2= summary + .row + .col-11.pr-2 + %h3.py-2= summary = yield From e239bd8b85fd6dad2e7fe4fcec72c46beb323b7a Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:25:25 -0300 Subject: [PATCH 153/227] fix: corregido usuarios en compo instance --- app/views/moderation_queue/_instance.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 3bfbde44..ec887d2d 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -9,8 +9,8 @@ %h4 %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe - %dl - %dt= t('.users') + %dl.d-inline-flex + %dt.pr-2= t('.users') %dd = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') From d4fa056db4d652070a829b16b79cea92f3e5c426 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 16:08:11 -0300 Subject: [PATCH 154/227] fix: corregido summary en compo details --- app/views/layouts/_details.haml | 4 +--- app/views/moderation_queue/_remote_profile.haml | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 99ba4894..a40d0403 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,7 +2,5 @@ %details.details.py-2 %summary - .row - .col-11.pr-2 - %h3.py-2= summary + %h3.py-2.pr-2= summary = yield diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 92cf8e96..263f9c6b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -16,8 +16,7 @@ %dd = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') - %dd - %p= remote_profile['summary'].html_safe + %dd= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 4bc11c700755d211967ef1b71e5e6828fc0f9e94 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:39:02 -0300 Subject: [PATCH 155/227] feat: gestionar listas de bloqueo desde el panel --- .../fediblock_states_controller.rb | 40 +++++++++++++++++++ .../activity_pub/instance_moderation_job.rb | 29 ++++++++++++++ app/models/site/social_distributed_press.rb | 1 + app/views/components/_block_list.haml | 14 ++++--- .../_block_instances_textarea.haml | 6 +-- app/views/moderation_queue/_instances.haml | 9 ++++- config/locales/en.yml | 2 + config/locales/es.yml | 2 + config/routes.rb | 1 + 9 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 app/controllers/fediblock_states_controller.rb create mode 100644 app/jobs/activity_pub/instance_moderation_job.rb diff --git a/app/controllers/fediblock_states_controller.rb b/app/controllers/fediblock_states_controller.rb new file mode 100644 index 00000000..c116b75a --- /dev/null +++ b/app/controllers/fediblock_states_controller.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Estado de las listas de bloqueo en cada sitio +class FediblockStatesController < ApplicationController + # Realiza cambios en las listas de bloqueo + def action_on_several + if fediblock_states_ids.present? + # Encontrar todas y deshabilitar las que no se enviaron + site.fediblock_states.all.find_each do |fediblock_state| + if fediblock_states_ids.include? fediblock_state.id + fediblock_state.enable! if fediblock_state.may_enable? + elsif fediblock_state.may_disable? + fediblock_state.disable! + end + end + end + + # Bloquear otras instancias + if custom_blocklist.present? + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: custom_blocklist) + end + + redirect_to site_moderation_queue_path + end + + private + + def fediblock_states_ids + params[:fediblock_states_ids] || [] + end + + # La lista de hostnames + def custom_blocklist + @custom_blocklist ||= fediblocks_states_params[:custom_blocklist].split("\n").map(&:strip).select(&:present?) + end + + def fediblocks_states_params + @fediblocks_states_params ||= params.permit(:custom_blocklist, fediblock_states_ids: []) + end +end diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb new file mode 100644 index 00000000..a9b0bea0 --- /dev/null +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class ActivityPub + # Bloquea varias instancias de una sola vez + class InstanceModerationJob < ApplicationJob + # @param :site [Site] + # @param :hostnames [Array] + def perform(site:, hostnames:) + # Crear las instancias que no existan todavía + hostnames.each do |hostname| + ActivityPub::Instance.find_or_create_by(hostname: hostname) + end + + instances = ActivityPub::Instance.where(hostname: hostnames) + + Site.transaction do + # Crea todas las moderaciones de instancia con un estado por + # defecto si no existen + instances.find_each do |instance| + # Esto bloquea cada una individualmente en la Social Inbox, + # idealmente son pocas instancias las que aparecen. + site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation| + instance_moderation.block! if instance_moderation.may_block? + end + end + end + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index e0d2d4f4..fdb37bca 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -13,6 +13,7 @@ class Site has_many :activity_pubs has_many :instance_moderations has_many :fediblock_states + has_many :instances, through: :instance_moderations before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index f972642a..79481363 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -1,8 +1,12 @@ -# Componente Listas de bloqueo de Instancias +- know_more = t('.know_more') .card.mt-3.mb-3 .card-body - .d-flex.flex-row - = render 'components/checkbox', id: state.id, checked: state.enabled? do - %span.h4= blocklist.title - %p.mb-0 - %a{ href: blocklist.url }= t('.more') + = render 'components/checkbox', id: state.id, name: 'fediblock_states_ids[]', value: state.id, checked: state.enabled? do + %span.h4.mb-0= blocklist.title + + %dl.mb-0 + %dt.d-inline= t('.instances_blocked') + %dd.d-inline.font-weight-normal= blocklist.instances.count + %p.mb-0.font-weight-normal + %a{ href: blocklist.url }= know_more diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 9b388a0d..9729d4de 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,3 @@ .form-group - = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') - = text_area_tag "custom_blocklist", nil, class: 'form-control' - %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') - + = label_tag 'custom_blocklist', t('moderation_queue.instances.custom_block') + = text_area_tag 'custom_blocklist', nil, class: 'form-control' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a08c8b10..d2ebb5a7 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -19,5 +19,10 @@ %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') - = render 'components/block_lists', blocklists: fediblock_states - = render 'moderation_queue/block_instances_textarea' + + = form_tag site_fediblock_states_action_on_several_path, method: :patch do + = render 'components/block_lists', blocklists: fediblock_states + = render 'moderation_queue/block_instances_textarea' + + .form-group + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') diff --git a/config/locales/en.yml b/config/locales/en.yml index 9581285f..717c9ece 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,6 +50,8 @@ en: pm: pm format: '%-I:%M %p' components: + block_list: + know_more: Know more instances_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index 9b1f1937..87111523 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -50,6 +50,8 @@ es: pm: pm format: '%-H:%M' components: + block_list: + know_more: Saber más (en inglés) instances_filters: text_show: Ver text_checked: Con los marcados diff --git a/config/routes.rb b/config/routes.rb index d9e2aca7..d70f8339 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,6 +69,7 @@ Rails.application.routes.draw do end patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' + patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' # Gestionar artículos según idioma nested do From d5f48c60073e8245e1f1cf1cbd8c558da60cdcfc Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:40:08 -0300 Subject: [PATCH 156/227] feat: al actualizar las blocklists, bloquear las instancias en los sitios que las tengan habilitadas --- app/jobs/activity_pub/fediblock_fetch_job.rb | 11 ++++++++- .../activity_pub/fediblock_updated_job.rb | 24 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 app/jobs/activity_pub/fediblock_updated_job.rb diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index d6cb4b83..6730cbf0 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -1,11 +1,20 @@ # frozen_string_literal: true class ActivityPub - # Se encarga de mantener las listas de bloqueo actualizadas + # Se encarga de mantener las listas de bloqueo actualizadas. Luego de + # actualizar el listado de instancias, bloquea las instancias en cada + # sitio que tenga el fediblock habilitado. class FediblockFetchJob < ApplicationJob def perform ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! + + instances_added = fediblock.instances - fediblock.instances_was + + # No hacer nada si no cambió con respecto a la versión anterior + next if instances_added.empty? + + ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: instances_added) rescue ActivityPub::Fediblock::FediblockDownloadError => e ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) end diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb new file mode 100644 index 00000000..007fa25e --- /dev/null +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Se encarga de mantener sincronizadas las listas de instancias +# de los fediblocks con los sitios que las tengan activadas. +class ActivityPub + class FediblockUpdatedJob < ApplicationJob + # @param :fediblock [ActivityPub::Fediblock] + # @param :instances [Array] + def perform(fediblock:, hostnames:) + instances = ActivityPub::Instance.where(hostname: instances) + + # Todos los sitios con la Social Inbox habilitada + Site.where(id: DeploySocialDistributedPress.pluck(:site_id)).find_each do |site| + # Crea el estado si no existía + fediblock_state = site.fediblock_states.find_or_create_by(fediblock: fediblock) + + # No hace nada con los deshabilitados + next unless fediblock_state.enabled? + + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: instances) + end + end + end +end From 34ead9ea4a40957e4f6251c691dcc5d53e258488 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:53:48 -0300 Subject: [PATCH 157/227] feat: establecer prioridades para las tareas --- app/jobs/activity_pub/actor_fetch_job.rb | 2 ++ app/jobs/activity_pub/fediblock_fetch_job.rb | 2 ++ app/jobs/activity_pub/fediblock_updated_job.rb | 2 ++ app/jobs/activity_pub/fetch_job.rb | 2 ++ app/jobs/activity_pub/instance_fetch_job.rb | 2 ++ app/jobs/activity_pub/instance_moderation_job.rb | 2 ++ 6 files changed, 12 insertions(+) diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb index 1c6f1735..71107151 100644 --- a/app/jobs/activity_pub/actor_fetch_job.rb +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -9,6 +9,8 @@ # autenticación. class ActivityPub class ActorFetchJob < ApplicationJob + self.priority = 50 + def perform(site:, actor:) ActivityPub::Actor.transaction do response = site.social_inbox.dereferencer.get(uri: actor.uri) diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index 6730cbf0..aa748bc6 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -5,6 +5,8 @@ class ActivityPub # actualizar el listado de instancias, bloquea las instancias en cada # sitio que tenga el fediblock habilitado. class FediblockFetchJob < ApplicationJob + self.priority = 50 + def perform ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb index 007fa25e..b4a56609 100644 --- a/app/jobs/activity_pub/fediblock_updated_job.rb +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -4,6 +4,8 @@ # de los fediblocks con los sitios que las tengan activadas. class ActivityPub class FediblockUpdatedJob < ApplicationJob + self.priority = 50 + # @param :fediblock [ActivityPub::Fediblock] # @param :instances [Array] def perform(fediblock:, hostnames:) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index b6c45026..e3fef993 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -9,6 +9,8 @@ # autenticación. class ActivityPub class FetchJob < ApplicationJob + self.priority = 50 + def perform(site:, object:) ActivityPub::Object.transaction do return if object.activity_pubs.where(aasm_state: 'removed').count.positive? diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index a5c07162..0ceb1a8a 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -3,6 +3,8 @@ class ActivityPub # Obtiene o actualiza los datos de una instancia. class InstanceFetchJob < ApplicationJob + self.priority = 100 + def perform(site:, instance:) %w[/api/v2/instance /api/v1/instance].each do |api| uri = SocialInbox.generate_uri(instance.hostname) do |u| diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index a9b0bea0..b205e68f 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -3,6 +3,8 @@ class ActivityPub # Bloquea varias instancias de una sola vez class InstanceModerationJob < ApplicationJob + self.priority = 50 + # @param :site [Site] # @param :hostnames [Array] def perform(site:, hostnames:) From 342521c897d77243e63fcbb565651eba7ae0f80d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:54:09 -0300 Subject: [PATCH 158/227] fix: guardar los datos de la instancia --- app/jobs/activity_pub/instance_fetch_job.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index 0ceb1a8a..ce202092 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true class ActivityPub - # Obtiene o actualiza los datos de una instancia. + # Obtiene o actualiza los datos de una instancia. Usamos un cliente + # de ActivityPub porque la instancia podría estar en federación + # limitada. class InstanceFetchJob < ApplicationJob self.priority = 100 @@ -14,8 +16,10 @@ class ActivityPub response = site.social_inbox.dereferencer.get(uri: uri) next unless response.ok? + # @todo Validate schema + next unless response.parsed_response.is_a?(DistributedPress::V1::Social::ReferencedObject) - instance.update(content: response.parsed_response) + instance.update(content: response.parsed_response.object) break end From aae04f3739c1cd07a4518922d8ff2cbac66180ac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 11:54:41 -0300 Subject: [PATCH 159/227] feat: al activar el fediverso, activar las listas de bloqueo --- app/models/deploy_social_distributed_press.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 7f761e46..9f968f36 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -8,6 +8,7 @@ class DeploySocialDistributedPress < Deploy DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync].freeze after_save :create_hooks! + after_create :enable_fediblocks! # Envía las notificaciones def deploy(output: false) @@ -95,4 +96,16 @@ class DeploySocialDistributedPress < Deploy ExceptionNotifier.notify_exception(e, data: { site_id: site.name, usuarie_id: rol.usuarie_id }) end end + + # Habilita todos los fediblocks disponibles. + # + # @todo Hacer que algunos sean opcionales + # @todo Mover a un Job + def enable_fediblocks! + ActivityPub::Fediblock.find_each do |fediblock| + site.fediblock_states.find_or_create_by(fediblock: fediblock).tap do |state| + state.enable! if state.may_enable? + end + end + end end From dc82b8cef2ee014898128a8916b75c5358d9646d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:05:09 -0300 Subject: [PATCH 160/227] feat: asignar rol a deploys al crear o modificar el sitio --- app/services/site_service.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 5c37cfe3..a3649bc5 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -26,6 +26,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # que no haya estados intermedios. site.locales = [usuarie.lang] + I18n.available_locales + add_role_to_deploys! + site.save && site.config.write && commit_config(action: :create) && @@ -43,7 +45,10 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Actualiza el sitio y guarda los cambios en la configuración def update I18n.with_locale(usuarie&.lang&.to_sym || I18n.default_locale) do - site.update(params) && + site.assign_attributes(params) + add_role_to_deploys! + + site.save && site.config.write && commit_config(action: :update) && site.reset.nil? && @@ -224,6 +229,17 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do private + # Asignar un rol a cada deploy si no lo tenía ya + def add_role_to_deploys! + site.deploys.each do |deploy| + deploy.rol ||= current_role + end + end + + def current_role + @current_role ||= usuarie.rol_for_site(site) + end + def with_all_locales(&block) site.locales.map do |locale| next unless I18n.available_locales.include? locale From d5cf0fffe09183cf9aea111bfaff60d6e7d6bfcb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:09:16 -0300 Subject: [PATCH 161/227] feat: no mostrar comentarios a invitades --- app/views/posts/edit.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 2e46590e..e7e0260d 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,9 @@ .row.justify-content-center .col-md-8 - - summary = t('posts.edit.post') - = render 'layouts/details', summary: summary do + - if policy(@site).edit? + = render 'layouts/details', summary: t('posts.edit.post') do + = render 'posts/form', site: @site, post: @post + = render 'layouts/details', summary: t('posts.edit.moderation_queue') do + = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue + - else = render 'posts/form', site: @site, post: @post - - summary = t('posts.edit.moderation_queue') - = render 'layouts/details', summary: summary do - = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From f1de4c80735b106fe4b7951ece4367bb20522bac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:32:59 -0300 Subject: [PATCH 162/227] fix: ignorar instancias que ya no existen --- app/jobs/activity_pub/instance_fetch_job.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index ce202092..9c562f7d 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -21,6 +21,16 @@ class ActivityPub instance.update(content: response.parsed_response.object) + break + rescue BRS::BaseError, + Errno::ECONNREFUSED, + HTTParty::Error, + JSON::JSONError, + Net::OpenTimeout, + OpenSSL::OpenSSLError, + SocketError, + Errno::ENETUNREACH => e + ExceptionNotifier.notify_exception(e, data: { instance: uri }) break end end From ee10e170ec6b8c6f939173ee647f874d4770bc3b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:01:36 -0300 Subject: [PATCH 163/227] =?UTF-8?q?fix:=20el=20rol=20todav=C3=ADa=20no=20e?= =?UTF-8?q?st=C3=A1=20guardado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/site_service.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index a3649bc5..6b57fc8b 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -13,7 +13,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do def create self.site = Site.new params - add_role temporal: false, rol: 'usuarie' + role = add_role temporal: false, rol: 'usuarie' site.deploys.build type: 'DeployLocal' # Los sitios de testing no se sincronizan sync_nodes unless site.name.end_with? '.testing' @@ -26,7 +26,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # que no haya estados intermedios. site.locales = [usuarie.lang] + I18n.available_locales - add_role_to_deploys! + add_role_to_deploys! role site.save && site.config.write && @@ -230,9 +230,9 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do private # Asignar un rol a cada deploy si no lo tenía ya - def add_role_to_deploys! + def add_role_to_deploys!(role = current_role) site.deploys.each do |deploy| - deploy.rol ||= current_role + deploy.rol ||= role end end From 670d6063e56922b3a8f8debdbd45fd823c34e38a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:04:52 -0300 Subject: [PATCH 164/227] fix: generar un rol dentro del sitio --- app/services/site_service.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 6b57fc8b..dabce349 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -13,7 +13,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do def create self.site = Site.new params - role = add_role temporal: false, rol: 'usuarie' + role = site.roles.build(usuarie: usuarie, temporal: false, rol: 'usuarie') site.deploys.build type: 'DeployLocal' # Los sitios de testing no se sincronizan sync_nodes unless site.name.end_with? '.testing' @@ -106,11 +106,6 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do GitPushJob.perform_later(site) end - def add_role(temporal: true, rol: 'invitade') - site.roles << Rol.new(site: site, usuarie: usuarie, - temporal: temporal, rol: rol) - end - # Crea la licencia del sitio para cada locale disponible en el sitio # # @return [Boolean] From 7521f598a64df25daac30501029d21171d48f7b1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:45:58 -0300 Subject: [PATCH 165/227] fix: poder deseleccionar todos los fediblocks --- app/controllers/fediblock_states_controller.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/controllers/fediblock_states_controller.rb b/app/controllers/fediblock_states_controller.rb index c116b75a..6d9737c3 100644 --- a/app/controllers/fediblock_states_controller.rb +++ b/app/controllers/fediblock_states_controller.rb @@ -4,14 +4,12 @@ class FediblockStatesController < ApplicationController # Realiza cambios en las listas de bloqueo def action_on_several - if fediblock_states_ids.present? - # Encontrar todas y deshabilitar las que no se enviaron - site.fediblock_states.all.find_each do |fediblock_state| - if fediblock_states_ids.include? fediblock_state.id - fediblock_state.enable! if fediblock_state.may_enable? - elsif fediblock_state.may_disable? - fediblock_state.disable! - end + # Encontrar todas y deshabilitar las que no se enviaron + site.fediblock_states.all.find_each do |fediblock_state| + if fediblock_states_ids.include? fediblock_state.id + fediblock_state.enable! if fediblock_state.may_enable? + elsif fediblock_state.may_disable? + fediblock_state.disable! end end From 15800e1096f01707def8a9c845407b38a9e8d545 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:47:40 -0300 Subject: [PATCH 166/227] BREAKING CHANGE: renombrar instancias por hostnames --- app/jobs/activity_pub/fediblock_fetch_job.rb | 6 +++--- app/jobs/activity_pub/fediblock_updated_job.rb | 9 ++++++--- app/models/activity_pub/fediblock.rb | 7 ++++++- app/views/components/_block_list.haml | 2 +- ...0228171335_rename_fediblock_instances_to_hostnames.rb | 9 +++++++++ db/structure.sql | 5 +++-- 6 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index aa748bc6..3d12f4cd 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -11,12 +11,12 @@ class ActivityPub ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! - instances_added = fediblock.instances - fediblock.instances_was + hostnames_added = fediblock.hostnames - fediblock.hostnames_was # No hacer nada si no cambió con respecto a la versión anterior - next if instances_added.empty? + next if hostnames_added.empty? - ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: instances_added) + ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: hostnames_added) rescue ActivityPub::Fediblock::FediblockDownloadError => e ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) end diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb index b4a56609..1bb47517 100644 --- a/app/jobs/activity_pub/fediblock_updated_job.rb +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -2,14 +2,17 @@ # Se encarga de mantener sincronizadas las listas de instancias # de los fediblocks con los sitios que las tengan activadas. +# +# También va a asociar las listas con todos los sitios que tengan la +# Social Inbox habilitada. class ActivityPub class FediblockUpdatedJob < ApplicationJob self.priority = 50 # @param :fediblock [ActivityPub::Fediblock] - # @param :instances [Array] + # @param :hostnames [Array] def perform(fediblock:, hostnames:) - instances = ActivityPub::Instance.where(hostname: instances) + instances = ActivityPub::Instance.where(hostname: hostnames) # Todos los sitios con la Social Inbox habilitada Site.where(id: DeploySocialDistributedPress.pluck(:site_id)).find_each do |site| @@ -19,7 +22,7 @@ class ActivityPub # No hace nada con los deshabilitados next unless fediblock_state.enabled? - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: instances) + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: hostnames) end end end diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb index 8d024f56..4abcb80f 100644 --- a/app/models/activity_pub/fediblock.rb +++ b/app/models/activity_pub/fediblock.rb @@ -43,6 +43,11 @@ class ActivityPub @client ||= Client.new end + # Todas las instancias de este fediblock + def instances + ActivityPub::Instance.where(hostname: hostnames) + end + # Descarga la lista y crea las instancias con el estado necesario def process! response = client.get(download_url) @@ -53,7 +58,7 @@ class ActivityPub csv = response.parsed_response process_csv! csv - update(instances: csv.map { |r| r[hostname_header] }) + update(hostnames: csv.map { |r| r[hostname_header] }) end end diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 79481363..75825bb0 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -7,6 +7,6 @@ %dl.mb-0 %dt.d-inline= t('.instances_blocked') - %dd.d-inline.font-weight-normal= blocklist.instances.count + %dd.d-inline.font-weight-normal= blocklist.hostnames.count %p.mb-0.font-weight-normal %a{ href: blocklist.url }= know_more diff --git a/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb b/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb new file mode 100644 index 00000000..bad343f2 --- /dev/null +++ b/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Cambia el nombre de la columna para que podamos obtener todas las +# instancias de un fediblock +class RenameFediblockInstancesToHostnames < ActiveRecord::Migration[6.1] + def change + rename_column :activity_pub_fediblocks, :instances, :hostnames + end +end diff --git a/db/structure.sql b/db/structure.sql index ac897695..740f5d87 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -514,7 +514,7 @@ CREATE TABLE public.activity_pub_fediblocks ( url character varying NOT NULL, download_url character varying NOT NULL, format character varying NOT NULL, - instances jsonb DEFAULT '[]'::jsonb + hostnames jsonb DEFAULT '[]'::jsonb ); @@ -2615,6 +2615,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240226133022'), ('20240226134335'), ('20240227134845'), -('20240227142019'); +('20240227142019'), +('20240228171335'); From 1ee41f2d5e9de7dc78f79c7afcb574ff2fa79648 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:04:37 -0300 Subject: [PATCH 167/227] feat: al activar o desactivar un fediblock, vincular con todas las instancias --- app/models/fediblock_state.rb | 28 +++++++++++++++++++++------- app/models/instance_moderation.rb | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 8045e23e..13e31cb2 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -1,6 +1,12 @@ # frozen_string_literal: true -# Relación entre Fediblocks y Sites +# Relación entre Fediblocks y Sites. +# +# Cuando se habilita un Fediblock, tenemos que asociar todas sus +# instancias con el sitio y bloquearlas. Cuando se deshabilita, la +# relación ya está creada y se va actualizando. +# +# @see ActivityPub::FediblockUpdatedJob class FediblockState < ApplicationRecord include AASM @@ -22,6 +28,15 @@ class FediblockState < ApplicationRecord before do enable_remotely! + + # Al actualizar el estado en masa garantizamos que las + # instancias que ya existen queden sincronizadas con el bloqueo + # en masa que acabamos de hacer. + instance_moderations.block_all! + + # Luego esta tarea crea las que falten e ignora las que ya se + # bloquearon. + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames) end end @@ -35,18 +50,17 @@ class FediblockState < ApplicationRecord before do disable_remotely! + + instance_moderations.pause_all! end end end private - # Obtiene todos los IDs de instancias para poder obtener el estado de - # moderación en el sitio. - # - # @return [Array] - def instance_ids - ActivityPub::Instance.where(hostname: fediblock.instances).pluck(:id) + # Todas las instancias de moderación de este sitio + def instance_moderations + site.instance_moderations.where(instance_id: fediblock.instances.pluck(:id)) end # @return [Array] diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 735ec387..d9f74527 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -7,6 +7,21 @@ class InstanceModeration < ApplicationRecord belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' + # Traer todas las instancias bloqueables, según la máquina de estados, + # todas las que no estén bloqueadas ya. + scope :may_block, -> { where.not(aasm_state: 'blocked') } + scope :may_pause, -> { where.not(aasm_state: 'paused') } + + # Bloquear instancias en masa + def self.block_all! + self.may_block.update_all(aasm_state: 'blocked', updated_at: Time.now) + end + + # Pausar instancias en masa + def self.pause_all! + self.may_pause.update_all(aasm_state: 'paused', updated_at: Time.now) + end + aasm do state :paused, initial: true state :allowed From 43d190ba7426ee8cf85e88a6a88b8fd2cebc94b4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:13:51 -0300 Subject: [PATCH 168/227] feat: mostrar la cantidad de instancias --- app/models/instance_moderation.rb | 3 +++ app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 6 +++--- app/views/moderation_queue/_instances.haml | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index d9f74527..10b5e8e0 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -11,6 +11,9 @@ class InstanceModeration < ApplicationRecord # todas las que no estén bloqueadas ya. scope :may_block, -> { where.not(aasm_state: 'blocked') } scope :may_pause, -> { where.not(aasm_state: 'paused') } + scope :paused, -> { where(aasm_state: 'paused') } + scope :blocked, -> { where(aasm_state: 'blocked') } + scope :allowed, -> { where(aasm_state: 'allowed') } # Bloquear instancias en masa def self.block_all! diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index eac20d38..fe40ced3 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -3,4 +3,4 @@ = render 'components/instances_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/instances_show_submenu' + = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 56206735..811d65c7 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_paused'), path: site_moderation_queue_path(state: 'paused') -= render 'components/dropdown_item', text: t('.submenu_allowed'), path: site_moderation_queue_path(state: 'allowed') -= render 'components/dropdown_item', text: t('.submenu_blocked'), path: site_moderation_queue_path(state: 'blocked') += render 'components/dropdown_item', text: t('.submenu_paused', count: site.instance_moderations.paused.count), path: site_moderation_queue_path(state: 'paused') += render 'components/dropdown_item', text: t('.submenu_allowed', count: site.instance_moderations.allowed.count), path: site_moderation_queue_path(state: 'allowed') += render 'components/dropdown_item', text: t('.submenu_blocked', count: site.instance_moderations.blocked.count), path: site_moderation_queue_path(state: 'blocked') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d2ebb5a7..65f4350a 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,7 +5,7 @@ = render 'components/select_all', id: 'instances' .col-11 -# Filtros - = render 'components/instances_filters' + = render 'components/instances_filters', site: site .col-12 - if instance_moderations.count.zero? From 259d1c1e90d86d12c86aedf5aefdeb3bdad1cbbc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:23:18 -0300 Subject: [PATCH 169/227] =?UTF-8?q?feat:=20optimizar=20acceso=20a=20inform?= =?UTF-8?q?aci=C3=B3n=20y=20ordenar=20por=20hostname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/processors/instance_moderation_processor.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb index 414901d6..908beaf7 100644 --- a/app/processors/instance_moderation_processor.rb +++ b/app/processors/instance_moderation_processor.rb @@ -2,6 +2,10 @@ # Gestiona los filtros de InstanceModeration class InstanceModerationProcessor < Rubanok::Processor + prepare do + raw.includes(:instance).order('activity_pub_instances.hostname') + end + map :state, activate_always: true do |state: 'paused'| raw.where(aasm_state: state) end From f9d02cc63eeb38d2b4e8c27e69521a463720eec4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:32:03 -0300 Subject: [PATCH 170/227] =?UTF-8?q?feat:=20recordar=20el=20filtro=20que=20?= =?UTF-8?q?est=C3=A1bamos=20usando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../instance_moderations_controller.rb | 21 +++++++++---------- .../moderation_queue_controller.rb | 2 ++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 67a6be1d..d25e1450 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -3,23 +3,18 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController before_action :authorize_policy, except: %i[action_on_several] + around_action :redirect_to_moderation_queue! def pause - instance_moderation.pause! - - redirect_to site_moderation_queue_path + instance_moderation.pause! if instance_moderation.may_pause? end def allow - instance_moderation.allow! - - redirect_to site_moderation_queue_path + instance_moderation.allow! if instance_moderation.may_allow? end def block - instance_moderation.block! - - redirect_to site_moderation_queue_path + instance_moderation.block! if instance_moderation.may_block? end def action_on_several @@ -39,12 +34,16 @@ class InstanceModerationsController < ApplicationController instance_moderation.public_send(method) end end - - redirect_to site_moderation_queue_path end private + def redirect_to_moderation_queue!(&action) + redirect_back fallback_location: site_moderation_queue_path, state: session[:moderation_queue_filtered_by_state] + + yield + end + # @return [InstanceModeration] def instance_moderation @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 8c030460..fd7d2acb 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,6 +6,8 @@ class ModerationQueueController < ApplicationController def index dummy_data + session[:moderation_queue_filtered_by_state] = params[:state] + # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) From 448564aa46739bdb72e4d226775993ee6ea55271 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:36:50 -0300 Subject: [PATCH 171/227] =?UTF-8?q?fix:=20hacer=20la=20tarea=20sincr=C3=B3?= =?UTF-8?q?nicamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/fediblock_state.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 13e31cb2..a160c43a 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -36,7 +36,7 @@ class FediblockState < ApplicationRecord # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames) + ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) end end From 17705f66ad2f0c1a66469393f009e2081ebd50c6 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:42:18 -0300 Subject: [PATCH 172/227] feat: tarjeta cacheada de instancia --- app/views/moderation_queue/_instance.haml | 16 +++++++++------- app/views/moderation_queue/_instances.haml | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index ec76c6e6..73655e1b 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,15 +1,17 @@ +- usuaries = instance.content.dig('usage', 'users', 'active_month') +- usuaries ||= instance.content.dig('stats', 'user_count') + .row.no-gutters.pt-2 .col-1 = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - %a{ href: instance.uri }= instance.content['title'] - %p= instance.content['description'].html_safe - %dl - %dt.d-inline= t('.users') - %dd.d-inline - = instance.content.dig('usage', 'users', 'active_month') - = instance.content.dig('stats', 'user_count') + %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname + %p= sanitize instance.content['description'] + - if usuaries.present? + %dl + %dt.d-inline= t('.users') + %dd.d-inline= sanitize usuaries.to_s -# Botones moderación .d-flex.pb-4 diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 65f4350a..a45da354 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -12,8 +12,9 @@ %h3= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + - cache [instance_moderation.aasm_state, instance_moderation.instance] do + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance %hr %div From dd20c6ce84881d96704f24a516e9fc2561e535c7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:42:39 -0300 Subject: [PATCH 173/227] fixup! feat: mostrar la cantidad de instancias --- config/locales/en.yml | 6 +++--- config/locales/es.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 717c9ece..c6a7d936 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -60,9 +60,9 @@ en: submenu_allow: Allow submenu_block: Block instances_show_submenu: - submenu_paused: Moderated - submenu_allowed: Allowed - submenu_blocked: Blocked + submenu_paused: "Moderated (%{count})" + submenu_allowed: "Allowed (%{count})" + submenu_blocked: "Blocked (%{count})" comments_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index 87111523..b3105220 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -60,9 +60,9 @@ es: submenu_allow: Permitir todo submenu_block: Rechazar todo instances_show_submenu: - submenu_paused: Pausadas - submenu_allowed: Permitidas - submenu_blocked: Bloqueadas + submenu_paused: "Pausadas (%{count})" + submenu_allowed: "Permitidas (%{count})" + submenu_blocked: "Bloqueadas (%{count})" comments_filters: text_show: Ver text_checked: Con los marcados From ef9169c89135259c98d5117b9af4f20179f2b110 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:12:33 -0300 Subject: [PATCH 174/227] =?UTF-8?q?fix:=20traducci=C3=B3n=20faltante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_block_list.haml | 3 ++- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 75825bb0..27e44cac 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -1,12 +1,13 @@ -# Componente Listas de bloqueo de Instancias - know_more = t('.know_more') +- instances_blocked = t('.instances_blocked') .card.mt-3.mb-3 .card-body = render 'components/checkbox', id: state.id, name: 'fediblock_states_ids[]', value: state.id, checked: state.enabled? do %span.h4.mb-0= blocklist.title %dl.mb-0 - %dt.d-inline= t('.instances_blocked') + %dt.d-inline= instances_blocked %dd.d-inline.font-weight-normal= blocklist.hostnames.count %p.mb-0.font-weight-normal %a{ href: blocklist.url }= know_more diff --git a/config/locales/en.yml b/config/locales/en.yml index c6a7d936..aaa5a451 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -52,6 +52,7 @@ en: components: block_list: know_more: Know more + instances_blocked: Instances blocked instances_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index b3105220..8fe01b83 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -52,6 +52,7 @@ es: components: block_list: know_more: Saber más (en inglés) + instances_blocked: Instancias bloqueadas instances_filters: text_show: Ver text_checked: Con los marcados From eafe8bcdd577d817a791552ffb774241bfd34422 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:26:22 -0300 Subject: [PATCH 175/227] feat: poder seleccionar todas las cuentas --- app/views/moderation_queue/_account.haml | 4 ++-- app/views/moderation_queue/_accounts.haml | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 2c929402..27ea30d1 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: profile['id'] + = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 %a{href: profile['id']}= profile['preferredUsername'] @@ -8,4 +8,4 @@ -# Botones de Moderación .d-flex.pb-4 - = render 'components/profiles_btn_box' \ No newline at end of file + = render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 2d8e1420..c88a2de6 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,10 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/checkbox', id: moderation_queue.first['id'] + = render 'components/select_all', id: 'actors' .col-11 -# Filtros = render 'components/profiles_filters' - -- @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| - %hr - = render 'account', profile: remote_profile - - + .col-12 + - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + %hr + = render 'account', profile: remote_profile From f524724c0ffe37830ef305f3ca6fa66f38b2bfbf Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:34:34 -0300 Subject: [PATCH 176/227] feat: moderar actores --- app/models/activity_pub/actor.rb | 1 + app/models/actor_moderation.rb | 32 +++++++++++++++ app/models/site/social_distributed_press.rb | 1 + ...20240228202830_create_actor_moderations.rb | 14 +++++++ db/structure.sql | 39 ++++++++++++++++++- 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 app/models/actor_moderation.rb create mode 100644 db/migrate/20240228202830_create_actor_moderations.rb diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 7a858a7e..92750946 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -10,6 +10,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :instance + has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb new file mode 100644 index 00000000..69fbf3bd --- /dev/null +++ b/app/models/actor_moderation.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# Mantiene la relación entre Site y Actor +class ActorModeration < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :actor, class_name: 'ActivityPub::Actor' + + aasm do + state :paused, initial: true + state :allowed + state :blocked + state :reported + + event :pause do + transitions from: %i[allowed blocked reported], to: :paused + end + + event :allowed do + transitions from: %i[paused blocked reported], to: :allowed + end + + event :blocked do + transitions from: %i[paused allowed], to: :blocked + end + + event :reported do + transitions from: %i[blocked], to: :reported + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index fdb37bca..e916bf3e 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -12,6 +12,7 @@ class Site has_many :activity_pubs has_many :instance_moderations + has_many :actor_moderations has_many :fediblock_states has_many :instances, through: :instance_moderations diff --git a/db/migrate/20240228202830_create_actor_moderations.rb b/db/migrate/20240228202830_create_actor_moderations.rb new file mode 100644 index 00000000..01460eae --- /dev/null +++ b/db/migrate/20240228202830_create_actor_moderations.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Relación entre Actor y Site +class CreateActorModerations < ActiveRecord::Migration[6.1] + def change + create_table :actor_moderations, id: :uuid do |t| + t.timestamps + + t.belongs_to :site + t.uuid :actor_id, index: true + t.string :aasm_state, null: false + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 740f5d87..e4d39ad0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -562,6 +562,20 @@ CREATE TABLE public.activity_pubs ( ); +-- +-- Name: actor_moderations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.actor_moderations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + actor_id uuid, + aasm_state character varying NOT NULL +); + + -- -- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - -- @@ -1756,6 +1770,14 @@ ALTER TABLE ONLY public.activity_pubs ADD CONSTRAINT activity_pubs_pkey PRIMARY KEY (id); +-- +-- Name: actor_moderations actor_moderations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.actor_moderations + ADD CONSTRAINT actor_moderations_pkey PRIMARY KEY (id); + + -- -- Name: blazer_audits blazer_audits_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2107,6 +2129,20 @@ CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_ins CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type); +-- +-- Name: index_actor_moderations_on_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_actor_moderations_on_actor_id ON public.actor_moderations USING btree (actor_id); + + +-- +-- Name: index_actor_moderations_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_actor_moderations_on_site_id ON public.actor_moderations USING btree (site_id); + + -- -- Name: index_blazer_audits_on_query_id; Type: INDEX; Schema: public; Owner: - -- @@ -2616,6 +2652,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240226134335'), ('20240227134845'), ('20240227142019'), -('20240228171335'); +('20240228171335'), +('20240228202830'); From aeb8f884935964ec00e2d213042bea33b13fddb2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:44:21 -0300 Subject: [PATCH 177/227] =?UTF-8?q?feat:=20crear=20el=20estado=20de=20mode?= =?UTF-8?q?raci=C3=B3n=20si=20no=20existe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 12545915..f52525f1 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -158,6 +158,8 @@ module Api a.save! + site.actor_moderations.find_or_create_by(actor: a) + ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end From 6eaf00c7ad1597a2bac9b22e1719f10ad8e70b7b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:52:24 -0300 Subject: [PATCH 178/227] fix: recibir actividades correctamente --- .../api/v1/webhooks/social_inbox_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index f52525f1..34ef1d6c 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -5,6 +5,9 @@ module Api module Webhooks # Recibe webhooks de la Social Inbox # + # @todo Mover todo a un Job que obtenga el objeto remoto antes de + # instanciar el objeto localmente en lugar de arreglarlo después y + # poder responder lo más rápido posible el webhook. # @see {https://www.w3.org/TR/activitypub/} class SocialInboxController < BaseController include Api::V1::Webhooks::Concerns::WebhookConcern @@ -28,6 +31,7 @@ module Api instance.present? object.present? activity_pub.present? + activity.update_activity_pub_state! end rescue ActiveRecord::RecordInvalid => e @@ -125,7 +129,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, object: object) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object: object) end # Crea la actividad y la vincula con el estado @@ -135,7 +139,7 @@ module Api @activity ||= ActivityPub::Activity .type_from(original_activity) - .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri a.save! From 6d9a64f7283a488b59fd32d325acac1ec6a34af9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:58:00 -0300 Subject: [PATCH 179/227] feat: moderar en la social inbox --- app/models/activity_pub/actor.rb | 11 ++++++++++ app/models/actor_moderation.rb | 37 ++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 92750946..a5171815 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -13,5 +13,16 @@ class ActivityPub has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities + + # Obtiene el nombre de la Actor como mención, solo si obtuvimos el + # contenido de antemano. + # + # @return [String, nil] + def mention + return if content['preferredUsername'].blank? + return if instance.blank? + + @mention ||= "@#{content['preferredUsername']}@#{instance.hostname}" + end end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 69fbf3bd..efbde33b 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -15,18 +15,51 @@ class ActorModeration < ApplicationRecord event :pause do transitions from: %i[allowed blocked reported], to: :paused + + before do + pause_remotely! + end end - event :allowed do + event :allow do transitions from: %i[paused blocked reported], to: :allowed + + before do + allow_remotely! + end end - event :blocked do + event :block do transitions from: %i[paused allowed], to: :blocked + + before do + block_remotely! + end end event :reported do transitions from: %i[blocked], to: :reported end end + + def pause_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && + site.social_inbox.blocklist.delete(list: [actor.mention]).ok? + end + + def allow_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.post(list: [actor.mention]).ok? && + site.social_inbox.blocklist.delete(list: [actor.mention]).ok? + end + + def block_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && + site.social_inbox.blocklist.post(list: [actor.mention]).ok? + end end From e07da7858e02309f0571428dfd754de0bc38687b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:27:15 -0300 Subject: [PATCH 180/227] =?UTF-8?q?feat:=20cambiar=20a=20orden=20descendie?= =?UTF-8?q?nte=20por=20fecha=20de=20modificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/processors/actor_moderation_processor.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 app/processors/actor_moderation_processor.rb diff --git a/app/processors/actor_moderation_processor.rb b/app/processors/actor_moderation_processor.rb new file mode 100644 index 00000000..efd12666 --- /dev/null +++ b/app/processors/actor_moderation_processor.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Gestiona los filtros de ActorModeration +class ActorModerationProcessor < Rubanok::Processor + # En orden descendiente para encontrar le últime Actor + prepare do + raw.order(updated_at: :desc) + end + + map :actor_state, activate_always: true do |state: 'paused'| + raw.where(aasm_state: state) + end +end From 0e2f6276eb501b0787442f096fe916dca0bfd4ba Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:31:28 -0300 Subject: [PATCH 181/227] feat: siempre actualizar la fecha de le actore al guardar una actividad --- app/models/activity_pub/activity.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index a220b831..1147c5b8 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -16,7 +16,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :activity_pub - belongs_to :actor + belongs_to :actor, touch: true has_one :object, through: :activity_pub validates :activity_pub_id, presence: true From 25c9963284887f581758d2f524e9b81ab9ed4991 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:35:34 -0300 Subject: [PATCH 182/227] =?UTF-8?q?feat:=20mostrar=20las=20cuentas=20en=20?= =?UTF-8?q?la=20cola=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 1 + app/processors/actor_moderation_processor.rb | 4 ++-- app/views/moderation_queue/_accounts.haml | 4 ++-- app/views/moderation_queue/index.haml | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index fd7d2acb..a9611a1b 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -11,6 +11,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) + @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) end # Perfil remoto de usuarie diff --git a/app/processors/actor_moderation_processor.rb b/app/processors/actor_moderation_processor.rb index efd12666..a3035654 100644 --- a/app/processors/actor_moderation_processor.rb +++ b/app/processors/actor_moderation_processor.rb @@ -7,7 +7,7 @@ class ActorModerationProcessor < Rubanok::Processor raw.order(updated_at: :desc) end - map :actor_state, activate_always: true do |state: 'paused'| - raw.where(aasm_state: state) + map :actor_state, activate_always: true do |actor_state: 'paused'| + raw.where(aasm_state: actor_state) end end diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index c88a2de6..5630a6d7 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -5,6 +5,6 @@ -# Filtros = render 'components/profiles_filters' .col-12 - - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + - actor_moderations.find_each do |actor_moderation| %hr - = render 'account', profile: remote_profile + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0fb1c968..df2c219d 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -9,7 +9,7 @@ %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do - = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations %hr - summary = t('.comments') = render 'layouts/details', summary: summary do From 2edafc8901a92e81534f3d50ff9c5fea797488ed Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:42:48 -0300 Subject: [PATCH 183/227] feat: ver la cuenta de cuentas por moderar --- app/views/components/_profiles_filters.haml | 4 ++-- app/views/components/_profiles_show_submenu.haml | 7 ++++--- app/views/moderation_queue/_accounts.haml | 2 +- config/locales/en.yml | 9 +++++---- config/locales/es.yml | 9 +++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index 0088afef..c6397e69 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu' + = render 'components/profiles_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/profiles_show_submenu' \ No newline at end of file + = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 2ba949b1..703e4a15 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,3 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' \ No newline at end of file +- ActorModeration.aasm.states.map(&:name).each do |actor_state| + = render 'components/dropdown_item', + text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), + path: site_moderation_queue_path(params.permit(:state, :actor_state).merge(actor_state: actor_state)) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5630a6d7..44c2893e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -3,7 +3,7 @@ = render 'components/select_all', id: 'actors' .col-11 -# Filtros - = render 'components/profiles_filters' + = render 'components/profiles_filters', actor_moderations: actor_moderations .col-12 - actor_moderations.find_each do |actor_moderation| %hr diff --git a/config/locales/en.yml b/config/locales/en.yml index aaa5a451..c4bff0a9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -85,10 +85,11 @@ en: submenu_reject: Reject submenu_block: Block profiles_show_submenu: - submenu_accept: Accept - submenu_block: Block - submenu_reject: Reject - block_lists: + submenu_paused: "Paused (%{count})" + submenu_allowed: "Allowed (%{count})" + submenu_blocked: "Blocked (%{count})" + submenu_reported: "Reported (%{count})" + block_lists: title: Block lists comments_btn_box: text_pause: Pause diff --git a/config/locales/es.yml b/config/locales/es.yml index 8fe01b83..9409eddd 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -85,10 +85,11 @@ es: submenu_reject: Rechazado submenu_block: Bloqueado profiles_show_submenu: - submenu_accept: Aceptado - submenu_block: Bloqueado - submenu_reject: Rechazado - block_lists: + submenu_paused: "Pausadas (%{count})" + submenu_allowed: "Permitidas (%{count})" + submenu_blocked: "Bloqueadas (%{count})" + submenu_reported: "Reportadas (%{count})" + block_lists: title: Listas de bloqueo comments_btn_box: text_pause: Pausa From 0539eb8f2245d4c8573aa744352f1ea72b9f74ae Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:51:41 -0300 Subject: [PATCH 184/227] =?UTF-8?q?feat:=20avisar=20cuando=20no=20se=20enc?= =?UTF-8?q?ontr=C3=B3=20nada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_accounts.haml | 2 ++ app/views/moderation_queue/_instances.haml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 44c2893e..c7dba0a1 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -5,6 +5,8 @@ -# Filtros = render 'components/profiles_filters', actor_moderations: actor_moderations .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') - actor_moderations.find_each do |actor_moderation| %hr = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a45da354..77b6adea 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,7 +9,7 @@ .col-12 - if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + %h4= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - cache [instance_moderation.aasm_state, instance_moderation.instance] do From 5370a542ff52be582e927262ed57c8ffce8da42a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 19:10:37 -0300 Subject: [PATCH 185/227] feat: cambiar el estado de les actores desde el panel --- .../actor_moderations_controller.rb | 20 +++++++++++++++++++ .../moderation_queue_controller.rb | 2 +- app/models/actor_moderation.rb | 6 +++++- app/policies/actor_moderation_policy.rb | 16 +++++++++++++++ app/views/components/_profiles_btn_box.haml | 10 ++++++---- app/views/moderation_queue/_account.haml | 7 ++++--- config/locales/en.yml | 6 +++--- config/locales/es.yml | 6 +++--- 8 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 app/controllers/actor_moderations_controller.rb create mode 100644 app/policies/actor_moderation_policy.rb diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb new file mode 100644 index 00000000..543ca74d --- /dev/null +++ b/app/controllers/actor_moderations_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Gestiona la cola de moderación de actores +class ActorModerationsController < ApplicationController + ActorModeration.aasm.events.map(&:name).each do |actor_event| + define_method(actor_event) do + authorize actor_moderation + + actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") + + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end + + private + + def actor_moderation + @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id]) + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index a9611a1b..df36dfbe 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,7 +6,7 @@ class ModerationQueueController < ApplicationController def index dummy_data - session[:moderation_queue_filtered_by_state] = params[:state] + session[:moderation_queue_filters] = params.permit(:state, :actor_state) # @todo cambiar el estado por query @activity_pubs = site.activity_pubs diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index efbde33b..f186dd69 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -7,6 +7,10 @@ class ActorModeration < ApplicationRecord belongs_to :site belongs_to :actor, class_name: 'ActivityPub::Actor' + def self.events + aasm.events.map(&:name) + end + aasm do state :paused, initial: true state :allowed @@ -37,7 +41,7 @@ class ActorModeration < ApplicationRecord end end - event :reported do + event :report do transitions from: %i[blocked], to: :reported end end diff --git a/app/policies/actor_moderation_policy.rb b/app/policies/actor_moderation_policy.rb new file mode 100644 index 00000000..07a9a752 --- /dev/null +++ b/app/policies/actor_moderation_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar actores +ActorModerationPolicy = Struct.new(:usuarie, :actor_moderation) do + ActorModeration.events.each do |actor_event| + define_method(:"#{actor_event}?") do + actor_moderation.site.usuarie? usuarie + end + end + + # En este paso tenemos varias cuentas por moderar pero todas son + # del mismo sitio. + def action_on_several? + actor_moderation.first.site.usuarie? usuarie + end +end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 06faa8a1..bc1fd7e4 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,7 +1,9 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) - btn_class = 'btn-secondary' -= render 'components/btn_base', text: t('.text_approve'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file +- ActorModeration.events.each do |actor_event| + = render 'components/btn_base', + text: t(".text_#{actor_event}"), + path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), + class: btn_class, + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 27ea30d1..24fbb270 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,9 +3,10 @@ = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 - %a{href: profile['id']}= profile['preferredUsername'] - =profile['summary'].html_safe + %a{href: profile['id']}= sanitize profile['name'] + .mb-3 + = sanitize profile['summary'].html_safe -# Botones de Moderación .d-flex.pb-4 - = render 'components/profiles_btn_box' + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index c4bff0a9..3c8e8851 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -102,9 +102,9 @@ en: text_allow: Allow everything text_deny: Block instance profiles_btn_box: - text_approve: Always approve - text_check: Always check - text_deny: Block + text_pause: Always check + text_allow: Always approve + text_block: Block text_report: Report moderation_queue: everything: 'Select all' diff --git a/config/locales/es.yml b/config/locales/es.yml index 9409eddd..d2c30ef6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -102,9 +102,9 @@ es: text_allow: Permitir todo text_deny: Bloquear instancia profiles_btn_box: - text_approve: Aprobar siempre - text_check: Revisar siempre - text_deny: Bloquear + text_pause: Revisar siempre + text_allow: Aprobar siempre + text_block: Bloquear text_report: Reportar moderation_queue: everything: 'Seleccionar todo' From cf46988d9db2aa34bb26ae5dbd521923da28ed23 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 15:53:32 -0300 Subject: [PATCH 186/227] fixup! feat: cambiar el estado de les actores desde el panel --- app/views/actor_moderations/show.haml | 4 ++++ config/routes.rb | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 app/views/actor_moderations/show.haml diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml new file mode 100644 index 00000000..ba0fc257 --- /dev/null +++ b/app/views/actor_moderations/show.haml @@ -0,0 +1,4 @@ +.row.justify-content-center + .col-md-8 + %h1= t('.profile') + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/config/routes.rb b/config/routes.rb index d70f8339..f6b412e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -71,6 +71,12 @@ Rails.application.routes.draw do patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' + resources :actor_moderations, only: [] do + ActorModeration.events.each do |actor_event| + patch actor_event, to: "actor_moderations##{actor_event}" + end + end + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 3ba23a8b8c49ae25accd7bbcfaef99f6779d8a05 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 15:54:53 -0300 Subject: [PATCH 187/227] feat: poder ir al perfil desde la lista --- .../actor_moderations_controller.rb | 7 ++++- .../moderation_queue_controller.rb | 5 ---- app/views/actor_moderations/show.haml | 8 +++-- app/views/components/_actor.haml | 21 ++++++++++++++ app/views/components/_profiles_btn_box.haml | 15 +++++----- app/views/moderation_queue/_account.haml | 2 +- .../moderation_queue/_remote_profile.haml | 29 ------------------- .../moderation_queue/remote_profile.haml | 4 --- config/locales/en.yml | 17 ++++++----- config/locales/es.yml | 17 ++++++----- config/routes.rb | 3 +- 11 files changed, 61 insertions(+), 67 deletions(-) create mode 100644 app/views/components/_actor.haml delete mode 100644 app/views/moderation_queue/_remote_profile.haml delete mode 100644 app/views/moderation_queue/remote_profile.haml diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 543ca74d..f4637d70 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -12,9 +12,14 @@ class ActorModerationsController < ApplicationController end end + # Ver el perfil remoto + def show + @remote_profile = actor_moderation.actor.content + end + private def actor_moderation - @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id]) + @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index df36dfbe..95639b35 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -14,11 +14,6 @@ class ModerationQueueController < ApplicationController @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) end - # Perfil remoto de usuarie - def remote_profile - dummy_data - end - # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml index ba0fc257..7b62f672 100644 --- a/app/views/actor_moderations/show.haml +++ b/app/views/actor_moderations/show.haml @@ -1,4 +1,8 @@ .row.justify-content-center - .col-md-8 + .col-12.col-md-8 %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile + = render 'components/actor', remote_profile: @remote_profile + .col-12.col-md-8 + = render 'components/profiles_btn_box', actor_moderation: @actor_moderation + -# + = render 'moderation_queue/comments', moderation_queue: @moderation_queue diff --git a/app/views/components/_actor.haml b/app/views/components/_actor.haml new file mode 100644 index 00000000..f5d6efae --- /dev/null +++ b/app/views/components/_actor.haml @@ -0,0 +1,21 @@ +-# Componente Remote_Profile + +.py-2 + %dl + %dt= t('.profile_name') + %dd= sanitize remote_profile['name'] + + %dt= t('.preferred_name') + %dd= sanitize remote_profile['preferredUsername'] + + %dt= t('.profile_id') + %dd + = link_to sanitize(remote_profile['id']) + + - if remote_profile['published'].present? + %dt= t('.profile_published') + %dd + = render 'layouts/time', time: sanitize(remote_profile['published']) + %dt= t('.profile_summary') + %dd + = sanitize remote_profile['summary'] diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index bc1fd7e4..bd994f84 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,9 +1,10 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) -- btn_class = 'btn-secondary' -- ActorModeration.events.each do |actor_event| - = render 'components/btn_base', - text: t(".text_#{actor_event}"), - path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), - class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") +.d-flex.flex-row + - btn_class = 'btn-secondary' + - ActorModeration.events.each do |actor_event| + = render 'components/btn_base', + text: t(".text_#{actor_event}"), + path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), + class: btn_class, + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 24fbb270..cdcc0ad4 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,7 +3,7 @@ = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 - %a{href: profile['id']}= sanitize profile['name'] + = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) .mb-3 = sanitize profile['summary'].html_safe diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml deleted file mode 100644 index 92cf8e96..00000000 --- a/app/views/moderation_queue/_remote_profile.haml +++ /dev/null @@ -1,29 +0,0 @@ --# Componente Remote_Profile - -.flex.py-2.mx-2 - %dl - %dt= t('.profile_name') - %dd= remote_profile['name'] - - %dt= t('.preferred_name') - %dd= remote_profile['preferredUsername'] - - %dt= t('.profile_id') - %dd - %a{ href: 'https://mastodon.mauve.moe/users/mauve' }= remote_profile['id'] - - %dt= t('.profile_published') - %dd - = render 'layouts/time', time: remote_profile['published'] - %dt= t('.profile_summary') - %dd - %p= remote_profile['summary'].html_safe - - = render 'moderation_queue/comments', moderation_queue: @moderation_queue - -%dl.mt-5 - %dt= t('.profile_name') - %dd= remote_profile['name'] - --# Botones de Moderación -= render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml deleted file mode 100644 index ba0fc257..00000000 --- a/app/views/moderation_queue/remote_profile.haml +++ /dev/null @@ -1,4 +0,0 @@ -.row.justify-content-center - .col-md-8 - %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/config/locales/en.yml b/config/locales/en.yml index 3c8e8851..62e9a1a7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,6 +106,15 @@ en: text_allow: Always approve text_block: Block text_report: Report + actor_moderations: + show: + user: Username + profile: Profile + profile_name: Profile name + preferred_name: Name in Fediverse + profile_id: ID + profile_published: Published + profile_summary: Summary moderation_queue: everything: 'Select all' nothing: "There's nothing for this filter" @@ -117,14 +126,6 @@ en: comment: source_profile: Source Profile reply_to: Reply to - remote_profile: - user: Username - profile: Profile - profile_name: Profile name - preferred_name: Name in Fediverse - profile_id: ID - profile_published: Published - profile_summary: Summary instances: title: My block lists description: Description diff --git a/config/locales/es.yml b/config/locales/es.yml index d2c30ef6..3dc68d98 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,15 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + actor_moderations: + show: + user: Nombre de usuarie + profile: Cuenta de Origen + profile_name: Nombre de la cuenta + preferred_name: Nombre en el Fediverso + profile_id: ID + profile_published: Publicada + profile_summary: Presentación moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' @@ -117,14 +126,6 @@ es: comment: source_profile: Cuenta de Origen reply_to: En respuesta a - remote_profile: - user: Nombre de usuario - profile: Cuenta de Origen - profile_name: Nombre de la Cuenta - preferred_name: Nombre en el Fediverso - profile_id: ID - profile_published: Publicada - profile_summary: Presentación instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo diff --git a/config/routes.rb b/config/routes.rb index f6b412e2..ceffcd26 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -59,7 +59,6 @@ Rails.application.routes.draw do post 'collaborate', to: 'collaborations#accept_collaboration' get 'moderation_queue', to: 'moderation_queue#index' - get 'remote_profile', to: 'moderation_queue#remote_profile' get 'instances', to: 'moderation_queue#instances' resources :instance_moderations, only: [] do @@ -71,7 +70,7 @@ Rails.application.routes.draw do patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' - resources :actor_moderations, only: [] do + resources :actor_moderations, only: %i[show] do ActorModeration.events.each do |actor_event| patch actor_event, to: "actor_moderations##{actor_event}" end From cbba822f31b12d5607210aa2dec749915d8184c7 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 16:27:48 -0300 Subject: [PATCH 188/227] feat: recordar el estado del details --- .../controllers/details_controller.js | 17 +++++++++++++++++ app/views/layouts/_details.haml | 9 +++++++-- app/views/moderation_queue/index.haml | 9 +++------ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 app/javascript/controllers/details_controller.js diff --git a/app/javascript/controllers/details_controller.js b/app/javascript/controllers/details_controller.js new file mode 100644 index 00000000..57935e1e --- /dev/null +++ b/app/javascript/controllers/details_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = []; + + connect() { + const state = window.sessionStorage.getItem(this.element.id); + + if (state === "open") { + this.element.setAttribute("open", true); + } + } + + store(event = undefined) { + window.sessionStorage.setItem(this.element.id, event.newState); + } +} diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 99ba4894..ce38bddd 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,6 +1,11 @@ --# Detail Cola de Moderación +-# + Detail Cola de Moderación -%details.details.py-2 + @param :id [String] El ID opcional sirve para mantener el historial de + cuál estaba abierto y recuperarlo al cargar la página + @param :summary [String] El resumen + +%details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' } } %summary .row .col-11.pr-2 diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index df2c219d..799fc641 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -3,14 +3,11 @@ %h1= t('.title') .row .col - - summary = t('.instances') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'summary', summary: t('.instances') do = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr - - summary = t('.accounts') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'accounts', summary: t('.accounts') do = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations %hr - - summary = t('.comments') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'comments', summary: t('.comments') do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue From 6c61aec60e177d522e0dacd7d50152c6ec72b5d0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 16:45:06 -0300 Subject: [PATCH 189/227] feat: al modificar un fediblock, cambiar el estado a todes les actores --- app/models/actor_moderation.rb | 12 ++++++++++++ app/models/fediblock_state.rb | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index f186dd69..1d9bae5d 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -7,6 +7,18 @@ class ActorModeration < ApplicationRecord belongs_to :site belongs_to :actor, class_name: 'ActivityPub::Actor' + # Bloquea todes les Actores bloqueables + def self.block_all! + self.update_all(aasm_state: 'blocked', updated_at: Time.now) + end + + def self.pause_all! + 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 diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index a160c43a..180a45b5 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -37,6 +37,11 @@ class FediblockState < ApplicationRecord # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) + + # Bloquear a todes les Actores de las instancias bloqueadas para + # indicarle a le usuarie que les tiene que desbloquear + # manualmente. + ActorModeration.where(actor_id: actor_ids).paused.block_all! end end @@ -52,15 +57,27 @@ class FediblockState < ApplicationRecord disable_remotely! instance_moderations.pause_all! + + # Volver a pausar todes les actores de esta instancia que fueron + # bloqueades. + ActorModeration.where(actor_id: actor_ids).blocked.pause_all! end end end private + def actor_ids + ActivityPub::Actor.where(instance_id: instance_ids).pluck(:id) + end + + def instance_ids + fediblock.instances.pluck(:id) + end + # Todas las instancias de moderación de este sitio def instance_moderations - site.instance_moderations.where(instance_id: fediblock.instances.pluck(:id)) + site.instance_moderations.where(instance_id: instance_ids) end # @return [Array] From 67d9731b1e37606f6b150704fd9d853b6caf34e3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 15:04:07 -0300 Subject: [PATCH 190/227] feat: enviar reportes remotos --- .../activity_pub/remote_flags_controller.rb | 27 +++++++++++ app/jobs/activity_pub/remote_flag_job.rb | 25 ++++++++++ app/models/activity_pub/actor.rb | 1 + app/models/deploy_social_distributed_press.rb | 9 +--- app/models/site/social_distributed_press.rb | 8 ++++ app/models/social_inbox.rb | 26 ++++++++--- config/routes.rb | 4 ++ ...201155_create_activity_pub_remote_flags.rb | 16 +++++++ db/structure.sql | 46 ++++++++++++++++++- 9 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 app/controllers/api/v1/activity_pub/remote_flags_controller.rb create mode 100644 app/jobs/activity_pub/remote_flag_job.rb create mode 100644 db/migrate/20240229201155_create_activity_pub_remote_flags.rb diff --git a/app/controllers/api/v1/activity_pub/remote_flags_controller.rb b/app/controllers/api/v1/activity_pub/remote_flags_controller.rb new file mode 100644 index 00000000..23245b8b --- /dev/null +++ b/app/controllers/api/v1/activity_pub/remote_flags_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Api + module V1 + module ActivityPub + # Devuelve los reportes remotos hechos + # + # @todo Verificar la firma. Por ahora no es necesario porque no es + # posible obtener remotamente todos los reportes y se identifican por + # UUIDv4. + class RemoteFlagsController < BaseController + skip_forgery_protection + + def show + render json: (remote_flag&.content || {}), content_type: 'application/activity+json' + end + + private + + # @return [ActivityPub::RemoteFlag,nil] + def remote_flag + @remote_flag ||= ::ActivityPub::RemoteFlag.find(params[:id]) + end + end + end + end +end diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb new file mode 100644 index 00000000..332d31ac --- /dev/null +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# Envía un reporte directamente a la instancia remota +# +# @todo El panel debería ser su propia instancia y firmar sus propios +# mensajes. +# @todo Como la Social Inbox no soporta enviar actividades +# a destinataries que no sean seguidores, enviamos el reporte +# directamente a la instancia. +# @see {https://github.com/hyphacoop/social.distributed.press/issues/14} +class ActivityPub + class RemoteFlagJob < ApplicationJob + self.priority = 30 + + def perform(remote_flag:) + client = remote_flag.site.social_inbox.client_for(remote_flag.actor.content['inbox']) + response = client.post(endpoint: '', body: remote_flag.content) + + raise 'No se pudo enviar el reporte' unless response.ok? + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) + raise + end + end +end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index a5171815..fe6052bf 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -13,6 +13,7 @@ class ActivityPub has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities + has_many :remote_flags # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 9f968f36..eec8189b 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -58,13 +58,6 @@ class DeploySocialDistributedPress < Deploy private - # Obtiene el hostname de la API de Sutty - # - # @return [String] - def api_hostname - Rails.application.routes.default_url_options[:host].sub('panel', 'api') - end - # Crea los hooks en la Social Inbox para que nos avise de actividades # nuevas # @@ -80,7 +73,7 @@ class DeploySocialDistributedPress < Deploy webhook_class.new.call({ method: 'POST', url: Rails.application.routes.url_helpers.public_send( - event_url, site_id: site.name, host: api_hostname + event_url, site_id: site.name, host: site.social_inbox_hostname ), headers: { 'X-Social-Inbox': rol.token diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index e916bf3e..0716a670 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -15,6 +15,7 @@ class Site has_many :actor_moderations has_many :fediblock_states has_many :instances, through: :instance_moderations + has_many :remote_flags, class_name: 'ActivityPub::RemoteFlag' before_save :generate_private_key_pem!, unless: :private_key_pem? @@ -23,6 +24,13 @@ class Site @social_inbox ||= SocialInbox.new(site: self) end + # Obtiene el hostname de la API de Sutty + # + # @return [String] + def social_inbox_hostname + Rails.application.routes.default_url_options[:host].sub('panel', 'api') + end + private # Genera la llave privada y la almacena diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 6677a320..183ebfb0 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -37,13 +37,25 @@ class SocialInbox # @return [DistributedPress::V1::Social::Client] def client - @client ||= DistributedPress::V1::Social::Client.new( - url: site.config.dig('activity_pub', 'url'), - public_key_url: public_key_url, - private_key_pem: site.private_key_pem, - logger: Rails.logger, - cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) - ) + @client ||= client_for site.config.dig('activity_pub', 'url') + end + + # Permite enviar mensajes directo a otro servidor + # + # @param url [String] + # @return [DistributedPress::V1::Social::Client] + def client_for(url) + raise "Falló generar un cliente" if url.blank? + + @client_for ||= {} + @client_for[url] ||= + DistributedPress::V1::Social::Client.new( + url: url, + public_key_url: public_key_url, + private_key_pem: site.private_key_pem, + logger: Rails.logger, + cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) + ) end # @return [DistributedPress::V1::Social::Inbox] diff --git a/config/routes.rb b/config/routes.rb index ceffcd26..32936d42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,10 @@ Rails.application.routes.draw do namespace :v1 do resources :csp_reports, only: %i[create] + namespace :activity_pub do + resources :remote_flags, only: %i[show] + end + resources :sites, only: %i[index], constraints: { site_id: /[a-z0-9\-.]+/, id: /[a-z0-9\-.]+/ } do get :'invitades/cookie', to: 'invitades#cookie' post :'posts/:layout', to: 'posts#create', as: :posts diff --git a/db/migrate/20240229201155_create_activity_pub_remote_flags.rb b/db/migrate/20240229201155_create_activity_pub_remote_flags.rb new file mode 100644 index 00000000..c60aca22 --- /dev/null +++ b/db/migrate/20240229201155_create_activity_pub_remote_flags.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Lleva el registro de reportes remotos +class CreateActivityPubRemoteFlags < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_remote_flags, id: :uuid do |t| + t.timestamps + t.belongs_to :site + t.uuid :actor_id, index: true + + t.text :message + + t.index %i[site_id actor_id], unique: true + end + end +end diff --git a/db/structure.sql b/db/structure.sql index e4d39ad0..6cdb49f1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -546,6 +546,20 @@ CREATE TABLE public.activity_pub_objects ( ); +-- +-- Name: activity_pub_remote_flags; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_remote_flags ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + actor_id uuid, + message text +); + + -- -- Name: activity_pubs; Type: TABLE; Schema: public; Owner: - -- @@ -1762,6 +1776,14 @@ ALTER TABLE ONLY public.activity_pub_objects ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id); +-- +-- Name: activity_pub_remote_flags activity_pub_remote_flags_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_remote_flags + ADD CONSTRAINT activity_pub_remote_flags_pkey PRIMARY KEY (id); + + -- -- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2122,6 +2144,27 @@ CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USIN CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); +-- +-- Name: index_activity_pub_remote_flags_on_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_remote_flags_on_actor_id ON public.activity_pub_remote_flags USING btree (actor_id); + + +-- +-- Name: index_activity_pub_remote_flags_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_remote_flags_on_site_id ON public.activity_pub_remote_flags USING btree (site_id); + + +-- +-- Name: index_activity_pub_remote_flags_on_site_id_and_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_activity_pub_remote_flags_on_site_id_and_actor_id ON public.activity_pub_remote_flags USING btree (site_id, actor_id); + + -- -- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - -- @@ -2653,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240227134845'), ('20240227142019'), ('20240228171335'), -('20240228202830'); +('20240228202830'), +('20240229201155'); From 3fa19ee8b042e5e0a35481450ba07f3d734f3392 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 15:51:54 -0300 Subject: [PATCH 191/227] feat: reportar desde el panel --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- .../actor_moderations_controller.rb | 12 ++++++++++- app/models/activity_pub/remote_flag.rb | 20 +++++++++++++++++++ app/models/actor_moderation.rb | 9 +++++++++ app/views/components/_profiles_btn_box.haml | 11 +++++++++- app/views/moderation_queue/_account.haml | 5 +++-- config/locales/en.yml | 1 + config/locales/es.yml | 1 + ...224_add_remote_flag_to_actor_moderation.rb | 18 +++++++++++++++++ db/structure.sql | 6 ++++-- 11 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 app/models/activity_pub/remote_flag.rb create mode 100644 db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb diff --git a/Gemfile b/Gemfile index d720a2d6..f4125f65 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'devise-i18n' gem 'devise_invitable' gem 'redis-client' gem 'hiredis-client' -gem 'distributed-press-api-client', '~> 0.4.0rc2' +gem 'distributed-press-api-client', '~> 0.4.0rc3' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 72a30af1..366b58a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,12 +166,12 @@ GEM devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0rc2) + distributed-press-api-client (0.4.0rc3) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema httparty (~> 0.18) - httparty-cache (~> 0.0.4) + httparty-cache (~> 0.0.6) json (~> 2.1, >= 2.1.0) jwt (~> 2.6.0) dotenv (2.8.1) @@ -272,7 +272,7 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - httparty-cache (0.0.5) + httparty-cache (0.0.6) httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -626,7 +626,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0rc2) + distributed-press-api-client (~> 0.4.0rc3) dotenv-rails down ed25519 diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index f4637d70..7450835b 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -2,10 +2,13 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController - ActorModeration.aasm.events.map(&:name).each do |actor_event| + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation + # Crea una RemoteFlag si se envían los parámetros adecuados + actor_moderation.update(actor_moderation_params) if actor_event == :report + actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) @@ -22,4 +25,11 @@ class ActorModerationsController < ApplicationController def actor_moderation @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end + + def actor_moderation_params + params.require(:actor_moderation).permit(remote_flag_attributes: %i[message]).tap do |p| + p[:remote_flag_attributes][:site_id] = actor_moderation.site_id + p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id + end + end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb new file mode 100644 index 00000000..b790c4b1 --- /dev/null +++ b/app/models/activity_pub/remote_flag.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class ActivityPub + class RemoteFlag < ApplicationRecord + belongs_to :actor + belongs_to :site + + # Genera la actividad a enviar + def content + { + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, host: site.social_inbox_hostname), + 'type' => 'Flag', + 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, + 'content' => message.to_s, + 'object' => [ actor.uri ] + } + end + end +end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 1d9bae5d..c6f8bfc0 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -5,8 +5,11 @@ class ActorModeration < ApplicationRecord include AASM belongs_to :site + belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' belongs_to :actor, class_name: 'ActivityPub::Actor' + accepts_nested_attributes_for :remote_flag + # Bloquea todes les Actores bloqueables def self.block_all! self.update_all(aasm_state: 'blocked', updated_at: Time.now) @@ -53,8 +56,14 @@ class ActorModeration < ApplicationRecord end end + # Al reportar, necesitamos asociar una RemoteFlag para poder + # enviarla. event :report do transitions from: %i[blocked], to: :reported + + before do + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + end end end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index bd994f84..3ec95e59 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,5 +1,13 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) +- form_params = {} +- form_params[:report] = { actor_moderation: { remote_flag_attributes: { message: '' } } } +- I18n.available_locales.each do |locale| + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t(locale) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += ': ' + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t('.report_message', locale: locale, panel_actor_mention: ENV.fetch('PANEL_ACTOR_MENTION') { '@sutty@sutty.nl' }) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += '\n\n' + .d-flex.flex-row - btn_class = 'btn-secondary' - ActorModeration.events.each do |actor_event| @@ -7,4 +15,5 @@ text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") + disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), + params: form_params[actor_event] diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index cdcc0ad4..5e574c71 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -8,5 +8,6 @@ = sanitize profile['summary'].html_safe -# Botones de Moderación - .d-flex.pb-4 - = render 'components/profiles_btn_box', actor_moderation: actor_moderation + - cache actor_moderation do + .d-flex.pb-4 + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index 62e9a1a7..4aea89f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,6 +106,7 @@ en: text_allow: Always approve text_block: Block text_report: Report + report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." actor_moderations: show: user: Username diff --git a/config/locales/es.yml b/config/locales/es.yml index 3dc68d98..7b033859 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,7 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." actor_moderations: show: user: Nombre de usuarie diff --git a/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb new file mode 100644 index 00000000..63e4ce1b --- /dev/null +++ b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Las acciones de moderación pueden tener un reporte remoto asociado +class AddRemoteFlagToActorModeration < ActiveRecord::Migration[6.1] + def up + add_column :actor_moderations, :remote_flag_id, :uuid, null: true + + ActivityPub::RemoteFlag.all.find_each do |remote_flag| + actor_moderation = ActorModeration.find_by(actor_id: remote_flag.actor_id) + + actor_moderation&.update_column(:remote_flag_id, remote_flag.id) + end + end + + def down + remove_column :actor_moderations, :remote_flag_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 6cdb49f1..38a56b46 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -586,7 +586,8 @@ CREATE TABLE public.actor_moderations ( updated_at timestamp(6) without time zone NOT NULL, site_id bigint, actor_id uuid, - aasm_state character varying NOT NULL + aasm_state character varying NOT NULL, + remote_flag_id uuid ); @@ -2697,6 +2698,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240227142019'), ('20240228171335'), ('20240228202830'), -('20240229201155'); +('20240229201155'), +('20240301181224'); From f8b45866336c097267261bc34c80bfb5afd1e4d5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:11:33 -0300 Subject: [PATCH 192/227] feat: poder cambiar el estado a varies actores --- .../actor_moderations_controller.rb | 18 +++++++++++++ .../components/_profiles_checked_submenu.haml | 6 ++--- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_accounts.haml | 26 ++++++++++--------- config/locales/en.yml | 4 +-- config/locales/es.yml | 8 +++--- config/routes.rb | 2 ++ 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 7450835b..907f21c6 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -20,6 +20,24 @@ class ActorModerationsController < ApplicationController @remote_profile = actor_moderation.actor.content end + def action_on_several + actor_moderations = site.actor_moderations.where(id: params[:actor_moderation]) + + authorize actor_moderations + + action = params[:actor_moderation_action].to_sym + method = :"#{action}!" + may = :"may_#{action}?" + + return unless ActorModeration.events.include? action + + ActorModeration.transaction do + actor_moderations.find_each do |actor_moderation| + actor_moderation.public_send(method) if actor_moderation.public_send(may) + end + end + end + private def actor_moderation diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index 8d8f8940..c0b99aa5 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,4 +1,2 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' +- ActorModeration.events.each do |actor_event| + = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 5e574c71..e891b4ad 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } + = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index c7dba0a1..35b0b86e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,14 @@ -.row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'actors' - .col-11 - -# Filtros - = render 'components/profiles_filters', actor_moderations: actor_moderations - .col-12 - - if actor_moderations.count.zero? - %h4= t('moderation_queue.nothing') - - actor_moderations.find_each do |actor_moderation| - %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content +%form{ action: site_actor_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'actors' + .col-11 + -# Filtros + = render 'components/profiles_filters', actor_moderations: actor_moderations + .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') + - actor_moderations.find_each do |actor_moderation| + - cache [actor_moderation, actor_moderation.actor] do + %hr + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/config/locales/en.yml b/config/locales/en.yml index 4aea89f7..6d5baf5a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -81,9 +81,9 @@ en: text_checked: With selected profiles_checked_submenu: submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject + submenu_allow: Allow submenu_block: Block + submenu_report: Report profiles_show_submenu: submenu_paused: "Paused (%{count})" submenu_allowed: "Allowed (%{count})" diff --git a/config/locales/es.yml b/config/locales/es.yml index 7b033859..13534822 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -80,10 +80,10 @@ es: text_show: Ver text_checked: Con los marcados profiles_checked_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_reject: Rechazado - submenu_block: Bloqueado + submenu_pause: Pausar + submenu_allow: Aceptar + submenu_block: Bloquear + submenu_report: Reportar profiles_show_submenu: submenu_paused: "Pausadas (%{count})" submenu_allowed: "Permitidas (%{count})" diff --git a/config/routes.rb b/config/routes.rb index 32936d42..9d825a3c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,8 @@ Rails.application.routes.draw do end end + patch :actor_moderations_action_on_several, to: 'actor_moderations#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 567f0a10fb9f8427157992352be9ebe8dfd636f5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:12:34 -0300 Subject: [PATCH 193/227] =?UTF-8?q?fix:=20no=20fallar=20si=20no=20se=20pue?= =?UTF-8?q?de=20hacer=20la=20acci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/instance_moderations_controller.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index d25e1450..dc9e1dfa 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -24,14 +24,14 @@ class InstanceModerationsController < ApplicationController action = params[:instance_moderation_action].to_sym method = :"#{action}!" + may = :"may_#{action}?" + events = instance_moderation.aasm.events.map(&:name) + + return unless events.include? action InstanceModeration.transaction do instance_moderations.find_each do |instance_moderation| - events = instance_moderation.aasm.events.map(&:name) - - next unless events.include? action - - instance_moderation.public_send(method) + instance_moderation.public_send(method) if instance_moderation.public_send(may) end end end From 163f3fa7375e624bb7e30a6076f019c2d413eddd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:00 -0300 Subject: [PATCH 194/227] fix: namespace --- .../v1/webhooks/social_inbox_controller.rb | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 34ef1d6c..9c1a62ba 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -25,7 +25,8 @@ module Api # Devuelve un error si el token no es válido usuarie.present? - ActivityPub.transaction do + ::ActivityPub.transaction do + # Crea todos los registros necesarios y actualiza el estado actor.present? instance.present? @@ -47,7 +48,7 @@ module Api # # @todo DRY def onapproved - ActivityPub.transaction do + ::ActivityPub.transaction do actor.present? instance.present? object.present? @@ -63,7 +64,7 @@ module Api # # @todo DRY def onrejected - ActivityPub.transaction do + ::ActivityPub.transaction do actor.present? instance.present? object.present? @@ -110,7 +111,7 @@ module Api # # @return [ActivityPub::Object] def object - @object ||= ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| + @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| # XXX: Si el objeto es una actividad, esto siempre va a ser # Generic o.type ||= 'ActivityPub::Object::Generic' @@ -120,7 +121,7 @@ module Api # XXX: el objeto necesita ser guardado antes de poder # procesarlo - ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? + ::ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? end end @@ -137,7 +138,7 @@ module Api # @return [ActivityPub::Activity] def activity @activity ||= - ActivityPub::Activity + ::ActivityPub::Activity .type_from(original_activity) .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup @@ -151,20 +152,20 @@ module Api # # @return [Actor] def actor - @actor ||= ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + @actor ||= ::ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| unless a.instance - a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) site.instance_moderations.find_or_create_by(instance: a.instance) - ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end a.save! site.actor_moderations.find_or_create_by(actor: a) - ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) + ::ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end From 4bef3096210f73b2be57016f21d5e8d2c49a82dc Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:11 -0300 Subject: [PATCH 195/227] fix: soportar flags --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 9c1a62ba..c6aad11f 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -91,6 +91,7 @@ module Api def object_uri @object_uri ||= case original_activity[:object] + when Array then original_activity[:object].first when String then original_activity[:object] when Hash then original_activity.dig(:object, :id) end From 2e1087107af045aa0563c1f0dd5078b27d6bc225 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:23 -0300 Subject: [PATCH 196/227] fix: indexar por el tipo actual --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c6aad11f..23bd749d 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -131,7 +131,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object: object) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object_id: object.id, object_type: object.type) end # Crea la actividad y la vincula con el estado From 09e56b88ed5bfa2329b153ef33cf78a534ed5a40 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:51:40 -0300 Subject: [PATCH 197/227] =?UTF-8?q?fix:=20detectar=20si=20viene=20vac?= =?UTF-8?q?=C3=ADo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 23bd749d..3de32104 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -96,7 +96,7 @@ module Api when Hash then original_activity.dig(:object, :id) end ensure - raise ActiveRecord::RecordNotFound, 'object id missing' unless @object_uri + raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? end # Atajo a la instancia From 22f730b805dbcfc4daa16bde2147872d07250ceb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 17:14:24 -0300 Subject: [PATCH 198/227] fix: guardar el tipo correcto de objeto si lo soportamos --- .../api/v1/webhooks/social_inbox_controller.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 3de32104..dec2ee97 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -116,7 +116,15 @@ module Api # XXX: Si el objeto es una actividad, esto siempre va a ser # Generic o.type ||= 'ActivityPub::Object::Generic' - o.content = original_object if object_embedded? + + if object_embedded? + o.content = original_object + begin + type = original_object[:type].presence + o.type = "ActivityPub::Object::#{type}".constantize if type + rescue NameError + end + end o.save! From 85c45d48236f0a7040e2e23545ee08bfc6f2fb9e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 17:29:08 -0300 Subject: [PATCH 199/227] =?UTF-8?q?fix:=20no=20duplicar=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 7 +------ app/models/activity_pub.rb | 3 ++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index dec2ee97..fda51f49 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -89,12 +89,7 @@ module Api # # @return [String] def object_uri - @object_uri ||= - case original_activity[:object] - when Array then original_activity[:object].first - when String then original_activity[:object] - when Hash then original_activity.dig(:object, :id) - end + @object_uri ||= ::ActivityPub.uri_from_object(original_activity[:object]) ensure raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 1afeee96..86c3f240 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -24,8 +24,9 @@ class ActivityPub < ApplicationRecord # @return [String, nil] def self.uri_from_object(object) case object + when Array then uri_from_object(object.first) when String then object - when Hash then object['id'] + when Hash then (object['id'] || object[:id]) end end From b255acf2fd98d2541a8bf6277390a7dc06609843 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 11:59:29 -0300 Subject: [PATCH 200/227] feat: comentarios por actore --- .../v1/webhooks/social_inbox_controller.rb | 2 +- .../moderation_queue_controller.rb | 1 + app/models/activity_pub.rb | 1 + app/processors/activity_pub_processor.rb | 15 ++++++++ app/views/moderation_queue/_comment.haml | 37 +++++++++---------- app/views/moderation_queue/_comments.haml | 10 ++--- app/views/moderation_queue/index.haml | 4 +- ...301202955_add_actor_id_to_activity_pubs.rb | 16 ++++++++ db/structure.sql | 6 ++- 9 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 app/processors/activity_pub_processor.rb create mode 100644 db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index fda51f49..464a0ffe 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -134,7 +134,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object_id: object.id, object_type: object.type) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, actor: actor, instance: instance, object_id: object.id, object_type: object.type) end # Crea la actividad y la vincula con el estado diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 95639b35..b803ccc9 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -12,6 +12,7 @@ class ModerationQueueController < ApplicationController @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) + @moderation_queue = rubanok_process(site.activity_pubs, with: ActivityPubProcessor) end # todon.nl está usando /api/v2/instance diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 86c3f240..b52c2a76 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -13,6 +13,7 @@ class ActivityPub < ApplicationRecord belongs_to :instance belongs_to :site belongs_to :object, polymorphic: true + belongs_to :actor has_many :activities validates :site_id, presence: true diff --git a/app/processors/activity_pub_processor.rb b/app/processors/activity_pub_processor.rb new file mode 100644 index 00000000..52cdb6d3 --- /dev/null +++ b/app/processors/activity_pub_processor.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Gestiona los filtros de ActivityPub +class ActivityPubProcessor < Rubanok::Processor + # En orden descendiente para encontrar la última actividad + # + # Por ahora solo queremos moderar comentarios. + prepare do + raw.where(object_type: %w[ActivityPub::Object::Note ActivityPub::Object::Article]).order(updated_at: :desc) + end + + map :activity_pub_state, activate_always: true do |activity_pub_state: 'paused'| + raw.where(aasm_state: activity_pub_state) + end +end diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index afd2a335..495aaf55 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,24 +4,21 @@ .col-1 = render 'components/checkbox', id: comment['id'] .col-11 - .row.no-gutters - .col.col-lg-10.d-inline-flex.justify-content-between - %h4 - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + .d-flex.flex-row.align-items-center.justify-content-between + %h4.mb-0 + %a{ href: comment['attributedTo'] }= sanitize profile['preferredUsername'] + %small = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'] - .row.no-gutters - .col.p-0 - %p - %span= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row.no-gutters - .col.p-0 - - if comment['summary'] - - summary = comment['summary'] - = render 'layouts/details', summary: summary do - %p= comment['content'].html_safe - - else - %p= comment['content'].html_safe - + - if comment['inReplyTo'].present? + %dl + %dt.d-inline + %small= t('.reply_to') + %dd.d-inline + %small + %a{ href: comment['inReplyTo'] }= sanitize comment['inReplyTo'] + %div + - if comment['summary'].present? + = render 'layouts/details', summary: comment['summary'], summary_class: 'h5' do + = sanitize comment['content'] + - else + = sanitize comment['content'] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index eadfd78b..4fe84652 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/checkbox', id: moderation_queue.first['id'] + = render 'components/select_all', id: 'select-all-comments' .col-md-9 -# Filtros = render 'components/comments_filters' -- moderation_queue.each do |comment| +- moderation_queue.each do |activity_pub| %hr - = render 'comment', comment: comment, profile: comment['attributedTo'] - + = 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: comment \ No newline at end of file + = render 'components/comments_btn_box', comment: activity_pub.object.content diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 799fc641..80f0bd7c 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -7,7 +7,7 @@ = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr = render 'layouts/details', id: 'accounts', summary: t('.accounts') do - = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations + = render 'moderation_queue/accounts', site: @site, actor_moderations: @actor_moderations %hr = render 'layouts/details', id: 'comments', summary: t('.comments') do - = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/comments', site: @site, moderation_queue: @moderation_queue diff --git a/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb b/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb new file mode 100644 index 00000000..37db4bfc --- /dev/null +++ b/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Relaciona estados de actividades con les actores que las hicieron +class AddActorIdToActivityPubs < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :actor_id, :uuid + + ActivityPub.all.find_each do |activity_pub| + activity_pub.update_column(:actor_id, activity_pub.activities.last.actor_id) + end + end + + def down + remove_column :activity_pubs, :actor_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 38a56b46..ca3a868b 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -572,7 +572,8 @@ CREATE TABLE public.activity_pubs ( object_id uuid NOT NULL, object_type character varying NOT NULL, aasm_state character varying NOT NULL, - instance_id uuid + instance_id uuid, + actor_id uuid ); @@ -2699,6 +2700,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240228171335'), ('20240228202830'), ('20240229201155'), -('20240301181224'); +('20240301181224'), +('20240301202955'); From d1a87177a58664da0c420e17764e297fdb74ffa9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 12:01:32 -0300 Subject: [PATCH 201/227] fix: eliminar indice unico en realidad lo queremos mantener... --- ...240301194154_remove_unique_index_from_activity_pubs.rb | 8 ++++++++ db/structure.sql | 8 +------- 2 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb diff --git a/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb b/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb new file mode 100644 index 00000000..0fa80e60 --- /dev/null +++ b/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# A veces tenemos varias acciones sobre el mismo objeto +class RemoveUniqueIndexFromActivityPubs < ActiveRecord::Migration[6.1] + def change + remove_index :activity_pubs, %i[site_id object_id object_type], unique: true + end +end diff --git a/db/structure.sql b/db/structure.sql index ca3a868b..ff6cf895 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2167,13 +2167,6 @@ CREATE INDEX index_activity_pub_remote_flags_on_site_id ON public.activity_pub_r CREATE UNIQUE INDEX index_activity_pub_remote_flags_on_site_id_and_actor_id ON public.activity_pub_remote_flags USING btree (site_id, actor_id); --- --- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type); - - -- -- Name: index_actor_moderations_on_actor_id; Type: INDEX; Schema: public; Owner: - -- @@ -2701,6 +2694,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240228202830'), ('20240229201155'), ('20240301181224'), +('20240301194154'), ('20240301202955'); From b8e7e53ebd651332cae10f0c23dfb8239a3d1089 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:09:36 -0300 Subject: [PATCH 202/227] feat: limpieza de texto --- app/helpers/application_helper.rb | 22 ++++++++++++++++++---- app/models/metadata_template.rb | 14 ++------------ app/views/posts/show.haml | 1 - config/application.rb | 5 +++++ 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9f7be213..146846f0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,10 +33,24 @@ module ApplicationHelper end end - # Devuelve todas las etiquetas HTML que queremos mantener - def all_html_tags - %w[h1 h2 h3 h4 h5 h6 p a ul ol li table tr td th tbody thead - tfoot em strong sup blockquote cite pre section article] + # Sanitizador que elimina todo + # + # @param html [String] + # @return [String] + def text_plain(html) + sanitize(html, tags: [], attributes: []) + end + + # Sanitizador con etiquetas y atributos por defecto + # + # @param html [String] + # @param options [Hash] + # @return [String] + def sanitize(html, options = {}) + options[:tags] ||= Sutty::ALLOWED_TAGS + options[:attributes] ||= Sutty::ALLOWED_ATTRIBUTES + + super(html, options) end # Genera HTML y limpia etiquetas innecesarias diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 823443d2..a9765918 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -190,8 +190,8 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, sanitizer .sanitize(string.tr("\r", '').unicode_normalize, - tags: allowed_tags, - attributes: allowed_attributes) + tags: Sutty::ALLOWED_TAGS, + attributes: Sutty::ALLOWED_ATTRIBUTES) .strip .html_safe end @@ -200,16 +200,6 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, @sanitizer ||= Rails::Html::Sanitizer.safe_list_sanitizer.new end - def allowed_attributes - @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze - end - - def allowed_tags - @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze - end - # Decifra el valor # # XXX: Otros tipos de valores necesitan implementar su propio método diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index ec191d87..10fe64e3 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -20,7 +20,6 @@ post: @post, attribute: attr, metadata: metadata, site: @site, - tags: all_html_tags, locale: @locale, dir: dir) diff --git a/config/application.rb b/config/application.rb index 27a21cc6..ed7e5a78 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,6 +37,11 @@ if %w[development test].include? ENV['RAILS_ENV'] end module Sutty + ALLOWED_ATTRIBUTES = %w[style href src alt controls data-align data-multimedia data-multimedia-inner id name rel + target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze + ALLOWED_TAGS = %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote + figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze + # Sutty! class Application < Rails::Application # Initialize configuration defaults for originally generated Rails From 01c042b51265222638d32c8a06d89d66c4f8cf38 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:11:17 -0300 Subject: [PATCH 203/227] fix: limpiar html remoto --- app/views/components/_actor.haml | 8 ++++---- app/views/moderation_queue/_account.haml | 4 ++-- app/views/moderation_queue/_comment.haml | 10 ++++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/views/components/_actor.haml b/app/views/components/_actor.haml index 68aa3f90..3983d617 100644 --- a/app/views/components/_actor.haml +++ b/app/views/components/_actor.haml @@ -3,18 +3,18 @@ .py-2 %dl %dt= t('.profile_name') - %dd= sanitize remote_profile['name'] + %dd= text_plain remote_profile['name'] %dt= t('.preferred_name') - %dd= sanitize remote_profile['preferredUsername'] + %dd= text_plain remote_profile['preferredUsername'] %dt= t('.profile_id') %dd - = link_to sanitize(remote_profile['id']) + = link_to text_plain(remote_profile['id']) - if remote_profile['published'].present? %dt= t('.profile_published') %dd - = render 'layouts/time', time: sanitize(remote_profile['published']) + = render 'layouts/time', time: text_plain(remote_profile['published']) %dt= t('.profile_summary') %dd= sanitize remote_profile['summary'] diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index e891b4ad..fee90316 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,9 +3,9 @@ = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) + = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) .mb-3 - = sanitize profile['summary'].html_safe + = sanitize profile['summary'] -# Botones de Moderación - cache actor_moderation do diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 495aaf55..e0e625fd 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,24 +1,26 @@ -# Componente Comentario +- in_reply_to = text_plain comment['inReplyTo'] + .row.no-gutters .col-1 = render 'components/checkbox', id: comment['id'] .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 - %a{ href: comment['attributedTo'] }= sanitize profile['preferredUsername'] + %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] %small = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'].present? + - if in_reply_to.present? %dl %dt.d-inline %small= t('.reply_to') %dd.d-inline %small - %a{ href: comment['inReplyTo'] }= sanitize comment['inReplyTo'] + %a{ href: in_reply_to) }= in_reply_to %div - if comment['summary'].present? - = render 'layouts/details', summary: comment['summary'], summary_class: 'h5' do + = render 'layouts/details', summary: text_plain(comment['summary']), summary_class: 'h5' do = sanitize comment['content'] - else = sanitize comment['content'] From 6110172324f6f267f5d10a1b33e2458f061ea67a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:12:22 -0300 Subject: [PATCH 204/227] feat: poder cambiar el nivel de summary --- app/assets/stylesheets/application.scss | 34 ++++++++++++++----------- app/views/layouts/_details.haml | 9 +++++-- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a24af4c8..cdf97b5b 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -561,24 +561,28 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); // details styles .details { - summary { + & > summary { list-style: none; - cursor: default; - position: relative; + cursor: pointer; + + .hide-when-open { + display: inline; + } + + .show-when-open { + display: none; + } } - summary::after { - content: '▶'; - font-size: 1.8rem; - position: absolute; - left: 97%; - bottom: 3%; - transform: rotate(180deg); - } + &[open] { & > summary { - &::after { - transform: rotate(90deg); - } + .hide-when-open { + display: none; + } + + .show-when-open { + display: inline; + } } } -} +} diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 3260bfcb..a21f46c1 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -4,8 +4,13 @@ @param :id [String] El ID opcional sirve para mantener el historial de cuál estaba abierto y recuperarlo al cargar la página @param :summary [String] El resumen + @param :summary_class [String] Clases para el summary + +- local_assigns[:summary_class] ||= 'h3' %details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' } } - %summary - %h3.py-2.pr-2= summary + %summary.d-flex.flex-row.align-items-center.justify-content-between{ class: local_assigns[:summary_class] } + %span= summary + %span.hide-when-open ▶ + %span.show-when-open ▼ = yield From d8487ea7e9b29ef389d8a1c3ebd790bcf52f6ebe Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:17:21 -0300 Subject: [PATCH 205/227] fixup! fix: limpiar html remoto --- app/views/moderation_queue/_comment.haml | 11 ++++++----- app/views/moderation_queue/_instance.haml | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index e0e625fd..29888ef7 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,6 +1,7 @@ -# Componente Comentario - in_reply_to = text_plain comment['inReplyTo'] +- summary = text_plain(comment['summary']) .row.no-gutters .col-1 @@ -10,17 +11,17 @@ %h4.mb-0 %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] %small - = render 'layouts/time', time: comment['published'] + = render 'layouts/time', time: text_plain(comment['published']) - if in_reply_to.present? %dl %dt.d-inline %small= t('.reply_to') %dd.d-inline %small - %a{ href: in_reply_to) }= in_reply_to - %div - - if comment['summary'].present? - = render 'layouts/details', summary: text_plain(comment['summary']), summary_class: 'h5' do + %a{ href: in_reply_to }= in_reply_to + .content + - if summary.present? + = render 'layouts/details', summary: summary, summary_class: 'h5' do = sanitize comment['content'] - else = sanitize comment['content'] diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 73655e1b..97d23f10 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -7,11 +7,12 @@ .col-11 %h4 %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname - %p= sanitize instance.content['description'] + .content + = sanitize instance.content['description'] - if usuaries.present? %dl %dt.d-inline= t('.users') - %dd.d-inline= sanitize usuaries.to_s + %dd.d-inline= text_plain usuaries.to_s -# Botones moderación .d-flex.pb-4 From 5fabe9cd832753e90b2f27f9e5cab77c7c2c6a0d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:49:07 -0300 Subject: [PATCH 206/227] feat: acciones sobre comentarios --- app/controllers/activity_pubs_controller.rb | 22 +++++++++++++++++ app/models/activity_pub.rb | 3 +++ app/models/actor_moderation.rb | 10 +++----- app/models/concerns/aasm_events_concern.rb | 14 +++++++++++ app/views/components/_btn_base.haml | 1 + app/views/components/_comments_btn_box.haml | 12 +++++----- app/views/moderation_queue/_comment.haml | 12 +++++++--- app/views/moderation_queue/_comments.haml | 26 ++++++++++----------- config/locales/en.yml | 2 +- config/locales/es.yml | 5 ++-- config/routes.rb | 8 +++++++ 11 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 app/controllers/activity_pubs_controller.rb create mode 100644 app/models/concerns/aasm_events_concern.rb 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 From a2204779af2bca3f5b158e59553fa6c8787986b0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:59:01 -0300 Subject: [PATCH 207/227] feat: filtrar por estado del comentario --- app/helpers/moderation_queue_helper.rb | 7 +++++++ app/models/activity_pub.rb | 1 + app/models/actor_moderation.rb | 1 + app/models/concerns/aasm_events_concern.rb | 7 +++++++ app/views/components/_comments_filters.haml | 2 +- app/views/components/_comments_show_submenu.haml | 8 ++++---- app/views/components/_profiles_show_submenu.haml | 4 ++-- app/views/moderation_queue/_comments.haml | 2 +- config/locales/en.yml | 8 ++++---- config/locales/es.yml | 8 ++++---- 10 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 app/helpers/moderation_queue_helper.rb diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb new file mode 100644 index 00000000..3681bec3 --- /dev/null +++ b/app/helpers/moderation_queue_helper.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ModerationQueueHelper + def filter_states(**args) + params.permit(:state, :actor_state, :activity_pub_state).merge(**args) + end +end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 95fa3bf3..51ee0d71 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -12,6 +12,7 @@ class ActivityPub < ApplicationRecord include AasmEventsConcern IGNORED_EVENTS = %i[remove] + IGNORED_STATES = %i[removed] belongs_to :instance belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 1fc1a42a..421d4c6e 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -6,6 +6,7 @@ class ActorModeration < ApplicationRecord include AasmEventsConcern IGNORED_EVENTS = [] + IGNORED_STATES = [] belongs_to :site belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 79250ea9..59ea243f 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -10,5 +10,12 @@ module AasmEventsConcern def self.events aasm.events.map(&:name) - self::IGNORED_EVENTS end + + # Todos los estados de la máquina de estados + # + # @return [Array] + def self.states + aasm.states.map(&:name) - self::IGNORED_STATES + end end end diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index 7c453088..b4597be5 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -3,4 +3,4 @@ = render 'components/comments_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/comments_show_submenu' \ No newline at end of file + = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml index 0308b926..eb037975 100644 --- a/app/views/components/_comments_show_submenu.haml +++ b/app/views/components/_comments_show_submenu.haml @@ -1,4 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_report'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file +- ActivityPub.states.each do |state| + = render 'components/dropdown_item', + text: t(".submenu_#{state}", count: activity_pubs.unscope(where: :aasm_state).public_send(state).count), + path: site_moderation_queue_path(filter_states(activity_pub_state: state)) diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 703e4a15..0209ef2f 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,4 +1,4 @@ -- ActorModeration.aasm.states.map(&:name).each do |actor_state| +- ActorModeration.states.each do |actor_state| = render 'components/dropdown_item', text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), - path: site_moderation_queue_path(params.permit(:state, :actor_state).merge(actor_state: actor_state)) + path: site_moderation_queue_path(filter_states(actor_state: actor_state)) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 97f77e3c..f243b02a 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -4,7 +4,7 @@ = render 'components/select_all', id: 'select-all-comments' .col-md-9 -# Filtros - = render 'components/comments_filters' + = render 'components/comments_filters', activity_pubs: moderation_queue - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') diff --git a/config/locales/en.yml b/config/locales/en.yml index f69d60b0..eecd5ebd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -72,10 +72,10 @@ en: submenu_accept: Accept submenu_reject: Reject comments_show_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_report: Report - submenu_reject: Reject + submenu_paused: "Paused (%{count})" + submenu_approved: "Approved (%{count})" + submenu_rejected: "Rejected (%{count})" + submenu_reported: "Reported (%{count})" profiles_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index a0aaa4d6..0f9eb68a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -72,10 +72,10 @@ es: submenu_accept: Aceptado submenu_reject: Rechazado comments_show_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_report: Reportado - submenu_reject: Rechazado + submenu_paused: "Pausados (%{count})" + submenu_approved: "Aprobados (%{count})" + submenu_rejected: "Rechazados (%{count})" + submenu_reported: "Reportados (%{count})" profiles_filters: text_show: Ver text_checked: Con los marcados From 0b3f4e33fb4f32671f11bc6b2593adfe3a60524b Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:25:19 -0300 Subject: [PATCH 208/227] =?UTF-8?q?fix:=20siempre=20es=20un=20bot=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://blog.saeloun.com/2021/08/24/rails-7-button-to-rendering/ --- app/views/components/_btn_base.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index a950ad5a..4d8566d3 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -5,4 +5,5 @@ - local_assigns[:class] = "btn #{local_assigns[:class]}" -# @todo path es obligatorio -= button_to text, local_assigns[:path], **local_assigns += button_to local_assigns[:path], **local_assigns do + = text From 27d7589f9aab294283df57a14fa3b9a7cb7c7ee9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:26:41 -0300 Subject: [PATCH 209/227] fix: no se pueden anidar formularios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usando el atributo form, podemos crear un formulario vacío y colocar inputs por fuera de su contexto. de lo contrario el primer botón de acción individual no funciona --- app/models/instance_moderation.rb | 7 +++-- app/views/components/_checkbox.haml | 2 +- app/views/components/_dropdown_button.haml | 2 +- .../_instances_checked_submenu.haml | 5 ++- app/views/components/_instances_filters.haml | 2 +- app/views/components/_select_all.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 31 ++++++++++--------- 9 files changed, 28 insertions(+), 27 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 10b5e8e0..7447cc89 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -3,6 +3,10 @@ # Mantiene el registro de relaciones entre sitios e instancias class InstanceModeration < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = [] + IGNORED_STATES = [] belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' @@ -11,9 +15,6 @@ class InstanceModeration < ApplicationRecord # todas las que no estén bloqueadas ya. scope :may_block, -> { where.not(aasm_state: 'blocked') } scope :may_pause, -> { where.not(aasm_state: 'paused') } - scope :paused, -> { where(aasm_state: 'paused') } - scope :blocked, -> { where(aasm_state: 'blocked') } - scope :allowed, -> { where(aasm_state: 'allowed') } # Bloquear instancias en masa def self.block_all! diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 596ff074..68f1a663 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,5 +1,5 @@ -# Componente Checkbox - local_assigns[:name] ||= id .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, **local_assigns } + %input.custom-control-input{ form: local_assigns[:form_id], type: 'checkbox', id: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml index 8b0c4684..c8c98209 100644 --- a/app/views/components/_dropdown_button.haml +++ b/app/views/components/_dropdown_button.haml @@ -1,4 +1,4 @@ -# @param name [String] @param value [String] -%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value }= text +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, form: local_assigns[:form_id] }= text diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index c3573ead..2d28fb1c 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,2 @@ -= render 'components/dropdown_button', text: t('.submenu_pause'), name: 'instance_moderation_action', value: 'pause' -= render 'components/dropdown_button', text: t('.submenu_allow'), name: 'instance_moderation_action', value: 'allow' -= render 'components/dropdown_button', text: t('.submenu_block'), name: 'instance_moderation_action', value: 'block' +- InstanceModeration.events.each do |event| + = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form_id: form_id diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index fe40ced3..2c05693a 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/instances_checked_submenu' + = render 'components/instances_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_select_all.haml b/app/views/components/_select_all.haml index 2603dfd3..68711c4a 100644 --- a/app/views/components/_select_all.haml +++ b/app/views/components/_select_all.haml @@ -1,4 +1,4 @@ -# @param id [String] -= render 'components/checkbox', id: id, data: { action: 'select-all#toggle', target: 'select-all.toggle' } do += render 'components/checkbox', id: id, form: local_assigns[:form_id], data: { action: 'select-all#toggle', target: 'select-all.toggle' } do %span.sr-only= t('.label') diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index ffaf76cf..33ebc722 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -10,7 +10,7 @@ .row.no-gutters .col-1 - = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' }, form: form_id .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 97d23f10..05510724 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -3,7 +3,7 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: instance.hostname, form_id: form_id, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 77b6adea..83b0c772 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,22 +1,23 @@ +- form_id = 'instance_moderation_action_on_several' %section - %form{ action: site_instance_moderations_action_on_several_path, method: :post } - .row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'instances' - .col-11 - -# Filtros - = render 'components/instances_filters', site: site + %form{ id: form_id, action: site_instance_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'instances', form_id: form_id + .col-11 + -# Filtros + = render 'components/instances_filters', site: site, form_id: form_id - .col-12 - - if instance_moderations.count.zero? - %h4= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h4= t('moderation_queue.nothing') - - instance_moderations.each do |instance_moderation| - - cache [instance_moderation.aasm_state, instance_moderation.instance] do - %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + - instance_moderations.each do |instance_moderation| + - cache [instance_moderation.aasm_state, instance_moderation.instance] do + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form_id: form_id - %hr + %hr %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') From 5211c9bd28c089ea6db5b568bf20e2497e5a1597 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:39:06 -0300 Subject: [PATCH 210/227] fix: formularios --- .../components/_profiles_checked_submenu.haml | 2 +- app/views/components/_profiles_filters.haml | 2 +- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_accounts.haml | 31 ++++++++++--------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index c0b99aa5..13e016ca 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,2 +1,2 @@ - ActorModeration.events.each do |actor_event| - = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event + = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form_id: form_id diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index c6397e69..a2593f4c 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu' + = render 'components/profiles_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index fee90316..f63b6f6f 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: actor_moderation.id, form_id: form_id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 35b0b86e..53d2f28e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,14 +1,17 @@ -%form{ action: site_actor_moderations_action_on_several_path, method: :post } - .row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'actors' - .col-11 - -# Filtros - = render 'components/profiles_filters', actor_moderations: actor_moderations - .col-12 - - if actor_moderations.count.zero? - %h4= t('moderation_queue.nothing') - - actor_moderations.find_each do |actor_moderation| - - cache [actor_moderation, actor_moderation.actor] do - %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content +- form_id = 'actor_moderations_action_on_several' + += form_tag site_actor_moderations_action_on_several_path, id: form_id, method: :patch + +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'actors', form_id: form_id + .col-11 + -# Filtros + = render 'components/profiles_filters', actor_moderations: actor_moderations, form_id: form_id + .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') + - actor_moderations.find_each do |actor_moderation| + - cache [actor_moderation, actor_moderation.actor] do + %hr + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form_id: form_id From 8e681cdba79024e6fb584654025ce730d9c5d90a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:47:20 -0300 Subject: [PATCH 211/227] fix: sincronizar controladores --- app/controllers/activity_pubs_controller.rb | 8 +++-- .../actor_moderations_controller.rb | 6 +++- .../concerns/moderation_concern.rb | 13 ++++++++ .../instance_moderations_controller.rb | 32 ++++++------------- .../moderation_queue_controller.rb | 2 +- app/policies/activity_pub_policy.rb | 16 ++++++++++ app/policies/instance_moderation_policy.rb | 14 +++----- 7 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 app/controllers/concerns/moderation_concern.rb create mode 100644 app/policies/activity_pub_policy.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index dfe388a4..057e65f7 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -2,16 +2,20 @@ # Gestiona acciones de moderación class ActivityPubsController < ApplicationController + include ModerationConcern + ActivityPub.events.each do |event| define_method(event) do + authorize activity_pub + activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") - redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + redirect_to_moderation_queue! end end def action_on_several - + redirect_to_moderation_queue! end private diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 907f21c6..eadc2165 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -2,6 +2,8 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController + include ModerationConcern + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation @@ -11,7 +13,7 @@ class ActorModerationsController < ApplicationController actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") - redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + redirect_to_moderation_queue! end end @@ -29,6 +31,8 @@ class ActorModerationsController < ApplicationController method = :"#{action}!" may = :"may_#{action}?" + redirect_to_moderation_queue! + return unless ActorModeration.events.include? action ActorModeration.transaction do diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb new file mode 100644 index 00000000..9a4f1c16 --- /dev/null +++ b/app/controllers/concerns/moderation_concern.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ModerationConcern + extend ActiveSupport::Concern + + included do + private + + def redirect_to_moderation_queue! + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end +end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index dc9e1dfa..270f0588 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -2,19 +2,16 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController - before_action :authorize_policy, except: %i[action_on_several] - around_action :redirect_to_moderation_queue! + include ModerationConcern - def pause - instance_moderation.pause! if instance_moderation.may_pause? - end + InstanceModeration.events.each do |event| + define_method(event) do + authorize instance_moderation - def allow - instance_moderation.allow! if instance_moderation.may_allow? - end + instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?") - def block - instance_moderation.block! if instance_moderation.may_block? + redirect_to_moderation_queue! + end end def action_on_several @@ -25,9 +22,10 @@ class InstanceModerationsController < ApplicationController action = params[:instance_moderation_action].to_sym method = :"#{action}!" may = :"may_#{action}?" - events = instance_moderation.aasm.events.map(&:name) - return unless events.include? action + redirect_to_moderation_queue! + + return unless InstanceModeration.events.include? action InstanceModeration.transaction do instance_moderations.find_each do |instance_moderation| @@ -38,18 +36,8 @@ class InstanceModerationsController < ApplicationController private - def redirect_to_moderation_queue!(&action) - redirect_back fallback_location: site_moderation_queue_path, state: session[:moderation_queue_filtered_by_state] - - yield - end - # @return [InstanceModeration] def instance_moderation @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) end - - def authorize_policy - authorize instance_moderation - end end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index b803ccc9..6a628aaa 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,7 +6,7 @@ class ModerationQueueController < ApplicationController def index dummy_data - session[:moderation_queue_filters] = params.permit(:state, :actor_state) + session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) # @todo cambiar el estado por query @activity_pubs = site.activity_pubs diff --git a/app/policies/activity_pub_policy.rb b/app/policies/activity_pub_policy.rb new file mode 100644 index 00000000..f5755840 --- /dev/null +++ b/app/policies/activity_pub_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar comentarios +ActivityPubPolicy = Struct.new(:usuarie, :activity_pub) do + ActivityPub.events.each do |event| + define_method(:"#{event}?") do + activity_pub.site.usuarie? usuarie + end + end + + # En este paso tenemos varias instancias por moderar pero todas son + # del mismo sitio. + def action_on_several? + activity_pub.first.site.usuarie? usuarie + end +end diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index c07455b3..13ebfeca 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -2,16 +2,10 @@ # Solo les usuaries pueden moderar instancias InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do - def pause? - instance_moderation.site.usuarie? usuarie - end - - def allow? - pause? - end - - def block? - pause? + InstanceModeration.events.each do |event| + define_method(:"#{event}?") do + instance_moderation.site.usuarie? usuarie + end end # En este paso tenemos varias instancias por moderar pero todas son From a7d33976ec7c5da2d3a7a5257eee7ba66d329ce9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:59:17 -0300 Subject: [PATCH 212/227] fixup! fix: no se pueden anidar formularios --- app/views/moderation_queue/_instances.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 83b0c772..a707d48a 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,8 @@ - form_id = 'instance_moderation_action_on_several' + %section - %form{ id: form_id, action: site_instance_moderations_action_on_several_path, method: :post } + = form_tag site_instance_moderations_action_on_several_path, id: form_id, method: :patch + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'instances', form_id: form_id From 3967a631632c09a1310c4248c7b1a61406284d3e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:10:20 -0300 Subject: [PATCH 213/227] feat: extraer en un componente --- app/views/components/_select_all_container.haml | 13 +++++++++++++ app/views/moderation_queue/_accounts.haml | 2 +- app/views/moderation_queue/_instances.haml | 3 +-- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 app/views/components/_select_all_container.haml diff --git a/app/views/components/_select_all_container.haml b/app/views/components/_select_all_container.haml new file mode 100644 index 00000000..5fa91e2d --- /dev/null +++ b/app/views/components/_select_all_container.haml @@ -0,0 +1,13 @@ +-# + Contenedor para las acciones en masa. + + Es un formulario auto-contenido, que permite colocar los elementos + fuera del formulario para evitar anidarlos. Mientras los elementos + tengan el atributo `form` con el mismo parámetro `form_id`, el + navegador los va a asignar a este formulario. + + @param path [String] + @param form_id [String] + += form_tag path, id: form_id, method: :patch do + -# nada diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 53d2f28e..65ff953f 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,6 @@ - form_id = 'actor_moderations_action_on_several' -= form_tag site_actor_moderations_action_on_several_path, id: form_id, method: :patch += render 'components/select_all_container', path: site_actor_moderations_action_on_several_path, form_id: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a707d48a..d9db967f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,8 +1,7 @@ - form_id = 'instance_moderation_action_on_several' %section - = form_tag site_instance_moderations_action_on_several_path, id: form_id, method: :patch - + = render 'components/select_all_container', path: site_instance_moderations_action_on_several_path, form_id: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'instances', form_id: form_id From b201c3de1881c0e20f8b53468ea69f62b8aeb386 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:11:29 -0300 Subject: [PATCH 214/227] feat: filtros y acciones para comentarios --- .../components/_comments_checked_submenu.haml | 5 ++-- app/views/components/_comments_filters.haml | 2 +- app/views/moderation_queue/_comments.haml | 27 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml index 4998e5c7..fa3d7612 100644 --- a/app/views/components/_comments_checked_submenu.haml +++ b/app/views/components/_comments_checked_submenu.haml @@ -1,3 +1,2 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file +- ActivityPub.events.each do |event| + = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event}"), name: 'activity_pub_action', value: event diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index b4597be5..15f5173d 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/comments_checked_submenu' + = render 'components/comments_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index f243b02a..bf1e94a0 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,17 @@ -%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', activity_pubs: moderation_queue +- form_id = 'activity_pub_action_on_several' - - 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 += render 'components/select_all_container', path: site_activity_pubs_action_on_several_path, form_id: form_id + +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'select-all-comments', form_id: form_id + .col-md-9 + -# Filtros + = render 'components/comments_filters', activity_pubs: moderation_queue, form_id: form_id + .col-12 + - 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 + = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form_id: form_id From b7989808655e29cfad5db4d04755b28194108a88 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:13:01 -0300 Subject: [PATCH 215/227] feat: acciones masivas para comentarios --- app/controllers/activity_pubs_controller.rb | 16 ++++++++++++++++ config/locales/en.yml | 3 ++- config/locales/es.yml | 7 ++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 057e65f7..9bbbb9cc 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -15,7 +15,23 @@ class ActivityPubsController < ApplicationController end def action_on_several + activity_pubs = site.activity_pubs.where(id: params[:activity_pub]) + + authorize activity_pubs + + action = params[:activity_pub_action].to_sym + method = :"#{action}!" + may = :"may_#{action}?" + redirect_to_moderation_queue! + + return unless ActivityPub.events.include? action + + ActivityPub.transaction do + activity_pubs.find_each do |activity_pub| + activity_pub.public_send(method) if activity_pub.public_send(may) + end + end end private diff --git a/config/locales/en.yml b/config/locales/en.yml index eecd5ebd..a10b9f3a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -69,8 +69,9 @@ en: text_checked: With selected comments_checked_submenu: submenu_pause: Pause - submenu_accept: Accept + submenu_approve: Approve submenu_reject: Reject + submenu_report: Report comments_show_submenu: submenu_paused: "Paused (%{count})" submenu_approved: "Approved (%{count})" diff --git a/config/locales/es.yml b/config/locales/es.yml index 0f9eb68a..f5487e47 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -68,9 +68,10 @@ es: text_show: Ver text_checked: Con los marcados comments_checked_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_reject: Rechazado + submenu_pause: Pausar + submenu_approve: Aprobar + submenu_reject: Rechazar + submenu_report: Reportar comments_show_submenu: submenu_paused: "Pausados (%{count})" submenu_approved: "Aprobados (%{count})" From ccd3df2038b893b0ead29682df691dbb81862dfa Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:46:43 -0300 Subject: [PATCH 216/227] feat: aprobar o rechazar actividades --- app/models/activity_pub.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 51ee0d71..838eea80 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -64,14 +64,26 @@ class ActivityPub < ApplicationRecord transitions from: %i[approved rejected], to: :paused end - # La actividad se aprueba + # La actividad se aprueba, informándole a la Social Inbox que está + # aprobada. También recibimos la aprobación via + # webhook a modo de confirmación. event :approve do transitions from: %i[paused rejected], to: :approved + + before do + raise AASM::InvalidTransition unless + site.social_inbox.inbox.accept(id: object.uri).ok? + end end # La actividad fue rechazada event :reject do transitions from: %i[paused approved], to: :rejected + + before do + raise AASM::InvalidTransition unless + site.social_inbox.inbox.reject(id: object.uri).ok? + end end # Solo podemos reportarla luego de rechazarla From 0e2a4c42882774f56a494e29fb674401b10904e2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:52:28 -0300 Subject: [PATCH 217/227] =?UTF-8?q?fix:=20todav=C3=ADa=20no=20se=20puede?= =?UTF-8?q?=20volver=20de=20una=20actividad=20rechazada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 838eea80..0cd44814 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -61,14 +61,14 @@ class ActivityPub < ApplicationRecord # Si un objeto previamente aprobado fue actualizado, volvemos a # pausarlo. event :pause do - transitions from: %i[approved rejected], to: :paused + transitions from: %i[approved], to: :paused end # La actividad se aprueba, informándole a la Social Inbox que está # aprobada. También recibimos la aprobación via # webhook a modo de confirmación. event :approve do - transitions from: %i[paused rejected], to: :approved + transitions from: %i[paused], to: :approved before do raise AASM::InvalidTransition unless From 1fe6199cea375c319e6eb3423985151337d091e8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:53:23 -0300 Subject: [PATCH 218/227] =?UTF-8?q?fix:=20todav=C3=ADa=20no=20se=20puede?= =?UTF-8?q?=20pausar=20luego=20de=20aprobar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 0cd44814..6f0d884c 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -58,12 +58,6 @@ class ActivityPub < ApplicationRecord end end - # Si un objeto previamente aprobado fue actualizado, volvemos a - # pausarlo. - event :pause do - transitions from: %i[approved], to: :paused - end - # La actividad se aprueba, informándole a la Social Inbox que está # aprobada. También recibimos la aprobación via # webhook a modo de confirmación. From c49182e278edd723a29fcad7671a138ee1f1d623 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 17:14:46 -0300 Subject: [PATCH 219/227] feat: poder bloquear en masa --- .../actor_moderations_controller.rb | 27 ++++++++++++++++--- app/views/components/_profiles_btn_box.haml | 12 +-------- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index eadc2165..2d834015 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -9,7 +9,7 @@ class ActorModerationsController < ApplicationController authorize actor_moderation # Crea una RemoteFlag si se envían los parámetros adecuados - actor_moderation.update(actor_moderation_params) if actor_event == :report + actor_moderation.update(actor_moderation_params(actor_moderation)) if actor_event == :report actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") @@ -37,7 +37,11 @@ class ActorModerationsController < ApplicationController ActorModeration.transaction do actor_moderations.find_each do |actor_moderation| - actor_moderation.public_send(method) if actor_moderation.public_send(may) + next unless actor_moderation.public_send(may) + + actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report + + actor_moderation.public_send(method) end end end @@ -48,10 +52,25 @@ class ActorModerationsController < ApplicationController @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end - def actor_moderation_params - params.require(:actor_moderation).permit(remote_flag_attributes: %i[message]).tap do |p| + # @return [String] + def panel_actor_mention + @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') + end + + # @return [Hash] + def actor_moderation_params(actor_moderation) + { remote_flag_attributes: { id: actor_moderation.remote_flag_id, message: '' } }.tap do |p| p[:remote_flag_attributes][:site_id] = actor_moderation.site_id p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id + + I18n.available_locales.each do |locale| + p[:remote_flag_attributes][:message].tap do |m| + m += I18n.t(locale) + m += ': ' + m += I18n.t('actor_moderations.report_message', locale: locale, panel_actor_mention: panel_actor_mention) + m += '\n\n' + end + end end end end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 3ec95e59..073c142e 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,13 +1,4 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) - -- form_params = {} -- form_params[:report] = { actor_moderation: { remote_flag_attributes: { message: '' } } } -- I18n.available_locales.each do |locale| - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t(locale) - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += ': ' - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t('.report_message', locale: locale, panel_actor_mention: ENV.fetch('PANEL_ACTOR_MENTION') { '@sutty@sutty.nl' }) - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += '\n\n' - .d-flex.flex-row - btn_class = 'btn-secondary' - ActorModeration.events.each do |actor_event| @@ -15,5 +6,4 @@ text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), - params: form_params[actor_event] + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/config/locales/en.yml b/config/locales/en.yml index a10b9f3a..fe8798f4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -107,7 +107,6 @@ en: text_allow: Always approve text_block: Block text_report: Report - report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." actor_moderations: show: user: Username @@ -117,6 +116,7 @@ en: profile_id: ID profile_published: Published profile_summary: Summary + report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." moderation_queue: everything: 'Select all' nothing: "There's nothing for this filter" diff --git a/config/locales/es.yml b/config/locales/es.yml index f5487e47..e22fdf57 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,7 +106,6 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar - report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." actor_moderations: show: user: Nombre de usuarie @@ -116,6 +115,7 @@ es: profile_id: ID profile_published: Publicada profile_summary: Presentación + report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' From 67a56c540aff22e01c76a42dbb5c71ba6f414ee6 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 17:45:16 -0300 Subject: [PATCH 220/227] feat: no mostrar opciones que no se pueden ejecutar con el filtro actual --- app/models/concerns/aasm_events_concern.rb | 10 ++++++++++ app/views/components/_comments_checked_submenu.haml | 8 ++++++-- app/views/components/_comments_filters.haml | 7 +++++-- app/views/components/_instances_checked_submenu.haml | 2 +- app/views/components/_instances_filters.haml | 7 +++++-- app/views/components/_profiles_checked_submenu.haml | 2 +- app/views/components/_profiles_filters.haml | 7 +++++-- app/views/moderation_queue/_comments.haml | 2 +- 8 files changed, 34 insertions(+), 11 deletions(-) diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 59ea243f..418368d8 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -11,6 +11,16 @@ module AasmEventsConcern aasm.events.map(&:name) - self::IGNORED_EVENTS end + # Encuentra todos los eventos que se pueden ejecutar con el filtro + # actual. + # + # @return [Array] + def self.transitionable_events(current_state) + self.events.select do |event| + aasm.events.find { |x| x.name == event }.transitions_from_state? current_state + end + end + # Todos los estados de la máquina de estados # # @return [Array] diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml index fa3d7612..a09da426 100644 --- a/app/views/components/_comments_checked_submenu.haml +++ b/app/views/components/_comments_checked_submenu.haml @@ -1,2 +1,6 @@ -- ActivityPub.events.each do |event| - = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event}"), name: 'activity_pub_action', value: event +- current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first + +- ActivityPub.aasm.events.each do |event| + - next if ActivityPub::IGNORED_EVENTS.include? event.name + - next unless event.transitions_from_state?(current_state) + = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event.name}"), name: 'activity_pub_action', value: event.name diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index 15f5173d..35cd5dda 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/comments_checked_submenu', form_id: form_id + - if ActivityPub.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/comments_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index 2d28fb1c..4c45b7ab 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,2 +1,2 @@ -- InstanceModeration.events.each do |event| +- InstanceModeration.transitionable_events(current_state).each do |event| = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form_id: form_id diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 2c05693a..9e8509c4 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:state]&.to_sym || InstanceModeration.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/instances_checked_submenu', form_id: form_id + - if InstanceModeration.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/instances_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index 13e016ca..66a0fa78 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,2 +1,2 @@ -- ActorModeration.events.each do |actor_event| +- ActorModeration.transitionable_events(current_state).each do |actor_event| = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form_id: form_id diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index a2593f4c..bf7fb48a 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:actor_state]&.to_sym || ActorModeration.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu', form_id: form_id + - if ActorModeration.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/profiles_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index bf1e94a0..436777db 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -5,7 +5,7 @@ .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'select-all-comments', form_id: form_id - .col-md-9 + .col-11 -# Filtros = render 'components/comments_filters', activity_pubs: moderation_queue, form_id: form_id .col-12 From ff428c652713c0d412b0660cb5788d274fec71fa Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 14:18:06 -0300 Subject: [PATCH 221/227] feat: poder reportar comentarios --- app/controllers/activity_pubs_controller.rb | 5 +++- .../actor_moderations_controller.rb | 24 +------------------ .../concerns/moderation_concern.rb | 21 ++++++++++++++++ app/jobs/activity_pub/remote_flag_job.rb | 2 +- app/models/activity_pub.rb | 7 ++++++ app/models/activity_pub/remote_flag.rb | 7 +++++- config/locales/en.yml | 1 + config/locales/es.yml | 1 + .../20240305164653_change_remote_flags.rb | 12 ++++++++++ db/structure.sql | 6 +++-- 10 files changed, 58 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20240305164653_change_remote_flags.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 9bbbb9cc..37702d96 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -8,6 +8,7 @@ class ActivityPubsController < ApplicationController define_method(event) do authorize activity_pub + activity_pub.update(remote_flag_params(activity_pub)) if event == :report activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") redirect_to_moderation_queue! @@ -29,7 +30,9 @@ class ActivityPubsController < ApplicationController ActivityPub.transaction do activity_pubs.find_each do |activity_pub| - activity_pub.public_send(method) if activity_pub.public_send(may) + next unless activity_pub.public_send(may) + + activity_pub.public_send(method) end end end diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 2d834015..56adda4a 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -9,7 +9,7 @@ class ActorModerationsController < ApplicationController authorize actor_moderation # Crea una RemoteFlag si se envían los parámetros adecuados - actor_moderation.update(actor_moderation_params(actor_moderation)) if actor_event == :report + actor_moderation.update(remote_flag_params(actor_moderation)) if actor_event == :report actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") @@ -51,26 +51,4 @@ class ActorModerationsController < ApplicationController def actor_moderation @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end - - # @return [String] - def panel_actor_mention - @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') - end - - # @return [Hash] - def actor_moderation_params(actor_moderation) - { remote_flag_attributes: { id: actor_moderation.remote_flag_id, message: '' } }.tap do |p| - p[:remote_flag_attributes][:site_id] = actor_moderation.site_id - p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id - - I18n.available_locales.each do |locale| - p[:remote_flag_attributes][:message].tap do |m| - m += I18n.t(locale) - m += ': ' - m += I18n.t('actor_moderations.report_message', locale: locale, panel_actor_mention: panel_actor_mention) - m += '\n\n' - end - end - end - end end diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb index 9a4f1c16..5b4c276d 100644 --- a/app/controllers/concerns/moderation_concern.rb +++ b/app/controllers/concerns/moderation_concern.rb @@ -9,5 +9,26 @@ module ModerationConcern def redirect_to_moderation_queue! redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) end + + # @return [String] + def panel_actor_mention + @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') + end + + def remote_flag_params(model) + { remote_flag_attributes: { id: model.remote_flag_id, message: '' } }.tap do |p| + p[:remote_flag_attributes][:site_id] = model.site_id + p[:remote_flag_attributes][:actor_id] = model.actor_id + + I18n.available_locales.each do |locale| + p[:remote_flag_attributes][:message].tap do |m| + m << I18n.t(locale) + m << ': ' + m << I18n.t('remote_flags.report_message', locale: locale, panel_actor_mention: panel_actor_mention) + m << '\n\n' + end + end + end + end end end diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 332d31ac..30796923 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,7 +13,7 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) - client = remote_flag.site.social_inbox.client_for(remote_flag.actor.content['inbox']) + client = remote_flag.site.social_inbox.client_for(remote_flag.actor&.content['inbox']) response = client.post(endpoint: '', body: remote_flag.content) raise 'No se pudo enviar el reporte' unless response.ok? diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 6f0d884c..23f4324f 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -18,12 +18,15 @@ class ActivityPub < ApplicationRecord belongs_to :site belongs_to :object, polymorphic: true belongs_to :actor + belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' has_many :activities validates :site_id, presence: true validates :object_id, presence: true validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] } + accepts_nested_attributes_for :remote_flag + # Encuentra la URI de un objeto # # @return [String, nil] @@ -83,6 +86,10 @@ class ActivityPub < ApplicationRecord # Solo podemos reportarla luego de rechazarla event :report do transitions from: :rejected, to: :reported + + before do + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + end end end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index b790c4b1..a302503b 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -5,6 +5,11 @@ class ActivityPub belongs_to :actor belongs_to :site + has_one :actor_moderation + has_many :activity_pubs + # XXX: source_type es obligatorio para el `through` + has_many :objects, through: :activity_pubs, source_type: 'ActivityPub::Object::Note' + # Genera la actividad a enviar def content { @@ -13,7 +18,7 @@ class ActivityPub 'type' => 'Flag', 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, 'content' => message.to_s, - 'object' => [ actor.uri ] + 'object' => [ actor.uri ] + objects.pluck(:uri) } end end diff --git a/config/locales/en.yml b/config/locales/en.yml index fe8798f4..0ca90aa7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -116,6 +116,7 @@ en: profile_id: ID profile_published: Published profile_summary: Summary + remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." moderation_queue: everything: 'Select all' diff --git a/config/locales/es.yml b/config/locales/es.yml index e22fdf57..40a1a18c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -115,6 +115,7 @@ es: profile_id: ID profile_published: Publicada profile_summary: Presentación + remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." moderation_queue: everything: 'Seleccionar todo' diff --git a/db/migrate/20240305164653_change_remote_flags.rb b/db/migrate/20240305164653_change_remote_flags.rb new file mode 100644 index 00000000..258f3335 --- /dev/null +++ b/db/migrate/20240305164653_change_remote_flags.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Agrega relaciones en las remote flags +class ChangeRemoteFlags < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :remote_flag_id, :uuid, index: true, null: true + end + + def down + remove_column :activity_pubs, :remote_flag_id + end +end diff --git a/db/structure.sql b/db/structure.sql index ff6cf895..55a5ecb0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -573,7 +573,8 @@ CREATE TABLE public.activity_pubs ( object_type character varying NOT NULL, aasm_state character varying NOT NULL, instance_id uuid, - actor_id uuid + actor_id uuid, + remote_flag_id uuid ); @@ -2695,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240229201155'), ('20240301181224'), ('20240301194154'), -('20240301202955'); +('20240301202955'), +('20240305164653'); From 054dbc31e03bb7df899e978b988b46a59e41ad18 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 14:19:33 -0300 Subject: [PATCH 222/227] =?UTF-8?q?fix:=20no=20fallar=20si=20la=20activida?= =?UTF-8?q?d=20ya=20hab=C3=ADa=20cambiado=20de=20estado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 464a0ffe..548781fa 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -53,7 +53,7 @@ module Api instance.present? object.present? activity.present? - activity_pub.approve! + activity_pub.approve! if activity_pub.may_approve? end head :accepted @@ -69,7 +69,7 @@ module Api instance.present? object.present? activity.present? - activity_pub.reject! + activity_pub.reject! if activity_pub.may_reject? end head :accepted From 30fd6c28eec100ba8205f468d4fcf5f4f7e2cfea Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 15:46:33 -0300 Subject: [PATCH 223/227] feat: enviar un reporte por actore --- app/controllers/activity_pubs_controller.rb | 14 ++++++++++++++ app/controllers/concerns/moderation_concern.rb | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 37702d96..2b54cacd 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -28,6 +28,20 @@ class ActivityPubsController < ApplicationController return unless ActivityPub.events.include? action + # Crear una sola remote flag por autore + if action == :report + message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message) + + activity_pubs.distinct.pluck(:actor_id).each do |actor_id| + remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) + remote_flag.message = message + remote_flag.save + # XXX: Idealmente todas las ActivityPub que enviamos pueden + # cambiar de estado, pero chequeamos de todas formas. + remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) }) + end + end + ActivityPub.transaction do activity_pubs.find_each do |activity_pub| next unless activity_pub.public_send(may) diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb index 5b4c276d..3b9d818f 100644 --- a/app/controllers/concerns/moderation_concern.rb +++ b/app/controllers/concerns/moderation_concern.rb @@ -16,7 +16,7 @@ module ModerationConcern end def remote_flag_params(model) - { remote_flag_attributes: { id: model.remote_flag_id, message: '' } }.tap do |p| + { remote_flag_attributes: { id: model.remote_flag_id, message: ''.dup } }.tap do |p| p[:remote_flag_attributes][:site_id] = model.site_id p[:remote_flag_attributes][:actor_id] = model.actor_id From 5b53a9813f163ecffe592be15f5c146eca1fca61 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:00:47 -0300 Subject: [PATCH 224/227] feat: enviar una sola vez el reporte remoto y volver a enviarlo si le agregamos reportes --- app/controllers/activity_pubs_controller.rb | 2 ++ app/jobs/activity_pub/remote_flag_job.rb | 6 ++++++ app/models/activity_pub.rb | 2 +- app/models/activity_pub/remote_flag.rb | 21 +++++++++++++++++++ app/models/actor_moderation.rb | 2 +- ...0240305184854_add_state_to_remote_flags.rb | 8 +++++++ db/structure.sql | 6 ++++-- 7 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20240305184854_add_state_to_remote_flags.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 2b54cacd..c8f86ef0 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -35,6 +35,8 @@ class ActivityPubsController < ApplicationController activity_pubs.distinct.pluck(:actor_id).each do |actor_id| remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) remote_flag.message = message + # Lo estamos actualizando, con lo que lo vamos a volver a enviar + remote_flag.requeue if remote_flag.persisted? remote_flag.save # XXX: Idealmente todas las ActivityPub que enviamos pueden # cambiar de estado, pero chequeamos de todas formas. diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 30796923..7d8131db 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,10 +13,16 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) + return if remote_flag.can_queue? + + remote_flag.queue! + client = remote_flag.site.social_inbox.client_for(remote_flag.actor&.content['inbox']) response = client.post(endpoint: '', body: remote_flag.content) raise 'No se pudo enviar el reporte' unless response.ok? + + remote_flag.send! rescue Exception => e ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) raise diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 23f4324f..b07fe790 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -88,7 +88,7 @@ class ActivityPub < ApplicationRecord transitions from: :rejected, to: :reported before do - ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index a302503b..25f1b743 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -2,6 +2,27 @@ class ActivityPub class RemoteFlag < ApplicationRecord + include AASM + include AasmEventsConcern + + aasm do + state :waiting, initial: true + state :queued + state :sent + + event :queue do + transitions from: :waiting, to: :queued + end + + event :send do + transitions from: :queued, to: :sent + end + + event :resend do + transitions from: :sent, to: :waiting + end + end + belongs_to :actor belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 421d4c6e..d7eea709 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -59,7 +59,7 @@ class ActorModeration < ApplicationRecord transitions from: %i[blocked], to: :reported before do - ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end end diff --git a/db/migrate/20240305184854_add_state_to_remote_flags.rb b/db/migrate/20240305184854_add_state_to_remote_flags.rb new file mode 100644 index 00000000..7ff78dfb --- /dev/null +++ b/db/migrate/20240305184854_add_state_to_remote_flags.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Estado de los reportes remotos +class AddStateToRemoteFlags < ActiveRecord::Migration[6.1] + def change + add_column :activity_pub_remote_flags, :aasm_state, :string, null: false, default: 'waiting' + end +end diff --git a/db/structure.sql b/db/structure.sql index 55a5ecb0..97bd372e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -556,7 +556,8 @@ CREATE TABLE public.activity_pub_remote_flags ( updated_at timestamp(6) without time zone NOT NULL, site_id bigint, actor_id uuid, - message text + message text, + aasm_state character varying DEFAULT 'waiting'::character varying NOT NULL ); @@ -2697,6 +2698,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240301181224'), ('20240301194154'), ('20240301202955'), -('20240305164653'); +('20240305164653'), +('20240305184854'); From b1dee5d5676954610fd54e52ab00c0cfd9bb90e4 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:10:06 -0300 Subject: [PATCH 225/227] fix: dejar de cargar datos de prueba --- app/controllers/application_controller.rb | 10 - .../moderation_queue_controller.rb | 8 - config/routes.rb | 1 - db/seeds/blocklists.yml | 7 - db/seeds/instances.yaml | 285 ------------------ db/seeds/moderation_queue.yaml | 153 ---------- db/seeds/remote_profile.yaml | 106 ------- 7 files changed, 570 deletions(-) delete mode 100644 db/seeds/blocklists.yml delete mode 100644 db/seeds/instances.yaml delete mode 100644 db/seeds/moderation_queue.yaml delete mode 100644 db/seeds/remote_profile.yaml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b55176ec..05fa98e9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,16 +27,6 @@ class ApplicationController < ActionController::Base end private - # Traer datos de muestra de la cola de moderación - def dummy_data - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) - @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) - @blocklists= YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'blocklists.yml'))) - @moderation_queue.each do |activity| - activity['attributedTo'] = @remote_profile - end - end def notify_unconfirmed_email return unless current_usuarie diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 6a628aaa..0df62499 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,8 +4,6 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - dummy_data - session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) # @todo cambiar el estado por query @@ -14,10 +12,4 @@ class ModerationQueueController < ApplicationController @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) @moderation_queue = rubanok_process(site.activity_pubs, with: ActivityPubProcessor) end - - # todon.nl está usando /api/v2/instance - # mauve.moe usa /api/v1/instance - def instances - dummy_data - end end diff --git a/config/routes.rb b/config/routes.rb index 8809767b..054b7f4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -63,7 +63,6 @@ Rails.application.routes.draw do post 'collaborate', to: 'collaborations#accept_collaboration' get 'moderation_queue', to: 'moderation_queue#index' - get 'instances', to: 'moderation_queue#instances' resources :instance_moderations, only: [] do patch :pause, to: 'instance_moderations#pause' diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml deleted file mode 100644 index 54dfe6c9..00000000 --- a/db/seeds/blocklists.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- id: gardenfence - title: Gardenfence - link: 'https://gardenfence.github.io/' -- id: lista - title: Lista - link: '#' diff --git a/db/seeds/instances.yaml b/db/seeds/instances.yaml deleted file mode 100644 index bf326832..00000000 --- a/db/seeds/instances.yaml +++ /dev/null @@ -1,285 +0,0 @@ ---- -- domain: todon.nl - title: Todon.nl - version: 4.2.3 - source_url: https://github.com/mastodon/mastodon - description: Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, - (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, - intersectionelen, veganisten, mensenrechten, enz. - usage: - users: - active_month: 372 - thumbnail: - url: https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png - blurhash: UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE - versions: - "@1x": https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png - "@2x": https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png - languages: - - en - configuration: - urls: - streaming: wss://todon.nl - status: https://status.todon.eu - accounts: - max_featured_tags: 10 - statuses: - max_characters: 1312 - max_media_attachments: 4 - characters_reserved_per_url: 23 - media_attachments: - supported_mime_types: - - image/jpeg - - image/png - - image/gif - - image/heic - - image/heif - - image/webp - - image/avif - - video/webm - - video/mp4 - - video/quicktime - - video/ogg - - audio/wave - - audio/wav - - audio/x-wav - - audio/x-pn-wave - - audio/vnd.wave - - audio/ogg - - audio/vorbis - - audio/mpeg - - audio/mp3 - - audio/webm - - audio/flac - - audio/aac - - audio/m4a - - audio/x-m4a - - audio/mp4 - - audio/3gpp - - video/x-ms-asf - image_size_limit: 16777216 - image_matrix_limit: 33177600 - video_size_limit: 103809024 - video_frame_rate_limit: 120 - video_matrix_limit: 8294400 - polls: - max_options: 4 - max_characters_per_option: 50 - min_expiration: 300 - max_expiration: 2629746 - translation: - enabled: true - registrations: - enabled: false - approval_required: false - message: | -

¡No pasarán!

- -

Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

- - - -

Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

- -

It is temporary not possible to request on account on Todon.nl.

- - - -

Go to joinmastodon.org or FediDB Network to find another server.

- url: - max_toot_chars: 1312 - contact: - email: todon@posteo.eu - account: - id: '1' - username: admin - acct: admin - display_name: "Admin \U0001F913 Todon.nl (mod)" - locked: false - bot: false - discoverable: false - group: false - created_at: '2017-04-28T00:00:00.000Z' - note: "

This account is used for \U0001F399 Todon.nl announcements and ⚖️ - moderation.

\U0001F6AB Don't follow this account when you are not - on Todon.nl.

New? First read our \U0001F469‍\U0001F3EB Todon 101 \U0001F469‍\U0001F393 - at https://wiki.todon.eu/todon/101

⚖️ - For all our moderators go to https://wiki.todon.nl/todon/moderators

\U0001F4DD Public toots from this account - are in English.

\U0001F515 Criticism is fine, but people who do false - accusations are muted.

✉ todon@posteo.eu

#nobot

" - url: https://todon.nl/@admin - uri: https://todon.nl/users/admin - avatar: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png - avatar_static: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png - header: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png - header_static: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png - followers_count: 3164 - following_count: 8 - statuses_count: 724 - last_status_at: '2024-01-12' - noindex: true - emojis: [] - roles: - - id: '3' - name: Admin - color: "#595aff" - fields: - - name: "\U0001F4DC Terms of Service" - value: wiki.todon.nl/todon/terms_en - verified_at: '2018-11-01T14:39:45.465+00:00' - - name: ℹ️ Wiki - value: wiki.todon.nl/todon/informatio - verified_at: '2018-11-01T14:40:54.679+00:00' - - name: "\U0001F4CA Status" - value: status.todon.eu - verified_at: '2023-10-26T20:38:30.185+00:00' - - name: "\U0001F4B3️ Donations" - value: wiki.todon.eu/todon/donations - verified_at: '2022-11-02T00:06:31.865+00:00' - rules: - - id: '1' - text: We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, - apartheid and casteism - see our Terms of Service for our complete definition). - - id: '2' - text: We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, - non-binary people, intersexual people, queer people in general, etc. - - id: '4' - text: Sexism, misogyny and hate against black women (misogynoir). - - id: '6' - text: We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) - and body-shaming. - - id: '8' - text: We do not accept harassment and trolling. - - id: '10' - text: We also do not accept other forms of hate speech. - - id: '11' - text: We do not accept (sexual) abuse of minors, adults and animals (also not - virtual). - - id: '13' - text: We do not accept glorification of violence, calls for murder, death threats, - terrorism and militarism. - - id: '15' - text: We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms - and nationalism (above all nationalism of nation states, incl. flags/symbols - of those on Todon.*, see our Terms of Service). - - id: '16' - text: We do not accept fascism, right-wing populism, and right-wing and religious - extremism. - - id: '17' - text: We do not accept evangelisation and other forms of religious propaganda - [local only], and extreme sects and cults. - - id: '19' - text: We do not accept Marxist-Leninists, Stalinists, Maoists or other followers - of extreme authoritarian (so called) communist/socialist ideologies/regimes - (aka tankies). - - id: '20' - text: We do not accept capitalists, including so called 'anarcho-capitalists' - (aka ancaps) and neoliberals. - - id: '21' - text: We do not accept anthropogenic climate change denial, downplaying the climate - crisis, greenwashing and deceptive climate solutions (like nuclear energy). - - id: '27' - text: We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and - other forms of disinformation. - - id: '28' - text: Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain - in the final step. -- uri: mastodon.mauve.moe - title: Mauvestodon - short_description: Escape ship from centralized social media run by Mauve. - description: Chat about random techie and anarchist stuff. - email: contact@mauve.moe - version: 3.5.10 - urls: - streaming_api: wss://mastodon.mauve.moe - stats: - user_count: 12 - status_count: 3287 - domain_count: 11625 - thumbnail: https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png - languages: - - en - registrations: false - approval_required: false - invites_enabled: true - configuration: - statuses: - max_characters: 500 - max_media_attachments: 4 - characters_reserved_per_url: 23 - media_attachments: - supported_mime_types: - - image/jpeg - - image/png - - image/gif - - video/webm - - video/mp4 - - video/quicktime - - video/ogg - - audio/wave - - audio/wav - - audio/x-wav - - audio/x-pn-wave - - audio/ogg - - audio/vorbis - - audio/mpeg - - audio/mp3 - - audio/webm - - audio/flac - - audio/aac - - audio/m4a - - audio/x-m4a - - audio/mp4 - - audio/3gpp - - video/x-ms-asf - image_size_limit: 10485760 - image_matrix_limit: 16777216 - video_size_limit: 41943040 - video_frame_rate_limit: 60 - video_matrix_limit: 2304000 - polls: - max_options: 4 - max_characters_per_option: 50 - min_expiration: 300 - max_expiration: 2629746 - contact_account: - id: '1' - username: admin - acct: admin - display_name: '' - locked: false - bot: false - discoverable: true - group: false - created_at: '2022-04-25T00:00:00.000Z' - note: '' - url: https://mastodon.mauve.moe/@admin - avatar: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png - avatar_static: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png - header: https://mastodon.mauve.moe/headers/original/missing.png - header_static: https://mastodon.mauve.moe/headers/original/missing.png - followers_count: 0 - following_count: 0 - statuses_count: 0 - last_status_at: '2023-01-30' - emojis: [] - fields: - - name: Alternatel Contact - value: @mauve - verified_at: - rules: [] diff --git a/db/seeds/moderation_queue.yaml b/db/seeds/moderation_queue.yaml deleted file mode 100644 index c7075c7e..00000000 --- a/db/seeds/moderation_queue.yaml +++ /dev/null @@ -1,153 +0,0 @@ ---- -- "@context": - - https://www.w3.org/ns/activitystreams - - ostatus: http://ostatus.org# - atomUri: ostatus:atomUri - inReplyToAtomUri: ostatus:inReplyToAtomUri - conversation: ostatus:conversation - sensitive: as:sensitive - toot: http://joinmastodon.org/ns# - votersCount: toot:votersCount - Hashtag: as:Hashtag - id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 - type: Note - summary: - inReplyTo: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 - published: '2023-11-23T22:50:10Z' - url: https://mastodon.mauve.moe/@mauve/111462305634770041 - attributedTo: https://mastodon.mauve.moe/users/mauve - to: - - https://www.w3.org/ns/activitystreams#Public - cc: - - https://mastodon.mauve.moe/users/mauve/followers - - https://hypha.coop/about.jsonld - sensitive: false - atomUri: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 - inReplyToAtomUri: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 - conversation: tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation - content:

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

-

- contentMap: - en:

Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

-

- attachment: [] - tag: - - type: Mention - href: https://hypha.coop/about.jsonld - name: "@dripline@hypha.coop" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/p2p - name: "#p2p" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/activitypub - name: "#activitypub" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/fediverse - name: "#fediverse" - replies: - id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies - type: Collection - first: - type: CollectionPage - next: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true - partOf: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies - items: [] -- "@context": - - https://www.w3.org/ns/activitystreams - - "@language": es - sensitive: as:sensitive - type: Note - id: https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/ - summary: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty - published: '2023-12-04T21:53:05+00:00' - updated: '2023-12-05T20:41:34+00:00' - attributedTo: https://sutty.nl/about.jsonld - to: - - https://www.w3.org/ns/activitystreams#Public - cc: - - https://social.distributed.press/v1/@sutty@sutty.nl/followers - inReplyTo: https://hypha.coop/dripline/announcing-dp-social-inbox/ - sensitive: true - content: | -

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    -
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. -
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. -

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    -
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • -
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • -
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • -
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • -
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • -
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • -

Qué permite hacer

    -
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • -
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • -
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • -
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • -
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • -

Qué se viene

    -
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • -
  • Incorporación de menciones desde el panel de Sutty.

  • -
  • Mejoras en la interfaz general del panel.

  • -
  • Nuevas implementaciones para una mejor moderación.

  • -
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • -
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • -
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • -
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • -
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • -
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • -

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

- name: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty - contentMap: - es: | -

Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

    -
  1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

  2. -
  3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

  4. -

Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

Qué significa

    -
  • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

  • -
  • Que tus artículos pueden ser publicados en las redes del Fediverso.

  • -
  • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

  • -
  • Que les usuaries del Fediverso pueden seguir tus publicaciones.

  • -
  • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

  • -
  • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

  • -

Qué permite hacer

    -
  • Activar la publicación en el Fediverso para todos los sitios de Sutty.

  • -
  • Activar la publicación de los artículos que quieras en el Fediverso.

  • -
  • Responder comentarios desde los artículos de tu sitio en Sutty.

  • -
  • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

  • -
  • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

  • -

Qué se viene

    -
  • Mejoras en la integración de las respuestas como comentarios en el sitio.

  • -
  • Incorporación de menciones desde el panel de Sutty.

  • -
  • Mejoras en la interfaz general del panel.

  • -
  • Nuevas implementaciones para una mejor moderación.

  • -
  • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

  • -
  • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

  • -
  • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

  • -
  • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

  • -
  • Acceder a la lista de seguidorxs y seguides desde tu panel.

  • -
  • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

  • -

¡Quiero usarlo!

Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

Para tecno-curioses

Cómo funciona

Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

Cómo funciona el Fediverso en la moderación

El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

¿Te interesa participar?

Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

Otras posibilidades de integración de Social Inbox en sitios estáticos

Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

Recomendado para saber más

- attachment: - - type: Document - mediaType: image/png - url: https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png - name: Botones de colores para activar la "Web Disribuida" y el "Fediverso". diff --git a/db/seeds/remote_profile.yaml b/db/seeds/remote_profile.yaml deleted file mode 100644 index 1a670d6b..00000000 --- a/db/seeds/remote_profile.yaml +++ /dev/null @@ -1,106 +0,0 @@ ---- -"@context": -- https://www.w3.org/ns/activitystreams -- https://w3id.org/security/v1 -- manuallyApprovesFollowers: as:manuallyApprovesFollowers - toot: http://joinmastodon.org/ns# - featured: - "@id": toot:featured - "@type": "@id" - featuredTags: - "@id": toot:featuredTags - "@type": "@id" - alsoKnownAs: - "@id": as:alsoKnownAs - "@type": "@id" - movedTo: - "@id": as:movedTo - "@type": "@id" - schema: http://schema.org# - PropertyValue: schema:PropertyValue - value: schema:value - discoverable: toot:discoverable - Device: toot:Device - Ed25519Signature: toot:Ed25519Signature - Ed25519Key: toot:Ed25519Key - Curve25519Key: toot:Curve25519Key - EncryptedMessage: toot:EncryptedMessage - publicKeyBase64: toot:publicKeyBase64 - deviceId: toot:deviceId - claim: - "@type": "@id" - "@id": toot:claim - fingerprintKey: - "@type": "@id" - "@id": toot:fingerprintKey - identityKey: - "@type": "@id" - "@id": toot:identityKey - devices: - "@type": "@id" - "@id": toot:devices - messageFranking: toot:messageFranking - messageType: toot:messageType - cipherText: toot:cipherText - suspended: toot:suspended - focalPoint: - "@container": "@list" - "@id": toot:focalPoint -id: https://mastodon.mauve.moe/users/mauve -type: Person -following: https://mastodon.mauve.moe/users/mauve/following -followers: https://mastodon.mauve.moe/users/mauve/followers -inbox: https://mastodon.mauve.moe/users/mauve/inbox -outbox: https://mastodon.mauve.moe/users/mauve/outbox -featured: https://mastodon.mauve.moe/users/mauve/collections/featured -featuredTags: https://mastodon.mauve.moe/users/mauve/collections/tags -preferredUsername: mauve -name: "Mauve \U0001F441\U0001F49C" -summary: "

Occult Enby that's making local-first software with peer to peer - protocols, mesh networks, and the web.

Also exploring what a local-first - cyberspace might look like in my spare time.

" -url: https://mastodon.mauve.moe/@mauve -manuallyApprovesFollowers: false -discoverable: true -published: '2022-04-25T00:00:00Z' -devices: https://mastodon.mauve.moe/users/mauve/collections/devices -alsoKnownAs: -- https://infosec.exchange/users/RangerMauve -publicKey: - id: https://mastodon.mauve.moe/users/mauve#main-key - owner: https://mastodon.mauve.moe/users/mauve - publicKeyPem: | - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ - umIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng - 7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK - 75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq - WUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D - zAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf - XwIDAQAB - -----END PUBLIC KEY----- -tag: [] -attachment: -- type: PropertyValue - name: Pronouns - value: they/them/it -- type: PropertyValue - name: Email - value: mauve@mauve.moe -- type: PropertyValue - name: Matrix - value: @mauve:mauve.moe -- type: PropertyValue - name: Github/Twitter - value: "@RangerMauve" -endpoints: - sharedInbox: https://mastodon.mauve.moe/inbox -icon: - type: Image - mediaType: image/png - url: https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png -image: - type: Image - mediaType: image/png - url: https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png From 2df9f721cd4b9f6831f8f891aad1f4c08785f295 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:10:53 -0300 Subject: [PATCH 226/227] =?UTF-8?q?feat:=20ver=20los=20art=C3=ADculos=20de?= =?UTF-8?q?=20le=20actore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/actor_moderations_controller.rb | 1 + app/views/actor_moderations/show.haml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 56adda4a..00874321 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -20,6 +20,7 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show @remote_profile = actor_moderation.actor.content + @moderation_queue = site.activity_pubs.where(actor_id: actor_moderation.actor_id) end def action_on_several diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml index 7b62f672..633c1be5 100644 --- a/app/views/actor_moderations/show.haml +++ b/app/views/actor_moderations/show.haml @@ -4,5 +4,5 @@ = render 'components/actor', remote_profile: @remote_profile .col-12.col-md-8 = render 'components/profiles_btn_box', actor_moderation: @actor_moderation - -# - = render 'moderation_queue/comments', moderation_queue: @moderation_queue + .col-12.col-md-8 + = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 0da69de6a73543d90c032b09bd04b74be5c8cbef Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:24:16 -0300 Subject: [PATCH 227/227] feat: filtros comunes --- app/controllers/actor_moderations_controller.rb | 3 ++- .../concerns/moderation_filters_concern.rb | 15 +++++++++++++++ app/controllers/moderation_queue_controller.rb | 4 ++-- app/processors/instance_moderation_processor.rb | 4 ++-- app/views/components/_comments_show_submenu.haml | 2 +- app/views/components/_dropdown_item.haml | 2 +- app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 7 ++++--- app/views/components/_profiles_show_submenu.haml | 2 +- app/views/moderation_queue/_instances.haml | 2 +- 10 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 app/controllers/concerns/moderation_filters_concern.rb diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 00874321..6b924677 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -3,6 +3,7 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController include ModerationConcern + include ModerationFiltersConcern ActorModeration.events.each do |actor_event| define_method(actor_event) do @@ -20,7 +21,7 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show @remote_profile = actor_moderation.actor.content - @moderation_queue = site.activity_pubs.where(actor_id: actor_moderation.actor_id) + @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), with: ActivityPubProcessor) end def action_on_several diff --git a/app/controllers/concerns/moderation_filters_concern.rb b/app/controllers/concerns/moderation_filters_concern.rb new file mode 100644 index 00000000..25293a4f --- /dev/null +++ b/app/controllers/concerns/moderation_filters_concern.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ModerationFiltersConcern + extend ActiveSupport::Concern + + included do + before_action :store_filters_in_session!, only: %i[index show] + + private + + def store_filters_in_session! + session[:moderation_queue_filters] = params.permit(:instance_state, :actor_state, :activity_pub_state) + end + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 0df62499..eebd9eae 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -2,10 +2,10 @@ # Cola de moderación de ActivityPub class ModerationQueueController < ApplicationController + include ModerationFiltersConcern + # Cola de moderación viendo todo el sitio def index - session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) - # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb index 908beaf7..eb9a7c8b 100644 --- a/app/processors/instance_moderation_processor.rb +++ b/app/processors/instance_moderation_processor.rb @@ -6,7 +6,7 @@ class InstanceModerationProcessor < Rubanok::Processor raw.includes(:instance).order('activity_pub_instances.hostname') end - map :state, activate_always: true do |state: 'paused'| - raw.where(aasm_state: state) + map :instance_state, activate_always: true do |instance_state: 'paused'| + raw.where(aasm_state: instance_state) end end diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml index eb037975..60c02501 100644 --- a/app/views/components/_comments_show_submenu.haml +++ b/app/views/components/_comments_show_submenu.haml @@ -1,4 +1,4 @@ - ActivityPub.states.each do |state| = render 'components/dropdown_item', text: t(".submenu_#{state}", count: activity_pubs.unscope(where: :aasm_state).public_send(state).count), - path: site_moderation_queue_path(filter_states(activity_pub_state: state)) + path: filter_states(activity_pub_state: state) diff --git a/app/views/components/_dropdown_item.haml b/app/views/components/_dropdown_item.haml index 3f79403d..e5b16950 100644 --- a/app/views/components/_dropdown_item.haml +++ b/app/views/components/_dropdown_item.haml @@ -1,4 +1,4 @@ -# @param :text [String] Contenido del link - @param :path [String] Link + @param :path [String,Hash] Link = link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' } diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 9e8509c4..2c23fd72 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -6,4 +6,4 @@ = render 'components/instances_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do - = render 'components/instances_show_submenu', site: site + = render 'components/instances_show_submenu', instance_moderations: instance_moderations diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 811d65c7..c56df547 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,3 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_paused', count: site.instance_moderations.paused.count), path: site_moderation_queue_path(state: 'paused') -= render 'components/dropdown_item', text: t('.submenu_allowed', count: site.instance_moderations.allowed.count), path: site_moderation_queue_path(state: 'allowed') -= render 'components/dropdown_item', text: t('.submenu_blocked', count: site.instance_moderations.blocked.count), path: site_moderation_queue_path(state: 'blocked') +- InstanceModeration.states.each do |state| + = render 'components/dropdown_item', + text: t(".submenu_#{state}", count: instance_moderations.unscope(where: :aasm_state).public_send(state).count), + path: filter_states(instance_state: state) diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 0209ef2f..99694698 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,4 +1,4 @@ - ActorModeration.states.each do |actor_state| = render 'components/dropdown_item', text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), - path: site_moderation_queue_path(filter_states(actor_state: actor_state)) + path: filter_states(actor_state: actor_state) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d9db967f..3954ce65 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -7,7 +7,7 @@ = render 'components/select_all', id: 'instances', form_id: form_id .col-11 -# Filtros - = render 'components/instances_filters', site: site, form_id: form_id + = render 'components/instances_filters', instance_moderations: instance_moderations, form_id: form_id .col-12 - if instance_moderations.count.zero?