From 1ed32b5d0fac588d9bccce745f7b25431b6afe84 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 10 Oct 2024 13:00:44 -0500 Subject: [PATCH 01/47] Stub out likes block --- src/likes/block.json | 14 ++++++++++++++ src/likes/edit.js | 4 ++++ src/likes/index.js | 6 ++++++ 3 files changed, 24 insertions(+) create mode 100644 src/likes/block.json create mode 100644 src/likes/edit.js create mode 100644 src/likes/index.js diff --git a/src/likes/block.json b/src/likes/block.json new file mode 100644 index 000000000..41fc53992 --- /dev/null +++ b/src/likes/block.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "name": "activitypub/post-likes", + "apiVersion": 3, + "version": "1.0.0", + "title": "Fediverse Likes", + "category": "widgets", + "description": "Fediverse Likes", + "textdomain": "activitypub", + "editorScript": "file:./index.js", + "blockHooks": { + "core/post-content": "lastChild" + } +} diff --git a/src/likes/edit.js b/src/likes/edit.js new file mode 100644 index 000000000..50d98a1d0 --- /dev/null +++ b/src/likes/edit.js @@ -0,0 +1,4 @@ +export default function Edit() { + return

Editing the likes block.

; + +} \ No newline at end of file diff --git a/src/likes/index.js b/src/likes/index.js new file mode 100644 index 000000000..fcf99fde8 --- /dev/null +++ b/src/likes/index.js @@ -0,0 +1,6 @@ +import { registerBlockType } from '@wordpress/blocks'; + +import edit from './edit'; +import metadata from './block.json'; + +registerBlockType( metadata.name, { edit } ); \ No newline at end of file From 62c65602926832f2f6a0d6a0ceb0a73f154a684a Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Mon, 21 Oct 2024 20:57:06 -0500 Subject: [PATCH 02/47] register block --- includes/class-blocks.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 663022c6c..64bf7b9de 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -146,6 +146,23 @@ public static function register_blocks() { 'render_callback' => array( self::class, 'render_reply_block' ), ) ); + \register_block_type_from_metadata( + ACTIVITYPUB_PLUGIN_DIR . '/build/likes', + array( + 'render_callback' => array( self::class, 'render_post_likes_block' ), + ) + ); + } + + /** + * Render the post likes block. + * + * @param array $attrs The block attributes. + * + * @return string The HTML to render. + */ + public static function render_post_likes_block( $attrs ) { + return '
POST LIKES HERE
'; } /** From 32bc07412f3cb721e839e3a91297d63557e3e2de Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 10 Dec 2024 15:47:54 -0600 Subject: [PATCH 03/47] rename --- src/{likes => reactions}/block.json | 0 src/{likes => reactions}/edit.js | 0 src/{likes => reactions}/index.js | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/{likes => reactions}/block.json (100%) rename src/{likes => reactions}/edit.js (100%) rename src/{likes => reactions}/index.js (100%) diff --git a/src/likes/block.json b/src/reactions/block.json similarity index 100% rename from src/likes/block.json rename to src/reactions/block.json diff --git a/src/likes/edit.js b/src/reactions/edit.js similarity index 100% rename from src/likes/edit.js rename to src/reactions/edit.js diff --git a/src/likes/index.js b/src/reactions/index.js similarity index 100% rename from src/likes/index.js rename to src/reactions/index.js From e85b658c7e9a9b9b6624da5df6b9e76e616dd0cb Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 10 Dec 2024 15:53:28 -0600 Subject: [PATCH 04/47] =?UTF-8?q?Working=20reactions=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/class-blocks.php | 26 ++++++++-- includes/rest/class-interaction.php | 74 ++++++++++++++++++++++++++ src/reactions/block.json | 28 +++++++--- src/reactions/edit.js | 41 ++++++++++++++- src/reactions/editor.scss | 4 ++ src/reactions/index.js | 1 + src/reactions/reactions.js | 80 +++++++++++++++++++++++++++++ src/reactions/style.scss | 38 ++++++++++++++ src/reactions/view.js | 11 ++++ 9 files changed, 288 insertions(+), 15 deletions(-) create mode 100644 src/reactions/editor.scss create mode 100644 src/reactions/reactions.js create mode 100644 src/reactions/style.scss create mode 100644 src/reactions/view.js diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 64bf7b9de..052d46459 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -112,6 +112,7 @@ public static function add_data() { $context = is_admin() ? 'editor' : 'view'; $followers_handle = 'activitypub-followers-' . $context . '-script'; $follow_me_handle = 'activitypub-follow-me-' . $context . '-script'; + $reactions_handle = 'activitypub-reactions-' . $context . '-script'; $data = array( 'namespace' => ACTIVITYPUB_REST_NAMESPACE, 'enabled' => array( @@ -122,6 +123,7 @@ public static function add_data() { $js = sprintf( 'var _activityPubOptions = %s;', wp_json_encode( $data ) ); \wp_add_inline_script( $followers_handle, $js, 'before' ); \wp_add_inline_script( $follow_me_handle, $js, 'before' ); + \wp_add_inline_script( $reactions_handle, $js, 'before' ); } /** @@ -147,22 +149,36 @@ public static function register_blocks() { ) ); \register_block_type_from_metadata( - ACTIVITYPUB_PLUGIN_DIR . '/build/likes', + ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', array( - 'render_callback' => array( self::class, 'render_post_likes_block' ), + 'render_callback' => array( self::class, 'render_post_reactions_block' ), ) ); } /** - * Render the post likes block. + * Render the post reactions block. * * @param array $attrs The block attributes. * * @return string The HTML to render. */ - public static function render_post_likes_block( $attrs ) { - return '
POST LIKES HERE
'; + public static function render_post_reactions_block( $attrs ) { + if ( ! isset( $attrs['postId'] ) ) { + $attrs['postId'] = get_the_ID(); + } + + $wrapper_attributes = get_block_wrapper_attributes( + array( + 'class' => 'activitypub-reactions-block', + 'data-attrs' => wp_json_encode( $attrs ), + ) + ); + + return sprintf( + '
', + $wrapper_attributes + ); } /** diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 8bf78267e..582f72605 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -43,6 +43,24 @@ public static function register_routes() { ), ) ); + + \register_rest_route( + ACTIVITYPUB_REST_NAMESPACE, + '/reactions/(?P\d+)', + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( self::class, 'get_reactions' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'id' => array( + 'required' => true, + 'validate_callback' => function ( $val ) { + return is_numeric( $val ); + }, + ), + ), + ) + ); } /** @@ -115,4 +133,60 @@ public static function get( $request ) { ) ); } + + /** + * Get reactions (likes and reposts) for a post + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error Response object or WP_Error. + */ + public static function get_reactions( $request ) { + $post_id = $request->get_param( 'id' ); + $post = get_post( $post_id ); + $likes = array(); + $reposts = array(); + + if ( ! $post ) { + return new \WP_Error( + 'activitypub_post_not_found', + __( 'Post not found', 'activitypub' ), + array( 'status' => 404 ) + ); + } + + $reactions = get_comments( + array( + 'post_id' => $post_id, + 'type__in' => array( 'like', 'repost' ), + 'status' => 'approve', + ) + ); + + $format_reaction = function ( $comment ) { + return array( + 'avatar' => get_comment_meta( $comment->comment_ID, 'avatar_url', true ), + 'url' => $comment->comment_author_url, + 'name' => $comment->comment_author, + ); + }; + + foreach ( $reactions as $reaction ) { + switch ( $reaction->comment_type ) { + case 'like': + $likes[] = $format_reaction( $reaction ); + break; + case 'repost': + $reposts[] = $format_reaction( $reaction ); + break; + } + } + + return new WP_REST_Response( + array( + 'likes' => $likes, + 'reposts' => $reposts, + ), + 200 + ); + } } diff --git a/src/reactions/block.json b/src/reactions/block.json index 41fc53992..a1741e04f 100644 --- a/src/reactions/block.json +++ b/src/reactions/block.json @@ -1,14 +1,26 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "name": "activitypub/post-likes", - "apiVersion": 3, + "name": "activitypub/reactions", + "apiVersion": 2, "version": "1.0.0", - "title": "Fediverse Likes", + "title": "Fediverse Reactions", "category": "widgets", - "description": "Fediverse Likes", + "icon": "heart", + "description": "Display Fediverse likes and reposts", + "supports": { + "html": false + }, + "attributes": { + "title": { + "type": "string", + "default": "Fediverse reactions" + }, + "postId": { + "type": "number" + } + }, "textdomain": "activitypub", - "editorScript": "file:./index.js", - "blockHooks": { - "core/post-content": "lastChild" - } + "editorScript": "file:./index.js", + "style": "file:./style-index.css", + "viewScript": "file:./view.js" } diff --git a/src/reactions/edit.js b/src/reactions/edit.js index 50d98a1d0..5f0e4e821 100644 --- a/src/reactions/edit.js +++ b/src/reactions/edit.js @@ -1,4 +1,41 @@ -export default function Edit() { - return

Editing the likes block.

; +import { useBlockProps, RichText } from '@wordpress/block-editor'; +import { useEffect, useState } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import apiFetch from '@wordpress/api-fetch'; +import { Spinner, Notice } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { Reactions } from './reactions'; +const { namespace } = window._activityPubOptions; + +export default function Edit( { attributes, setAttributes } ) { + const postId = useSelect( ( select ) => { + return select( 'core/editor' )?.getCurrentPostId(); + }, [] ); + + const blockProps = useBlockProps(); + + if ( ! postId ) { + return ( +
+ + { __( 'This block can only be used in a single post or page context.', 'activitypub' ) } + +
+ ); + } + + return ( +
+ setAttributes( { title } ) } + /> +
+ ); } \ No newline at end of file diff --git a/src/reactions/editor.scss b/src/reactions/editor.scss new file mode 100644 index 000000000..b4efee0ea --- /dev/null +++ b/src/reactions/editor.scss @@ -0,0 +1,4 @@ +.wp-block-activitypub-reactions { + // Any editor-specific styles would go here + // For now, we'll inherit all styles from style.scss +} \ No newline at end of file diff --git a/src/reactions/index.js b/src/reactions/index.js index fcf99fde8..48e12d2a8 100644 --- a/src/reactions/index.js +++ b/src/reactions/index.js @@ -2,5 +2,6 @@ import { registerBlockType } from '@wordpress/blocks'; import edit from './edit'; import metadata from './block.json'; +import './style.scss'; registerBlockType( metadata.name, { edit } ); \ No newline at end of file diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js new file mode 100644 index 000000000..26c785474 --- /dev/null +++ b/src/reactions/reactions.js @@ -0,0 +1,80 @@ +import { RichText } from '@wordpress/components'; +import { useState, useEffect } from '@wordpress/element'; +import apiFetch from '@wordpress/api-fetch'; +import { __ } from '@wordpress/i18n'; + +const { namespace } = window._activityPubOptions; + +const FacepileRow = ( { reactions } ) => { + return ( +
+ { reactions.map( ( reaction, index ) => ( + + { + + ) ) } +
+ ); +}; + +export function Reactions( { + title, + postId, + isEditing = false, + setTitle = () => {}, + } ) { + const [ reactions, setReactions ] = useState( null ); + const [ loading, setLoading ] = useState( true ); + + useEffect( () => { + setLoading( true ); + apiFetch( { + path: `/${ namespace }/reactions/${ postId }`, + } ).then( ( response ) => { + setReactions( response ); + setLoading( false ); + } ).catch( () => setLoading( false ) ); + }, [ postId ] ); + + if ( loading || ! reactions ) { + return null; + } + + return ( +
+ { isEditing ? ( + + ) : title &&

{ title }

} + + { reactions?.likes?.length > 0 && ( +
+ { __( 'Likes:', 'activitypub' ) } + +
+ ) } + + { reactions?.reposts?.length > 0 && ( +
+ { __( 'Reposts:', 'activitypub' ) } + +
+ ) } +
+ ); +} \ No newline at end of file diff --git a/src/reactions/style.scss b/src/reactions/style.scss new file mode 100644 index 000000000..683497e88 --- /dev/null +++ b/src/reactions/style.scss @@ -0,0 +1,38 @@ +.activitypub-reactions { + .reaction-group { + display: flex; + align-items: center; + margin: 0.5em 0; + + span { + margin-right: 0.5em; + } + } + + .reaction-facepile { + display: flex; + align-items: center; + + a { + margin-right: -16px; // Half of avatar width for 50% overlap + transition: transform 0.2s ease; + + &:hover { + z-index: 2; + transform: scale(1.1); + } + + &:last-child { + margin-right: 0; + } + } + + .reaction-avatar { + border-radius: 50%; + border: 2px solid #fff; // Helps separate overlapping avatars + width: 32px; + height: 32px; + display: block; + } + } +} \ No newline at end of file diff --git a/src/reactions/view.js b/src/reactions/view.js new file mode 100644 index 000000000..16d202ab0 --- /dev/null +++ b/src/reactions/view.js @@ -0,0 +1,11 @@ +import { createRoot } from '@wordpress/element'; +import domReady from '@wordpress/dom-ready'; +import { Reactions } from './reactions'; + +domReady( () => { + // iterate over a nodelist + [].forEach.call( document.querySelectorAll( '.activitypub-reactions-block' ), ( element ) => { + const attrs = JSON.parse( element.dataset.attrs ); + createRoot( element ).render( ); + } ); +} ); \ No newline at end of file From a6fb9f777b7ccb1a09f41a7dc22c2cd20c11e2d7 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 10 Dec 2024 15:54:10 -0600 Subject: [PATCH 05/47] built files --- build/reactions/block.json | 26 ++++++++++++++++++++++++++ build/reactions/index.asset.php | 1 + build/reactions/index.js | 1 + build/reactions/style-index-rtl.css | 1 + build/reactions/style-index.css | 1 + build/reactions/view.asset.php | 1 + build/reactions/view.js | 1 + 7 files changed, 32 insertions(+) create mode 100644 build/reactions/block.json create mode 100644 build/reactions/index.asset.php create mode 100644 build/reactions/index.js create mode 100644 build/reactions/style-index-rtl.css create mode 100644 build/reactions/style-index.css create mode 100644 build/reactions/view.asset.php create mode 100644 build/reactions/view.js diff --git a/build/reactions/block.json b/build/reactions/block.json new file mode 100644 index 000000000..07b15466e --- /dev/null +++ b/build/reactions/block.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "name": "activitypub/reactions", + "apiVersion": 2, + "version": "1.0.0", + "title": "Fediverse Reactions", + "category": "widgets", + "icon": "heart", + "description": "Display Fediverse likes and reposts", + "supports": { + "html": false + }, + "attributes": { + "title": { + "type": "string", + "default": "Fediverse reactions" + }, + "postId": { + "type": "number" + } + }, + "textdomain": "activitypub", + "editorScript": "file:./index.js", + "style": "file:./style-index.css", + "viewScript": "file:./view.js" +} \ No newline at end of file diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php new file mode 100644 index 000000000..a073f3b9e --- /dev/null +++ b/build/reactions/index.asset.php @@ -0,0 +1 @@ + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'a1d5717ae5a8c5be9af7'); diff --git a/build/reactions/index.js b/build/reactions/index.js new file mode 100644 index 000000000..908eeff1e --- /dev/null +++ b/build/reactions/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,t={482:(e,t,i)=>{const a=window.wp.blocks,r=window.React,n=window.wp.blockEditor,s=window.wp.element,o=window.wp.data,c=window.wp.apiFetch;var l=i.n(c);const p=window.wp.components,u=window.wp.i18n,{namespace:d}=window._activityPubOptions,v=({reactions:e})=>(0,r.createElement)("div",{className:"reaction-facepile"},e.map(((e,t)=>(0,r.createElement)("a",{key:t,href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,r.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))));function m({title:e,postId:t,isEditing:i=!1,setTitle:a=(()=>{})}){const[n,o]=(0,s.useState)(null),[c,m]=(0,s.useState)(!0);return(0,s.useEffect)((()=>{m(!0),l()({path:`/${d}/reactions/${t}`}).then((e=>{o(e),m(!1)})).catch((()=>m(!1)))}),[t]),c||!n?null:(0,r.createElement)("div",{className:"activitypub-reactions"},i?(0,r.createElement)(p.RichText,{tagName:"h4",value:e,onChange:a,placeholder:(0,u.__)("Fediverse reactions","activitypub")}):e&&(0,r.createElement)("h4",null,e),n?.likes?.length>0&&(0,r.createElement)("div",{className:"reaction-group activitypub-reactions-likes"},(0,r.createElement)("span",null,(0,u.__)("Likes:","activitypub")," "),(0,r.createElement)(v,{reactions:n.likes})),n?.reposts?.length>0&&(0,r.createElement)("div",{className:"reaction-group activitypub-reactions-reposts"},(0,r.createElement)("span",null,(0,u.__)("Reposts:","activitypub")," "),(0,r.createElement)(v,{reactions:n.reposts})))}const{namespace:w}=window._activityPubOptions,b=JSON.parse('{"UU":"activitypub/reactions"}');(0,a.registerBlockType)(b.UU,{edit:function({attributes:e,setAttributes:t}){const i=(0,o.useSelect)((e=>e("core/editor")?.getCurrentPostId()),[]),a=(0,n.useBlockProps)();return i?(0,r.createElement)("div",{...a},(0,r.createElement)(m,{postId:i,isEditing:!0,title:e.title,setTitle:e=>t({title:e})})):(0,r.createElement)("div",{...a},(0,r.createElement)(p.Notice,{status:"warning",isDismissible:!1},(0,u.__)("This block can only be used in a single post or page context.","activitypub")))}})}},i={};function a(e){var r=i[e];if(void 0!==r)return r.exports;var n=i[e]={exports:{}};return t[e](n,n.exports,a),n.exports}a.m=t,e=[],a.O=(t,i,r,n)=>{if(!i){var s=1/0;for(p=0;p=n)&&Object.keys(a.O).every((e=>a.O[e](i[c])))?i.splice(c--,1):(o=!1,n0&&e[p-1][2]>n;p--)e[p]=e[p-1];e[p]=[i,r,n]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var i in t)a.o(t,i)&&!a.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};a.O.j=t=>0===e[t];var t=(t,i)=>{var r,n,[s,o,c]=i,l=0;if(s.some((t=>0!==e[t]))){for(r in o)a.o(o,r)&&(a.m[r]=o[r]);if(c)var p=c(a)}for(t&&t(i);la(482)));r=a.O(r)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css new file mode 100644 index 000000000..b0d9c1667 --- /dev/null +++ b/build/reactions/style-index-rtl.css @@ -0,0 +1 @@ +.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0}.activitypub-reactions .reaction-group span{margin-left:.5em}.activitypub-reactions .reaction-facepile{align-items:center;display:flex}.activitypub-reactions .reaction-facepile a{margin-left:-16px;transition:transform .2s ease}.activitypub-reactions .reaction-facepile a:hover{transform:scale(1.1);z-index:2}.activitypub-reactions .reaction-facepile a:last-child{margin-left:0}.activitypub-reactions .reaction-facepile .reaction-avatar{border:2px solid #fff;border-radius:50%;display:block;height:32px;width:32px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css new file mode 100644 index 000000000..a011808bb --- /dev/null +++ b/build/reactions/style-index.css @@ -0,0 +1 @@ +.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0}.activitypub-reactions .reaction-group span{margin-right:.5em}.activitypub-reactions .reaction-facepile{align-items:center;display:flex}.activitypub-reactions .reaction-facepile a{margin-right:-16px;transition:transform .2s ease}.activitypub-reactions .reaction-facepile a:hover{transform:scale(1.1);z-index:2}.activitypub-reactions .reaction-facepile a:last-child{margin-right:0}.activitypub-reactions .reaction-facepile .reaction-avatar{border:2px solid #fff;border-radius:50%;display:block;height:32px;width:32px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php new file mode 100644 index 000000000..8dc807296 --- /dev/null +++ b/build/reactions/view.asset.php @@ -0,0 +1 @@ + array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '471bfae478141ab790fc'); diff --git a/build/reactions/view.js b/build/reactions/view.js new file mode 100644 index 000000000..5231e6e9b --- /dev/null +++ b/build/reactions/view.js @@ -0,0 +1 @@ +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const c=window.wp.components,i=window.wp.apiFetch;var o=e.n(i);const s=window.wp.i18n,{namespace:l}=window._activityPubOptions,p=({reactions:e})=>(0,t.createElement)("div",{className:"reaction-facepile"},e.map(((e,a)=>(0,t.createElement)("a",{key:a,href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))));function u({title:e,postId:n,isEditing:r=!1,setTitle:i=(()=>{})}){const[u,m]=(0,a.useState)(null),[d,v]=(0,a.useState)(!0);return(0,a.useEffect)((()=>{v(!0),o()({path:`/${l}/reactions/${n}`}).then((e=>{m(e),v(!1)})).catch((()=>v(!1)))}),[n]),d||!u?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:i,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),u?.likes?.length>0&&(0,t.createElement)("div",{className:"reaction-group activitypub-reactions-likes"},(0,t.createElement)("span",null,(0,s.__)("Likes:","activitypub")," "),(0,t.createElement)(p,{reactions:u.likes})),u?.reposts?.length>0&&(0,t.createElement)("div",{className:"reaction-group activitypub-reactions-reposts"},(0,t.createElement)("span",null,(0,s.__)("Reposts:","activitypub")," "),(0,t.createElement)(p,{reactions:u.reposts})))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(u,{...n}))}))}))})(); \ No newline at end of file From 7b661d51e2c0095ad501c6783e610700934b4d5b Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 07:54:18 -0600 Subject: [PATCH 06/47] no postId --- src/reactions/block.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/reactions/block.json b/src/reactions/block.json index a1741e04f..ea74e7b30 100644 --- a/src/reactions/block.json +++ b/src/reactions/block.json @@ -14,9 +14,6 @@ "title": { "type": "string", "default": "Fediverse reactions" - }, - "postId": { - "type": "number" } }, "textdomain": "activitypub", From 1b8dca8d4387b4a6c86efa9e9e9244027e18a12d Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 16:54:44 -0600 Subject: [PATCH 07/47] generate fake facepile in the editor --- src/reactions/block.json | 10 ++- src/reactions/edit.js | 94 ++++++++++++++++------ src/reactions/index.js | 4 +- src/reactions/reactions.js | 158 +++++++++++++++++++++++++++++++------ src/reactions/style.scss | 85 +++++++++++++++----- 5 files changed, 279 insertions(+), 72 deletions(-) diff --git a/src/reactions/block.json b/src/reactions/block.json index ea74e7b30..5c478e767 100644 --- a/src/reactions/block.json +++ b/src/reactions/block.json @@ -8,7 +8,15 @@ "icon": "heart", "description": "Display Fediverse likes and reposts", "supports": { - "html": false + "html": false, + "align": true, + "layout": { + "default": { + "type": "constrained", + "orientation": "vertical", + "justifyContent": "center" + } + } }, "attributes": { "title": { diff --git a/src/reactions/edit.js b/src/reactions/edit.js index 5f0e4e821..a95c08464 100644 --- a/src/reactions/edit.js +++ b/src/reactions/edit.js @@ -1,40 +1,86 @@ -import { useBlockProps, RichText } from '@wordpress/block-editor'; -import { useEffect, useState } from '@wordpress/element'; -import { useSelect } from '@wordpress/data'; -import apiFetch from '@wordpress/api-fetch'; -import { Spinner, Notice } from '@wordpress/components'; +import { useBlockProps } from '@wordpress/block-editor'; +import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Reactions } from './reactions'; -const { namespace } = window._activityPubOptions; +/** + * Generate a dummy reaction with a random letter and color. + * + * @param {number} index Index for color selection. + * @return {Object} Reaction object. + */ +const generateDummyReaction = ( index ) => { + const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + const colors = [ + '#FF6B6B', + '#4ECDC4', + '#45B7D1', + '#96CEB4', + '#FFEEAD', + '#D4A5A5', + '#9B59B6', + '#3498DB', + '#E67E22', + ]; + const letter = letters[ Math.floor( Math.random() * letters.length ) ]; + // random color + const color = colors[ Math.floor( Math.random() * colors.length ) ]; + + // Create a data URL for a colored circle with a letter. + const canvas = document.createElement( 'canvas' ); + canvas.width = 64; + canvas.height = 64; + const ctx = canvas.getContext( '2d' ); + + // Draw colored circle. + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc( 32, 32, 32, 0, 2 * Math.PI ); + ctx.fill(); + + // Draw letter. + ctx.fillStyle = '#FFFFFF'; + ctx.font = 'bold 32px sans-serif'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText( letter, 32, 32 ); + + return { + name: `User ${ index }`, + url: '#', + avatar: canvas.toDataURL(), + }; +}; -export default function Edit( { attributes, setAttributes } ) { - const postId = useSelect( ( select ) => { - return select( 'core/editor' )?.getCurrentPostId(); - }, [] ); +/** + * Generate dummy reactions for editor preview. + * + * @return {Object} Reactions data. + */ +const generateDummyReactions = () => ( { + likes: Array.from( { length: 9 }, ( _, i ) => generateDummyReaction( i ) ), + reposts: Array.from( { length: 6 }, ( _, i ) => generateDummyReaction( i + 9 ) ), +} ); +/** + * Edit component for the Reactions block. + * + * @param {Object} props Block props. + * @param {Object} props.attributes Block attributes. + * @param {Function} props.setAttributes Attribute update callback. + * @return {JSX.Element} Component to render. + */ +export default function Edit( { attributes, setAttributes } ) { const blockProps = useBlockProps(); - - if ( ! postId ) { - return ( -
- - { __( 'This block can only be used in a single post or page context.', 'activitypub' ) } - -
- ); - } + const [ dummyReactions ] = useState( generateDummyReactions() ); return (
setAttributes( { title } ) } + reactions={ dummyReactions } />
); diff --git a/src/reactions/index.js b/src/reactions/index.js index 48e12d2a8..ec6f92ca1 100644 --- a/src/reactions/index.js +++ b/src/reactions/index.js @@ -1,7 +1,7 @@ import { registerBlockType } from '@wordpress/blocks'; import edit from './edit'; -import metadata from './block.json'; +import { name } from './block.json'; import './style.scss'; -registerBlockType( metadata.name, { edit } ); \ No newline at end of file +registerBlockType( name, { edit } ); \ No newline at end of file diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 26c785474..38f4d3833 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -1,53 +1,157 @@ -import { RichText } from '@wordpress/components'; +import { RichText } from '@wordpress/block-editor'; import { useState, useEffect } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; import { __ } from '@wordpress/i18n'; +/** + * Extract the namespace from the global _activityPubOptions object. + * + * @type {string} + */ const { namespace } = window._activityPubOptions; -const FacepileRow = ( { reactions } ) => { +/** + * A component that renders a row of user avatars for a given set of reactions. + * + * @param {Object} props Component props. + * @param {Array} props.reactions Array of reaction objects. + * @return {JSX.Element} The rendered component. + */ +const FacepileRow = ( { reactions } ) => ( +
+ { reactions.map( ( reaction, index ) => ( + + { + + ) ) } +
+); + +/** + * A component that renders a dropdown list of reactions. + * + * @param {Object} props Component props. + * @param {Array} props.reactions Array of reaction objects. + * @param {boolean} props.isOpen Whether the dropdown is open. + * @return {JSX.Element} The rendered component. + */ +const ReactionDropdown = ( { reactions, isOpen } ) => { + if ( ! isOpen ) { + return null; + } + return ( -
+
{ reactions.map( ( reaction, index ) => ( { + { reaction.name } ) ) }
); }; +/** + * A component that renders a reaction group with facepile and dropdown. + * + * @param {Object} props Component props. + * @param {Array} props.reactions Array of reaction objects. + * @param {string} props.type Type of reaction (likes/reposts). + * @return {JSX.Element} The rendered component. + */ +const ReactionGroup = ( { reactions, type } ) => { + const [ isOpen, setIsOpen ] = useState( false ); + const count = reactions.length; + const label = type === 'likes' ? + __( '%d Like', '%d Likes', count, 'activitypub' ) : + __( '%d Repost', '%d Reposts', count, 'activitypub' ); + + return ( +
+ + + +
+ ); +}; + +/** + * The Reactions component. + * + * @param {Object} props Component props. + * @param {string} props.title The title text. + * @param {?number} props.postId The post ID. + * @param {boolean} props.isEditing Whether in edit mode. + * @param {Function} props.setTitle Title update callback. + * @param {?Object} props.reactions Optional reactions data. + * @return {?JSX.Element} The rendered component. + */ export function Reactions( { - title, - postId, + title = '', + postId = null, isEditing = false, setTitle = () => {}, - } ) { - const [ reactions, setReactions ] = useState( null ); - const [ loading, setLoading ] = useState( true ); + reactions: providedReactions = null, +} ) { + const [ reactions, setReactions ] = useState( providedReactions ); + const [ loading, setLoading ] = useState( ! providedReactions ); useEffect( () => { + if ( providedReactions ) { + setReactions( providedReactions ); + setLoading( false ); + return; + } + + if ( ! postId ) { + setLoading( false ); + return; + } + setLoading( true ); apiFetch( { path: `/${ namespace }/reactions/${ postId }`, - } ).then( ( response ) => { - setReactions( response ); - setLoading( false ); - } ).catch( () => setLoading( false ) ); - }, [ postId ] ); + } ) + .then( ( response ) => { + setReactions( response ); + setLoading( false ); + } ) + .catch( () => setLoading( false ) ); + }, [ postId, providedReactions ] ); - if ( loading || ! reactions ) { + if ( loading ) { return null; } @@ -60,20 +164,22 @@ export function Reactions( { onChange={ setTitle } placeholder={ __( 'Fediverse reactions', 'activitypub' ) } /> - ) : title &&

{ title }

} + ) : ( + title &&

{ title }

+ ) } { reactions?.likes?.length > 0 && ( -
- { __( 'Likes:', 'activitypub' ) } - -
+ ) } { reactions?.reposts?.length > 0 && ( -
- { __( 'Reposts:', 'activitypub' ) } - -
+ ) }
); diff --git a/src/reactions/style.scss b/src/reactions/style.scss index 683497e88..969f476a1 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -3,36 +3,83 @@ display: flex; align-items: center; margin: 0.5em 0; - - span { - margin-right: 0.5em; - } + position: relative; } .reaction-facepile { display: flex; align-items: center; + overflow: hidden; + flex: 0 1 auto; + max-width: calc(100% - 100px); // Reserve space for label + } + + .reaction-label { + margin-left: 0.75em; + white-space: nowrap; + cursor: pointer; + flex: 0 0 auto; + color: #2271b1; + + &:hover { + color: #135e96; + } + } + + .reaction-avatar { + border-radius: 50%; + border: 2px solid #fff; + width: 32px; + height: 32px; + display: block; + } - a { - margin-right: -16px; // Half of avatar width for 50% overlap - transition: transform 0.2s ease; + .reaction-facepile a { + margin-right: -10.5px; + transition: transform 0.2s ease; + position: relative; + z-index: 1; + + &:hover { + z-index: 2; + transform: scale(1.1); + } + + &:last-child { + margin-right: 0; + } + } + + .reaction-dropdown { + position: absolute; + top: 100%; + right: 0; + background: #fff; + border: 1px solid #ddd; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + min-width: 200px; + margin-top: 0.5em; + z-index: 10; + max-height: 300px; + overflow-y: auto; + + .reaction-item { + display: flex; + align-items: center; + padding: 0.5em; + text-decoration: none; + color: inherit; &:hover { - z-index: 2; - transform: scale(1.1); + background: #f0f0f0; } - &:last-child { - margin-right: 0; + img { + width: 24px; + height: 24px; + margin-right: 0.5em; } } - - .reaction-avatar { - border-radius: 50%; - border: 2px solid #fff; // Helps separate overlapping avatars - width: 32px; - height: 32px; - display: block; - } } } \ No newline at end of file From 1c32c8e3b493c866e3e1eefba8855dadd43728fa Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 22:20:16 -0600 Subject: [PATCH 08/47] nicer layout with dropdowns to show all reactions with names --- src/reactions/block.json | 2 +- src/reactions/edit.js | 3 +- src/reactions/reactions.js | 148 +++++++++++++++++++++++-------------- src/reactions/style.scss | 121 +++++++++++++++++------------- 4 files changed, 165 insertions(+), 109 deletions(-) diff --git a/src/reactions/block.json b/src/reactions/block.json index 5c478e767..a9be62580 100644 --- a/src/reactions/block.json +++ b/src/reactions/block.json @@ -26,6 +26,6 @@ }, "textdomain": "activitypub", "editorScript": "file:./index.js", - "style": "file:./style-index.css", + "style": [ "file:./style-index.css", "wp-components" ], "viewScript": "file:./view.js" } diff --git a/src/reactions/edit.js b/src/reactions/edit.js index a95c08464..b190396d3 100644 --- a/src/reactions/edit.js +++ b/src/reactions/edit.js @@ -23,7 +23,6 @@ const generateDummyReaction = ( index ) => { '#E67E22', ]; const letter = letters[ Math.floor( Math.random() * letters.length ) ]; - // random color const color = colors[ Math.floor( Math.random() * colors.length ) ]; // Create a data URL for a colored circle with a letter. @@ -40,7 +39,7 @@ const generateDummyReaction = ( index ) => { // Draw letter. ctx.fillStyle = '#FFFFFF'; - ctx.font = 'bold 32px sans-serif'; + ctx.font = '32px sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText( letter, 32, 32 ); diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 38f4d3833..4e99b24b0 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -1,7 +1,8 @@ import { RichText } from '@wordpress/block-editor'; import { useState, useEffect } from '@wordpress/element'; +import { Popover, Button } from '@wordpress/components'; import apiFetch from '@wordpress/api-fetch'; -import { __ } from '@wordpress/i18n'; +import { __, _nx, sprintf } from '@wordpress/i18n'; /** * Extract the namespace from the global _activityPubOptions object. @@ -19,60 +20,68 @@ const { namespace } = window._activityPubOptions; */ const FacepileRow = ( { reactions } ) => (
- { reactions.map( ( reaction, index ) => ( - - { - - ) ) } +
    + { reactions.map( ( reaction, index ) => ( +
  • + + { + +
  • + ) ) } +
); /** * A component that renders a dropdown list of reactions. * - * @param {Object} props Component props. - * @param {Array} props.reactions Array of reaction objects. - * @param {boolean} props.isOpen Whether the dropdown is open. - * @return {JSX.Element} The rendered component. + * @param {Object} props Component props. + * @param {Array} props.reactions Array of reaction objects. + * @param {Object} props.anchor Reference to anchor element. + * @param {Function} props.onClose Callback when dropdown closes. + * @return {JSX.Element} The rendered component. */ -const ReactionDropdown = ( { reactions, isOpen } ) => { - if ( ! isOpen ) { - return null; - } - - return ( -
+const ReactionDropdown = ( { reactions, anchor, onClose } ) => ( + +
- ); -}; + + +); /** * A component that renders a reaction group with facepile and dropdown. @@ -84,25 +93,52 @@ const ReactionDropdown = ( { reactions, isOpen } ) => { */ const ReactionGroup = ( { reactions, type } ) => { const [ isOpen, setIsOpen ] = useState( false ); + const [ buttonRef, setButtonRef ] = useState( null ); const count = reactions.length; - const label = type === 'likes' ? - __( '%d Like', '%d Likes', count, 'activitypub' ) : - __( '%d Repost', '%d Reposts', count, 'activitypub' ); + + const label = sprintf( + /* translators: %d: number of reactions */ + _nx( + '%d Like', + '%d Likes', + count, + 'number of likes', + 'activitypub' + ), + count + ); + + const repostLabel = sprintf( + /* translators: %d: number of reactions */ + _nx( + '%d Repost', + '%d Reposts', + count, + 'number of reposts', + 'activitypub' + ), + count + ); return (
- - + { type === 'likes' ? label : repostLabel } + + { isOpen && buttonRef && ( + setIsOpen( false ) } + /> + ) }
); }; diff --git a/src/reactions/style.scss b/src/reactions/style.scss index 969f476a1..b573c5415 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -6,80 +6,101 @@ position: relative; } - .reaction-facepile { + .reaction-avatars { display: flex; align-items: center; - overflow: hidden; - flex: 0 1 auto; - max-width: calc(100% - 100px); // Reserve space for label - } + margin: 0; + padding: 0; + list-style: none; + width: 100%; - .reaction-label { - margin-left: 0.75em; - white-space: nowrap; - cursor: pointer; - flex: 0 0 auto; - color: #2271b1; + li { + margin: 0; + padding: 0; + margin-right: -10.5px; - &:hover { - color: #135e96; + &:last-child { + margin-right: 0; + } + } + + a { + display: block; + transition: transform 0.2s ease; + position: relative; + z-index: 1; + + &:hover { + z-index: 2; + transform: scale( 1.33 ); + } } } .reaction-avatar { border-radius: 50%; - border: 2px solid #fff; + border: 1px solid #fff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); width: 32px; height: 32px; display: block; } - .reaction-facepile a { - margin-right: -10.5px; - transition: transform 0.2s ease; - position: relative; - z-index: 1; + .reaction-label.components-button { + margin-left: 0.75em; + white-space: nowrap; + height: auto; + min-width: 0; + padding: 0; + text-decoration: none; + color: #2271b1; &:hover { - z-index: 2; - transform: scale(1.1); + color: #135e96; + text-decoration: underline; } - &:last-child { - margin-right: 0; + &:focus:not(:disabled) { + box-shadow: none; + outline: 1px solid #135e96; + outline-offset: 2px; } } +} - .reaction-dropdown { - position: absolute; - top: 100%; - right: 0; - background: #fff; - border: 1px solid #ddd; - border-radius: 4px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - min-width: 200px; - margin-top: 0.5em; - z-index: 10; - max-height: 300px; - overflow-y: auto; +.reaction-list { + margin: 0; + padding: .25em .5em; + list-style: none; + min-width: 200px; + width: max-content; + max-width: 300px; - .reaction-item { - display: flex; - align-items: center; - padding: 0.5em; - text-decoration: none; - color: inherit; + li { + margin: 0; + padding: 0; + font-size: var(--wp--preset--font-size--small); + } - &:hover { - background: #f0f0f0; - } + a { + display: flex; + align-items: center; + justify-content: flex-start; + gap: .5em; + padding: .25em .5em; + text-decoration: none; + font-size: var( --wp--preset--font-size--small, .75rem ); + color: inherit; - img { - width: 24px; - height: 24px; - margin-right: 0.5em; - } + &:hover { + text-decoration: underline; + } + + img { + width: 32px; + height: 32px; + border-radius: 50%; + flex: none; } } } \ No newline at end of file From cb0b2fad604264c1355a5fc9f9f2cb7542783e87 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 22:20:45 -0600 Subject: [PATCH 09/47] built files --- build/reactions/block.json | 18 +++++++++++++----- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 4 +++- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 4 +++- 7 files changed, 23 insertions(+), 11 deletions(-) diff --git a/build/reactions/block.json b/build/reactions/block.json index 07b15466e..2acdf4710 100644 --- a/build/reactions/block.json +++ b/build/reactions/block.json @@ -8,19 +8,27 @@ "icon": "heart", "description": "Display Fediverse likes and reposts", "supports": { - "html": false + "html": false, + "align": true, + "layout": { + "default": { + "type": "constrained", + "orientation": "vertical", + "justifyContent": "center" + } + } }, "attributes": { "title": { "type": "string", "default": "Fediverse reactions" - }, - "postId": { - "type": "number" } }, "textdomain": "activitypub", "editorScript": "file:./index.js", - "style": "file:./style-index.css", + "style": [ + "file:./style-index.css", + "wp-components" + ], "viewScript": "file:./view.js" } \ No newline at end of file diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index a073f3b9e..32097b7bd 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'a1d5717ae5a8c5be9af7'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '3d2a6079f2139df2030f'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 908eeff1e..7f03b2cb6 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1,3 @@ -(()=>{"use strict";var e,t={482:(e,t,i)=>{const a=window.wp.blocks,r=window.React,n=window.wp.blockEditor,s=window.wp.element,o=window.wp.data,c=window.wp.apiFetch;var l=i.n(c);const p=window.wp.components,u=window.wp.i18n,{namespace:d}=window._activityPubOptions,v=({reactions:e})=>(0,r.createElement)("div",{className:"reaction-facepile"},e.map(((e,t)=>(0,r.createElement)("a",{key:t,href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,r.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))));function m({title:e,postId:t,isEditing:i=!1,setTitle:a=(()=>{})}){const[n,o]=(0,s.useState)(null),[c,m]=(0,s.useState)(!0);return(0,s.useEffect)((()=>{m(!0),l()({path:`/${d}/reactions/${t}`}).then((e=>{o(e),m(!1)})).catch((()=>m(!1)))}),[t]),c||!n?null:(0,r.createElement)("div",{className:"activitypub-reactions"},i?(0,r.createElement)(p.RichText,{tagName:"h4",value:e,onChange:a,placeholder:(0,u.__)("Fediverse reactions","activitypub")}):e&&(0,r.createElement)("h4",null,e),n?.likes?.length>0&&(0,r.createElement)("div",{className:"reaction-group activitypub-reactions-likes"},(0,r.createElement)("span",null,(0,u.__)("Likes:","activitypub")," "),(0,r.createElement)(v,{reactions:n.likes})),n?.reposts?.length>0&&(0,r.createElement)("div",{className:"reaction-group activitypub-reactions-reposts"},(0,r.createElement)("span",null,(0,u.__)("Reposts:","activitypub")," "),(0,r.createElement)(v,{reactions:n.reposts})))}const{namespace:w}=window._activityPubOptions,b=JSON.parse('{"UU":"activitypub/reactions"}');(0,a.registerBlockType)(b.UU,{edit:function({attributes:e,setAttributes:t}){const i=(0,o.useSelect)((e=>e("core/editor")?.getCurrentPostId()),[]),a=(0,n.useBlockProps)();return i?(0,r.createElement)("div",{...a},(0,r.createElement)(m,{postId:i,isEditing:!0,title:e.title,setTitle:e=>t({title:e})})):(0,r.createElement)("div",{...a},(0,r.createElement)(p.Notice,{status:"warning",isDismissible:!1},(0,u.__)("This block can only be used in a single post or page context.","activitypub")))}})}},i={};function a(e){var r=i[e];if(void 0!==r)return r.exports;var n=i[e]={exports:{}};return t[e](n,n.exports,a),n.exports}a.m=t,e=[],a.O=(t,i,r,n)=>{if(!i){var s=1/0;for(p=0;p=n)&&Object.keys(a.O).every((e=>a.O[e](i[c])))?i.splice(c--,1):(o=!1,n0&&e[p-1][2]>n;p--)e[p]=e[p-1];e[p]=[i,r,n]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var i in t)a.o(t,i)&&!a.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};a.O.j=t=>0===e[t];var t=(t,i)=>{var r,n,[s,o,c]=i,l=0;if(s.some((t=>0!==e[t]))){for(r in o)a.o(o,r)&&(a.m[r]=o[r]);if(c)var p=c(a)}for(t&&t(i);la(482)));r=a.O(r)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,i=window.wp.blockEditor,o=window.wp.element,l=window.wp.i18n,s=window.wp.components,c=window.wp.apiFetch;var p=a.n(c);const{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,n.createElement)("div",{className:"reaction-facepile"},(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"}))))))),d=({reactions:e,anchor:t,onClose:a})=>(0,n.createElement)(s.Popover,{anchor:t,placement:"bottom-end",onClose:a,className:"reaction-dropdown",noArrow:!1,offset:10},(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name))))))),h=({reactions:e,type:t})=>{const[a,r]=(0,o.useState)(!1),[i,c]=(0,o.useState)(null),p=e.length,m=(0,l.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ +(0,l._nx)("%d Like","%d Likes",p,"number of likes","activitypub"),p),h=(0,l.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ +(0,l._nx)("%d Repost","%d Reposts",p,"number of reposts","activitypub"),p);return(0,n.createElement)("div",{className:"reaction-group"},(0,n.createElement)(u,{reactions:e}),(0,n.createElement)(s.Button,{ref:c,variant:"link",className:"reaction-label",onClick:()=>r(!a),"aria-expanded":a},"likes"===t?m:h),a&&i&&(0,n.createElement)(d,{reactions:e,anchor:i,onClose:()=>r(!1)}))};function f({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:s=null}){const[c,u]=(0,o.useState)(s),[d,f]=(0,o.useState)(!s);return(0,o.useEffect)((()=>{if(s)return u(s),void f(!1);t?(f(!0),p()({path:`/${m}/reactions/${t}`}).then((e=>{u(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,s]),d?null:(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(i.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,l.__)("Fediverse reactions","activitypub")}):e&&(0,n.createElement)("h4",null,e),c?.likes?.length>0&&(0,n.createElement)(h,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,n.createElement)(h,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],r=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const i=n.getContext("2d");return i.fillStyle=r,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(a,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t}){const a=(0,i.useBlockProps)(),[r]=(0,o.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...a},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:r}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var i=a[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.m=t,e=[],r.O=(t,a,n,i)=>{if(!a){var o=1/0;for(p=0;p=i)&&Object.keys(r.O).every((e=>r.O[e](a[s])))?a.splice(s--,1):(l=!1,i0&&e[p-1][2]>i;p--)e[p]=e[p-1];e[p]=[a,n,i]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,i,[o,l,s]=a,c=0;if(o.some((t=>0!==e[t]))){for(n in l)r.o(l,n)&&(r.m[n]=l[n]);if(s)var p=s(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index b0d9c1667..f41ecfe39 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0}.activitypub-reactions .reaction-group span{margin-left:.5em}.activitypub-reactions .reaction-facepile{align-items:center;display:flex}.activitypub-reactions .reaction-facepile a{margin-left:-16px;transition:transform .2s ease}.activitypub-reactions .reaction-facepile a:hover{transform:scale(1.1);z-index:2}.activitypub-reactions .reaction-facepile a:last-child{margin-left:0}.activitypub-reactions .reaction-facepile .reaction-avatar{border:2px solid #fff;border-radius:50%;display:block;height:32px;width:32px} +.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0;position:relative}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;list-style:none;margin:0;padding:0;width:100%}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10.5px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars a:hover{transform:scale(1.33);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;height:auto;margin-right:.75em;min-width:0;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.25em .5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:32px;width:32px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index a011808bb..46d80a4e4 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0}.activitypub-reactions .reaction-group span{margin-right:.5em}.activitypub-reactions .reaction-facepile{align-items:center;display:flex}.activitypub-reactions .reaction-facepile a{margin-right:-16px;transition:transform .2s ease}.activitypub-reactions .reaction-facepile a:hover{transform:scale(1.1);z-index:2}.activitypub-reactions .reaction-facepile a:last-child{margin-right:0}.activitypub-reactions .reaction-facepile .reaction-avatar{border:2px solid #fff;border-radius:50%;display:block;height:32px;width:32px} +.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0;position:relative}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;list-style:none;margin:0;padding:0;width:100%}.activitypub-reactions .reaction-avatars li{margin:0 -10.5px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars a:hover{transform:scale(1.33);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;height:auto;margin-left:.75em;min-width:0;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.25em .5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:32px;width:32px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 8dc807296..0d8c0efb3 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '471bfae478141ab790fc'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'f0dbb6dec4396e35168c'); diff --git a/build/reactions/view.js b/build/reactions/view.js index 5231e6e9b..442e560e9 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1,3 @@ -(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const c=window.wp.components,i=window.wp.apiFetch;var o=e.n(i);const s=window.wp.i18n,{namespace:l}=window._activityPubOptions,p=({reactions:e})=>(0,t.createElement)("div",{className:"reaction-facepile"},e.map(((e,a)=>(0,t.createElement)("a",{key:a,href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))));function u({title:e,postId:n,isEditing:r=!1,setTitle:i=(()=>{})}){const[u,m]=(0,a.useState)(null),[d,v]=(0,a.useState)(!0);return(0,a.useEffect)((()=>{v(!0),o()({path:`/${l}/reactions/${n}`}).then((e=>{m(e),v(!1)})).catch((()=>v(!1)))}),[n]),d||!u?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:i,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),u?.likes?.length>0&&(0,t.createElement)("div",{className:"reaction-group activitypub-reactions-likes"},(0,t.createElement)("span",null,(0,s.__)("Likes:","activitypub")," "),(0,t.createElement)(p,{reactions:u.likes})),u?.reposts?.length>0&&(0,t.createElement)("div",{className:"reaction-group activitypub-reactions-reposts"},(0,t.createElement)("span",null,(0,s.__)("Reposts:","activitypub")," "),(0,t.createElement)(p,{reactions:u.reposts})))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(u,{...n}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const o=window.wp.blockEditor,c=window.wp.components,l=window.wp.apiFetch;var i=e.n(l);const s=window.wp.i18n,{namespace:m}=window._activityPubOptions,p=({reactions:e})=>(0,t.createElement)("div",{className:"reaction-facepile"},(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"}))))))),d=({reactions:e,anchor:a,onClose:n})=>(0,t.createElement)(c.Popover,{anchor:a,placement:"bottom-end",onClose:n,className:"reaction-dropdown",noArrow:!1,offset:10},(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name))))))),u=({reactions:e,type:n})=>{const[r,o]=(0,a.useState)(!1),[l,i]=(0,a.useState)(null),m=e.length,u=(0,s.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ +(0,s._nx)("%d Like","%d Likes",m,"number of likes","activitypub"),m),w=(0,s.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ +(0,s._nx)("%d Repost","%d Reposts",m,"number of reposts","activitypub"),m);return(0,t.createElement)("div",{className:"reaction-group"},(0,t.createElement)(p,{reactions:e}),(0,t.createElement)(c.Button,{ref:i,variant:"link",className:"reaction-label",onClick:()=>o(!r),"aria-expanded":r},"likes"===n?u:w),r&&l&&(0,t.createElement)(d,{reactions:e,anchor:l,onClose:()=>o(!1)}))};function w({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:l=null}){const[p,d]=(0,a.useState)(l),[w,h]=(0,a.useState)(!l);return(0,a.useEffect)((()=>{if(l)return d(l),void h(!1);n?(h(!0),i()({path:`/${m}/reactions/${n}`}).then((e=>{d(e),h(!1)})).catch((()=>h(!1)))):h(!1)}),[n,l]),w?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(o.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),p?.likes?.length>0&&(0,t.createElement)(u,{reactions:p.likes,type:"likes"}),p?.reposts?.length>0&&(0,t.createElement)(u,{reactions:p.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(w,{...n}))}))}))})(); \ No newline at end of file From daa55bb0634a0791bf6e7c6f29bb499274fb1b50 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 22:22:24 -0600 Subject: [PATCH 10/47] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a1700de9..8fc2d40fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* Reactions block to display likes and reposts * `icon` support for `Audio` and `Video` attachments * Send "new follower" emails * Send "direct message" emails From 308538c2ae4f6cedd1cc0f458eb930cd9b786e95 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Wed, 11 Dec 2024 22:25:57 -0600 Subject: [PATCH 11/47] =?UTF-8?q?changelog=20=E2=9C=8C=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index d132fb67a..589df3039 100644 --- a/readme.txt +++ b/readme.txt @@ -134,6 +134,7 @@ For reasons of data protection, it is not possible to see the followers of other = Unreleased = +* Added: Reactions block to display likes and reposts * Added: `icon` support for `Audio` and `Video` attachments * Added: Send "new follower" emails * Added: Send "direct message" emails From 6202b413e379b1ef0c9dcbb3a4cb00419742027e Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 10:00:01 -0600 Subject: [PATCH 12/47] constrain to a single line --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 4 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 4 +- src/reactions/index.js | 4 +- src/reactions/reactions.js | 173 +++++++++++++++++++--------- src/reactions/style.scss | 42 ++++--- 9 files changed, 155 insertions(+), 80 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 32097b7bd..82842086b 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '3d2a6079f2139df2030f'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '04f883d578a346838549'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 7f03b2cb6..2bcce5b45 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1,3 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,i=window.wp.blockEditor,o=window.wp.element,l=window.wp.i18n,s=window.wp.components,c=window.wp.apiFetch;var p=a.n(c);const{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,n.createElement)("div",{className:"reaction-facepile"},(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"}))))))),d=({reactions:e,anchor:t,onClose:a})=>(0,n.createElement)(s.Popover,{anchor:t,placement:"bottom-end",onClose:a,className:"reaction-dropdown",noArrow:!1,offset:10},(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name))))))),h=({reactions:e,type:t})=>{const[a,r]=(0,o.useState)(!1),[i,c]=(0,o.useState)(null),p=e.length,m=(0,l.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ -(0,l._nx)("%d Like","%d Likes",p,"number of likes","activitypub"),p),h=(0,l.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ -(0,l._nx)("%d Repost","%d Reposts",p,"number of reposts","activitypub"),p);return(0,n.createElement)("div",{className:"reaction-group"},(0,n.createElement)(u,{reactions:e}),(0,n.createElement)(s.Button,{ref:c,variant:"link",className:"reaction-label",onClick:()=>r(!a),"aria-expanded":a},"likes"===t?m:h),a&&i&&(0,n.createElement)(d,{reactions:e,anchor:i,onClose:()=>r(!1)}))};function f({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:s=null}){const[c,u]=(0,o.useState)(s),[d,f]=(0,o.useState)(!s);return(0,o.useEffect)((()=>{if(s)return u(s),void f(!1);t?(f(!0),p()({path:`/${m}/reactions/${t}`}).then((e=>{u(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,s]),d?null:(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(i.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,l.__)("Fediverse reactions","activitypub")}):e&&(0,n.createElement)("h4",null,e),c?.likes?.length>0&&(0,n.createElement)(h,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,n.createElement)(h,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],r=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const i=n.getContext("2d");return i.fillStyle=r,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(a,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t}){const a=(0,i.useBlockProps)(),[r]=(0,o.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...a},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:r}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var i=a[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.m=t,e=[],r.O=(t,a,n,i)=>{if(!a){var o=1/0;for(p=0;p=i)&&Object.keys(r.O).every((e=>r.O[e](a[s])))?a.splice(s--,1):(l=!1,i0&&e[p-1][2]>i;p--)e[p]=e[p-1];e[p]=[a,n,i]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,i,[o,l,s]=a,c=0;if(o.some((t=>0!==e[t]))){for(n in l)r.o(l,n)&&(r.m[n]=l[n]);if(s)var p=s(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,i=window.wp.blockEditor,l=window.wp.element,s=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:p}=window._activityPubOptions,m=({reactions:e})=>(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),h=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),d=({reactions:e,type:t})=>{const[r,n]=(0,l.useState)(!1),[i,c]=(0,l.useState)(null),[u,p]=(0,l.useState)(e.length),d=(0,l.useRef)(null),f=e.length;(0,l.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const r=t.offsetWidth-(i?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));p(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(d.current),()=>{r.disconnect()}}),[i,e.length]);const v=e.slice(0,u),E="likes"===t?(0,s._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,s._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,a.createElement)("div",{className:"reaction-group",ref:d},(0,a.createElement)(m,{reactions:v}),(0,a.createElement)(o.Button,{ref:c,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},(0,s.sprintf)(E,f)),r&&i&&(0,a.createElement)(o.Popover,{anchor:i,onClose:()=>n(!1)},(0,a.createElement)(h,{reactions:e,type:t})))};function f({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:o=null}){const[c,m]=(0,l.useState)(o),[h,f]=(0,l.useState)(!o);return(0,l.useEffect)((()=>{if(o)return m(o),void f(!1);t?(f(!0),u()({path:`/${p}/reactions/${t}`}).then((e=>{m(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),h?null:(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(i.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,a.createElement)("h4",null,e),c?.likes?.length>0&&(0,a.createElement)(d,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,a.createElement)(d,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const i=a.getContext("2d");return i.fillStyle=n,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t}){const r=(0,i.useBlockProps)(),[n]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...r},(0,a.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:n}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.m=t,e=[],n.O=(t,r,a,i)=>{if(!r){var l=1/0;for(u=0;u=i)&&Object.keys(n.O).every((e=>n.O[e](r[o])))?r.splice(o--,1):(s=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,a,i]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,i,[l,s,o]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in s)n.o(s,a)&&(n.m[a]=s[a]);if(o)var u=o(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index f41ecfe39..bd2f7d1ad 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0;position:relative}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;list-style:none;margin:0;padding:0;width:100%}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10.5px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars a:hover{transform:scale(1.33);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;height:auto;margin-right:.75em;min-width:0;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.25em .5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:32px;width:32px} +.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 46d80a4e4..fe2b70ad8 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;margin:.5em 0;position:relative}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;list-style:none;margin:0;padding:0;width:100%}.activitypub-reactions .reaction-avatars li{margin:0 -10.5px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars a:hover{transform:scale(1.33);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;height:auto;margin-left:.75em;min-width:0;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.25em .5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:32px;width:32px} +.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 0d8c0efb3..2103466f5 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'f0dbb6dec4396e35168c'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '66719732000dbe7f7a5c'); diff --git a/build/reactions/view.js b/build/reactions/view.js index 442e560e9..eca7afc39 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1,3 +1 @@ -(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const o=window.wp.blockEditor,c=window.wp.components,l=window.wp.apiFetch;var i=e.n(l);const s=window.wp.i18n,{namespace:m}=window._activityPubOptions,p=({reactions:e})=>(0,t.createElement)("div",{className:"reaction-facepile"},(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"}))))))),d=({reactions:e,anchor:a,onClose:n})=>(0,t.createElement)(c.Popover,{anchor:a,placement:"bottom-end",onClose:n,className:"reaction-dropdown",noArrow:!1,offset:10},(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name))))))),u=({reactions:e,type:n})=>{const[r,o]=(0,a.useState)(!1),[l,i]=(0,a.useState)(null),m=e.length,u=(0,s.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ -(0,s._nx)("%d Like","%d Likes",m,"number of likes","activitypub"),m),w=(0,s.sprintf)(/* translators: %d: number of reactions */ /* translators: %d: number of reactions */ -(0,s._nx)("%d Repost","%d Reposts",m,"number of reposts","activitypub"),m);return(0,t.createElement)("div",{className:"reaction-group"},(0,t.createElement)(p,{reactions:e}),(0,t.createElement)(c.Button,{ref:i,variant:"link",className:"reaction-label",onClick:()=>o(!r),"aria-expanded":r},"likes"===n?u:w),r&&l&&(0,t.createElement)(d,{reactions:e,anchor:l,onClose:()=>o(!1)}))};function w({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:l=null}){const[p,d]=(0,a.useState)(l),[w,h]=(0,a.useState)(!l);return(0,a.useEffect)((()=>{if(l)return d(l),void h(!1);n?(h(!0),i()({path:`/${m}/reactions/${n}`}).then((e=>{d(e),h(!1)})).catch((()=>h(!1)))):h(!1)}),[n,l]),w?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(o.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),p?.likes?.length>0&&(0,t.createElement)(u,{reactions:p.likes,type:"likes"}),p?.reposts?.length>0&&(0,t.createElement)(u,{reactions:p.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(w,{...n}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,l=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({reactions:e,type:a})=>{const[r,c]=(0,n.useState)(!1),[o,s]=(0,n.useState)(null),[u,d]=(0,n.useState)(e.length),h=(0,n.useRef)(null),f=e.length;(0,n.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const n=t.offsetWidth-(o?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));d(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(h.current),()=>{n.disconnect()}}),[o,e.length]);const w=e.slice(0,u),E="likes"===a?(0,i._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,i._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(m,{reactions:w}),(0,t.createElement)(l.Button,{ref:s,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},(0,i.sprintf)(E,f)),r&&o&&(0,t.createElement)(l.Popover,{anchor:o,onClose:()=>c(!1)},(0,t.createElement)(p,{reactions:e,type:a})))};function h({title:e="",postId:a=null,isEditing:r=!1,setTitle:l=(()=>{}),reactions:o=null}){const[m,p]=(0,n.useState)(o),[h,f]=(0,n.useState)(!o);return(0,n.useEffect)((()=>{if(o)return p(o),void f(!1);a?(f(!0),s()({path:`/${u}/reactions/${a}`}).then((e=>{p(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[a,o]),h?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:l,placeholder:(0,i.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),m?.likes?.length>0&&(0,t.createElement)(d,{reactions:m.likes,type:"likes"}),m?.reposts?.length>0&&(0,t.createElement)(d,{reactions:m.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(h,{...a}))}))}))})(); \ No newline at end of file diff --git a/src/reactions/index.js b/src/reactions/index.js index ec6f92ca1..48e12d2a8 100644 --- a/src/reactions/index.js +++ b/src/reactions/index.js @@ -1,7 +1,7 @@ import { registerBlockType } from '@wordpress/blocks'; import edit from './edit'; -import { name } from './block.json'; +import metadata from './block.json'; import './style.scss'; -registerBlockType( name, { edit } ); \ No newline at end of file +registerBlockType( metadata.name, { edit } ); \ No newline at end of file diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 4e99b24b0..10d55e629 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -1,5 +1,8 @@ +/** + * WordPress dependencies + */ import { RichText } from '@wordpress/block-editor'; -import { useState, useEffect } from '@wordpress/element'; +import { useState, useEffect, useRef } from '@wordpress/element'; import { Popover, Button } from '@wordpress/components'; import apiFetch from '@wordpress/api-fetch'; import { __, _nx, sprintf } from '@wordpress/i18n'; @@ -19,27 +22,25 @@ const { namespace } = window._activityPubOptions; * @return {JSX.Element} The rendered component. */ const FacepileRow = ( { reactions } ) => ( -
-
    - { reactions.map( ( reaction, index ) => ( -
  • - - { - -
  • - ) ) } -
-
+
    + { reactions.map( ( reaction, index ) => ( +
  • + + { + +
  • + ) ) } +
); /** @@ -83,6 +84,37 @@ const ReactionDropdown = ( { reactions, anchor, onClose } ) => ( ); +/** + * A component that renders a dropdown list of reactions. + * + * @param {Object} props Component props. + * @param {Array} props.reactions Array of reaction objects. + * @param {string} props.type Type of reaction (likes/reposts). + * @return {JSX.Element} The rendered component. + */ +const ReactionList = ( { reactions, type } ) => ( + +); + /** * A component that renders a reaction group with facepile and dropdown. * @@ -94,50 +126,87 @@ const ReactionDropdown = ( { reactions, anchor, onClose } ) => ( const ReactionGroup = ( { reactions, type } ) => { const [ isOpen, setIsOpen ] = useState( false ); const [ buttonRef, setButtonRef ] = useState( null ); + const [ visibleCount, setVisibleCount ] = useState( reactions.length ); + const containerRef = useRef( null ); const count = reactions.length; - const label = sprintf( - /* translators: %d: number of reactions */ - _nx( - '%d Like', - '%d Likes', + // Constants for calculations + const AVATAR_WIDTH = 32; // Width of each avatar + const AVATAR_OVERLAP = 10; // How much each avatar overlaps + const EFFECTIVE_AVATAR_WIDTH = AVATAR_WIDTH - AVATAR_OVERLAP; // Width each additional avatar takes + const BUTTON_GAP = 12; // Gap between avatars and button (0.75em) + + useEffect( () => { + if ( ! containerRef.current ) { + return; + } + + const calculateVisibleAvatars = () => { + const container = containerRef.current; + if ( ! container ) { + return; + } + + const containerWidth = container.offsetWidth; + const labelWidth = buttonRef?.offsetWidth || 0; + const availableWidth = containerWidth - labelWidth - BUTTON_GAP; + + // Calculate how many avatars can fit + // First avatar takes full width, rest take effective width + const maxAvatars = Math.max( 1, Math.floor( ( availableWidth - AVATAR_WIDTH ) / EFFECTIVE_AVATAR_WIDTH ) ); + + // Ensure we don't show more than we have + setVisibleCount( Math.min( maxAvatars, reactions.length ) ); + }; + + // Initial calculation + calculateVisibleAvatars(); + + // Setup resize observer + const resizeObserver = new ResizeObserver( calculateVisibleAvatars ); + resizeObserver.observe( containerRef.current ); + + return () => { + resizeObserver.disconnect(); + }; + }, [ buttonRef, reactions.length ] ); + + const visibleReactions = reactions.slice( 0, visibleCount ); + + const label = type === 'likes' + ? _nx( + '%d like', + '%d likes', count, 'number of likes', 'activitypub' - ), - count - ); - - const repostLabel = sprintf( - /* translators: %d: number of reactions */ - _nx( - '%d Repost', - '%d Reposts', + ) + : _nx( + '%d repost', + '%d reposts', count, 'number of reposts', 'activitypub' - ), - count - ); + ); return ( -
- +
+ { isOpen && buttonRef && ( - setIsOpen( false ) } - /> + > + + ) }
); @@ -180,11 +249,11 @@ export function Reactions( { apiFetch( { path: `/${ namespace }/reactions/${ postId }`, } ) - .then( ( response ) => { - setReactions( response ); - setLoading( false ); - } ) - .catch( () => setLoading( false ) ); + .then( ( response ) => { + setReactions( response ); + setLoading( false ); + } ) + .catch( () => setLoading( false ) ); }, [ postId, providedReactions ] ); if ( loading ) { diff --git a/src/reactions/style.scss b/src/reactions/style.scss index b573c5415..c75e55dca 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -4,6 +4,16 @@ align-items: center; margin: 0.5em 0; position: relative; + width: 100%; + gap: 0.75em; + justify-content: flex-start; + + // When content overflows, switch to space-between + &:has(.reaction-avatars:not(:empty)) { + @media (max-width: 782px) { + justify-content: space-between; + } + } } .reaction-avatars { @@ -12,27 +22,28 @@ margin: 0; padding: 0; list-style: none; - width: 100%; + flex: 0 1 auto; + min-width: 0; li { margin: 0; padding: 0; - margin-right: -10.5px; + margin-right: -10px; &:last-child { margin-right: 0; } - } - a { - display: block; - transition: transform 0.2s ease; - position: relative; - z-index: 1; + a { + display: block; + transition: transform 0.2s ease; + position: relative; + z-index: 1; - &:hover { - z-index: 2; - transform: scale( 1.33 ); + &:hover { + z-index: 2; + transform: scale(1.5); + } } } } @@ -47,13 +58,12 @@ } .reaction-label.components-button { - margin-left: 0.75em; white-space: nowrap; height: auto; - min-width: 0; padding: 0; text-decoration: none; color: #2271b1; + flex: 0 0 auto; &:hover { color: #135e96; @@ -87,7 +97,7 @@ align-items: center; justify-content: flex-start; gap: .5em; - padding: .25em .5em; + padding: .5em; text-decoration: none; font-size: var( --wp--preset--font-size--small, .75rem ); color: inherit; @@ -97,8 +107,8 @@ } img { - width: 32px; - height: 32px; + width: 24px; + height: 24px; border-radius: 50%; flex: none; } From fc46a4f6e4a850cce19ceb4c2b23c5543659db05 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 12:41:35 -0600 Subject: [PATCH 13/47] use integer type, prop @obenland --- includes/rest/class-interaction.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 582f72605..f48aee6ed 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -53,10 +53,8 @@ public static function register_routes() { 'permission_callback' => '__return_true', 'args' => array( 'id' => array( - 'required' => true, - 'validate_callback' => function ( $val ) { - return is_numeric( $val ); - }, + 'required' => true, + 'type' => 'integer', ), ), ) From 7984d2aeaf0021cc7cee3768226b2d93bda95726 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 15:04:59 -0600 Subject: [PATCH 14/47] fit and finish --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- src/reactions/edit.js | 4 ++-- src/reactions/reactions.js | 2 ++ src/reactions/style.scss | 6 ++++++ 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 82842086b..1bc51c552 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '04f883d578a346838549'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'cfc8249e527b0a048773'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 2bcce5b45..0f6603b0c 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,i=window.wp.blockEditor,l=window.wp.element,s=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:p}=window._activityPubOptions,m=({reactions:e})=>(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),h=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),d=({reactions:e,type:t})=>{const[r,n]=(0,l.useState)(!1),[i,c]=(0,l.useState)(null),[u,p]=(0,l.useState)(e.length),d=(0,l.useRef)(null),f=e.length;(0,l.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const r=t.offsetWidth-(i?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));p(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(d.current),()=>{r.disconnect()}}),[i,e.length]);const v=e.slice(0,u),E="likes"===t?(0,s._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,s._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,a.createElement)("div",{className:"reaction-group",ref:d},(0,a.createElement)(m,{reactions:v}),(0,a.createElement)(o.Button,{ref:c,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},(0,s.sprintf)(E,f)),r&&i&&(0,a.createElement)(o.Popover,{anchor:i,onClose:()=>n(!1)},(0,a.createElement)(h,{reactions:e,type:t})))};function f({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:o=null}){const[c,m]=(0,l.useState)(o),[h,f]=(0,l.useState)(!o);return(0,l.useEffect)((()=>{if(o)return m(o),void f(!1);t?(f(!0),u()({path:`/${p}/reactions/${t}`}).then((e=>{m(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),h?null:(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(i.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,s.__)("Fediverse reactions","activitypub")}):e&&(0,a.createElement)("h4",null,e),c?.likes?.length>0&&(0,a.createElement)(d,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,a.createElement)(d,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const i=a.getContext("2d");return i.fillStyle=n,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t}){const r=(0,i.useBlockProps)(),[n]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...r},(0,a.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:n}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.m=t,e=[],n.O=(t,r,a,i)=>{if(!r){var l=1/0;for(u=0;u=i)&&Object.keys(n.O).every((e=>n.O[e](r[o])))?r.splice(o--,1):(s=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,a,i]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,i,[l,s,o]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in s)n.o(s,a)&&(n.m[a]=s[a]);if(o)var u=o(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,r)=>{const a=window.wp.blocks,n=window.React,i=window.wp.blockEditor,s=window.wp.element,l=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:p}=window._activityPubOptions,m=({reactions:e})=>(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),h=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),d=({reactions:e,type:t})=>{const[r,a]=(0,s.useState)(!1),[i,c]=(0,s.useState)(null),[u,p]=(0,s.useState)(e.length),d=(0,s.useRef)(null),f=e.length;(0,s.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const r=t.offsetWidth-(i?.offsetWidth||0)-12,a=Math.max(1,Math.floor((r-32)/22));p(Math.min(a,e.length))};t();const r=new ResizeObserver(t);return r.observe(d.current),()=>{r.disconnect()}}),[i,e.length]);const v=e.slice(0,u),E="likes"===t?(0,l._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,l._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,n.createElement)("div",{className:"reaction-group",ref:d},(0,n.createElement)(m,{reactions:v}),(0,n.createElement)(o.Button,{ref:c,className:"reaction-label is-link",onClick:()=>a(!r),"aria-expanded":r},(0,l.sprintf)(E,f)),r&&i&&(0,n.createElement)(o.Popover,{anchor:i,onClose:()=>a(!1)},(0,n.createElement)(h,{reactions:e,type:t})))};function f({title:e="",postId:t=null,isEditing:r=!1,setTitle:a=(()=>{}),reactions:o=null}){const[c,m]=(0,s.useState)(o),[h,f]=(0,s.useState)(!o);return(0,s.useEffect)((()=>{if(o)return m(o),void f(!1);t?(f(!0),u()({path:`/${p}/reactions/${t}`}).then((e=>{m(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),h?null:(0,n.createElement)("div",{className:"activitypub-reactions"},r?(0,n.createElement)(i.RichText,{tagName:"h4",value:e,onChange:a,placeholder:(0,l.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),c?.likes?.length>0&&(0,n.createElement)(d,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,n.createElement)(d,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],a=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const i=n.getContext("2d");return i.fillStyle=a,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,a.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const a=(0,i.useBlockProps)({className:r}),[l]=(0,s.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...a},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:l}))}})}},r={};function a(e){var n=r[e];if(void 0!==n)return n.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,a),i.exports}a.m=t,e=[],a.O=(t,r,n,i)=>{if(!r){var s=1/0;for(u=0;u=i)&&Object.keys(a.O).every((e=>a.O[e](r[o])))?r.splice(o--,1):(l=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,n,i]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};a.O.j=t=>0===e[t];var t=(t,r)=>{var n,i,[s,l,o]=r,c=0;if(s.some((t=>0!==e[t]))){for(n in l)a.o(l,n)&&(a.m[n]=l[n]);if(o)var u=o(a)}for(t&&t(r);ca(505)));n=a.O(n)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index bd2f7d1ad..8d2820e25 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index fe2b70ad8..3d799bf35 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 2103466f5..de2d51b61 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '66719732000dbe7f7a5c'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'fc37c3857994bda4badd'); diff --git a/build/reactions/view.js b/build/reactions/view.js index eca7afc39..b5938c629 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,l=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({reactions:e,type:a})=>{const[r,c]=(0,n.useState)(!1),[o,s]=(0,n.useState)(null),[u,d]=(0,n.useState)(e.length),h=(0,n.useRef)(null),f=e.length;(0,n.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const n=t.offsetWidth-(o?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));d(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(h.current),()=>{n.disconnect()}}),[o,e.length]);const w=e.slice(0,u),E="likes"===a?(0,i._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,i._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(m,{reactions:w}),(0,t.createElement)(l.Button,{ref:s,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},(0,i.sprintf)(E,f)),r&&o&&(0,t.createElement)(l.Popover,{anchor:o,onClose:()=>c(!1)},(0,t.createElement)(p,{reactions:e,type:a})))};function h({title:e="",postId:a=null,isEditing:r=!1,setTitle:l=(()=>{}),reactions:o=null}){const[m,p]=(0,n.useState)(o),[h,f]=(0,n.useState)(!o);return(0,n.useEffect)((()=>{if(o)return p(o),void f(!1);a?(f(!0),s()({path:`/${u}/reactions/${a}`}).then((e=>{p(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[a,o]),h?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:l,placeholder:(0,i.__)("Fediverse reactions","activitypub")}):e&&(0,t.createElement)("h4",null,e),m?.likes?.length>0&&(0,t.createElement)(d,{reactions:m.likes,type:"likes"}),m?.reposts?.length>0&&(0,t.createElement)(d,{reactions:m.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(h,{...a}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const l=window.wp.blockEditor,c=window.wp.components,s=window.wp.apiFetch;var o=e.n(s);const i=window.wp.i18n,{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:a})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({reactions:e,type:n})=>{const[r,l]=(0,a.useState)(!1),[s,o]=(0,a.useState)(null),[m,d]=(0,a.useState)(e.length),h=(0,a.useRef)(null),f=e.length;(0,a.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const a=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((a-32)/22));d(Math.min(n,e.length))};t();const a=new ResizeObserver(t);return a.observe(h.current),()=>{a.disconnect()}}),[s,e.length]);const w=e.slice(0,m),E="likes"===n?(0,i._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,i._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(u,{reactions:w}),(0,t.createElement)(c.Button,{ref:o,className:"reaction-label is-link",onClick:()=>l(!r),"aria-expanded":r},(0,i.sprintf)(E,f)),r&&s&&(0,t.createElement)(c.Popover,{anchor:s,onClose:()=>l(!1)},(0,t.createElement)(p,{reactions:e,type:n})))};function h({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:s=null}){const[u,p]=(0,a.useState)(s),[h,f]=(0,a.useState)(!s);return(0,a.useEffect)((()=>{if(s)return p(s),void f(!1);n?(f(!0),o()({path:`/${m}/reactions/${n}`}).then((e=>{p(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[n,s]),h?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(l.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),u?.likes?.length>0&&(0,t.createElement)(d,{reactions:u.likes,type:"likes"}),u?.reposts?.length>0&&(0,t.createElement)(d,{reactions:u.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(h,{...n}))}))}))})(); \ No newline at end of file diff --git a/src/reactions/edit.js b/src/reactions/edit.js index b190396d3..c7cd23405 100644 --- a/src/reactions/edit.js +++ b/src/reactions/edit.js @@ -69,8 +69,8 @@ const generateDummyReactions = () => ( { * @param {Function} props.setAttributes Attribute update callback. * @return {JSX.Element} Component to render. */ -export default function Edit( { attributes, setAttributes } ) { - const blockProps = useBlockProps(); +export default function Edit( { attributes, setAttributes, __unstableLayoutClassNames } ) { + const blockProps = useBlockProps( { className: __unstableLayoutClassNames } ); const [ dummyReactions ] = useState( generateDummyReactions() ); return ( diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 10d55e629..9d56fd661 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -268,6 +268,8 @@ export function Reactions( { value={ title } onChange={ setTitle } placeholder={ __( 'Fediverse reactions', 'activitypub' ) } + disableLineBreaks={ true } + allowedFormats={ [] } /> ) : ( title &&

{ title }

diff --git a/src/reactions/style.scss b/src/reactions/style.scss index c75e55dca..45ba44ff3 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -1,4 +1,10 @@ .activitypub-reactions { + h4 { + border-top: 1px solid; + display: inline-block; + padding-top: .5em; + border-top-color: var(--wp--preset--color--contrast-2); + } .reaction-group { display: flex; align-items: center; From 6fbe830f32abaa889a356e517f2d416952d18f86 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 15:14:32 -0600 Subject: [PATCH 15/47] Use the 'after' block hook --- build/reactions/block.json | 3 +++ src/reactions/block.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/build/reactions/block.json b/build/reactions/block.json index 2acdf4710..e489c0f89 100644 --- a/build/reactions/block.json +++ b/build/reactions/block.json @@ -24,6 +24,9 @@ "default": "Fediverse reactions" } }, + "blockHooks": { + "core/post-content": "after" + }, "textdomain": "activitypub", "editorScript": "file:./index.js", "style": [ diff --git a/src/reactions/block.json b/src/reactions/block.json index a9be62580..1a6a3acdf 100644 --- a/src/reactions/block.json +++ b/src/reactions/block.json @@ -24,6 +24,9 @@ "default": "Fediverse reactions" } }, + "blockHooks": { + "core/post-content": "after" + }, "textdomain": "activitypub", "editorScript": "file:./index.js", "style": [ "file:./style-index.css", "wp-components" ], From 18645253158afc8dbbcc09a8faae50d939de3756 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 15:24:20 -0600 Subject: [PATCH 16/47] Enable Likes and Reposts by default --- includes/constants.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/constants.php b/includes/constants.php index 6a2428f79..44abde3b5 100644 --- a/includes/constants.php +++ b/includes/constants.php @@ -18,8 +18,7 @@ \defined( 'ACTIVITYPUB_CUSTOM_POST_CONTENT' ) || \define( 'ACTIVITYPUB_CUSTOM_POST_CONTENT', "[ap_title type=\"html\"]\n\n[ap_content]\n\n[ap_hashtags]" ); \defined( 'ACTIVITYPUB_DISABLE_REWRITES' ) || \define( 'ACTIVITYPUB_DISABLE_REWRITES', false ); \defined( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS', false ); -// Disable reactions like `Like` and `Announce` by default. -\defined( 'ACTIVITYPUB_DISABLE_REACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_REACTIONS', true ); +\defined( 'ACTIVITYPUB_DISABLE_REACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_REACTIONS', false ); \defined( 'ACTIVITYPUB_DISABLE_OUTGOING_INTERACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_OUTGOING_INTERACTIONS', false ); \defined( 'ACTIVITYPUB_SHARED_INBOX_FEATURE' ) || \define( 'ACTIVITYPUB_SHARED_INBOX_FEATURE', false ); \defined( 'ACTIVITYPUB_SEND_VARY_HEADER' ) || \define( 'ACTIVITYPUB_SEND_VARY_HEADER', false ); From fb55c1f99f23c9128ff968f086e616f940190fc9 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 15:41:23 -0600 Subject: [PATCH 17/47] Use the comment registry for the reactions endpoint --- includes/class-comment.php | 2 + includes/rest/class-interaction.php | 70 +++++++++++++---------------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index c81e6d1ed..0e22ccd2f 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -617,6 +617,7 @@ public static function register_comment_types() { 'icon' => '♻️', 'class' => 'p-repost', 'type' => 'repost', + 'collection' => 'reposts', 'excerpt' => __( '… reposted this!', 'activitypub' ), ) ); @@ -630,6 +631,7 @@ public static function register_comment_types() { 'icon' => '👍', 'class' => 'p-like', 'type' => 'like', + 'collection' => 'likes', 'excerpt' => __( '… liked this!', 'activitypub' ), ) ); diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index f48aee6ed..a50ccd001 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -7,6 +7,7 @@ namespace Activitypub\Rest; +use Activitypub\Comment; use WP_REST_Response; use Activitypub\Http; @@ -133,58 +134,47 @@ public static function get( $request ) { } /** - * Get reactions (likes and reposts) for a post + * Get reactions for a post. * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response|WP_Error Response object or WP_Error. + * @param \WP_REST_Request $request The request. + * + * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure. */ public static function get_reactions( $request ) { $post_id = $request->get_param( 'id' ); - $post = get_post( $post_id ); - $likes = array(); - $reposts = array(); + $post = \get_post( $post_id ); if ( ! $post ) { - return new \WP_Error( - 'activitypub_post_not_found', - __( 'Post not found', 'activitypub' ), - array( 'status' => 404 ) - ); + return new \WP_Error( 'post_not_found', 'Post not found', array( 'status' => 404 ) ); } - $reactions = get_comments( - array( - 'post_id' => $post_id, - 'type__in' => array( 'like', 'repost' ), - 'status' => 'approve', - ) - ); + $reactions = array(); - $format_reaction = function ( $comment ) { - return array( - 'avatar' => get_comment_meta( $comment->comment_ID, 'avatar_url', true ), - 'url' => $comment->comment_author_url, - 'name' => $comment->comment_author, + foreach ( Comment::get_comment_types() as $type_object ) { + $comments = \get_comments( + array( + 'post_id' => $post_id, + 'type' => $type_object['type'], + 'status' => 'approve', + ) ); - }; - - foreach ( $reactions as $reaction ) { - switch ( $reaction->comment_type ) { - case 'like': - $likes[] = $format_reaction( $reaction ); - break; - case 'repost': - $reposts[] = $format_reaction( $reaction ); - break; + + if ( empty( $comments ) ) { + continue; } + + $reactions[ $type_object['collection'] ] = array_map( + function ( $comment ) { + return array( + 'name' => $comment->comment_author, + 'url' => $comment->comment_author_url, + 'avatar' => \get_comment_meta( $comment->comment_ID, 'avatar_url', true ), + ); + }, + $comments + ); } - return new WP_REST_Response( - array( - 'likes' => $likes, - 'reposts' => $reposts, - ), - 200 - ); + return new \WP_REST_Response( $reactions ); } } From c881b4d75529fb6ed72fa963ca35811107046326 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 15:48:01 -0600 Subject: [PATCH 18/47] lint --- includes/class-comment.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index c9bc227da..8e10fed43 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -641,30 +641,30 @@ public static function register_comment_types() { register_comment_type( 'repost', array( - 'label' => __( 'Reposts', 'activitypub' ), - 'singular' => __( 'Repost', 'activitypub' ), - 'description' => __( 'A repost on the indieweb is a post that is purely a 100% re-publication of another (typically someone else\'s) post.', 'activitypub' ), - 'icon' => '♻️', - 'class' => 'p-repost', - 'type' => 'repost', - 'collection' => 'reposts', - 'activity_types' => array( 'announce' ), - 'excerpt' => __( '… reposted this!', 'activitypub' ), + 'label' => __( 'Reposts', 'activitypub' ), + 'singular' => __( 'Repost', 'activitypub' ), + 'description' => __( 'A repost on the indieweb is a post that is purely a 100% re-publication of another (typically someone else\'s) post.', 'activitypub' ), + 'icon' => '♻️', + 'class' => 'p-repost', + 'type' => 'repost', + 'collection' => 'reposts', + 'activity_types' => array( 'announce' ), + 'excerpt' => __( '… reposted this!', 'activitypub' ), ) ); register_comment_type( 'like', array( - 'label' => __( 'Likes', 'activitypub' ), - 'singular' => __( 'Like', 'activitypub' ), - 'description' => __( 'A like is a popular webaction button and in some cases post type on various silos such as Facebook and Instagram.', 'activitypub' ), - 'icon' => '👍', - 'class' => 'p-like', - 'type' => 'like', - 'collection' => 'likes', - 'activity_types' => array( 'like' ), - 'excerpt' => __( '… liked this!', 'activitypub' ), + 'label' => __( 'Likes', 'activitypub' ), + 'singular' => __( 'Like', 'activitypub' ), + 'description' => __( 'A like is a popular webaction button and in some cases post type on various silos such as Facebook and Instagram.', 'activitypub' ), + 'icon' => '👍', + 'class' => 'p-like', + 'type' => 'like', + 'collection' => 'likes', + 'activity_types' => array( 'like' ), + 'excerpt' => __( '… liked this!', 'activitypub' ), ) ); } From e0a88217030b05a4aaf76d1012de03d1357bd630 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 16:40:27 -0600 Subject: [PATCH 19/47] changelog the reactions enabling --- CHANGELOG.md | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d955eaf1..99b800c84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Improved +* Likes and Reposts enabled by default * Email templates for Likes and Reposts * Improve Interactions moderation * Compatibility with Akismet diff --git a/readme.txt b/readme.txt index 4c51a65cb..addf202f6 100644 --- a/readme.txt +++ b/readme.txt @@ -134,6 +134,7 @@ For reasons of data protection, it is not possible to see the followers of other = Unreleased = +* Improved: Reactions (likes and reposts) now enabled by default * Added: Reactions block to display likes and reposts * Added: `icon` support for `Audio` and `Video` attachments * Added: Send "new follower" emails From c37516344ea74164ca837074d30396fbfddd98e3 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 16:41:02 -0600 Subject: [PATCH 20/47] Consume the REST API response without hardcoding keys --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- includes/class-comment.php | 4 ++ includes/rest/class-interaction.php | 32 ++++++++++---- src/reactions/reactions.js | 66 ++++++++++++----------------- 7 files changed, 58 insertions(+), 52 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 1bc51c552..9a3389674 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'cfc8249e527b0a048773'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '361ed83a718cba30cdcf'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 0f6603b0c..9f3e326e5 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,r)=>{const a=window.wp.blocks,n=window.React,i=window.wp.blockEditor,s=window.wp.element,l=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:p}=window._activityPubOptions,m=({reactions:e})=>(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),h=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),d=({reactions:e,type:t})=>{const[r,a]=(0,s.useState)(!1),[i,c]=(0,s.useState)(null),[u,p]=(0,s.useState)(e.length),d=(0,s.useRef)(null),f=e.length;(0,s.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const r=t.offsetWidth-(i?.offsetWidth||0)-12,a=Math.max(1,Math.floor((r-32)/22));p(Math.min(a,e.length))};t();const r=new ResizeObserver(t);return r.observe(d.current),()=>{r.disconnect()}}),[i,e.length]);const v=e.slice(0,u),E="likes"===t?(0,l._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,l._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,n.createElement)("div",{className:"reaction-group",ref:d},(0,n.createElement)(m,{reactions:v}),(0,n.createElement)(o.Button,{ref:c,className:"reaction-label is-link",onClick:()=>a(!r),"aria-expanded":r},(0,l.sprintf)(E,f)),r&&i&&(0,n.createElement)(o.Popover,{anchor:i,onClose:()=>a(!1)},(0,n.createElement)(h,{reactions:e,type:t})))};function f({title:e="",postId:t=null,isEditing:r=!1,setTitle:a=(()=>{}),reactions:o=null}){const[c,m]=(0,s.useState)(o),[h,f]=(0,s.useState)(!o);return(0,s.useEffect)((()=>{if(o)return m(o),void f(!1);t?(f(!0),u()({path:`/${p}/reactions/${t}`}).then((e=>{m(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),h?null:(0,n.createElement)("div",{className:"activitypub-reactions"},r?(0,n.createElement)(i.RichText,{tagName:"h4",value:e,onChange:a,placeholder:(0,l.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),c?.likes?.length>0&&(0,n.createElement)(d,{reactions:c.likes,type:"likes"}),c?.reposts?.length>0&&(0,n.createElement)(d,{reactions:c.reposts,type:"reposts"}))}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],a=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const i=n.getContext("2d");return i.fillStyle=a,i.beginPath(),i.arc(32,32,32,0,2*Math.PI),i.fill(),i.fillStyle="#FFFFFF",i.font="32px sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},E=JSON.parse('{"UU":"activitypub/reactions"}');(0,a.registerBlockType)(E.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const a=(0,i.useBlockProps)({className:r}),[l]=(0,s.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...a},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:l}))}})}},r={};function a(e){var n=r[e];if(void 0!==n)return n.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,a),i.exports}a.m=t,e=[],a.O=(t,r,n,i)=>{if(!r){var s=1/0;for(u=0;u=i)&&Object.keys(a.O).every((e=>a.O[e](r[o])))?r.splice(o--,1):(l=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,n,i]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};a.O.j=t=>0===e[t];var t=(t,r)=>{var n,i,[s,l,o]=r,c=0;if(s.some((t=>0!==e[t]))){for(n in l)a.o(l,n)&&(a.m[n]=l[n]);if(o)var u=o(a)}for(t&&t(r);ca(505)));n=a.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,l=window.wp.blockEditor,i=window.wp.element,s=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=a.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),d=({items:e,label:t})=>{const[a,r]=(0,i.useState)(!1),[l,s]=(0,i.useState)(null),[c,u]=(0,i.useState)(e.length),m=(0,i.useRef)(null);(0,i.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const a=t.offsetWidth-(l?.offsetWidth||0)-12,r=Math.max(1,Math.floor((a-32)/22));u(Math.min(r,e.length))};t();const a=new ResizeObserver(t);return a.observe(m.current),()=>{a.disconnect()}}),[l,e.length]);const d=e.slice(0,c);return(0,n.createElement)("div",{className:"reaction-group",ref:m},(0,n.createElement)(h,{reactions:d}),(0,n.createElement)(o.Button,{ref:s,className:"reaction-label is-link",onClick:()=>r(!a),"aria-expanded":a},t),a&&l&&(0,n.createElement)(o.Popover,{anchor:l,onClose:()=>r(!1)},(0,n.createElement)(p,{reactions:e})))};function f({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:o=null}){const[c,h]=(0,i.useState)(o),[p,f]=(0,i.useState)(!o);return(0,i.useEffect)((()=>{if(o)return h(o),void f(!1);t?(f(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(l.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,s.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,n.createElement)(d,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],r=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const l=n.getContext("2d");return l.fillStyle=r,l.beginPath(),l.arc(32,32,32,0,2*Math.PI),l.fill(),l.fillStyle="#FFFFFF",l.font="32px sans-serif",l.textAlign="center",l.textBaseline="middle",l.fillText(a,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},b=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(b.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:a}){const r=(0,l.useBlockProps)({className:a}),[s]=(0,i.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...r},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:s}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,r),l.exports}r.m=t,e=[],r.O=(t,a,n,l)=>{if(!a){var i=1/0;for(u=0;u=l)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(s=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[i,s,o]=a,c=0;if(i.some((t=>0!==e[t]))){for(n in s)r.o(s,n)&&(r.m[n]=s[n]);if(o)var u=o(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index de2d51b61..8c5d72b0b 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'fc37c3857994bda4badd'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '55a7acb63659b2551c80'); diff --git a/build/reactions/view.js b/build/reactions/view.js index b5938c629..96ac13a13 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const l=window.wp.blockEditor,c=window.wp.components,s=window.wp.apiFetch;var o=e.n(s);const i=window.wp.i18n,{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:a})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({reactions:e,type:n})=>{const[r,l]=(0,a.useState)(!1),[s,o]=(0,a.useState)(null),[m,d]=(0,a.useState)(e.length),h=(0,a.useRef)(null),f=e.length;(0,a.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const a=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((a-32)/22));d(Math.min(n,e.length))};t();const a=new ResizeObserver(t);return a.observe(h.current),()=>{a.disconnect()}}),[s,e.length]);const w=e.slice(0,m),E="likes"===n?(0,i._nx)("%d like","%d likes",f,"number of likes","activitypub"):(0,i._nx)("%d repost","%d reposts",f,"number of reposts","activitypub");return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(u,{reactions:w}),(0,t.createElement)(c.Button,{ref:o,className:"reaction-label is-link",onClick:()=>l(!r),"aria-expanded":r},(0,i.sprintf)(E,f)),r&&s&&(0,t.createElement)(c.Popover,{anchor:s,onClose:()=>l(!1)},(0,t.createElement)(p,{reactions:e,type:n})))};function h({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:s=null}){const[u,p]=(0,a.useState)(s),[h,f]=(0,a.useState)(!s);return(0,a.useEffect)((()=>{if(s)return p(s),void f(!1);n?(f(!0),o()({path:`/${m}/reactions/${n}`}).then((e=>{p(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[n,s]),h?null:(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(l.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),u?.likes?.length>0&&(0,t.createElement)(d,{reactions:u.likes,type:"likes"}),u?.reposts?.length>0&&(0,t.createElement)(d,{reactions:u.reposts,type:"reposts"}))}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(h,{...n}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const l=window.wp.blockEditor,c=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),d=({reactions:e,type:a})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),p=({items:e,label:n})=>{const[r,l]=(0,a.useState)(!1),[o,s]=(0,a.useState)(null),[i,m]=(0,a.useState)(e.length),p=(0,a.useRef)(null);(0,a.useEffect)((()=>{if(!p.current)return;const t=()=>{const t=p.current;if(!t)return;const a=t.offsetWidth-(o?.offsetWidth||0)-12,n=Math.max(1,Math.floor((a-32)/22));m(Math.min(n,e.length))};t();const a=new ResizeObserver(t);return a.observe(p.current),()=>{a.disconnect()}}),[o,e.length]);const h=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:p},(0,t.createElement)(u,{reactions:h}),(0,t.createElement)(c.Button,{ref:s,className:"reaction-label is-link",onClick:()=>l(!r),"aria-expanded":r},n),r&&o&&(0,t.createElement)(c.Popover,{anchor:o,onClose:()=>l(!1)},(0,t.createElement)(d,{reactions:e})))};function h({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:o=null}){const[u,d]=(0,a.useState)(o),[h,w]=(0,a.useState)(!o);return(0,a.useEffect)((()=>{if(o)return d(o),void w(!1);n?(w(!0),s()({path:`/${m}/reactions/${n}`}).then((e=>{d(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[n,o]),h?null:u&&Object.values(u).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(l.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(u).map((([e,a])=>a.items?.length?(0,t.createElement)(p,{key:e,items:a.items,label:a.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(h,{...n}))}))}))})(); \ No newline at end of file diff --git a/includes/class-comment.php b/includes/class-comment.php index 8e10fed43..bfcb552fd 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -650,6 +650,8 @@ public static function register_comment_types() { 'collection' => 'reposts', 'activity_types' => array( 'announce' ), 'excerpt' => __( '… reposted this!', 'activitypub' ), + 'count_single' => _x( '%d repost', 'number of reposts', 'activitypub' ), + 'count_plural' => _x( '%d reposts', 'number of reposts', 'activitypub' ), ) ); @@ -665,6 +667,8 @@ public static function register_comment_types() { 'collection' => 'likes', 'activity_types' => array( 'like' ), 'excerpt' => __( '… liked this!', 'activitypub' ), + 'count_single' => _x( '%d like', 'number of likes', 'activitypub' ), + 'count_plural' => _x( '%d likes', 'number of likes', 'activitypub' ), ) ); } diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index a50ccd001..982f76a5b 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -163,15 +163,29 @@ public static function get_reactions( $request ) { continue; } - $reactions[ $type_object['collection'] ] = array_map( - function ( $comment ) { - return array( - 'name' => $comment->comment_author, - 'url' => $comment->comment_author_url, - 'avatar' => \get_comment_meta( $comment->comment_ID, 'avatar_url', true ), - ); - }, - $comments + $count = count( $comments ); + $label = sprintf( + _n( + $type_object['count_single'], + $type_object['count_plural'], + $count, + 'activitypub' + ), + $count + ); + + $reactions[ $type_object['collection'] ] = array( + 'label' => $label, + 'items' => array_map( + function ( $comment ) { + return array( + 'name' => $comment->comment_author, + 'url' => $comment->comment_author_url, + 'avatar' => \get_comment_meta( $comment->comment_ID, 'avatar_url', true ), + ); + }, + $comments + ), ); } diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 9d56fd661..979b252c3 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -119,16 +119,15 @@ const ReactionList = ( { reactions, type } ) => ( * A component that renders a reaction group with facepile and dropdown. * * @param {Object} props Component props. - * @param {Array} props.reactions Array of reaction objects. - * @param {string} props.type Type of reaction (likes/reposts). + * @param {Array} props.items Array of reaction objects. + * @param {string} props.label Label for the reaction group. * @return {JSX.Element} The rendered component. */ -const ReactionGroup = ( { reactions, type } ) => { +const ReactionGroup = ( { items, label } ) => { const [ isOpen, setIsOpen ] = useState( false ); const [ buttonRef, setButtonRef ] = useState( null ); - const [ visibleCount, setVisibleCount ] = useState( reactions.length ); + const [ visibleCount, setVisibleCount ] = useState( items.length ); const containerRef = useRef( null ); - const count = reactions.length; // Constants for calculations const AVATAR_WIDTH = 32; // Width of each avatar @@ -156,7 +155,7 @@ const ReactionGroup = ( { reactions, type } ) => { const maxAvatars = Math.max( 1, Math.floor( ( availableWidth - AVATAR_WIDTH ) / EFFECTIVE_AVATAR_WIDTH ) ); // Ensure we don't show more than we have - setVisibleCount( Math.min( maxAvatars, reactions.length ) ); + setVisibleCount( Math.min( maxAvatars, items.length ) ); }; // Initial calculation @@ -169,43 +168,27 @@ const ReactionGroup = ( { reactions, type } ) => { return () => { resizeObserver.disconnect(); }; - }, [ buttonRef, reactions.length ] ); - - const visibleReactions = reactions.slice( 0, visibleCount ); + }, [ buttonRef, items.length ] ); - const label = type === 'likes' - ? _nx( - '%d like', - '%d likes', - count, - 'number of likes', - 'activitypub' - ) - : _nx( - '%d repost', - '%d reposts', - count, - 'number of reposts', - 'activitypub' - ); + const visibleItems = items.slice( 0, visibleCount ); return (
- + { isOpen && buttonRef && ( setIsOpen( false ) } > - + ) }
@@ -260,6 +243,11 @@ export function Reactions( { return null; } + // Return null if there are no reactions + if ( ! reactions || ! Object.values( reactions ).some( group => group.items?.length > 0 ) ) { + return null; + } + return (
{ isEditing ? ( @@ -275,19 +263,19 @@ export function Reactions( { title &&

{ title }

) } - { reactions?.likes?.length > 0 && ( - - ) } + { Object.entries( reactions ).map( ( [ key, group ] ) => { + if ( ! group.items?.length ) { + return null; + } - { reactions?.reposts?.length > 0 && ( - - ) } + return ( + + ); + } ) }
); } \ No newline at end of file From 1e8b785c71dd94b3f3d5d0143d1e027c1c336385 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Thu, 12 Dec 2024 16:51:54 -0600 Subject: [PATCH 21/47] phpcs appeasement --- includes/class-comment.php | 4 ++++ includes/rest/class-interaction.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/includes/class-comment.php b/includes/class-comment.php index bfcb552fd..2fb024f1e 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -650,7 +650,9 @@ public static function register_comment_types() { 'collection' => 'reposts', 'activity_types' => array( 'announce' ), 'excerpt' => __( '… reposted this!', 'activitypub' ), + /* translators: %d: Number of reposts */ 'count_single' => _x( '%d repost', 'number of reposts', 'activitypub' ), + /* translators: %d: Number of reposts */ 'count_plural' => _x( '%d reposts', 'number of reposts', 'activitypub' ), ) ); @@ -667,7 +669,9 @@ public static function register_comment_types() { 'collection' => 'likes', 'activity_types' => array( 'like' ), 'excerpt' => __( '… liked this!', 'activitypub' ), + /* translators: %d: Number of likes */ 'count_single' => _x( '%d like', 'number of likes', 'activitypub' ), + /* translators: %d: Number of likes */ 'count_plural' => _x( '%d likes', 'number of likes', 'activitypub' ), ) ); diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 982f76a5b..7b23ef09a 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -164,6 +164,7 @@ public static function get_reactions( $request ) { } $count = count( $comments ); + // phpcs:disable WordPress.WP.I18n $label = sprintf( _n( $type_object['count_single'], @@ -173,6 +174,7 @@ public static function get_reactions( $request ) { ), $count ); + // phpcs:enable WordPress.WP.I18n $reactions[ $type_object['collection'] ] = array( 'label' => $label, From 018d45dbc01cef1b49a40a746eb46c110763e7df Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 10:49:58 -0600 Subject: [PATCH 22/47] use `number_format_i18n` --- includes/rest/class-interaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 7b23ef09a..69900645d 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -172,7 +172,7 @@ public static function get_reactions( $request ) { $count, 'activitypub' ), - $count + number_format_i18n( $count ) ); // phpcs:enable WordPress.WP.I18n From 00271e37069db26b99905cd3c074b1512b86721e Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 13:24:20 -0600 Subject: [PATCH 23/47] =?UTF-8?q?animations!=20=F0=9F=8E=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- src/reactions/reactions.js | 98 ++++++++++++++++++++++------- src/reactions/style.scss | 40 ++++++------ 8 files changed, 104 insertions(+), 46 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 9a3389674..77953de0a 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '361ed83a718cba30cdcf'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '9510644ee73086cd687c'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 9f3e326e5..99a680968 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,l=window.wp.blockEditor,i=window.wp.element,s=window.wp.i18n,o=window.wp.components,c=window.wp.apiFetch;var u=a.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),p=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),d=({items:e,label:t})=>{const[a,r]=(0,i.useState)(!1),[l,s]=(0,i.useState)(null),[c,u]=(0,i.useState)(e.length),m=(0,i.useRef)(null);(0,i.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const a=t.offsetWidth-(l?.offsetWidth||0)-12,r=Math.max(1,Math.floor((a-32)/22));u(Math.min(r,e.length))};t();const a=new ResizeObserver(t);return a.observe(m.current),()=>{a.disconnect()}}),[l,e.length]);const d=e.slice(0,c);return(0,n.createElement)("div",{className:"reaction-group",ref:m},(0,n.createElement)(h,{reactions:d}),(0,n.createElement)(o.Button,{ref:s,className:"reaction-label is-link",onClick:()=>r(!a),"aria-expanded":a},t),a&&l&&(0,n.createElement)(o.Popover,{anchor:l,onClose:()=>r(!1)},(0,n.createElement)(p,{reactions:e})))};function f({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:o=null}){const[c,h]=(0,i.useState)(o),[p,f]=(0,i.useState)(!o);return(0,i.useEffect)((()=>{if(o)return h(o),void f(!1);t?(f(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),f(!1)})).catch((()=>f(!1)))):f(!1)}),[t,o]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(l.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,s.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,n.createElement)(d,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],r=t[Math.floor(Math.random()*t.length)],n=document.createElement("canvas");n.width=64,n.height=64;const l=n.getContext("2d");return l.fillStyle=r,l.beginPath(),l.arc(32,32,32,0,2*Math.PI),l.fill(),l.fillStyle="#FFFFFF",l.font="32px sans-serif",l.textAlign="center",l.textBaseline="middle",l.fillText(a,32,32),{name:`User ${e}`,url:"#",avatar:n.toDataURL()}},b=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(b.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:a}){const r=(0,l.useBlockProps)({className:a}),[s]=(0,i.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,n.createElement)("div",{...r},(0,n.createElement)(f,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:s}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,r),l.exports}r.m=t,e=[],r.O=(t,a,n,l)=>{if(!a){var i=1/0;for(u=0;u=l)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(s=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[i,s,o]=a,c=0;if(i.some((t=>0!==e[t]))){for(n in s)r.o(s,n)&&(r.m[n]=s[n]);if(o)var u=o(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,l=window.wp.blockEditor,s=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,s.useState)(new Set),n=(0,s.useRef)([]),l=()=>{n.current.forEach((e=>clearTimeout(e))),n.current=[]},o=(t,a)=>{l(),new Set;const s=e.length;for(let e=t;e{r((t=>{const r=new Set(t);return a?r.add(e):r.delete(e),r}))}),150*(e-t));n.current.push(l)}for(let e=t-1;e>=0;e--){const l=setTimeout((()=>{r((t=>{const r=new Set(t);return a?r.add(e):r.delete(e),r}))}),150*(t-e));n.current.push(l)}};return(0,s.useEffect)((()=>()=>l()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>o(r,!0),onMouseLeave:()=>o(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar"+(t.has(r)?" wave-active":""),width:"32",height:"32"}))))))},d=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,s.useState)(!1),[l,o]=(0,s.useState)(null),[c,u]=(0,s.useState)(e.length),m=(0,s.useRef)(null);(0,s.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(l?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[l,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&l&&(0,a.createElement)(i.Popover,{anchor:l,onClose:()=>n(!1)},(0,a.createElement)(d,{reactions:e})))};function p({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,s.useState)(i),[d,p]=(0,s.useState)(!i);return(0,s.useEffect)((()=>{if(i)return h(i),void p(!1);t?(p(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),p(!1)})).catch((()=>p(!1)))):p(!1)}),[t,i]),d?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(l.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const l=a.getContext("2d");return l.fillStyle=n,l.beginPath(),l.arc(32,32,32,0,2*Math.PI),l.fill(),l.fillStyle="#FFFFFF",l.font="32px sans-serif",l.textAlign="center",l.textBaseline="middle",l.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,l.useBlockProps)({className:r}),[o]=(0,s.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(p,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var l=r[e]={exports:{}};return t[e](l,l.exports,n),l.exports}n.m=t,e=[],n.O=(t,r,a,l)=>{if(!r){var s=1/0;for(u=0;u=l)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[r,a,l]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,l,[s,o,i]=r,c=0;if(s.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index 8d2820e25..dce527523 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform .3s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 3d799bf35..60b6d157e 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex:0 1 auto;list-style:none;margin:0;min-width:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;position:relative;transition:transform .2s ease;z-index:1}.activitypub-reactions .reaction-avatars li a:hover{transform:scale(1.5);z-index:2}.activitypub-reactions .reaction-avatar{border:1px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);display:block;height:32px;width:32px}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform .3s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 8c5d72b0b..62daddcdb 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '55a7acb63659b2551c80'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'cd004d38235169998861'); diff --git a/build/reactions/view.js b/build/reactions/view.js index 96ac13a13..cf19f92b1 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.domReady;var r=e.n(n);const l=window.wp.blockEditor,c=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:m}=window._activityPubOptions,u=({reactions:e})=>(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar",width:"32",height:"32"})))))),d=({reactions:e,type:a})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,a)=>(0,t.createElement)("li",{key:a},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),p=({items:e,label:n})=>{const[r,l]=(0,a.useState)(!1),[o,s]=(0,a.useState)(null),[i,m]=(0,a.useState)(e.length),p=(0,a.useRef)(null);(0,a.useEffect)((()=>{if(!p.current)return;const t=()=>{const t=p.current;if(!t)return;const a=t.offsetWidth-(o?.offsetWidth||0)-12,n=Math.max(1,Math.floor((a-32)/22));m(Math.min(n,e.length))};t();const a=new ResizeObserver(t);return a.observe(p.current),()=>{a.disconnect()}}),[o,e.length]);const h=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:p},(0,t.createElement)(u,{reactions:h}),(0,t.createElement)(c.Button,{ref:s,className:"reaction-label is-link",onClick:()=>l(!r),"aria-expanded":r},n),r&&o&&(0,t.createElement)(c.Popover,{anchor:o,onClose:()=>l(!1)},(0,t.createElement)(d,{reactions:e})))};function h({title:e="",postId:n=null,isEditing:r=!1,setTitle:c=(()=>{}),reactions:o=null}){const[u,d]=(0,a.useState)(o),[h,w]=(0,a.useState)(!o);return(0,a.useEffect)((()=>{if(o)return d(o),void w(!1);n?(w(!0),s()({path:`/${m}/reactions/${n}`}).then((e=>{d(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[n,o]),h?null:u&&Object.values(u).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(l.RichText,{tagName:"h4",value:e,onChange:c,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(u).map((([e,a])=>a.items?.length?(0,t.createElement)(p,{key:e,items:a.items,label:a.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const n=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,t.createElement)(h,{...n}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,l=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),c=(0,n.useRef)([]),l=()=>{c.current.forEach((e=>clearTimeout(e))),c.current=[]},o=(t,n)=>{l(),new Set;const a=e.length;for(let e=t;e{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a}))}),150*(e-t));c.current.push(a)}for(let e=t-1;e>=0;e--){const a=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a}))}),150*(t-e));c.current.push(a)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>o(n,!0),onMouseLeave:()=>o(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar"+(a.has(n)?" wave-active":""),width:"32",height:"32"}))))))},d=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),h=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[o,s]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),h=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const n=t.offsetWidth-(o?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(h.current),()=>{n.disconnect()}}),[o,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(l.Button,{ref:s,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&o&&(0,t.createElement)(l.Popover,{anchor:o,onClose:()=>c(!1)},(0,t.createElement)(d,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:l=(()=>{}),reactions:o=null}){const[m,d]=(0,n.useState)(o),[p,w]=(0,n.useState)(!o);return(0,n.useEffect)((()=>{if(o)return d(o),void w(!1);a?(w(!0),s()({path:`/${u}/reactions/${a}`}).then((e=>{d(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,o]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:l,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(h,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index 979b252c3..e28ad58f1 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -21,27 +21,83 @@ const { namespace } = window._activityPubOptions; * @param {Array} props.reactions Array of reaction objects. * @return {JSX.Element} The rendered component. */ -const FacepileRow = ( { reactions } ) => ( -
    - { reactions.map( ( reaction, index ) => ( -
  • - - { - -
  • - ) ) } -
-); +const FacepileRow = ( { reactions } ) => { + const [activeIndices, setActiveIndices] = useState(new Set()); + const timeoutRefs = useRef([]); + + const clearTimeouts = () => { + timeoutRefs.current.forEach(timeout => clearTimeout(timeout)); + timeoutRefs.current = []; + }; + + const startWave = (startIndex, isEntering) => { + clearTimeouts(); + const newIndices = new Set(); + const delay = 150; // 150ms between each avatar + const totalAvatars = reactions.length; + + // Spread the wave to the right + for (let i = startIndex; i < totalAvatars; i++) { + const timeout = setTimeout(() => { + setActiveIndices(current => { + const updated = new Set(current); + if (isEntering) { + updated.add(i); + } else { + updated.delete(i); + } + return updated; + }); + }, (i - startIndex) * delay); + timeoutRefs.current.push(timeout); + } + + // Spread the wave to the left + for (let i = startIndex - 1; i >= 0; i--) { + const timeout = setTimeout(() => { + setActiveIndices(current => { + const updated = new Set(current); + if (isEntering) { + updated.add(i); + } else { + updated.delete(i); + } + return updated; + }); + }, (startIndex - i) * delay); + timeoutRefs.current.push(timeout); + } + }; + + // Cleanup timeouts on unmount + useEffect(() => { + return () => clearTimeouts(); + }, []); + + return ( + + ); +}; /** * A component that renders a dropdown list of reactions. diff --git a/src/reactions/style.scss b/src/reactions/style.scss index 45ba44ff3..bf3ddd4a4 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -24,12 +24,11 @@ .reaction-avatars { display: flex; + flex-direction: row; align-items: center; + list-style: none; margin: 0; padding: 0; - list-style: none; - flex: 0 1 auto; - min-width: 0; li { margin: 0; @@ -42,25 +41,28 @@ a { display: block; - transition: transform 0.2s ease; - position: relative; - z-index: 1; - - &:hover { - z-index: 2; - transform: scale(1.5); - } + text-decoration: none; } } - } - .reaction-avatar { - border-radius: 50%; - border: 1px solid #fff; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - width: 32px; - height: 32px; - display: block; + .reaction-avatar { + width: 32px; + height: 32px; + border-radius: 50%; + border: 2px solid #fff; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + will-change: transform; + + &.wave-active { + transform: translateY(-16px); + } + + &:hover { + z-index: 1; + position: relative; + } + } } .reaction-label.components-button { From e3bb4381f8614e7b405f4d19367f210d6043ed5d Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 13:53:39 -0600 Subject: [PATCH 24/47] proper calling of new post route --- activitypub.php | 1 + build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- includes/rest/class-interaction.php | 77 ----------------- includes/rest/class-post.php | 110 ++++++++++++++++++++++++ src/reactions/reactions.js | 129 ++++++++++++++++++---------- src/reactions/style.scss | 10 ++- 11 files changed, 208 insertions(+), 131 deletions(-) create mode 100644 includes/rest/class-post.php diff --git a/activitypub.php b/activitypub.php index 6948febeb..22f3c00e2 100644 --- a/activitypub.php +++ b/activitypub.php @@ -49,6 +49,7 @@ function rest_init() { Rest\Server::init(); Rest\Collection::init(); Rest\Interaction::init(); + Rest\Post::init(); // Load NodeInfo endpoints only if blog is public. if ( is_blog_public() ) { diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 77953de0a..7e5b01411 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '9510644ee73086cd687c'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '55ab7d62d199fbe4d320'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 99a680968..116c26126 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,l=window.wp.blockEditor,s=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,s.useState)(new Set),n=(0,s.useRef)([]),l=()=>{n.current.forEach((e=>clearTimeout(e))),n.current=[]},o=(t,a)=>{l(),new Set;const s=e.length;for(let e=t;e{r((t=>{const r=new Set(t);return a?r.add(e):r.delete(e),r}))}),150*(e-t));n.current.push(l)}for(let e=t-1;e>=0;e--){const l=setTimeout((()=>{r((t=>{const r=new Set(t);return a?r.add(e):r.delete(e),r}))}),150*(t-e));n.current.push(l)}};return(0,s.useEffect)((()=>()=>l()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>o(r,!0),onMouseLeave:()=>o(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar"+(t.has(r)?" wave-active":""),width:"32",height:"32"}))))))},d=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,s.useState)(!1),[l,o]=(0,s.useState)(null),[c,u]=(0,s.useState)(e.length),m=(0,s.useRef)(null);(0,s.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(l?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[l,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&l&&(0,a.createElement)(i.Popover,{anchor:l,onClose:()=>n(!1)},(0,a.createElement)(d,{reactions:e})))};function p({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,s.useState)(i),[d,p]=(0,s.useState)(!i);return(0,s.useEffect)((()=>{if(i)return h(i),void p(!1);t?(p(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),p(!1)})).catch((()=>p(!1)))):p(!1)}),[t,i]),d?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(l.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const l=a.getContext("2d");return l.fillStyle=n,l.beginPath(),l.arc(32,32,32,0,2*Math.PI),l.fill(),l.fillStyle="#FFFFFF",l.font="32px sans-serif",l.textAlign="center",l.textBaseline="middle",l.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,l.useBlockProps)({className:r}),[o]=(0,s.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(p,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var l=r[e]={exports:{}};return t[e](l,l.exports,n),l.exports}n.m=t,e=[],n.O=(t,r,a,l)=>{if(!r){var s=1/0;for(u=0;u=l)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[r,a,l]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,l,[s,o,i]=r,c=0;if(s.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,s=window.wp.blockEditor,l=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,l.useState)(new Set),[n,s]=(0,l.useState)(new Map),o=(0,l.useRef)([]),i=()=>{o.current.forEach((e=>clearTimeout(e))),o.current=[]},c=(t,n)=>{i();const a=150,l=e.length;n&&s((e=>{const r=new Map(e);return r.set(t,"clockwise"),r}));const c=e=>{const i="right"===e,c=i?l-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const l=Math.abs(e-t),i=setTimeout((()=>{r((t=>{const r=new Set(t);return n?r.add(e):r.delete(e),r})),n&&e!==t&&s((t=>{const r=new Map(t),n=e-u,a=r.get(n);return r.set(e,"clockwise"===a?"counter":"clockwise"),r}))}),l*a);o.current.push(i)}};if(c("right"),c("left"),!n){const e=Math.max((l-t)*a,t*a),r=setTimeout((()=>{s(new Map)}),e+a);o.current.push(r)}};return(0,l.useEffect)((()=>()=>i()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>{const s=n.get(r),l=["reaction-avatar",t.has(r)?"wave-active":"",s?`rotate-${s}`:""].filter(Boolean).join(" ");return(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(r,!0),onMouseLeave:()=>c(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:l,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,l.useState)(!1),[s,o]=(0,l.useState)(null),[c,u]=(0,l.useState)(e.length),m=(0,l.useRef)(null);(0,l.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[s,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&s&&(0,a.createElement)(i.Popover,{anchor:s,onClose:()=>n(!1)},(0,a.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,l.useState)(i),[p,d]=(0,l.useState)(!i);return(0,l.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(s.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const s=a.getContext("2d");return s.fillStyle=n,s.beginPath(),s.arc(32,32,32,0,2*Math.PI),s.fill(),s.fillStyle="#FFFFFF",s.font="32px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,s.useBlockProps)({className:r}),[o]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,n),s.exports}n.m=t,e=[],n.O=(t,r,a,s)=>{if(!r){var l=1/0;for(u=0;u=s)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,s0&&e[u-1][2]>s;u--)e[u]=e[u-1];e[u]=[r,a,s]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,s,[l,o,i]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index dce527523..d97074430 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform .3s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 60b6d157e..4b3155706 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform .3s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 62daddcdb..7fa7e53da 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'cd004d38235169998861'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '29431b14122db1380a21'); diff --git a/build/reactions/view.js b/build/reactions/view.js index cf19f92b1..01ff8ca0b 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,l=window.wp.components,o=window.wp.apiFetch;var s=e.n(o);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),c=(0,n.useRef)([]),l=()=>{c.current.forEach((e=>clearTimeout(e))),c.current=[]},o=(t,n)=>{l(),new Set;const a=e.length;for(let e=t;e{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a}))}),150*(e-t));c.current.push(a)}for(let e=t-1;e>=0;e--){const a=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a}))}),150*(t-e));c.current.push(a)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>o(n,!0),onMouseLeave:()=>o(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:"reaction-avatar"+(a.has(n)?" wave-active":""),width:"32",height:"32"}))))))},d=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),h=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[o,s]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),h=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!h.current)return;const t=()=>{const t=h.current;if(!t)return;const n=t.offsetWidth-(o?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(h.current),()=>{n.disconnect()}}),[o,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:h},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(l.Button,{ref:s,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&o&&(0,t.createElement)(l.Popover,{anchor:o,onClose:()=>c(!1)},(0,t.createElement)(d,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:l=(()=>{}),reactions:o=null}){const[m,d]=(0,n.useState)(o),[p,w]=(0,n.useState)(!o);return(0,n.useEffect)((()=>{if(o)return d(o),void w(!1);a?(w(!0),s()({path:`/${u}/reactions/${a}`}).then((e=>{d(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,o]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:l,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(h,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,o=window.wp.components,s=window.wp.apiFetch;var l=e.n(s);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),[c,o]=(0,n.useState)(new Map),s=(0,n.useRef)([]),l=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},i=(t,n)=>{l();const a=150,c=e.length;n&&o((e=>{const n=new Map(e);return n.set(t,"clockwise"),n}));const i=e=>{const l="right"===e,i=l?c-1:0,u=l?1:-1;for(let e=l?t:t-1;l?e<=i:e>=i;e+=u){const c=Math.abs(e-t),l=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a})),n&&e!==t&&o((t=>{const n=new Map(t),a=e-u,r=n.get(a);return n.set(e,"clockwise"===r?"counter":"clockwise"),n}))}),c*a);s.current.push(l)}};if(i("right"),i("left"),!n){const e=Math.max((c-t)*a,t*a),n=setTimeout((()=>{o(new Map)}),e+a);s.current.push(n)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>{const r=c.get(n),o=["reaction-avatar",a.has(n)?"wave-active":"",r?`rotate-${r}`:""].filter(Boolean).join(" ");return(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>i(n,!0),onMouseLeave:()=>i(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},h=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[s,l]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),d=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const n=t.offsetWidth-(s?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(d.current),()=>{n.disconnect()}}),[s,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:d},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(o.Button,{ref:l,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&s&&(0,t.createElement)(o.Popover,{anchor:s,onClose:()=>c(!1)},(0,t.createElement)(h,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:o=(()=>{}),reactions:s=null}){const[m,h]=(0,n.useState)(s),[p,w]=(0,n.useState)(!s);return(0,n.useEffect)((()=>{if(s)return h(s),void w(!1);a?(w(!0),l()({path:`/${u}/reactions/${a}`}).then((e=>{h(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,s]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:o,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(d,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 69900645d..28a2ea9ac 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -44,22 +44,6 @@ public static function register_routes() { ), ) ); - - \register_rest_route( - ACTIVITYPUB_REST_NAMESPACE, - '/reactions/(?P\d+)', - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( self::class, 'get_reactions' ), - 'permission_callback' => '__return_true', - 'args' => array( - 'id' => array( - 'required' => true, - 'type' => 'integer', - ), - ), - ) - ); } /** @@ -132,65 +116,4 @@ public static function get( $request ) { ) ); } - - /** - * Get reactions for a post. - * - * @param \WP_REST_Request $request The request. - * - * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure. - */ - public static function get_reactions( $request ) { - $post_id = $request->get_param( 'id' ); - $post = \get_post( $post_id ); - - if ( ! $post ) { - return new \WP_Error( 'post_not_found', 'Post not found', array( 'status' => 404 ) ); - } - - $reactions = array(); - - foreach ( Comment::get_comment_types() as $type_object ) { - $comments = \get_comments( - array( - 'post_id' => $post_id, - 'type' => $type_object['type'], - 'status' => 'approve', - ) - ); - - if ( empty( $comments ) ) { - continue; - } - - $count = count( $comments ); - // phpcs:disable WordPress.WP.I18n - $label = sprintf( - _n( - $type_object['count_single'], - $type_object['count_plural'], - $count, - 'activitypub' - ), - number_format_i18n( $count ) - ); - // phpcs:enable WordPress.WP.I18n - - $reactions[ $type_object['collection'] ] = array( - 'label' => $label, - 'items' => array_map( - function ( $comment ) { - return array( - 'name' => $comment->comment_author, - 'url' => $comment->comment_author_url, - 'avatar' => \get_comment_meta( $comment->comment_ID, 'avatar_url', true ), - ); - }, - $comments - ), - ); - } - - return new \WP_REST_Response( $reactions ); - } } diff --git a/includes/rest/class-post.php b/includes/rest/class-post.php new file mode 100644 index 000000000..2ede92017 --- /dev/null +++ b/includes/rest/class-post.php @@ -0,0 +1,110 @@ +\d+)/reactions', + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( static::class, 'get_reactions' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'id' => array( + 'required' => true, + 'type' => 'integer', + ), + ), + ) + ); + } + + /** + * Get reactions for a post. + * + * @param \WP_REST_Request $request The request. + * + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + public static function get_reactions( $request ) { + $post_id = $request->get_param( 'id' ); + $post = get_post( $post_id ); + + if ( ! $post ) { + return new WP_Error( 'post_not_found', 'Post not found', array( 'status' => 404 ) ); + } + + $reactions = array(); + + foreach ( Comment::get_comment_types() as $type_object ) { + $comments = get_comments( + array( + 'post_id' => $post_id, + 'type' => $type_object['type'], + 'status' => 'approve', + ) + ); + + if ( empty( $comments ) ) { + continue; + } + + $count = count( $comments ); + // phpcs:disable WordPress.WP.I18n + $label = sprintf( + _n( + $type_object['count_single'], + $type_object['count_plural'], + $count, + 'activitypub' + ), + number_format_i18n( $count ) + ); + // phpcs:enable WordPress.WP.I18n + + $reactions[ $type_object['collection'] ] = array( + 'label' => $label, + 'items' => array_map( + function ( $comment ) { + return array( + 'name' => $comment->comment_author, + 'url' => $comment->comment_author_url, + 'avatar' => get_comment_meta( $comment->comment_ID, 'avatar_url', true ), + ); + }, + $comments + ), + ); + } + + return new WP_REST_Response( $reactions ); + } +} diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index e28ad58f1..dcf8ffdce 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -23,6 +23,7 @@ const { namespace } = window._activityPubOptions; */ const FacepileRow = ( { reactions } ) => { const [activeIndices, setActiveIndices] = useState(new Set()); + const [rotationStates, setRotationStates] = useState(new Map()); const timeoutRefs = useRef([]); const clearTimeouts = () => { @@ -32,39 +33,64 @@ const FacepileRow = ( { reactions } ) => { const startWave = (startIndex, isEntering) => { clearTimeouts(); - const newIndices = new Set(); const delay = 150; // 150ms between each avatar const totalAvatars = reactions.length; - // Spread the wave to the right - for (let i = startIndex; i < totalAvatars; i++) { - const timeout = setTimeout(() => { - setActiveIndices(current => { - const updated = new Set(current); - if (isEntering) { - updated.add(i); - } else { - updated.delete(i); - } - return updated; - }); - }, (i - startIndex) * delay); - timeoutRefs.current.push(timeout); + if (isEntering) { + setRotationStates(current => { + const updated = new Map(current); + updated.set(startIndex, 'clockwise'); + return updated; + }); } - // Spread the wave to the left - for (let i = startIndex - 1; i >= 0; i--) { - const timeout = setTimeout(() => { - setActiveIndices(current => { - const updated = new Set(current); - if (isEntering) { - updated.add(i); - } else { - updated.delete(i); + // Helper function to create wave in either direction + const createWave = (direction) => { + const isRightward = direction === 'right'; + const start = isRightward ? startIndex : startIndex - 1; + const end = isRightward ? totalAvatars - 1 : 0; + const step = isRightward ? 1 : -1; + + for (let i = start; isRightward ? i <= end : i >= end; i += step) { + const delayMultiplier = Math.abs(i - startIndex); + const timeout = setTimeout(() => { + setActiveIndices(current => { + const updated = new Set(current); + if (isEntering) { + updated.add(i); + } else { + updated.delete(i); + } + return updated; + }); + + if (isEntering && i !== startIndex) { + setRotationStates(current => { + const updated = new Map(current); + const neighborIndex = i - step; + const neighborRotation = updated.get(neighborIndex); + updated.set(i, neighborRotation === 'clockwise' ? 'counter' : 'clockwise'); + return updated; + }); } - return updated; - }); - }, (startIndex - i) * delay); + }, delayMultiplier * delay); + timeoutRefs.current.push(timeout); + } + }; + + // Create waves in both directions + createWave('right'); + createWave('left'); + + // Clear rotations when wave finishes retracting + if (!isEntering) { + const maxDelay = Math.max( + (totalAvatars - startIndex) * delay, + startIndex * delay + ); + const timeout = setTimeout(() => { + setRotationStates(new Map()); + }, maxDelay + delay); timeoutRefs.current.push(timeout); } }; @@ -76,25 +102,34 @@ const FacepileRow = ( { reactions } ) => { return ( ); }; @@ -286,7 +321,7 @@ export function Reactions( { setLoading( true ); apiFetch( { - path: `/${ namespace }/reactions/${ postId }`, + path: `/${ namespace }/posts/${ postId }/reactions`, } ) .then( ( response ) => { setReactions( response ); diff --git a/src/reactions/style.scss b/src/reactions/style.scss index bf3ddd4a4..b6c0343d5 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -51,11 +51,19 @@ border-radius: 50%; border: 2px solid #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); - transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + transition: transform 1s cubic-bezier(0.34, 1.56, 0.64, 1); will-change: transform; &.wave-active { transform: translateY(-16px); + + &.rotate-clockwise { + transform: translateY(-16px) rotate(360deg); + } + + &.rotate-counter { + transform: translateY(-16px) rotate(-360deg); + } } &:hover { From 9f4ff3f7fc803fe5906b1e2847e17af44fc7c403 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Fri, 13 Dec 2024 13:54:35 -0600 Subject: [PATCH 25/47] First pass at showing reactions in non-block themes Also adds a setting to disable reactions. --- activitypub.php | 1 + includes/class-blocks.php | 23 ++ .../class-federated-reactions-settings.php | 169 ++++++++++++++ ...lass-test-federated-reactions-settings.php | 218 ++++++++++++++++++ 4 files changed, 411 insertions(+) create mode 100644 includes/class-federated-reactions-settings.php create mode 100644 tests/includes/class-test-federated-reactions-settings.php diff --git a/activitypub.php b/activitypub.php index 6948febeb..2a6262bdd 100644 --- a/activitypub.php +++ b/activitypub.php @@ -64,6 +64,7 @@ function plugin_init() { \add_action( 'init', array( __NAMESPACE__ . '\Migration', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activitypub', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activity_Dispatcher', 'init' ) ); + \add_action( 'init', array( __NAMESPACE__ . '\Federated_Reactions_Settings', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Handler', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Admin', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Hashtag', 'init' ) ); diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 052d46459..7fe2577d4 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -27,6 +27,8 @@ public static function init() { // Add editor plugin. \add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) ); \add_action( 'init', array( self::class, 'register_postmeta' ), 11 ); + + \add_action( 'the_content', array( self::class, 'maybe_add_fediverse_reactions' ) ); } /** @@ -391,4 +393,25 @@ public static function render_follower( $follower ) { $external_svg ); } + + /** + * Add fediverse reactions to the content. + * + * @param string $content The post content. + * @return string The post content with fediverse reactions. + */ + public static function maybe_add_fediverse_reactions( $content ) { + if ( ! is_singular() || wp_is_block_theme() ) { + return $content; + } + + if ( ! Federated_Reactions_Settings::is_reactions_enabled() ) { + return $content; + } + + // Create a block instance for proper rendering. + $block_content = do_blocks( '' ); + + return $content . $block_content; + } } diff --git a/includes/class-federated-reactions-settings.php b/includes/class-federated-reactions-settings.php new file mode 100644 index 000000000..500584ede --- /dev/null +++ b/includes/class-federated-reactions-settings.php @@ -0,0 +1,169 @@ + true, + 'single' => true, + 'type' => 'string', + 'sanitize_callback' => function ( $value ) { + return in_array( $value, array( '0', '1' ), true ) ? $value : '1'; + }, + ) + ); + } + } + + /** + * Register settings. + */ + public static function register_settings() { + register_setting( + 'discussion', + 'activitypub_reactions_enabled', + array( + 'type' => 'boolean', + 'show_in_rest' => true, + 'default' => true, + ) + ); + + add_settings_field( + 'activitypub_reactions_enabled', + __( 'Federated Reactions', 'activitypub' ), + array( self::class, 'render_reactions_enabled_field' ), + 'discussion' + ); + } + + /** + * Render the reactions enabled field. + */ + public static function render_reactions_enabled_field() { + ?> +
+ + +

+ +

+
+ ID, 'activitypub_reactions_enabled', true ); + if ( '' === $value ) { + $value = get_option( 'activitypub_reactions_enabled', '1' ); + } + wp_nonce_field( 'activitypub_reactions_meta_box', 'activitypub_reactions_meta_box_nonce' ); + ?> + +

+ +

+ assertEquals( 11, has_action( 'init', array( Federated_Reactions_Settings::class, 'register_postmeta' ) ) ); + $this->assertEquals( 10, has_action( 'admin_init', array( Federated_Reactions_Settings::class, 'register_settings' ) ) ); + $this->assertEquals( 10, has_action( 'add_meta_boxes', array( Federated_Reactions_Settings::class, 'add_meta_box' ) ) ); + $this->assertEquals( 10, has_action( 'save_post', array( Federated_Reactions_Settings::class, 'meta_box_save' ) ) ); + } + + /** + * Test registration of post meta. + * + * @covers ::register_post_meta + */ + public function test_register_post_meta() { + Federated_Reactions_Settings::register_post_meta(); + + $post_type = 'post'; + $registered = get_registered_meta_keys( 'post', $post_type ); + + $this->assertArrayHasKey( 'activitypub_reactions_enabled', $registered ); + $this->assertTrue( $registered['activitypub_reactions_enabled']['show_in_rest'] ); + $this->assertTrue( $registered['activitypub_reactions_enabled']['single'] ); + $this->assertEquals( 'string', $registered['activitypub_reactions_enabled']['type'] ); + + // Test sanitize callback. + $sanitize_callback = $registered['activitypub_reactions_enabled']['sanitize_callback']; + $this->assertEquals( '1', $sanitize_callback( '1' ) ); + $this->assertEquals( '0', $sanitize_callback( '0' ) ); + $this->assertEquals( '1', $sanitize_callback( 'invalid' ) ); + } + + /** + * Test registration of settings. + * + * @covers ::register_settings + */ + public function test_register_settings() { + Federated_Reactions_Settings::register_settings(); + + $registered = get_registered_settings(); + $this->assertArrayHasKey( 'activitypub_reactions_enabled', $registered ); + $this->assertEquals( 'boolean', $registered['activitypub_reactions_enabled']['type'] ); + $this->assertTrue( $registered['activitypub_reactions_enabled']['show_in_rest'] ); + $this->assertTrue( $registered['activitypub_reactions_enabled']['default'] ); + } + + /** + * Test rendering of the settings field. + * + * @covers ::render_reactions_enabled_field + */ + public function test_render_reactions_enabled_field() { + // Test with default value. + update_option( 'activitypub_reactions_enabled', '1' ); + ob_start(); + Federated_Reactions_Settings::render_reactions_enabled_field(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); + $this->assertStringContainsString( 'value="1"', $output ); + $this->assertStringContainsString( 'checked=\'checked\'', $output ); + + // Test with disabled value. + update_option( 'activitypub_reactions_enabled', '0' ); + ob_start(); + Federated_Reactions_Settings::render_reactions_enabled_field(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); + $this->assertStringContainsString( 'value="1"', $output ); + $this->assertStringNotContainsString( 'checked=\'checked\'', $output ); + } + + /** + * Test adding meta box. + * + * @covers ::add_meta_box + */ + public function test_add_meta_box() { + global $wp_meta_boxes; + + Federated_Reactions_Settings::add_meta_box(); + + $this->assertArrayHasKey( 'post', $wp_meta_boxes ); + $this->assertArrayHasKey( 'side', $wp_meta_boxes['post'] ); + $this->assertArrayHasKey( 'default', $wp_meta_boxes['post']['side'] ); + $this->assertArrayHasKey( 'activitypub_reactions', $wp_meta_boxes['post']['side']['default'] ); + } + + /** + * Test rendering of meta box. + * + * @covers ::render_meta_box + */ + public function test_render_meta_box() { + $post = self::factory()->post->create_and_get(); + + // Test with default value (no meta set). + update_option( 'activitypub_reactions_enabled', '1' ); + ob_start(); + Federated_Reactions_Settings::render_meta_box( $post ); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); + $this->assertStringContainsString( 'value="1"', $output ); + $this->assertStringContainsString( 'checked=\'checked\'', $output ); + + // Test with meta value set. + update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); + ob_start(); + Federated_Reactions_Settings::render_meta_box( $post ); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); + $this->assertStringContainsString( 'value="1"', $output ); + $this->assertStringNotContainsString( 'checked=\'checked\'', $output ); + } + + /** + * Test saving meta box data. + * + * @covers ::meta_box_save + */ + public function test_meta_box_save() { + $post = self::factory()->post->create_and_get(); + $user_id = self::factory()->user->create( array( 'role' => 'administrator' ) ); + wp_set_current_user( $user_id ); + + // Test with missing nonce. + $_POST = array(); + Federated_Reactions_Settings::meta_box_save( $post->ID ); + $this->assertEmpty( get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); + + // Test with invalid nonce. + $_POST = array( + 'activitypub_reactions_meta_box_nonce' => 'invalid', + ); + Federated_Reactions_Settings::meta_box_save( $post->ID ); + $this->assertEmpty( get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); + + // Test with valid data - checkbox checked. + $_POST = array( + 'activitypub_reactions_meta_box_nonce' => wp_create_nonce( 'activitypub_reactions_meta_box' ), + 'activitypub_reactions_enabled' => '1', + ); + Federated_Reactions_Settings::meta_box_save( $post->ID ); + $this->assertEquals( '1', get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); + + // Test with valid data - checkbox unchecked. + $_POST = array( + 'activitypub_reactions_meta_box_nonce' => wp_create_nonce( 'activitypub_reactions_meta_box' ), + ); + Federated_Reactions_Settings::meta_box_save( $post->ID ); + $this->assertEquals( '0', get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); + } + + /** + * Test checking if reactions are enabled. + * + * @covers ::is_reactions_enabled + */ + public function test_is_reactions_enabled() { + $post = self::factory()->post->create_and_get(); + + // Test with default global setting. + update_option( 'activitypub_reactions_enabled', '1' ); + $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + + // Test with disabled global setting. + update_option( 'activitypub_reactions_enabled', '0' ); + $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + + // Test with post meta overriding global setting. + update_option( 'activitypub_reactions_enabled', '1' ); + update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); + $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + + update_option( 'activitypub_reactions_enabled', '0' ); + update_post_meta( $post->ID, 'activitypub_reactions_enabled', '1' ); + $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + } +} From 6fa685754d3e44879dd6b67634a95e66decd720d Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 14:17:03 -0600 Subject: [PATCH 26/47] built reactions --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 7e5b01411..a6edd481b 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '55ab7d62d199fbe4d320'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'f4c4522c7203fe3786f4'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 116c26126..392f88772 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,s=window.wp.blockEditor,l=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,l.useState)(new Set),[n,s]=(0,l.useState)(new Map),o=(0,l.useRef)([]),i=()=>{o.current.forEach((e=>clearTimeout(e))),o.current=[]},c=(t,n)=>{i();const a=150,l=e.length;n&&s((e=>{const r=new Map(e);return r.set(t,"clockwise"),r}));const c=e=>{const i="right"===e,c=i?l-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const l=Math.abs(e-t),i=setTimeout((()=>{r((t=>{const r=new Set(t);return n?r.add(e):r.delete(e),r})),n&&e!==t&&s((t=>{const r=new Map(t),n=e-u,a=r.get(n);return r.set(e,"clockwise"===a?"counter":"clockwise"),r}))}),l*a);o.current.push(i)}};if(c("right"),c("left"),!n){const e=Math.max((l-t)*a,t*a),r=setTimeout((()=>{s(new Map)}),e+a);o.current.push(r)}};return(0,l.useEffect)((()=>()=>i()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>{const s=n.get(r),l=["reaction-avatar",t.has(r)?"wave-active":"",s?`rotate-${s}`:""].filter(Boolean).join(" ");return(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(r,!0),onMouseLeave:()=>c(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:l,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,l.useState)(!1),[s,o]=(0,l.useState)(null),[c,u]=(0,l.useState)(e.length),m=(0,l.useRef)(null);(0,l.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[s,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&s&&(0,a.createElement)(i.Popover,{anchor:s,onClose:()=>n(!1)},(0,a.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,l.useState)(i),[p,d]=(0,l.useState)(!i);return(0,l.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/reactions/${t}`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(s.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const s=a.getContext("2d");return s.fillStyle=n,s.beginPath(),s.arc(32,32,32,0,2*Math.PI),s.fill(),s.fillStyle="#FFFFFF",s.font="32px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,s.useBlockProps)({className:r}),[o]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,n),s.exports}n.m=t,e=[],n.O=(t,r,a,s)=>{if(!r){var l=1/0;for(u=0;u=s)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,s0&&e[u-1][2]>s;u--)e[u]=e[u-1];e[u]=[r,a,s]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,s,[l,o,i]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,s=window.wp.blockEditor,l=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,l.useState)(new Set),[n,s]=(0,l.useState)(new Map),o=(0,l.useRef)([]),i=()=>{o.current.forEach((e=>clearTimeout(e))),o.current=[]},c=(t,n)=>{i();const a=150,l=e.length;n&&s((e=>{const r=new Map(e);return r.set(t,"clockwise"),r}));const c=e=>{const i="right"===e,c=i?l-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const l=Math.abs(e-t),i=setTimeout((()=>{r((t=>{const r=new Set(t);return n?r.add(e):r.delete(e),r})),n&&e!==t&&s((t=>{const r=new Map(t),n=e-u,a=r.get(n);return r.set(e,"clockwise"===a?"counter":"clockwise"),r}))}),l*a);o.current.push(i)}};if(c("right"),c("left"),!n){const e=Math.max((l-t)*a,t*a),r=setTimeout((()=>{s(new Map)}),e+a);o.current.push(r)}};return(0,l.useEffect)((()=>()=>i()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>{const s=n.get(r),l=["reaction-avatar",t.has(r)?"wave-active":"",s?`rotate-${s}`:""].filter(Boolean).join(" ");return(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(r,!0),onMouseLeave:()=>c(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:l,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,l.useState)(!1),[s,o]=(0,l.useState)(null),[c,u]=(0,l.useState)(e.length),m=(0,l.useRef)(null);(0,l.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[s,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&s&&(0,a.createElement)(i.Popover,{anchor:s,onClose:()=>n(!1)},(0,a.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,l.useState)(i),[p,d]=(0,l.useState)(!i);return(0,l.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/posts/${t}/reactions`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(s.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const s=a.getContext("2d");return s.fillStyle=n,s.beginPath(),s.arc(32,32,32,0,2*Math.PI),s.fill(),s.fillStyle="#FFFFFF",s.font="32px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,s.useBlockProps)({className:r}),[o]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,n),s.exports}n.m=t,e=[],n.O=(t,r,a,s)=>{if(!r){var l=1/0;for(u=0;u=s)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,s0&&e[u-1][2]>s;u--)e[u]=e[u-1];e[u]=[r,a,s]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,s,[l,o,i]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 7fa7e53da..257053d2b 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '29431b14122db1380a21'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '0e2791f56cd75776751b'); diff --git a/build/reactions/view.js b/build/reactions/view.js index 01ff8ca0b..e1ac209dd 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,o=window.wp.components,s=window.wp.apiFetch;var l=e.n(s);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),[c,o]=(0,n.useState)(new Map),s=(0,n.useRef)([]),l=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},i=(t,n)=>{l();const a=150,c=e.length;n&&o((e=>{const n=new Map(e);return n.set(t,"clockwise"),n}));const i=e=>{const l="right"===e,i=l?c-1:0,u=l?1:-1;for(let e=l?t:t-1;l?e<=i:e>=i;e+=u){const c=Math.abs(e-t),l=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a})),n&&e!==t&&o((t=>{const n=new Map(t),a=e-u,r=n.get(a);return n.set(e,"clockwise"===r?"counter":"clockwise"),n}))}),c*a);s.current.push(l)}};if(i("right"),i("left"),!n){const e=Math.max((c-t)*a,t*a),n=setTimeout((()=>{o(new Map)}),e+a);s.current.push(n)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>{const r=c.get(n),o=["reaction-avatar",a.has(n)?"wave-active":"",r?`rotate-${r}`:""].filter(Boolean).join(" ");return(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>i(n,!0),onMouseLeave:()=>i(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},h=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[s,l]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),d=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const n=t.offsetWidth-(s?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(d.current),()=>{n.disconnect()}}),[s,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:d},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(o.Button,{ref:l,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&s&&(0,t.createElement)(o.Popover,{anchor:s,onClose:()=>c(!1)},(0,t.createElement)(h,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:o=(()=>{}),reactions:s=null}){const[m,h]=(0,n.useState)(s),[p,w]=(0,n.useState)(!s);return(0,n.useEffect)((()=>{if(s)return h(s),void w(!1);a?(w(!0),l()({path:`/${u}/reactions/${a}`}).then((e=>{h(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,s]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:o,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(d,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,o=window.wp.components,s=window.wp.apiFetch;var l=e.n(s);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),[c,o]=(0,n.useState)(new Map),s=(0,n.useRef)([]),l=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},i=(t,n)=>{l();const a=150,c=e.length;n&&o((e=>{const n=new Map(e);return n.set(t,"clockwise"),n}));const i=e=>{const l="right"===e,i=l?c-1:0,u=l?1:-1;for(let e=l?t:t-1;l?e<=i:e>=i;e+=u){const c=Math.abs(e-t),l=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a})),n&&e!==t&&o((t=>{const n=new Map(t),a=e-u,r=n.get(a);return n.set(e,"clockwise"===r?"counter":"clockwise"),n}))}),c*a);s.current.push(l)}};if(i("right"),i("left"),!n){const e=Math.max((c-t)*a,t*a),n=setTimeout((()=>{o(new Map)}),e+a);s.current.push(n)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>{const r=c.get(n),o=["reaction-avatar",a.has(n)?"wave-active":"",r?`rotate-${r}`:""].filter(Boolean).join(" ");return(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>i(n,!0),onMouseLeave:()=>i(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},h=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[s,l]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),d=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const n=t.offsetWidth-(s?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(d.current),()=>{n.disconnect()}}),[s,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:d},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(o.Button,{ref:l,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&s&&(0,t.createElement)(o.Popover,{anchor:s,onClose:()=>c(!1)},(0,t.createElement)(h,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:o=(()=>{}),reactions:s=null}){const[m,h]=(0,n.useState)(s),[p,w]=(0,n.useState)(!s);return(0,n.useEffect)((()=>{if(s)return h(s),void w(!1);a?(w(!0),l()({path:`/${u}/posts/${a}/reactions`}).then((e=>{h(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,s]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:o,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(d,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file From 4f5b4d925fa5e6c24265a1214dd9ea38d62f6e15 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Fri, 13 Dec 2024 14:24:45 -0600 Subject: [PATCH 27/47] Use correct callback name when checking init. --- tests/includes/class-test-federated-reactions-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/includes/class-test-federated-reactions-settings.php b/tests/includes/class-test-federated-reactions-settings.php index 8687e2717..2e87890f5 100644 --- a/tests/includes/class-test-federated-reactions-settings.php +++ b/tests/includes/class-test-federated-reactions-settings.php @@ -32,7 +32,7 @@ public function tear_down() { * @covers ::init */ public function test_init() { - $this->assertEquals( 11, has_action( 'init', array( Federated_Reactions_Settings::class, 'register_postmeta' ) ) ); + $this->assertEquals( 11, has_action( 'init', array( Federated_Reactions_Settings::class, 'register_post_meta' ) ) ); $this->assertEquals( 10, has_action( 'admin_init', array( Federated_Reactions_Settings::class, 'register_settings' ) ) ); $this->assertEquals( 10, has_action( 'add_meta_boxes', array( Federated_Reactions_Settings::class, 'add_meta_box' ) ) ); $this->assertEquals( 10, has_action( 'save_post', array( Federated_Reactions_Settings::class, 'meta_box_save' ) ) ); From 9e7736a8b98abea938b0bb5ba0e4c970bd9dc872 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 14:25:09 -0600 Subject: [PATCH 28/47] only hook the_content in non-block theme context --- includes/class-blocks.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 7fe2577d4..e27d51e6c 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -27,8 +27,9 @@ public static function init() { // Add editor plugin. \add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) ); \add_action( 'init', array( self::class, 'register_postmeta' ), 11 ); - - \add_action( 'the_content', array( self::class, 'maybe_add_fediverse_reactions' ) ); + if ( ! \wp_is_block_theme() ) { + \add_action( 'the_content', array( self::class, 'maybe_add_fediverse_reactions' ) ); + } } /** @@ -401,7 +402,7 @@ public static function render_follower( $follower ) { * @return string The post content with fediverse reactions. */ public static function maybe_add_fediverse_reactions( $content ) { - if ( ! is_singular() || wp_is_block_theme() ) { + if ( ! is_singular() ) { return $content; } @@ -411,7 +412,6 @@ public static function maybe_add_fediverse_reactions( $content ) { // Create a block instance for proper rendering. $block_content = do_blocks( '' ); - return $content . $block_content; } } From c4a87a2e7c34096b1db5fef3fcbc9f9279f5f5e0 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 15:23:35 -0600 Subject: [PATCH 29/47] Fix editor, fix script data, improve styling --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- includes/class-blocks.php | 23 +++++----- src/reactions/edit.js | 68 +++++++++++++++++++++-------- src/reactions/style.scss | 14 +++--- 7 files changed, 71 insertions(+), 42 deletions(-) diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index a6edd481b..1376d4cb9 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'f4c4522c7203fe3786f4'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '1428460a7cd0bc1c8486'); diff --git a/build/reactions/index.js b/build/reactions/index.js index 392f88772..fc7abfed1 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,r)=>{const n=window.wp.blocks,a=window.React,s=window.wp.blockEditor,l=window.wp.element,o=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=r.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,r]=(0,l.useState)(new Set),[n,s]=(0,l.useState)(new Map),o=(0,l.useRef)([]),i=()=>{o.current.forEach((e=>clearTimeout(e))),o.current=[]},c=(t,n)=>{i();const a=150,l=e.length;n&&s((e=>{const r=new Map(e);return r.set(t,"clockwise"),r}));const c=e=>{const i="right"===e,c=i?l-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const l=Math.abs(e-t),i=setTimeout((()=>{r((t=>{const r=new Set(t);return n?r.add(e):r.delete(e),r})),n&&e!==t&&s((t=>{const r=new Map(t),n=e-u,a=r.get(n);return r.set(e,"clockwise"===a?"counter":"clockwise"),r}))}),l*a);o.current.push(i)}};if(c("right"),c("left"),!n){const e=Math.max((l-t)*a,t*a),r=setTimeout((()=>{s(new Map)}),e+a);o.current.push(r)}};return(0,l.useEffect)((()=>()=>i()),[]),(0,a.createElement)("ul",{className:"reaction-avatars"},e.map(((e,r)=>{const s=n.get(r),l=["reaction-avatar",t.has(r)?"wave-active":"",s?`rotate-${s}`:""].filter(Boolean).join(" ");return(0,a.createElement)("li",{key:r},(0,a.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(r,!0),onMouseLeave:()=>c(r,!1)},(0,a.createElement)("img",{src:e.avatar,alt:e.name,className:l,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,a.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,a.createElement)("li",{key:t},(0,a.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,a.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,a.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[r,n]=(0,l.useState)(!1),[s,o]=(0,l.useState)(null),[c,u]=(0,l.useState)(e.length),m=(0,l.useRef)(null);(0,l.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const r=t.offsetWidth-(s?.offsetWidth||0)-12,n=Math.max(1,Math.floor((r-32)/22));u(Math.min(n,e.length))};t();const r=new ResizeObserver(t);return r.observe(m.current),()=>{r.disconnect()}}),[s,e.length]);const f=e.slice(0,c);return(0,a.createElement)("div",{className:"reaction-group",ref:m},(0,a.createElement)(h,{reactions:f}),(0,a.createElement)(i.Button,{ref:o,className:"reaction-label is-link",onClick:()=>n(!r),"aria-expanded":r},t),r&&s&&(0,a.createElement)(i.Popover,{anchor:s,onClose:()=>n(!1)},(0,a.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:r=!1,setTitle:n=(()=>{}),reactions:i=null}){const[c,h]=(0,l.useState)(i),[p,d]=(0,l.useState)(!i);return(0,l.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/posts/${t}/reactions`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,a.createElement)("div",{className:"activitypub-reactions"},r?(0,a.createElement)(s.RichText,{tagName:"h4",value:e,onChange:n,placeholder:(0,o.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,a.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,a.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const v=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],r="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(26*Math.random())],n=t[Math.floor(Math.random()*t.length)],a=document.createElement("canvas");a.width=64,a.height=64;const s=a.getContext("2d");return s.fillStyle=n,s.beginPath(),s.arc(32,32,32,0,2*Math.PI),s.fill(),s.fillStyle="#FFFFFF",s.font="32px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillText(r,32,32),{name:`User ${e}`,url:"#",avatar:a.toDataURL()}},w=JSON.parse('{"UU":"activitypub/reactions"}');(0,n.registerBlockType)(w.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:r}){const n=(0,s.useBlockProps)({className:r}),[o]=(0,l.useState)({likes:Array.from({length:9},((e,t)=>v(t))),reposts:Array.from({length:6},((e,t)=>v(t+9)))});return(0,a.createElement)("div",{...n},(0,a.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:o}))}})}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,n),s.exports}n.m=t,e=[],n.O=(t,r,a,s)=>{if(!r){var l=1/0;for(u=0;u=s)&&Object.keys(n.O).every((e=>n.O[e](r[i])))?r.splice(i--,1):(o=!1,s0&&e[u-1][2]>s;u--)e[u]=e[u-1];e[u]=[r,a,s]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};n.O.j=t=>0===e[t];var t=(t,r)=>{var a,s,[l,o,i]=r,c=0;if(l.some((t=>0!==e[t]))){for(a in o)n.o(o,a)&&(n.m[a]=o[a]);if(i)var u=i(n)}for(t&&t(r);cn(505)));a=n.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,l=window.wp.blockEditor,o=window.wp.element,s=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=a.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,a]=(0,o.useState)(new Set),[r,l]=(0,o.useState)(new Map),s=(0,o.useRef)([]),i=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},c=(t,r)=>{i();const n=150,o=e.length;r&&l((e=>{const a=new Map(e);return a.set(t,"clockwise"),a}));const c=e=>{const i="right"===e,c=i?o-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const o=Math.abs(e-t),i=setTimeout((()=>{a((t=>{const a=new Set(t);return r?a.add(e):a.delete(e),a})),r&&e!==t&&l((t=>{const a=new Map(t),r=e-u,n=a.get(r);return a.set(e,"clockwise"===n?"counter":"clockwise"),a}))}),o*n);s.current.push(i)}};if(c("right"),c("left"),!r){const e=Math.max((o-t)*n,t*n),a=setTimeout((()=>{l(new Map)}),e+n);s.current.push(a)}};return(0,o.useEffect)((()=>()=>i()),[]),(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>{const l=r.get(a),o=["reaction-avatar",t.has(a)?"wave-active":"",l?`rotate-${l}`:""].filter(Boolean).join(" ");return(0,n.createElement)("li",{key:a},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(a,!0),onMouseLeave:()=>c(a,!1)},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[a,r]=(0,o.useState)(!1),[l,s]=(0,o.useState)(null),[c,u]=(0,o.useState)(e.length),m=(0,o.useRef)(null);(0,o.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const a=t.offsetWidth-(l?.offsetWidth||0)-12,r=Math.max(1,Math.floor((a-32)/22));u(Math.min(r,e.length))};t();const a=new ResizeObserver(t);return a.observe(m.current),()=>{a.disconnect()}}),[l,e.length]);const f=e.slice(0,c);return(0,n.createElement)("div",{className:"reaction-group",ref:m},(0,n.createElement)(h,{reactions:f}),(0,n.createElement)(i.Button,{ref:s,className:"reaction-label is-link",onClick:()=>r(!a),"aria-expanded":a},t),a&&l&&(0,n.createElement)(i.Popover,{anchor:l,onClose:()=>r(!1)},(0,n.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:i=null}){const[c,h]=(0,o.useState)(i),[p,d]=(0,o.useState)(!i);return(0,o.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/posts/${t}/reactions`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(l.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,s.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,n.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const g=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a=(()=>{const e=["Bouncy","Cosmic","Dancing","Fluffy","Giggly","Hoppy","Jazzy","Magical","Nifty","Perky","Quirky","Sparkly","Twirly","Wiggly","Zippy"],t=["Badger","Capybara","Dolphin","Echidna","Flamingo","Giraffe","Hedgehog","Iguana","Jellyfish","Koala","Lemur","Manatee","Narwhal","Octopus","Penguin"];return`${e[Math.floor(Math.random()*e.length)]} ${t[Math.floor(Math.random()*t.length)]}`})(),r=t[Math.floor(Math.random()*t.length)],n=a.charAt(0),l=document.createElement("canvas");l.width=64,l.height=64;const o=l.getContext("2d");return o.fillStyle=r,o.beginPath(),o.arc(32,32,32,0,2*Math.PI),o.fill(),o.fillStyle="#FFFFFF",o.font="32px sans-serif",o.textAlign="center",o.textBaseline="middle",o.fillText(n,32,32),{name:a,url:"#",avatar:l.toDataURL()}},v=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(v.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:a}){const r=(0,l.useBlockProps)({className:a}),[s]=(0,o.useState)({likes:{label:"9 likes",items:Array.from({length:9},((e,t)=>g()))},reposts:{label:"6 reposts",items:Array.from({length:6},((e,t)=>g()))}});return(0,n.createElement)("div",{...r},(0,n.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:s}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,r),l.exports}r.m=t,e=[],r.O=(t,a,n,l)=>{if(!a){var o=1/0;for(u=0;u=l)&&Object.keys(r.O).every((e=>r.O[e](a[i])))?a.splice(i--,1):(s=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[o,s,i]=a,c=0;if(o.some((t=>0!==e[t]))){for(n in s)r.o(s,n)&&(r.m[n]=s[n]);if(i)var u=i(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index d97074430..02df9d903 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 4b3155706..9f2923f62 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:2px solid #fff;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/includes/class-blocks.php b/includes/class-blocks.php index e27d51e6c..834b2d1cb 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -21,8 +21,8 @@ public static function init() { // This is already being called on the init hook, so just add it. self::register_blocks(); - \add_action( 'wp_enqueue_scripts', array( self::class, 'add_data' ) ); - \add_action( 'enqueue_block_editor_assets', array( self::class, 'add_data' ) ); + \add_action( 'wp_enqueue_scripts', array( self::class, 'inject_activitypub_options' ) ); + \add_action( 'admin_print_scripts', array( self::class, 'inject_activitypub_options' ) ); \add_action( 'load-post-new.php', array( self::class, 'handle_in_reply_to_get_param' ) ); // Add editor plugin. \add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) ); @@ -109,24 +109,21 @@ public static function handle_in_reply_to_get_param() { } /** - * Add data to the block editor. + * Output ActivityPub options as a script tag. */ - public static function add_data() { - $context = is_admin() ? 'editor' : 'view'; - $followers_handle = 'activitypub-followers-' . $context . '-script'; - $follow_me_handle = 'activitypub-follow-me-' . $context . '-script'; - $reactions_handle = 'activitypub-reactions-' . $context . '-script'; - $data = array( + public static function inject_activitypub_options() { + $data = array( 'namespace' => ACTIVITYPUB_REST_NAMESPACE, 'enabled' => array( 'site' => ! is_user_type_disabled( 'blog' ), 'users' => ! is_user_type_disabled( 'user' ), ), ); - $js = sprintf( 'var _activityPubOptions = %s;', wp_json_encode( $data ) ); - \wp_add_inline_script( $followers_handle, $js, 'before' ); - \wp_add_inline_script( $follow_me_handle, $js, 'before' ); - \wp_add_inline_script( $reactions_handle, $js, 'before' ); + + printf( + '', + wp_json_encode( $data ) + ); } /** diff --git a/src/reactions/edit.js b/src/reactions/edit.js index c7cd23405..28bf5631c 100644 --- a/src/reactions/edit.js +++ b/src/reactions/edit.js @@ -3,6 +3,29 @@ import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Reactions } from './reactions'; +/** + * Generate a whimsical name using an adjective and noun combination. + * + * @return {string} A whimsical name. + */ +const generateWhimsicalName = () => { + const adjectives = [ + 'Bouncy', 'Cosmic', 'Dancing', 'Fluffy', 'Giggly', + 'Hoppy', 'Jazzy', 'Magical', 'Nifty', 'Perky', + 'Quirky', 'Sparkly', 'Twirly', 'Wiggly', 'Zippy', + ]; + const nouns = [ + 'Badger', 'Capybara', 'Dolphin', 'Echidna', 'Flamingo', + 'Giraffe', 'Hedgehog', 'Iguana', 'Jellyfish', 'Koala', + 'Lemur', 'Manatee', 'Narwhal', 'Octopus', 'Penguin', + ]; + + const adjective = adjectives[Math.floor(Math.random() * adjectives.length)]; + const noun = nouns[Math.floor(Math.random() * nouns.length)]; + + return `${adjective} ${noun}`; +}; + /** * Generate a dummy reaction with a random letter and color. * @@ -10,31 +33,32 @@ import { Reactions } from './reactions'; * @return {Object} Reaction object. */ const generateDummyReaction = ( index ) => { - const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const colors = [ - '#FF6B6B', - '#4ECDC4', - '#45B7D1', - '#96CEB4', - '#FFEEAD', - '#D4A5A5', - '#9B59B6', - '#3498DB', - '#E67E22', + '#FF6B6B', // Coral + '#4ECDC4', // Turquoise + '#45B7D1', // Sky Blue + '#96CEB4', // Sage + '#FFEEAD', // Cream + '#D4A5A5', // Dusty Rose + '#9B59B6', // Purple + '#3498DB', // Blue + '#E67E22', // Orange ]; - const letter = letters[ Math.floor( Math.random() * letters.length ) ]; - const color = colors[ Math.floor( Math.random() * colors.length ) ]; + + const name = generateWhimsicalName(); + const color = colors[Math.floor(Math.random() * colors.length)]; + const letter = name.charAt(0); // Create a data URL for a colored circle with a letter. - const canvas = document.createElement( 'canvas' ); + const canvas = document.createElement('canvas'); canvas.width = 64; canvas.height = 64; - const ctx = canvas.getContext( '2d' ); + const ctx = canvas.getContext('2d'); // Draw colored circle. ctx.fillStyle = color; ctx.beginPath(); - ctx.arc( 32, 32, 32, 0, 2 * Math.PI ); + ctx.arc(32, 32, 32, 0, 2 * Math.PI); ctx.fill(); // Draw letter. @@ -42,10 +66,10 @@ const generateDummyReaction = ( index ) => { ctx.font = '32px sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - ctx.fillText( letter, 32, 32 ); + ctx.fillText(letter, 32, 32); return { - name: `User ${ index }`, + name, url: '#', avatar: canvas.toDataURL(), }; @@ -57,8 +81,14 @@ const generateDummyReaction = ( index ) => { * @return {Object} Reactions data. */ const generateDummyReactions = () => ( { - likes: Array.from( { length: 9 }, ( _, i ) => generateDummyReaction( i ) ), - reposts: Array.from( { length: 6 }, ( _, i ) => generateDummyReaction( i + 9 ) ), + likes: { + label: '9 likes', + items: Array.from( { length: 9 }, ( _, i ) => generateDummyReaction( i ) ), + }, + reposts: { + label: '6 reposts', + items: Array.from( { length: 6 }, ( _, i ) => generateDummyReaction( i + 9 ) ), + }, } ); /** diff --git a/src/reactions/style.scss b/src/reactions/style.scss index b6c0343d5..203df2c99 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -1,5 +1,5 @@ .activitypub-reactions { - h4 { + h6 { border-top: 1px solid; display: inline-block; padding-top: .5em; @@ -49,20 +49,22 @@ width: 32px; height: 32px; border-radius: 50%; - border: 2px solid #fff; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + border: 0.5px solid rgba(255, 255, 255, 0.8); + box-shadow: + 0 0 0 0.5px rgba(255, 255, 255, 0.8), // Crisp white border + 0 1px 3px rgba(0, 0, 0, 0.2); // Soft drop shadow transition: transform 1s cubic-bezier(0.34, 1.56, 0.64, 1); will-change: transform; &.wave-active { - transform: translateY(-16px); + transform: translateY(-16px) scale(1.2); &.rotate-clockwise { - transform: translateY(-16px) rotate(360deg); + transform: translateY(-16px) scale(1.2) rotate(360deg); } &.rotate-counter { - transform: translateY(-16px) rotate(-360deg); + transform: translateY(-16px) scale(1.2) rotate(-360deg); } } From a8488f4a27f2df04cadf8b5ce2d509cad3589a5a Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 16:27:55 -0600 Subject: [PATCH 30/47] Reactions disabling fit n finish --- build/editor-plugin/plugin.asset.php | 2 +- build/editor-plugin/plugin.js | 2 +- includes/class-blocks.php | 21 ++++-- .../class-federated-reactions-settings.php | 64 ------------------- src/editor-plugin/plugin.js | 15 ++++- 5 files changed, 31 insertions(+), 73 deletions(-) diff --git a/build/editor-plugin/plugin.asset.php b/build/editor-plugin/plugin.asset.php index 578ae55f6..f105a081d 100644 --- a/build/editor-plugin/plugin.asset.php +++ b/build/editor-plugin/plugin.asset.php @@ -1 +1 @@ - array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '4d5e9ed82e8448bb4fd1'); + array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'df17f53a1f77c7270fc9'); diff --git a/build/editor-plugin/plugin.js b/build/editor-plugin/plugin.js index f5d718aa7..c9476416e 100644 --- a/build/editor-plugin/plugin.js +++ b/build/editor-plugin/plugin.js @@ -1 +1 @@ -(()=>{"use strict";var e={20:(e,t,i)=>{var n=i(609),r=Symbol.for("react.element"),o=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,i){var n,c={},s=null,p=null;for(n in void 0!==i&&(s=""+i),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(p=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(c[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===c[n]&&(c[n]=t[n]);return{$$typeof:r,type:e,key:s,ref:p,props:c,_owner:a.current}}},848:(e,t,i)=>{e.exports=i(20)},609:e=>{e.exports=window.React}},t={};function i(n){var r=t[n];if(void 0!==r)return r.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,i),o.exports}var n=i(609);const r=window.wp.editor,o=window.wp.plugins,a=window.wp.components,l=window.wp.element,c=(0,l.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,l.cloneElement)(e,{width:t,height:t,...i,ref:n})})),s=window.wp.primitives;var p=i(848);const u=(0,p.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(s.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})}),v=(0,p.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(s.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),w=(0,p.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(s.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"})}),d=(0,p.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(s.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),h=window.wp.data,_=window.wp.coreData,y=window.wp.url,b=window.wp.i18n;(0,o.registerPlugin)("activitypub-editor-plugin",{render:()=>{const e=(0,h.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[t,i]=(0,_.useEntityProp)("postType",e,"meta"),o={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},l=(e,t)=>(0,n.createElement)(a.__experimentalText,{style:o},(0,n.createElement)(c,{icon:t}),e);return"wp_block"===e?null:(0,n.createElement)(r.PluginDocumentSettingPanel,{name:"activitypub",title:(0,b.__)("⁂ Fediverse","activitypub")},(0,n.createElement)(a.TextControl,{label:(0,b.__)("Content Warning","activitypub"),value:t?.activitypub_content_warning,onChange:e=>{i({...t,activitypub_content_warning:e})},placeholder:(0,b.__)("Optional content warning","activitypub"),help:(0,b.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,n.createElement)(a.RadioControl,{label:(0,b.__)("Visibility","activitypub"),help:(0,b.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:t?.activitypub_content_visibility||"public",options:[{label:l((0,b.__)("Public","activitypub"),u),value:"public"},{label:l((0,b.__)("Quiet public","activitypub"),v),value:"quiet_public"},{label:l((0,b.__)("Do not federate","activitypub"),w),value:"local"}],onChange:e=>{i({...t,activitypub_content_visibility:e})},className:"activitypub-visibility"}))}}),(0,o.registerPlugin)("activitypub-editor-preview",{render:()=>{const e=(0,h.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,n.createElement)(n.Fragment,null,r.PluginPreviewMenuItem?(0,n.createElement)(r.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,h.select)("core/editor").getEditedPostPreviewLink(),t=(0,y.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:d,disabled:"auto-draft"===e},(0,b.__)("⁂ Fediverse preview","activitypub")):null)}})})(); \ No newline at end of file +(()=>{"use strict";var e={20:(e,t,i)=>{var n=i(609),r=Symbol.for("react.element"),o=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,i){var n,c={},s=null,p=null;for(n in void 0!==i&&(s=""+i),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(p=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(c[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===c[n]&&(c[n]=t[n]);return{$$typeof:r,type:e,key:s,ref:p,props:c,_owner:a.current}}},848:(e,t,i)=>{e.exports=i(20)},609:e=>{e.exports=window.React}},t={};function i(n){var r=t[n];if(void 0!==r)return r.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,i),o.exports}(()=>{var e=i(609);const t=window.wp.editor,n=window.wp.plugins,r=window.wp.components,o=window.wp.element,a=(0,o.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,o.cloneElement)(e,{width:t,height:t,...i,ref:n})})),l=window.wp.primitives;var c=i(848);const s=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})}),p=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),u=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"})}),v=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),d=window.wp.data,w=window.wp.coreData,h=window.wp.url,_=window.wp.i18n;(0,n.registerPlugin)("activitypub-editor-plugin",{render:()=>{const i=(0,d.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[n,o]=(0,w.useEntityProp)("postType",i,"meta"),l={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},c=(t,i)=>(0,e.createElement)(r.__experimentalText,{style:l},(0,e.createElement)(a,{icon:i}),t);if("wp_block"===i)return null;const v="0"!==n?.activitypub_reactions_enabled;return(0,e.createElement)(t.PluginDocumentSettingPanel,{name:"activitypub",title:(0,_.__)("⁂ Fediverse","activitypub")},(0,e.createElement)(r.TextControl,{label:(0,_.__)("Content Warning","activitypub"),value:n?.activitypub_content_warning,onChange:e=>{o({...n,activitypub_content_warning:e})},placeholder:(0,_.__)("Optional content warning","activitypub"),help:(0,_.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,e.createElement)(r.RadioControl,{label:(0,_.__)("Visibility","activitypub"),help:(0,_.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:n?.activitypub_content_visibility||"public",options:[{label:c((0,_.__)("Public","activitypub"),s),value:"public"},{label:c((0,_.__)("Quiet public","activitypub"),p),value:"quiet_public"},{label:c((0,_.__)("Do not federate","activitypub"),u),value:"local"}],onChange:e=>{o({...n,activitypub_content_visibility:e})},className:"activitypub-visibility"}),(0,e.createElement)("br",null),(0,e.createElement)(r.CheckboxControl,{label:(0,_.__)("Show federated reactions","activitypub"),checked:v,onChange:e=>{o({...n,activitypub_reactions_enabled:e?"1":"0"})},help:(0,_.__)("When disabled, federated reactions will be hidden for this post.","activitypub")}))}}),(0,n.registerPlugin)("activitypub-editor-preview",{render:()=>{const i=(0,d.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,e.createElement)(e.Fragment,null,t.PluginPreviewMenuItem?(0,e.createElement)(t.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,d.select)("core/editor").getEditedPostPreviewLink(),t=(0,h.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:v,disabled:"auto-draft"===i},(0,_.__)("⁂ Fediverse preview","activitypub")):null)}})})()})(); \ No newline at end of file diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 834b2d1cb..f9a66eb9a 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -148,12 +148,16 @@ public static function register_blocks() { 'render_callback' => array( self::class, 'render_reply_block' ), ) ); - \register_block_type_from_metadata( - ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', - array( - 'render_callback' => array( self::class, 'render_post_reactions_block' ), - ) - ); + + // Only register reactions block if globally enabled + if ( get_option( 'activitypub_reactions_enabled', '1' ) === '1' ) { + \register_block_type_from_metadata( + ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', + array( + 'render_callback' => array( self::class, 'render_post_reactions_block' ), + ) + ); + } } /** @@ -164,6 +168,11 @@ public static function register_blocks() { * @return string The HTML to render. */ public static function render_post_reactions_block( $attrs ) { + // Check if reactions are enabled, generally, or for the current post. + if ( ! Federated_Reactions_Settings::is_reactions_enabled() ) { + return ''; + } + if ( ! isset( $attrs['postId'] ) ) { $attrs['postId'] = get_the_ID(); } diff --git a/includes/class-federated-reactions-settings.php b/includes/class-federated-reactions-settings.php index 500584ede..7832f0ebe 100644 --- a/includes/class-federated-reactions-settings.php +++ b/includes/class-federated-reactions-settings.php @@ -18,8 +18,6 @@ class Federated_Reactions_Settings { public static function init() { add_action( 'init', array( self::class, 'register_post_meta' ), 11 ); add_action( 'admin_init', array( self::class, 'register_settings' ) ); - add_action( 'add_meta_boxes', array( self::class, 'add_meta_box' ) ); - add_action( 'save_post', array( self::class, 'meta_box_save' ) ); } /** @@ -83,68 +81,6 @@ public static function render_reactions_enabled_field() { ID, 'activitypub_reactions_enabled', true ); - if ( '' === $value ) { - $value = get_option( 'activitypub_reactions_enabled', '1' ); - } - wp_nonce_field( 'activitypub_reactions_meta_box', 'activitypub_reactions_meta_box_nonce' ); - ?> - -

- -

- { return null; } + // Default to enabled if not set + const isReactionsEnabled = meta?.activitypub_reactions_enabled !== '0'; + return ( { placeholder={ __( 'Optional content warning', 'activitypub' ) } help={ __( 'Content warnings do not change the content on your site, only in the fediverse.', 'activitypub' ) } /> + { } } className="activitypub-visibility" /> +
+ { + setMeta( { ...meta, activitypub_reactions_enabled: checked ? '1' : '0' } ); + } } + help={ __( 'When disabled, federated reactions will be hidden for this post.', 'activitypub' ) } + />
); } From 5f48511f7cd26b88bf8d0ba445cd9c2cbd703f72 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 16:34:28 -0600 Subject: [PATCH 31/47] fix tests --- build/follow-me/index.asset.php | 2 +- build/follow-me/index.js | 4 +- build/follow-me/view.asset.php | 2 +- build/follow-me/view.js | 2 +- build/followers/index.asset.php | 2 +- build/followers/index.js | 6 +- build/followers/view.asset.php | 2 +- build/followers/view.js | 6 +- build/reactions/style-index-rtl.css | 2 +- build/reactions/style-index.css | 2 +- build/remote-reply/index.asset.php | 2 +- build/remote-reply/index.js | 2 +- build/reply/index.asset.php | 2 +- build/reply/index.js | 2 +- ...lass-test-federated-reactions-settings.php | 96 +------------------ 15 files changed, 22 insertions(+), 112 deletions(-) diff --git a/build/follow-me/index.asset.php b/build/follow-me/index.asset.php index d5face1ed..8b64aac5f 100644 --- a/build/follow-me/index.asset.php +++ b/build/follow-me/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '62610556ba8e5f129fdf'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '9ba472502cdfebc07309'); diff --git a/build/follow-me/index.js b/build/follow-me/index.js index cd4eff04e..82c4f1fe4 100644 --- a/build/follow-me/index.js +++ b/build/follow-me/index.js @@ -1,2 +1,2 @@ -(()=>{"use strict";var e,t={399:(e,t,r)=>{const o=window.wp.blocks,n=window.wp.primitives;var i=r(848);const a=(0,i.jsx)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(n.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})});var l=r(609);const c=window.wp.blockEditor,s=window.wp.i18n,u=window.wp.data,p=window.wp.coreData,d=window.wp.components,m=window.wp.element,v=window._activityPubOptions?.enabled,f=window.wp.apiFetch;var y=r.n(f);function b(e){return`var(--wp--preset--color--${e})`}function _(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return b(t)}function w(e,t,r=null,o=""){return r?`${e}${o} { ${t}: ${r}; }\n`:""}function h(e,t,r,o){return w(e,"background-color",t)+w(e,"color",r)+w(e,"background-color",o,":hover")+w(e,"background-color",o,":focus")}function g({selector:e,style:t,backgroundColor:r}){const o=function(e,t,r){const o=`${e} .components-button`,n=("string"==typeof(i=r)?b(i):i?.color?.background||null)||t?.color?.background;var i;return h(o,_(t?.elements?.link?.color?.text),n,_(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,r);return(0,l.createElement)("style",null,o)}const E=(0,i.jsx)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(n.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),k=(0,i.jsx)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(n.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),x=(0,m.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,m.cloneElement)(e,{width:t,height:t,...r,ref:o})})),S=window.wp.compose,O="fediverse-remote-user";function C(e){try{return new URL(e),!0}catch(e){return!1}}function N({actionText:e,copyDescription:t,handle:r,resourceUrl:o,myProfile:n=!1,rememberProfile:i=!1}){const c=(0,s.__)("Loading...","activitypub"),u=(0,s.__)("Opening...","activitypub"),p=(0,s.__)("Error","activitypub"),v=(0,s.__)("Invalid","activitypub"),f=n||(0,s.__)("My Profile","activitypub"),[b,_]=(0,m.useState)(e),[w,h]=(0,m.useState)(E),g=(0,S.useCopyToClipboard)(r,(()=>{h(k),setTimeout((()=>h(E)),1e3)})),[N,I]=(0,m.useState)(""),[R,U]=(0,m.useState)(!0),{setRemoteUser:P}=function(){const[e,t]=(0,m.useState)(function(){const e=localStorage.getItem(O);return e?JSON.parse(e):{}}()),r=(0,m.useCallback)((e=>{!function(e){localStorage.setItem(O,JSON.stringify(e))}(e),t(e)}),[]),o=(0,m.useCallback)((()=>{localStorage.removeItem(O),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}(),$=(0,m.useCallback)((()=>{let t;if(!C(N)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&C(`https://${t[1]}`)}(N))return _(v),t=setTimeout((()=>_(e)),2e3),()=>clearTimeout(t);const r=o+N;_(c),y()({path:r}).then((({url:t,template:r})=>{R&&P({profileURL:N,template:r}),_(u),setTimeout((()=>{window.open(t,"_blank"),_(e)}),200)})).catch((()=>{_(p),setTimeout((()=>_(e)),2e3)}))}),[N]);return(0,l.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,l.createElement)("div",{className:"activitypub-dialog__section"},(0,l.createElement)("h4",{id:"dialog-title"},f),(0,l.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,l.createElement)("div",{className:"activitypub-dialog__button-group"},(0,l.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,l.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,l.createElement)(d.Button,{ref:g,"aria-label":(0,s.__)("Copy handle to clipboard","activitypub")},(0,l.createElement)(x,{icon:w}),(0,s.__)("Copy","activitypub")))),(0,l.createElement)("div",{className:"activitypub-dialog__section"},(0,l.createElement)("h4",{id:"remote-profile-title"},(0,s.__)("Your Profile","activitypub")),(0,l.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,m.createInterpolateElement)((0,s.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,l.createElement)("code",null)})),(0,l.createElement)("div",{className:"activitypub-dialog__button-group"},(0,l.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,s.__)("Enter your ActivityPub profile","activitypub")),(0,l.createElement)("input",{type:"text",id:"remote-profile",value:N,onKeyDown:e=>{"Enter"===e?.code&&$()},onChange:e=>I(e.target.value),"aria-invalid":b===v}),(0,l.createElement)(d.Button,{onClick:$,"aria-label":(0,s.__)("Submit profile","activitypub")},(0,l.createElement)(x,{icon:a}),b)),i&&(0,l.createElement)("div",{className:"activitypub-dialog__remember"},(0,l.createElement)(d.CheckboxControl,{checked:R,label:(0,s.__)("Remember me for easier comments","activitypub"),onChange:()=>{U(!R)}}))))}const{namespace:I}=window._activityPubOptions,R={avatar:"",webfinger:"@well@hello.dolly",name:(0,s.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function U(e){if(!e)return R;const t={...R,...e};return t.avatar=t?.icon?.url,t}function P({profile:e,popupStyles:t,userId:r}){const{webfinger:o,avatar:n,name:i}=e,a=o.startsWith("@")?o:`@${o}`;return(0,l.createElement)("div",{className:"activitypub-profile"},(0,l.createElement)("img",{className:"activitypub-profile__avatar",src:n,alt:i}),(0,l.createElement)("div",{className:"activitypub-profile__content"},(0,l.createElement)("div",{className:"activitypub-profile__name"},i),(0,l.createElement)("div",{className:"activitypub-profile__handle",title:a},a)),(0,l.createElement)($,{profile:e,popupStyles:t,userId:r}))}function $({profile:e,popupStyles:t,userId:r}){const[o,n]=(0,m.useState)(!1),i=(0,s.sprintf)((0,s.__)("Follow %s","activitypub"),e?.name);return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(d.Button,{className:"activitypub-profile__follow",onClick:()=>n(!0),"aria-haspopup":"dialog","aria-expanded":o,"aria-label":(0,s.__)("Follow me on the Fediverse","activitypub")},(0,s.__)("Follow","activitypub")),o&&(0,l.createElement)(d.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>n(!1),title:i,"aria-label":i,role:"dialog"},(0,l.createElement)(T,{profile:e,userId:r}),(0,l.createElement)("style",null,t)))}function T({profile:e,userId:t}){const{webfinger:r}=e,o=(0,s.__)("Follow","activitypub"),n=`/${I}/actors/${t}/remote-follow?resource=`,i=(0,s.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub"),a=r.startsWith("@")?r:`@${r}`;return(0,l.createElement)(N,{actionText:o,copyDescription:i,handle:a,resourceUrl:n})}function j({selectedUser:e,style:t,backgroundColor:r,id:o,useId:n=!1,profileData:i=!1}){const[a,c]=(0,m.useState)(U()),s="site"===e?0:e,u=function(e){return h(".apfmd__button-group .components-button",_(e?.elements?.link?.color?.text)||"#111","#fff",_(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),p=n?{id:o}:{};function d(e){c(U(e))}return(0,m.useEffect)((()=>{if(i)return d(i);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${I}/actors/${e}`};return y()(t)})(s).then(d)}),[s,i]),(0,l.createElement)("div",{...p},(0,l.createElement)(g,{selector:`#${o}`,style:t,backgroundColor:r}),(0,l.createElement)(P,{profile:a,userId:s,popupStyles:u}))}const F=window._activityPubOptions?.enabled;function B({name:e}){const t=F?.site?"":(0,s.__)("It will be empty in other non-author contexts.","activitypub"),r=(0,s.sprintf)(/* translators: %1$s: block name, %2$s: extra information for non-author context */ /* translators: %1$s: block name, %2$s: extra information for non-author context */ -(0,s.__)("This %1$s block will adapt to the page it is on, displaying the user profile associated with a post author (in a loop) or a user archive. %2$s","activitypub"),e,t).trim();return(0,l.createElement)(d.Card,null,(0,l.createElement)(d.CardBody,null,(0,m.createInterpolateElement)(r,{strong:(0,l.createElement)("strong",null)})))}(0,o.registerBlockType)("activitypub/follow-me",{edit:function({attributes:e,setAttributes:t,context:{postType:r,postId:o}}){const n=(0,c.useBlockProps)({className:"activitypub-follow-me-block-wrapper"}),i=function({withInherit:e=!1}){const t=v?.users?(0,u.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,m.useMemo)((()=>{if(!t)return[];const r=[];return v?.site&&r.push({label:(0,s.__)("Site","activitypub"),value:"site"}),e&&v?.users&&r.push({label:(0,s.__)("Dynamic User","activitypub"),value:"inherit"}),t.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),r)}),[t])}({withInherit:!0}),{selectedUser:a}=e,f="inherit"===a,y=(0,u.useSelect)((e=>{const{getEditedEntityRecord:t}=e(p.store),n=t("postType",r,o)?.author;return null!=n?n:null}),[r,o]);return(0,m.useEffect)((()=>{i.length&&(i.find((({value:e})=>e===a))||t({selectedUser:i[0].value}))}),[a,i]),(0,l.createElement)("div",{...n},i.length>1&&(0,l.createElement)(c.InspectorControls,{key:"setting"},(0,l.createElement)(d.PanelBody,{title:(0,s.__)("Followers Options","activitypub")},(0,l.createElement)(d.SelectControl,{label:(0,s.__)("Select User","activitypub"),value:e.selectedUser,options:i,onChange:e=>t({selectedUser:e})}))),f?y?(0,l.createElement)(j,{...e,id:n.id,selectedUser:y}):(0,l.createElement)(B,{name:(0,s.__)("Follow Me","activitypub")}):(0,l.createElement)(j,{...e,id:n.id}))},save:()=>null,icon:a})},20:(e,t,r)=>{var o=r(609),n=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,u=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:n,type:e,key:s,ref:u,props:c,_owner:a.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var n=r[e];if(void 0!==n)return n.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,o),i.exports}o.m=t,e=[],o.O=(t,r,n,i)=>{if(!r){var a=1/0;for(u=0;u=i)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,n,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={338:0,301:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var n,i,a=r[0],l=r[1],c=r[2],s=0;if(a.some((t=>0!==e[t]))){for(n in l)o.o(l,n)&&(o.m[n]=l[n]);if(c)var u=c(o)}for(t&&t(r);so(399)));n=o.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={399:(e,t,r)=>{const o=window.wp.blocks,i=window.wp.primitives;var n=r(848);const a=(0,n.jsx)(i.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,n.jsx)(i.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})});var l=r(609);const c=window.wp.blockEditor,s=window.wp.i18n,u=window.wp.data,p=window.wp.coreData,d=window.wp.components,m=window.wp.element,v=window._activityPubOptions?.enabled,f=window.wp.apiFetch;var b=r.n(f);function y(e){return`var(--wp--preset--color--${e})`}function _(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return y(t)}function h(e,t,r=null,o=""){return r?`${e}${o} { ${t}: ${r}; }\n`:""}function w(e,t,r,o){return h(e,"background-color",t)+h(e,"color",r)+h(e,"background-color",o,":hover")+h(e,"background-color",o,":focus")}function g({selector:e,style:t,backgroundColor:r}){const o=function(e,t,r){const o=`${e} .components-button`,i=("string"==typeof(n=r)?y(n):n?.color?.background||null)||t?.color?.background;var n;return w(o,_(t?.elements?.link?.color?.text),i,_(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,r);return(0,l.createElement)("style",null,o)}const E=(0,n.jsx)(i.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,n.jsx)(i.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),k=(0,n.jsx)(i.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,n.jsx)(i.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),x=(0,m.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,m.cloneElement)(e,{width:t,height:t,...r,ref:o})})),S=window.wp.compose,O="fediverse-remote-user";function C(e){try{return new URL(e),!0}catch(e){return!1}}function N({actionText:e,copyDescription:t,handle:r,resourceUrl:o,myProfile:i=!1,rememberProfile:n=!1}){const c=(0,s.__)("Loading...","activitypub"),u=(0,s.__)("Opening...","activitypub"),p=(0,s.__)("Error","activitypub"),v=(0,s.__)("Invalid","activitypub"),f=i||(0,s.__)("My Profile","activitypub"),[y,_]=(0,m.useState)(e),[h,w]=(0,m.useState)(E),g=(0,S.useCopyToClipboard)(r,(()=>{w(k),setTimeout((()=>w(E)),1e3)})),[N,I]=(0,m.useState)(""),[R,U]=(0,m.useState)(!0),{setRemoteUser:P}=function(){const[e,t]=(0,m.useState)(function(){const e=localStorage.getItem(O);return e?JSON.parse(e):{}}()),r=(0,m.useCallback)((e=>{!function(e){localStorage.setItem(O,JSON.stringify(e))}(e),t(e)}),[]),o=(0,m.useCallback)((()=>{localStorage.removeItem(O),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}(),$=(0,m.useCallback)((()=>{let t;if(!C(N)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&C(`https://${t[1]}`)}(N))return _(v),t=setTimeout((()=>_(e)),2e3),()=>clearTimeout(t);const r=o+N;_(c),b()({path:r}).then((({url:t,template:r})=>{R&&P({profileURL:N,template:r}),_(u),setTimeout((()=>{window.open(t,"_blank"),_(e)}),200)})).catch((()=>{_(p),setTimeout((()=>_(e)),2e3)}))}),[N]);return(0,l.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,l.createElement)("div",{className:"activitypub-dialog__section"},(0,l.createElement)("h4",{id:"dialog-title"},f),(0,l.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,l.createElement)("div",{className:"activitypub-dialog__button-group"},(0,l.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,l.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,l.createElement)(d.Button,{ref:g,"aria-label":(0,s.__)("Copy handle to clipboard","activitypub")},(0,l.createElement)(x,{icon:h}),(0,s.__)("Copy","activitypub")))),(0,l.createElement)("div",{className:"activitypub-dialog__section"},(0,l.createElement)("h4",{id:"remote-profile-title"},(0,s.__)("Your Profile","activitypub")),(0,l.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,m.createInterpolateElement)((0,s.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,l.createElement)("code",null)})),(0,l.createElement)("div",{className:"activitypub-dialog__button-group"},(0,l.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,s.__)("Enter your ActivityPub profile","activitypub")),(0,l.createElement)("input",{type:"text",id:"remote-profile",value:N,onKeyDown:e=>{"Enter"===e?.code&&$()},onChange:e=>I(e.target.value),"aria-invalid":y===v}),(0,l.createElement)(d.Button,{onClick:$,"aria-label":(0,s.__)("Submit profile","activitypub")},(0,l.createElement)(x,{icon:a}),y)),n&&(0,l.createElement)("div",{className:"activitypub-dialog__remember"},(0,l.createElement)(d.CheckboxControl,{checked:R,label:(0,s.__)("Remember me for easier comments","activitypub"),onChange:()=>{U(!R)}}))))}const{namespace:I}=window._activityPubOptions,R={avatar:"",webfinger:"@well@hello.dolly",name:(0,s.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function U(e){if(!e)return R;const t={...R,...e};return t.avatar=t?.icon?.url,t}function P({profile:e,popupStyles:t,userId:r}){const{webfinger:o,avatar:i,name:n}=e,a=o.startsWith("@")?o:`@${o}`;return(0,l.createElement)("div",{className:"activitypub-profile"},(0,l.createElement)("img",{className:"activitypub-profile__avatar",src:i,alt:n}),(0,l.createElement)("div",{className:"activitypub-profile__content"},(0,l.createElement)("div",{className:"activitypub-profile__name"},n),(0,l.createElement)("div",{className:"activitypub-profile__handle",title:a},a)),(0,l.createElement)($,{profile:e,popupStyles:t,userId:r}))}function $({profile:e,popupStyles:t,userId:r}){const[o,i]=(0,m.useState)(!1),n=(0,s.sprintf)((0,s.__)("Follow %s","activitypub"),e?.name);return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(d.Button,{className:"activitypub-profile__follow",onClick:()=>i(!0),"aria-haspopup":"dialog","aria-expanded":o,"aria-label":(0,s.__)("Follow me on the Fediverse","activitypub")},(0,s.__)("Follow","activitypub")),o&&(0,l.createElement)(d.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>i(!1),title:n,"aria-label":n,role:"dialog"},(0,l.createElement)(T,{profile:e,userId:r}),(0,l.createElement)("style",null,t)))}function T({profile:e,userId:t}){const{webfinger:r}=e,o=(0,s.__)("Follow","activitypub"),i=`/${I}/actors/${t}/remote-follow?resource=`,n=(0,s.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub"),a=r.startsWith("@")?r:`@${r}`;return(0,l.createElement)(N,{actionText:o,copyDescription:n,handle:a,resourceUrl:i})}function j({selectedUser:e,style:t,backgroundColor:r,id:o,useId:i=!1,profileData:n=!1}){const[a,c]=(0,m.useState)(U()),s="site"===e?0:e,u=function(e){return w(".apfmd__button-group .components-button",_(e?.elements?.link?.color?.text)||"#111","#fff",_(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),p=i?{id:o}:{};function d(e){c(U(e))}return(0,m.useEffect)((()=>{if(n)return d(n);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${I}/actors/${e}`};return b()(t)})(s).then(d)}),[s,n]),(0,l.createElement)("div",{...p},(0,l.createElement)(g,{selector:`#${o}`,style:t,backgroundColor:r}),(0,l.createElement)(P,{profile:a,userId:s,popupStyles:u}))}const F=window._activityPubOptions?.enabled;function B({name:e}){const t=F?.site?"":(0,s.__)("It will be empty in other non-author contexts.","activitypub"),r=(0,s.sprintf)(/* translators: %1$s: block name, %2$s: extra information for non-author context */ /* translators: %1$s: block name, %2$s: extra information for non-author context */ +(0,s.__)("This %1$s block will adapt to the page it is on, displaying the user profile associated with a post author (in a loop) or a user archive. %2$s","activitypub"),e,t).trim();return(0,l.createElement)(d.Card,null,(0,l.createElement)(d.CardBody,null,(0,m.createInterpolateElement)(r,{strong:(0,l.createElement)("strong",null)})))}(0,o.registerBlockType)("activitypub/follow-me",{edit:function({attributes:e,setAttributes:t,context:{postType:r,postId:o}}){const i=(0,c.useBlockProps)({className:"activitypub-follow-me-block-wrapper"}),n=function({withInherit:e=!1}){const t=v?.users?(0,u.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,m.useMemo)((()=>{if(!t)return[];const r=[];return v?.site&&r.push({label:(0,s.__)("Site","activitypub"),value:"site"}),e&&v?.users&&r.push({label:(0,s.__)("Dynamic User","activitypub"),value:"inherit"}),t.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),r)}),[t])}({withInherit:!0}),{selectedUser:a}=e,f="inherit"===a,b=(0,u.useSelect)((e=>{const{getEditedEntityRecord:t}=e(p.store),i=t("postType",r,o)?.author;return null!=i?i:null}),[r,o]);return(0,m.useEffect)((()=>{n.length&&(n.find((({value:e})=>e===a))||t({selectedUser:n[0].value}))}),[a,n]),(0,l.createElement)("div",{...i},n.length>1&&(0,l.createElement)(c.InspectorControls,{key:"setting"},(0,l.createElement)(d.PanelBody,{title:(0,s.__)("Followers Options","activitypub")},(0,l.createElement)(d.SelectControl,{label:(0,s.__)("Select User","activitypub"),value:e.selectedUser,options:n,onChange:e=>t({selectedUser:e})}))),f?b?(0,l.createElement)(j,{...e,id:i.id,selectedUser:b}):(0,l.createElement)(B,{name:(0,s.__)("Follow Me","activitypub")}):(0,l.createElement)(j,{...e,id:i.id}))},save:()=>null,icon:a})},20:(e,t,r)=>{var o=r(609),i=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,u=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(u=t.ref),t)n.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:i,type:e,key:s,ref:u,props:c,_owner:a.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var i=r[e];if(void 0!==i)return i.exports;var n=r[e]={exports:{}};return t[e](n,n.exports,o),n.exports}o.m=t,e=[],o.O=(t,r,i,n)=>{if(!r){var a=1/0;for(u=0;u=n)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,n0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[r,i,n]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={338:0,301:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var i,n,[a,l,c]=r,s=0;if(a.some((t=>0!==e[t]))){for(i in l)o.o(l,i)&&(o.m[i]=l[i]);if(c)var u=c(o)}for(t&&t(r);so(399)));i=o.O(i)})(); \ No newline at end of file diff --git a/build/follow-me/view.asset.php b/build/follow-me/view.asset.php index 5068f4ba1..6d6b7da86 100644 --- a/build/follow-me/view.asset.php +++ b/build/follow-me/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '8008189b4c59111938ec'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'e8c42d9f4e0a51441bdc'); diff --git a/build/follow-me/view.js b/build/follow-me/view.js index 72946cd37..98c3baf5a 100644 --- a/build/follow-me/view.js +++ b/build/follow-me/view.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={729:(e,t,r)=>{var o=r(609);const a=window.wp.element,n=window.wp.domReady;var i=r.n(n);const l=window.wp.apiFetch;var c=r.n(l);const s=window.wp.components,u=window.wp.i18n;function p(e){return`var(--wp--preset--color--${e})`}function d(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return p(t)}function m(e,t,r=null,o=""){return r?`${e}${o} { ${t}: ${r}; }\n`:""}function v(e,t,r,o){return m(e,"background-color",t)+m(e,"color",r)+m(e,"background-color",o,":hover")+m(e,"background-color",o,":focus")}function f({selector:e,style:t,backgroundColor:r}){const a=function(e,t,r){const o=`${e} .components-button`,a=("string"==typeof(n=r)?p(n):n?.color?.background||null)||t?.color?.background;var n;return v(o,d(t?.elements?.link?.color?.text),a,d(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,r);return(0,o.createElement)("style",null,a)}const y=window.wp.primitives;var b=r(848);const _=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),w=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),h=(0,a.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,a.cloneElement)(e,{width:t,height:t,...r,ref:o})})),g=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),E=window.wp.compose,k="fediverse-remote-user";function x(e){try{return new URL(e),!0}catch(e){return!1}}function S({actionText:e,copyDescription:t,handle:r,resourceUrl:n,myProfile:i=!1,rememberProfile:l=!1}){const p=(0,u.__)("Loading...","activitypub"),d=(0,u.__)("Opening...","activitypub"),m=(0,u.__)("Error","activitypub"),v=(0,u.__)("Invalid","activitypub"),f=i||(0,u.__)("My Profile","activitypub"),[y,b]=(0,a.useState)(e),[S,O]=(0,a.useState)(_),N=(0,E.useCopyToClipboard)(r,(()=>{O(w),setTimeout((()=>O(_)),1e3)})),[C,R]=(0,a.useState)(""),[I,$]=(0,a.useState)(!0),{setRemoteUser:P}=function(){const[e,t]=(0,a.useState)(function(){const e=localStorage.getItem(k);return e?JSON.parse(e):{}}()),r=(0,a.useCallback)((e=>{!function(e){localStorage.setItem(k,JSON.stringify(e))}(e),t(e)}),[]),o=(0,a.useCallback)((()=>{localStorage.removeItem(k),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}(),j=(0,a.useCallback)((()=>{let t;if(!x(C)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&x(`https://${t[1]}`)}(C))return b(v),t=setTimeout((()=>b(e)),2e3),()=>clearTimeout(t);const r=n+C;b(p),c()({path:r}).then((({url:t,template:r})=>{I&&P({profileURL:C,template:r}),b(d),setTimeout((()=>{window.open(t,"_blank"),b(e)}),200)})).catch((()=>{b(m),setTimeout((()=>b(e)),2e3)}))}),[C]);return(0,o.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"dialog-title"},f),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,o.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,o.createElement)(s.Button,{ref:N,"aria-label":(0,u.__)("Copy handle to clipboard","activitypub")},(0,o.createElement)(h,{icon:S}),(0,u.__)("Copy","activitypub")))),(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"remote-profile-title"},(0,u.__)("Your Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,a.createInterpolateElement)((0,u.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,o.createElement)("code",null)})),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,u.__)("Enter your ActivityPub profile","activitypub")),(0,o.createElement)("input",{type:"text",id:"remote-profile",value:C,onKeyDown:e=>{"Enter"===e?.code&&j()},onChange:e=>R(e.target.value),"aria-invalid":y===v}),(0,o.createElement)(s.Button,{onClick:j,"aria-label":(0,u.__)("Submit profile","activitypub")},(0,o.createElement)(h,{icon:g}),y)),l&&(0,o.createElement)("div",{className:"activitypub-dialog__remember"},(0,o.createElement)(s.CheckboxControl,{checked:I,label:(0,u.__)("Remember me for easier comments","activitypub"),onChange:()=>{$(!I)}}))))}const{namespace:O}=window._activityPubOptions,N={avatar:"",webfinger:"@well@hello.dolly",name:(0,u.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function C(e){if(!e)return N;const t={...N,...e};return t.avatar=t?.icon?.url,t}function R({profile:e,popupStyles:t,userId:r}){const{webfinger:a,avatar:n,name:i}=e,l=a.startsWith("@")?a:`@${a}`;return(0,o.createElement)("div",{className:"activitypub-profile"},(0,o.createElement)("img",{className:"activitypub-profile__avatar",src:n,alt:i}),(0,o.createElement)("div",{className:"activitypub-profile__content"},(0,o.createElement)("div",{className:"activitypub-profile__name"},i),(0,o.createElement)("div",{className:"activitypub-profile__handle",title:l},l)),(0,o.createElement)(I,{profile:e,popupStyles:t,userId:r}))}function I({profile:e,popupStyles:t,userId:r}){const[n,i]=(0,a.useState)(!1),l=(0,u.sprintf)((0,u.__)("Follow %s","activitypub"),e?.name);return(0,o.createElement)(o.Fragment,null,(0,o.createElement)(s.Button,{className:"activitypub-profile__follow",onClick:()=>i(!0),"aria-haspopup":"dialog","aria-expanded":n,"aria-label":(0,u.__)("Follow me on the Fediverse","activitypub")},(0,u.__)("Follow","activitypub")),n&&(0,o.createElement)(s.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>i(!1),title:l,"aria-label":l,role:"dialog"},(0,o.createElement)($,{profile:e,userId:r}),(0,o.createElement)("style",null,t)))}function $({profile:e,userId:t}){const{webfinger:r}=e,a=(0,u.__)("Follow","activitypub"),n=`/${O}/actors/${t}/remote-follow?resource=`,i=(0,u.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub"),l=r.startsWith("@")?r:`@${r}`;return(0,o.createElement)(S,{actionText:a,copyDescription:i,handle:l,resourceUrl:n})}function P({selectedUser:e,style:t,backgroundColor:r,id:n,useId:i=!1,profileData:l=!1}){const[s,u]=(0,a.useState)(C()),p="site"===e?0:e,m=function(e){return v(".apfmd__button-group .components-button",d(e?.elements?.link?.color?.text)||"#111","#fff",d(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),y=i?{id:n}:{};function b(e){u(C(e))}return(0,a.useEffect)((()=>{if(l)return b(l);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${O}/actors/${e}`};return c()(t)})(p).then(b)}),[p,l]),(0,o.createElement)("div",{...y},(0,o.createElement)(f,{selector:`#${n}`,style:t,backgroundColor:r}),(0,o.createElement)(R,{profile:s,userId:p,popupStyles:m}))}let j=1;i()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follow-me-block-wrapper"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,o.createElement)(P,{...t,id:"activitypub-follow-me-block-"+j++,useId:!0}))}))}))},20:(e,t,r)=>{var o=r(609),a=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),i=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,u=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(u=t.ref),t)n.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:a,type:e,key:s,ref:u,props:c,_owner:i.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var n=r[e]={exports:{}};return t[e](n,n.exports,o),n.exports}o.m=t,e=[],o.O=(t,r,a,n)=>{if(!r){var i=1/0;for(u=0;u=n)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,n0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[r,a,n]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={41:0,301:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var a,n,i=r[0],l=r[1],c=r[2],s=0;if(i.some((t=>0!==e[t]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(c)var u=c(o)}for(t&&t(r);so(729)));a=o.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={729:(e,t,r)=>{var o=r(609);const a=window.wp.element,i=window.wp.domReady;var n=r.n(i);const l=window.wp.apiFetch;var c=r.n(l);const s=window.wp.components,u=window.wp.i18n;function p(e){return`var(--wp--preset--color--${e})`}function d(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return p(t)}function m(e,t,r=null,o=""){return r?`${e}${o} { ${t}: ${r}; }\n`:""}function v(e,t,r,o){return m(e,"background-color",t)+m(e,"color",r)+m(e,"background-color",o,":hover")+m(e,"background-color",o,":focus")}function f({selector:e,style:t,backgroundColor:r}){const a=function(e,t,r){const o=`${e} .components-button`,a=("string"==typeof(i=r)?p(i):i?.color?.background||null)||t?.color?.background;var i;return v(o,d(t?.elements?.link?.color?.text),a,d(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,r);return(0,o.createElement)("style",null,a)}const y=window.wp.primitives;var b=r(848);const _=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),h=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),w=(0,a.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,a.cloneElement)(e,{width:t,height:t,...r,ref:o})})),g=(0,b.jsx)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,b.jsx)(y.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),E=window.wp.compose,k="fediverse-remote-user";function x(e){try{return new URL(e),!0}catch(e){return!1}}function S({actionText:e,copyDescription:t,handle:r,resourceUrl:i,myProfile:n=!1,rememberProfile:l=!1}){const p=(0,u.__)("Loading...","activitypub"),d=(0,u.__)("Opening...","activitypub"),m=(0,u.__)("Error","activitypub"),v=(0,u.__)("Invalid","activitypub"),f=n||(0,u.__)("My Profile","activitypub"),[y,b]=(0,a.useState)(e),[S,O]=(0,a.useState)(_),N=(0,E.useCopyToClipboard)(r,(()=>{O(h),setTimeout((()=>O(_)),1e3)})),[C,R]=(0,a.useState)(""),[I,$]=(0,a.useState)(!0),{setRemoteUser:P}=function(){const[e,t]=(0,a.useState)(function(){const e=localStorage.getItem(k);return e?JSON.parse(e):{}}()),r=(0,a.useCallback)((e=>{!function(e){localStorage.setItem(k,JSON.stringify(e))}(e),t(e)}),[]),o=(0,a.useCallback)((()=>{localStorage.removeItem(k),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}(),j=(0,a.useCallback)((()=>{let t;if(!x(C)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&x(`https://${t[1]}`)}(C))return b(v),t=setTimeout((()=>b(e)),2e3),()=>clearTimeout(t);const r=i+C;b(p),c()({path:r}).then((({url:t,template:r})=>{I&&P({profileURL:C,template:r}),b(d),setTimeout((()=>{window.open(t,"_blank"),b(e)}),200)})).catch((()=>{b(m),setTimeout((()=>b(e)),2e3)}))}),[C]);return(0,o.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"dialog-title"},f),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,o.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,o.createElement)(s.Button,{ref:N,"aria-label":(0,u.__)("Copy handle to clipboard","activitypub")},(0,o.createElement)(w,{icon:S}),(0,u.__)("Copy","activitypub")))),(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"remote-profile-title"},(0,u.__)("Your Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,a.createInterpolateElement)((0,u.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,o.createElement)("code",null)})),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,u.__)("Enter your ActivityPub profile","activitypub")),(0,o.createElement)("input",{type:"text",id:"remote-profile",value:C,onKeyDown:e=>{"Enter"===e?.code&&j()},onChange:e=>R(e.target.value),"aria-invalid":y===v}),(0,o.createElement)(s.Button,{onClick:j,"aria-label":(0,u.__)("Submit profile","activitypub")},(0,o.createElement)(w,{icon:g}),y)),l&&(0,o.createElement)("div",{className:"activitypub-dialog__remember"},(0,o.createElement)(s.CheckboxControl,{checked:I,label:(0,u.__)("Remember me for easier comments","activitypub"),onChange:()=>{$(!I)}}))))}const{namespace:O}=window._activityPubOptions,N={avatar:"",webfinger:"@well@hello.dolly",name:(0,u.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function C(e){if(!e)return N;const t={...N,...e};return t.avatar=t?.icon?.url,t}function R({profile:e,popupStyles:t,userId:r}){const{webfinger:a,avatar:i,name:n}=e,l=a.startsWith("@")?a:`@${a}`;return(0,o.createElement)("div",{className:"activitypub-profile"},(0,o.createElement)("img",{className:"activitypub-profile__avatar",src:i,alt:n}),(0,o.createElement)("div",{className:"activitypub-profile__content"},(0,o.createElement)("div",{className:"activitypub-profile__name"},n),(0,o.createElement)("div",{className:"activitypub-profile__handle",title:l},l)),(0,o.createElement)(I,{profile:e,popupStyles:t,userId:r}))}function I({profile:e,popupStyles:t,userId:r}){const[i,n]=(0,a.useState)(!1),l=(0,u.sprintf)((0,u.__)("Follow %s","activitypub"),e?.name);return(0,o.createElement)(o.Fragment,null,(0,o.createElement)(s.Button,{className:"activitypub-profile__follow",onClick:()=>n(!0),"aria-haspopup":"dialog","aria-expanded":i,"aria-label":(0,u.__)("Follow me on the Fediverse","activitypub")},(0,u.__)("Follow","activitypub")),i&&(0,o.createElement)(s.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>n(!1),title:l,"aria-label":l,role:"dialog"},(0,o.createElement)($,{profile:e,userId:r}),(0,o.createElement)("style",null,t)))}function $({profile:e,userId:t}){const{webfinger:r}=e,a=(0,u.__)("Follow","activitypub"),i=`/${O}/actors/${t}/remote-follow?resource=`,n=(0,u.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub"),l=r.startsWith("@")?r:`@${r}`;return(0,o.createElement)(S,{actionText:a,copyDescription:n,handle:l,resourceUrl:i})}function P({selectedUser:e,style:t,backgroundColor:r,id:i,useId:n=!1,profileData:l=!1}){const[s,u]=(0,a.useState)(C()),p="site"===e?0:e,m=function(e){return v(".apfmd__button-group .components-button",d(e?.elements?.link?.color?.text)||"#111","#fff",d(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),y=n?{id:i}:{};function b(e){u(C(e))}return(0,a.useEffect)((()=>{if(l)return b(l);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${O}/actors/${e}`};return c()(t)})(p).then(b)}),[p,l]),(0,o.createElement)("div",{...y},(0,o.createElement)(f,{selector:`#${i}`,style:t,backgroundColor:r}),(0,o.createElement)(R,{profile:s,userId:p,popupStyles:m}))}let j=1;n()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follow-me-block-wrapper"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,o.createElement)(P,{...t,id:"activitypub-follow-me-block-"+j++,useId:!0}))}))}))},20:(e,t,r)=>{var o=r(609),a=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),n=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,u=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:a,type:e,key:s,ref:u,props:c,_owner:n.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,o),i.exports}o.m=t,e=[],o.O=(t,r,a,i)=>{if(!r){var n=1/0;for(u=0;u=i)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[r,a,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={41:0,301:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var a,i,[n,l,c]=r,s=0;if(n.some((t=>0!==e[t]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(c)var u=c(o)}for(t&&t(r);so(729)));a=o.O(a)})(); \ No newline at end of file diff --git a/build/followers/index.asset.php b/build/followers/index.asset.php index 33e823773..269f24cfe 100644 --- a/build/followers/index.asset.php +++ b/build/followers/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-url'), 'version' => 'eca29e57bfd7a1ef0298'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-url'), 'version' => '9fd7d6b6bca51eefcdf0'); diff --git a/build/followers/index.js b/build/followers/index.js index 971c4bbff..b5cd444e8 100644 --- a/build/followers/index.js +++ b/build/followers/index.js @@ -1,4 +1,4 @@ -(()=>{var e={20:(e,t,a)=>{"use strict";var r=a(609),n=Symbol.for("react.element"),l=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),o=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,a){var r,c={},s=null,p=null;for(r in void 0!==a&&(s=""+a),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(p=t.ref),t)l.call(t,r)&&!i.hasOwnProperty(r)&&(c[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===c[r]&&(c[r]=t[r]);return{$$typeof:n,type:e,key:s,ref:p,props:c,_owner:o.current}}},848:(e,t,a)=>{"use strict";e.exports=a(20)},609:e=>{"use strict";e.exports=window.React},942:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e="",t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";const e=window.wp.blocks,t=window.wp.primitives;var r=a(848);const n=(0,r.jsx)(t.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,r.jsx)(t.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})});var l=a(609);const o=window.wp.components,i=window.wp.element,c=window.wp.blockEditor,s=window.wp.data,p=window.wp.coreData,u=window.wp.i18n,v=window.wp.apiFetch;var m=a.n(v);const w=window.wp.url;var d=a(942),b=a.n(d);function f({active:e,children:t,page:a,pageClick:r,className:n}){const o=b()("wp-block activitypub-pager",n,{current:e});return(0,l.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&r(a)}},t)}function y({compact:e,nextLabel:t,page:a,pageClick:r,perPage:n,prevLabel:o,total:i,variant:c="outlined"}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(i/n)),p=b()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,l.createElement)("nav",{className:p},o&&(0,l.createElement)(f,{key:"prev",page:a-1,pageClick:r,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,l.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,l.createElement)(f,{key:e,page:e,pageClick:r,active:e===a,className:"page-numbers"},e)))),t&&(0,l.createElement)(f,{key:"next",page:a+1,pageClick:r,active:a===Math.ceil(i/n),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const{namespace:g}=window._activityPubOptions;function _({selectedUser:e,per_page:t,order:a,title:r,page:n,setPage:o,className:c="",followLinks:s=!0,followerData:p=!1}){const v="site"===e?0:e,[d,b]=(0,l.useState)([]),[f,_]=(0,l.useState)(0),[k,E]=(0,l.useState)(0),[x,S]=function(){const[e,t]=(0,l.useState)(1);return[e,t]}(),N=n||x,C=o||S,O=(0,i.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ +(()=>{var e={20:(e,t,a)=>{"use strict";var r=a(609),n=Symbol.for("react.element"),l=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),o=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,a){var r,c={},s=null,p=null;for(r in void 0!==a&&(s=""+a),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(p=t.ref),t)l.call(t,r)&&!i.hasOwnProperty(r)&&(c[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===c[r]&&(c[r]=t[r]);return{$$typeof:n,type:e,key:s,ref:p,props:c,_owner:o.current}}},848:(e,t,a)=>{"use strict";e.exports=a(20)},609:e=>{"use strict";e.exports=window.React},942:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e="",t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";const e=window.wp.blocks,t=window.wp.primitives;var r=a(848);const n=(0,r.jsx)(t.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,r.jsx)(t.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})});var l=a(609);const o=window.wp.components,i=window.wp.element,c=window.wp.blockEditor,s=window.wp.data,p=window.wp.coreData,u=window.wp.i18n,m=window.wp.apiFetch;var v=a.n(m);const d=window.wp.url;var w=a(942),b=a.n(w);function f({active:e,children:t,page:a,pageClick:r,className:n}){const o=b()("wp-block activitypub-pager",n,{current:e});return(0,l.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&r(a)}},t)}const y={outlined:"outlined",minimal:"minimal"};function g({compact:e,nextLabel:t,page:a,pageClick:r,perPage:n,prevLabel:o,total:i,variant:c=y.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(i/n)),p=b()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,l.createElement)("nav",{className:p},o&&(0,l.createElement)(f,{key:"prev",page:a-1,pageClick:r,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,l.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,l.createElement)(f,{key:e,page:e,pageClick:r,active:e===a,className:"page-numbers"},e)))),t&&(0,l.createElement)(f,{key:"next",page:a+1,pageClick:r,active:a===Math.ceil(i/n),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const{namespace:_}=window._activityPubOptions;function h({selectedUser:e,per_page:t,order:a,title:r,page:n,setPage:o,className:c="",followLinks:s=!0,followerData:p=!1}){const m="site"===e?0:e,[w,b]=(0,l.useState)([]),[f,y]=(0,l.useState)(0),[h,E]=(0,l.useState)(0),[x,S]=function(){const[e,t]=(0,l.useState)(1);return[e,t]}(),N=n||x,C=o||S,O=(0,i.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ (0,u.__)(" Less","activitypub"),{span:(0,l.createElement)("span",{className:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),P=(0,i.createInterpolateElement)(/* translators: arrow for next followers link */ /* translators: arrow for next followers link */ -(0,u.__)("More ","activitypub"),{span:(0,l.createElement)("span",{className:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),I=(e,a)=>{b(e),E(a),_(Math.ceil(a/t))};return(0,l.useEffect)((()=>{if(p&&1===N)return I(p.followers,p.total);const e=function(e,t,a,r){const n=`/${g}/actors/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,w.addQueryArgs)(n,l)}(v,t,a,N);m()({path:e}).then((e=>I(e.orderedItems,e.totalItems))).catch((()=>{}))}),[v,t,a,N,p]),(0,l.createElement)("div",{className:"activitypub-follower-block "+c},(0,l.createElement)("h3",null,r),(0,l.createElement)("ul",null,d&&d.map((e=>(0,l.createElement)("li",{key:e.url},(0,l.createElement)(h,{...e,followLinks:s}))))),f>1&&(0,l.createElement)(y,{page:N,perPage:t,total:k,pageClick:C,nextLabel:P,prevLabel:O,compact:"is-style-compact"===c}))}function h({name:e,icon:t,url:a,preferredUsername:r,followLinks:n=!0}){const i=`@${r}`,c={};return n||(c.onClick=e=>e.preventDefault()),(0,l.createElement)(o.ExternalLink,{className:"activitypub-link",href:a,title:i,...c},(0,l.createElement)("img",{width:"40",height:"40",src:t.url,className:"avatar activitypub-avatar",alt:e}),(0,l.createElement)("span",{className:"activitypub-actor"},(0,l.createElement)("strong",{className:"activitypub-name"},e),(0,l.createElement)("span",{className:"sep"},"/"),(0,l.createElement)("span",{className:"activitypub-handle"},i)))}const k=window._activityPubOptions?.enabled,E=window._activityPubOptions?.enabled;function x({name:e}){const t=E?.site?"":(0,u.__)("It will be empty in other non-author contexts.","activitypub"),a=(0,u.sprintf)(/* translators: %1$s: block name, %2$s: extra information for non-author context */ /* translators: %1$s: block name, %2$s: extra information for non-author context */ -(0,u.__)("This %1$s block will adapt to the page it is on, displaying the user profile associated with a post author (in a loop) or a user archive. %2$s","activitypub"),e,t).trim();return(0,l.createElement)(o.Card,null,(0,l.createElement)(o.CardBody,null,(0,i.createInterpolateElement)(a,{strong:(0,l.createElement)("strong",null)})))}(0,e.registerBlockType)("activitypub/followers",{edit:function({attributes:e,setAttributes:t,context:{postType:a,postId:r}}){const{order:n,per_page:v,selectedUser:m,title:w}=e,d=(0,c.useBlockProps)(),[b,f]=(0,i.useState)(1),y=[{label:(0,u.__)("New to old","activitypub"),value:"desc"},{label:(0,u.__)("Old to new","activitypub"),value:"asc"}],g=function({withInherit:e=!1}){const t=k?.users?(0,s.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,i.useMemo)((()=>{if(!t)return[];const a=[];return k?.site&&a.push({label:(0,u.__)("Site","activitypub"),value:"site"}),e&&k?.users&&a.push({label:(0,u.__)("Dynamic User","activitypub"),value:"inherit"}),t.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),a)}),[t])}({withInherit:!0}),h=e=>a=>{f(1),t({[e]:a})},E=(0,s.useSelect)((e=>{const{getEditedEntityRecord:t}=e(p.store),n=t("postType",a,r)?.author;return null!=n?n:null}),[a,r]);return(0,i.useEffect)((()=>{g.length&&(g.find((({value:e})=>e===m))||t({selectedUser:g[0].value}))}),[m,g]),(0,l.createElement)("div",{...d},(0,l.createElement)(c.InspectorControls,{key:"setting"},(0,l.createElement)(o.PanelBody,{title:(0,u.__)("Followers Options","activitypub")},(0,l.createElement)(o.TextControl,{label:(0,u.__)("Title","activitypub"),help:(0,u.__)("Title to display above the list of followers. Blank for none.","activitypub"),value:w,onChange:e=>t({title:e})}),g.length>1&&(0,l.createElement)(o.SelectControl,{label:(0,u.__)("Select User","activitypub"),value:m,options:g,onChange:h("selectedUser")}),(0,l.createElement)(o.SelectControl,{label:(0,u.__)("Sort","activitypub"),value:n,options:y,onChange:h("order")}),(0,l.createElement)(o.RangeControl,{label:(0,u.__)("Number of Followers","activitypub"),value:v,onChange:h("per_page"),min:1,max:10}))),"inherit"===m?E?(0,l.createElement)(_,{...e,page:b,setPage:f,followLinks:!1,selectedUser:E}):(0,l.createElement)(x,{name:(0,u.__)("Followers","activitypub")}):(0,l.createElement)(_,{...e,page:b,setPage:f,followLinks:!1}))},save:()=>null,icon:n})})()})(); \ No newline at end of file +(0,u.__)("More ","activitypub"),{span:(0,l.createElement)("span",{className:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),I=(e,a)=>{b(e),E(a),y(Math.ceil(a/t))};return(0,l.useEffect)((()=>{if(p&&1===N)return I(p.followers,p.total);const e=function(e,t,a,r){const n=`/${_}/actors/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,d.addQueryArgs)(n,l)}(m,t,a,N);v()({path:e}).then((e=>I(e.orderedItems,e.totalItems))).catch((()=>{}))}),[m,t,a,N,p]),(0,l.createElement)("div",{className:"activitypub-follower-block "+c},(0,l.createElement)("h3",null,r),(0,l.createElement)("ul",null,w&&w.map((e=>(0,l.createElement)("li",{key:e.url},(0,l.createElement)(k,{...e,followLinks:s}))))),f>1&&(0,l.createElement)(g,{page:N,perPage:t,total:h,pageClick:C,nextLabel:P,prevLabel:O,compact:"is-style-compact"===c}))}function k({name:e,icon:t,url:a,preferredUsername:r,followLinks:n=!0}){const i=`@${r}`,c={};return n||(c.onClick=e=>e.preventDefault()),(0,l.createElement)(o.ExternalLink,{className:"activitypub-link",href:a,title:i,...c},(0,l.createElement)("img",{width:"40",height:"40",src:t.url,className:"avatar activitypub-avatar",alt:e}),(0,l.createElement)("span",{className:"activitypub-actor"},(0,l.createElement)("strong",{className:"activitypub-name"},e),(0,l.createElement)("span",{className:"sep"},"/"),(0,l.createElement)("span",{className:"activitypub-handle"},i)))}const E=window._activityPubOptions?.enabled,x=window._activityPubOptions?.enabled;function S({name:e}){const t=x?.site?"":(0,u.__)("It will be empty in other non-author contexts.","activitypub"),a=(0,u.sprintf)(/* translators: %1$s: block name, %2$s: extra information for non-author context */ /* translators: %1$s: block name, %2$s: extra information for non-author context */ +(0,u.__)("This %1$s block will adapt to the page it is on, displaying the user profile associated with a post author (in a loop) or a user archive. %2$s","activitypub"),e,t).trim();return(0,l.createElement)(o.Card,null,(0,l.createElement)(o.CardBody,null,(0,i.createInterpolateElement)(a,{strong:(0,l.createElement)("strong",null)})))}(0,e.registerBlockType)("activitypub/followers",{edit:function({attributes:e,setAttributes:t,context:{postType:a,postId:r}}){const{order:n,per_page:m,selectedUser:v,title:d}=e,w=(0,c.useBlockProps)(),[b,f]=(0,i.useState)(1),y=[{label:(0,u.__)("New to old","activitypub"),value:"desc"},{label:(0,u.__)("Old to new","activitypub"),value:"asc"}],g=function({withInherit:e=!1}){const t=E?.users?(0,s.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,i.useMemo)((()=>{if(!t)return[];const a=[];return E?.site&&a.push({label:(0,u.__)("Site","activitypub"),value:"site"}),e&&E?.users&&a.push({label:(0,u.__)("Dynamic User","activitypub"),value:"inherit"}),t.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),a)}),[t])}({withInherit:!0}),_=e=>a=>{f(1),t({[e]:a})},k=(0,s.useSelect)((e=>{const{getEditedEntityRecord:t}=e(p.store),n=t("postType",a,r)?.author;return null!=n?n:null}),[a,r]);return(0,i.useEffect)((()=>{g.length&&(g.find((({value:e})=>e===v))||t({selectedUser:g[0].value}))}),[v,g]),(0,l.createElement)("div",{...w},(0,l.createElement)(c.InspectorControls,{key:"setting"},(0,l.createElement)(o.PanelBody,{title:(0,u.__)("Followers Options","activitypub")},(0,l.createElement)(o.TextControl,{label:(0,u.__)("Title","activitypub"),help:(0,u.__)("Title to display above the list of followers. Blank for none.","activitypub"),value:d,onChange:e=>t({title:e})}),g.length>1&&(0,l.createElement)(o.SelectControl,{label:(0,u.__)("Select User","activitypub"),value:v,options:g,onChange:_("selectedUser")}),(0,l.createElement)(o.SelectControl,{label:(0,u.__)("Sort","activitypub"),value:n,options:y,onChange:_("order")}),(0,l.createElement)(o.RangeControl,{label:(0,u.__)("Number of Followers","activitypub"),value:m,onChange:_("per_page"),min:1,max:10}))),"inherit"===v?k?(0,l.createElement)(h,{...e,page:b,setPage:f,followLinks:!1,selectedUser:k}):(0,l.createElement)(S,{name:(0,u.__)("Followers","activitypub")}):(0,l.createElement)(h,{...e,page:b,setPage:f,followLinks:!1}))},save:()=>null,icon:n})})()})(); \ No newline at end of file diff --git a/build/followers/view.asset.php b/build/followers/view.asset.php index c4528416c..4e64279dd 100644 --- a/build/followers/view.asset.php +++ b/build/followers/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '771bb557b87449bcca85'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '111b88843c05346aadbf'); diff --git a/build/followers/view.js b/build/followers/view.js index 2450a7ee3..e9a5792ae 100644 --- a/build/followers/view.js +++ b/build/followers/view.js @@ -1,3 +1,3 @@ -(()=>{var e,t={250:(e,t,a)=>{"use strict";const r=window.React,n=window.wp.apiFetch;var l=a.n(n);const o=window.wp.url,c=window.wp.element,i=window.wp.i18n;var s=a(942),p=a.n(s);function u({active:e,children:t,page:a,pageClick:n,className:l}){const o=p()("wp-block activitypub-pager",l,{current:e});return(0,r.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&n(a)}},t)}function m({compact:e,nextLabel:t,page:a,pageClick:n,perPage:l,prevLabel:o,total:c,variant:i="outlined"}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(c/l)),m=p()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${i}`,{"is-compact":e});return(0,r.createElement)("nav",{className:m},o&&(0,r.createElement)(u,{key:"prev",page:a-1,pageClick:n,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,r.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,r.createElement)(u,{key:e,page:e,pageClick:n,active:e===a,className:"page-numbers"},e)))),t&&(0,r.createElement)(u,{key:"next",page:a+1,pageClick:n,active:a===Math.ceil(c/l),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const f=window.wp.components,{namespace:v}=window._activityPubOptions;function b({selectedUser:e,per_page:t,order:a,title:n,page:s,setPage:p,className:u="",followLinks:f=!0,followerData:b=!1}){const d="site"===e?0:e,[g,y]=(0,r.useState)([]),[k,h]=(0,r.useState)(0),[E,N]=(0,r.useState)(0),[x,_]=function(){const[e,t]=(0,r.useState)(1);return[e,t]}(),O=s||x,S=p||_,C=(0,c.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ -(0,i.__)(" Less","activitypub"),{span:(0,r.createElement)("span",{className:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,c.createInterpolateElement)(/* translators: arrow for next followers link */ /* translators: arrow for next followers link */ -(0,i.__)("More ","activitypub"),{span:(0,r.createElement)("span",{className:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),q=(e,a)=>{y(e),N(a),h(Math.ceil(a/t))};return(0,r.useEffect)((()=>{if(b&&1===O)return q(b.followers,b.total);const e=function(e,t,a,r){const n=`/${v}/actors/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,o.addQueryArgs)(n,l)}(d,t,a,O);l()({path:e}).then((e=>q(e.orderedItems,e.totalItems))).catch((()=>{}))}),[d,t,a,O,b]),(0,r.createElement)("div",{className:"activitypub-follower-block "+u},(0,r.createElement)("h3",null,n),(0,r.createElement)("ul",null,g&&g.map((e=>(0,r.createElement)("li",{key:e.url},(0,r.createElement)(w,{...e,followLinks:f}))))),k>1&&(0,r.createElement)(m,{page:O,perPage:t,total:E,pageClick:S,nextLabel:L,prevLabel:C,compact:"is-style-compact"===u}))}function w({name:e,icon:t,url:a,preferredUsername:n,followLinks:l=!0}){const o=`@${n}`,c={};return l||(c.onClick=e=>e.preventDefault()),(0,r.createElement)(f.ExternalLink,{className:"activitypub-link",href:a,title:o,...c},(0,r.createElement)("img",{width:"40",height:"40",src:t.url,className:"avatar activitypub-avatar",alt:e}),(0,r.createElement)("span",{className:"activitypub-actor"},(0,r.createElement)("strong",{className:"activitypub-name"},e),(0,r.createElement)("span",{className:"sep"},"/"),(0,r.createElement)("span",{className:"activitypub-handle"},o)))}const d=window.wp.domReady;a.n(d)()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follower-block"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,c.createRoot)(e).render((0,r.createElement)(b,{...t}))}))}))},942:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e="",t=0;t{if(!a){var o=1/0;for(p=0;p=l)&&Object.keys(r.O).every((e=>r.O[e](a[i])))?a.splice(i--,1):(c=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={996:0,528:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,o=a[0],c=a[1],i=a[2],s=0;if(o.some((t=>0!==e[t]))){for(n in c)r.o(c,n)&&(r.m[n]=c[n]);if(i)var p=i(r)}for(t&&t(a);sr(250)));n=r.O(n)})(); \ No newline at end of file +(()=>{var e,t={250:(e,t,a)=>{"use strict";const r=window.React,n=window.wp.apiFetch;var l=a.n(n);const o=window.wp.url,i=window.wp.element,c=window.wp.i18n;var s=a(942),p=a.n(s);function u({active:e,children:t,page:a,pageClick:n,className:l}){const o=p()("wp-block activitypub-pager",l,{current:e});return(0,r.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&n(a)}},t)}const m={outlined:"outlined",minimal:"minimal"};function f({compact:e,nextLabel:t,page:a,pageClick:n,perPage:l,prevLabel:o,total:i,variant:c=m.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(i/l)),f=p()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,r.createElement)("nav",{className:f},o&&(0,r.createElement)(u,{key:"prev",page:a-1,pageClick:n,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,r.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,r.createElement)(u,{key:e,page:e,pageClick:n,active:e===a,className:"page-numbers"},e)))),t&&(0,r.createElement)(u,{key:"next",page:a+1,pageClick:n,active:a===Math.ceil(i/l),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const v=window.wp.components,{namespace:b}=window._activityPubOptions;function d({selectedUser:e,per_page:t,order:a,title:n,page:s,setPage:p,className:u="",followLinks:m=!0,followerData:v=!1}){const d="site"===e?0:e,[g,y]=(0,r.useState)([]),[k,h]=(0,r.useState)(0),[E,N]=(0,r.useState)(0),[x,_]=function(){const[e,t]=(0,r.useState)(1);return[e,t]}(),O=s||x,S=p||_,C=(0,i.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ +(0,c.__)(" Less","activitypub"),{span:(0,r.createElement)("span",{className:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,i.createInterpolateElement)(/* translators: arrow for next followers link */ /* translators: arrow for next followers link */ +(0,c.__)("More ","activitypub"),{span:(0,r.createElement)("span",{className:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),q=(e,a)=>{y(e),N(a),h(Math.ceil(a/t))};return(0,r.useEffect)((()=>{if(v&&1===O)return q(v.followers,v.total);const e=function(e,t,a,r){const n=`/${b}/actors/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,o.addQueryArgs)(n,l)}(d,t,a,O);l()({path:e}).then((e=>q(e.orderedItems,e.totalItems))).catch((()=>{}))}),[d,t,a,O,v]),(0,r.createElement)("div",{className:"activitypub-follower-block "+u},(0,r.createElement)("h3",null,n),(0,r.createElement)("ul",null,g&&g.map((e=>(0,r.createElement)("li",{key:e.url},(0,r.createElement)(w,{...e,followLinks:m}))))),k>1&&(0,r.createElement)(f,{page:O,perPage:t,total:E,pageClick:S,nextLabel:L,prevLabel:C,compact:"is-style-compact"===u}))}function w({name:e,icon:t,url:a,preferredUsername:n,followLinks:l=!0}){const o=`@${n}`,i={};return l||(i.onClick=e=>e.preventDefault()),(0,r.createElement)(v.ExternalLink,{className:"activitypub-link",href:a,title:o,...i},(0,r.createElement)("img",{width:"40",height:"40",src:t.url,className:"avatar activitypub-avatar",alt:e}),(0,r.createElement)("span",{className:"activitypub-actor"},(0,r.createElement)("strong",{className:"activitypub-name"},e),(0,r.createElement)("span",{className:"sep"},"/"),(0,r.createElement)("span",{className:"activitypub-handle"},o)))}const g=window.wp.domReady;a.n(g)()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follower-block"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,i.createRoot)(e).render((0,r.createElement)(d,{...t}))}))}))},942:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e="",t=0;t{if(!a){var o=1/0;for(p=0;p=l)&&Object.keys(r.O).every((e=>r.O[e](a[c])))?a.splice(c--,1):(i=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={996:0,528:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[o,i,c]=a,s=0;if(o.some((t=>0!==e[t]))){for(n in i)r.o(i,n)&&(r.m[n]=i[n]);if(c)var p=c(r)}for(t&&t(a);sr(250)));n=r.O(n)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css index 02df9d903..67e8a23b9 100644 --- a/build/reactions/style-index-rtl.css +++ b/build/reactions/style-index-rtl.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h6{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 9f2923f62..8fc74db89 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions h4{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h6{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/remote-reply/index.asset.php b/build/remote-reply/index.asset.php index a5bf54012..6d2d6d5fc 100644 --- a/build/remote-reply/index.asset.php +++ b/build/remote-reply/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'e834ccbee61327a31bfe'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '1061665c7a59ab0dbe4b'); diff --git a/build/remote-reply/index.js b/build/remote-reply/index.js index fddefa349..4e32a2dd2 100644 --- a/build/remote-reply/index.js +++ b/build/remote-reply/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={456:(e,t,r)=>{var o=r(609);const a=window.wp.element,i=window.wp.domReady;var n=r.n(i);const l=window.wp.components,c=window.wp.i18n,s=(0,a.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,a.cloneElement)(e,{width:t,height:t,...r,ref:o})})),m=window.wp.primitives;var p=r(848);const u=(0,p.jsx)(m.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(m.Path,{d:"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"})}),d=window.wp.apiFetch;var v=r.n(d);const y=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),_=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),f=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),b=window.wp.compose,w="fediverse-remote-user";function h(){const[e,t]=(0,a.useState)(function(){const e=localStorage.getItem(w);return e?JSON.parse(e):{}}()),r=(0,a.useCallback)((e=>{!function(e){localStorage.setItem(w,JSON.stringify(e))}(e),t(e)}),[]),o=(0,a.useCallback)((()=>{localStorage.removeItem(w),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}function g(e){try{return new URL(e),!0}catch(e){return!1}}function E({actionText:e,copyDescription:t,handle:r,resourceUrl:i,myProfile:n=!1,rememberProfile:m=!1}){const p=(0,c.__)("Loading...","activitypub"),u=(0,c.__)("Opening...","activitypub"),d=(0,c.__)("Error","activitypub"),w=(0,c.__)("Invalid","activitypub"),E=n||(0,c.__)("My Profile","activitypub"),[C,R]=(0,a.useState)(e),[x,O]=(0,a.useState)(y),k=(0,b.useCopyToClipboard)(r,(()=>{O(_),setTimeout((()=>O(y)),1e3)})),[L,S]=(0,a.useState)(""),[U,N]=(0,a.useState)(!0),{setRemoteUser:P}=h(),j=(0,a.useCallback)((()=>{let t;if(!g(L)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&g(`https://${t[1]}`)}(L))return R(w),t=setTimeout((()=>R(e)),2e3),()=>clearTimeout(t);const r=i+L;R(p),v()({path:r}).then((({url:t,template:r})=>{U&&P({profileURL:L,template:r}),R(u),setTimeout((()=>{window.open(t,"_blank"),R(e)}),200)})).catch((()=>{R(d),setTimeout((()=>R(e)),2e3)}))}),[L]);return(0,o.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"dialog-title"},E),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,o.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,o.createElement)(l.Button,{ref:k,"aria-label":(0,c.__)("Copy handle to clipboard","activitypub")},(0,o.createElement)(s,{icon:x}),(0,c.__)("Copy","activitypub")))),(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"remote-profile-title"},(0,c.__)("Your Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,a.createInterpolateElement)((0,c.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,o.createElement)("code",null)})),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,c.__)("Enter your ActivityPub profile","activitypub")),(0,o.createElement)("input",{type:"text",id:"remote-profile",value:L,onKeyDown:e=>{"Enter"===e?.code&&j()},onChange:e=>S(e.target.value),"aria-invalid":C===w}),(0,o.createElement)(l.Button,{onClick:j,"aria-label":(0,c.__)("Submit profile","activitypub")},(0,o.createElement)(s,{icon:f}),C)),m&&(0,o.createElement)("div",{className:"activitypub-dialog__remember"},(0,o.createElement)(l.CheckboxControl,{checked:U,label:(0,c.__)("Remember me for easier comments","activitypub"),onChange:()=>{N(!U)}}))))}const{namespace:C}=window._activityPubOptions;function R({selectedComment:e,commentId:t}){const r=(0,c.__)("Reply","activitypub"),a=`/${C}/comments/${t}/remote-reply?resource=`,i=(0,c.__)("Copy and paste the Comment URL into the search field of your favorite fediverse app or server.","activitypub");return(0,o.createElement)(E,{actionText:r,copyDescription:i,handle:e,resourceUrl:a,myProfile:(0,c.__)("Original Comment URL","activitypub"),rememberProfile:!0})}function x({profileURL:e,template:t,commentURL:r,deleteRemoteUser:a}){return(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.Button,{variant:"link",className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>{const e=t.replace("{uri}",r);window.open(e,"_blank")}},(0,c.sprintf)((0,c.__)("Reply as %s","activitypub"),e)),(0,o.createElement)(l.Button,{className:"activitypub-remote-profile-delete",onClick:a,title:(0,c.__)("Delete Remote Profile","activitypub")},(0,o.createElement)(s,{icon:u,size:18})))}function O({selectedComment:e,commentId:t}){const[r,i]=(0,a.useState)(!1),n=(0,c.__)("Remote Reply","activitypub"),{profileURL:s,template:m,deleteRemoteUser:p}=h(),u=s&&m;return(0,o.createElement)(o.Fragment,null,u?(0,o.createElement)(x,{profileURL:s,template:m,commentURL:e,deleteRemoteUser:p}):(0,o.createElement)(l.Button,{variant:"link",className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>i(!0)},(0,c.__)("Reply on the Fediverse","activitypub")),r&&(0,o.createElement)(l.Modal,{className:"activitypub-remote-reply__modal activitypub__modal",onRequestClose:()=>i(!1),title:n},(0,o.createElement)(R,{selectedComment:e,commentId:t})))}let k=1;n()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-remote-reply"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,o.createElement)(O,{...t,id:"activitypub-remote-reply-link-"+k++,useId:!0}))}))}))},20:(e,t,r)=>{var o=r(609),a=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),n=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,m=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(m=t.ref),t)i.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:a,type:e,key:s,ref:m,props:c,_owner:n.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,o),i.exports}o.m=t,e=[],o.O=(t,r,a,i)=>{if(!r){var n=1/0;for(m=0;m=i)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,i0&&e[m-1][2]>i;m--)e[m]=e[m-1];e[m]=[r,a,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={227:0,739:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var a,i,n=r[0],l=r[1],c=r[2],s=0;if(n.some((t=>0!==e[t]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(c)var m=c(o)}for(t&&t(r);so(456)));a=o.O(a)})(); \ No newline at end of file +(()=>{"use strict";var e,t={456:(e,t,r)=>{var o=r(609);const a=window.wp.element,i=window.wp.domReady;var n=r.n(i);const l=window.wp.components,c=window.wp.i18n,s=(0,a.forwardRef)((function({icon:e,size:t=24,...r},o){return(0,a.cloneElement)(e,{width:t,height:t,...r,ref:o})})),m=window.wp.primitives;var p=r(848);const u=(0,p.jsx)(m.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(m.Path,{d:"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"})}),d=window.wp.apiFetch;var v=r.n(d);const y=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})}),_=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),f=(0,p.jsx)(m.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(m.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),b=window.wp.compose,w="fediverse-remote-user";function h(){const[e,t]=(0,a.useState)(function(){const e=localStorage.getItem(w);return e?JSON.parse(e):{}}()),r=(0,a.useCallback)((e=>{!function(e){localStorage.setItem(w,JSON.stringify(e))}(e),t(e)}),[]),o=(0,a.useCallback)((()=>{localStorage.removeItem(w),t({})}),[]);return{template:e?.template||!1,profileURL:e?.profileURL||!1,setRemoteUser:r,deleteRemoteUser:o}}function g(e){try{return new URL(e),!0}catch(e){return!1}}function E({actionText:e,copyDescription:t,handle:r,resourceUrl:i,myProfile:n=!1,rememberProfile:m=!1}){const p=(0,c.__)("Loading...","activitypub"),u=(0,c.__)("Opening...","activitypub"),d=(0,c.__)("Error","activitypub"),w=(0,c.__)("Invalid","activitypub"),E=n||(0,c.__)("My Profile","activitypub"),[C,R]=(0,a.useState)(e),[x,O]=(0,a.useState)(y),k=(0,b.useCopyToClipboard)(r,(()=>{O(_),setTimeout((()=>O(y)),1e3)})),[L,S]=(0,a.useState)(""),[U,N]=(0,a.useState)(!0),{setRemoteUser:P}=h(),j=(0,a.useCallback)((()=>{let t;if(!g(L)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&g(`https://${t[1]}`)}(L))return R(w),t=setTimeout((()=>R(e)),2e3),()=>clearTimeout(t);const r=i+L;R(p),v()({path:r}).then((({url:t,template:r})=>{U&&P({profileURL:L,template:r}),R(u),setTimeout((()=>{window.open(t,"_blank"),R(e)}),200)})).catch((()=>{R(d),setTimeout((()=>R(e)),2e3)}))}),[L]);return(0,o.createElement)("div",{className:"activitypub__dialog",role:"dialog","aria-labelledby":"dialog-title"},(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"dialog-title"},E),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"copy-description"},t),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"profile-handle",className:"screen-reader-text"},t),(0,o.createElement)("input",{type:"text",id:"profile-handle",value:r,readOnly:!0}),(0,o.createElement)(l.Button,{ref:k,"aria-label":(0,c.__)("Copy handle to clipboard","activitypub")},(0,o.createElement)(s,{icon:x}),(0,c.__)("Copy","activitypub")))),(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",{id:"remote-profile-title"},(0,c.__)("Your Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog__description",id:"remote-profile-description"},(0,a.createInterpolateElement)((0,c.__)("Or, if you know your own profile, we can start things that way! (eg @yourusername@example.com)","activitypub"),{code:(0,o.createElement)("code",null)})),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("label",{htmlFor:"remote-profile",className:"screen-reader-text"},(0,c.__)("Enter your ActivityPub profile","activitypub")),(0,o.createElement)("input",{type:"text",id:"remote-profile",value:L,onKeyDown:e=>{"Enter"===e?.code&&j()},onChange:e=>S(e.target.value),"aria-invalid":C===w}),(0,o.createElement)(l.Button,{onClick:j,"aria-label":(0,c.__)("Submit profile","activitypub")},(0,o.createElement)(s,{icon:f}),C)),m&&(0,o.createElement)("div",{className:"activitypub-dialog__remember"},(0,o.createElement)(l.CheckboxControl,{checked:U,label:(0,c.__)("Remember me for easier comments","activitypub"),onChange:()=>{N(!U)}}))))}const{namespace:C}=window._activityPubOptions;function R({selectedComment:e,commentId:t}){const r=(0,c.__)("Reply","activitypub"),a=`/${C}/comments/${t}/remote-reply?resource=`,i=(0,c.__)("Copy and paste the Comment URL into the search field of your favorite fediverse app or server.","activitypub");return(0,o.createElement)(E,{actionText:r,copyDescription:i,handle:e,resourceUrl:a,myProfile:(0,c.__)("Original Comment URL","activitypub"),rememberProfile:!0})}function x({profileURL:e,template:t,commentURL:r,deleteRemoteUser:a}){return(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.Button,{variant:"link",className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>{const e=t.replace("{uri}",r);window.open(e,"_blank")}},(0,c.sprintf)((0,c.__)("Reply as %s","activitypub"),e)),(0,o.createElement)(l.Button,{className:"activitypub-remote-profile-delete",onClick:a,title:(0,c.__)("Delete Remote Profile","activitypub")},(0,o.createElement)(s,{icon:u,size:18})))}function O({selectedComment:e,commentId:t}){const[r,i]=(0,a.useState)(!1),n=(0,c.__)("Remote Reply","activitypub"),{profileURL:s,template:m,deleteRemoteUser:p}=h(),u=s&&m;return(0,o.createElement)(o.Fragment,null,u?(0,o.createElement)(x,{profileURL:s,template:m,commentURL:e,deleteRemoteUser:p}):(0,o.createElement)(l.Button,{variant:"link",className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>i(!0)},(0,c.__)("Reply on the Fediverse","activitypub")),r&&(0,o.createElement)(l.Modal,{className:"activitypub-remote-reply__modal activitypub__modal",onRequestClose:()=>i(!1),title:n},(0,o.createElement)(R,{selectedComment:e,commentId:t})))}let k=1;n()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-remote-reply"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,a.createRoot)(e).render((0,o.createElement)(O,{...t,id:"activitypub-remote-reply-link-"+k++,useId:!0}))}))}))},20:(e,t,r)=>{var o=r(609),a=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),n=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,c={},s=null,m=null;for(o in void 0!==r&&(s=""+r),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(m=t.ref),t)i.call(t,o)&&!l.hasOwnProperty(o)&&(c[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===c[o]&&(c[o]=t[o]);return{$$typeof:a,type:e,key:s,ref:m,props:c,_owner:n.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,o),i.exports}o.m=t,e=[],o.O=(t,r,a,i)=>{if(!r){var n=1/0;for(m=0;m=i)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(l=!1,i0&&e[m-1][2]>i;m--)e[m]=e[m-1];e[m]=[r,a,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={227:0,739:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var a,i,[n,l,c]=r,s=0;if(n.some((t=>0!==e[t]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(c)var m=c(o)}for(t&&t(r);so(456)));a=o.O(a)})(); \ No newline at end of file diff --git a/build/reply/index.asset.php b/build/reply/index.asset.php index 2e7cd8438..5cd87275b 100644 --- a/build/reply/index.asset.php +++ b/build/reply/index.asset.php @@ -1 +1 @@ - array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '808c98599517db815fc5'); + array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '9eb1d863fcf6d209ef29'); diff --git a/build/reply/index.js b/build/reply/index.js index 9cabdce19..27704083d 100644 --- a/build/reply/index.js +++ b/build/reply/index.js @@ -1 +1 @@ -(()=>{"use strict";var e={20:(e,t,r)=>{var o=r(609),n=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,s={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,l={},p=null,c=null;for(o in void 0!==r&&(p=""+r),void 0!==t.key&&(p=""+t.key),void 0!==t.ref&&(c=t.ref),t)i.call(t,o)&&!s.hasOwnProperty(o)&&(l[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===l[o]&&(l[o]=t[o]);return{$$typeof:n,type:e,key:p,ref:c,props:l,_owner:a.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,r),i.exports}const o=window.wp.blocks,n=window.wp.primitives;var i=r(848);const a=(0,i.jsx)(n.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(n.Path,{d:"M6.68822 10.625L6.24878 11.0649L5.5 11.8145L5.5 5.5L12.5 5.5V8L14 6.5V5C14 4.44772 13.5523 4 13 4H5C4.44772 4 4 4.44771 4 5V13.5247C4 13.8173 4.16123 14.086 4.41935 14.2237C4.72711 14.3878 5.10601 14.3313 5.35252 14.0845L7.31 12.125H8.375L9.875 10.625H7.31H6.68822ZM14.5605 10.4983L11.6701 13.75H16.9975C17.9963 13.75 18.7796 14.1104 19.3553 14.7048C19.9095 15.2771 20.2299 16.0224 20.4224 16.7443C20.7645 18.0276 20.7543 19.4618 20.7487 20.2544C20.7481 20.345 20.7475 20.4272 20.7475 20.4999L19.2475 20.5001C19.2475 20.4191 19.248 20.3319 19.2484 20.2394V20.2394C19.2526 19.4274 19.259 18.2035 18.973 17.1307C18.8156 16.5401 18.586 16.0666 18.2778 15.7483C17.9909 15.4521 17.5991 15.25 16.9975 15.25H11.8106L14.5303 17.9697L13.4696 19.0303L8.96956 14.5303L13.4394 9.50171L14.5605 10.4983Z"})});var s=r(609);const l=window.wp.i18n,p=window.wp.blockEditor,c=window.wp.components,w=window.wp.element,u=window.wp.data;(0,o.registerBlockType)("activitypub/reply",{edit:function({attributes:e,setAttributes:t,clientId:r,isSelected:o}){const[n,i]=(0,w.useState)(""),{insertAfterBlock:a,removeBlock:d}=(0,u.useDispatch)(p.store),v=(0,l.__)("For example: Paste a URL from a Mastodon post or note into the field above to leave a comment.","activitypub"),[f,y]=(0,w.useState)(v);return(0,s.createElement)("div",{...(0,p.useBlockProps)()},(0,s.createElement)(c.TextControl,{label:(0,l.__)("This post is a reply to the following URL","activitypub"),value:e.url,onChange:e=>{!function(e){try{return new URL(e),!0}catch(e){return!1}}(e)?(i("error"),y((0,l.__)("Please enter a valid URL.","activitypub"))):(i(""),y(v)),t({url:e})},onKeyDown:t=>{"Enter"===t.key&&a(r),!e.url&&["Backspace","Delete"].includes(t.key)&&d(r)},type:"url",placeholder:"https://example.org/path",className:n,help:o?f:""}))},save:()=>null,icon:a})})(); \ No newline at end of file +(()=>{"use strict";var e={20:(e,t,r)=>{var o=r(609),n=Symbol.for("react.element"),i=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,s={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,r){var o,l={},p=null,c=null;for(o in void 0!==r&&(p=""+r),void 0!==t.key&&(p=""+t.key),void 0!==t.ref&&(c=t.ref),t)i.call(t,o)&&!s.hasOwnProperty(o)&&(l[o]=t[o]);if(e&&e.defaultProps)for(o in t=e.defaultProps)void 0===l[o]&&(l[o]=t[o]);return{$$typeof:n,type:e,key:p,ref:c,props:l,_owner:a.current}}},848:(e,t,r)=>{e.exports=r(20)},609:e=>{e.exports=window.React}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,r),i.exports}(()=>{const e=window.wp.blocks,t=window.wp.primitives;var o=r(848);const n=(0,o.jsx)(t.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,o.jsx)(t.Path,{d:"M6.68822 10.625L6.24878 11.0649L5.5 11.8145L5.5 5.5L12.5 5.5V8L14 6.5V5C14 4.44772 13.5523 4 13 4H5C4.44772 4 4 4.44771 4 5V13.5247C4 13.8173 4.16123 14.086 4.41935 14.2237C4.72711 14.3878 5.10601 14.3313 5.35252 14.0845L7.31 12.125H8.375L9.875 10.625H7.31H6.68822ZM14.5605 10.4983L11.6701 13.75H16.9975C17.9963 13.75 18.7796 14.1104 19.3553 14.7048C19.9095 15.2771 20.2299 16.0224 20.4224 16.7443C20.7645 18.0276 20.7543 19.4618 20.7487 20.2544C20.7481 20.345 20.7475 20.4272 20.7475 20.4999L19.2475 20.5001C19.2475 20.4191 19.248 20.3319 19.2484 20.2394V20.2394C19.2526 19.4274 19.259 18.2035 18.973 17.1307C18.8156 16.5401 18.586 16.0666 18.2778 15.7483C17.9909 15.4521 17.5991 15.25 16.9975 15.25H11.8106L14.5303 17.9697L13.4696 19.0303L8.96956 14.5303L13.4394 9.50171L14.5605 10.4983Z"})});var i=r(609);const a=window.wp.i18n,s=window.wp.blockEditor,l=window.wp.components,p=window.wp.element,c=window.wp.data;(0,e.registerBlockType)("activitypub/reply",{edit:function({attributes:e,setAttributes:t,clientId:r,isSelected:o}){const[n,w]=(0,p.useState)(""),{insertAfterBlock:u,removeBlock:d}=(0,c.useDispatch)(s.store),v=(0,a.__)("For example: Paste a URL from a Mastodon post or note into the field above to leave a comment.","activitypub"),[f,y]=(0,p.useState)(v);return(0,i.createElement)("div",{...(0,s.useBlockProps)()},(0,i.createElement)(l.TextControl,{label:(0,a.__)("This post is a reply to the following URL","activitypub"),value:e.url,onChange:e=>{!function(e){try{return new URL(e),!0}catch(e){return!1}}(e)?(w("error"),y((0,a.__)("Please enter a valid URL.","activitypub"))):(w(""),y(v)),t({url:e})},onKeyDown:t=>{"Enter"===t.key&&u(r),!e.url&&["Backspace","Delete"].includes(t.key)&&d(r)},type:"url",placeholder:"https://example.org/path",className:n,help:o?f:""}))},save:()=>null,icon:n})})()})(); \ No newline at end of file diff --git a/tests/includes/class-test-federated-reactions-settings.php b/tests/includes/class-test-federated-reactions-settings.php index 2e87890f5..f09b6fc0b 100644 --- a/tests/includes/class-test-federated-reactions-settings.php +++ b/tests/includes/class-test-federated-reactions-settings.php @@ -22,8 +22,6 @@ class Test_Federated_Reactions_Settings extends \WP_UnitTestCase { public function tear_down() { parent::tear_down(); delete_option( 'activitypub_reactions_enabled' ); - $GLOBALS['wp_meta_boxes'] = array(); - $_POST = array(); } /** @@ -34,8 +32,6 @@ public function tear_down() { public function test_init() { $this->assertEquals( 11, has_action( 'init', array( Federated_Reactions_Settings::class, 'register_post_meta' ) ) ); $this->assertEquals( 10, has_action( 'admin_init', array( Federated_Reactions_Settings::class, 'register_settings' ) ) ); - $this->assertEquals( 10, has_action( 'add_meta_boxes', array( Federated_Reactions_Settings::class, 'add_meta_box' ) ) ); - $this->assertEquals( 10, has_action( 'save_post', array( Federated_Reactions_Settings::class, 'meta_box_save' ) ) ); } /** @@ -105,91 +101,6 @@ public function test_render_reactions_enabled_field() { $this->assertStringNotContainsString( 'checked=\'checked\'', $output ); } - /** - * Test adding meta box. - * - * @covers ::add_meta_box - */ - public function test_add_meta_box() { - global $wp_meta_boxes; - - Federated_Reactions_Settings::add_meta_box(); - - $this->assertArrayHasKey( 'post', $wp_meta_boxes ); - $this->assertArrayHasKey( 'side', $wp_meta_boxes['post'] ); - $this->assertArrayHasKey( 'default', $wp_meta_boxes['post']['side'] ); - $this->assertArrayHasKey( 'activitypub_reactions', $wp_meta_boxes['post']['side']['default'] ); - } - - /** - * Test rendering of meta box. - * - * @covers ::render_meta_box - */ - public function test_render_meta_box() { - $post = self::factory()->post->create_and_get(); - - // Test with default value (no meta set). - update_option( 'activitypub_reactions_enabled', '1' ); - ob_start(); - Federated_Reactions_Settings::render_meta_box( $post ); - $output = ob_get_clean(); - - $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); - $this->assertStringContainsString( 'value="1"', $output ); - $this->assertStringContainsString( 'checked=\'checked\'', $output ); - - // Test with meta value set. - update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); - ob_start(); - Federated_Reactions_Settings::render_meta_box( $post ); - $output = ob_get_clean(); - - $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); - $this->assertStringContainsString( 'value="1"', $output ); - $this->assertStringNotContainsString( 'checked=\'checked\'', $output ); - } - - /** - * Test saving meta box data. - * - * @covers ::meta_box_save - */ - public function test_meta_box_save() { - $post = self::factory()->post->create_and_get(); - $user_id = self::factory()->user->create( array( 'role' => 'administrator' ) ); - wp_set_current_user( $user_id ); - - // Test with missing nonce. - $_POST = array(); - Federated_Reactions_Settings::meta_box_save( $post->ID ); - $this->assertEmpty( get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); - - // Test with invalid nonce. - $_POST = array( - 'activitypub_reactions_meta_box_nonce' => 'invalid', - ); - Federated_Reactions_Settings::meta_box_save( $post->ID ); - $this->assertEmpty( get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); - - // Test with valid data - checkbox checked. - $_POST = array( - 'activitypub_reactions_meta_box_nonce' => wp_create_nonce( 'activitypub_reactions_meta_box' ), - 'activitypub_reactions_enabled' => '1', - ); - Federated_Reactions_Settings::meta_box_save( $post->ID ); - $this->assertEquals( '1', get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); - - // Test with valid data - checkbox unchecked. - $_POST = array( - 'activitypub_reactions_meta_box_nonce' => wp_create_nonce( 'activitypub_reactions_meta_box' ), - ); - Federated_Reactions_Settings::meta_box_save( $post->ID ); - $this->assertEquals( '0', get_post_meta( $post->ID, 'activitypub_reactions_enabled', true ) ); - } - /** * Test checking if reactions are enabled. * @@ -199,18 +110,17 @@ public function test_is_reactions_enabled() { $post = self::factory()->post->create_and_get(); // Test with default global setting. - update_option( 'activitypub_reactions_enabled', '1' ); $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); - // Test with disabled global setting. + // Test with global setting disabled. update_option( 'activitypub_reactions_enabled', '0' ); $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); - // Test with post meta overriding global setting. + // Test with global setting enabled but post setting disabled. update_option( 'activitypub_reactions_enabled', '1' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); - + update_option( 'activitypub_reactions_enabled', '0' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '1' ); $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); From 826dc6c207657814f27e8b13b8774aca6ee72a84 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 17:14:19 -0600 Subject: [PATCH 32/47] lint --- includes/class-blocks.php | 2 +- tests/includes/class-test-federated-reactions-settings.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index f9a66eb9a..da8228a8e 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -149,7 +149,7 @@ public static function register_blocks() { ) ); - // Only register reactions block if globally enabled + // Only register reactions block if globally enabled. if ( get_option( 'activitypub_reactions_enabled', '1' ) === '1' ) { \register_block_type_from_metadata( ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', diff --git a/tests/includes/class-test-federated-reactions-settings.php b/tests/includes/class-test-federated-reactions-settings.php index f09b6fc0b..b6d985520 100644 --- a/tests/includes/class-test-federated-reactions-settings.php +++ b/tests/includes/class-test-federated-reactions-settings.php @@ -120,7 +120,7 @@ public function test_is_reactions_enabled() { update_option( 'activitypub_reactions_enabled', '1' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); - + update_option( 'activitypub_reactions_enabled', '0' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '1' ); $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); From 8f60aeb85f2aa10702852ef33ba181128c2b8285 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Fri, 13 Dec 2024 18:45:54 -0600 Subject: [PATCH 33/47] add reactions endpoint tests --- tests/includes/rest/class-test-post.php | 193 ++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tests/includes/rest/class-test-post.php diff --git a/tests/includes/rest/class-test-post.php b/tests/includes/rest/class-test-post.php new file mode 100644 index 000000000..91bfa7ba5 --- /dev/null +++ b/tests/includes/rest/class-test-post.php @@ -0,0 +1,193 @@ +server = $wp_rest_server; + + do_action( 'rest_api_init' ); + } + + /** + * Test initialization of hooks. + * + * @covers ::init + */ + public function test_init() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/(?P\d+)/reactions', $routes ); + } + + /** + * Test getting reactions for a non-existent post. + * + * @covers ::get_reactions + */ + public function test_get_reactions_non_existent_post() { + $request = new WP_REST_Request( 'GET', '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/999999/reactions' ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + $this->assertEquals( 'post_not_found', $response->get_data()['code'] ); + } + + /** + * Test getting reactions for a post with no reactions. + * + * @covers ::get_reactions + */ + public function test_get_reactions_no_reactions() { + $post_id = self::factory()->post->create(); + $request = new WP_REST_Request( 'GET', '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/' . $post_id . '/reactions' ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEmpty( $response->get_data() ); + } + + /** + * Test getting reactions for a post with reactions. + * + * @covers ::get_reactions + */ + public function test_get_reactions_with_reactions() { + $post_id = self::factory()->post->create(); + + // Create a "like" reaction. + $comment_data = array( + 'comment_post_ID' => $post_id, + 'comment_author' => 'Test User', + 'comment_author_url' => 'https://example.com/user', + 'comment_author_email' => '', + 'comment_content' => '', + 'comment_type' => 'like', + 'comment_parent' => 0, + 'user_id' => 0, + 'comment_approved' => 1, + ); + $comment_id = wp_insert_comment( $comment_data ); + update_comment_meta( $comment_id, 'avatar_url', 'https://example.com/avatar.jpg' ); + + $request = new WP_REST_Request( 'GET', '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/' . $post_id . '/reactions' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertArrayHasKey( 'likes', $data ); + $this->assertEquals( '1 like', $data['likes']['label'] ); + $this->assertCount( 1, $data['likes']['items'] ); + + $item = $data['likes']['items'][0]; + $this->assertEquals( 'Test User', $item['name'] ); + $this->assertEquals( 'https://example.com/user', $item['url'] ); + $this->assertEquals( 'https://example.com/avatar.jpg', $item['avatar'] ); + } + + /** + * Test getting reactions for a post with multiple reaction types. + * + * @covers ::get_reactions + */ + public function test_get_reactions_multiple_types() { + $post_id = self::factory()->post->create(); + + // Create reactions of different types. + $reaction_types = array( + array( + 'type' => 'like', + 'author' => 'Like User', + 'url' => 'https://example.com/like-user', + ), + array( + 'type' => 'repost', + 'author' => 'Announce User', + 'url' => 'https://example.com/announce-user', + ), + ); + + foreach ( $reaction_types as $reaction ) { + $comment_data = array( + 'comment_post_ID' => $post_id, + 'comment_author' => $reaction['author'], + 'comment_author_url' => $reaction['url'], + 'comment_author_email' => '', + 'comment_content' => '', + 'comment_type' => $reaction['type'], + 'comment_parent' => 0, + 'user_id' => 0, + 'comment_approved' => 1, + ); + wp_insert_comment( $comment_data ); + } + + $request = new WP_REST_Request( 'GET', '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/' . $post_id . '/reactions' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertArrayHasKey( 'likes', $data ); + $this->assertArrayHasKey( 'reposts', $data ); + $this->assertEquals( '1 like', $data['likes']['label'] ); + $this->assertEquals( '1 repost', $data['reposts']['label'] ); + } + + /** + * Test getting reactions respects comment approval status. + * + * @covers ::get_reactions + */ + public function test_get_reactions_respects_approval() { + $post_id = self::factory()->post->create(); + + // Create an unapproved reaction. + $comment_data = array( + 'comment_post_ID' => $post_id, + 'comment_author' => 'Test User', + 'comment_author_url' => 'https://example.com/user', + 'comment_author_email' => '', + 'comment_content' => '', + 'comment_type' => 'like', + 'comment_parent' => 0, + 'user_id' => 0, + 'comment_approved' => 0, + ); + wp_insert_comment( $comment_data ); + + $request = new WP_REST_Request( 'GET', '/' . ACTIVITYPUB_REST_NAMESPACE . '/posts/' . $post_id . '/reactions' ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEmpty( $response->get_data() ); + } +} From 2b5c69694a4ff539416220729013b05fbad55763 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 16 Dec 2024 08:32:08 -0600 Subject: [PATCH 34/47] Move reactions setting to Activitypub settings See https://github.com/Automattic/wordpress-activitypub/pull/1070#discussion_r1886688035 --- includes/class-federated-reactions-settings.php | 7 ++++--- templates/settings.php | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/class-federated-reactions-settings.php b/includes/class-federated-reactions-settings.php index 7832f0ebe..84c63b3d6 100644 --- a/includes/class-federated-reactions-settings.php +++ b/includes/class-federated-reactions-settings.php @@ -46,7 +46,7 @@ public static function register_post_meta() { */ public static function register_settings() { register_setting( - 'discussion', + 'activitypub', 'activitypub_reactions_enabled', array( 'type' => 'boolean', @@ -59,7 +59,8 @@ public static function register_settings() { 'activitypub_reactions_enabled', __( 'Federated Reactions', 'activitypub' ), array( self::class, 'render_reactions_enabled_field' ), - 'discussion' + 'activitypub', + 'activity' ); } @@ -72,7 +73,7 @@ public static function render_reactions_enabled_field() {

diff --git a/templates/settings.php b/templates/settings.php index fd29a784b..dec95197b 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -183,10 +183,9 @@

+ - -
From c5d65516b52b0684472f71d6de8701967e4c41b2 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 16 Dec 2024 08:34:37 -0600 Subject: [PATCH 35/47] Rename settings class. See https://github.com/Automattic/wordpress-activitypub/pull/1070#discussion_r1884618732 --- ...tings.php => class-reactions-settings.php} | 6 ++-- ....php => class-test-reactions-settings.php} | 28 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) rename includes/{class-federated-reactions-settings.php => class-reactions-settings.php} (95%) rename tests/includes/{class-test-federated-reactions-settings.php => class-test-reactions-settings.php} (76%) diff --git a/includes/class-federated-reactions-settings.php b/includes/class-reactions-settings.php similarity index 95% rename from includes/class-federated-reactions-settings.php rename to includes/class-reactions-settings.php index 84c63b3d6..bb4f22c19 100644 --- a/includes/class-federated-reactions-settings.php +++ b/includes/class-reactions-settings.php @@ -1,6 +1,6 @@ assertEquals( 11, has_action( 'init', array( Federated_Reactions_Settings::class, 'register_post_meta' ) ) ); - $this->assertEquals( 10, has_action( 'admin_init', array( Federated_Reactions_Settings::class, 'register_settings' ) ) ); + $this->assertEquals( 11, has_action( 'init', array( Reactions_Settings::class, 'register_post_meta' ) ) ); + $this->assertEquals( 10, has_action( 'admin_init', array( Reactions_Settings::class, 'register_settings' ) ) ); } /** @@ -40,7 +40,7 @@ public function test_init() { * @covers ::register_post_meta */ public function test_register_post_meta() { - Federated_Reactions_Settings::register_post_meta(); + Reactions_Settings::register_post_meta(); $post_type = 'post'; $registered = get_registered_meta_keys( 'post', $post_type ); @@ -63,7 +63,7 @@ public function test_register_post_meta() { * @covers ::register_settings */ public function test_register_settings() { - Federated_Reactions_Settings::register_settings(); + Reactions_Settings::register_settings(); $registered = get_registered_settings(); $this->assertArrayHasKey( 'activitypub_reactions_enabled', $registered ); @@ -81,7 +81,7 @@ public function test_render_reactions_enabled_field() { // Test with default value. update_option( 'activitypub_reactions_enabled', '1' ); ob_start(); - Federated_Reactions_Settings::render_reactions_enabled_field(); + Reactions_Settings::render_reactions_enabled_field(); $output = ob_get_clean(); $this->assertStringContainsString( 'assertStringContainsString( 'post->create_and_get(); // Test with default global setting. - $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + $this->assertTrue( Reactions_Settings::is_reactions_enabled( $post->ID ) ); // Test with global setting disabled. update_option( 'activitypub_reactions_enabled', '0' ); - $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + $this->assertFalse( Reactions_Settings::is_reactions_enabled( $post->ID ) ); // Test with global setting enabled but post setting disabled. update_option( 'activitypub_reactions_enabled', '1' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); - $this->assertFalse( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + $this->assertFalse( Reactions_Settings::is_reactions_enabled( $post->ID ) ); update_option( 'activitypub_reactions_enabled', '0' ); update_post_meta( $post->ID, 'activitypub_reactions_enabled', '1' ); - $this->assertTrue( Federated_Reactions_Settings::is_reactions_enabled( $post->ID ) ); + $this->assertTrue( Reactions_Settings::is_reactions_enabled( $post->ID ) ); } } From 4dbf9e6391e0538ec8ec17ee7ff1512322ac1510 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 16 Dec 2024 08:39:03 -0600 Subject: [PATCH 36/47] Rename remaining class reference --- activitypub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activitypub.php b/activitypub.php index a001d3894..f00f24e4c 100644 --- a/activitypub.php +++ b/activitypub.php @@ -65,7 +65,7 @@ function plugin_init() { \add_action( 'init', array( __NAMESPACE__ . '\Migration', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activitypub', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activity_Dispatcher', 'init' ) ); - \add_action( 'init', array( __NAMESPACE__ . '\Federated_Reactions_Settings', 'init' ) ); + \add_action( 'init', array( __NAMESPACE__ . '\Reactions_Settings', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Handler', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Admin', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Hashtag', 'init' ) ); From f58651bcf17da55c0e25a20b6513e42f3c9da272 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 16 Dec 2024 15:46:25 +0100 Subject: [PATCH 37/47] move all settings hooks --- templates/settings.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/templates/settings.php b/templates/settings.php index dec95197b..00bb02f51 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -59,10 +59,9 @@

+ - -
@@ -231,10 +230,10 @@

+ + - -

@@ -261,9 +260,9 @@ + -
From fb7197c7ef2d316f4d65257f54c4f554d58d35b7 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 16 Dec 2024 08:52:35 -0600 Subject: [PATCH 38/47] =?UTF-8?q?This=20refactor=20manager=20didn't=20do?= =?UTF-8?q?=20its=20job=20at=20all=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/class-blocks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index da8228a8e..639280414 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -169,7 +169,7 @@ public static function register_blocks() { */ public static function render_post_reactions_block( $attrs ) { // Check if reactions are enabled, generally, or for the current post. - if ( ! Federated_Reactions_Settings::is_reactions_enabled() ) { + if ( ! Reactions_Settings::is_reactions_enabled() ) { return ''; } @@ -412,7 +412,7 @@ public static function maybe_add_fediverse_reactions( $content ) { return $content; } - if ( ! Federated_Reactions_Settings::is_reactions_enabled() ) { + if ( ! Reactions_Settings::is_reactions_enabled() ) { return $content; } From 3129aea7ffed1fc8e028378c294acff72b3e0fd8 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 16 Dec 2024 09:15:55 -0600 Subject: [PATCH 39/47] Bring back meta box for Classic Editor users. See https://github.com/Automattic/wordpress-activitypub/pull/1070#discussion_r1886829441 --- includes/class-reactions-settings.php | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/includes/class-reactions-settings.php b/includes/class-reactions-settings.php index bb4f22c19..49d48b3bc 100644 --- a/includes/class-reactions-settings.php +++ b/includes/class-reactions-settings.php @@ -18,6 +18,8 @@ class Reactions_Settings { public static function init() { add_action( 'init', array( self::class, 'register_post_meta' ), 11 ); add_action( 'admin_init', array( self::class, 'register_settings' ) ); + add_action( 'add_meta_boxes', array( self::class, 'add_meta_box' ) ); + add_action( 'save_post', array( self::class, 'save_meta_box' ) ); } /** @@ -82,6 +84,74 @@ public static function render_reactions_enabled_field() { ID, 'activitypub_reactions_enabled', true ); + if ( '' === $value ) { + $value = '1'; // Default to enabled. + } + ?> + +

+ +

+ Date: Mon, 16 Dec 2024 10:33:26 -0600 Subject: [PATCH 40/47] always register block --- includes/class-blocks.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/includes/class-blocks.php b/includes/class-blocks.php index 639280414..b29386ad5 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -149,15 +149,12 @@ public static function register_blocks() { ) ); - // Only register reactions block if globally enabled. - if ( get_option( 'activitypub_reactions_enabled', '1' ) === '1' ) { - \register_block_type_from_metadata( - ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', - array( - 'render_callback' => array( self::class, 'render_post_reactions_block' ), - ) - ); - } + \register_block_type_from_metadata( + ACTIVITYPUB_PLUGIN_DIR . '/build/reactions', + array( + 'render_callback' => array( self::class, 'render_post_reactions_block' ), + ) + ); } /** From aab821d406f3f532ac5d1f766a947270be40b2a4 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Mon, 16 Dec 2024 12:31:45 -0600 Subject: [PATCH 41/47] setting for non-block themes only --- includes/class-reactions-settings.php | 76 ++++++++++++++++++++------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/includes/class-reactions-settings.php b/includes/class-reactions-settings.php index 49d48b3bc..36f01048c 100644 --- a/includes/class-reactions-settings.php +++ b/includes/class-reactions-settings.php @@ -18,8 +18,10 @@ class Reactions_Settings { public static function init() { add_action( 'init', array( self::class, 'register_post_meta' ), 11 ); add_action( 'admin_init', array( self::class, 'register_settings' ) ); - add_action( 'add_meta_boxes', array( self::class, 'add_meta_box' ) ); - add_action( 'save_post', array( self::class, 'save_meta_box' ) ); + if ( self::is_reactions_globally_enabled() ) { + add_action( 'add_meta_boxes', array( self::class, 'add_meta_box' ) ); + add_action( 'save_post', array( self::class, 'save_meta_box' ) ); + } } /** @@ -70,18 +72,47 @@ public static function register_settings() { * Render the reactions enabled field. */ public static function render_reactions_enabled_field() { - ?> -
- - -

- + if ( ! wp_is_block_theme() ) { + ?> +

+ + +

+ +

+
+ 'wp_template', + 'postId' => get_stylesheet() . '//single', + 'canvas' => 'edit', + ), + admin_url( 'site-editor.php' ) + ); + ?> +

+ Edit Single Posts template', 'activitypub' ), + array( + 'a' => array( + 'href' => array(), + ), + ) + ), + esc_url( $editor_url ) + ); + ?>

-
- Date: Mon, 16 Dec 2024 12:49:59 -0600 Subject: [PATCH 42/47] subtler animations --- build/reactions/index.asset.php | 2 +- build/reactions/index.js | 2 +- build/reactions/style-index-rtl.css | 1 - build/reactions/style-index.css | 2 +- build/reactions/view.asset.php | 2 +- build/reactions/view.js | 2 +- src/reactions/reactions.js | 6 +++--- src/reactions/style.scss | 8 ++++---- 8 files changed, 12 insertions(+), 13 deletions(-) delete mode 100644 build/reactions/style-index-rtl.css diff --git a/build/reactions/index.asset.php b/build/reactions/index.asset.php index 1376d4cb9..13d11e417 100644 --- a/build/reactions/index.asset.php +++ b/build/reactions/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '1428460a7cd0bc1c8486'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'd2ab9060d8af2ad682c4'); diff --git a/build/reactions/index.js b/build/reactions/index.js index fc7abfed1..4e4a70276 100644 --- a/build/reactions/index.js +++ b/build/reactions/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,l=window.wp.blockEditor,o=window.wp.element,s=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=a.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,a]=(0,o.useState)(new Set),[r,l]=(0,o.useState)(new Map),s=(0,o.useRef)([]),i=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},c=(t,r)=>{i();const n=150,o=e.length;r&&l((e=>{const a=new Map(e);return a.set(t,"clockwise"),a}));const c=e=>{const i="right"===e,c=i?o-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const o=Math.abs(e-t),i=setTimeout((()=>{a((t=>{const a=new Set(t);return r?a.add(e):a.delete(e),a})),r&&e!==t&&l((t=>{const a=new Map(t),r=e-u,n=a.get(r);return a.set(e,"clockwise"===n?"counter":"clockwise"),a}))}),o*n);s.current.push(i)}};if(c("right"),c("left"),!r){const e=Math.max((o-t)*n,t*n),a=setTimeout((()=>{l(new Map)}),e+n);s.current.push(a)}};return(0,o.useEffect)((()=>()=>i()),[]),(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>{const l=r.get(a),o=["reaction-avatar",t.has(a)?"wave-active":"",l?`rotate-${l}`:""].filter(Boolean).join(" ");return(0,n.createElement)("li",{key:a},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(a,!0),onMouseLeave:()=>c(a,!1)},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[a,r]=(0,o.useState)(!1),[l,s]=(0,o.useState)(null),[c,u]=(0,o.useState)(e.length),m=(0,o.useRef)(null);(0,o.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const a=t.offsetWidth-(l?.offsetWidth||0)-12,r=Math.max(1,Math.floor((a-32)/22));u(Math.min(r,e.length))};t();const a=new ResizeObserver(t);return a.observe(m.current),()=>{a.disconnect()}}),[l,e.length]);const f=e.slice(0,c);return(0,n.createElement)("div",{className:"reaction-group",ref:m},(0,n.createElement)(h,{reactions:f}),(0,n.createElement)(i.Button,{ref:s,className:"reaction-label is-link",onClick:()=>r(!a),"aria-expanded":a},t),a&&l&&(0,n.createElement)(i.Popover,{anchor:l,onClose:()=>r(!1)},(0,n.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:i=null}){const[c,h]=(0,o.useState)(i),[p,d]=(0,o.useState)(!i);return(0,o.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/posts/${t}/reactions`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(l.RichText,{tagName:"h4",value:e,onChange:r,placeholder:(0,s.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h4",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,n.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const g=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a=(()=>{const e=["Bouncy","Cosmic","Dancing","Fluffy","Giggly","Hoppy","Jazzy","Magical","Nifty","Perky","Quirky","Sparkly","Twirly","Wiggly","Zippy"],t=["Badger","Capybara","Dolphin","Echidna","Flamingo","Giraffe","Hedgehog","Iguana","Jellyfish","Koala","Lemur","Manatee","Narwhal","Octopus","Penguin"];return`${e[Math.floor(Math.random()*e.length)]} ${t[Math.floor(Math.random()*t.length)]}`})(),r=t[Math.floor(Math.random()*t.length)],n=a.charAt(0),l=document.createElement("canvas");l.width=64,l.height=64;const o=l.getContext("2d");return o.fillStyle=r,o.beginPath(),o.arc(32,32,32,0,2*Math.PI),o.fill(),o.fillStyle="#FFFFFF",o.font="32px sans-serif",o.textAlign="center",o.textBaseline="middle",o.fillText(n,32,32),{name:a,url:"#",avatar:l.toDataURL()}},v=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(v.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:a}){const r=(0,l.useBlockProps)({className:a}),[s]=(0,o.useState)({likes:{label:"9 likes",items:Array.from({length:9},((e,t)=>g()))},reposts:{label:"6 reposts",items:Array.from({length:6},((e,t)=>g()))}});return(0,n.createElement)("div",{...r},(0,n.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:s}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,r),l.exports}r.m=t,e=[],r.O=(t,a,n,l)=>{if(!a){var o=1/0;for(u=0;u=l)&&Object.keys(r.O).every((e=>r.O[e](a[i])))?a.splice(i--,1):(s=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[o,s,i]=a,c=0;if(o.some((t=>0!==e[t]))){for(n in s)r.o(s,n)&&(r.m[n]=s[n]);if(i)var u=i(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={505:(e,t,a)=>{const r=window.wp.blocks,n=window.React,l=window.wp.blockEditor,o=window.wp.element,s=window.wp.i18n,i=window.wp.components,c=window.wp.apiFetch;var u=a.n(c);const{namespace:m}=window._activityPubOptions,h=({reactions:e})=>{const[t,a]=(0,o.useState)(new Set),[r,l]=(0,o.useState)(new Map),s=(0,o.useRef)([]),i=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},c=(t,r)=>{i();const n=100,o=e.length;r&&l((e=>{const a=new Map(e);return a.set(t,"clockwise"),a}));const c=e=>{const i="right"===e,c=i?o-1:0,u=i?1:-1;for(let e=i?t:t-1;i?e<=c:e>=c;e+=u){const o=Math.abs(e-t),i=setTimeout((()=>{a((t=>{const a=new Set(t);return r?a.add(e):a.delete(e),a})),r&&e!==t&&l((t=>{const a=new Map(t),r=e-u,n=a.get(r);return a.set(e,"clockwise"===n?"counter":"clockwise"),a}))}),o*n);s.current.push(i)}};if(c("right"),c("left"),!r){const e=Math.max((o-t)*n,t*n),a=setTimeout((()=>{l(new Map)}),e+n);s.current.push(a)}};return(0,o.useEffect)((()=>()=>i()),[]),(0,n.createElement)("ul",{className:"reaction-avatars"},e.map(((e,a)=>{const l=r.get(a),o=["reaction-avatar",t.has(a)?"wave-active":"",l?`rotate-${l}`:""].filter(Boolean).join(" ");return(0,n.createElement)("li",{key:a},(0,n.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>c(a,!0),onMouseLeave:()=>c(a,!1)},(0,n.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},p=({reactions:e,type:t})=>(0,n.createElement)("ul",{className:"reaction-list"},e.map(((e,t)=>(0,n.createElement)("li",{key:t},(0,n.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,n.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,n.createElement)("span",null,e.name)))))),f=({items:e,label:t})=>{const[a,r]=(0,o.useState)(!1),[l,s]=(0,o.useState)(null),[c,u]=(0,o.useState)(e.length),m=(0,o.useRef)(null);(0,o.useEffect)((()=>{if(!m.current)return;const t=()=>{const t=m.current;if(!t)return;const a=t.offsetWidth-(l?.offsetWidth||0)-12,r=Math.max(1,Math.floor((a-32)/22));u(Math.min(r,e.length))};t();const a=new ResizeObserver(t);return a.observe(m.current),()=>{a.disconnect()}}),[l,e.length]);const f=e.slice(0,c);return(0,n.createElement)("div",{className:"reaction-group",ref:m},(0,n.createElement)(h,{reactions:f}),(0,n.createElement)(i.Button,{ref:s,className:"reaction-label is-link",onClick:()=>r(!a),"aria-expanded":a},t),a&&l&&(0,n.createElement)(i.Popover,{anchor:l,onClose:()=>r(!1)},(0,n.createElement)(p,{reactions:e})))};function d({title:e="",postId:t=null,isEditing:a=!1,setTitle:r=(()=>{}),reactions:i=null}){const[c,h]=(0,o.useState)(i),[p,d]=(0,o.useState)(!i);return(0,o.useEffect)((()=>{if(i)return h(i),void d(!1);t?(d(!0),u()({path:`/${m}/posts/${t}/reactions`}).then((e=>{h(e),d(!1)})).catch((()=>d(!1)))):d(!1)}),[t,i]),p?null:c&&Object.values(c).some((e=>e.items?.length>0))?(0,n.createElement)("div",{className:"activitypub-reactions"},a?(0,n.createElement)(l.RichText,{tagName:"h6",value:e,onChange:r,placeholder:(0,s.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,n.createElement)("h6",null,e),Object.entries(c).map((([e,t])=>t.items?.length?(0,n.createElement)(f,{key:e,items:t.items,label:t.label}):null))):null}const g=e=>{const t=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEEAD","#D4A5A5","#9B59B6","#3498DB","#E67E22"],a=(()=>{const e=["Bouncy","Cosmic","Dancing","Fluffy","Giggly","Hoppy","Jazzy","Magical","Nifty","Perky","Quirky","Sparkly","Twirly","Wiggly","Zippy"],t=["Badger","Capybara","Dolphin","Echidna","Flamingo","Giraffe","Hedgehog","Iguana","Jellyfish","Koala","Lemur","Manatee","Narwhal","Octopus","Penguin"];return`${e[Math.floor(Math.random()*e.length)]} ${t[Math.floor(Math.random()*t.length)]}`})(),r=t[Math.floor(Math.random()*t.length)],n=a.charAt(0),l=document.createElement("canvas");l.width=64,l.height=64;const o=l.getContext("2d");return o.fillStyle=r,o.beginPath(),o.arc(32,32,32,0,2*Math.PI),o.fill(),o.fillStyle="#FFFFFF",o.font="32px sans-serif",o.textAlign="center",o.textBaseline="middle",o.fillText(n,32,32),{name:a,url:"#",avatar:l.toDataURL()}},v=JSON.parse('{"UU":"activitypub/reactions"}');(0,r.registerBlockType)(v.UU,{edit:function({attributes:e,setAttributes:t,__unstableLayoutClassNames:a}){const r=(0,l.useBlockProps)({className:a}),[s]=(0,o.useState)({likes:{label:"9 likes",items:Array.from({length:9},((e,t)=>g()))},reposts:{label:"6 reposts",items:Array.from({length:6},((e,t)=>g()))}});return(0,n.createElement)("div",{...r},(0,n.createElement)(d,{isEditing:!0,title:e.title,setTitle:e=>t({title:e}),reactions:s}))}})}},a={};function r(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,r),l.exports}r.m=t,e=[],r.O=(t,a,n,l)=>{if(!a){var o=1/0;for(u=0;u=l)&&Object.keys(r.O).every((e=>r.O[e](a[i])))?a.splice(i--,1):(s=!1,l0&&e[u-1][2]>l;u--)e[u]=e[u-1];e[u]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={608:0,104:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[o,s,i]=a,c=0;if(o.some((t=>0!==e[t]))){for(n in s)r.o(s,n)&&(r.m[n]=s[n]);if(i)var u=i(r)}for(t&&t(a);cr(505)));n=r.O(n)})(); \ No newline at end of file diff --git a/build/reactions/style-index-rtl.css b/build/reactions/style-index-rtl.css deleted file mode 100644 index 67e8a23b9..000000000 --- a/build/reactions/style-index-rtl.css +++ /dev/null @@ -1 +0,0 @@ -.activitypub-reactions h6{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 0 0 -10px;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-left:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/style-index.css b/build/reactions/style-index.css index 8fc74db89..3f711936f 100644 --- a/build/reactions/style-index.css +++ b/build/reactions/style-index.css @@ -1 +1 @@ -.activitypub-reactions h6{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform 1s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-16px) scale(1.2)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-16px) scale(1.2) rotate(1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-16px) scale(1.2) rotate(-1turn)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} +.activitypub-reactions h6{border-top:1px solid;border-top-color:var(--wp--preset--color--contrast-2);display:inline-block;padding-top:.5em}.activitypub-reactions .reaction-group{align-items:center;display:flex;gap:.75em;justify-content:flex-start;margin:.5em 0;position:relative;width:100%}@media(max-width:782px){.activitypub-reactions .reaction-group:has(.reaction-avatars:not(:empty)){justify-content:space-between}}.activitypub-reactions .reaction-avatars{align-items:center;display:flex;flex-direction:row;list-style:none;margin:0;padding:0}.activitypub-reactions .reaction-avatars li{margin:0 -10px 0 0;padding:0}.activitypub-reactions .reaction-avatars li:last-child{margin-right:0}.activitypub-reactions .reaction-avatars li a{display:block;text-decoration:none}.activitypub-reactions .reaction-avatars .reaction-avatar{border:.5px solid hsla(0,0%,100%,.8);border-radius:50%;box-shadow:0 0 0 .5px hsla(0,0%,100%,.8),0 1px 3px rgba(0,0,0,.2);height:32px;transition:transform .6s cubic-bezier(.34,1.56,.64,1);width:32px;will-change:transform}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active{transform:translateY(-5px)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-clockwise{transform:translateY(-5px) rotate(30deg)}.activitypub-reactions .reaction-avatars .reaction-avatar.wave-active.rotate-counter{transform:translateY(-5px) rotate(-30deg)}.activitypub-reactions .reaction-avatars .reaction-avatar:hover{position:relative;z-index:1}.activitypub-reactions .reaction-label.components-button{color:#2271b1;flex:0 0 auto;height:auto;padding:0;text-decoration:none;white-space:nowrap}.activitypub-reactions .reaction-label.components-button:hover{color:#135e96;text-decoration:underline}.activitypub-reactions .reaction-label.components-button:focus:not(:disabled){box-shadow:none;outline:1px solid #135e96;outline-offset:2px}.reaction-list{list-style:none;margin:0;max-width:300px;min-width:200px;padding:.25em .5em;width:-moz-max-content;width:max-content}.reaction-list li{font-size:var(--wp--preset--font-size--small);margin:0;padding:0}.reaction-list a{align-items:center;color:inherit;display:flex;font-size:var(--wp--preset--font-size--small,.75rem);gap:.5em;justify-content:flex-start;padding:.5em;text-decoration:none}.reaction-list a:hover{text-decoration:underline}.reaction-list a img{border-radius:50%;flex:none;height:24px;width:24px} diff --git a/build/reactions/view.asset.php b/build/reactions/view.asset.php index 257053d2b..f33b7ed58 100644 --- a/build/reactions/view.asset.php +++ b/build/reactions/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '0e2791f56cd75776751b'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'f1f89b7613b2985f097f'); diff --git a/build/reactions/view.js b/build/reactions/view.js index e1ac209dd..e4c023ad3 100644 --- a/build/reactions/view.js +++ b/build/reactions/view.js @@ -1 +1 @@ -(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,o=window.wp.components,s=window.wp.apiFetch;var l=e.n(s);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),[c,o]=(0,n.useState)(new Map),s=(0,n.useRef)([]),l=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},i=(t,n)=>{l();const a=150,c=e.length;n&&o((e=>{const n=new Map(e);return n.set(t,"clockwise"),n}));const i=e=>{const l="right"===e,i=l?c-1:0,u=l?1:-1;for(let e=l?t:t-1;l?e<=i:e>=i;e+=u){const c=Math.abs(e-t),l=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a})),n&&e!==t&&o((t=>{const n=new Map(t),a=e-u,r=n.get(a);return n.set(e,"clockwise"===r?"counter":"clockwise"),n}))}),c*a);s.current.push(l)}};if(i("right"),i("left"),!n){const e=Math.max((c-t)*a,t*a),n=setTimeout((()=>{o(new Map)}),e+a);s.current.push(n)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>{const r=c.get(n),o=["reaction-avatar",a.has(n)?"wave-active":"",r?`rotate-${r}`:""].filter(Boolean).join(" ");return(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>i(n,!0),onMouseLeave:()=>i(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},h=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[s,l]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),d=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const n=t.offsetWidth-(s?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(d.current),()=>{n.disconnect()}}),[s,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:d},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(o.Button,{ref:l,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&s&&(0,t.createElement)(o.Popover,{anchor:s,onClose:()=>c(!1)},(0,t.createElement)(h,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:o=(()=>{}),reactions:s=null}){const[m,h]=(0,n.useState)(s),[p,w]=(0,n.useState)(!s);return(0,n.useEffect)((()=>{if(s)return h(s),void w(!1);a?(w(!0),l()({path:`/${u}/posts/${a}/reactions`}).then((e=>{h(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,s]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h4",value:e,onChange:o,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h4",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(d,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file +(()=>{"use strict";var e={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{for(var a in n)e.o(n,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:n[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,n=window.wp.element,a=window.wp.domReady;var r=e.n(a);const c=window.wp.blockEditor,o=window.wp.components,s=window.wp.apiFetch;var l=e.n(s);const i=window.wp.i18n,{namespace:u}=window._activityPubOptions,m=({reactions:e})=>{const[a,r]=(0,n.useState)(new Set),[c,o]=(0,n.useState)(new Map),s=(0,n.useRef)([]),l=()=>{s.current.forEach((e=>clearTimeout(e))),s.current=[]},i=(t,n)=>{l();const a=100,c=e.length;n&&o((e=>{const n=new Map(e);return n.set(t,"clockwise"),n}));const i=e=>{const l="right"===e,i=l?c-1:0,u=l?1:-1;for(let e=l?t:t-1;l?e<=i:e>=i;e+=u){const c=Math.abs(e-t),l=setTimeout((()=>{r((t=>{const a=new Set(t);return n?a.add(e):a.delete(e),a})),n&&e!==t&&o((t=>{const n=new Map(t),a=e-u,r=n.get(a);return n.set(e,"clockwise"===r?"counter":"clockwise"),n}))}),c*a);s.current.push(l)}};if(i("right"),i("left"),!n){const e=Math.max((c-t)*a,t*a),n=setTimeout((()=>{o(new Map)}),e+a);s.current.push(n)}};return(0,n.useEffect)((()=>()=>l()),[]),(0,t.createElement)("ul",{className:"reaction-avatars"},e.map(((e,n)=>{const r=c.get(n),o=["reaction-avatar",a.has(n)?"wave-active":"",r?`rotate-${r}`:""].filter(Boolean).join(" ");return(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",onMouseEnter:()=>i(n,!0),onMouseLeave:()=>i(n,!1)},(0,t.createElement)("img",{src:e.avatar,alt:e.name,className:o,width:"32",height:"32"})))})))},h=({reactions:e,type:n})=>(0,t.createElement)("ul",{className:"reaction-list"},e.map(((e,n)=>(0,t.createElement)("li",{key:n},(0,t.createElement)("a",{href:e.url,className:"reaction-item",target:"_blank",rel:"noopener noreferrer"},(0,t.createElement)("img",{src:e.avatar,alt:e.name,width:"32",height:"32"}),(0,t.createElement)("span",null,e.name)))))),d=({items:e,label:a})=>{const[r,c]=(0,n.useState)(!1),[s,l]=(0,n.useState)(null),[i,u]=(0,n.useState)(e.length),d=(0,n.useRef)(null);(0,n.useEffect)((()=>{if(!d.current)return;const t=()=>{const t=d.current;if(!t)return;const n=t.offsetWidth-(s?.offsetWidth||0)-12,a=Math.max(1,Math.floor((n-32)/22));u(Math.min(a,e.length))};t();const n=new ResizeObserver(t);return n.observe(d.current),()=>{n.disconnect()}}),[s,e.length]);const p=e.slice(0,i);return(0,t.createElement)("div",{className:"reaction-group",ref:d},(0,t.createElement)(m,{reactions:p}),(0,t.createElement)(o.Button,{ref:l,className:"reaction-label is-link",onClick:()=>c(!r),"aria-expanded":r},a),r&&s&&(0,t.createElement)(o.Popover,{anchor:s,onClose:()=>c(!1)},(0,t.createElement)(h,{reactions:e})))};function p({title:e="",postId:a=null,isEditing:r=!1,setTitle:o=(()=>{}),reactions:s=null}){const[m,h]=(0,n.useState)(s),[p,w]=(0,n.useState)(!s);return(0,n.useEffect)((()=>{if(s)return h(s),void w(!1);a?(w(!0),l()({path:`/${u}/posts/${a}/reactions`}).then((e=>{h(e),w(!1)})).catch((()=>w(!1)))):w(!1)}),[a,s]),p?null:m&&Object.values(m).some((e=>e.items?.length>0))?(0,t.createElement)("div",{className:"activitypub-reactions"},r?(0,t.createElement)(c.RichText,{tagName:"h6",value:e,onChange:o,placeholder:(0,i.__)("Fediverse reactions","activitypub"),disableLineBreaks:!0,allowedFormats:[]}):e&&(0,t.createElement)("h6",null,e),Object.entries(m).map((([e,n])=>n.items?.length?(0,t.createElement)(d,{key:e,items:n.items,label:n.label}):null))):null}r()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-reactions-block"),(e=>{const a=JSON.parse(e.dataset.attrs);(0,n.createRoot)(e).render((0,t.createElement)(p,{...a}))}))}))})(); \ No newline at end of file diff --git a/src/reactions/reactions.js b/src/reactions/reactions.js index dcf8ffdce..0b140a509 100644 --- a/src/reactions/reactions.js +++ b/src/reactions/reactions.js @@ -33,7 +33,7 @@ const FacepileRow = ( { reactions } ) => { const startWave = (startIndex, isEntering) => { clearTimeouts(); - const delay = 150; // 150ms between each avatar + const delay = 100; // 100ms between each avatar const totalAvatars = reactions.length; if (isEntering) { @@ -343,7 +343,7 @@ export function Reactions( {
{ isEditing ? ( ) : ( - title &&

{ title }

+ title &&
{ title }
) } { Object.entries( reactions ).map( ( [ key, group ] ) => { diff --git a/src/reactions/style.scss b/src/reactions/style.scss index 203df2c99..76ed286e9 100644 --- a/src/reactions/style.scss +++ b/src/reactions/style.scss @@ -53,18 +53,18 @@ box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.8), // Crisp white border 0 1px 3px rgba(0, 0, 0, 0.2); // Soft drop shadow - transition: transform 1s cubic-bezier(0.34, 1.56, 0.64, 1); + transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); will-change: transform; &.wave-active { - transform: translateY(-16px) scale(1.2); + transform: translateY(-5px); &.rotate-clockwise { - transform: translateY(-16px) scale(1.2) rotate(360deg); + transform: translateY(-5px) rotate(30deg); } &.rotate-counter { - transform: translateY(-16px) scale(1.2) rotate(-360deg); + transform: translateY(-5px) rotate(-30deg); } } From 4c41d464df371d676223c5a0bdbc0ce16e3cbc83 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Mon, 16 Dec 2024 12:57:59 -0600 Subject: [PATCH 43/47] Remove `ACTIVITYPUB_DISABLE_REACTIONS` constant --- includes/class-handler.php | 5 +---- includes/constants.php | 1 - includes/handler/class-announce.php | 4 +--- tests/bootstrap.php | 1 - 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/includes/class-handler.php b/includes/class-handler.php index a62d7d0e6..14114f804 100644 --- a/includes/class-handler.php +++ b/includes/class-handler.php @@ -36,10 +36,7 @@ public static function register_handlers() { Follow::init(); Undo::init(); Update::init(); - - if ( ! ACTIVITYPUB_DISABLE_REACTIONS ) { - Like::init(); - } + Like::init(); /** * Register additional handlers. diff --git a/includes/constants.php b/includes/constants.php index 44abde3b5..f00582368 100644 --- a/includes/constants.php +++ b/includes/constants.php @@ -18,7 +18,6 @@ \defined( 'ACTIVITYPUB_CUSTOM_POST_CONTENT' ) || \define( 'ACTIVITYPUB_CUSTOM_POST_CONTENT', "[ap_title type=\"html\"]\n\n[ap_content]\n\n[ap_hashtags]" ); \defined( 'ACTIVITYPUB_DISABLE_REWRITES' ) || \define( 'ACTIVITYPUB_DISABLE_REWRITES', false ); \defined( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS', false ); -\defined( 'ACTIVITYPUB_DISABLE_REACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_REACTIONS', false ); \defined( 'ACTIVITYPUB_DISABLE_OUTGOING_INTERACTIONS' ) || \define( 'ACTIVITYPUB_DISABLE_OUTGOING_INTERACTIONS', false ); \defined( 'ACTIVITYPUB_SHARED_INBOX_FEATURE' ) || \define( 'ACTIVITYPUB_SHARED_INBOX_FEATURE', false ); \defined( 'ACTIVITYPUB_SEND_VARY_HEADER' ) || \define( 'ACTIVITYPUB_SEND_VARY_HEADER', false ); diff --git a/includes/handler/class-announce.php b/includes/handler/class-announce.php index 377a3c6e3..670e9ceef 100644 --- a/includes/handler/class-announce.php +++ b/includes/handler/class-announce.php @@ -44,9 +44,7 @@ public static function handle_announce( $announcement, $user_id, $activity = nul return; } - if ( ! ACTIVITYPUB_DISABLE_REACTIONS ) { - self::maybe_save_announce( $announcement, $user_id ); - } + self::maybe_save_announce( $announcement, $user_id ); if ( is_string( $announcement['object'] ) ) { $object = Http::get_remote_object( $announcement['object'] ); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 5dfe7c954..b3d8887d4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,7 +5,6 @@ * @package Activitypub */ -\define( 'ACTIVITYPUB_DISABLE_REACTIONS', false ); \define( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS', false ); $_tests_dir = \getenv( 'WP_TESTS_DIR' ); From 4d883bc5dba0f8dbe0412360619b0fe50351cf7e Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 17 Dec 2024 11:09:17 -0600 Subject: [PATCH 44/47] Use our own `notAllowed` icon --- build/editor-plugin/plugin.asset.php | 2 +- build/editor-plugin/plugin.js | 2 +- src/editor-plugin/plugin.js | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/build/editor-plugin/plugin.asset.php b/build/editor-plugin/plugin.asset.php index f105a081d..d702478cf 100644 --- a/build/editor-plugin/plugin.asset.php +++ b/build/editor-plugin/plugin.asset.php @@ -1 +1 @@ - array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'df17f53a1f77c7270fc9'); + array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '9f537927c965439dd1fd'); diff --git a/build/editor-plugin/plugin.js b/build/editor-plugin/plugin.js index c9476416e..3347d4257 100644 --- a/build/editor-plugin/plugin.js +++ b/build/editor-plugin/plugin.js @@ -1 +1 @@ -(()=>{"use strict";var e={20:(e,t,i)=>{var n=i(609),r=Symbol.for("react.element"),o=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,i){var n,c={},s=null,p=null;for(n in void 0!==i&&(s=""+i),void 0!==t.key&&(s=""+t.key),void 0!==t.ref&&(p=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(c[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===c[n]&&(c[n]=t[n]);return{$$typeof:r,type:e,key:s,ref:p,props:c,_owner:a.current}}},848:(e,t,i)=>{e.exports=i(20)},609:e=>{e.exports=window.React}},t={};function i(n){var r=t[n];if(void 0!==r)return r.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,i),o.exports}(()=>{var e=i(609);const t=window.wp.editor,n=window.wp.plugins,r=window.wp.components,o=window.wp.element,a=(0,o.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,o.cloneElement)(e,{width:t,height:t,...i,ref:n})})),l=window.wp.primitives;var c=i(848);const s=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})}),p=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),u=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"})}),v=(0,c.jsx)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,c.jsx)(l.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),d=window.wp.data,w=window.wp.coreData,h=window.wp.url,_=window.wp.i18n;(0,n.registerPlugin)("activitypub-editor-plugin",{render:()=>{const i=(0,d.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[n,o]=(0,w.useEntityProp)("postType",i,"meta"),l={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},c=(t,i)=>(0,e.createElement)(r.__experimentalText,{style:l},(0,e.createElement)(a,{icon:i}),t);if("wp_block"===i)return null;const v="0"!==n?.activitypub_reactions_enabled;return(0,e.createElement)(t.PluginDocumentSettingPanel,{name:"activitypub",title:(0,_.__)("⁂ Fediverse","activitypub")},(0,e.createElement)(r.TextControl,{label:(0,_.__)("Content Warning","activitypub"),value:n?.activitypub_content_warning,onChange:e=>{o({...n,activitypub_content_warning:e})},placeholder:(0,_.__)("Optional content warning","activitypub"),help:(0,_.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,e.createElement)(r.RadioControl,{label:(0,_.__)("Visibility","activitypub"),help:(0,_.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:n?.activitypub_content_visibility||"public",options:[{label:c((0,_.__)("Public","activitypub"),s),value:"public"},{label:c((0,_.__)("Quiet public","activitypub"),p),value:"quiet_public"},{label:c((0,_.__)("Do not federate","activitypub"),u),value:"local"}],onChange:e=>{o({...n,activitypub_content_visibility:e})},className:"activitypub-visibility"}),(0,e.createElement)("br",null),(0,e.createElement)(r.CheckboxControl,{label:(0,_.__)("Show federated reactions","activitypub"),checked:v,onChange:e=>{o({...n,activitypub_reactions_enabled:e?"1":"0"})},help:(0,_.__)("When disabled, federated reactions will be hidden for this post.","activitypub")}))}}),(0,n.registerPlugin)("activitypub-editor-preview",{render:()=>{const i=(0,d.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,e.createElement)(e.Fragment,null,t.PluginPreviewMenuItem?(0,e.createElement)(t.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,d.select)("core/editor").getEditedPostPreviewLink(),t=(0,h.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:v,disabled:"auto-draft"===i},(0,_.__)("⁂ Fediverse preview","activitypub")):null)}})})()})(); \ No newline at end of file +(()=>{"use strict";const e=window.React,t=window.wp.editor,i=window.wp.plugins,n=window.wp.components,a=window.wp.element,l=(0,a.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,a.cloneElement)(e,{width:t,height:t,...i,ref:n})})),c=window.wp.primitives,o=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})),r=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),u=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})),s=window.wp.data,p=window.wp.coreData,w=window.wp.url,v=window.wp.i18n,d=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"}));(0,i.registerPlugin)("activitypub-editor-plugin",{render:()=>{const i=(0,s.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[a,c]=(0,p.useEntityProp)("postType",i,"meta"),u={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},w=(t,i)=>(0,e.createElement)(n.__experimentalText,{style:u},(0,e.createElement)(l,{icon:i}),t);if("wp_block"===i)return null;const h="0"!==a?.activitypub_reactions_enabled;return(0,e.createElement)(t.PluginDocumentSettingPanel,{name:"activitypub",title:(0,v.__)("⁂ Fediverse","activitypub")},(0,e.createElement)(n.TextControl,{label:(0,v.__)("Content Warning","activitypub"),value:a?.activitypub_content_warning,onChange:e=>{c({...a,activitypub_content_warning:e})},placeholder:(0,v.__)("Optional content warning","activitypub"),help:(0,v.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,e.createElement)(n.RadioControl,{label:(0,v.__)("Visibility","activitypub"),help:(0,v.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:a?.activitypub_content_visibility||"public",options:[{label:w((0,v.__)("Public","activitypub"),o),value:"public"},{label:w((0,v.__)("Quiet public","activitypub"),r),value:"quiet_public"},{label:w((0,v.__)("Do not federate","activitypub"),d),value:"local"}],onChange:e=>{c({...a,activitypub_content_visibility:e})},className:"activitypub-visibility"}),(0,e.createElement)("br",null),(0,e.createElement)(n.CheckboxControl,{label:(0,v.__)("Show federated reactions","activitypub"),checked:h,onChange:e=>{c({...a,activitypub_reactions_enabled:e?"1":"0"})},help:(0,v.__)("When disabled, federated reactions will be hidden for this post.","activitypub")}))}}),(0,i.registerPlugin)("activitypub-editor-preview",{render:()=>{const i=(0,s.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,e.createElement)(e.Fragment,null,t.PluginPreviewMenuItem?(0,e.createElement)(t.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,s.select)("core/editor").getEditedPostPreviewLink(),t=(0,w.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:u,disabled:"auto-draft"===i},(0,v.__)("⁂ Fediverse preview","activitypub")):null)}})})(); \ No newline at end of file diff --git a/src/editor-plugin/plugin.js b/src/editor-plugin/plugin.js index 7f7252999..d38efaffa 100644 --- a/src/editor-plugin/plugin.js +++ b/src/editor-plugin/plugin.js @@ -1,11 +1,24 @@ import { PluginDocumentSettingPanel, PluginPreviewMenuItem } from '@wordpress/editor'; import { registerPlugin } from '@wordpress/plugins'; import { TextControl, RadioControl, CheckboxControl, __experimentalText as Text } from '@wordpress/components'; -import { Icon, notAllowed, globe, people, external } from '@wordpress/icons'; +import { Icon, globe, people, external } from '@wordpress/icons'; import { useSelect, select } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data'; import { addQueryArgs } from '@wordpress/url'; import { __ } from '@wordpress/i18n'; +import { SVG, Path } from '@wordpress/primitives'; + +// Defining our own because it's too new in @wordpress/icons +// https://github.com/WordPress/gutenberg/blob/trunk/packages/icons/src/library/not-allowed.js +const notAllowed = ( + + + +); const EditorPlugin = () => { From 7a1c67fee8923f7f053e54268ac1c448050075a1 Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 17 Dec 2024 11:31:42 -0600 Subject: [PATCH 45/47] remove stray use --- includes/rest/class-interaction.php | 1 - 1 file changed, 1 deletion(-) diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 28a2ea9ac..8bf78267e 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -7,7 +7,6 @@ namespace Activitypub\Rest; -use Activitypub\Comment; use WP_REST_Response; use Activitypub\Http; From 1f821aed90db988388a5a74a7c0d5e410cefd48c Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Tue, 17 Dec 2024 11:54:08 -0600 Subject: [PATCH 46/47] Remove settings and classic theme compat It's not yet ready for prime time. --- activitypub.php | 1 - includes/class-blocks.php | 28 --- includes/class-reactions-settings.php | 216 ------------------ .../class-test-reactions-settings.php | 128 ----------- 4 files changed, 373 deletions(-) delete mode 100644 includes/class-reactions-settings.php delete mode 100644 tests/includes/class-test-reactions-settings.php diff --git a/activitypub.php b/activitypub.php index f00f24e4c..22f3c00e2 100644 --- a/activitypub.php +++ b/activitypub.php @@ -65,7 +65,6 @@ function plugin_init() { \add_action( 'init', array( __NAMESPACE__ . '\Migration', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activitypub', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activity_Dispatcher', 'init' ) ); - \add_action( 'init', array( __NAMESPACE__ . '\Reactions_Settings', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Handler', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Admin', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Hashtag', 'init' ) ); diff --git a/includes/class-blocks.php b/includes/class-blocks.php index b29386ad5..052368346 100644 --- a/includes/class-blocks.php +++ b/includes/class-blocks.php @@ -27,9 +27,6 @@ public static function init() { // Add editor plugin. \add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) ); \add_action( 'init', array( self::class, 'register_postmeta' ), 11 ); - if ( ! \wp_is_block_theme() ) { - \add_action( 'the_content', array( self::class, 'maybe_add_fediverse_reactions' ) ); - } } /** @@ -165,11 +162,6 @@ public static function register_blocks() { * @return string The HTML to render. */ public static function render_post_reactions_block( $attrs ) { - // Check if reactions are enabled, generally, or for the current post. - if ( ! Reactions_Settings::is_reactions_enabled() ) { - return ''; - } - if ( ! isset( $attrs['postId'] ) ) { $attrs['postId'] = get_the_ID(); } @@ -397,24 +389,4 @@ public static function render_follower( $follower ) { $external_svg ); } - - /** - * Add fediverse reactions to the content. - * - * @param string $content The post content. - * @return string The post content with fediverse reactions. - */ - public static function maybe_add_fediverse_reactions( $content ) { - if ( ! is_singular() ) { - return $content; - } - - if ( ! Reactions_Settings::is_reactions_enabled() ) { - return $content; - } - - // Create a block instance for proper rendering. - $block_content = do_blocks( '' ); - return $content . $block_content; - } } diff --git a/includes/class-reactions-settings.php b/includes/class-reactions-settings.php deleted file mode 100644 index 36f01048c..000000000 --- a/includes/class-reactions-settings.php +++ /dev/null @@ -1,216 +0,0 @@ - true, - 'single' => true, - 'type' => 'string', - 'sanitize_callback' => function ( $value ) { - return in_array( $value, array( '0', '1' ), true ) ? $value : '1'; - }, - ) - ); - } - } - - /** - * Register settings. - */ - public static function register_settings() { - register_setting( - 'activitypub', - 'activitypub_reactions_enabled', - array( - 'type' => 'boolean', - 'show_in_rest' => true, - 'default' => true, - ) - ); - - add_settings_field( - 'activitypub_reactions_enabled', - __( 'Federated Reactions', 'activitypub' ), - array( self::class, 'render_reactions_enabled_field' ), - 'activitypub', - 'activity' - ); - } - - /** - * Render the reactions enabled field. - */ - public static function render_reactions_enabled_field() { - if ( ! wp_is_block_theme() ) { - ?> -
- - -

- -

-
- 'wp_template', - 'postId' => get_stylesheet() . '//single', - 'canvas' => 'edit', - ), - admin_url( 'site-editor.php' ) - ); - ?> -

- Edit Single Posts template', 'activitypub' ), - array( - 'a' => array( - 'href' => array(), - ), - ) - ), - esc_url( $editor_url ) - ); - ?> -

- ID, 'activitypub_reactions_enabled', true ); - if ( '' === $value ) { - $value = '1'; // Default to enabled. - } - ?> - -

- -

- assertEquals( 11, has_action( 'init', array( Reactions_Settings::class, 'register_post_meta' ) ) ); - $this->assertEquals( 10, has_action( 'admin_init', array( Reactions_Settings::class, 'register_settings' ) ) ); - } - - /** - * Test registration of post meta. - * - * @covers ::register_post_meta - */ - public function test_register_post_meta() { - Reactions_Settings::register_post_meta(); - - $post_type = 'post'; - $registered = get_registered_meta_keys( 'post', $post_type ); - - $this->assertArrayHasKey( 'activitypub_reactions_enabled', $registered ); - $this->assertTrue( $registered['activitypub_reactions_enabled']['show_in_rest'] ); - $this->assertTrue( $registered['activitypub_reactions_enabled']['single'] ); - $this->assertEquals( 'string', $registered['activitypub_reactions_enabled']['type'] ); - - // Test sanitize callback. - $sanitize_callback = $registered['activitypub_reactions_enabled']['sanitize_callback']; - $this->assertEquals( '1', $sanitize_callback( '1' ) ); - $this->assertEquals( '0', $sanitize_callback( '0' ) ); - $this->assertEquals( '1', $sanitize_callback( 'invalid' ) ); - } - - /** - * Test registration of settings. - * - * @covers ::register_settings - */ - public function test_register_settings() { - Reactions_Settings::register_settings(); - - $registered = get_registered_settings(); - $this->assertArrayHasKey( 'activitypub_reactions_enabled', $registered ); - $this->assertEquals( 'boolean', $registered['activitypub_reactions_enabled']['type'] ); - $this->assertTrue( $registered['activitypub_reactions_enabled']['show_in_rest'] ); - $this->assertTrue( $registered['activitypub_reactions_enabled']['default'] ); - } - - /** - * Test rendering of the settings field. - * - * @covers ::render_reactions_enabled_field - */ - public function test_render_reactions_enabled_field() { - // Test with default value. - update_option( 'activitypub_reactions_enabled', '1' ); - ob_start(); - Reactions_Settings::render_reactions_enabled_field(); - $output = ob_get_clean(); - - $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); - $this->assertStringContainsString( 'value="1"', $output ); - $this->assertStringContainsString( 'checked=\'checked\'', $output ); - - // Test with disabled value. - update_option( 'activitypub_reactions_enabled', '0' ); - ob_start(); - Reactions_Settings::render_reactions_enabled_field(); - $output = ob_get_clean(); - - $this->assertStringContainsString( 'assertStringContainsString( 'name="activitypub_reactions_enabled"', $output ); - $this->assertStringContainsString( 'value="1"', $output ); - $this->assertStringNotContainsString( 'checked=\'checked\'', $output ); - } - - /** - * Test checking if reactions are enabled. - * - * @covers ::is_reactions_enabled - */ - public function test_is_reactions_enabled() { - $post = self::factory()->post->create_and_get(); - - // Test with default global setting. - $this->assertTrue( Reactions_Settings::is_reactions_enabled( $post->ID ) ); - - // Test with global setting disabled. - update_option( 'activitypub_reactions_enabled', '0' ); - $this->assertFalse( Reactions_Settings::is_reactions_enabled( $post->ID ) ); - - // Test with global setting enabled but post setting disabled. - update_option( 'activitypub_reactions_enabled', '1' ); - update_post_meta( $post->ID, 'activitypub_reactions_enabled', '0' ); - $this->assertFalse( Reactions_Settings::is_reactions_enabled( $post->ID ) ); - - update_option( 'activitypub_reactions_enabled', '0' ); - update_post_meta( $post->ID, 'activitypub_reactions_enabled', '1' ); - $this->assertTrue( Reactions_Settings::is_reactions_enabled( $post->ID ) ); - } -} From 3e82ef57055cb1860d807ae8a3b4cc98402a57bc Mon Sep 17 00:00:00 2001 From: Matt Wiebe Date: Tue, 17 Dec 2024 12:01:23 -0600 Subject: [PATCH 47/47] remove reactions postmeta from editor plugin --- build/editor-plugin/plugin.asset.php | 2 +- build/editor-plugin/plugin.js | 2 +- src/editor-plugin/plugin.js | 12 ------------ 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/build/editor-plugin/plugin.asset.php b/build/editor-plugin/plugin.asset.php index d702478cf..548126f53 100644 --- a/build/editor-plugin/plugin.asset.php +++ b/build/editor-plugin/plugin.asset.php @@ -1 +1 @@ - array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '9f537927c965439dd1fd'); + array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '6b15195803d2f5a2c116'); diff --git a/build/editor-plugin/plugin.js b/build/editor-plugin/plugin.js index 3347d4257..1d75171bd 100644 --- a/build/editor-plugin/plugin.js +++ b/build/editor-plugin/plugin.js @@ -1 +1 @@ -(()=>{"use strict";const e=window.React,t=window.wp.editor,i=window.wp.plugins,n=window.wp.components,a=window.wp.element,l=(0,a.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,a.cloneElement)(e,{width:t,height:t,...i,ref:n})})),c=window.wp.primitives,o=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})),r=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),u=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})),s=window.wp.data,p=window.wp.coreData,w=window.wp.url,v=window.wp.i18n,d=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"}));(0,i.registerPlugin)("activitypub-editor-plugin",{render:()=>{const i=(0,s.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[a,c]=(0,p.useEntityProp)("postType",i,"meta"),u={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},w=(t,i)=>(0,e.createElement)(n.__experimentalText,{style:u},(0,e.createElement)(l,{icon:i}),t);if("wp_block"===i)return null;const h="0"!==a?.activitypub_reactions_enabled;return(0,e.createElement)(t.PluginDocumentSettingPanel,{name:"activitypub",title:(0,v.__)("⁂ Fediverse","activitypub")},(0,e.createElement)(n.TextControl,{label:(0,v.__)("Content Warning","activitypub"),value:a?.activitypub_content_warning,onChange:e=>{c({...a,activitypub_content_warning:e})},placeholder:(0,v.__)("Optional content warning","activitypub"),help:(0,v.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,e.createElement)(n.RadioControl,{label:(0,v.__)("Visibility","activitypub"),help:(0,v.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:a?.activitypub_content_visibility||"public",options:[{label:w((0,v.__)("Public","activitypub"),o),value:"public"},{label:w((0,v.__)("Quiet public","activitypub"),r),value:"quiet_public"},{label:w((0,v.__)("Do not federate","activitypub"),d),value:"local"}],onChange:e=>{c({...a,activitypub_content_visibility:e})},className:"activitypub-visibility"}),(0,e.createElement)("br",null),(0,e.createElement)(n.CheckboxControl,{label:(0,v.__)("Show federated reactions","activitypub"),checked:h,onChange:e=>{c({...a,activitypub_reactions_enabled:e?"1":"0"})},help:(0,v.__)("When disabled, federated reactions will be hidden for this post.","activitypub")}))}}),(0,i.registerPlugin)("activitypub-editor-preview",{render:()=>{const i=(0,s.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,e.createElement)(e.Fragment,null,t.PluginPreviewMenuItem?(0,e.createElement)(t.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,s.select)("core/editor").getEditedPostPreviewLink(),t=(0,w.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:u,disabled:"auto-draft"===i},(0,v.__)("⁂ Fediverse preview","activitypub")):null)}})})(); \ No newline at end of file +(()=>{"use strict";const e=window.React,t=window.wp.editor,i=window.wp.plugins,n=window.wp.components,a=window.wp.element,l=(0,a.forwardRef)((function({icon:e,size:t=24,...i},n){return(0,a.cloneElement)(e,{width:t,height:t,...i,ref:n})})),c=window.wp.primitives,o=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"})),r=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),u=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})),w=window.wp.data,p=window.wp.coreData,v=window.wp.url,s=window.wp.i18n,d=(0,e.createElement)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,e.createElement)(c.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"}));(0,i.registerPlugin)("activitypub-editor-plugin",{render:()=>{const i=(0,w.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[a,c]=(0,p.useEntityProp)("postType",i,"meta"),u={verticalAlign:"middle",gap:"4px",justifyContent:"start",display:"inline-flex",alignItems:"center"},v=(t,i)=>(0,e.createElement)(n.__experimentalText,{style:u},(0,e.createElement)(l,{icon:i}),t);return"wp_block"===i?null:(0,e.createElement)(t.PluginDocumentSettingPanel,{name:"activitypub",title:(0,s.__)("⁂ Fediverse","activitypub")},(0,e.createElement)(n.TextControl,{label:(0,s.__)("Content Warning","activitypub"),value:a?.activitypub_content_warning,onChange:e=>{c({...a,activitypub_content_warning:e})},placeholder:(0,s.__)("Optional content warning","activitypub"),help:(0,s.__)("Content warnings do not change the content on your site, only in the fediverse.","activitypub")}),(0,e.createElement)(n.RadioControl,{label:(0,s.__)("Visibility","activitypub"),help:(0,s.__)("This adjusts the visibility of a post in the fediverse, but note that it won't affect how the post appears on the blog.","activitypub"),selected:a?.activitypub_content_visibility||"public",options:[{label:v((0,s.__)("Public","activitypub"),o),value:"public"},{label:v((0,s.__)("Quiet public","activitypub"),r),value:"quiet_public"},{label:v((0,s.__)("Do not federate","activitypub"),d),value:"local"}],onChange:e=>{c({...a,activitypub_content_visibility:e})},className:"activitypub-visibility"}))}}),(0,i.registerPlugin)("activitypub-editor-preview",{render:()=>{const i=(0,w.useSelect)((e=>e("core/editor").getCurrentPost().status));return(0,e.createElement)(e.Fragment,null,t.PluginPreviewMenuItem?(0,e.createElement)(t.PluginPreviewMenuItem,{onClick:()=>function(){const e=(0,w.select)("core/editor").getEditedPostPreviewLink(),t=(0,v.addQueryArgs)(e,{activitypub:"true"});window.open(t,"_blank")}(),icon:u,disabled:"auto-draft"===i},(0,s.__)("⁂ Fediverse preview","activitypub")):null)}})})(); \ No newline at end of file diff --git a/src/editor-plugin/plugin.js b/src/editor-plugin/plugin.js index d38efaffa..f15921f82 100644 --- a/src/editor-plugin/plugin.js +++ b/src/editor-plugin/plugin.js @@ -48,9 +48,6 @@ const EditorPlugin = () => { return null; } - // Default to enabled if not set - const isReactionsEnabled = meta?.activitypub_reactions_enabled !== '0'; - return ( { } } className="activitypub-visibility" /> -
- { - setMeta( { ...meta, activitypub_reactions_enabled: checked ? '1' : '0' } ); - } } - help={ __( 'When disabled, federated reactions will be hidden for this post.', 'activitypub' ) } - />
); }