diff --git a/app/Entities/EpisodeComment.php b/app/Entities/EpisodeComment.php index b7670d82ac3befa4b294532866b7dd753252750e..d30e3c5a5c6fa07e7a4b5dc36ce495754953d74a 100644 --- a/app/Entities/EpisodeComment.php +++ b/app/Entities/EpisodeComment.php @@ -47,6 +47,8 @@ class EpisodeComment extends UuidEntity */ protected ?array $replies = null; + protected bool $has_replies = false; + /** * @var string[] */ @@ -115,6 +117,11 @@ class EpisodeComment extends UuidEntity return $this->replies; } + public function getHasReplies(): bool + { + return $this->getReplies() !== null; + } + public function getReplyToComment(): ?self { if ($this->in_reply_to_id === null) { diff --git a/app/Resources/styles/custom.css b/app/Resources/styles/custom.css index e229f820feff576fedd7955935cbd8a64de12f4d..8f5fabad550a360dfd606fd474a0775f3b9d4f9e 100644 --- a/app/Resources/styles/custom.css +++ b/app/Resources/styles/custom.css @@ -1,4 +1,10 @@ @layer components { + .post-content { + & a { + @apply text-sm font-semibold text-pine-600 hover:underline; + } + } + .ring-castopod { @apply outline-none ring-2 ring-pine-500 ring-offset-2 ring-offset-pine-100; } diff --git a/app/Resources/styles/index.css b/app/Resources/styles/index.css index 7ac86a77e647622afe93215bb8daff148ffab462..bf5dbe92a906fd74d2292510d288b3c3ad7204f6 100644 --- a/app/Resources/styles/index.css +++ b/app/Resources/styles/index.css @@ -7,7 +7,6 @@ @import "./radioBtn.css"; @import "./switch.css"; @import "./charts.css"; -@import "./post.css"; @import "./radioToggler.css"; @import "./formInputTabs.css"; @import "./stickyHeader.css"; diff --git a/app/Resources/styles/post.css b/app/Resources/styles/post.css deleted file mode 100644 index 966ec60663d6f5f5580a5f1b30576251fd612c19..0000000000000000000000000000000000000000 --- a/app/Resources/styles/post.css +++ /dev/null @@ -1,22 +0,0 @@ -@layer components { - .post-content { - & a { - @apply text-sm font-semibold text-pine-600 hover:underline; - } - } - - .post-replies > * { - @apply relative; - - & img { - @apply z-20; - } - - &:not(:last-child)::before { - @apply absolute z-10 h-full bg-gray-300 top-8; - content: ""; - left: 3rem; - width: 2px; - } - } -} diff --git a/themes/cp_admin/episode/publish.php b/themes/cp_admin/episode/publish.php index a149e6f49850c34d7d43da95c09040f5d75eb9a9..11af5a63fda9ff1d62fc368514fb6e71e55a5033 100644 --- a/themes/cp_admin/episode/publish.php +++ b/themes/cp_admin/episode/publish.php @@ -27,8 +27,8 @@ ) ?></label> <small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small> <div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl"> - <div class="flex px-4 py-3"> - <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + <div class="flex px-4 py-3 gap-x-2"> + <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col min-w-0"> <p class="flex items-baseline min-w-0"> <span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span> diff --git a/themes/cp_admin/episode/publish_edit.php b/themes/cp_admin/episode/publish_edit.php index eff01066e549810c0d2fb5c63baa687f15dc9202..cd6de4b545fddbcda855431ab5f7232efd8832dc 100644 --- a/themes/cp_admin/episode/publish_edit.php +++ b/themes/cp_admin/episode/publish_edit.php @@ -28,8 +28,8 @@ ) ?></label> <small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small> <div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl"> - <div class="flex px-4 py-3"> - <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + <div class="flex px-4 py-3 gap-x-2"> + <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col min-w-0"> <p class="flex items-baseline min-w-0"> <span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span> diff --git a/themes/cp_app/episode/_partials/comment.php b/themes/cp_app/episode/_partials/comment.php index bb1624a9d6a63474c21b0577cc714b8213a8cc89..f6700fa415040d4c85d4294e74b9278cb1157298 100644 --- a/themes/cp_app/episode/_partials/comment.php +++ b/themes/cp_app/episode/_partials/comment.php @@ -1,5 +1,5 @@ -<article class="relative z-10 flex w-full px-4 py-2 rounded-conditional-2xl"> - <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> +<article class="relative z-10 flex w-full px-4 py-2 rounded-conditional-2xl gap-x-2"> + <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex-1"> <header class="w-full mb-2 text-sm"> <a href="<?= $comment->actor diff --git a/themes/cp_app/episode/_partials/comment_card.php b/themes/cp_app/episode/_partials/comment_card.php index eedbcf90a1efa47c18fdb7e8aa3758d17dd86c5f..da915a39078d896a9ec69bffdf8be039863b5ab2 100644 --- a/themes/cp_app/episode/_partials/comment_card.php +++ b/themes/cp_app/episode/_partials/comment_card.php @@ -1,5 +1,5 @@ -<article class="relative z-10 flex w-full p-4 bg-white shadow rounded-conditional-2xl"> - <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> +<article class="relative z-10 flex w-full p-4 bg-white shadow rounded-conditional-2xl gap-x-2"> + <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex-1"> <header class="w-full mb-2 text-sm"> <a href="<?= $comment->actor->uri ?>" class="flex items-baseline hover:underline" <?= $comment->actor->is_local diff --git a/themes/cp_app/episode/_partials/comment_reply.php b/themes/cp_app/episode/_partials/comment_reply.php index 59b5643fdd9cc03415525baa33c0ef7c89423ef9..c14646b516c1a24d2ea335fc7abc7fcc9cb05263 100644 --- a/themes/cp_app/episode/_partials/comment_reply.php +++ b/themes/cp_app/episode/_partials/comment_reply.php @@ -1,6 +1,6 @@ -<article class="flex px-6 py-4 bg-gray-50"> +<article class="flex px-6 py-4 bg-gray-50 gap-x-2"> <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full ring-gray-50 ring-2" /> + ->display_name ?>" class="z-10 w-10 h-10 rounded-full ring-gray-50 ring-2" /> <div class="flex flex-col flex-1 min-w-0"> <header class="flex items-center mb-2"> <a href="<?= $reply->actor diff --git a/themes/cp_app/episode/_partials/comment_reply_actions.php b/themes/cp_app/episode/_partials/comment_reply_actions.php index bae6c3cb139873fd34fee6c561622f8ea4a03fc1..61f9ea56cb9dfba554ca38eb50b0681aab96bfc6 100644 --- a/themes/cp_app/episode/_partials/comment_reply_actions.php +++ b/themes/cp_app/episode/_partials/comment_reply_actions.php @@ -6,7 +6,7 @@ [ 'numberOfLikes' => $reply->likes_count, ], -) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button> +) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button> <Button uri="<?= route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button> </form> <?php else: ?> @@ -15,7 +15,7 @@ [ 'numberOfLikes' => $reply->likes_count, ], -) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-500') . $reply->likes_count ?></button> +) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-500') . $reply->likes_count ?></button> <?php if ($reply->replies_count): ?> <?= anchor( route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id), diff --git a/themes/cp_app/episode/_partials/comment_with_replies.php b/themes/cp_app/episode/_partials/comment_with_replies.php index 45b42537fc7250fa6d154b70eefcee49f32c9078..ec96f6f7cc745fe33fd0cad6a15aff84f2783fb9 100644 --- a/themes/cp_app/episode/_partials/comment_with_replies.php +++ b/themes/cp_app/episode/_partials/comment_with_replies.php @@ -1,11 +1,21 @@ +<?php declare(strict_types=1); + +if ($comment->in_reply_to_id): ?> + <div class="relative -mb-2 overflow-hidden border-t border-l border-r rounded-t-xl"> + <div class="absolute z-0 w-[2px] h-full bg-gray-300 left-[43px] top-4"></div> + <?= view('episode/_partials/comment_reply', [ + 'reply' => $comment->reply_to_comment, + ]) ?> + </div> +<?php endif; ?> <?= $this->include('episode/_partials/comment_card') ?> <div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl"> <?php if (can_user_interact()): ?> -<form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 bg-gray-50"> +<form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 gap-x-2 bg-gray-50"> <img src="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor() - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full ring-gray-50 ring-2" /> + ->display_name ?>" class="w-10 h-10 rounded-full ring-gray-50 ring-2" /> <div class="flex flex-col flex-1"> <Forms.Textarea name="message" @@ -20,10 +30,14 @@ </form> <?php endif; ?> -<?php foreach ($comment->replies as $reply): ?> - <?= view('episode/_partials/comment_reply', [ - 'reply' => $reply, - ]) ?> -<?php endforeach; ?> +<?php if ($comment->has_replies): ?> + <div class="border-t divide-y"> + <?php foreach ($comment->replies as $reply): ?> + <?= view('episode/_partials/comment_reply', [ + 'reply' => $reply, + ]) ?> + <?php endforeach; ?> + </div> +<?php endif; ?> </div> diff --git a/themes/cp_app/episode/activity.php b/themes/cp_app/episode/activity.php index df14e3201609768c96932e01f5f419f71ef807c8..6c5ca3a125a08e55bf52442acf670d60d2b37c55 100644 --- a/themes/cp_app/episode/activity.php +++ b/themes/cp_app/episode/activity.php @@ -35,14 +35,13 @@ <?= $this->section('content') ?> <?php if (can_user_interact()): ?> - <form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 bg-white shadow rounded-conditional-2xl"> + <?= view('_message_block') ?> + <form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 bg-white shadow gap-x-2 rounded-conditional-2xl"> <?= csrf_field() ?> - <?= view('_message_block') ?> - <img src="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor() - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + ->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col flex-1 min-w-0 gap-y-2"> <input name="episode_url" value="<?= $episode->link ?>" type="hidden" /> <Forms.Textarea diff --git a/themes/cp_app/episode/comments.php b/themes/cp_app/episode/comments.php index df5d33481778eb10d2c13c1377d9cf574b3e6167..a90b464445968a5f4541b7f569b1f0d82b96fc69 100644 --- a/themes/cp_app/episode/comments.php +++ b/themes/cp_app/episode/comments.php @@ -37,14 +37,13 @@ <?= $this->section('content') ?> <?php if (can_user_interact()): ?> - <form action="<?= route_to('comment-attempt-create', $podcast->id, $episode->id) ?>" method="POST" class="flex p-4"> + <?= view('_message_block') ?> + <form action="<?= route_to('comment-attempt-create', $podcast->id, $episode->id) ?>" method="POST" class="flex p-4 gap-x-2"> <?= csrf_field() ?> - <?= view('_message_block') ?> - <img src="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor() - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + ->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col flex-1 min-w-0 gap-y-2"> <Forms.Textarea name="message" diff --git a/themes/cp_app/podcast/activity.php b/themes/cp_app/podcast/activity.php index 4e7119e9d9738b34384f32edc573f161892fb6ab..f291f25794e028e8ec2d5465cc461f8a6f6f9535 100644 --- a/themes/cp_app/podcast/activity.php +++ b/themes/cp_app/podcast/activity.php @@ -28,14 +28,14 @@ <?= $this->section('content') ?> <?php if (can_user_interact()): ?> - <form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 bg-white shadow rounded-conditional-2xl"> + <form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 bg-white shadow gap-x-2 rounded-conditional-2xl"> <?= csrf_field() ?> <?= view('_message_block') ?> <img src="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor() - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + ->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col flex-1 min-w-0 gap-y-2"> <Forms.Textarea name="message" diff --git a/themes/cp_app/post/_partials/card.php b/themes/cp_app/post/_partials/card.php index a5dee3cb15bf0e4a340dbf023499cf174a0a25dc..65271c7c29fee1ed9689b1f005abfaff871ad714 100644 --- a/themes/cp_app/post/_partials/card.php +++ b/themes/cp_app/post/_partials/card.php @@ -1,7 +1,7 @@ <article class="relative z-10 w-full bg-white shadow sm:rounded-conditional-2xl"> - <header class="flex px-6 py-4"> + <header class="flex px-6 py-4 gap-x-2"> <img src="<?= $post->actor - ->avatar_image_url ?>" alt="<?= $post->actor->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + ->avatar_image_url ?>" alt="<?= $post->actor->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col min-w-0"> <a href="<?= $post->actor ->uri ?>" class="flex items-baseline hover:underline" <?= $post diff --git a/themes/cp_app/post/_partials/post_with_replies.php b/themes/cp_app/post/_partials/post_with_replies.php index a5f5f2ba36111520ca01c85964e71cad9cc2f504..32f630e8f98eeea2c2c2fca0edd8de5d93325e51 100644 --- a/themes/cp_app/post/_partials/post_with_replies.php +++ b/themes/cp_app/post/_partials/post_with_replies.php @@ -1,3 +1,14 @@ +<?php declare(strict_types=1); + +if ($post->in_reply_to_id): ?> + <div class="relative -mb-2 overflow-hidden border-t border-l border-r rounded-t-xl"> + <div class="absolute z-0 w-[2px] h-full bg-gray-300 left-[43px] top-4"></div> + <?= view('post/_partials/reply', [ + 'podcast' => $podcast, + 'reply' => $post->reply_to_post, + ]) ?> + </div> +<?php endif; ?> <?= view('post/_partials/card', [ 'index' => $index, 'post' => $post, @@ -6,10 +17,10 @@ <div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl"> <div class="px-6 pt-8 pb-4 bg-gray-50"> <?php if (can_user_interact()): ?> - <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex" > + <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex gap-x-2" > <img src="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor() - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full ring-gray-50 ring-2" /> + ->display_name ?>" class="w-10 h-10 rounded-full ring-gray-50 ring-2" /> <div class="flex flex-col flex-1"> <Forms.Textarea name="message" @@ -39,11 +50,13 @@ </div> <?php if ($post->has_replies): ?> + <div class="border-t divide-y"> <?php foreach ($post->replies as $reply): ?> <?= view('post/_partials/reply', [ 'podcast' => $podcast, 'reply' => $reply, ]) ?> <?php endforeach; ?> + </div> <?php endif; ?> </div> \ No newline at end of file diff --git a/themes/cp_app/post/_partials/reblog.php b/themes/cp_app/post/_partials/reblog.php index f2f7a77145a88253eb59e390cbca4dec39980ad7..2e81cd663aeebecb9040394c552d01fee761e13d 100644 --- a/themes/cp_app/post/_partials/reblog.php +++ b/themes/cp_app/post/_partials/reblog.php @@ -6,9 +6,9 @@ lang('Post.actor_shared', [ 'actor' => $post->actor->display_name, ]) ?></p> - <header class="flex px-6 py-4"> + <header class="flex px-6 py-4 gap-x-2"> <img src="<?= $post->actor - ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-10 h-10 mr-2 rounded-full" /> + ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-10 h-10 rounded-full" /> <div class="flex flex-col min-w-0"> <a href="<?= $post->actor ->uri ?>" class="flex items-baseline hover:underline" <?= $post diff --git a/themes/cp_app/post/_partials/reply.php b/themes/cp_app/post/_partials/reply.php index 12dcafde88e2c5ee394dbdcd8bc73ca65e4aa383..e15b996d2653f753282847851730faf6370c077b 100644 --- a/themes/cp_app/post/_partials/reply.php +++ b/themes/cp_app/post/_partials/reply.php @@ -1,6 +1,6 @@ -<article class="flex px-6 py-4 bg-gray-50"> +<article class="flex px-6 py-4 bg-gray-50 gap-x-2"> <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor - ->display_name ?>" class="w-10 h-10 mr-2 rounded-full ring-gray-50 ring-2" /> + ->display_name ?>" class="z-10 w-10 h-10 rounded-full ring-gray-50 ring-2" /> <div class="flex flex-col flex-1 min-w-0"> <header class="flex items-center mb-2"> <a href="<?= $reply->actor diff --git a/themes/cp_app/post/_partials/reply_actions.php b/themes/cp_app/post/_partials/reply_actions.php index dccc47ff51cb5c3003732bd46543ac4635ff76b4..1c15ae81f0af10e7305afccdd291a4593bb2f014 100644 --- a/themes/cp_app/post/_partials/reply_actions.php +++ b/themes/cp_app/post/_partials/reply_actions.php @@ -1,30 +1,30 @@ <footer> <?php if (can_user_interact()): ?> - <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $reply->id) ?>" method="POST" class="flex items-start"> + <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $reply->id) ?>" method="POST" class="flex items-start gap-x-6"> <?= csrf_field() ?> <?= anchor( route_to('post', $podcast->handle, $reply->id), - icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count, + icon('chat', 'text-lg mr-1 text-gray-400') . $reply->replies_count, [ - 'class' => 'inline-flex items-center mr-6 hover:underline', + 'class' => 'inline-flex items-center hover:underline text-sm', 'title' => lang('Post.replies', [ 'numberOfReplies' => $reply->replies_count, ]), ], ) ?> - <button type="submit" name="action" value="reblog" class="inline-flex items-center mr-6 hover:underline" title="<?= lang( + <button type="submit" name="action" value="reblog" class="inline-flex items-center text-sm hover:underline" title="<?= lang( 'Post.reblogs', [ 'numberOfReblogs' => $reply->reblogs_count, ], -) ?>"><?= icon('repeat', 'text-xl mr-1 text-gray-400') . +) ?>"><?= icon('repeat', 'text-lg mr-1 text-gray-400') . $reply->reblogs_count ?></button> - <button type="submit" name="action" value="favourite" class="inline-flex items-center mr-6 hover:underline" title="<?= lang( + <button type="submit" name="action" value="favourite" class="inline-flex items-center text-sm hover:underline" title="<?= lang( 'Post.favourites', [ 'numberOfFavourites' => $reply->favourites_count, ], - ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400') . + ) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-400') . $reply->favourites_count ?></button> <button id="<?= $reply->id . '-more-dropdown' ?>" type="button" class="text-xl text-gray-500 focus:ring-castopod" data-dropdown="button" data-dropdown-target="<?= $reply->id . @@ -88,9 +88,9 @@ <?php else: ?> <?= anchor( route_to('post', $podcast->handle, $reply->id), - icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count, + icon('chat', 'text-lg mr-1 text-gray-400') . $reply->replies_count, [ - 'class' => 'inline-flex items-center hover:underline', + 'class' => 'inline-flex items-center hover:underline text-sm', 'title' => lang('Post.replies', [ 'numberOfReplies' => $reply->replies_count, ]), @@ -98,9 +98,9 @@ ) ?> <?= anchor_popup( route_to('post-remote-action', $podcast->handle, $reply->id, 'reblog'), - icon('repeat', 'text-xl mr-1 text-gray-400') . $reply->reblogs_count, + icon('repeat', 'text-lg mr-1 text-gray-400') . $reply->reblogs_count, [ - 'class' => 'inline-flex items-center hover:underline', + 'class' => 'inline-flex items-center hover:underline text-sm', 'width' => 420, 'height' => 620, 'title' => lang('Post.reblogs', [ @@ -110,9 +110,9 @@ ) ?> <?= anchor_popup( route_to('post-remote-action', $podcast->handle, $reply->id, 'favourite'), - icon('heart', 'text-xl mr-1 text-gray-400') . $reply->favourites_count, + icon('heart', 'text-lg mr-1 text-gray-400') . $reply->favourites_count, [ - 'class' => 'inline-flex items-center hover:underline', + 'class' => 'inline-flex items-center hover:underline text-sm', 'width' => 420, 'height' => 620, 'title' => lang('Post.favourites', [