diff --git a/components/Conversation/Controller/Reply.php b/components/Conversation/Controller/Reply.php index 63a4a7049a..62759ee885 100644 --- a/components/Conversation/Controller/Reply.php +++ b/components/Conversation/Controller/Reply.php @@ -49,7 +49,7 @@ class Reply extends FeedController * * @return array */ - public function addReply(Request $request, int $note_id, int $actor_id) + public function addReply(Request $request, int $note_id) { $user = Common::ensureLoggedIn(); diff --git a/components/Conversation/Conversation.php b/components/Conversation/Conversation.php index 16089c35b0..3a697b8481 100644 --- a/components/Conversation/Conversation.php +++ b/components/Conversation/Conversation.php @@ -86,9 +86,9 @@ class Conversation extends Component } // Generating URL for reply action route - $args = ['note_id' => $note->getId(), 'actor_id' => $note->getActor()->getId()]; + $args = ['note_id' => $note->getId()]; $type = Router::ABSOLUTE_PATH; - $reply_action_url = Router::url('reply_add', $args, $type); + $reply_action_url = Router::url('conversation_reply_to', $args, $type); $query_string = $request->getQueryString(); // Concatenating get parameter to redirect the user to where he came from @@ -109,7 +109,7 @@ class Conversation extends Component { // If Actor is adding a reply, get parent's Note id // Else it's null - $extra_args['reply_to'] = $request->get('_route') === 'reply_add' ? (int) $request->get('note_id') : null; + $extra_args['reply_to'] = $request->get('_route') === 'conversation_reply_to' ? (int) $request->get('note_id') : null; return Event::next; } @@ -147,7 +147,7 @@ class Conversation extends Component public function onAddRoute(RouteLoader $r): bool { - $r->connect('reply_add', '/object/note/new?to={actor_id<\d+>}&reply_to={note_id<\d+>}', [ReplyController::class, 'addReply']); + $r->connect('conversation_reply_to', '/conversation/reply?reply_to_note={note_id<\d+>}', [ReplyController::class, 'addReply']); $r->connect('conversation', '/conversation/{conversation_id<\d+>}', [Controller\Conversation::class, 'showConversation']); $r->connect('conversation_mute', '/conversation/{conversation_id<\d+>}/mute', [Controller\Conversation::class, 'muteConversation']); diff --git a/components/Feed/Util/FeedController.php b/components/Feed/Util/FeedController.php index d625374cd0..cd30eb2093 100644 --- a/components/Feed/Util/FeedController.php +++ b/components/Feed/Util/FeedController.php @@ -38,6 +38,7 @@ use App\Entity\Actor; use App\Entity\Note; use App\Util\Common; use Functional as F; +use function App\Core\I18n\_m; abstract class FeedController extends Controller { @@ -49,12 +50,11 @@ abstract class FeedController extends Controller protected function postProcess(array $result): array { $actor = Common::actor(); - if (\array_key_exists('notes', $result)) { $notes = $result['notes']; self::enforceScope($notes, $actor); Event::handle('FilterNoteList', [$actor, &$notes, $result['request']]); - Event::handle('FormatNoteList', [$notes, &$result['notes']]); + Event::handle('FormatNoteList', [$notes, &$result['notes'], &$result['request']]); } return $result; diff --git a/components/RightPanel/templates/right_panel/view.html.twig b/components/RightPanel/templates/right_panel/view.html.twig index f7f9c9c79f..9981fe0ef4 100644 --- a/components/RightPanel/templates/right_panel/view.html.twig +++ b/components/RightPanel/templates/right_panel/view.html.twig @@ -15,7 +15,7 @@

{% set current_path = app.request.get('_route') %} - {% if current_path == 'reply_add' %} + {% if current_path == 'conversation_reply_to' %} {{ "Reply to note" | trans }} {% else %} {{ "Create a note" | trans }} diff --git a/plugins/TreeNotes/TreeNotes.php b/plugins/TreeNotes/TreeNotes.php index f1df8787d5..2b1f1b78c0 100644 --- a/plugins/TreeNotes/TreeNotes.php +++ b/plugins/TreeNotes/TreeNotes.php @@ -23,30 +23,72 @@ namespace Plugin\TreeNotes; use App\Core\Modules\Plugin; use App\Entity\Note; +use Symfony\Component\HttpFoundation\Request; class TreeNotes extends Plugin { + /** - * Format the given $notes_in_trees_out in a list of reply trees + * Formatting notes without taking a direct reply out of context + * Show whole conversation in conversation related routes + * + * @param array $notes_in + * @param array $notes_out + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return void */ - public function onFormatNoteList(array $notes_in, ?array &$notes_out) + public function onFormatNoteList(array $notes_in, array &$notes_out, Request $request) { - $roots = array_filter($notes_in, static fn (Note $note) => \is_null($note->getReplyTo())); - $notes_out = $this->build_tree($roots, $notes_in); + if (str_starts_with($request->get('_route'), 'conversation')) { + $parents = $this->conversationFormat($notes_in); + $notes_out = $this->conversationFormatTree($parents, $notes_in); + } else { + $notes_out = $this->feedFormatTree($notes_in); + } } - private function build_tree(array $parents, array $notes) + private function feedFormatTree(array $notes): array + { + $tree = []; + $notes = array_reverse($notes); + foreach ($notes as $note) { + if (!is_null($children = $note->getReplies())) { + $notes = array_filter($notes, fn (Note $n) => !in_array($n, $children)); + + $tree[] = [ + 'note' => $note, + 'replies' => array_map( + function ($n) { + return ['note' => $n, 'replies' => []]; + }, + $children + ), + ]; + } else { + $tree[] = ['note' => $note, 'replies' => []]; + } + } + return array_reverse($tree); + } + + private function conversationFormat(array $notes_in) + { + return array_filter($notes_in, static fn (Note $note) => \is_null($note->getReplyTo())); + } + + private function conversationFormatTree(array $parents, array $notes) { $subtree = []; foreach ($parents as $p) { - $subtree[] = $this->build_subtree($p, $notes); + $subtree[] = $this->conversationFormatSubTree($p, $notes); } return $subtree; } - private function build_subtree(Note $parent, array $notes) + private function conversationFormatSubTree(Note $parent, array $notes) { $children = array_filter($notes, fn (Note $note) => $note->getReplyTo() === $parent->getId()); - return ['note' => $parent, 'replies' => $this->build_tree($children, $notes)]; + return ['note' => $parent, 'replies' => $this->conversationFormatTree($children, $notes)]; } } diff --git a/src/Entity/Note.php b/src/Entity/Note.php index ad71ffef2f..ad9e811ef7 100644 --- a/src/Entity/Note.php +++ b/src/Entity/Note.php @@ -352,7 +352,7 @@ class Note extends Entity */ public function getReplies(): array { - return Cache::getList('note-replies-' . $this->getId(), fn () => DB::findBy('note', ['reply_to' => $this->getId()], order_by: ['created' => 'DESC', 'id' => 'DESC'])); + return DB::findBy('note', ['reply_to' => $this->getId()], order_by: ['created' => 'DESC', 'id' => 'DESC']); } /**