From bb4752c35e086664f5fd75fdc0d56546a1e356f6 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 13 Aug 2021 11:07:29 +0000
Subject: [PATCH] feat(comments): add comments to episodes + update naming of
 status to post

- remove confusing counts for episode (total favourites, total reblogs)
- add comments section to
episode page to display episode comments + post replies linked to the episode
---
 app/Config/Events.php                         | 203 +++++------
 app/Config/Routes.php                         |  76 ++--
 app/Controllers/Admin/EpisodeController.php   |  83 +++--
 app/Controllers/EpisodeController.php         |  59 +++-
 app/Controllers/PodcastController.php         |   4 +-
 ...tatusController.php => PostController.php} |  60 ++--
 .../2020-06-05-170000_add_episodes.php        |  11 +-
 .../2020-08-17-150000_add_pages.php           |   2 +-
 ...-02-23-100000_add_episode_id_to_posts.php} |  12 +-
 ...-03-09-113000_add_created_by_to_posts.php} |  12 +-
 .../2021-08-12-150000_add_comments.php        |  85 +++++
 app/Database/Seeds/AuthSeeder.php             |   4 +-
 app/Entities/Comment.php                      | 110 ++++++
 app/Entities/Episode.php                      |  37 +-
 app/Entities/{Status.php => Post.php}         |   8 +-
 app/Helpers/components_helper.php             |   2 +-
 app/Helpers/url_helper.php                    |   2 +-
 app/Language/en/Comment.php                   |  27 ++
 app/Language/en/Episode.php                   |  21 +-
 app/Language/en/Podcast.php                   |   2 +-
 app/Language/en/{Status.php => Post.php}      |   2 +-
 app/Language/fr/Episode.php                   |  19 +-
 app/Language/fr/Podcast.php                   |   2 +-
 app/Language/fr/{Status.php => Post.php}      |   2 +-
 .../Activities/AnnounceActivity.php           |  12 +-
 app/Libraries/ActivityPub/Config/Routes.php   |  22 +-
 .../Controllers/ActorController.php           |  80 ++---
 ...tatusController.php => PostController.php} |  60 ++--
 .../Controllers/SchedulerController.php       |   2 +-
 .../2018-01-01-010000_add_actors.php          |   4 +-
 ...es.php => 2018-01-01-020000_add_posts.php} |  16 +-
 .../2018-01-01-100000_add_activities.php      |   4 +-
 .../2018-01-01-100000_add_favourites.php      |   6 +-
 ...-01-01-110000_add_posts_preview_cards.php} |  14 +-
 .../2018-01-01-120000_add_blocked_domains.php |   2 +-
 .../ActivityPub/Entities/Activity.php         |  24 +-
 app/Libraries/ActivityPub/Entities/Actor.php  |   4 +-
 .../ActivityPub/Entities/Favourite.php        |   6 +-
 .../Entities/{Status.php => Post.php}         |  66 ++--
 .../ActivityPub/Entities/PreviewCard.php      |   4 +-
 .../ActivityPub/Models/ActivityModel.php      |   8 +-
 .../ActivityPub/Models/ActorModel.php         |   2 +-
 .../ActivityPub/Models/FavouriteModel.php     |  62 ++--
 .../Models/{StatusModel.php => PostModel.php} | 326 +++++++++---------
 .../ActivityPub/Models/PreviewCardModel.php   |  10 +-
 .../ActivityPub/Objects/NoteObject.php        |  20 +-
 app/Libraries/CommentObject.php               |  42 +++
 app/Libraries/NoteObject.php                  |  16 +-
 app/Models/CommentModel.php                   | 184 ++++++++++
 app/Models/EpisodeModel.php                   |   5 +-
 app/Models/PostModel.php                      |  56 +++
 app/Models/StatusModel.php                    |  74 ----
 app/Resources/icons/thumb-down.svg            |   6 +
 app/Resources/icons/thumb-up.svg              |   6 +
 app/Resources/styles/index.css                |   2 +-
 app/Resources/styles/{status.css => post.css} |   4 +-
 app/Resources/styles/tabs.css                 |  11 +-
 app/Views/admin/episode/list.php              |   2 +-
 app/Views/admin/episode/publish.php           |   4 +-
 app/Views/admin/episode/publish_edit.php      |  10 +-
 app/Views/podcast/_partials/comment.php       |  43 +++
 app/Views/podcast/_partials/episode_card.php  |   8 +-
 app/Views/podcast/_partials/header.php        |   4 +-
 app/Views/podcast/_partials/post.php          |  36 ++
 app/Views/podcast/_partials/post_actions.php  |  36 ++
 ...ted.php => post_actions_authenticated.php} |  62 ++--
 .../podcast/_partials/post_authenticated.php  |  36 ++
 ...with_replies.php => post_with_replies.php} |  12 +-
 ...hp => post_with_replies_authenticated.php} |  16 +-
 app/Views/podcast/_partials/reblog.php        |  38 +-
 .../_partials/reblog_authenticated.php        |  38 +-
 app/Views/podcast/_partials/reply.php         |   4 +-
 app/Views/podcast/_partials/reply_actions.php |  12 +-
 .../_partials/reply_actions_authenticated.php |  26 +-
 .../podcast/_partials/reply_authenticated.php |   4 +-
 app/Views/podcast/_partials/status.php        |  36 --
 .../podcast/_partials/status_actions.php      |  36 --
 .../_partials/status_authenticated.php        |  36 --
 app/Views/podcast/activity.php                |   8 +-
 app/Views/podcast/activity_authenticated.php  |  16 +-
 app/Views/podcast/episode.php                 |  75 +---
 app/Views/podcast/episode_authenticated.php   | 102 +++---
 app/Views/podcast/post.php                    |  38 ++
 ...thenticated.php => post_authenticated.php} |  22 +-
 ...mote_action.php => post_remote_action.php} |  16 +-
 app/Views/podcast/status.php                  |  38 --
 86 files changed, 1667 insertions(+), 1152 deletions(-)
 rename app/Controllers/{StatusController.php => PostController.php} (77%)
 rename app/Database/Migrations/{2021-02-23-100000_add_episode_id_to_statuses.php => 2021-02-23-100000_add_episode_id_to_posts.php} (52%)
 rename app/Database/Migrations/{2021-03-09-113000_add_created_by_to_statuses.php => 2021-03-09-113000_add_created_by_to_posts.php} (52%)
 create mode 100644 app/Database/Migrations/2021-08-12-150000_add_comments.php
 create mode 100644 app/Entities/Comment.php
 rename app/Entities/{Status.php => Post.php} (83%)
 create mode 100644 app/Language/en/Comment.php
 rename app/Language/en/{Status.php => Post.php} (95%)
 rename app/Language/fr/{Status.php => Post.php} (94%)
 rename app/Libraries/ActivityPub/Controllers/{StatusController.php => PostController.php} (81%)
 rename app/Libraries/ActivityPub/Database/Migrations/{2018-01-01-020000_add_statuses.php => 2018-01-01-020000_add_posts.php} (85%)
 rename app/Libraries/ActivityPub/Database/Migrations/{2018-01-01-110000_add_statuses_preview_cards.php => 2018-01-01-110000_add_posts_preview_cards.php} (59%)
 rename app/Libraries/ActivityPub/Entities/{Status.php => Post.php} (66%)
 rename app/Libraries/ActivityPub/Models/{StatusModel.php => PostModel.php} (53%)
 create mode 100644 app/Libraries/CommentObject.php
 create mode 100644 app/Models/CommentModel.php
 create mode 100644 app/Models/PostModel.php
 delete mode 100644 app/Models/StatusModel.php
 create mode 100644 app/Resources/icons/thumb-down.svg
 create mode 100644 app/Resources/icons/thumb-up.svg
 rename app/Resources/styles/{status.css => post.css} (87%)
 create mode 100644 app/Views/podcast/_partials/comment.php
 create mode 100644 app/Views/podcast/_partials/post.php
 create mode 100644 app/Views/podcast/_partials/post_actions.php
 rename app/Views/podcast/_partials/{status_actions_authenticated.php => post_actions_authenticated.php} (61%)
 create mode 100644 app/Views/podcast/_partials/post_authenticated.php
 rename app/Views/podcast/_partials/{status_with_replies.php => post_with_replies.php} (53%)
 rename app/Views/podcast/_partials/{status_with_replies_authenticated.php => post_with_replies_authenticated.php} (65%)
 delete mode 100644 app/Views/podcast/_partials/status.php
 delete mode 100644 app/Views/podcast/_partials/status_actions.php
 delete mode 100644 app/Views/podcast/_partials/status_authenticated.php
 create mode 100644 app/Views/podcast/post.php
 rename app/Views/podcast/{status_authenticated.php => post_authenticated.php} (51%)
 rename app/Views/podcast/{status_remote_action.php => post_remote_action.php} (76%)
 delete mode 100644 app/Views/podcast/status.php

diff --git a/app/Config/Events.php b/app/Config/Events.php
index b2288b940b..59bfed7dad 100644
--- a/app/Config/Events.php
+++ b/app/Config/Events.php
@@ -5,7 +5,7 @@ declare(strict_types=1);
 namespace Config;
 
 use App\Entities\Actor;
-use App\Entities\Status;
+use App\Entities\Post;
 use App\Entities\User;
 use CodeIgniter\Events\Events;
 use CodeIgniter\Exceptions\FrameworkException;
@@ -120,82 +120,72 @@ Events::on('on_undo_follow', function ($actor, $targetActor): void {
 });
 
 /**
- * @param Status $status
+ * @param Post $post
  */
-Events::on('on_status_add', function ($status): void {
-    if ($status->in_reply_to_id !== null) {
-        $status = $status->reply_to_status;
+Events::on('on_post_add', function ($post): void {
+    $isReply = $post->in_reply_to_id !== null;
+
+    if ($isReply) {
+        $post = $post->reply_to_post;
     }
 
-    if ($status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $status->episode_id)
-            ->increment('statuses_total');
+    if ($post->episode_id !== null) {
+        if ($isReply) {
+            model('EpisodeModel', false)
+                ->where('id', $post->episode_id)
+                ->increment('comments_count');
+        } else {
+            model('EpisodeModel', false)
+                ->where('id', $post->episode_id)
+                ->increment('posts_count');
+        }
     }
 
-    if ($status->actor->is_podcast) {
+    if ($post->actor->is_podcast) {
         // Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs
         // same for other events below
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 });
 
 /**
- * @param Status $status
+ * @param Post $post
  */
-Events::on('on_status_remove', function ($status): void {
-    if ($status->in_reply_to_id !== null) {
-        Events::trigger('on_status_remove', $status->reply_to_status);
+Events::on('on_post_remove', function ($post): void {
+    if ($post->in_reply_to_id !== null) {
+        Events::trigger('on_post_remove', $post->reply_to_post);
     }
 
-    if ($episodeId = $status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->decrement('statuses_total', 1 + $status->reblogs_count);
-
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->decrement('reblogs_total', $status->reblogs_count);
-
-        model('EpisodeModel')
+    if ($episodeId = $post->episode_id) {
+        model('EpisodeModel', false)
             ->where('id', $episodeId)
-            ->decrement('favourites_total', $status->favourites_count);
+            ->decrement('posts_count');
     }
 
-    if ($status->actor->is_podcast) {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
 });
 
 /**
  * @param Actor $actor
- * @param Status $status
+ * @param Post $post
  */
-Events::on('on_status_reblog', function ($actor, $status): void {
-    if ($episodeId = $status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->increment('reblogs_total');
-
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->increment('statuses_total');
-    }
-
-    if ($status->actor->is_podcast) {
+Events::on('on_post_reblog', function ($actor, $post): void {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     if ($actor->is_podcast) {
@@ -205,111 +195,96 @@ Events::on('on_status_reblog', function ($actor, $status): void {
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
 
-    if ($status->in_reply_to_id !== null) {
-        cache()->deleteMatching("page_status#{$status->in_reply_to_id}");
+    if ($post->in_reply_to_id !== null) {
+        cache()->deleteMatching("page_post#{$post->in_reply_to_id}");
     }
 });
 
 /**
- * @param Status $reblogStatus
+ * @param Post $reblogPost
  */
-Events::on('on_status_undo_reblog', function ($reblogStatus): void {
-    $status = $reblogStatus->reblog_of_status;
-    if ($episodeId = $status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->decrement('reblogs_total');
-
-        model('EpisodeModel')
-            ->where('id', $episodeId)
-            ->decrement('statuses_total');
-    }
+Events::on('on_post_undo_reblog', function ($reblogPost): void {
+    $post = $reblogPost->reblog_of_post;
 
-    if ($status->actor->is_podcast) {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
     cache()
-        ->deleteMatching("page_status#{$reblogStatus->id}*");
+        ->deleteMatching("page_post#{$reblogPost->id}*");
 
-    if ($status->in_reply_to_id !== null) {
-        cache()->deleteMatching("page_status#{$status->in_reply_to_id}");
+    if ($post->in_reply_to_id !== null) {
+        cache()->deleteMatching("page_post#{$post->in_reply_to_id}");
     }
 
-    if ($reblogStatus->actor->is_podcast) {
+    if ($reblogPost->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$reblogStatus->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$reblogPost->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$reblogStatus->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$reblogPost->actor->podcast->id}*");
     }
 });
 
 /**
- * @param Status $reply
+ * @param Post $reply
  */
-Events::on('on_status_reply', function ($reply): void {
-    $status = $reply->reply_to_status;
+Events::on('on_post_reply', function ($reply): void {
+    $post = $reply->reply_to_post;
 
-    if ($status->actor->is_podcast) {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
 });
 
 /**
- * @param Status $reply
+ * @param Post $reply
  */
 Events::on('on_reply_remove', function ($reply): void {
-    $status = $reply->reply_to_status;
+    $post = $reply->reply_to_post;
 
-    if ($status->actor->is_podcast) {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
     cache()
-        ->deleteMatching("page_status#{$reply->id}*");
+        ->deleteMatching("page_post#{$reply->id}*");
 });
 
 /**
  * @param Actor $actor
- * @param Status $status
+ * @param Post $post
  */
-Events::on('on_status_favourite', function ($actor, $status): void {
-    if ($status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $status->episode_id)
-            ->increment('favourites_total');
-    }
-
-    if ($status->actor->is_podcast) {
+Events::on('on_post_favourite', function ($actor, $post): void {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
 
-    if ($status->in_reply_to_id !== null) {
-        cache()->deleteMatching("page_status#{$status->in_reply_to_id}*");
+    if ($post->in_reply_to_id !== null) {
+        cache()->deleteMatching("page_post#{$post->in_reply_to_id}*");
     }
 
     if ($actor->is_podcast) {
@@ -321,27 +296,21 @@ Events::on('on_status_favourite', function ($actor, $status): void {
 
 /**
  * @param Actor $actor
- * @param Status $status
+ * @param Post $post
  */
-Events::on('on_status_undo_favourite', function ($actor, $status): void {
-    if ($status->episode_id) {
-        model('EpisodeModel')
-            ->where('id', $status->episode_id)
-            ->decrement('favourites_total');
-    }
-
-    if ($status->actor->is_podcast) {
+Events::on('on_post_undo_favourite', function ($actor, $post): void {
+    if ($post->actor->is_podcast) {
         cache()
-            ->deleteMatching("podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
         cache()
-            ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
+            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
     }
 
     cache()
-        ->deleteMatching("page_status#{$status->id}*");
+        ->deleteMatching("page_post#{$post->id}*");
 
-    if ($status->in_reply_to_id !== null) {
-        cache()->deleteMatching("page_status#{$status->in_reply_to_id}*");
+    if ($post->in_reply_to_id !== null) {
+        cache()->deleteMatching("page_post#{$post->in_reply_to_id}*");
     }
 
     if ($actor->is_podcast) {
@@ -356,7 +325,7 @@ Events::on('on_block_actor', function (int $actorId): void {
     cache()
         ->deleteMatching('podcast*');
     cache()
-        ->deleteMatching('page_status*');
+        ->deleteMatching('page_post*');
 });
 
 Events::on('on_unblock_actor', function (int $actorId): void {
@@ -364,7 +333,7 @@ Events::on('on_unblock_actor', function (int $actorId): void {
     cache()
         ->deleteMatching('podcast*');
     cache()
-        ->deleteMatching('page_status*');
+        ->deleteMatching('page_post*');
 });
 
 Events::on('on_block_domain', function (string $domainName): void {
@@ -372,7 +341,7 @@ Events::on('on_block_domain', function (string $domainName): void {
     cache()
         ->deleteMatching('podcast*');
     cache()
-        ->deleteMatching('page_status*');
+        ->deleteMatching('page_post*');
 });
 
 Events::on('on_unblock_domain', function (string $domainName): void {
@@ -380,5 +349,5 @@ Events::on('on_unblock_domain', function (string $domainName): void {
     cache()
         ->deleteMatching('podcast*');
     cache()
-        ->deleteMatching('page_status*');
+        ->deleteMatching('page_post*');
 });
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index f75b2240dd..88d4be2e1e 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -32,10 +32,10 @@ $routes->setAutoRoute(false);
  */
 
 $routes->addPlaceholder('podcastHandle', '[a-zA-Z0-9\_]{1,32}');
-$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}');
+$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,128}');
 $routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}');
 $routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding');
-$routes->addPlaceholder('statusAction', '\bfavourite|\breblog|\breply');
+$routes->addPlaceholder('postAction', '\bfavourite|\breblog|\breply');
 $routes->addPlaceholder('embeddablePlayerTheme', '\blight|\bdark|\blight-transparent|\bdark-transparent');
 $routes->addPlaceholder(
     'uuid',
@@ -416,6 +416,25 @@ $routes->group(
                                 ],
                             );
                         });
+
+                        $routes->group('comments', function ($routes): void {
+                            $routes->post(
+                                'new',
+                                'EpisodeController::attemptCommentCreate/$1/$2',
+                                [
+                                    'as' => 'comment-attempt-create',
+                                    'filter' => 'permission:podcast-manage_publications',
+                                ]
+                            );
+                            $routes->post(
+                                'delete',
+                                'EpisodeController::attemptCommentDelete/$1/$2',
+                                [
+                                    'as' => 'comment-attempt-delete',
+                                    'filter' => 'permission:podcast-manage_publications',
+                                ]
+                            );
+                        });
                     });
                 });
 
@@ -752,6 +771,12 @@ $routes->group('@(:podcastHandle)', function ($routes): void {
                 'controller-method' => 'EpisodeController::comments/$1/$2',
             ],
         ]);
+        $routes->get('comments/(:uuid)', 'EpisodeController::comment/$1/$2/$3', [
+            'as' => 'comment',
+        ]);
+        $routes->get('comments/(:uuid)/replies', 'EpisodeController::commentReplies/$1/$2/$3', [
+            'as' => 'comment-replies',
+        ]);
         $routes->get('oembed.json', 'EpisodeController::oembedJSON/$1/$2', [
             'as' => 'episode-oembed-json',
         ]);
@@ -803,73 +828,74 @@ $routes->post('interact-as-actor', 'AuthController::attemptInteractAsActor', [
  * Overwriting ActivityPub routes file
  */
 $routes->group('@(:podcastHandle)', function ($routes): void {
-    $routes->post('statuses/new', 'StatusController::attemptCreate/$1', [
-        'as' => 'status-attempt-create',
+    $routes->post('posts/new', 'PostController::attemptCreate/$1', [
+        'as' => 'post-attempt-create',
         'filter' => 'permission:podcast-manage_publications',
     ]);
-    // Status
-    $routes->group('statuses/(:uuid)', function ($routes): void {
+
+    // Post
+    $routes->group('posts/(:uuid)', function ($routes): void {
         $routes->options('/', 'ActivityPubController::preflight');
-        $routes->get('/', 'StatusController::view/$1/$2', [
-            'as' => 'status',
+        $routes->get('/', 'PostController::view/$1/$2', [
+            'as' => 'post',
             'alternate-content' => [
                 'application/activity+json' => [
                     'namespace' => 'ActivityPub\Controllers',
-                    'controller-method' => 'StatusController/$2',
+                    'controller-method' => 'PostController/$2',
                 ],
                 'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
                     'namespace' => 'ActivityPub\Controllers',
-                    'controller-method' => 'StatusController/$2',
+                    'controller-method' => 'PostController/$2',
                 ],
             ],
         ]);
         $routes->options('replies', 'ActivityPubController::preflight');
-        $routes->get('replies', 'StatusController/$1/$2', [
-            'as' => 'status-replies',
+        $routes->get('replies', 'PostController/$1/$2', [
+            'as' => 'post-replies',
             'alternate-content' => [
                 'application/activity+json' => [
                     'namespace' => 'ActivityPub\Controllers',
-                    'controller-method' => 'StatusController::replies/$2',
+                    'controller-method' => 'PostController::replies/$2',
                 ],
                 'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
                     'namespace' => 'ActivityPub\Controllers',
-                    'controller-method' => 'StatusController::replies/$2',
+                    'controller-method' => 'PostController::replies/$2',
                 ],
             ],
         ]);
 
         // Actions
-        $routes->post('action', 'StatusController::attemptAction/$1/$2', [
-            'as' => 'status-attempt-action',
+        $routes->post('action', 'PostController::attemptAction/$1/$2', [
+            'as' => 'post-attempt-action',
             'filter' => 'permission:podcast-interact_as',
         ]);
 
         $routes->post(
             'block-actor',
-            'StatusController::attemptBlockActor/$1/$2',
+            'PostController::attemptBlockActor/$1/$2',
             [
-                'as' => 'status-attempt-block-actor',
+                'as' => 'post-attempt-block-actor',
                 'filter' => 'permission:fediverse-block_actors',
             ],
         );
         $routes->post(
             'block-domain',
-            'StatusController::attemptBlockDomain/$1/$2',
+            'PostController::attemptBlockDomain/$1/$2',
             [
-                'as' => 'status-attempt-block-domain',
+                'as' => 'post-attempt-block-domain',
                 'filter' => 'permission:fediverse-block_domains',
             ],
         );
-        $routes->post('delete', 'StatusController::attemptDelete/$1/$2', [
-            'as' => 'status-attempt-delete',
+        $routes->post('delete', 'PostController::attemptDelete/$1/$2', [
+            'as' => 'post-attempt-delete',
             'filter' => 'permission:podcast-manage_publications',
         ]);
 
         $routes->get(
-            'remote/(:statusAction)',
-            'StatusController::remoteAction/$1/$2/$3',
+            'remote/(:postAction)',
+            'PostController::remoteAction/$1/$2/$3',
             [
-                'as' => 'status-remote-action',
+                'as' => 'post-remote-action',
             ],
         );
     });
diff --git a/app/Controllers/Admin/EpisodeController.php b/app/Controllers/Admin/EpisodeController.php
index bacf575f52..fea2490da0 100644
--- a/app/Controllers/Admin/EpisodeController.php
+++ b/app/Controllers/Admin/EpisodeController.php
@@ -10,15 +10,17 @@ declare(strict_types=1);
 
 namespace App\Controllers\Admin;
 
+use App\Entities\Comment;
 use App\Entities\Episode;
 use App\Entities\Image;
 use App\Entities\Location;
 use App\Entities\Podcast;
-use App\Entities\Status;
+use App\Entities\Post;
+use App\Models\CommentModel;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
+use App\Models\PostModel;
 use App\Models\SoundbiteModel;
-use App\Models\StatusModel;
 use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\HTTP\RedirectResponse;
 use CodeIgniter\I18n\Time;
@@ -429,7 +431,7 @@ class EpisodeController extends BaseController
         $db = db_connect();
         $db->transStart();
 
-        $newStatus = new Status([
+        $newPost = new Post([
             'actor_id' => $this->podcast->actor_id,
             'episode_id' => $this->episode->id,
             'message' => $this->request->getPost('message'),
@@ -456,15 +458,15 @@ class EpisodeController extends BaseController
             $this->episode->published_at = Time::now();
         }
 
-        $newStatus->published_at = $this->episode->published_at;
+        $newPost->published_at = $this->episode->published_at;
 
-        $statusModel = new StatusModel();
-        if (! $statusModel->addStatus($newStatus)) {
+        $postModel = new PostModel();
+        if (! $postModel->addPost($newPost)) {
             $db->transRollback();
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $statusModel->errors());
+                ->with('errors', $postModel->errors());
         }
 
         $episodeModel = new EpisodeModel();
@@ -489,7 +491,7 @@ class EpisodeController extends BaseController
             $data = [
                 'podcast' => $this->podcast,
                 'episode' => $this->episode,
-                'status' => (new StatusModel())
+                'post' => (new PostModel())
                     ->where([
                         'actor_id' => $this->podcast->actor_id,
                         'episode_id' => $this->episode->id,
@@ -513,7 +515,7 @@ class EpisodeController extends BaseController
     public function attemptPublishEdit(): RedirectResponse
     {
         $rules = [
-            'status_id' => 'required',
+            'post_id' => 'required',
             'publication_method' => 'required',
             'scheduled_publication_date' =>
                 'valid_date[Y-m-d H:i]|permit_empty',
@@ -549,19 +551,19 @@ class EpisodeController extends BaseController
             $this->episode->published_at = Time::now();
         }
 
-        $status = (new StatusModel())->getStatusById($this->request->getPost('status_id'));
+        $post = (new PostModel())->getPostById($this->request->getPost('post_id'));
 
-        if ($status !== null) {
-            $status->message = $this->request->getPost('message');
-            $status->published_at = $this->episode->published_at;
+        if ($post !== null) {
+            $post->message = $this->request->getPost('message');
+            $post->published_at = $this->episode->published_at;
 
-            $statusModel = new StatusModel();
-            if (! $statusModel->editStatus($status)) {
+            $postModel = new PostModel();
+            if (! $postModel->editPost($post)) {
                 $db->transRollback();
                 return redirect()
                     ->back()
                     ->withInput()
-                    ->with('errors', $statusModel->errors());
+                    ->with('errors', $postModel->errors());
             }
         }
 
@@ -585,14 +587,14 @@ class EpisodeController extends BaseController
             $db = db_connect();
             $db->transStart();
 
-            $statusModel = new StatusModel();
-            $status = $statusModel
+            $postModel = new PostModel();
+            $post = $postModel
                 ->where([
                     'actor_id' => $this->podcast->actor_id,
                     'episode_id' => $this->episode->id,
                 ])
                 ->first();
-            $statusModel->removeStatus($status);
+            $postModel->removePost($post);
 
             $this->episode->published_at = null;
 
@@ -656,13 +658,13 @@ class EpisodeController extends BaseController
 
         $db->transStart();
 
-        $allStatusesLinkedToEpisode = (new StatusModel())
+        $allPostsLinkedToEpisode = (new PostModel())
             ->where([
                 'episode_id' => $this->episode->id,
             ])
             ->findAll();
-        foreach ($allStatusesLinkedToEpisode as $status) {
-            (new StatusModel())->removeStatus($status);
+        foreach ($allPostsLinkedToEpisode as $post) {
+            (new PostModel())->removePost($post);
         }
 
         // set episode published_at to null to unpublish
@@ -782,4 +784,41 @@ class EpisodeController extends BaseController
         ]);
         return view('admin/episode/embeddable_player', $data);
     }
+
+    public function attemptCommentCreate(): RedirectResponse
+    {
+        $rules = [
+            'message' => 'required|max_length[500]',
+        ];
+
+        if (! $this->validate($rules)) {
+            return redirect()
+                ->back()
+                ->withInput()
+                ->with('errors', $this->validator->getErrors());
+        }
+
+        $message = $this->request->getPost('message');
+
+        $newComment = new Comment([
+            'actor_id' => interact_as_actor_id(),
+            'episode_id' => $this->episode->id,
+            'message' => $message,
+            'created_at' => new Time('now'),
+            'created_by' => user_id(),
+        ]);
+
+        $commentModel = new CommentModel();
+        if (
+            ! $commentModel->addComment($newComment, true)
+        ) {
+            return redirect()
+                ->back()
+                ->withInput()
+                ->with('errors', $commentModel->errors());
+        }
+
+        // Comment has been successfully created
+        return redirect()->back();
+    }
 }
diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php
index e51ba7b756..4e44af5744 100644
--- a/app/Controllers/EpisodeController.php
+++ b/app/Controllers/EpisodeController.php
@@ -15,8 +15,10 @@ use ActivityPub\Objects\OrderedCollectionPage;
 use Analytics\AnalyticsTrait;
 use App\Entities\Episode;
 use App\Entities\Podcast;
+use App\Libraries\CommentObject;
 use App\Libraries\NoteObject;
 use App\Libraries\PodcastEpisode;
+use App\Models\CommentModel;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
 use CodeIgniter\Database\BaseBuilder;
@@ -219,10 +221,10 @@ class EpisodeController extends BaseController
         /**
          * get comments: aggregated replies from posts referring to the episode
          */
-        $episodeComments = model('StatusModel')
+        $episodeComments = model('PostModel')
             ->whereIn('in_reply_to_id', function (BaseBuilder $builder): BaseBuilder {
                 return $builder->select('id')
-                    ->from('activitypub_statuses')
+                    ->from('activitypub_posts')
                     ->where('episode_id', $this->episode->id);
             })
             ->where('`published_at` <= NOW()', null, false)
@@ -254,4 +256,57 @@ class EpisodeController extends BaseController
             ->setHeader('Access-Control-Allow-Origin', '*')
             ->setBody($collection->toJSON());
     }
+
+    /**
+     * @noRector ReturnTypeDeclarationRector
+     */
+    public function comment(string $commentId): Response
+    {
+        if (
+            ($comment = (new CommentModel())->getCommentById($commentId)) === null
+        ) {
+            throw PageNotFoundException::forPageNotFound();
+        }
+
+        $commentObject = new CommentObject($comment);
+
+        return $this->response
+            ->setContentType('application/json')
+            ->setBody($commentObject->toJSON());
+    }
+
+    public function commentReplies(string $commentId): Response
+    {
+        /**
+         * get comment replies
+         */
+        $commentReplies = model('CommentModel', false)
+            ->where('in_reply_to_id', service('uuid')->fromString($commentId)->getBytes())
+            ->orderBy('created_at', 'ASC');
+
+        $pageNumber = (int) $this->request->getGet('page');
+
+        if ($pageNumber < 1) {
+            $commentReplies->paginate(12);
+            $pager = $commentReplies->pager;
+            $collection = new OrderedCollectionObject(null, $pager);
+        } else {
+            $paginatedReplies = $commentReplies->paginate(12, 'default', $pageNumber);
+            $pager = $commentReplies->pager;
+
+            $orderedItems = [];
+            if ($paginatedReplies !== null) {
+                foreach ($paginatedReplies as $reply) {
+                    $replyObject = new CommentObject($reply);
+                    $orderedItems[] = $replyObject;
+                }
+            }
+
+            $collection = new OrderedCollectionPage($pager, $orderedItems);
+        }
+
+        return $this->response
+            ->setContentType('application/activity+json')
+            ->setBody($collection->toJSON());
+    }
 }
diff --git a/app/Controllers/PodcastController.php b/app/Controllers/PodcastController.php
index 2322535eed..a21f117ec3 100644
--- a/app/Controllers/PodcastController.php
+++ b/app/Controllers/PodcastController.php
@@ -18,7 +18,7 @@ use App\Libraries\PodcastActor;
 use App\Libraries\PodcastEpisode;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
-use App\Models\StatusModel;
+use App\Models\PostModel;
 use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\HTTP\Response;
 
@@ -81,7 +81,7 @@ class PodcastController extends BaseController
         if (! ($cachedView = cache($cacheName))) {
             $data = [
                 'podcast' => $this->podcast,
-                'statuses' => (new StatusModel())->getActorPublishedStatuses($this->podcast->actor_id),
+                'posts' => (new PostModel())->getActorPublishedPosts($this->podcast->actor_id),
             ];
 
             // if user is logged in then send to the authenticated activity view
diff --git a/app/Controllers/StatusController.php b/app/Controllers/PostController.php
similarity index 77%
rename from app/Controllers/StatusController.php
rename to app/Controllers/PostController.php
index c6f5c2f062..c3761da63b 100644
--- a/app/Controllers/StatusController.php
+++ b/app/Controllers/PostController.php
@@ -10,21 +10,21 @@ declare(strict_types=1);
 
 namespace App\Controllers;
 
-use ActivityPub\Controllers\StatusController as ActivityPubStatusController;
-use ActivityPub\Entities\Status as ActivityPubStatus;
+use ActivityPub\Controllers\PostController as ActivityPubPostController;
+use ActivityPub\Entities\Post as ActivityPubPost;
 use Analytics\AnalyticsTrait;
 use App\Entities\Actor;
 use App\Entities\Podcast;
-use App\Entities\Status as CastopodStatus;
+use App\Entities\Post as CastopodPost;
 use App\Models\EpisodeModel;
 use App\Models\PodcastModel;
-use App\Models\StatusModel;
+use App\Models\PostModel;
 use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\HTTP\RedirectResponse;
 use CodeIgniter\HTTP\URI;
 use CodeIgniter\I18n\Time;
 
-class StatusController extends ActivityPubStatusController
+class PostController extends ActivityPubPostController
 {
     use AnalyticsTrait;
 
@@ -50,9 +50,9 @@ class StatusController extends ActivityPubStatusController
 
         if (
             count($params) > 1 &&
-            ($status = (new StatusModel())->getStatusById($params[1])) !== null
+            ($post = (new PostModel())->getPostById($params[1])) !== null
         ) {
-            $this->status = $status;
+            $this->post = $post;
 
             unset($params[0]);
             unset($params[1]);
@@ -72,7 +72,7 @@ class StatusController extends ActivityPubStatusController
             '_',
             array_filter([
                 'page',
-                "status#{$this->status->id}",
+                "post#{$this->post->id}",
                 service('request')
                     ->getLocale(),
                 can_user_interact() ? '_authenticated' : null,
@@ -83,15 +83,15 @@ class StatusController extends ActivityPubStatusController
             $data = [
                 'podcast' => $this->podcast,
                 'actor' => $this->actor,
-                'status' => $this->status,
+                'post' => $this->post,
             ];
 
             // if user is logged in then send to the authenticated activity view
             if (can_user_interact()) {
                 helper('form');
-                return view('podcast/status_authenticated', $data);
+                return view('podcast/post_authenticated', $data);
             }
-            return view('podcast/status', $data, [
+            return view('podcast/post', $data, [
                 'cache' => DECADE,
                 'cache_name' => $cacheName,
             ]);
@@ -116,7 +116,7 @@ class StatusController extends ActivityPubStatusController
 
         $message = $this->request->getPost('message');
 
-        $newStatus = new CastopodStatus([
+        $newPost = new CastopodPost([
             'actor_id' => interact_as_actor_id(),
             'published_at' => Time::now(),
             'created_by' => user_id(),
@@ -129,23 +129,23 @@ class StatusController extends ActivityPubStatusController
             ($params = extract_params_from_episode_uri(new URI($episodeUri))) &&
             ($episode = (new EpisodeModel())->getEpisodeBySlug($params['podcastHandle'], $params['episodeSlug']))
         ) {
-            $newStatus->episode_id = $episode->id;
+            $newPost->episode_id = $episode->id;
         }
 
-        $newStatus->message = $message;
+        $newPost->message = $message;
 
-        $statusModel = new StatusModel();
+        $postModel = new PostModel();
         if (
-            ! $statusModel
-                ->addStatus($newStatus, ! (bool) $newStatus->episode_id, true)
+            ! $postModel
+                ->addPost($newPost, ! (bool) $newPost->episode_id, true)
         ) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $statusModel->errors());
+                ->with('errors', $postModel->errors());
         }
 
-        // Status has been successfully created
+        // Post has been successfully created
         return redirect()->back();
     }
 
@@ -162,36 +162,36 @@ class StatusController extends ActivityPubStatusController
                 ->with('errors', $this->validator->getErrors());
         }
 
-        $newStatus = new ActivityPubStatus([
+        $newPost = new ActivityPubPost([
             'actor_id' => interact_as_actor_id(),
-            'in_reply_to_id' => $this->status->id,
+            'in_reply_to_id' => $this->post->id,
             'message' => $this->request->getPost('message'),
             'published_at' => Time::now(),
             'created_by' => user_id(),
         ]);
 
-        $statusModel = new StatusModel();
-        if (! $statusModel->addReply($newStatus)) {
+        $postModel = new PostModel();
+        if (! $postModel->addReply($newPost)) {
             return redirect()
                 ->back()
                 ->withInput()
-                ->with('errors', $statusModel->errors());
+                ->with('errors', $postModel->errors());
         }
 
-        // Reply status without preview card has been successfully created
+        // Reply post without preview card has been successfully created
         return redirect()->back();
     }
 
     public function attemptFavourite(): RedirectResponse
     {
-        model('FavouriteModel')->toggleFavourite(interact_as_actor(), $this->status);
+        model('FavouriteModel')->toggleFavourite(interact_as_actor(), $this->post);
 
         return redirect()->back();
     }
 
     public function attemptReblog(): RedirectResponse
     {
-        (new StatusModel())->toggleReblog(interact_as_actor(), $this->status);
+        (new PostModel())->toggleReblog(interact_as_actor(), $this->post);
 
         return redirect()->back();
     }
@@ -230,20 +230,20 @@ class StatusController extends ActivityPubStatusController
 
         $cacheName = implode(
             '_',
-            array_filter(['page', "status#{$this->status->id}", "remote_{$action}", service('request') ->getLocale()]),
+            array_filter(['page', "post#{$this->post->id}", "remote_{$action}", service('request') ->getLocale()]),
         );
 
         if (! ($cachedView = cache($cacheName))) {
             $data = [
                 'podcast' => $this->podcast,
                 'actor' => $this->actor,
-                'status' => $this->status,
+                'post' => $this->post,
                 'action' => $action,
             ];
 
             helper('form');
 
-            return view('podcast/status_remote_action', $data, [
+            return view('podcast/post_remote_action', $data, [
                 'cache' => DECADE,
                 'cache_name' => $cacheName,
             ]);
diff --git a/app/Database/Migrations/2020-06-05-170000_add_episodes.php b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
index a6d517966a..310b1b70a5 100644
--- a/app/Database/Migrations/2020-06-05-170000_add_episodes.php
+++ b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
@@ -38,7 +38,7 @@ class AddEpisodes extends Migration
             ],
             'slug' => [
                 'type' => 'VARCHAR',
-                'constraint' => 191,
+                'constraint' => 128,
             ],
             'audio_file_path' => [
                 'type' => 'VARCHAR',
@@ -147,17 +147,12 @@ class AddEpisodes extends Migration
                 'type' => 'JSON',
                 'null' => true,
             ],
-            'favourites_total' => [
-                'type' => 'INT',
-                'unsigned' => true,
-                'default' => 0,
-            ],
-            'reblogs_total' => [
+            'posts_count' => [
                 'type' => 'INT',
                 'unsigned' => true,
                 'default' => 0,
             ],
-            'statuses_total' => [
+            'comments_count' => [
                 'type' => 'INT',
                 'unsigned' => true,
                 'default' => 0,
diff --git a/app/Database/Migrations/2020-08-17-150000_add_pages.php b/app/Database/Migrations/2020-08-17-150000_add_pages.php
index cee4ef5877..ef5e2a3b9b 100644
--- a/app/Database/Migrations/2020-08-17-150000_add_pages.php
+++ b/app/Database/Migrations/2020-08-17-150000_add_pages.php
@@ -30,7 +30,7 @@ class AddPages extends Migration
             ],
             'slug' => [
                 'type' => 'VARCHAR',
-                'constraint' => 191,
+                'constraint' => 128,
                 'unique' => true,
             ],
             'content_markdown' => [
diff --git a/app/Database/Migrations/2021-02-23-100000_add_episode_id_to_statuses.php b/app/Database/Migrations/2021-02-23-100000_add_episode_id_to_posts.php
similarity index 52%
rename from app/Database/Migrations/2021-02-23-100000_add_episode_id_to_statuses.php
rename to app/Database/Migrations/2021-02-23-100000_add_episode_id_to_posts.php
index a81a782f88..b34c801f50 100644
--- a/app/Database/Migrations/2021-02-23-100000_add_episode_id_to_statuses.php
+++ b/app/Database/Migrations/2021-02-23-100000_add_episode_id_to_posts.php
@@ -3,7 +3,7 @@
 declare(strict_types=1);
 
 /**
- * Class AddEpisodeIdToStatuses Adds episode_id field to activitypub_statuses table in database
+ * Class AddEpisodeIdToPosts Adds episode_id field to activitypub_posts table in database
  *
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -14,23 +14,23 @@ namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
 
-class AddEpisodeIdToStatuses extends Migration
+class AddEpisodeIdToPosts extends Migration
 {
     public function up(): void
     {
         $prefix = $this->db->getPrefix();
 
         $createQuery = <<<CODE_SAMPLE
-            ALTER TABLE {$prefix}activitypub_statuses
+            ALTER TABLE {$prefix}activitypub_posts
             ADD COLUMN `episode_id` INT UNSIGNED NULL AFTER `replies_count`,
-            ADD FOREIGN KEY {$prefix}activitypub_statuses_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE;
+            ADD FOREIGN KEY {$prefix}activitypub_posts_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE;
         CODE_SAMPLE;
         $this->db->query($createQuery);
     }
 
     public function down(): void
     {
-        $this->forge->dropForeignKey('activitypub_statuses', 'activitypub_statuses_episode_id_foreign');
-        $this->forge->dropColumn('activitypub_statuses', 'episode_id');
+        $this->forge->dropForeignKey('activitypub_posts', 'activitypub_posts_episode_id_foreign');
+        $this->forge->dropColumn('activitypub_posts', 'episode_id');
     }
 }
diff --git a/app/Database/Migrations/2021-03-09-113000_add_created_by_to_statuses.php b/app/Database/Migrations/2021-03-09-113000_add_created_by_to_posts.php
similarity index 52%
rename from app/Database/Migrations/2021-03-09-113000_add_created_by_to_statuses.php
rename to app/Database/Migrations/2021-03-09-113000_add_created_by_to_posts.php
index 2f9a29d6e4..9ccd81bde1 100644
--- a/app/Database/Migrations/2021-03-09-113000_add_created_by_to_statuses.php
+++ b/app/Database/Migrations/2021-03-09-113000_add_created_by_to_posts.php
@@ -3,7 +3,7 @@
 declare(strict_types=1);
 
 /**
- * Class AddCreatedByToStatuses Adds created_by field to activitypub_statuses table in database
+ * Class AddCreatedByToPosts Adds created_by field to activitypub_posts table in database
  *
  * @copyright  2020 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -14,23 +14,23 @@ namespace App\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
 
-class AddCreatedByToStatuses extends Migration
+class AddCreatedByToPosts extends Migration
 {
     public function up(): void
     {
         $prefix = $this->db->getPrefix();
 
         $createQuery = <<<CODE_SAMPLE
-            ALTER TABLE {$prefix}activitypub_statuses
+            ALTER TABLE {$prefix}activitypub_posts
             ADD COLUMN `created_by` INT UNSIGNED AFTER `episode_id`,
-            ADD FOREIGN KEY {$prefix}activitypub_statuses_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE;
+            ADD FOREIGN KEY {$prefix}activitypub_posts_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE;
         CODE_SAMPLE;
         $this->db->query($createQuery);
     }
 
     public function down(): void
     {
-        $this->forge->dropForeignKey('activitypub_statuses', 'activitypub_statuses_created_by_foreign');
-        $this->forge->dropColumn('activitypub_statuses', 'created_by');
+        $this->forge->dropForeignKey('activitypub_posts', 'activitypub_posts_created_by_foreign');
+        $this->forge->dropColumn('activitypub_posts', 'created_by');
     }
 }
diff --git a/app/Database/Migrations/2021-08-12-150000_add_comments.php b/app/Database/Migrations/2021-08-12-150000_add_comments.php
new file mode 100644
index 0000000000..612d9f6343
--- /dev/null
+++ b/app/Database/Migrations/2021-08-12-150000_add_comments.php
@@ -0,0 +1,85 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * Class AddComments creates comments table in database
+ *
+ * @copyright  2020 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Database\Migrations;
+
+use CodeIgniter\Database\Migration;
+
+class AddComments extends Migration
+{
+    public function up(): void
+    {
+        $this->forge->addField([
+            'id' => [
+                'type' => 'BINARY',
+                'constraint' => 16,
+            ],
+            'uri' => [
+                'type' => 'VARCHAR',
+                'constraint' => 255,
+            ],
+            'episode_id' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'actor_id' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'in_reply_to_id' => [
+                'type' => 'BINARY',
+                'constraint' => 16,
+                'null' => true,
+            ],
+            'message' => [
+                'type' => 'VARCHAR',
+                'constraint' => 500,
+                'null' => true,
+            ],
+            'message_html' => [
+                'type' => 'VARCHAR',
+                'constraint' => 600,
+                'null' => true,
+            ],
+            'likes_count' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'dislikes_count' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'replies_count' => [
+                'type' => 'INT',
+                'unsigned' => true,
+            ],
+            'created_at' => [
+                'type' => 'DATETIME',
+            ],
+            'created_by' => [
+                'type' => 'INT',
+                'unsigned' => true,
+                'null' => true,
+            ],
+        ]);
+        $this->forge->addPrimaryKey('id');
+        $this->forge->addForeignKey('episode_id', 'episodes', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('created_by', 'users', 'id');
+        $this->forge->createTable('comments');
+    }
+
+    public function down(): void
+    {
+        $this->forge->dropTable('comments');
+    }
+}
diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php
index 1e46d1ad58..3a76e36215 100644
--- a/app/Database/Seeds/AuthSeeder.php
+++ b/app/Database/Seeds/AuthSeeder.php
@@ -162,13 +162,13 @@ class AuthSeeder extends Seeder
             [
                 'name' => 'manage_publications',
                 'description' =>
-                    'Publish / unpublish episodes & statuses of a podcast',
+                    'Publish / unpublish episodes & posts of a podcast',
                 'has_permission' => ['podcast_admin'],
             ],
             [
                 'name' => 'interact_as',
                 'description' =>
-                    'Interact as the podcast to favourite / share or reply to statuses.',
+                    'Interact as the podcast to favourite / share or reply to posts.',
                 'has_permission' => ['podcast_admin'],
             ],
         ],
diff --git a/app/Entities/Comment.php b/app/Entities/Comment.php
new file mode 100644
index 0000000000..6235802f8f
--- /dev/null
+++ b/app/Entities/Comment.php
@@ -0,0 +1,110 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Entities;
+
+use App\Models\EpisodeModel;
+use CodeIgniter\I18n\Time;
+use Michalsn\Uuid\UuidEntity;
+use RuntimeException;
+
+/**
+ * @property string $id
+ * @property string $uri
+ * @property int $episode_id
+ * @property Episode|null $episode
+ * @property int $actor_id
+ * @property Actor|null $actor
+ * @property string $in_reply_to_id
+ * @property Comment|null $reply_to_comment
+ * @property string $message
+ * @property string $message_html
+ * @property int $likes_count
+ * @property int $dislikes_count
+ * @property int $replies_count
+ * @property Time $created_at
+ * @property int $created_by
+ */
+class Comment extends UuidEntity
+{
+    protected ?Episode $episode = null;
+
+    protected ?Actor $actor = null;
+
+    protected ?Comment $reply_to_comment = null;
+
+    /**
+     * @var string[]
+     */
+    protected $dates = ['created_at'];
+
+    /**
+     * @var array<string, string>
+     */
+    protected $casts = [
+        'id' => 'string',
+        'uri' => 'string',
+        'episode_id' => 'integer',
+        'actor_id' => 'integer',
+        'in_reply_to_id' => '?string',
+        'message' => 'string',
+        'message_html' => 'string',
+        'likes_count' => 'integer',
+        'dislikes_count' => 'integer',
+        'replies_count' => 'integer',
+        'created_by' => 'integer',
+        'is_from_post' => 'boolean',
+    ];
+
+    /**
+     * Returns the comment's attached episode
+     */
+    public function getEpisode(): ?Episode
+    {
+        if ($this->episode_id === null) {
+            throw new RuntimeException('Comment must have an episode_id before getting episode.');
+        }
+
+        if (! $this->episode instanceof Episode) {
+            $this->episode = (new EpisodeModel())->getEpisodeById($this->episode_id);
+        }
+
+        return $this->episode;
+    }
+
+    /**
+     * Returns the comment's actor
+     */
+    public function getActor(): Actor
+    {
+        if ($this->actor_id === null) {
+            throw new RuntimeException('Comment must have an actor_id before getting actor.');
+        }
+
+        if ($this->actor === null) {
+            $this->actor = model('ActorModel', false)
+                ->getActorById($this->actor_id);
+        }
+
+        return $this->actor;
+    }
+
+    public function setMessage(string $message): static
+    {
+        helper('activitypub');
+
+        $messageWithoutTags = strip_tags($message);
+
+        $this->attributes['message'] = $messageWithoutTags;
+        $this->attributes['message_html'] = str_replace("\n", '<br />', linkify($messageWithoutTags));
+
+        return $this;
+    }
+}
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index 31ae9da291..7b976a2ec4 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -11,10 +11,11 @@ declare(strict_types=1);
 namespace App\Entities;
 
 use App\Libraries\SimpleRSSElement;
+use App\Models\CommentModel;
 use App\Models\PersonModel;
 use App\Models\PodcastModel;
+use App\Models\PostModel;
 use App\Models\SoundbiteModel;
-use App\Models\StatusModel;
 use CodeIgniter\Entity\Entity;
 use CodeIgniter\Files\File;
 use CodeIgniter\HTTP\Files\UploadedFile;
@@ -65,9 +66,8 @@ use RuntimeException;
  * @property string|null $location_osm
  * @property array|null $custom_rss
  * @property string $custom_rss_string
- * @property int $favourites_total
- * @property int $reblogs_total
- * @property int $statuses_total
+ * @property int $posts_count
+ * @property int $comments_count
  * @property int $created_by
  * @property int $updated_by
  * @property string $publication_status;
@@ -117,12 +117,12 @@ class Episode extends Entity
     protected ?array $soundbites = null;
 
     /**
-     * @var Status[]|null
+     * @var Post[]|null
      */
-    protected ?array $statuses = null;
+    protected ?array $posts = null;
 
     /**
-     * @var Status[]|null
+     * @var Comment[]|null
      */
     protected ?array $comments = null;
 
@@ -168,9 +168,8 @@ class Episode extends Entity
         'location_geo' => '?string',
         'location_osm' => '?string',
         'custom_rss' => '?json-array',
-        'favourites_total' => 'integer',
-        'reblogs_total' => 'integer',
-        'statuses_total' => 'integer',
+        'posts_count' => 'integer',
+        'comments_count' => 'integer',
         'created_by' => 'integer',
         'updated_by' => 'integer',
     ];
@@ -387,23 +386,23 @@ class Episode extends Entity
     }
 
     /**
-     * @return Status[]
+     * @return Post[]
      */
-    public function getStatuses(): array
+    public function getPosts(): array
     {
         if ($this->id === null) {
-            throw new RuntimeException('Episode must be created before getting statuses.');
+            throw new RuntimeException('Episode must be created before getting posts.');
         }
 
-        if ($this->statuses === null) {
-            $this->statuses = (new StatusModel())->getEpisodeStatuses($this->id);
+        if ($this->posts === null) {
+            $this->posts = (new PostModel())->getEpisodePosts($this->id);
         }
 
-        return $this->statuses;
+        return $this->posts;
     }
 
     /**
-     * @return Status[]
+     * @return Comment[]
      */
     public function getComments(): array
     {
@@ -412,7 +411,7 @@ class Episode extends Entity
         }
 
         if ($this->comments === null) {
-            $this->comments = (new StatusModel())->getEpisodeComments($this->id);
+            $this->comments = (new CommentModel())->getEpisodeComments($this->id);
         }
 
         return $this->comments;
@@ -420,7 +419,7 @@ class Episode extends Entity
 
     public function getLink(): string
     {
-        return url_to('episode', $this->getPodcast()->name, $this->attributes['slug']);
+        return url_to('episode', $this->getPodcast()->handle, $this->attributes['slug']);
     }
 
     public function getEmbeddablePlayerUrl(string $theme = null): string
diff --git a/app/Entities/Status.php b/app/Entities/Post.php
similarity index 83%
rename from app/Entities/Status.php
rename to app/Entities/Post.php
index c2e305d633..a76d863336 100644
--- a/app/Entities/Status.php
+++ b/app/Entities/Post.php
@@ -10,7 +10,7 @@ declare(strict_types=1);
 
 namespace App\Entities;
 
-use ActivityPub\Entities\Status as ActivityPubStatus;
+use ActivityPub\Entities\Post as ActivityPubPost;
 use App\Models\EpisodeModel;
 use RuntimeException;
 
@@ -18,7 +18,7 @@ use RuntimeException;
  * @property int|null $episode_id
  * @property Episode|null $episode
  */
-class Status extends ActivityPubStatus
+class Post extends ActivityPubPost
 {
     protected ?Episode $episode = null;
 
@@ -41,12 +41,12 @@ class Status extends ActivityPubStatus
     ];
 
     /**
-     * Returns the status' attached episode
+     * Returns the post's attached episode
      */
     public function getEpisode(): ?Episode
     {
         if ($this->episode_id === null) {
-            throw new RuntimeException('Status must have an episode_id before getting episode.');
+            throw new RuntimeException('Post must have an episode_id before getting episode.');
         }
 
         if (! $this->episode instanceof Episode) {
diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php
index 661e222c20..649114ce6a 100644
--- a/app/Helpers/components_helper.php
+++ b/app/Helpers/components_helper.php
@@ -255,7 +255,7 @@ if (! function_exists('publication_button')) {
     /**
      * Publication button component
      *
-     * Displays the appropriate publication button depending on the publication status.
+     * Displays the appropriate publication button depending on the publication post.
      */
     function publication_button(int $podcastId, int $episodeId, string $publicationStatus): string
     {
diff --git a/app/Helpers/url_helper.php b/app/Helpers/url_helper.php
index 461ba0c120..09bb644b81 100644
--- a/app/Helpers/url_helper.php
+++ b/app/Helpers/url_helper.php
@@ -40,7 +40,7 @@ if (! function_exists('extract_params_from_episode_uri')) {
     function extract_params_from_episode_uri(URI $episodeUri): ?array
     {
         preg_match(
-            '~@(?P<podcastHandle>[a-zA-Z0-9\_]{1,32})\/episodes\/(?P<episodeSlug>[a-zA-Z0-9\-]{1,191})~',
+            '~@(?P<podcastHandle>[a-zA-Z0-9\_]{1,32})\/episodes\/(?P<episodeSlug>[a-zA-Z0-9\-]{1,128})~',
             $episodeUri->getPath(),
             $matches,
         );
diff --git a/app/Language/en/Comment.php b/app/Language/en/Comment.php
new file mode 100644
index 0000000000..7073865a09
--- /dev/null
+++ b/app/Language/en/Comment.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'form' => [
+        'episode_message_placeholder' => 'Write a comment...',
+        'reply_to_placeholder' => 'Reply to @{actorUsername}',
+        'submit' => 'Send!',
+        'submit_reply' => 'Reply',
+    ],
+    'like' => 'Like',
+    'dislike' => 'Dislike',
+    'replies' => '{numberOfReplies, plural,
+        one {# reply}
+        other {# replies}
+    }',
+    'block_actor' => 'Block user @{actorUsername}',
+    'block_domain' => 'Block domain @{actorDomain}',
+    'delete' => 'Delete comment',
+];
diff --git a/app/Language/en/Episode.php b/app/Language/en/Episode.php
index 7749b06a2e..06855b9d71 100644
--- a/app/Language/en/Episode.php
+++ b/app/Language/en/Episode.php
@@ -16,19 +16,12 @@ return [
     'season_episode' => 'Season {seasonNumber} episode {episodeNumber}',
     'season_episode_abbr' => 'S{seasonNumber}E{episodeNumber}',
     'back_to_episodes' => 'Back to episodes of {podcast}',
+    'comments' => 'Comments',
     'activity' => 'Activity',
     'description' => 'Description',
-    'total_favourites' => '{numberOfTotalFavourites, plural,
-        one {# total favourite}
-        other {# total favourites}
-    }',
-    'total_reblogs' => '{numberOfTotalReblogs, plural,
-        one {# total share}
-        other {# total shares}
-    }',
-    'total_statuses' => '{numberOfTotalStatuses, plural,
-        one {# total post}
-        other {# total posts}
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# comment}
+        other {# comments}
     }',
     'all_podcast_episodes' => 'All podcast episodes',
     'back_to_podcast' => 'Go back to podcast',
@@ -116,14 +109,14 @@ return [
         'custom_rss_hint' => 'This will be injected within the ❬item❭ tag.',
         'block' => 'Episode should be hidden from all platforms',
         'block_hint' =>
-            'The episode show or hide status. If you want this episode removed from the Apple directory, toggle this on.',
+            'The episode show or hide post. If you want this episode removed from the Apple directory, toggle this on.',
         'submit_create' => 'Create episode',
         'submit_edit' => 'Save episode',
     ],
     'publish_form' => [
         'back_to_episode_dashboard' => 'Back to episode dashboard',
-        'status' => 'Your announcement post',
-        'status_hint' =>
+        'post' => 'Your announcement post',
+        'post_hint' =>
             "Write a message to announce the publication of your episode. The message will be broadcasted to all your followers in the fediverse and be featured in your podcast's homepage.",
         'publication_date' => 'Publication date',
         'publication_method' => [
diff --git a/app/Language/en/Podcast.php b/app/Language/en/Podcast.php
index f6118e02f2..946b0b1be4 100644
--- a/app/Language/en/Podcast.php
+++ b/app/Language/en/Podcast.php
@@ -223,7 +223,7 @@ return [
         one {<span class="font-semibold">#</span> follower}
         other {<span class="font-semibold">#</span> followers}
     }',
-    'statuses' => '{numberOfStatuses, plural,
+    'posts' => '{numberOfPosts, plural,
         one {<span class="font-semibold">#</span> post}
         other {<span class="font-semibold">#</span> posts}
     }',
diff --git a/app/Language/en/Status.php b/app/Language/en/Post.php
similarity index 95%
rename from app/Language/en/Status.php
rename to app/Language/en/Post.php
index 8f5f3a129b..a60ef30fec 100644
--- a/app/Language/en/Status.php
+++ b/app/Language/en/Post.php
@@ -10,7 +10,7 @@ declare(strict_types=1);
 
 return [
     'title' => "{actorDisplayName}'s post",
-    'back_to_actor_statuses' => 'Back to {actor} posts',
+    'back_to_actor_posts' => 'Back to {actor} posts',
     'actor_shared' => '{actor} shared',
     'reply_to' => 'Reply to @{actorUsername}',
     'form' => [
diff --git a/app/Language/fr/Episode.php b/app/Language/fr/Episode.php
index 678ed65be2..fc3d49364e 100644
--- a/app/Language/fr/Episode.php
+++ b/app/Language/fr/Episode.php
@@ -16,19 +16,12 @@ return [
     'season_episode' => 'Saison {seasonNumber} épisode {episodeNumber}',
     'season_episode_abbr' => 'S{seasonNumber}E{episodeNumber}',
     'back_to_episodes' => 'Retour aux épisodes de {podcast}',
+    'comments' => 'Commentaires',
     'activity' => 'Activité',
     'description' => 'Description',
-    'total_favourites' => '{numberOfTotalFavourites, plural,
-        one {# favori en tout}
-        other {# favoris en tout}
-    }',
-    'total_reblogs' => '{numberOfTotalReblogs, plural,
-        one {# partage en tout}
-        other {# partages en tout}
-    }',
-    'total_statuses' => '{numberOfTotalStatuses, plural,
-        one {# message}
-        other {# messages}
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# commentaire}
+        other {# commentaires}
     }',
     'all_podcast_episodes' => 'Tous les épisodes du podcast',
     'back_to_podcast' => 'Revenir au podcast',
@@ -125,8 +118,8 @@ return [
     ],
     'publish_form' => [
         'back_to_episode_dashboard' => 'Retour au tableau de bord de l’épisode',
-        'status' => 'Votre message de publication',
-        'status_hint' =>
+        'post' => 'Votre message de publication',
+        'post_hint' =>
             'Écrivez un message pour annoncer la publication de votre épisode. Le message sera diffusé à toutes les personnes qui vous suivent dans le fédiverse et mis en évidence sur la page d’accueil de votre podcast.',
         'publication_date' => 'Date de publication',
         'publication_date_clear' => 'Effacer la date de publication',
diff --git a/app/Language/fr/Podcast.php b/app/Language/fr/Podcast.php
index 4b571ac48c..1ef22cd776 100644
--- a/app/Language/fr/Podcast.php
+++ b/app/Language/fr/Podcast.php
@@ -225,7 +225,7 @@ return [
         one {<span class="font-semibold">#</span> abonné·e}
         other {<span class="font-semibold">#</span> abonné·e·s}
     }',
-    'statuses' => '{numberOfStatuses, plural,
+    'posts' => '{numberOfPosts, plural,
         one {<span class="font-semibold">#</span> publication}
         other {<span class="font-semibold">#</span> publications}
     }',
diff --git a/app/Language/fr/Status.php b/app/Language/fr/Post.php
similarity index 94%
rename from app/Language/fr/Status.php
rename to app/Language/fr/Post.php
index c19d0e2963..a12bdd6f25 100644
--- a/app/Language/fr/Status.php
+++ b/app/Language/fr/Post.php
@@ -10,7 +10,7 @@ declare(strict_types=1);
 
 return [
     'title' => 'Publication de {actorDisplayName}',
-    'back_to_actor_statuses' => 'Retour aux publications de {actor}',
+    'back_to_actor_posts' => 'Retour aux publications de {actor}',
     'actor_shared' => '{actor} a partagé',
     'reply_to' => 'Répondre à @{actorUsername}',
     'form' => [
diff --git a/app/Libraries/ActivityPub/Activities/AnnounceActivity.php b/app/Libraries/ActivityPub/Activities/AnnounceActivity.php
index 3eb4ba5097..75988ac635 100644
--- a/app/Libraries/ActivityPub/Activities/AnnounceActivity.php
+++ b/app/Libraries/ActivityPub/Activities/AnnounceActivity.php
@@ -14,19 +14,19 @@ declare(strict_types=1);
 namespace ActivityPub\Activities;
 
 use ActivityPub\Core\Activity;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 
 class AnnounceActivity extends Activity
 {
     protected string $type = 'Announce';
 
-    public function __construct(Status $reblogStatus)
+    public function __construct(Post $reblogPost)
     {
-        $this->actor = $reblogStatus->actor->uri;
-        $this->object = $reblogStatus->reblog_of_status->uri;
+        $this->actor = $reblogPost->actor->uri;
+        $this->object = $reblogPost->reblog_of_post->uri;
 
-        $this->published = $reblogStatus->published_at->format(DATE_W3C);
+        $this->published = $reblogPost->published_at->format(DATE_W3C);
 
-        $this->cc = [$reblogStatus->actor->uri, $reblogStatus->actor->followers_url];
+        $this->cc = [$reblogPost->actor->uri, $reblogPost->actor->followers_url];
     }
 }
diff --git a/app/Libraries/ActivityPub/Config/Routes.php b/app/Libraries/ActivityPub/Config/Routes.php
index a667e7219b..dd5dd0b1a1 100644
--- a/app/Libraries/ActivityPub/Config/Routes.php
+++ b/app/Libraries/ActivityPub/Config/Routes.php
@@ -13,7 +13,7 @@ $routes->addPlaceholder(
     'uuid',
     '[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}',
 );
-$routes->addPlaceholder('statusAction', '\bfavourite|\breblog|\breply');
+$routes->addPlaceholder('postAction', '\bfavourite|\breblog|\breply');
 
 /**
  * ActivityPub routes file
@@ -54,24 +54,24 @@ $routes->group('', [
         ]);
     });
 
-    // Status
-    $routes->post('statuses/new', 'StatusController::attemptCreate/$1', [
-        'as' => 'status-attempt-create',
+    // Post
+    $routes->post('posts/new', 'PostController::attemptCreate/$1', [
+        'as' => 'post-attempt-create',
     ]);
 
-    $routes->get('statuses/(:uuid)', 'StatusController/$1', [
-        'as' => 'status',
+    $routes->get('posts/(:uuid)', 'PostController/$1', [
+        'as' => 'post',
     ]);
 
-    $routes->get('statuses/(:uuid)/replies', 'StatusController/$1', [
-        'as' => 'status-replies',
+    $routes->get('posts/(:uuid)/replies', 'PostController/$1', [
+        'as' => 'post-replies',
     ]);
 
     $routes->post(
-        'statuses/(:uuid)/remote/(:statusAction)',
-        'StatusController::attemptRemoteAction/$1/$2/$3',
+        'posts/(:uuid)/remote/(:postAction)',
+        'PostController::attemptRemoteAction/$1/$2/$3',
         [
-            'as' => 'status-attempt-remote-action',
+            'as' => 'post-attempt-remote-action',
         ],
     );
 
diff --git a/app/Libraries/ActivityPub/Controllers/ActorController.php b/app/Libraries/ActivityPub/Controllers/ActorController.php
index 6bb9167cb9..7a9408975f 100644
--- a/app/Libraries/ActivityPub/Controllers/ActorController.php
+++ b/app/Libraries/ActivityPub/Controllers/ActorController.php
@@ -12,7 +12,7 @@ namespace ActivityPub\Controllers;
 
 use ActivityPub\Config\ActivityPub;
 use ActivityPub\Entities\Actor;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 use ActivityPub\Objects\OrderedCollectionObject;
 use ActivityPub\Objects\OrderedCollectionPage;
 use CodeIgniter\Controller;
@@ -101,30 +101,30 @@ class ActorController extends Controller
                             ->setJSON([]);
                     }
 
-                    $replyToStatus = model('StatusModel')
-                        ->getStatusByUri($payload->object->inReplyTo);
+                    $replyToPost = model('PostModel')
+                        ->getPostByUri($payload->object->inReplyTo);
 
                     $reply = null;
-                    if ($replyToStatus !== null) {
+                    if ($replyToPost !== null) {
                         // TODO: strip content from html to retrieve message
                         // remove all html tags and reconstruct message with mentions?
                         extract_text_from_html($payload->object->content);
-                        $reply = new Status([
+                        $reply = new Post([
                             'uri' => $payload->object->id,
                             'actor_id' => $payloadActor->id,
-                            'in_reply_to_id' => $replyToStatus->id,
+                            'in_reply_to_id' => $replyToPost->id,
                             'message' => $payload->object->content,
                             'published_at' => Time::parse($payload->object->published),
                         ]);
                     }
 
                     if ($reply !== null) {
-                        $statusId = model('StatusModel')
+                        $postId = model('PostModel')
                             ->addReply($reply, true, false);
 
                         model('ActivityModel')
                             ->update($activityId, [
-                                'status_id' => $statusId,
+                                'post_id' => $postId,
                             ]);
                     }
 
@@ -135,12 +135,12 @@ class ActorController extends Controller
                 return $this->response->setStatusCode(501)
                     ->setJSON([]);
             case 'Delete':
-                $statusToDelete = model('StatusModel')
-                    ->getStatusByUri($payload->object->id);
+                $postToDelete = model('PostModel')
+                    ->getPostByUri($payload->object->id);
 
-                if ($statusToDelete !== null) {
-                    model('StatusModel')
-                        ->removeStatus($statusToDelete, false);
+                if ($postToDelete !== null) {
+                    model('PostModel')
+                        ->removePost($postToDelete, false);
                 }
 
                 return $this->response->setStatusCode(200)
@@ -158,35 +158,35 @@ class ActorController extends Controller
                     ->setJSON([]);
 
             case 'Like':
-                // get favourited status
-                $status = model('StatusModel')
-                    ->getStatusByUri($payload->object);
+                // get favourited post
+                $post = model('PostModel')
+                    ->getPostByUri($payload->object);
 
-                if ($status !== null) {
+                if ($post !== null) {
                     // Like side-effect
                     model('FavouriteModel')
-                        ->addFavourite($payloadActor, $status, false);
+                        ->addFavourite($payloadActor, $post, false);
 
                     model('ActivityModel')
                         ->update($activityId, [
-                            'status_id' => $status->id,
+                            'post_id' => $post->id,
                         ]);
                 }
 
                 return $this->response->setStatusCode(200)
                     ->setJSON([]);
             case 'Announce':
-                $status = model('StatusModel')
-                    ->getStatusByUri($payload->object);
+                $post = model('PostModel')
+                    ->getPostByUri($payload->object);
 
-                if ($status !== null) {
+                if ($post !== null) {
                     model('ActivityModel')
                         ->update($activityId, [
-                            'status_id' => $status->id,
+                            'post_id' => $post->id,
                         ]);
 
-                    model('StatusModel')
-                        ->reblog($payloadActor, $status, false);
+                    model('PostModel')
+                        ->reblog($payloadActor, $post, false);
                 }
 
                 return $this->response->setStatusCode(200)
@@ -204,45 +204,45 @@ class ActorController extends Controller
                         return $this->response->setStatusCode(202)
                             ->setJSON([]);
                     case 'Like':
-                        $status = model('StatusModel')
-                            ->getStatusByUri($payload->object->object);
+                        $post = model('PostModel')
+                            ->getPostByUri($payload->object->object);
 
-                        if ($status !== null) {
+                        if ($post !== null) {
                             // revert side-effect by removing favourite from database
                             model('FavouriteModel')
-                                ->removeFavourite($payloadActor, $status, false);
+                                ->removeFavourite($payloadActor, $post, false);
 
                             model('ActivityModel')
                                 ->update($activityId, [
-                                    'status_id' => $status->id,
+                                    'post_id' => $post->id,
                                 ]);
                         }
 
                         return $this->response->setStatusCode(200)
                             ->setJSON([]);
                     case 'Announce':
-                        $status = model('StatusModel')
-                            ->getStatusByUri($payload->object->object);
+                        $post = model('PostModel')
+                            ->getPostByUri($payload->object->object);
 
-                        $reblogStatus = null;
-                        if ($status !== null) {
-                            $reblogStatus = model('StatusModel')
+                        $reblogPost = null;
+                        if ($post !== null) {
+                            $reblogPost = model('PostModel')
                                 ->where([
                                     'actor_id' => $payloadActor->id,
                                     'reblog_of_id' => service('uuid')
-                                        ->fromString($status->id)
+                                        ->fromString($post->id)
                                         ->getBytes(),
                                 ])
                                 ->first();
                         }
 
-                        if ($reblogStatus !== null) {
-                            model('StatusModel')
-                                ->undoReblog($reblogStatus, false);
+                        if ($reblogPost !== null) {
+                            model('PostModel')
+                                ->undoReblog($reblogPost, false);
 
                             model('ActivityModel')
                                 ->update($activityId, [
-                                    'status_id' => $status->id,
+                                    'post_id' => $post->id,
                                 ]);
                         }
 
diff --git a/app/Libraries/ActivityPub/Controllers/StatusController.php b/app/Libraries/ActivityPub/Controllers/PostController.php
similarity index 81%
rename from app/Libraries/ActivityPub/Controllers/StatusController.php
rename to app/Libraries/ActivityPub/Controllers/PostController.php
index 022304f271..73de6f5e77 100644
--- a/app/Libraries/ActivityPub/Controllers/StatusController.php
+++ b/app/Libraries/ActivityPub/Controllers/PostController.php
@@ -11,7 +11,7 @@ declare(strict_types=1);
 namespace ActivityPub\Controllers;
 
 use ActivityPub\Config\ActivityPub;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 use ActivityPub\Objects\OrderedCollectionObject;
 use ActivityPub\Objects\OrderedCollectionPage;
 use CodeIgniter\Controller;
@@ -21,14 +21,14 @@ use CodeIgniter\HTTP\Response;
 use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\I18n\Time;
 
-class StatusController extends Controller
+class PostController extends Controller
 {
     /**
      * @var string[]
      */
     protected $helpers = ['activitypub'];
 
-    protected Status $status;
+    protected Post $post;
 
     protected ActivityPub $config;
 
@@ -39,11 +39,11 @@ class StatusController extends Controller
 
     public function _remap(string $method, string ...$params): mixed
     {
-        if (($status = model('StatusModel')->getStatusById($params[0])) === null) {
+        if (($post = model('PostModel')->getPostById($params[0])) === null) {
             throw PageNotFoundException::forPageNotFound();
         }
 
-        $this->status = $status;
+        $this->post = $post;
 
         unset($params[0]);
 
@@ -56,7 +56,7 @@ class StatusController extends Controller
     public function index(): Response
     {
         $noteObjectClass = $this->config->noteObject;
-        $noteObject = new $noteObjectClass($this->status);
+        $noteObject = new $noteObjectClass($this->post);
 
         return $this->response
             ->setContentType('application/activity+json')
@@ -69,22 +69,22 @@ class StatusController extends Controller
     public function replies(): Response
     {
         /**
-         * get status replies
+         * get post replies
          */
-        $statusReplies = model('StatusModel')
-            ->where('in_reply_to_id', service('uuid') ->fromString($this->status->id) ->getBytes())
+        $postReplies = model('PostModel')
+            ->where('in_reply_to_id', service('uuid') ->fromString($this->post->id) ->getBytes())
             ->where('`published_at` <= NOW()', null, false)
             ->orderBy('published_at', 'ASC');
 
         $pageNumber = (int) $this->request->getGet('page');
 
         if ($pageNumber < 1) {
-            $statusReplies->paginate(12);
-            $pager = $statusReplies->pager;
+            $postReplies->paginate(12);
+            $pager = $postReplies->pager;
             $collection = new OrderedCollectionObject(null, $pager);
         } else {
-            $paginatedReplies = $statusReplies->paginate(12, 'default', $pageNumber);
-            $pager = $statusReplies->pager;
+            $paginatedReplies = $postReplies->paginate(12, 'default', $pageNumber);
+            $pager = $postReplies->pager;
 
             $orderedItems = [];
             $noteObjectClass = $this->config->noteObject;
@@ -118,21 +118,21 @@ class StatusController extends Controller
                 ->with('errors', $this->validator->getErrors());
         }
 
-        $newStatus = new Status([
+        $newPost = new Post([
             'actor_id' => $this->request->getPost('actor_id'),
             'message' => $this->request->getPost('message'),
             'published_at' => Time::now(),
         ]);
 
-        if (! model('StatusModel')->addStatus($newStatus)) {
+        if (! model('PostModel')->addPost($newPost)) {
             return redirect()
                 ->back()
                 ->withInput()
                 // TODO: translate
-                ->with('error', "Couldn't create Status");
+                ->with('error', "Couldn't create Post");
         }
 
-        // Status without preview card has been successfully created
+        // Post without preview card has been successfully created
         return redirect()->back();
     }
 
@@ -153,7 +153,7 @@ class StatusController extends Controller
             ->getActorById($this->request->getPost('actor_id'));
 
         model('FavouriteModel')
-            ->toggleFavourite($actor, $this->status->id);
+            ->toggleFavourite($actor, $this->post->id);
 
         return redirect()->back();
     }
@@ -174,8 +174,8 @@ class StatusController extends Controller
         $actor = model('ActorModel')
             ->getActorById($this->request->getPost('actor_id'));
 
-        model('StatusModel')
-            ->toggleReblog($actor, $this->status);
+        model('PostModel')
+            ->toggleReblog($actor, $this->post);
 
         return redirect()->back();
     }
@@ -194,14 +194,14 @@ class StatusController extends Controller
                 ->with('errors', $this->validator->getErrors());
         }
 
-        $newReplyStatus = new Status([
+        $newReplyPost = new Post([
             'actor_id' => $this->request->getPost('actor_id'),
-            'in_reply_to_id' => $this->status->id,
+            'in_reply_to_id' => $this->post->id,
             'message' => $this->request->getPost('message'),
             'published_at' => Time::now(),
         ]);
 
-        if (! model('StatusModel')->addReply($newReplyStatus)) {
+        if (! model('PostModel')->addReply($newReplyPost)) {
             return redirect()
                 ->back()
                 ->withInput()
@@ -209,7 +209,7 @@ class StatusController extends Controller
                 ->with('error', "Couldn't create Reply");
         }
 
-        // Reply status without preview card has been successfully created
+        // Reply post without preview card has been successfully created
         return redirect()->back();
     }
 
@@ -249,33 +249,33 @@ class StatusController extends Controller
         );
 
         if (! $ostatusKey) {
-            // TODO: error, couldn't remote favourite/share/reply to status
-            // The instance doesn't allow its users remote actions on statuses
+            // TODO: error, couldn't remote favourite/share/reply to post
+            // The instance doesn't allow its users remote actions on posts
             return $this->response->setJSON([]);
         }
 
         return redirect()->to(
-            str_replace('{uri}', urlencode($this->status->uri), $data->links[$ostatusKey]->template),
+            str_replace('{uri}', urlencode($this->post->uri), $data->links[$ostatusKey]->template),
         );
     }
 
     public function attemptBlockActor(): RedirectResponse
     {
-        model('ActorModel')->blockActor($this->status->actor->id);
+        model('ActorModel')->blockActor($this->post->actor->id);
 
         return redirect()->back();
     }
 
     public function attemptBlockDomain(): RedirectResponse
     {
-        model('BlockedDomainModel')->blockDomain($this->status->actor->domain);
+        model('BlockedDomainModel')->blockDomain($this->post->actor->domain);
 
         return redirect()->back();
     }
 
     public function attemptDelete(): RedirectResponse
     {
-        model('StatusModel', false)->removeStatus($this->status);
+        model('PostModel', false)->removePost($this->post);
 
         return redirect()->back();
     }
diff --git a/app/Libraries/ActivityPub/Controllers/SchedulerController.php b/app/Libraries/ActivityPub/Controllers/SchedulerController.php
index 057360a3f8..4b7928e234 100644
--- a/app/Libraries/ActivityPub/Controllers/SchedulerController.php
+++ b/app/Libraries/ActivityPub/Controllers/SchedulerController.php
@@ -33,7 +33,7 @@ class SchedulerController extends Controller
                 json_encode($scheduledActivity->payload, JSON_THROW_ON_ERROR),
             );
 
-            // set activity status to delivered
+            // set activity post to delivered
             model('ActivityModel')
                 ->update($scheduledActivity->id, [
                     'task_status' => 'delivered',
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-010000_add_actors.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-010000_add_actors.php
index 4fcc297372..d247fbc70d 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-010000_add_actors.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-010000_add_actors.php
@@ -34,7 +34,7 @@ class AddActors extends Migration
             ],
             'domain' => [
                 'type' => 'VARCHAR',
-                'constraint' => 191,
+                'constraint' => 255,
             ],
             'private_key' => [
                 'type' => 'TEXT',
@@ -93,7 +93,7 @@ class AddActors extends Migration
                 'unsigned' => true,
                 'default' => 0,
             ],
-            'statuses_count' => [
+            'posts_count' => [
                 'type' => 'INT',
                 'unsigned' => true,
                 'default' => 0,
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_statuses.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_posts.php
similarity index 85%
rename from app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_statuses.php
rename to app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_posts.php
index 68fe53fc5b..05cc28b419 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_statuses.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-020000_add_posts.php
@@ -3,7 +3,7 @@
 declare(strict_types=1);
 
 /**
- * Class AddStatuses Creates activitypub_statuses table in database
+ * Class AddPosts Creates activitypub_posts table in database
  *
  * @copyright  2021 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -14,7 +14,7 @@ namespace ActivityPub\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
 
-class AddStatuses extends Migration
+class AddPosts extends Migration
 {
     public function up(): void
     {
@@ -25,7 +25,7 @@ class AddStatuses extends Migration
             ],
             'uri' => [
                 'type' => 'VARCHAR',
-                'constraint' => 191,
+                'constraint' => 255,
             ],
             'actor_id' => [
                 'type' => 'INT',
@@ -76,16 +76,16 @@ class AddStatuses extends Migration
         ]);
         $this->forge->addPrimaryKey('id');
         $this->forge->addUniqueKey('uri');
-        // FIXME: an actor must reblog a status only once
+        // FIXME: an actor must reblog a post only once
         // $this->forge->addUniqueKey(['actor_id', 'reblog_of_id']);
         $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
-        $this->forge->addForeignKey('in_reply_to_id', 'activitypub_statuses', 'id', '', 'CASCADE');
-        $this->forge->addForeignKey('reblog_of_id', 'activitypub_statuses', 'id', '', 'CASCADE');
-        $this->forge->createTable('activitypub_statuses');
+        $this->forge->addForeignKey('in_reply_to_id', 'activitypub_posts', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('reblog_of_id', 'activitypub_posts', 'id', '', 'CASCADE');
+        $this->forge->createTable('activitypub_posts');
     }
 
     public function down(): void
     {
-        $this->forge->dropTable('activitypub_statuses');
+        $this->forge->dropTable('activitypub_posts');
     }
 }
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_activities.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_activities.php
index 443a3ea9e6..1b9e99b597 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_activities.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_activities.php
@@ -32,7 +32,7 @@ class AddActivities extends Migration
                 'unsigned' => true,
                 'null' => true,
             ],
-            'status_id' => [
+            'post_id' => [
                 'type' => 'BINARY',
                 'constraint' => 16,
                 'null' => true,
@@ -62,7 +62,7 @@ class AddActivities extends Migration
         $this->forge->addPrimaryKey('id');
         $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
         $this->forge->addForeignKey('target_actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
-        $this->forge->addForeignKey('status_id', 'activitypub_statuses', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('post_id', 'activitypub_posts', 'id', '', 'CASCADE');
         $this->forge->createTable('activitypub_activities');
     }
 
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_favourites.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_favourites.php
index 049284bb8d..cfdc98ab01 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_favourites.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-100000_add_favourites.php
@@ -23,15 +23,15 @@ class AddFavourites extends Migration
                 'type' => 'INT',
                 'unsigned' => true,
             ],
-            'status_id' => [
+            'post_id' => [
                 'type' => 'BINARY',
                 'constraint' => 16,
             ],
         ]);
         $this->forge->addField('`created_at` timestamp NOT NULL DEFAULT current_timestamp()');
-        $this->forge->addPrimaryKey(['actor_id', 'status_id']);
+        $this->forge->addPrimaryKey(['actor_id', 'post_id']);
         $this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
-        $this->forge->addForeignKey('status_id', 'activitypub_statuses', 'id', '', 'CASCADE');
+        $this->forge->addForeignKey('post_id', 'activitypub_posts', 'id', '', 'CASCADE');
         $this->forge->createTable('activitypub_favourites');
     }
 
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_statuses_preview_cards.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_posts_preview_cards.php
similarity index 59%
rename from app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_statuses_preview_cards.php
rename to app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_posts_preview_cards.php
index fe35855fe9..9b677174ba 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_statuses_preview_cards.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-110000_add_posts_preview_cards.php
@@ -3,7 +3,7 @@
 declare(strict_types=1);
 
 /**
- * Class AddStatusesPreviewCards Creates activitypub_statuses_preview_cards table in database
+ * Class AddPostsPreviewCards Creates activitypub_posts_preview_cards table in database
  *
  * @copyright  2021 Podlibre
  * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
@@ -14,12 +14,12 @@ namespace ActivityPub\Database\Migrations;
 
 use CodeIgniter\Database\Migration;
 
-class AddStatusesPreviewCards extends Migration
+class AddPostsPreviewCards extends Migration
 {
     public function up(): void
     {
         $this->forge->addField([
-            'status_id' => [
+            'post_id' => [
                 'type' => 'BINARY',
                 'constraint' => 16,
             ],
@@ -29,14 +29,14 @@ class AddStatusesPreviewCards extends Migration
             ],
         ]);
 
-        $this->forge->addPrimaryKey(['status_id', 'preview_card_id']);
-        $this->forge->addForeignKey('status_id', 'activitypub_statuses', 'id', '', 'CASCADE');
+        $this->forge->addPrimaryKey(['post_id', 'preview_card_id']);
+        $this->forge->addForeignKey('post_id', 'activitypub_posts', 'id', '', 'CASCADE');
         $this->forge->addForeignKey('preview_card_id', 'activitypub_preview_cards', 'id', '', 'CASCADE');
-        $this->forge->createTable('activitypub_statuses_preview_cards');
+        $this->forge->createTable('activitypub_posts_preview_cards');
     }
 
     public function down(): void
     {
-        $this->forge->dropTable('activitypub_statuses_preview_cards');
+        $this->forge->dropTable('activitypub_posts_preview_cards');
     }
 }
diff --git a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-120000_add_blocked_domains.php b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-120000_add_blocked_domains.php
index b7b0b49a20..dbbea7228c 100644
--- a/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-120000_add_blocked_domains.php
+++ b/app/Libraries/ActivityPub/Database/Migrations/2018-01-01-120000_add_blocked_domains.php
@@ -21,7 +21,7 @@ class AddBlockedDomains extends Migration
         $this->forge->addField([
             'name' => [
                 'type' => 'VARCHAR',
-                'constraint' => 191,
+                'constraint' => 255,
             ],
             'created_at' => [
                 'type' => 'DATETIME',
diff --git a/app/Libraries/ActivityPub/Entities/Activity.php b/app/Libraries/ActivityPub/Entities/Activity.php
index 4a67bdb0ce..e60995c939 100644
--- a/app/Libraries/ActivityPub/Entities/Activity.php
+++ b/app/Libraries/ActivityPub/Entities/Activity.php
@@ -19,8 +19,8 @@ use RuntimeException;
  * @property Actor $actor
  * @property int|null $target_actor_id
  * @property Actor $target_actor
- * @property string|null $status_id
- * @property Status $status
+ * @property string|null $post_id
+ * @property Post $post
  * @property string $type
  * @property object $payload
  * @property string|null $task_status
@@ -33,12 +33,12 @@ class Activity extends UuidEntity
 
     protected ?Actor $target_actor = null;
 
-    protected ?Status $status = null;
+    protected ?Post $post = null;
 
     /**
      * @var string[]
      */
-    protected $uuids = ['id', 'status_id'];
+    protected $uuids = ['id', 'post_id'];
 
     /**
      * @var string[]
@@ -52,7 +52,7 @@ class Activity extends UuidEntity
         'id' => 'string',
         'actor_id' => 'integer',
         'target_actor_id' => '?integer',
-        'status_id' => '?string',
+        'post_id' => '?string',
         'type' => 'string',
         'payload' => 'json',
         'task_status' => '?string',
@@ -86,17 +86,17 @@ class Activity extends UuidEntity
         return $this->target_actor;
     }
 
-    public function getStatus(): Status
+    public function getPost(): Post
     {
-        if ($this->status_id === null) {
-            throw new RuntimeException('Activity must have a status_id before getting status.');
+        if ($this->post_id === null) {
+            throw new RuntimeException('Activity must have a post_id before getting post.');
         }
 
-        if ($this->status === null) {
-            $this->status = model('StatusModel', false)
-                ->getStatusById($this->status_id);
+        if ($this->post === null) {
+            $this->post = model('PostModel', false)
+                ->getPostById($this->post_id);
         }
 
-        return $this->status;
+        return $this->post;
     }
 }
diff --git a/app/Libraries/ActivityPub/Entities/Actor.php b/app/Libraries/ActivityPub/Entities/Actor.php
index 25845f0080..bf07cf53de 100644
--- a/app/Libraries/ActivityPub/Entities/Actor.php
+++ b/app/Libraries/ActivityPub/Entities/Actor.php
@@ -31,7 +31,7 @@ use RuntimeException;
  * @property string|null $outbox_url
  * @property string|null $followers_url
  * @property int $followers_count
- * @property int $statuses_count
+ * @property int $posts_count
  * @property bool $is_blocked
  *
  * @property Actor[] $followers
@@ -68,7 +68,7 @@ class Actor extends Entity
         'outbox_url' => '?string',
         'followers_url' => '?string',
         'followers_count' => 'integer',
-        'statuses_count' => 'integer',
+        'posts_count' => 'integer',
         'is_blocked' => 'boolean',
     ];
 
diff --git a/app/Libraries/ActivityPub/Entities/Favourite.php b/app/Libraries/ActivityPub/Entities/Favourite.php
index 04014bb63f..b3d4028a7d 100644
--- a/app/Libraries/ActivityPub/Entities/Favourite.php
+++ b/app/Libraries/ActivityPub/Entities/Favourite.php
@@ -14,20 +14,20 @@ use Michalsn\Uuid\UuidEntity;
 
 /**
  * @property int $actor_id
- * @property string $status_id
+ * @property string $post_id
  */
 class Favourite extends UuidEntity
 {
     /**
      * @var string[]
      */
-    protected $uuids = ['status_id'];
+    protected $uuids = ['post_id'];
 
     /**
      * @var array<string, string>
      */
     protected $casts = [
         'actor_id' => 'integer',
-        'status_id' => 'string',
+        'post_id' => 'string',
     ];
 }
diff --git a/app/Libraries/ActivityPub/Entities/Status.php b/app/Libraries/ActivityPub/Entities/Post.php
similarity index 66%
rename from app/Libraries/ActivityPub/Entities/Status.php
rename to app/Libraries/ActivityPub/Entities/Post.php
index 94cfa0c7c5..7f33f0a987 100644
--- a/app/Libraries/ActivityPub/Entities/Status.php
+++ b/app/Libraries/ActivityPub/Entities/Post.php
@@ -20,9 +20,9 @@ use RuntimeException;
  * @property int $actor_id
  * @property Actor $actor
  * @property string|null $in_reply_to_id
- * @property Status|null $reply_to_status
+ * @property Post|null $reply_to_post
  * @property string|null $reblog_of_id
- * @property Status|null $reblog_of_status
+ * @property Post|null $reblog_of_post
  * @property string $message
  * @property string $message_html
  * @property int $favourites_count
@@ -35,30 +35,30 @@ use RuntimeException;
  * @property PreviewCard|null $preview_card
  *
  * @property bool $has_replies
- * @property Status[] $replies
- * @property Status[] $reblogs
+ * @property Post[] $replies
+ * @property Post[] $reblogs
  */
-class Status extends UuidEntity
+class Post extends UuidEntity
 {
     protected ?Actor $actor = null;
 
-    protected ?Status $reply_to_status = null;
+    protected ?Post $reply_to_post = null;
 
-    protected ?Status $reblog_of_status = null;
+    protected ?Post $reblog_of_post = null;
 
     protected ?PreviewCard $preview_card = null;
 
     protected bool $has_preview_card = false;
 
     /**
-     * @var Status[]|null
+     * @var Post[]|null
      */
     protected ?array $replies = null;
 
     protected bool $has_replies = false;
 
     /**
-     * @var Status[]|null
+     * @var Post[]|null
      */
     protected ?array $reblogs = null;
 
@@ -89,12 +89,12 @@ class Status extends UuidEntity
     ];
 
     /**
-     * Returns the status's actor
+     * Returns the post's actor
      */
     public function getActor(): Actor
     {
         if ($this->actor_id === null) {
-            throw new RuntimeException('Status must have an actor_id before getting actor.');
+            throw new RuntimeException('Post must have an actor_id before getting actor.');
         }
 
         if ($this->actor === null) {
@@ -108,12 +108,12 @@ class Status extends UuidEntity
     public function getPreviewCard(): ?PreviewCard
     {
         if ($this->id === null) {
-            throw new RuntimeException('Status must be created before getting preview_card.');
+            throw new RuntimeException('Post must be created before getting preview_card.');
         }
 
         if ($this->preview_card === null) {
             $this->preview_card = model('PreviewCardModel', false)
-                ->getStatusPreviewCard($this->id);
+                ->getPostPreviewCard($this->id);
         }
 
         return $this->preview_card;
@@ -125,17 +125,17 @@ class Status extends UuidEntity
     }
 
     /**
-     * @return Status[]
+     * @return Post[]
      */
     public function getReplies(): array
     {
         if ($this->id === null) {
-            throw new RuntimeException('Status must be created before getting replies.');
+            throw new RuntimeException('Post must be created before getting replies.');
         }
 
         if ($this->replies === null) {
-            $this->replies = (array) model('StatusModel', false)
-                ->getStatusReplies($this->id);
+            $this->replies = (array) model('PostModel', false)
+                ->getPostReplies($this->id);
         }
 
         return $this->replies;
@@ -146,49 +146,49 @@ class Status extends UuidEntity
         return $this->getReplies() !== null;
     }
 
-    public function getReplyToStatus(): ?self
+    public function getReplyToPost(): ?self
     {
         if ($this->in_reply_to_id === null) {
-            throw new RuntimeException('Status is not a reply.');
+            throw new RuntimeException('Post is not a reply.');
         }
 
-        if ($this->reply_to_status === null) {
-            $this->reply_to_status = model('StatusModel', false)
-                ->getStatusById($this->in_reply_to_id);
+        if ($this->reply_to_post === null) {
+            $this->reply_to_post = model('PostModel', false)
+                ->getPostById($this->in_reply_to_id);
         }
 
-        return $this->reply_to_status;
+        return $this->reply_to_post;
     }
 
     /**
-     * @return Status[]
+     * @return Post[]
      */
     public function getReblogs(): array
     {
         if ($this->id === null) {
-            throw new RuntimeException('Status must be created before getting reblogs.');
+            throw new RuntimeException('Post must be created before getting reblogs.');
         }
 
         if ($this->reblogs === null) {
-            $this->reblogs = (array) model('StatusModel', false)
-                ->getStatusReblogs($this->id);
+            $this->reblogs = (array) model('PostModel', false)
+                ->getPostReblogs($this->id);
         }
 
         return $this->reblogs;
     }
 
-    public function getReblogOfStatus(): ?self
+    public function getReblogOfPost(): ?self
     {
         if ($this->reblog_of_id === null) {
-            throw new RuntimeException('Status is not a reblog.');
+            throw new RuntimeException('Post is not a reblog.');
         }
 
-        if ($this->reblog_of_status === null) {
-            $this->reblog_of_status = model('StatusModel', false)
-                ->getStatusById($this->reblog_of_id);
+        if ($this->reblog_of_post === null) {
+            $this->reblog_of_post = model('PostModel', false)
+                ->getPostById($this->reblog_of_id);
         }
 
-        return $this->reblog_of_status;
+        return $this->reblog_of_post;
     }
 
     public function setMessage(string $message): static
diff --git a/app/Libraries/ActivityPub/Entities/PreviewCard.php b/app/Libraries/ActivityPub/Entities/PreviewCard.php
index 630ccde178..8303dabacb 100644
--- a/app/Libraries/ActivityPub/Entities/PreviewCard.php
+++ b/app/Libraries/ActivityPub/Entities/PreviewCard.php
@@ -14,7 +14,7 @@ use CodeIgniter\Entity\Entity;
 
 /**
  * @property int $id
- * @property string $status_id
+ * @property string $post_id
  * @property string $url
  * @property string $title
  * @property string $description
@@ -33,7 +33,7 @@ class PreviewCard extends Entity
      */
     protected $casts = [
         'id' => 'integer',
-        'status_id' => 'string',
+        'post_id' => 'string',
         'url' => 'string',
         'title' => 'string',
         'description' => 'string',
diff --git a/app/Libraries/ActivityPub/Models/ActivityModel.php b/app/Libraries/ActivityPub/Models/ActivityModel.php
index 9b8af37ce0..708d1dc270 100644
--- a/app/Libraries/ActivityPub/Models/ActivityModel.php
+++ b/app/Libraries/ActivityPub/Models/ActivityModel.php
@@ -31,7 +31,7 @@ class ActivityModel extends UuidModel
     /**
      * @var string[]
      */
-    protected $uuidFields = ['id', 'status_id'];
+    protected $uuidFields = ['id', 'post_id'];
 
     /**
      * @var string[]
@@ -40,7 +40,7 @@ class ActivityModel extends UuidModel
         'id',
         'actor_id',
         'target_actor_id',
-        'status_id',
+        'post_id',
         'type',
         'payload',
         'task_status',
@@ -88,7 +88,7 @@ class ActivityModel extends UuidModel
         string $type,
         int $actorId,
         ?int $targetActorId,
-        ?string $statusId,
+        ?string $postId,
         string $payload,
         DateTimeInterface $scheduledAt = null,
         ?string $taskStatus = null
@@ -97,7 +97,7 @@ class ActivityModel extends UuidModel
             [
                 'actor_id' => $actorId,
                 'target_actor_id' => $targetActorId,
-                'status_id' => $statusId,
+                'post_id' => $postId,
                 'type' => $type,
                 'payload' => $payload,
                 'scheduled_at' => $scheduledAt,
diff --git a/app/Libraries/ActivityPub/Models/ActorModel.php b/app/Libraries/ActivityPub/Models/ActorModel.php
index 8fe539a153..48e7ff26c5 100644
--- a/app/Libraries/ActivityPub/Models/ActorModel.php
+++ b/app/Libraries/ActivityPub/Models/ActorModel.php
@@ -41,7 +41,7 @@ class ActorModel extends Model
         'outbox_url',
         'followers_url',
         'followers_count',
-        'statuses_count',
+        'posts_count',
         'is_blocked',
     ];
 
diff --git a/app/Libraries/ActivityPub/Models/FavouriteModel.php b/app/Libraries/ActivityPub/Models/FavouriteModel.php
index 5ea58981e9..3e22785bce 100644
--- a/app/Libraries/ActivityPub/Models/FavouriteModel.php
+++ b/app/Libraries/ActivityPub/Models/FavouriteModel.php
@@ -14,7 +14,7 @@ use ActivityPub\Activities\LikeActivity;
 use ActivityPub\Activities\UndoActivity;
 use ActivityPub\Entities\Actor;
 use ActivityPub\Entities\Favourite;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 use CodeIgniter\Events\Events;
 use Michalsn\Uuid\UuidModel;
 
@@ -28,12 +28,12 @@ class FavouriteModel extends UuidModel
     /**
      * @var string[]
      */
-    protected $uuidFields = ['status_id'];
+    protected $uuidFields = ['post_id'];
 
     /**
      * @var string[]
      */
-    protected $allowedFields = ['actor_id', 'status_id'];
+    protected $allowedFields = ['actor_id', 'post_id'];
 
     /**
      * @var string
@@ -47,32 +47,32 @@ class FavouriteModel extends UuidModel
 
     protected $updatedField;
 
-    public function addFavourite(Actor $actor, Status $status, bool $registerActivity = true): void
+    public function addFavourite(Actor $actor, Post $post, bool $registerActivity = true): void
     {
         $this->db->transStart();
 
         $this->insert([
             'actor_id' => $actor->id,
-            'status_id' => $status->id,
+            'post_id' => $post->id,
         ]);
 
-        model('StatusModel')
-            ->where('id', service('uuid') ->fromString($status->id) ->getBytes())
+        model('PostModel')
+            ->where('id', service('uuid') ->fromString($post->id) ->getBytes())
             ->increment('favourites_count');
 
         if ($registerActivity) {
             $likeActivity = new LikeActivity();
             $likeActivity->set('actor', $actor->uri)
-                ->set('object', $status->uri);
+                ->set('object', $post->uri);
 
             $activityId = model('ActivityModel')
                 ->newActivity(
                     'Like',
                     $actor->id,
                     null,
-                    $status->id,
+                    $post->id,
                     $likeActivity->toJSON(),
-                    $status->published_at,
+                    $post->published_at,
                     'queued',
                 );
 
@@ -84,28 +84,28 @@ class FavouriteModel extends UuidModel
                 ]);
         }
 
-        Events::trigger('on_status_favourite', $actor, $status);
+        Events::trigger('on_post_favourite', $actor, $post);
 
-        model('StatusModel')
-            ->clearCache($status);
+        model('PostModel')
+            ->clearCache($post);
 
         $this->db->transComplete();
     }
 
-    public function removeFavourite(Actor $actor, Status $status, bool $registerActivity = true): void
+    public function removeFavourite(Actor $actor, Post $post, bool $registerActivity = true): void
     {
         $this->db->transStart();
 
-        model('StatusModel')
-            ->where('id', service('uuid') ->fromString($status->id) ->getBytes())
+        model('PostModel')
+            ->where('id', service('uuid') ->fromString($post->id) ->getBytes())
             ->decrement('favourites_count');
 
         $this->db
             ->table('activitypub_favourites')
             ->where([
                 'actor_id' => $actor->id,
-                'status_id' => service('uuid')
-                    ->fromString($status->id)
+                'post_id' => service('uuid')
+                    ->fromString($post->id)
                     ->getBytes(),
             ])
             ->delete();
@@ -117,8 +117,8 @@ class FavouriteModel extends UuidModel
                 ->where([
                     'type' => 'Like',
                     'actor_id' => $actor->id,
-                    'status_id' => service('uuid')
-                        ->fromString($status->id)
+                    'post_id' => service('uuid')
+                        ->fromString($post->id)
                         ->getBytes(),
                 ])
                 ->first();
@@ -127,7 +127,7 @@ class FavouriteModel extends UuidModel
             $likeActivity
                 ->set('id', url_to('activity', $actor->username, $activity->id))
                 ->set('actor', $actor->uri)
-                ->set('object', $status->uri);
+                ->set('object', $post->uri);
 
             $undoActivity
                 ->set('actor', $actor->uri)
@@ -138,9 +138,9 @@ class FavouriteModel extends UuidModel
                     'Undo',
                     $actor->id,
                     null,
-                    $status->id,
+                    $post->id,
                     $undoActivity->toJSON(),
-                    $status->published_at,
+                    $post->published_at,
                     'queued',
                 );
 
@@ -152,10 +152,10 @@ class FavouriteModel extends UuidModel
                 ]);
         }
 
-        Events::trigger('on_status_undo_favourite', $actor, $status);
+        Events::trigger('on_post_undo_favourite', $actor, $post);
 
-        model('StatusModel')
-            ->clearCache($status);
+        model('PostModel')
+            ->clearCache($post);
 
         $this->db->transComplete();
     }
@@ -163,19 +163,19 @@ class FavouriteModel extends UuidModel
     /**
      * Adds or removes favourite from database and increments count
      */
-    public function toggleFavourite(Actor $actor, Status $status): void
+    public function toggleFavourite(Actor $actor, Post $post): void
     {
         if (
             $this->where([
                 'actor_id' => $actor->id,
-                'status_id' => service('uuid')
-                    ->fromString($status->id)
+                'post_id' => service('uuid')
+                    ->fromString($post->id)
                     ->getBytes(),
             ])->first()
         ) {
-            $this->removeFavourite($actor, $status);
+            $this->removeFavourite($actor, $post);
         } else {
-            $this->addFavourite($actor, $status);
+            $this->addFavourite($actor, $post);
         }
     }
 }
diff --git a/app/Libraries/ActivityPub/Models/StatusModel.php b/app/Libraries/ActivityPub/Models/PostModel.php
similarity index 53%
rename from app/Libraries/ActivityPub/Models/StatusModel.php
rename to app/Libraries/ActivityPub/Models/PostModel.php
index 3fc6b2dcd2..f7dc644a6f 100644
--- a/app/Libraries/ActivityPub/Models/StatusModel.php
+++ b/app/Libraries/ActivityPub/Models/PostModel.php
@@ -15,7 +15,7 @@ use ActivityPub\Activities\CreateActivity;
 use ActivityPub\Activities\DeleteActivity;
 use ActivityPub\Activities\UndoActivity;
 use ActivityPub\Entities\Actor;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 use ActivityPub\Objects\TombstoneObject;
 use CodeIgniter\Database\BaseResult;
 use CodeIgniter\Database\Query;
@@ -25,12 +25,12 @@ use CodeIgniter\I18n\Time;
 use Exception;
 use Michalsn\Uuid\UuidModel;
 
-class StatusModel extends UuidModel
+class PostModel extends UuidModel
 {
     /**
      * @var string
      */
-    protected $table = 'activitypub_statuses';
+    protected $table = 'activitypub_posts';
 
     /**
      * @var string
@@ -62,7 +62,7 @@ class StatusModel extends UuidModel
     /**
      * @var string
      */
-    protected $returnType = Status::class;
+    protected $returnType = Post::class;
 
     /**
      * @var bool
@@ -87,14 +87,14 @@ class StatusModel extends UuidModel
     /**
      * @var string[]
      */
-    protected $beforeInsert = ['setStatusId'];
+    protected $beforeInsert = ['setPostId'];
 
-    public function getStatusById(string $statusId): ?Status
+    public function getPostById(string $postId): ?Post
     {
         $cacheName = config('ActivityPub')
-            ->cachePrefix . "status#{$statusId}";
+            ->cachePrefix . "post#{$postId}";
         if (! ($found = cache($cacheName))) {
-            $found = $this->find($statusId);
+            $found = $this->find($postId);
 
             cache()
                 ->save($cacheName, $found, DECADE);
@@ -103,14 +103,14 @@ class StatusModel extends UuidModel
         return $found;
     }
 
-    public function getStatusByUri(string $statusUri): ?Status
+    public function getPostByUri(string $postUri): ?Post
     {
-        $hashedStatusUri = md5($statusUri);
+        $hashedPostUri = md5($postUri);
         $cacheName =
             config('ActivityPub')
-                ->cachePrefix . "status-{$hashedStatusUri}";
+                ->cachePrefix . "post-{$hashedPostUri}";
         if (! ($found = cache($cacheName))) {
-            $found = $this->where('uri', $statusUri)
+            $found = $this->where('uri', $postUri)
                 ->first();
 
             cache()
@@ -121,16 +121,16 @@ class StatusModel extends UuidModel
     }
 
     /**
-     * Retrieves all published statuses for a given actor ordered by publication date
+     * Retrieves all published posts for a given actor ordered by publication date
      *
-     * @return Status[]
+     * @return Post[]
      */
-    public function getActorPublishedStatuses(int $actorId): array
+    public function getActorPublishedPosts(int $actorId): array
     {
         $cacheName =
             config('ActivityPub')
                 ->cachePrefix .
-            "actor#{$actorId}_published_statuses";
+            "actor#{$actorId}_published_posts";
         if (! ($found = cache($cacheName))) {
             $found = $this->where([
                 'actor_id' => $actorId,
@@ -140,20 +140,20 @@ class StatusModel extends UuidModel
                 ->orderBy('published_at', 'DESC')
                 ->findAll();
 
-            $secondsToNextUnpublishedStatus = $this->getSecondsToNextUnpublishedStatuses($actorId);
+            $secondsToNextUnpublishedPost = $this->getSecondsToNextUnpublishedPosts($actorId);
 
             cache()
-                ->save($cacheName, $found, $secondsToNextUnpublishedStatus ? $secondsToNextUnpublishedStatus : DECADE);
+                ->save($cacheName, $found, $secondsToNextUnpublishedPost ? $secondsToNextUnpublishedPost : DECADE);
         }
 
         return $found;
     }
 
     /**
-     * Returns the timestamp difference in seconds between the next status to publish and the current timestamp. Returns
-     * false if there's no status to publish
+     * Returns the timestamp difference in seconds between the next post to publish and the current timestamp. Returns
+     * false if there's no post to publish
      */
-    public function getSecondsToNextUnpublishedStatuses(int $actorId): int | false
+    public function getSecondsToNextUnpublishedPosts(int $actorId): int | false
     {
         $result = $this->select('TIMESTAMPDIFF(SECOND, NOW(), `published_at`) as timestamp_diff')
             ->where([
@@ -170,26 +170,26 @@ class StatusModel extends UuidModel
     }
 
     /**
-     * Retrieves all published replies for a given status. By default, it does not get replies from blocked actors.
+     * Retrieves all published replies for a given post. By default, it does not get replies from blocked actors.
      *
-     * @return Status[]
+     * @return Post[]
      */
-    public function getStatusReplies(string $statusId, bool $withBlocked = false): array
+    public function getPostReplies(string $postId, bool $withBlocked = false): array
     {
         $cacheName =
             config('ActivityPub')
                 ->cachePrefix .
-            "status#{$statusId}_replies" .
+            "post#{$postId}_replies" .
             ($withBlocked ? '_withBlocked' : '');
 
         if (! ($found = cache($cacheName))) {
             if (! $withBlocked) {
-                $this->select('activitypub_statuses.*')
-                    ->join('activitypub_actors', 'activitypub_actors.id = activitypub_statuses.actor_id', 'inner')
+                $this->select('activitypub_posts.*')
+                    ->join('activitypub_actors', 'activitypub_actors.id = activitypub_posts.actor_id', 'inner')
                     ->where('activitypub_actors.is_blocked', 0);
             }
 
-            $this->where('in_reply_to_id', $this->uuid->fromString($statusId) ->getBytes())
+            $this->where('in_reply_to_id', $this->uuid->fromString($postId) ->getBytes())
                 ->where('`published_at` <= NOW()', null, false)
                 ->orderBy('published_at', 'ASC');
             $found = $this->findAll();
@@ -202,18 +202,18 @@ class StatusModel extends UuidModel
     }
 
     /**
-     * Retrieves all published reblogs for a given status
+     * Retrieves all published reblogs for a given post
      *
-     * @return Status[]
+     * @return Post[]
      */
-    public function getStatusReblogs(string $statusId): array
+    public function getPostReblogs(string $postId): array
     {
         $cacheName =
             config('ActivityPub')
-                ->cachePrefix . "status#{$statusId}_reblogs";
+                ->cachePrefix . "post#{$postId}_reblogs";
 
         if (! ($found = cache($cacheName))) {
-            $found = $this->where('reblog_of_id', $this->uuid->fromString($statusId) ->getBytes())
+            $found = $this->where('reblog_of_id', $this->uuid->fromString($postId) ->getBytes())
                 ->where('`published_at` <= NOW()', null, false)
                 ->orderBy('published_at', 'ASC')
                 ->findAll();
@@ -225,23 +225,23 @@ class StatusModel extends UuidModel
         return $found;
     }
 
-    public function addPreviewCard(string $statusId, int $previewCardId): Query | bool
+    public function addPreviewCard(string $postId, int $previewCardId): Query | bool
     {
-        return $this->db->table('activitypub_statuses_preview_cards')
+        return $this->db->table('activitypub_posts_preview_cards')
             ->insert([
-                'status_id' => $this->uuid->fromString($statusId)
+                'post_id' => $this->uuid->fromString($postId)
                     ->getBytes(),
                 'preview_card_id' => $previewCardId,
             ]);
     }
 
     /**
-     * Adds status in database along preview card if relevant
+     * Adds post in database along preview card if relevant
      *
-     * @return string|false returns the new status id if success or false otherwise
+     * @return string|false returns the new post id if success or false otherwise
      */
-    public function addStatus(
-        Status $status,
+    public function addPost(
+        Post $post,
         bool $createPreviewCard = true,
         bool $registerActivity = true
     ): string | false {
@@ -249,101 +249,101 @@ class StatusModel extends UuidModel
 
         $this->db->transStart();
 
-        if (! ($newStatusId = $this->insert($status, true))) {
+        if (! ($newPostId = $this->insert($post, true))) {
             $this->db->transRollback();
 
-            // Couldn't insert status
+            // Couldn't insert post
             return false;
         }
 
         if ($createPreviewCard) {
             // parse message
-            $messageUrls = extract_urls_from_message($status->message);
+            $messageUrls = extract_urls_from_message($post->message);
 
             if (
                 $messageUrls !== [] &&
                 ($previewCard = get_or_create_preview_card_from_url(new URI($messageUrls[0]))) &&
-                ! $this->addPreviewCard($newStatusId, $previewCard->id)
+                ! $this->addPreviewCard($newPostId, $previewCard->id)
             ) {
                 $this->db->transRollback();
-                // problem when linking status to preview card
+                // problem when linking post to preview card
                 return false;
             }
         }
 
-        model('ActorModel')
-            ->where('id', $status->actor_id)
-            ->increment('statuses_count');
+        model('ActorModel', false)
+            ->where('id', $post->actor_id)
+            ->increment('posts_count');
 
         if ($registerActivity) {
-            // set status id and uri to construct NoteObject
-            $status->id = $newStatusId;
-            $status->uri = url_to('status', $status->actor->username, $newStatusId);
+            // set post id and uri to construct NoteObject
+            $post->id = $newPostId;
+            $post->uri = url_to('post', $post->actor->username, $newPostId);
 
             $createActivity = new CreateActivity();
             $noteObjectClass = config('ActivityPub')
                 ->noteObject;
             $createActivity
-                ->set('actor', $status->actor->uri)
-                ->set('object', new $noteObjectClass($status));
+                ->set('actor', $post->actor->uri)
+                ->set('object', new $noteObjectClass($post));
 
-            $activityId = model('ActivityModel')
+            $activityId = model('ActivityModel', false)
                 ->newActivity(
                     'Create',
-                    $status->actor_id,
+                    $post->actor_id,
                     null,
-                    $newStatusId,
+                    $newPostId,
                     $createActivity->toJSON(),
-                    $status->published_at,
+                    $post->published_at,
                     'queued',
                 );
 
-            $createActivity->set('id', url_to('activity', $status->actor->username, $activityId));
+            $createActivity->set('id', url_to('activity', $post->actor->username, $activityId));
 
-            model('ActivityModel')
+            model('ActivityModel', false)
                 ->update($activityId, [
                     'payload' => $createActivity->toJSON(),
                 ]);
         }
 
-        Events::trigger('on_status_add', $status);
+        Events::trigger('on_post_add', $post);
 
-        $this->clearCache($status);
+        $this->clearCache($post);
 
         $this->db->transComplete();
 
-        return $newStatusId;
+        return $newPostId;
     }
 
-    public function editStatus(Status $updatedStatus): bool
+    public function editPost(Post $updatedPost): bool
     {
         $this->db->transStart();
 
-        // update status create activity schedule in database
-        $scheduledActivity = model('ActivityModel')
+        // update post create activity schedule in database
+        $scheduledActivity = model('ActivityModel', false)
             ->where([
                 'type' => 'Create',
-                'status_id' => $this->uuid
-                    ->fromString($updatedStatus->id)
+                'post_id' => $this->uuid
+                    ->fromString($updatedPost->id)
                     ->getBytes(),
             ])
             ->first();
 
         // update published date in payload
         $newPayload = $scheduledActivity->payload;
-        $newPayload->object->published = $updatedStatus->published_at->format(DATE_W3C);
-        model('ActivityModel')
+        $newPayload->object->published = $updatedPost->published_at->format(DATE_W3C);
+        model('ActivityModel', false)
             ->update($scheduledActivity->id, [
                 'payload' => json_encode($newPayload, JSON_THROW_ON_ERROR),
-                'scheduled_at' => $updatedStatus->published_at,
+                'scheduled_at' => $updatedPost->published_at,
             ]);
 
-        // update status
-        $updateResult = $this->update($updatedStatus->id, $updatedStatus);
+        // update post
+        $updateResult = $this->update($updatedPost->id, $updatedPost);
 
-        Events::trigger('on_status_edit', $updatedStatus);
+        Events::trigger('on_post_edit', $updatedPost);
 
-        $this->clearCache($updatedStatus);
+        $this->clearCache($updatedPost);
 
         $this->db->transComplete();
 
@@ -351,59 +351,59 @@ class StatusModel extends UuidModel
     }
 
     /**
-     * Removes a status from the database and decrements meta data
+     * Removes a post from the database and decrements meta data
      */
-    public function removeStatus(Status $status, bool $registerActivity = true): BaseResult | bool
+    public function removePost(Post $post, bool $registerActivity = true): BaseResult | bool
     {
         $this->db->transStart();
 
-        model('ActorModel')
-            ->where('id', $status->actor_id)
-            ->decrement('statuses_count');
+        model('ActorModel', false)
+            ->where('id', $post->actor_id)
+            ->decrement('posts_count');
 
-        if ($status->in_reply_to_id !== null) {
-            // Status to remove is a reply
-            model('StatusModel')
-                ->where('id', $this->uuid->fromString($status->in_reply_to_id) ->getBytes())
+        if ($post->in_reply_to_id !== null) {
+            // Post to remove is a reply
+            model('PostModel', false)
+                ->where('id', $this->uuid->fromString($post->in_reply_to_id) ->getBytes())
                 ->decrement('replies_count');
 
-            Events::trigger('on_reply_remove', $status);
+            Events::trigger('on_reply_remove', $post);
         }
 
-        // remove all status reblogs
-        foreach ($status->reblogs as $reblog) {
+        // remove all post reblogs
+        foreach ($post->reblogs as $reblog) {
             // FIXME: issue when actor is not local, can't get actor information
-            $this->removeStatus($reblog);
+            $this->removePost($reblog);
         }
 
-        // remove all status replies
-        foreach ($status->replies as $reply) {
-            $this->removeStatus($reply);
+        // remove all post replies
+        foreach ($post->replies as $reply) {
+            $this->removePost($reply);
         }
 
         // check that preview card is no longer used elsewhere before deleting it
         if (
-            $status->preview_card &&
+            $post->preview_card &&
             $this->db
-                ->table('activitypub_statuses_preview_cards')
-                ->where('preview_card_id', $status->preview_card->id)
+                ->table('activitypub_posts_preview_cards')
+                ->where('preview_card_id', $post->preview_card->id)
                 ->countAll() <= 1
         ) {
-            model('PreviewCardModel')->deletePreviewCard($status->preview_card->id, $status->preview_card->url);
+            model('PreviewCardModel', false)->deletePreviewCard($post->preview_card->id, $post->preview_card->url);
         }
 
         if ($registerActivity) {
             $deleteActivity = new DeleteActivity();
             $tombstoneObject = new TombstoneObject();
-            $tombstoneObject->set('id', $status->uri);
+            $tombstoneObject->set('id', $post->uri);
             $deleteActivity
-                ->set('actor', $status->actor->uri)
+                ->set('actor', $post->actor->uri)
                 ->set('object', $tombstoneObject);
 
-            $activityId = model('ActivityModel')
+            $activityId = model('ActivityModel', false)
                 ->newActivity(
                     'Delete',
-                    $status->actor_id,
+                    $post->actor_id,
                     null,
                     null,
                     $deleteActivity->toJSON(),
@@ -411,20 +411,20 @@ class StatusModel extends UuidModel
                     'queued',
                 );
 
-            $deleteActivity->set('id', url_to('activity', $status->actor->username, $activityId));
+            $deleteActivity->set('id', url_to('activity', $post->actor->username, $activityId));
 
-            model('ActivityModel')
+            model('ActivityModel', false)
                 ->update($activityId, [
                     'payload' => $deleteActivity->toJSON(),
                 ]);
         }
 
-        $result = model('StatusModel', false)
-            ->delete($status->id);
+        $result = model('PostModel', false)
+            ->delete($post->id);
 
-        Events::trigger('on_status_remove', $status);
+        Events::trigger('on_post_remove', $post);
 
-        $this->clearCache($status);
+        $this->clearCache($post);
 
         $this->db->transComplete();
 
@@ -432,182 +432,182 @@ class StatusModel extends UuidModel
     }
 
     public function addReply(
-        Status $reply,
+        Post $reply,
         bool $createPreviewCard = true,
         bool $registerActivity = true
     ): string | false {
         if (! $reply->in_reply_to_id) {
-            throw new Exception('Passed status is not a reply!');
+            throw new Exception('Passed post is not a reply!');
         }
 
         $this->db->transStart();
 
-        $statusId = $this->addStatus($reply, $createPreviewCard, $registerActivity);
+        $postId = $this->addPost($reply, $createPreviewCard, $registerActivity);
 
-        model('StatusModel')
+        model('PostModel', false)
             ->where('id', $this->uuid->fromString($reply->in_reply_to_id) ->getBytes())
             ->increment('replies_count');
 
-        Events::trigger('on_status_reply', $reply);
+        Events::trigger('on_post_reply', $reply);
 
         $this->clearCache($reply);
 
         $this->db->transComplete();
 
-        return $statusId;
+        return $postId;
     }
 
-    public function reblog(Actor $actor, Status $status, bool $registerActivity = true): string | false
+    public function reblog(Actor $actor, Post $post, bool $registerActivity = true): string | false
     {
         $this->db->transStart();
 
-        $reblog = new Status([
+        $reblog = new Post([
             'actor_id' => $actor->id,
-            'reblog_of_id' => $status->id,
+            'reblog_of_id' => $post->id,
             'published_at' => Time::now(),
         ]);
 
         // add reblog
         $reblogId = $this->insert($reblog);
 
-        model('ActorModel')
+        model('ActorModel', false)
             ->where('id', $actor->id)
-            ->increment('statuses_count');
+            ->increment('posts_count');
 
-        model('StatusModel')
-            ->where('id', $this->uuid->fromString($status->id)->getBytes())
+        model('PostModel', false)
+            ->where('id', $this->uuid->fromString($post->id)->getBytes())
             ->increment('reblogs_count');
 
         if ($registerActivity) {
             $announceActivity = new AnnounceActivity($reblog);
 
-            $activityId = model('ActivityModel')
+            $activityId = model('ActivityModel', false)
                 ->newActivity(
                     'Announce',
                     $actor->id,
                     null,
-                    $status->id,
+                    $post->id,
                     $announceActivity->toJSON(),
                     $reblog->published_at,
                     'queued',
                 );
 
-            $announceActivity->set('id', url_to('activity', $status->actor->username, $activityId));
+            $announceActivity->set('id', url_to('activity', $post->actor->username, $activityId));
 
-            model('ActivityModel')
+            model('ActivityModel', false)
                 ->update($activityId, [
                     'payload' => $announceActivity->toJSON(),
                 ]);
         }
 
-        Events::trigger('on_status_reblog', $actor, $status);
+        Events::trigger('on_post_reblog', $actor, $post);
 
-        $this->clearCache($status);
+        $this->clearCache($post);
 
         $this->db->transComplete();
 
         return $reblogId;
     }
 
-    public function undoReblog(Status $reblogStatus, bool $registerActivity = true): BaseResult | bool
+    public function undoReblog(Post $reblogPost, bool $registerActivity = true): BaseResult | bool
     {
         $this->db->transStart();
 
-        model('ActorModel')
-            ->where('id', $reblogStatus->actor_id)
-            ->decrement('statuses_count');
+        model('ActorModel', false)
+            ->where('id', $reblogPost->actor_id)
+            ->decrement('posts_count');
 
-        model('StatusModel')
-            ->where('id', $this->uuid->fromString($reblogStatus->reblog_of_id) ->getBytes())
+        model('PostModel', false)
+            ->where('id', $this->uuid->fromString($reblogPost->reblog_of_id) ->getBytes())
             ->decrement('reblogs_count');
 
         if ($registerActivity) {
             $undoActivity = new UndoActivity();
             // get like activity
-            $activity = model('ActivityModel')
+            $activity = model('ActivityModel', false)
                 ->where([
                     'type' => 'Announce',
-                    'actor_id' => $reblogStatus->actor_id,
-                    'status_id' => $this->uuid
-                        ->fromString($reblogStatus->reblog_of_id)
+                    'actor_id' => $reblogPost->actor_id,
+                    'post_id' => $this->uuid
+                        ->fromString($reblogPost->reblog_of_id)
                         ->getBytes(),
                 ])
                 ->first();
 
-            $announceActivity = new AnnounceActivity($reblogStatus);
-            $announceActivity->set('id', url_to('activity', $reblogStatus->actor->username, $activity->id),);
+            $announceActivity = new AnnounceActivity($reblogPost);
+            $announceActivity->set('id', url_to('activity', $reblogPost->actor->username, $activity->id),);
 
             $undoActivity
-                ->set('actor', $reblogStatus->actor->uri)
+                ->set('actor', $reblogPost->actor->uri)
                 ->set('object', $announceActivity);
 
-            $activityId = model('ActivityModel')
+            $activityId = model('ActivityModel', false)
                 ->newActivity(
                     'Undo',
-                    $reblogStatus->actor_id,
+                    $reblogPost->actor_id,
                     null,
-                    $reblogStatus->reblog_of_id,
+                    $reblogPost->reblog_of_id,
                     $undoActivity->toJSON(),
                     Time::now(),
                     'queued',
                 );
 
-            $undoActivity->set('id', url_to('activity', $reblogStatus->actor->username, $activityId));
+            $undoActivity->set('id', url_to('activity', $reblogPost->actor->username, $activityId));
 
-            model('ActivityModel')
+            model('ActivityModel', false)
                 ->update($activityId, [
                     'payload' => $undoActivity->toJSON(),
                 ]);
         }
 
-        $result = model('StatusModel', false)
-            ->delete($reblogStatus->id);
+        $result = model('PostModel', false)
+            ->delete($reblogPost->id);
 
-        Events::trigger('on_status_undo_reblog', $reblogStatus);
+        Events::trigger('on_post_undo_reblog', $reblogPost);
 
-        $this->clearCache($reblogStatus);
+        $this->clearCache($reblogPost);
 
         $this->db->transComplete();
 
         return $result;
     }
 
-    public function toggleReblog(Actor $actor, Status $status): void
+    public function toggleReblog(Actor $actor, Post $post): void
     {
         if (
-            ! ($reblogStatus = $this->where([
+            ! ($reblogPost = $this->where([
                 'actor_id' => $actor->id,
                 'reblog_of_id' => $this->uuid
-                    ->fromString($status->id)
+                    ->fromString($post->id)
                     ->getBytes(),
             ])->first())
         ) {
-            $this->reblog($actor, $status);
+            $this->reblog($actor, $post);
         } else {
-            $this->undoReblog($reblogStatus);
+            $this->undoReblog($reblogPost);
         }
     }
 
-    public function clearCache(Status $status): void
+    public function clearCache(Post $post): void
     {
         $cachePrefix = config('ActivityPub')
             ->cachePrefix;
 
-        $hashedStatusUri = md5($status->uri);
+        $hashedPostUri = md5($post->uri);
 
-        model('ActorModel')
-            ->clearCache($status->actor);
+        model('ActorModel', false)
+            ->clearCache($post->actor);
         cache()
-            ->deleteMatching($cachePrefix . "status#{$status->id}*");
+            ->deleteMatching($cachePrefix . "post#{$post->id}*");
         cache()
-            ->deleteMatching($cachePrefix . "status-{$hashedStatusUri}*");
+            ->deleteMatching($cachePrefix . "post-{$hashedPostUri}*");
 
-        if ($status->in_reply_to_id !== null) {
-            $this->clearCache($status->reply_to_status);
+        if ($post->in_reply_to_id !== null) {
+            $this->clearCache($post->reply_to_post);
         }
 
-        if ($status->reblog_of_id !== null) {
-            $this->clearCache($status->reblog_of_status);
+        if ($post->reblog_of_id !== null) {
+            $this->clearCache($post->reblog_of_post);
         }
     }
 
@@ -615,16 +615,16 @@ class StatusModel extends UuidModel
      * @param array<string, array<string|int, mixed>> $data
      * @return array<string, array<string|int, mixed>>
      */
-    protected function setStatusId(array $data): array
+    protected function setPostId(array $data): array
     {
         $uuid4 = $this->uuid->{$this->uuidVersion}();
         $data['data']['id'] = $uuid4->toString();
 
         if (! isset($data['data']['uri'])) {
-            $actor = model('ActorModel')
+            $actor = model('ActorModel', false)
                 ->getActorById((int) $data['data']['actor_id']);
 
-            $data['data']['uri'] = url_to('status', $actor->username, $uuid4->toString());
+            $data['data']['uri'] = url_to('post', $actor->username, $uuid4->toString());
         }
 
         return $data;
diff --git a/app/Libraries/ActivityPub/Models/PreviewCardModel.php b/app/Libraries/ActivityPub/Models/PreviewCardModel.php
index 161052f7b1..08879ff795 100644
--- a/app/Libraries/ActivityPub/Models/PreviewCardModel.php
+++ b/app/Libraries/ActivityPub/Models/PreviewCardModel.php
@@ -70,18 +70,18 @@ class PreviewCardModel extends Model
         return $found;
     }
 
-    public function getStatusPreviewCard(string $statusId): ?PreviewCard
+    public function getPostPreviewCard(string $postId): ?PreviewCard
     {
         $cacheName =
             config('ActivityPub')
-                ->cachePrefix . "status#{$statusId}_preview_card";
+                ->cachePrefix . "post#{$postId}_preview_card";
         if (! ($found = cache($cacheName))) {
             $found = $this->join(
-                'activitypub_statuses_preview_cards',
-                'activitypub_statuses_preview_cards.preview_card_id = id',
+                'activitypub_posts_preview_cards',
+                'activitypub_posts_preview_cards.preview_card_id = id',
                 'inner',
             )
-                ->where('status_id', service('uuid') ->fromString($statusId) ->getBytes())
+                ->where('post_id', service('uuid') ->fromString($postId) ->getBytes())
                 ->first();
 
             cache()
diff --git a/app/Libraries/ActivityPub/Objects/NoteObject.php b/app/Libraries/ActivityPub/Objects/NoteObject.php
index 067eef84e5..5588f9bb64 100644
--- a/app/Libraries/ActivityPub/Objects/NoteObject.php
+++ b/app/Libraries/ActivityPub/Objects/NoteObject.php
@@ -15,7 +15,7 @@ declare(strict_types=1);
 namespace ActivityPub\Objects;
 
 use ActivityPub\Core\ObjectType;
-use ActivityPub\Entities\Status;
+use ActivityPub\Entities\Post;
 
 class NoteObject extends ObjectType
 {
@@ -27,20 +27,20 @@ class NoteObject extends ObjectType
 
     protected string $replies;
 
-    public function __construct(Status $status)
+    public function __construct(Post $post)
     {
-        $this->id = $status->uri;
+        $this->id = $post->uri;
 
-        $this->content = $status->message_html;
-        $this->published = $status->published_at->format(DATE_W3C);
-        $this->attributedTo = $status->actor->uri;
+        $this->content = $post->message_html;
+        $this->published = $post->published_at->format(DATE_W3C);
+        $this->attributedTo = $post->actor->uri;
 
-        if ($status->in_reply_to_id !== null) {
-            $this->inReplyTo = $status->reply_to_status->uri;
+        if ($post->in_reply_to_id !== null) {
+            $this->inReplyTo = $post->reply_to_post->uri;
         }
 
-        $this->replies = url_to('status-replies', $status->actor->username, $status->id);
+        $this->replies = url_to('post-replies', $post->actor->username, $post->id);
 
-        $this->cc = [$status->actor->followers_url];
+        $this->cc = [$post->actor->followers_url];
     }
 }
diff --git a/app/Libraries/CommentObject.php b/app/Libraries/CommentObject.php
new file mode 100644
index 0000000000..d127bcc2d3
--- /dev/null
+++ b/app/Libraries/CommentObject.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Libraries;
+
+use ActivityPub\Core\ObjectType;
+use App\Entities\Comment;
+
+class CommentObject extends ObjectType
+{
+    protected string $type = 'Note';
+
+    protected string $attributedTo;
+
+    protected string $inReplyTo;
+
+    protected string $replies;
+
+    public function __construct(Comment $comment)
+    {
+        $this->id = $comment->uri;
+
+        $this->content = $comment->message_html;
+        $this->published = $comment->created_at->format(DATE_W3C);
+        $this->attributedTo = $comment->actor->uri;
+
+        if ($comment->in_reply_to_id !== null) {
+            $this->inReplyTo = $comment->reply_to_comment->uri;
+        }
+
+        $this->replies = url_to('comment-replies', $comment->actor->username, $comment->episode->slug, $comment->id);
+
+        $this->cc = [$comment->actor->followers_url];
+    }
+}
diff --git a/app/Libraries/NoteObject.php b/app/Libraries/NoteObject.php
index 2b4ea701c0..7c28bd69b1 100644
--- a/app/Libraries/NoteObject.php
+++ b/app/Libraries/NoteObject.php
@@ -11,25 +11,25 @@ declare(strict_types=1);
 namespace App\Libraries;
 
 use ActivityPub\Objects\NoteObject as ActivityPubNoteObject;
-use App\Entities\Status;
+use App\Entities\Post;
 
 class NoteObject extends ActivityPubNoteObject
 {
     /**
-     * @param Status $status
+     * @param Post $post
      */
-    public function __construct(\ActivityPub\Entities\Status $status)
+    public function __construct(\ActivityPub\Entities\Post $post)
     {
-        parent::__construct($status);
+        parent::__construct($post);
 
-        if ($status->episode_id) {
+        if ($post->episode_id) {
             $this->content =
                 '<a href="' .
-                $status->episode->link .
+                $post->episode->link .
                 '" target="_blank" rel="noopener noreferrer">' .
-                $status->episode->title .
+                $post->episode->title .
                 '</a><br/>' .
-                $status->message_html;
+                $post->message_html;
         }
     }
 }
diff --git a/app/Models/CommentModel.php b/app/Models/CommentModel.php
new file mode 100644
index 0000000000..ba7215faf0
--- /dev/null
+++ b/app/Models/CommentModel.php
@@ -0,0 +1,184 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Models;
+
+use ActivityPub\Activities\CreateActivity;
+use App\Entities\Comment;
+use App\Libraries\CommentObject;
+use CodeIgniter\Database\BaseBuilder;
+use Michalsn\Uuid\UuidModel;
+
+class CommentModel extends UuidModel
+{
+    /**
+     * @var string
+     */
+    protected $returnType = Comment::class;
+
+    /**
+     * @var string
+     */
+    protected $table = 'comments';
+
+    /**
+     * @var string[]
+     */
+    protected $uuidFields = ['id', 'in_reply_to_id'];
+
+    /**
+     * @var string[]
+     */
+    protected $allowedFields = [
+        'id',
+        'uri',
+        'episode_id',
+        'actor_id',
+        'in_reply_to_id',
+        'message',
+        'message_html',
+        'likes_count',
+        'dislikes_count',
+        'replies_count',
+        'created_at',
+        'created_by',
+    ];
+
+    /**
+     * @var string[]
+     */
+    protected $beforeInsert = ['setCommentId'];
+
+    public function getCommentById(string $commentId): ?Comment
+    {
+        $cacheName = "comment#{$commentId}";
+        if (! ($found = cache($cacheName))) {
+            $found = $this->find($commentId);
+
+            cache()
+                ->save($cacheName, $found, DECADE);
+        }
+
+        return $found;
+    }
+
+    public function addComment(Comment $comment, bool $registerActivity = false): string | false
+    {
+        $this->db->transStart();
+        // increment Episode's comments_count
+
+        if (! ($newCommentId = $this->insert($comment, true))) {
+            $this->db->transRollback();
+
+            // Couldn't insert comment
+            return false;
+        }
+
+        (new EpisodeModel())
+            ->where('id', $comment->episode_id)
+            ->increment('comments_count');
+
+        if ($registerActivity) {
+            // set post id and uri to construct NoteObject
+            $comment->id = $newCommentId;
+            $comment->uri = url_to('comment', $comment->actor->username, $comment->episode->slug, $comment->id);
+
+            $createActivity = new CreateActivity();
+            $createActivity
+                ->set('actor', $comment->actor->uri)
+                ->set('object', new CommentObject($comment));
+
+            $activityId = model('ActivityModel', false)
+                ->newActivity(
+                    'Create',
+                    $comment->actor_id,
+                    null,
+                    null,
+                    $createActivity->toJSON(),
+                    $comment->created_at,
+                    'queued',
+                );
+
+            $createActivity->set('id', url_to('activity', $comment->actor->username, $activityId));
+
+            model('ActivityModel', false)
+                ->update($activityId, [
+                    'payload' => $createActivity->toJSON(),
+                ]);
+        }
+
+        $this->db->transComplete();
+
+        return $newCommentId;
+    }
+
+    /**
+     * Retrieves all published posts for a given episode ordered by publication date
+     *
+     * @return Comment[]
+     */
+    public function getEpisodeComments(int $episodeId): array
+    {
+        // TODO: merge with replies from posts linked to episode linked
+        $episodeComments = $this->select('*, 0 as is_from_post')
+            ->where('episode_id', $episodeId)
+            ->getCompiledSelect();
+
+        $episodePostsReplies = $this->db->table('activitypub_posts')
+            ->select(
+                'id, uri, episode_id, actor_id, in_reply_to_id, message, message_html, favourites_count as likes_count, 0 as dislikes_count, replies_count, published_at as created_at, created_by, 1 as is_from_post'
+            )
+            ->whereIn('in_reply_to_id', function (BaseBuilder $builder) use (&$episodeId): BaseBuilder {
+                return $builder->select('id')
+                    ->from('activitypub_posts')
+                    ->where('episode_id', $episodeId);
+            })
+            ->where('`created_at` <= NOW()', null, false)
+            ->getCompiledSelect();
+
+        $allEpisodeComments = $this->db->query(
+            $episodeComments . ' UNION ' . $episodePostsReplies . ' ORDER BY created_at ASC'
+        );
+
+        return $allEpisodeComments->getCustomResultObject($this->returnType);
+    }
+
+    /**
+     * Retrieves all replies for a given comment
+     *
+     * @return Comment[]
+     */
+    public function getCommentReplies(int $episodeId, string $commentId): array
+    {
+        // TODO: get all replies for a given comment
+        return $this->findAll();
+    }
+
+    /**
+     * @param array<string, array<string|int, mixed>> $data
+     * @return array<string, array<string|int, mixed>>
+     */
+    protected function setCommentId(array $data): array
+    {
+        $uuid4 = $this->uuid->{$this->uuidVersion}();
+        $data['data']['id'] = $uuid4->toString();
+
+        if (! isset($data['data']['uri'])) {
+            $actor = model('ActorModel', false)
+                ->getActorById((int) $data['data']['actor_id']);
+            $episode = model('EpisodeModel', false)
+                ->find((int) $data['data']['episode_id']);
+
+            $data['data']['uri'] = url_to('comment', $actor->username, $episode->slug, $uuid4->toString());
+        }
+
+        return $data;
+    }
+}
diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php
index d554062486..f3973d1c5b 100644
--- a/app/Models/EpisodeModel.php
+++ b/app/Models/EpisodeModel.php
@@ -90,9 +90,8 @@ class EpisodeModel extends Model
         'location_geo',
         'location_osm',
         'custom_rss',
-        'favourites_total',
-        'reblogs_total',
-        'statuses_total',
+        'posts_count',
+        'comments_count',
         'published_at',
         'created_by',
         'updated_by',
diff --git a/app/Models/PostModel.php b/app/Models/PostModel.php
new file mode 100644
index 0000000000..db01aee40a
--- /dev/null
+++ b/app/Models/PostModel.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Podlibre
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+namespace App\Models;
+
+use ActivityPub\Models\PostModel as ActivityPubPostModel;
+use App\Entities\Post;
+
+class PostModel extends ActivityPubPostModel
+{
+    /**
+     * @var string
+     */
+    protected $returnType = Post::class;
+
+    /**
+     * @var string[]
+     */
+    protected $allowedFields = [
+        'id',
+        'uri',
+        'actor_id',
+        'in_reply_to_id',
+        'reblog_of_id',
+        'episode_id',
+        'message',
+        'message_html',
+        'favourites_count',
+        'reblogs_count',
+        'replies_count',
+        'created_by',
+        'published_at',
+    ];
+
+    /**
+     * Retrieves all published posts for a given episode ordered by publication date
+     *
+     * @return Post[]
+     */
+    public function getEpisodePosts(int $episodeId): array
+    {
+        return $this->where([
+            'episode_id' => $episodeId,
+        ])
+            ->where('`published_at` <= NOW()', null, false)
+            ->orderBy('published_at', 'DESC')
+            ->findAll();
+    }
+}
diff --git a/app/Models/StatusModel.php b/app/Models/StatusModel.php
deleted file mode 100644
index 132c48efd2..0000000000
--- a/app/Models/StatusModel.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright  2021 Podlibre
- * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
- * @link       https://castopod.org/
- */
-
-namespace App\Models;
-
-use ActivityPub\Models\StatusModel as ActivityPubStatusModel;
-use App\Entities\Status;
-use CodeIgniter\Database\BaseBuilder;
-
-class StatusModel extends ActivityPubStatusModel
-{
-    /**
-     * @var string
-     */
-    protected $returnType = Status::class;
-
-    /**
-     * @var string[]
-     */
-    protected $allowedFields = [
-        'id',
-        'uri',
-        'actor_id',
-        'in_reply_to_id',
-        'reblog_of_id',
-        'episode_id',
-        'message',
-        'message_html',
-        'favourites_count',
-        'reblogs_count',
-        'replies_count',
-        'created_by',
-        'published_at',
-    ];
-
-    /**
-     * Retrieves all published statuses for a given episode ordered by publication date
-     *
-     * @return Status[]
-     */
-    public function getEpisodeStatuses(int $episodeId): array
-    {
-        return $this->where([
-            'episode_id' => $episodeId,
-        ])
-            ->where('`published_at` <= NOW()', null, false)
-            ->orderBy('published_at', 'DESC')
-            ->findAll();
-    }
-
-    /**
-     * Retrieves all published statuses for a given episode ordered by publication date
-     *
-     * @return Status[]
-     */
-    public function getEpisodeComments(int $episodeId): array
-    {
-        return $this->whereIn('in_reply_to_id', function (BaseBuilder $builder) use (&$episodeId): BaseBuilder {
-            return $builder->select('id')
-                ->from('activitypub_statuses')
-                ->where('episode_id', $episodeId);
-        })
-            ->where('`published_at` <= NOW()', null, false)
-            ->orderBy('published_at', 'ASC')
-            ->findAll();
-    }
-}
diff --git a/app/Resources/icons/thumb-down.svg b/app/Resources/icons/thumb-down.svg
new file mode 100644
index 0000000000..ff06be8ab1
--- /dev/null
+++ b/app/Resources/icons/thumb-down.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+    <g>
+        <path fill="none" d="M0 0h24v24H0z"/>
+        <path d="M22 15h-3V3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-5.293 1.293l-6.4 6.4a.5.5 0 0 1-.654.047L8.8 22.1a1.5 1.5 0 0 1-.553-1.57L9.4 16H3a2 2 0 0 1-2-2v-2.104a2 2 0 0 1 .15-.762L4.246 3.62A1 1 0 0 1 5.17 3H16a1 1 0 0 1 1 1v11.586a1 1 0 0 1-.293.707z"/>
+    </g>
+</svg>
diff --git a/app/Resources/icons/thumb-up.svg b/app/Resources/icons/thumb-up.svg
new file mode 100644
index 0000000000..f0d6670272
--- /dev/null
+++ b/app/Resources/icons/thumb-up.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+    <g>
+        <path fill="none" d="M0 0h24v24H0z"/>
+        <path d="M2 9h3v12H2a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1zm5.293-1.293l6.4-6.4a.5.5 0 0 1 .654-.047l.853.64a1.5 1.5 0 0 1 .553 1.57L14.6 8H21a2 2 0 0 1 2 2v2.104a2 2 0 0 1-.15.762l-3.095 7.515a1 1 0 0 1-.925.619H8a1 1 0 0 1-1-1V8.414a1 1 0 0 1 .293-.707z"/>
+    </g>
+</svg>
diff --git a/app/Resources/styles/index.css b/app/Resources/styles/index.css
index 23780f3328..37bc69b1d4 100644
--- a/app/Resources/styles/index.css
+++ b/app/Resources/styles/index.css
@@ -7,7 +7,7 @@
 @import "./radioBtn.css";
 @import "./switch.css";
 @import "./charts.css";
-@import "./status.css";
+@import "./post.css";
 @import "./tabs.css";
 @import "./radioToggler.css";
 @import "./formInputTabs.css";
diff --git a/app/Resources/styles/status.css b/app/Resources/styles/post.css
similarity index 87%
rename from app/Resources/styles/status.css
rename to app/Resources/styles/post.css
index e3d2b794ac..966ec60663 100644
--- a/app/Resources/styles/status.css
+++ b/app/Resources/styles/post.css
@@ -1,11 +1,11 @@
 @layer components {
-  .status-content {
+  .post-content {
     & a {
       @apply text-sm font-semibold text-pine-600 hover:underline;
     }
   }
 
-  .status-replies > * {
+  .post-replies > * {
     @apply relative;
 
     & img {
diff --git a/app/Resources/styles/tabs.css b/app/Resources/styles/tabs.css
index f0f279b48b..6fb8e78144 100644
--- a/app/Resources/styles/tabs.css
+++ b/app/Resources/styles/tabs.css
@@ -1,6 +1,6 @@
 @layer components {
   .tabset {
-    @apply grid grid-cols-2;
+    @apply grid grid-cols-3;
   }
 
   .tabset > input[type="radio"] {
@@ -11,9 +11,10 @@
     @apply hidden;
   }
 
-  /* Logic for 2 tabs at most */
+  /* Logic for 3 tabs at most */
   .tabset > input:first-child:checked ~ .tab-panels > .tab-panel:first-child,
-  .tabset > input:nth-child(3):checked ~ .tab-panels > .tab-panel:nth-child(2) {
+  .tabset > input:nth-child(3):checked ~ .tab-panels > .tab-panel:nth-child(2),
+  .tabset > input:nth-child(5):checked ~ .tab-panels > .tab-panel:nth-child(3) {
     @apply block;
   }
 
@@ -23,7 +24,7 @@
   }
 
   .tabset > input:checked + label::after {
-    @apply absolute inset-x-0 bottom-0 w-1/2 h-1 mx-auto bg-pine-700;
+    @apply absolute inset-x-0 bottom-0 w-1/3 h-1 mx-auto bg-pine-700;
     content: "";
   }
 
@@ -32,6 +33,6 @@
   }
 
   .tabset .tab-panels {
-    @apply col-span-2 p-6;
+    @apply col-span-3 p-6;
   }
 }
diff --git a/app/Views/admin/episode/list.php b/app/Views/admin/episode/list.php
index a78dae29e2..c12c39b067 100644
--- a/app/Views/admin/episode/list.php
+++ b/app/Views/admin/episode/list.php
@@ -71,7 +71,7 @@
         [
             'header' => lang('Episode.list.comments'),
             'cell' => function ($episode): int {
-                return count($episode->comments);
+                return $episode->comments_count;
             },
         ],
         [
diff --git a/app/Views/admin/episode/publish.php b/app/Views/admin/episode/publish.php
index a3c192a24c..238d3b964d 100644
--- a/app/Views/admin/episode/publish.php
+++ b/app/Views/admin/episode/publish.php
@@ -27,9 +27,9 @@
 
 
 <label for="message" class="text-lg font-semibold"><?= lang(
-                                                        'Episode.publish_form.status',
+                                                        'Episode.publish_form.post',
                                                     ) ?></label>
-<small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.status_hint') ?></small>
+<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
diff --git a/app/Views/admin/episode/publish_edit.php b/app/Views/admin/episode/publish_edit.php
index 8d273db3f0..b83914a027 100644
--- a/app/Views/admin/episode/publish_edit.php
+++ b/app/Views/admin/episode/publish_edit.php
@@ -24,13 +24,13 @@
 ]) ?>
 <?= csrf_field() ?>
 <?= form_hidden('client_timezone', 'UTC') ?>
-<?= form_hidden('status_id', $status->id) ?>
+<?= form_hidden('post_id', $post->id) ?>
 
 
 <label for="message" class="text-lg font-semibold"><?= lang(
-                                                        'Episode.publish_form.status',
+                                                        'Episode.publish_form.post',
                                                     ) ?></label>
-<small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.status_hint') ?></small>
+<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
@@ -42,7 +42,7 @@
                 <span class="text-sm text-gray-500 truncate">@<?= $podcast
                                                                     ->actor->username ?></span>
             </p>
-            <?= relative_time($status->published_at, 'text-xs text-gray-500') ?>
+            <?= relative_time($post->published_at, 'text-xs text-gray-500') ?>
         </div>
     </div>
     <div class="px-4 mb-2">
@@ -54,7 +54,7 @@
                 'placeholder' => 'Write your message...',
                 'autofocus' => ''
             ],
-            old('message', $status->message, false),
+            old('message', $post->message, false),
             ['rows' => 2],
         ) ?>
     </div>
diff --git a/app/Views/podcast/_partials/comment.php b/app/Views/podcast/_partials/comment.php
new file mode 100644
index 0000000000..587df06942
--- /dev/null
+++ b/app/Views/podcast/_partials/comment.php
@@ -0,0 +1,43 @@
+<article class="relative z-10 flex w-full px-4 py-2 rounded-2xl">
+    <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+    <div class="flex-1">
+        <header class="w-full mb-2">
+            <a href="<?= $comment->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $comment->actor->is_local
+                ? ''
+                : 'target="_blank" rel="noopener noreferrer"' ?>>
+                <span class="mr-2 font-semibold truncate"><?= $comment->actor
+                    ->display_name ?></span>
+                <span class="text-sm text-gray-500 truncate">@<?= $comment->actor
+                    ->username .
+                    ($comment->actor->is_local
+                        ? ''
+                        : '@' . $comment->actor->domain) ?></span>
+                <?= relative_time($comment->created_at, 'text-xs text-gray-500 ml-auto') ?>
+            </a>
+        </header>
+        <div class="mb-2 post-content"><?= $comment->message_html ?></div>
+        <div class="inline-flex gap-x-4">
+            <?= anchor_popup(
+                route_to('comment-remote-action', $podcast->handle, $episode->slug, $comment->id, 'like'),
+                icon('thumb-up', 'text-lg mr-1 text-gray-400 group-hover:text-gray-600') . 0,
+                [
+                    'class' => 'inline-flex items-center hover:underline group',
+                    'width' => 420,
+                    'height' => 620,
+                    'title' => lang('Comment.like'),
+                ],
+            ) ?>
+            <?= anchor_popup(
+                route_to('comment-remote-action', $podcast->handle, $episode->slug, $comment->id, 'dislike'),
+                icon('thumb-down', 'text-lg text-gray-400 group-hover:text-gray-600'),
+                [
+                    'class' => 'inline-flex items-center hover:underline group',
+                    'width' => 420,
+                    'height' => 620,
+                    'title' => lang('Comment.dislike'),
+                ],
+            ) ?>
+        </div>
+    </div>
+</article>
diff --git a/app/Views/podcast/_partials/episode_card.php b/app/Views/podcast/_partials/episode_card.php
index 1aff9de6b6..01b5f412d4 100644
--- a/app/Views/podcast/_partials/episode_card.php
+++ b/app/Views/podcast/_partials/episode_card.php
@@ -28,12 +28,12 @@
                 <?= anchor(
                     route_to('episode', $podcast->handle, $episode->slug),
                     icon('chat', 'text-xl mr-1 text-gray-400') .
-                    $episode->statuses_total,
+                    $episode->comments_count,
                     [
                         'class' =>
-                        'inline-flex items-center hover:underline',
-                        'title' => lang('Episode.total_statuses', [
-                            'numberOfTotalStatuses' => $episode->statuses_total,
+                            'inline-flex items-center hover:underline',
+                        'title' => lang('Episode.number_of_comments', [
+                            'numberOfComments' => $episode->comments_count,
                         ]),
                     ],
                     ) ?>
diff --git a/app/Views/podcast/_partials/header.php b/app/Views/podcast/_partials/header.php
index 8714792f53..85679ae9d4 100644
--- a/app/Views/podcast/_partials/header.php
+++ b/app/Views/podcast/_partials/header.php
@@ -50,8 +50,8 @@
             <a href="<?= route_to(
                 'podcast-activity',
                 $podcast->handle,
-            ) ?>" class="hover:underline"><?= lang('Podcast.statuses', [
-    'numberOfStatuses' => $podcast->actor->statuses_count,
+            ) ?>" class="hover:underline"><?= lang('Podcast.posts', [
+    'numberOfPosts' => $podcast->actor->posts_count,
 ]) ?></a>
         </div>
     </div>
diff --git a/app/Views/podcast/_partials/post.php b/app/Views/podcast/_partials/post.php
new file mode 100644
index 0000000000..7ca262668c
--- /dev/null
+++ b/app/Views/podcast/_partials/post.php
@@ -0,0 +1,36 @@
+<article class="relative z-10 w-full bg-white shadow rounded-2xl">
+    <header class="flex px-6 py-4">
+        <img src="<?= $post->actor
+            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+        <div class="flex flex-col min-w-0">
+            <a href="<?= $post->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $post
+    ->actor->is_local
+    ? ''
+    : 'target="_blank" rel="noopener noreferrer"' ?>>
+                <span class="mr-2 font-semibold truncate"><?= $post->actor
+                    ->display_name ?></span>
+                <span class="text-sm text-gray-500 truncate">@<?= $post->actor
+                    ->username .
+                    ($post->actor->is_local
+                        ? ''
+                        : '@' . $post->actor->domain) ?></span>
+            </a>
+            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
+            class="text-xs text-gray-500">
+                <?= relative_time($post->published_at) ?>
+            </a>
+        </div>
+    </header>
+    <div class="px-6 mb-4 post-content"><?= $post->message_html ?></div>
+    <?php if ($post->episode_id): ?>
+        <?= view('podcast/_partials/episode_preview_card', [
+            'episode' => $post->episode,
+        ]) ?>
+    <?php elseif ($post->has_preview_card): ?>
+        <?= view('podcast/_partials/preview_card', [
+            'preview_card' => $post->preview_card,
+        ]) ?>
+    <?php endif; ?>
+    <?= $this->include('podcast/_partials/post_actions') ?>
+</article>
diff --git a/app/Views/podcast/_partials/post_actions.php b/app/Views/podcast/_partials/post_actions.php
new file mode 100644
index 0000000000..2468b3c1b5
--- /dev/null
+++ b/app/Views/podcast/_partials/post_actions.php
@@ -0,0 +1,36 @@
+<footer class="flex justify-around px-6 py-3">
+    <?= anchor(
+        route_to('post', $podcast->handle, $post->id),
+        icon('chat', 'text-2xl mr-1 text-gray-400') . $post->replies_count,
+        [
+            'class' => 'inline-flex items-center hover:underline',
+            'title' => lang('Post.replies', [
+                'numberOfReplies' => $post->replies_count,
+            ]),
+        ],
+    ) ?>
+    <?= anchor_popup(
+        route_to('post-remote-action', $podcast->handle, $post->id, 'reblog'),
+        icon('repeat', 'text-2xl mr-1 text-gray-400') . $post->reblogs_count,
+        [
+            'class' => 'inline-flex items-center hover:underline',
+            'width' => 420,
+            'height' => 620,
+            'title' => lang('Post.reblogs', [
+                'numberOfReblogs' => $post->reblogs_count,
+            ]),
+        ],
+    ) ?>
+    <?= anchor_popup(
+        route_to('post-remote-action', $podcast->handle, $post->id, 'favourite'),
+        icon('heart', 'text-2xl mr-1 text-gray-400') . $post->favourites_count,
+        [
+            'class' => 'inline-flex items-center hover:underline',
+            'width' => 420,
+            'height' => 620,
+            'title' => lang('Post.favourites', [
+                'numberOfFavourites' => $post->favourites_count,
+            ]),
+        ],
+    ) ?>
+</footer>
diff --git a/app/Views/podcast/_partials/status_actions_authenticated.php b/app/Views/podcast/_partials/post_actions_authenticated.php
similarity index 61%
rename from app/Views/podcast/_partials/status_actions_authenticated.php
rename to app/Views/podcast/_partials/post_actions_authenticated.php
index 9ee2cf6ef8..4cb02a32d4 100644
--- a/app/Views/podcast/_partials/status_actions_authenticated.php
+++ b/app/Views/podcast/_partials/post_actions_authenticated.php
@@ -1,87 +1,87 @@
 <footer class="px-6 py-3">
     <form action="<?= route_to(
-        'status-attempt-action',
+        'post-attempt-action',
         interact_as_actor()->username,
-        $status->id,
+        $post->id,
     ) ?>" method="POST" class="flex justify-around">
         <?= csrf_field() ?>
         <?= anchor(
-            route_to('status', $podcast->handle, $status->id),
-            icon('chat', 'text-2xl mr-1 text-gray-400') . $status->replies_count,
+            route_to('post', $podcast->handle, $post->id),
+            icon('chat', 'text-2xl mr-1 text-gray-400') . $post->replies_count,
             [
                 'class' => 'inline-flex items-center hover:underline',
-                'title' => lang('Status.replies', [
-                    'numberOfReplies' => $status->replies_count,
+                'title' => lang('Post.replies', [
+                    'numberOfReplies' => $post->replies_count,
                 ]),
             ],
         ) ?>
         <button type="submit" name="action" value="reblog" class="inline-flex items-center hover:underline" title="<?= lang(
-            'Status.reblogs',
+            'Post.reblogs',
             [
-                'numberOfReblogs' => $status->reblogs_count,
+                'numberOfReblogs' => $post->reblogs_count,
             ],
         ) ?>"><?= icon('repeat', 'text-2xl mr-1 text-gray-400') .
-    $status->reblogs_count ?></button>
+    $post->reblogs_count ?></button>
         <button type="submit" name="action" value="favourite" class="inline-flex items-center hover:underline" title="<?= lang(
-            'Status.favourites',
+            'Post.favourites',
             [
-                'numberOfFavourites' => $status->favourites_count,
+                'numberOfFavourites' => $post->favourites_count,
             ],
         ) ?>"><?= icon('heart', 'text-2xl mr-1 text-gray-400') .
-    $status->favourites_count ?></button>
-        <button id="<?= $status->id .
-            '-more-dropdown' ?>" type="button" class="px-2 py-1 text-2xl text-gray-500 outline-none focus:ring" data-dropdown="button" data-dropdown-target="<?= $status->id .
+    $post->favourites_count ?></button>
+        <button id="<?= $post->id .
+            '-more-dropdown' ?>" type="button" class="px-2 py-1 text-2xl text-gray-500 outline-none focus:ring" data-dropdown="button" data-dropdown-target="<?= $post->id .
     '-more-dropdown-menu' ?>" aria-label="<?= lang(
     'Common.more',
 ) ?>" aria-haspopup="true" aria-expanded="false"><?= icon('more') ?>
         </button>
     </form>
-    <nav id="<?= $status->id .
-        '-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm bg-white border rounded-lg shadow" aria-labelledby="<?= $status->id .
+    <nav id="<?= $post->id .
+        '-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm bg-white border rounded-lg shadow" aria-labelledby="<?= $post->id .
     '-more-dropdown' ?>" data-dropdown="menu" data-dropdown-placement="bottom">
         <?= anchor(
-            route_to('status', $podcast->handle, $status->id),
-            lang('Status.expand'),
+            route_to('post', $podcast->handle, $post->id),
+            lang('Post.expand'),
             [
                 'class' => 'px-4 py-1 hover:bg-gray-100',
             ],
         ) ?>
         <form action="<?= route_to(
-            'status-attempt-block-actor',
+            'post-attempt-block-actor',
             interact_as_actor()->username,
-            $status->id,
+            $post->id,
         ) ?>" method="POST">
             <?= csrf_field() ?>
             <button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
-                'Status.block_actor',
+                'Post.block_actor',
                 [
-                    'actorUsername' => $status->actor->username,
+                    'actorUsername' => $post->actor->username,
                 ],
             ) ?></button>
         </form>
         <form action="<?= route_to(
-            'status-attempt-block-domain',
+            'post-attempt-block-domain',
             interact_as_actor()->username,
-            $status->id,
+            $post->id,
         ) ?>" method="POST">
             <?= csrf_field() ?>
             <button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
-                'Status.block_domain',
+                'Post.block_domain',
                 [
-                    'actorDomain' => $status->actor->domain,
+                    'actorDomain' => $post->actor->domain,
                 ],
             ) ?></button>
         </form>
-        <?php if ($status->actor->is_local): ?>
+        <?php if ($post->actor->is_local): ?>
             <hr class="my-2" />
             <form action="<?= route_to(
-                'status-attempt-delete',
-                $status->actor->username,
-                $status->id,
+                'post-attempt-delete',
+                $post->actor->username,
+                $post->id,
             ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 font-semibold text-left text-red-600 hover:bg-gray-100"><?= lang(
-                    'Status.delete',
+                    'Post.delete',
                 ) ?></button>
             </form>
         <?php endif; ?>
diff --git a/app/Views/podcast/_partials/post_authenticated.php b/app/Views/podcast/_partials/post_authenticated.php
new file mode 100644
index 0000000000..1ec49dedef
--- /dev/null
+++ b/app/Views/podcast/_partials/post_authenticated.php
@@ -0,0 +1,36 @@
+<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
+    <header class="flex px-6 py-4">
+        <img src="<?= $post->actor
+            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+        <div class="flex flex-col min-w-0">
+            <a href="<?= $post->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $post
+    ->actor->is_local
+    ? ''
+    : 'target="_blank" rel="noopener noreferrer"' ?>>
+                <span class="mr-2 font-semibold truncate"><?= $post->actor
+                    ->display_name ?></span>
+                <span class="text-sm text-gray-500 truncate">@<?= $post->actor
+                    ->username .
+                    ($post->actor->is_local
+                        ? ''
+                        : '@' . $post->actor->domain) ?></span>
+            </a>
+            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
+            class="text-xs text-gray-500">
+                <?= relative_time($post->published_at) ?>
+            </a>
+        </div>
+    </header>
+    <div class="px-6 mb-4 post-content"><?= $post->message_html ?></div>
+    <?php if ($post->episode_id): ?>
+        <?= view('podcast/_partials/episode_preview_card', [
+            'episode' => $post->episode,
+        ]) ?>
+    <?php elseif ($post->has_preview_card): ?>
+        <?= view('podcast/_partials/preview_card', [
+            'preview_card' => $post->preview_card,
+        ]) ?>
+    <?php endif; ?>
+    <?= $this->include('podcast/_partials/post_actions_authenticated') ?>
+</article>
diff --git a/app/Views/podcast/_partials/status_with_replies.php b/app/Views/podcast/_partials/post_with_replies.php
similarity index 53%
rename from app/Views/podcast/_partials/status_with_replies.php
rename to app/Views/podcast/_partials/post_with_replies.php
index 5e10b01d03..f002d786de 100644
--- a/app/Views/podcast/_partials/status_with_replies.php
+++ b/app/Views/podcast/_partials/post_with_replies.php
@@ -1,10 +1,10 @@
-<?= $this->include('podcast/_partials/status') ?>
-<div class="-mt-2 overflow-hidden border-b border-l border-r status-replies rounded-b-xl">
+<?= $this->include('podcast/_partials/post') ?>
+<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">
 <?= anchor_popup(
-    route_to('status-remote-action', $podcast->handle, $status->id, 'reply'),
-    lang('Status.reply_to', ['actorUsername' => $status->actor->username]),
+    route_to('post-remote-action', $podcast->handle, $post->id, 'reply'),
+    lang('Post.reply_to', ['actorUsername' => $post->actor->username]),
     [
         'class' =>
             'text-center justify-center font-semibold rounded-full shadow relative z-10 px-4 py-2 w-full bg-rose-600 text-white inline-flex items-center hover:bg-rose-700',
@@ -15,8 +15,8 @@
 </div>
 
 
-<?php if ($status->has_replies): ?>
-    <?php foreach ($status->replies as $reply): ?>
+<?php if ($post->has_replies): ?>
+    <?php foreach ($post->replies as $reply): ?>
         <?= view('podcast/_partials/reply', ['reply' => $reply]) ?>
     <?php endforeach; ?>
 <?php endif; ?>
diff --git a/app/Views/podcast/_partials/status_with_replies_authenticated.php b/app/Views/podcast/_partials/post_with_replies_authenticated.php
similarity index 65%
rename from app/Views/podcast/_partials/status_with_replies_authenticated.php
rename to app/Views/podcast/_partials/post_with_replies_authenticated.php
index eb6d330817..4b71fe45bb 100644
--- a/app/Views/podcast/_partials/status_with_replies_authenticated.php
+++ b/app/Views/podcast/_partials/post_with_replies_authenticated.php
@@ -1,7 +1,7 @@
-<?= $this->include('podcast/_partials/status_authenticated') ?>
-<div class="-mt-2 overflow-hidden border-b border-l border-r status-replies rounded-b-xl">
+<?= $this->include('podcast/_partials/post_authenticated') ?>
+<div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl">
 <?= form_open(
-    route_to('status-attempt-action', interact_as_actor()->username, $status->id),
+    route_to('post-attempt-action', interact_as_actor()->username, $post->id),
     [
         'class' => 'bg-gray-50 flex px-6 pt-8 pb-4',
     ],
@@ -16,8 +16,8 @@
         'name' => 'message',
         'class' => 'form-textarea mb-4 w-full',
         'required' => 'required',
-        'placeholder' => lang('Status.form.reply_to_placeholder', [
-            'actorUsername' => $status->actor->username,
+        'placeholder' => lang('Post.form.reply_to_placeholder', [
+            'actorUsername' => $post->actor->username,
         ]),
     ],
     old('message', '', false),
@@ -26,7 +26,7 @@
     ],
 ) ?>
 <?= button(
-    lang('Status.form.submit_reply'),
+    lang('Post.form.submit_reply'),
     '',
     ['variant' => 'primary', 'size' => 'small'],
     [
@@ -39,8 +39,8 @@
 </div>
 <?= form_close() ?>
 
-<?php if ($status->has_replies): ?>
-    <?php foreach ($status->replies as $reply): ?>
+<?php if ($post->has_replies): ?>
+    <?php foreach ($post->replies as $reply): ?>
         <?= view('podcast/_partials/reply_authenticated', [
             'reply' => $reply,
         ]) ?>
diff --git a/app/Views/podcast/_partials/reblog.php b/app/Views/podcast/_partials/reblog.php
index 2abc307e99..84f3b782c5 100644
--- a/app/Views/podcast/_partials/reblog.php
+++ b/app/Views/podcast/_partials/reblog.php
@@ -1,43 +1,43 @@
-<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
+<article class="relative z-10 w-full bg-white shadow rounded-2xl">
     <p class="inline-flex px-6 pt-4 text-xs text-gray-700"><?= icon(
         'repeat',
         'text-lg mr-2 text-gray-400',
     ) .
-        lang('Status.actor_shared', [
-            'actor' => $status->actor->display_name,
+        lang('Post.actor_shared', [
+            'actor' => $post->actor->display_name,
         ]) ?></p>
     <header class="flex px-6 py-4">
-        <img src="<?= $status->actor
-            ->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+        <img src="<?= $post->actor
+            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
         <div class="flex flex-col min-w-0">
-            <a href="<?= $status->actor
-                ->uri ?>" class="flex items-baseline hover:underline" <?= $status
+            <a href="<?= $post->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $post
     ->actor->is_local
     ? ''
     : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $status->actor
+                <span class="mr-2 font-semibold truncate"><?= $post->actor
                     ->display_name ?></span>
-                <span class="text-sm text-gray-500 truncate">@<?= $status->actor
+                <span class="text-sm text-gray-500 truncate">@<?= $post->actor
                     ->username .
-                    ($status->actor->is_local
+                    ($post->actor->is_local
                         ? ''
-                        : '@' . $status->actor->domain) ?></span>
+                        : '@' . $post->actor->domain) ?></span>
             </a>
-            <a href="<?= route_to('status', $podcast->handle, $status->id) ?>"
+            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
             class="text-xs text-gray-500">
-                <?= relative_time($status->published_at) ?>
+                <?= relative_time($post->published_at) ?>
             </a>
         </div>
     </header>
-    <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
-    <?php if ($status->episode_id): ?>
+    <div class="px-6 mb-4 post-content"><?= $post->message_html ?></div>
+    <?php if ($post->episode_id): ?>
         <?= view('podcast/_partials/episode_preview_card', [
-            'episode' => $status->episode,
+            'episode' => $post->episode,
         ]) ?>
-    <?php elseif ($status->has_preview_card): ?>
+    <?php elseif ($post->has_preview_card): ?>
         <?= view('podcast/_partials/preview_card', [
-            'preview_card' => $status->preview_card,
+            'preview_card' => $post->preview_card,
         ]) ?>
     <?php endif; ?>
-    <?= $this->include('podcast/_partials/status_actions') ?>
+    <?= $this->include('podcast/_partials/post_actions') ?>
 </article>
diff --git a/app/Views/podcast/_partials/reblog_authenticated.php b/app/Views/podcast/_partials/reblog_authenticated.php
index 11c5d3012e..9defed3cbe 100644
--- a/app/Views/podcast/_partials/reblog_authenticated.php
+++ b/app/Views/podcast/_partials/reblog_authenticated.php
@@ -1,43 +1,43 @@
-<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
+<article class="relative z-10 w-full bg-white shadow rounded-2xl">
     <p class="inline-flex px-6 pt-4 text-xs text-gray-700"><?= icon(
         'repeat',
         'text-lg mr-2 text-gray-400',
     ) .
-        lang('Status.actor_shared', [
-            'actor' => $status->actor->display_name,
+        lang('Post.actor_shared', [
+            'actor' => $post->actor->display_name,
         ]) ?></p>
     <header class="flex px-6 py-4">
-        <img src="<?= $status->actor
-            ->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+        <img src="<?= $post->actor
+            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
         <div class="flex flex-col min-w-0">
-            <a href="<?= $status->actor
-                ->uri ?>" class="flex items-baseline hover:underline" <?= $status
+            <a href="<?= $post->actor
+                ->uri ?>" class="flex items-baseline hover:underline" <?= $post
     ->actor->is_local
     ? ''
     : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $status->actor
+                <span class="mr-2 font-semibold truncate"><?= $post->actor
                     ->display_name ?></span>
-                <span class="text-sm text-gray-500 truncate">@<?= $status->actor
+                <span class="text-sm text-gray-500 truncate">@<?= $post->actor
                     ->username .
-                    ($status->actor->is_local
+                    ($post->actor->is_local
                         ? ''
-                        : '@' . $status->actor->domain) ?></span>
+                        : '@' . $post->actor->domain) ?></span>
             </a>
-            <a href="<?= route_to('status', $podcast->handle, $status->id) ?>"
+            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
             class="text-xs text-gray-500">
-                <?= relative_time($status->published_at) ?>
+                <?= relative_time($post->published_at) ?>
             </a>
         </div>
     </header>
-    <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
-    <?php if ($status->episode_id): ?>
+    <div class="px-6 mb-4 post-content"><?= $post->message_html ?></div>
+    <?php if ($post->episode_id): ?>
         <?= view('podcast/_partials/episode_preview_card', [
-            'episode' => $status->episode,
+            'episode' => $post->episode,
         ]) ?>
-    <?php elseif ($status->has_preview_card): ?>
+    <?php elseif ($post->has_preview_card): ?>
         <?= view('podcast/_partials/preview_card', [
-            'preview_card' => $status->preview_card,
+            'preview_card' => $post->preview_card,
         ]) ?>
     <?php endif; ?>
-    <?= $this->include('podcast/_partials/status_actions_authenticated') ?>
+    <?= $this->include('podcast/_partials/post_actions_authenticated') ?>
 </article>
diff --git a/app/Views/podcast/_partials/reply.php b/app/Views/podcast/_partials/reply.php
index 12977a3608..7d672725ed 100644
--- a/app/Views/podcast/_partials/reply.php
+++ b/app/Views/podcast/_partials/reply.php
@@ -11,9 +11,9 @@
     ->display_name ?><span class="ml-1 text-sm font-normal text-gray-600">@<?= $reply
     ->actor->username .
     ($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
-            <?= relative_time($status->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?>
+            <?= relative_time($post->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?>
         </header>
-        <p class="mb-2 status-content"><?= $reply->message_html ?></p>
+        <p class="mb-2 post-content"><?= $reply->message_html ?></p>
         <?php if ($reply->has_preview_card): ?>
             <?= view('podcast/_partials/preview_card', [
                 'preview_card' => $reply->preview_card,
diff --git a/app/Views/podcast/_partials/reply_actions.php b/app/Views/podcast/_partials/reply_actions.php
index 0445f45499..6bdb11178b 100644
--- a/app/Views/podcast/_partials/reply_actions.php
+++ b/app/Views/podcast/_partials/reply_actions.php
@@ -1,34 +1,34 @@
 <footer class="mt-2 space-x-6 text-sm">
     <?= anchor(
-        route_to('status', $podcast->handle, $reply->id),
+        route_to('post', $podcast->handle, $reply->id),
         icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count,
         [
             'class' => 'inline-flex items-center hover:underline',
-            'title' => lang('Status.replies', [
+            'title' => lang('Post.replies', [
                 'numberOfReplies' => $reply->replies_count,
             ]),
         ],
     ) ?>
     <?= anchor_popup(
-        route_to('status-remote-action', $podcast->handle, $reply->id, 'reblog'),
+        route_to('post-remote-action', $podcast->handle, $reply->id, 'reblog'),
         icon('repeat', 'text-xl mr-1 text-gray-400') . $reply->reblogs_count,
         [
             'class' => 'inline-flex items-center hover:underline',
             'width' => 420,
             'height' => 620,
-            'title' => lang('Status.reblogs', [
+            'title' => lang('Post.reblogs', [
                 'numberOfReblogs' => $reply->reblogs_count,
             ]),
         ],
     ) ?>
     <?= anchor_popup(
-        route_to('status-remote-action', $podcast->handle, $reply->id, 'favourite'),
+        route_to('post-remote-action', $podcast->handle, $reply->id, 'favourite'),
         icon('heart', 'text-xl mr-1 text-gray-400') . $reply->favourites_count,
         [
             'class' => 'inline-flex items-center hover:underline',
             'width' => 420,
             'height' => 620,
-            'title' => lang('Status.favourites', [
+            'title' => lang('Post.favourites', [
                 'numberOfFavourites' => $reply->favourites_count,
             ]),
         ],
diff --git a/app/Views/podcast/_partials/reply_actions_authenticated.php b/app/Views/podcast/_partials/reply_actions_authenticated.php
index f876b85a96..249eb34afe 100644
--- a/app/Views/podcast/_partials/reply_actions_authenticated.php
+++ b/app/Views/podcast/_partials/reply_actions_authenticated.php
@@ -1,29 +1,29 @@
 <footer class="mt-2 text-sm">
     <form action="<?= route_to(
-        'status-attempt-action',
+        'post-attempt-action',
         interact_as_actor()->username,
         $reply->id,
     ) ?>" method="POST" class="flex items-start">
         <?= csrf_field() ?>
         <?= anchor(
-            route_to('status', $podcast->handle, $reply->id),
+            route_to('post', $podcast->handle, $reply->id),
             icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count,
             [
                 'class' => 'inline-flex items-center mr-6 hover:underline',
-                'title' => lang('Status.replies', [
+                '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(
-            'Status.reblogs',
+            'Post.reblogs',
             [
                 'numberOfReblogs' => $reply->reblogs_count,
             ],
         ) ?>"><?= icon('repeat', 'text-xl 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(
-            'Status.favourites',
+            'Post.favourites',
             [
                 'numberOfFavourites' => $reply->favourites_count,
             ],
@@ -40,33 +40,33 @@
         '-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm bg-white border rounded-lg shadow" aria-labelledby="<?= $reply->id .
     '-more-dropdown' ?>" data-dropdown="menu" data-dropdown-placement="bottom">
         <?= anchor(
-            route_to('status', $podcast->handle, $reply->id),
-            lang('Status.expand'),
+            route_to('post', $podcast->handle, $reply->id),
+            lang('Post.expand'),
             [
                 'class' => 'px-4 py-1 hover:bg-gray-100',
             ],
         ) ?>
         <form action="<?= route_to(
-            'status-attempt-block-actor',
+            'post-attempt-block-actor',
             interact_as_actor()->username,
             $reply->id,
         ) ?>" method="POST">
             <?= csrf_field() ?>
             <button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
-                'Status.block_actor',
+                'Post.block_actor',
                 [
                     'actorUsername' => $reply->actor->username,
                 ],
             ) ?></button>
         </form>
         <form action="<?= route_to(
-            'status-attempt-block-domain',
+            'post-attempt-block-domain',
             interact_as_actor()->username,
             $reply->id,
         ) ?>" method="POST">
             <?= csrf_field() ?>
             <button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
-                'Status.block_domain',
+                'Post.block_domain',
                 [
                     'actorDomain' => $reply->actor->domain,
                 ],
@@ -75,13 +75,13 @@
         <?php if ($reply->actor->is_local): ?>
             <hr class="my-2" />
             <form action="<?= route_to(
-                'status-attempt-delete',
+                'post-attempt-delete',
                 $reply->actor->username,
                 $reply->id,
             ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 font-semibold text-left text-red-600 hover:bg-gray-100"><?= lang(
-                    'Status.delete',
+                    'Post.delete',
                 ) ?></button>
             </form>
         <?php endif; ?>
diff --git a/app/Views/podcast/_partials/reply_authenticated.php b/app/Views/podcast/_partials/reply_authenticated.php
index 1d85461cc9..ff154acd54 100644
--- a/app/Views/podcast/_partials/reply_authenticated.php
+++ b/app/Views/podcast/_partials/reply_authenticated.php
@@ -11,9 +11,9 @@
     ->display_name ?><span class="ml-1 text-sm font-normal text-gray-600">@<?= $reply
     ->actor->username .
     ($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
-            <?= relative_time($status->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?>
+            <?= relative_time($post->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?>
         </header>
-        <p class="mb-2 status-content"><?= $reply->message_html ?></p>
+        <p class="mb-2 post-content"><?= $reply->message_html ?></p>
         <?php if ($reply->has_preview_card): ?>
             <?= view('podcast/_partials/preview_card', [
                 'preview_card' => $reply->preview_card,
diff --git a/app/Views/podcast/_partials/status.php b/app/Views/podcast/_partials/status.php
deleted file mode 100644
index 21d3d0807c..0000000000
--- a/app/Views/podcast/_partials/status.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<article class="relative z-10 w-full bg-white shadow rounded-2xl">
-    <header class="flex px-6 py-4">
-        <img src="<?= $status->actor
-            ->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
-        <div class="flex flex-col min-w-0">
-            <a href="<?= $status->actor
-                ->uri ?>" class="flex items-baseline hover:underline" <?= $status
-    ->actor->is_local
-    ? ''
-    : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $status->actor
-                    ->display_name ?></span>
-                <span class="text-sm text-gray-500 truncate">@<?= $status->actor
-                    ->username .
-                    ($status->actor->is_local
-                        ? ''
-                        : '@' . $status->actor->domain) ?></span>
-            </a>
-            <a href="<?= route_to('status', $podcast->handle, $status->id) ?>"
-            class="text-xs text-gray-500">
-                <?= relative_time($status->published_at) ?>
-            </a>
-        </div>
-    </header>
-    <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
-    <?php if ($status->episode_id): ?>
-        <?= view('podcast/_partials/episode_preview_card', [
-            'episode' => $status->episode,
-        ]) ?>
-    <?php elseif ($status->has_preview_card): ?>
-        <?= view('podcast/_partials/preview_card', [
-            'preview_card' => $status->preview_card,
-        ]) ?>
-    <?php endif; ?>
-    <?= $this->include('podcast/_partials/status_actions') ?>
-</article>
diff --git a/app/Views/podcast/_partials/status_actions.php b/app/Views/podcast/_partials/status_actions.php
deleted file mode 100644
index 36d7d9e7c2..0000000000
--- a/app/Views/podcast/_partials/status_actions.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<footer class="flex justify-around px-6 py-3">
-    <?= anchor(
-        route_to('status', $podcast->handle, $status->id),
-        icon('chat', 'text-2xl mr-1 text-gray-400') . $status->replies_count,
-        [
-            'class' => 'inline-flex items-center hover:underline',
-            'title' => lang('Status.replies', [
-                'numberOfReplies' => $status->replies_count,
-            ]),
-        ],
-    ) ?>
-    <?= anchor_popup(
-        route_to('status-remote-action', $podcast->handle, $status->id, 'reblog'),
-        icon('repeat', 'text-2xl mr-1 text-gray-400') . $status->reblogs_count,
-        [
-            'class' => 'inline-flex items-center hover:underline',
-            'width' => 420,
-            'height' => 620,
-            'title' => lang('Status.reblogs', [
-                'numberOfReblogs' => $status->reblogs_count,
-            ]),
-        ],
-    ) ?>
-    <?= anchor_popup(
-        route_to('status-remote-action', $podcast->handle, $status->id, 'favourite'),
-        icon('heart', 'text-2xl mr-1 text-gray-400') . $status->favourites_count,
-        [
-            'class' => 'inline-flex items-center hover:underline',
-            'width' => 420,
-            'height' => 620,
-            'title' => lang('Status.favourites', [
-                'numberOfFavourites' => $status->favourites_count,
-            ]),
-        ],
-    ) ?>
-</footer>
diff --git a/app/Views/podcast/_partials/status_authenticated.php b/app/Views/podcast/_partials/status_authenticated.php
deleted file mode 100644
index 143be143fc..0000000000
--- a/app/Views/podcast/_partials/status_authenticated.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
-    <header class="flex px-6 py-4">
-        <img src="<?= $status->actor
-            ->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
-        <div class="flex flex-col min-w-0">
-            <a href="<?= $status->actor
-                ->uri ?>" class="flex items-baseline hover:underline" <?= $status
-    ->actor->is_local
-    ? ''
-    : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $status->actor
-                    ->display_name ?></span>
-                <span class="text-sm text-gray-500 truncate">@<?= $status->actor
-                    ->username .
-                    ($status->actor->is_local
-                        ? ''
-                        : '@' . $status->actor->domain) ?></span>
-            </a>
-            <a href="<?= route_to('status', $podcast->handle, $status->id) ?>"
-            class="text-xs text-gray-500">
-                <?= relative_time($status->published_at) ?>
-            </a>
-        </div>
-    </header>
-    <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
-    <?php if ($status->episode_id): ?>
-        <?= view('podcast/_partials/episode_preview_card', [
-            'episode' => $status->episode,
-        ]) ?>
-    <?php elseif ($status->has_preview_card): ?>
-        <?= view('podcast/_partials/preview_card', [
-            'preview_card' => $status->preview_card,
-        ]) ?>
-    <?php endif; ?>
-    <?= $this->include('podcast/_partials/status_actions_authenticated') ?>
-</article>
diff --git a/app/Views/podcast/activity.php b/app/Views/podcast/activity.php
index 75bdbee563..11959f914c 100644
--- a/app/Views/podcast/activity.php
+++ b/app/Views/podcast/activity.php
@@ -40,13 +40,13 @@
 </nav>
 
 <section class="max-w-2xl px-6 py-8 mx-auto space-y-8">
-<?php foreach ($statuses as $status): ?>
-    <?php if ($status->reblog_of_id !== null): ?>
+<?php foreach ($posts as $post): ?>
+    <?php if ($post->reblog_of_id !== null): ?>
         <?= view('podcast/_partials/reblog', [
-            'status' => $status->reblog_of_status,
+            'post' => $post->reblog_of_post,
         ]) ?>
     <?php else: ?>
-        <?= view('podcast/_partials/status', ['status' => $status]) ?>
+        <?= view('podcast/_partials/post', ['post' => $post]) ?>
     <?php endif; ?>
 <?php endforeach; ?>
 </section>
diff --git a/app/Views/podcast/activity_authenticated.php b/app/Views/podcast/activity_authenticated.php
index d8404171a1..2042857073 100644
--- a/app/Views/podcast/activity_authenticated.php
+++ b/app/Views/podcast/activity_authenticated.php
@@ -40,7 +40,7 @@
 </nav>
 
 <section class="max-w-2xl px-6 py-8 mx-auto">
-<?= form_open(route_to('status-attempt-create', interact_as_actor()->username), [
+<?= form_open(route_to('post-attempt-create', interact_as_actor()->username), [
     'class' => 'flex p-4 bg-white shadow rounded-xl',
 ]) ?>
     <?= csrf_field() ?>
@@ -57,7 +57,7 @@
                 'name' => 'message',
                 'class' => 'form-textarea',
                 'required' => 'required',
-                'placeholder' => lang('Status.form.message_placeholder'),
+                'placeholder' => lang('Post.form.message_placeholder'),
             ],
             old('message', '', false),
             ['rows' => 2],
@@ -67,7 +67,7 @@
             'name' => 'episode_url',
             'class' => 'form-input mb-2',
             'placeholder' =>
-                lang('Status.form.episode_url_placeholder') .
+                lang('Post.form.episode_url_placeholder') .
                 ' (' .
                 lang('Common.optional') .
                 ')',
@@ -75,7 +75,7 @@
         ]) ?>
 
         <?= button(
-            lang('Status.form.submit'),
+            lang('Post.form.submit'),
             '',
             ['variant' => 'primary', 'size' => 'small'],
             ['type' => 'submit', 'class' => 'self-end'],
@@ -85,13 +85,13 @@
 <hr class="my-4 border-2 border-pine-100">
 
 <div class="space-y-8">
-<?php foreach ($statuses as $status): ?>
-    <?php if ($status->reblog_of_id !== null): ?>
+<?php foreach ($posts as $post): ?>
+    <?php if ($post->reblog_of_id !== null): ?>
         <?= view('podcast/_partials/reblog_authenticated', [
-            'status' => $status->reblog_of_status,
+            'post' => $post->reblog_of_post,
         ]) ?>
     <?php else: ?>
-        <?= view('podcast/_partials/status_authenticated', ['status' => $status]) ?>
+        <?= view('podcast/_partials/post_authenticated', ['post' => $post]) ?>
     <?php endif; ?>
 <?php endforeach; ?>
 </div>
diff --git a/app/Views/podcast/episode.php b/app/Views/podcast/episode.php
index 5d7fb5550e..b95c2249b4 100644
--- a/app/Views/podcast/episode.php
+++ b/app/Views/podcast/episode.php
@@ -65,46 +65,6 @@
                         <?= format_duration($episode->audio_file_duration) ?>
                     </time>
                 </div>
-                <div class="mb-2 space-x-4 text-sm">
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('chat', 'text-xl mr-1 text-gray-400') .
-                            $episode->statuses_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_statuses', [
-                                'numberOfTotalStatuses' => $episode->statuses_total,
-                            ]),
-                        ],
-                    ) ?>
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('repeat', 'text-xl mr-1 text-gray-400') .
-                            $episode->reblogs_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_reblogs', [
-                                'numberOfTotalReblogs' =>
-                                    $episode->reblogs_total,
-                            ]),
-                        ],
-                    ) ?>
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('heart', 'text-xl mr-1 text-gray-400') .
-                            $episode->favourites_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_favourites', [
-                                'numberOfTotalFavourites' =>
-                                    $episode->favourites_total,
-                            ]),
-                        ],
-                    ) ?>
-                </div>
                 <?= location_link($episode->location, 'text-sm mb-4') ?>
                 <?= person_list($episode->persons) ?>
                 <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype) ?>
@@ -113,27 +73,26 @@
     </header>
 
     <div class="tabset">
-        <?php if ($episode->statuses): ?>
-
-            <input type="radio" name="tabset" id="activity" aria-controls="activity" checked="checked" />
-            <label for="activity"><?= lang('Episode.activity') ?></label>
-        <?php endif; ?>
+        <input type="radio" name="tabset" id="comments" aria-controls="comments" checked="checked" />
+        <label for="comments"><?= lang('Episode.comments') . ' (' . $episode->comments_count . ')' ?></label>
+        
+        <input type="radio" name="tabset" id="activity" aria-controls="activity" />
+        <label for="activity"><?= lang('Episode.activity') . ' (' . $episode->posts_count . ')' ?></label>
 
-        <input type="radio" name="tabset" id="description" aria-controls="description" <?= $episode->statuses
-            ? ''
-            : 'checked="checked"' ?> />
-        <label for="description" class="<?= $episode->statuses
-            ? ''
-            : 'col-span-2' ?>"><?= lang('Episode.description') ?></label>
+        <input type="radio" name="tabset" id="description" aria-controls="description" />
+        <label for="description"><?= lang('Episode.description') ?></label>
 
         <div class="tab-panels">
-            <?php if ($episode->statuses): ?>
-                <section id="activity" class="space-y-8 tab-panel">
-                    <?php foreach ($episode->statuses as $status): ?>
-                        <?= view('podcast/_partials/status', ['status' => $status]) ?>
-                    <?php endforeach; ?>
-                </section>
-            <?php endif; ?>
+            <section id="comments" class="space-y-6 tab-panel">
+                <?php foreach ($episode->comments as $comment): ?>
+                    <?= view('podcast/_partials/comment', ['comment' => $comment]) ?>
+                <?php endforeach; ?>
+            </section>
+            <section id="activity" class="space-y-8 tab-panel">
+                <?php foreach ($episode->posts as $post): ?>
+                    <?= view('podcast/_partials/post', ['post' => $post]) ?>
+                <?php endforeach; ?>
+            </section>
             <section id="description" class="prose tab-panel">
                 <?= $episode->getDescriptionHtml('-+Website+-') ?>
             </section>
diff --git a/app/Views/podcast/episode_authenticated.php b/app/Views/podcast/episode_authenticated.php
index 743230cce4..b62bb0ada6 100644
--- a/app/Views/podcast/episode_authenticated.php
+++ b/app/Views/podcast/episode_authenticated.php
@@ -65,46 +65,6 @@
                         <?= format_duration($episode->audio_file_duration) ?>
                     </time>
                 </div>
-                <div class="mb-2 space-x-4 text-sm">
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('chat', 'text-xl mr-1 text-gray-400') .
-                            $episode->statuses_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_statuses', [
-                                'numberOfTotalStatuses' => $episode->statuses_total,
-                            ]),
-                        ],
-                    ) ?>
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('repeat', 'text-xl mr-1 text-gray-400') .
-                            $episode->reblogs_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_reblogs', [
-                                'numberOfTotalReblogs' =>
-                                    $episode->reblogs_total,
-                            ]),
-                        ],
-                    ) ?>
-                    <?= anchor(
-                        route_to('episode', $podcast->handle, $episode->slug),
-                        icon('heart', 'text-xl mr-1 text-gray-400') .
-                            $episode->favourites_total,
-                        [
-                            'class' =>
-                                'inline-flex items-center hover:underline',
-                            'title' => lang('Episode.total_favourites', [
-                                'numberOfTotalFavourites' =>
-                                    $episode->favourites_total,
-                            ]),
-                        ],
-                    ) ?>
-                </div>
                 <?= location_link($episode->location, 'text-sm mb-4') ?>
                 <?= person_list($episode->persons) ?>
                 <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype) ?>
@@ -113,15 +73,58 @@
     </header>
 
     <div class="tabset">
-        <input type="radio" name="tabset" id="activity" aria-controls="activity" checked="checked" />
-        <label for="activity"><?= lang('Episode.activity') ?></label>
+        <input type="radio" name="tabset" id="comments" aria-controls="comments" checked="checked" />
+        <label for="comments"><?= lang('Episode.comments') . ' (' . $episode->comments_count . ')' ?></label>
+        
+        <input type="radio" name="tabset" id="activity" aria-controls="activity" />
+        <label for="activity"><?= lang('Episode.activity') . ' ('. $episode->posts_count .')' ?></label>
 
         <input type="radio" name="tabset" id="description" aria-controls="description" />
         <label for="description"><?= lang('Episode.description') ?></label>
 
         <div class="tab-panels">
+            <section id="comments" class="space-y-6 tab-panel">
+            <?= form_open(route_to('comment-attempt-create', $podcast->id, $episode->id), [
+                    'class' => 'flex p-4 bg-white shadow rounded-xl',
+                ]) ?>
+                <?= csrf_field() ?>
+
+                <?= view('_message_block') ?>
+
+                <img src="<?= interact_as_actor()
+                    ->avatar_image_url ?>" alt="<?= interact_as_actor()->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+                <div class="flex flex-col flex-1 min-w-0">
+                    <?= form_textarea(
+                        [
+                            'id' => 'message',
+                            'name' => 'message',
+                            'class' => 'form-textarea mb-2',
+                            'required' => 'required',
+                            'placeholder' => lang(
+                                'Comment.form.episode_message_placeholder',
+                            ),
+                        ],
+                        old('message', '', false),
+                        [
+                            'rows' => 2,
+                        ],
+                    ) ?>
+
+                    <?= button(
+                        lang('Comment.form.submit'),
+                        '',
+                        ['variant' => 'primary', 'size' => 'small'],
+                        ['type' => 'submit', 'class' => 'self-end'],
+                    ) ?>
+                </div>
+                <?= form_close() ?>
+                <hr class="my-4 border border-pine-100">
+                <?php foreach ($episode->comments as $comment): ?>
+                    <?= view('podcast/_partials/comment', ['comment' => $comment]) ?>
+                <?php endforeach; ?>
+            </section>
             <section id="activity" class="space-y-8 tab-panel">
-                <?= form_open(route_to('status-attempt-create', $podcast->handle), [
+                <?= form_open(route_to('post-attempt-create', $podcast->handle), [
                     'class' => 'flex p-4 bg-white shadow rounded-xl',
                 ]) ?>
                 <?= csrf_field() ?>
@@ -129,8 +132,7 @@
                 <?= view('_message_block') ?>
 
                 <img src="<?= interact_as_actor()
-                    ->avatar_image_url ?>" alt="<?= interact_as_actor()
-    ->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
+                    ->avatar_image_url ?>" alt="<?= interact_as_actor()->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
                 <div class="flex flex-col flex-1 min-w-0">
                     <?= form_textarea(
                         [
@@ -139,7 +141,7 @@
                             'class' => 'form-textarea mb-2',
                             'required' => 'required',
                             'placeholder' => lang(
-                                'Status.form.episode_message_placeholder',
+                                'Post.form.episode_message_placeholder',
                             ),
                         ],
                         old('message', '', false),
@@ -154,7 +156,7 @@
                         'type' => 'hidden',
                     ]) ?>
                     <?= button(
-                        lang('Status.form.submit'),
+                        lang('Post.form.submit'),
                         '',
                         ['variant' => 'primary', 'size' => 'small'],
                         ['type' => 'submit', 'class' => 'self-end'],
@@ -162,9 +164,9 @@
                 </div>
                 <?= form_close() ?>
                 <hr class="my-4 border border-pine-100">
-                <?php foreach ($episode->statuses as $status): ?>
-                    <?= view('podcast/_partials/status_authenticated', [
-                        'status' => $status,
+                <?php foreach ($episode->posts as $post): ?>
+                    <?= view('podcast/_partials/post_authenticated', [
+                        'post' => $post,
                     ]) ?>
                 <?php endforeach; ?>
             </section>
diff --git a/app/Views/podcast/post.php b/app/Views/podcast/post.php
new file mode 100644
index 0000000000..45f75cc2bb
--- /dev/null
+++ b/app/Views/podcast/post.php
@@ -0,0 +1,38 @@
+<?= $this->extend('podcast/_layout') ?>
+
+<?= $this->section('meta-tags') ?>
+    <title><?= lang('Post.title', [
+        'actorDisplayName' => $post->actor->display_name,
+    ]) ?></title>
+    <meta name="description" content="<?= $post->message ?>"/>
+    <meta property="og:title" content="<?= lang('Post.title', [
+        'actorDisplayName' => $post->actor->display_name,
+    ]) ?>"/>
+    <meta property="og:locale" content="<?= service(
+        'request',
+    )->getLocale() ?>" />
+    <meta property="og:site_name" content="<?= $post->actor->display_name ?>" />
+    <meta property="og:url" content="<?= current_url() ?>" />
+    <meta property="og:image" content="<?= $post->actor->avatar_image_url ?>" />
+    <meta property="og:description" content="<?= $post->message ?>" />
+<?= $this->endSection() ?>
+
+<?= $this->section('content') ?>
+<div class="max-w-2xl px-6 mx-auto">
+    <nav class="py-3">
+        <a href="<?= route_to('podcast-activity', $podcast->handle) ?>"
+        class="inline-flex items-center px-4 py-2 text-sm"><?= icon(
+            'arrow-left',
+            'mr-2 text-lg',
+        ) .
+            lang('Post.back_to_actor_posts', [
+                'actor' => $post->actor->display_name,
+            ]) ?></a>
+    </nav>
+    <div class="pb-12">
+        <?= $this->include('podcast/_partials/post_with_replies') ?>
+    </div>
+</div>
+
+<?= $this->endSection()
+?>
diff --git a/app/Views/podcast/status_authenticated.php b/app/Views/podcast/post_authenticated.php
similarity index 51%
rename from app/Views/podcast/status_authenticated.php
rename to app/Views/podcast/post_authenticated.php
index be5f418048..e2e3b95696 100644
--- a/app/Views/podcast/status_authenticated.php
+++ b/app/Views/podcast/post_authenticated.php
@@ -1,20 +1,20 @@
 <?= $this->extend('podcast/_layout_authenticated') ?>
 
 <?= $this->section('meta-tags') ?>
-    <title><?= lang('Status.title', [
-        'actorDisplayName' => $status->actor->display_name,
+    <title><?= lang('Post.title', [
+        'actorDisplayName' => $post->actor->display_name,
     ]) ?></title>
-    <meta name="description" content="<?= $status->message ?>"/>
-    <meta property="og:title" content="<?= lang('Status.title', [
-        'actorDisplayName' => $status->actor->display_name,
+    <meta name="description" content="<?= $post->message ?>"/>
+    <meta property="og:title" content="<?= lang('Post.title', [
+        'actorDisplayName' => $post->actor->display_name,
     ]) ?>"/>
     <meta property="og:locale" content="<?= service(
         'request',
     )->getLocale() ?>" />
-    <meta property="og:site_name" content="<?= $status->actor->display_name ?>" />
+    <meta property="og:site_name" content="<?= $post->actor->display_name ?>" />
     <meta property="og:url" content="<?= current_url() ?>" />
-    <meta property="og:image" content="<?= $status->actor->avatar_image_url ?>" />
-    <meta property="og:description" content="<?= $status->message ?>" />
+    <meta property="og:image" content="<?= $post->actor->avatar_image_url ?>" />
+    <meta property="og:description" content="<?= $post->message ?>" />
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
@@ -25,13 +25,13 @@
             'arrow-left',
             'mr-2 text-lg',
         ) .
-            lang('Status.back_to_actor_statuses', [
-                'actor' => $status->actor->display_name,
+            lang('Post.back_to_actor_posts', [
+                'actor' => $post->actor->display_name,
             ]) ?></a>
     </nav>
     <div class="pb-12">
         <?= $this->include(
-            'podcast/_partials/status_with_replies_authenticated',
+            'podcast/_partials/post_with_replies_authenticated',
         ) ?>
     </div>
 </div>
diff --git a/app/Views/podcast/status_remote_action.php b/app/Views/podcast/post_remote_action.php
similarity index 76%
rename from app/Views/podcast/status_remote_action.php
rename to app/Views/podcast/post_remote_action.php
index 5b3e5cd848..04a99bcc8b 100644
--- a/app/Views/podcast/status_remote_action.php
+++ b/app/Views/podcast/post_remote_action.php
@@ -7,22 +7,22 @@
     <link rel="shortcut icon" type="image/png" href="/favicon.ico" />
 
     <title><?= lang('ActivityPub.' . $action . '.title', [
-        'actorDisplayName' => $status->actor->display_name,
+        'actorDisplayName' => $post->actor->display_name,
     ]) ?></title>
-    <meta name="description" content="<?= $status->message ?>"/>
+    <meta name="description" content="<?= $post->message ?>"/>
     <meta property="og:title" content="<?= lang(
         'ActivityPub.' . $action . '.title',
         [
-            'actorDisplayName' => $status->actor->display_name,
+            'actorDisplayName' => $post->actor->display_name,
         ],
     ) ?>"/>
     <meta property="og:locale" content="<?= service(
         'request',
     )->getLocale() ?>" />
-    <meta property="og:site_name" content="<?= $status->actor->display_name ?>" />
+    <meta property="og:site_name" content="<?= $post->actor->display_name ?>" />
     <meta property="og:url" content="<?= current_url() ?>" />
-    <meta property="og:image" content="<?= $status->actor->avatar_image_url ?>" />
-    <meta property="og:description" content="<?= $status->message ?>" />
+    <meta property="og:image" content="<?= $post->actor->avatar_image_url ?>" />
+    <meta property="og:description" content="<?= $post->message ?>" />
 
     <?= service('vite')->asset('styles/index.css', 'css') ?>
     <?= service('vite')->asset('js/podcast.ts', 'js') ?>
@@ -35,10 +35,10 @@
         ) ?></h1>
     </header>
     <main class="flex-1 max-w-xl px-4 pb-8 mx-auto -mt-24">
-        <?= $this->include('podcast/_partials/status') ?>
+        <?= $this->include('podcast/_partials/post') ?>
 
         <?= form_open(
-            route_to('status-attempt-remote-action', $status->id, $action),
+            route_to('post-attempt-remote-action', $post->id, $action),
             ['method' => 'post', 'class' => 'flex flex-col mt-8'],
         ) ?>
         <?= csrf_field() ?>
diff --git a/app/Views/podcast/status.php b/app/Views/podcast/status.php
deleted file mode 100644
index 61c8352664..0000000000
--- a/app/Views/podcast/status.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?= $this->extend('podcast/_layout') ?>
-
-<?= $this->section('meta-tags') ?>
-    <title><?= lang('Status.title', [
-        'actorDisplayName' => $status->actor->display_name,
-    ]) ?></title>
-    <meta name="description" content="<?= $status->message ?>"/>
-    <meta property="og:title" content="<?= lang('Status.title', [
-        'actorDisplayName' => $status->actor->display_name,
-    ]) ?>"/>
-    <meta property="og:locale" content="<?= service(
-        'request',
-    )->getLocale() ?>" />
-    <meta property="og:site_name" content="<?= $status->actor->display_name ?>" />
-    <meta property="og:url" content="<?= current_url() ?>" />
-    <meta property="og:image" content="<?= $status->actor->avatar_image_url ?>" />
-    <meta property="og:description" content="<?= $status->message ?>" />
-<?= $this->endSection() ?>
-
-<?= $this->section('content') ?>
-<div class="max-w-2xl px-6 mx-auto">
-    <nav class="py-3">
-        <a href="<?= route_to('podcast-activity', $podcast->handle) ?>"
-        class="inline-flex items-center px-4 py-2 text-sm"><?= icon(
-            'arrow-left',
-            'mr-2 text-lg',
-        ) .
-            lang('Status.back_to_actor_statuses', [
-                'actor' => $status->actor->display_name,
-            ]) ?></a>
-    </nav>
-    <div class="pb-12">
-        <?= $this->include('podcast/_partials/status_with_replies') ?>
-    </div>
-</div>
-
-<?= $this->endSection()
-?>
-- 
GitLab