mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-19 13:01:19 +00:00
feat: add task to housekeeping setting for resetting all instance counts
set two toggle switches to run housekeeping tasks seperately if needed
This commit is contained in:
parent
e65e236bbc
commit
9303e51bc5
@ -22,7 +22,6 @@ use CodeIgniter\HTTP\URI;
|
||||
use CodeIgniter\I18n\Time;
|
||||
use Modules\Analytics\AnalyticsTrait;
|
||||
use Modules\Fediverse\Controllers\PostController as FediversePostController;
|
||||
use Modules\Fediverse\Entities\Post as FediversePost;
|
||||
use Modules\Fediverse\Models\FavouriteModel;
|
||||
|
||||
class PostController extends FediversePostController
|
||||
@ -33,6 +32,11 @@ class PostController extends FediversePostController
|
||||
|
||||
protected Actor $actor;
|
||||
|
||||
/**
|
||||
* @var CastopodPost
|
||||
*/
|
||||
protected $post;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
@ -53,6 +57,7 @@ class PostController extends FediversePostController
|
||||
count($params) > 1 &&
|
||||
($post = (new PostModel())->getPostById($params[1])) !== null
|
||||
) {
|
||||
/** @var CastopodPost $post */
|
||||
$this->post = $post;
|
||||
|
||||
unset($params[0]);
|
||||
@ -163,7 +168,7 @@ class PostController extends FediversePostController
|
||||
->with('errors', $this->validator->getErrors());
|
||||
}
|
||||
|
||||
$newPost = new FediversePost([
|
||||
$newPost = new CastopodPost([
|
||||
'actor_id' => interact_as_actor_id(),
|
||||
'in_reply_to_id' => $this->post->id,
|
||||
'message' => $this->request->getPost('message'),
|
||||
@ -171,6 +176,10 @@ class PostController extends FediversePostController
|
||||
'created_by' => user_id(),
|
||||
]);
|
||||
|
||||
if ($this->post->in_reply_to_id === null && $this->post->episode_id !== null) {
|
||||
$newPost->episode_id = $this->post->episode_id;
|
||||
}
|
||||
|
||||
$postModel = new PostModel();
|
||||
if (! $postModel->addReply($newPost)) {
|
||||
return redirect()
|
||||
|
@ -149,7 +149,10 @@ class EpisodeCommentModel extends UuidModel
|
||||
->whereIn('in_reply_to_id', function (BaseBuilder $builder) use (&$episodeId): BaseBuilder {
|
||||
return $builder->select('id')
|
||||
->from(config('Fediverse')->tablesPrefix . 'posts')
|
||||
->where('episode_id', $episodeId);
|
||||
->where([
|
||||
'episode_id' => $episodeId,
|
||||
'in_reply_to_id' => null,
|
||||
]);
|
||||
})
|
||||
->where('`created_at` <= NOW()', null, false)
|
||||
->getCompiledSelect();
|
||||
@ -179,6 +182,37 @@ class EpisodeCommentModel extends UuidModel
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function resetLikesCount(): int | false
|
||||
{
|
||||
$commentsLikesCount = $this->db->table('likes')
|
||||
->select('comment_id as id, COUNT(*) as `likes_count`')
|
||||
->groupBy('id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($commentsLikesCount !== []) {
|
||||
$this->uuidUseBytes = false;
|
||||
return $this->updateBatch($commentsLikesCount, 'id');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resetRepliesCount(): int | false
|
||||
{
|
||||
$commentsRepliesCount = $this->select('episode_comments.id, COUNT(*) as `replies_count`')
|
||||
->join('episode_comments as c2', 'episode_comments.id = c2.in_reply_to_id')
|
||||
->groupBy('episode_comments.id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($commentsRepliesCount !== []) {
|
||||
$this->uuidUseBytes = false;
|
||||
return $this->updateBatch($commentsRepliesCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, array<string|int, mixed>> $data
|
||||
* @return array<string, array<string|int, mixed>>
|
||||
|
@ -322,6 +322,58 @@ class EpisodeModel extends Model
|
||||
return $stats;
|
||||
}
|
||||
|
||||
public function resetCommentsCount(): int | false
|
||||
{
|
||||
$episodeCommentsCount = $this->select('episodes.id, COUNT(*) as `comments_count`')
|
||||
->join('episode_comments', 'episodes.id = episode_comments.episode_id')
|
||||
->where('in_reply_to_id', null)
|
||||
->groupBy('episodes.id')
|
||||
->getCompiledSelect();
|
||||
|
||||
$episodePostsRepliesCount = $this
|
||||
->select('episodes.id, COUNT(*) as `comments_count`')
|
||||
->join(
|
||||
config('Fediverse')
|
||||
->tablesPrefix . 'posts',
|
||||
'episodes.id = ' . config('Fediverse')->tablesPrefix . 'posts.episode_id'
|
||||
)
|
||||
->where('in_reply_to_id IS NOT', null)
|
||||
->groupBy('episodes.id')
|
||||
->getCompiledSelect();
|
||||
|
||||
$query = $this->db->query(
|
||||
'SELECT `id`, SUM(`comments_count`) as `comments_count` FROM (' . $episodeCommentsCount . ' UNION ALL ' . $episodePostsRepliesCount . ') x GROUP BY `id`'
|
||||
);
|
||||
|
||||
$countsPerEpisodeId = $query->getResultArray();
|
||||
|
||||
if ($countsPerEpisodeId !== []) {
|
||||
return $this->updateBatch($countsPerEpisodeId, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resetPostsCount(): int | false
|
||||
{
|
||||
$episodePostsCount = $this->select('episodes.id, COUNT(*) as `posts_count`')
|
||||
->join(
|
||||
config('Fediverse')
|
||||
->tablesPrefix . 'posts',
|
||||
'episodes.id = ' . config('Fediverse')->tablesPrefix . 'posts.episode_id'
|
||||
)
|
||||
->where('in_reply_to_id', null)
|
||||
->groupBy('episodes.id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($episodePostsCount !== []) {
|
||||
return $this->updateBatch($episodePostsCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $data
|
||||
*
|
||||
|
@ -49,8 +49,33 @@ class PostModel extends FediversePostModel
|
||||
return $this->where([
|
||||
'episode_id' => $episodeId,
|
||||
])
|
||||
->where('in_reply_to_id', null)
|
||||
->where('`published_at` <= NOW()', null, false)
|
||||
->orderBy('published_at', 'DESC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function setEpisodeIdForRepliesOfEpisodePosts(): int | false
|
||||
{
|
||||
// make sure that posts in reply to episode activities have an episode id
|
||||
$postsToUpdate = $this->db->table(config('Fediverse')->tablesPrefix . 'posts as p1')
|
||||
->join(config('Fediverse')->tablesPrefix . 'posts as p2', 'p1.id = p2.in_reply_to_id')
|
||||
->select('p2.id, p1.episode_id')
|
||||
->where([
|
||||
'p1.in_reply_to_id' => null,
|
||||
'p2.in_reply_to_id IS NOT' => null,
|
||||
'p2.episode_id' => null,
|
||||
'p1.episode_id IS NOT' => null,
|
||||
])
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($postsToUpdate !== []) {
|
||||
$postModel = new self();
|
||||
$postModel->uuidUseBytes = false;
|
||||
return $postModel->updateBatch($postsToUpdate, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace Modules\Admin\Controllers;
|
||||
|
||||
use App\Entities\Media\Image;
|
||||
use App\Models\ActorModel;
|
||||
use App\Models\EpisodeCommentModel;
|
||||
use App\Models\EpisodeModel;
|
||||
use App\Models\MediaModel;
|
||||
use App\Models\PersonModel;
|
||||
use App\Models\PodcastModel;
|
||||
use App\Models\PostModel;
|
||||
use CodeIgniter\Files\File;
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use PHP_ICO;
|
||||
@ -158,93 +160,112 @@ class SettingsController extends BaseController
|
||||
|
||||
public function runHousekeeping(): RedirectResponse
|
||||
{
|
||||
if ($this->request->getPost('reset_counts') === 'yes') {
|
||||
// recalculate fediverse counts
|
||||
(new ActorModel())->resetFollowersCount();
|
||||
(new ActorModel())->resetPostsCount();
|
||||
(new PostModel())->setEpisodeIdForRepliesOfEpisodePosts();
|
||||
(new PostModel())->resetFavouritesCount();
|
||||
(new PostModel())->resetReblogsCount();
|
||||
(new PostModel())->resetRepliesCount();
|
||||
(new EpisodeModel())->resetCommentsCount();
|
||||
(new EpisodeModel())->resetPostsCount();
|
||||
(new EpisodeCommentModel())->resetLikesCount();
|
||||
(new EpisodeCommentModel())->resetRepliesCount();
|
||||
}
|
||||
helper('media');
|
||||
|
||||
// Delete all podcast image sizes to recreate them
|
||||
$allPodcasts = (new PodcastModel())->findAll();
|
||||
foreach ($allPodcasts as $podcast) {
|
||||
$podcastImages = glob(media_path("/podcasts/{$podcast->handle}/*_*{jpg,png,webp}"), GLOB_BRACE);
|
||||
if ($this->request->getPost('rewrite_media') === 'yes') {
|
||||
|
||||
if ($podcastImages) {
|
||||
foreach ($podcastImages as $podcastImage) {
|
||||
if (is_file($podcastImage)) {
|
||||
unlink($podcastImage);
|
||||
// Delete all podcast image sizes to recreate them
|
||||
$allPodcasts = (new PodcastModel())->findAll();
|
||||
foreach ($allPodcasts as $podcast) {
|
||||
$podcastImages = glob(media_path("/podcasts/{$podcast->handle}/*_*{jpg,png,webp}"), GLOB_BRACE);
|
||||
|
||||
if ($podcastImages) {
|
||||
foreach ($podcastImages as $podcastImage) {
|
||||
if (is_file($podcastImage)) {
|
||||
unlink($podcastImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all person image sizes to recreate them
|
||||
$personsImages = glob(media_path('/persons/*_*{jpg,png,webp}'), GLOB_BRACE);
|
||||
if ($personsImages) {
|
||||
foreach ($personsImages as $personsImage) {
|
||||
if (is_file($personsImage)) {
|
||||
unlink($personsImage);
|
||||
// Delete all person image sizes to recreate them
|
||||
$personsImages = glob(media_path('/persons/*_*{jpg,png,webp}'), GLOB_BRACE);
|
||||
if ($personsImages) {
|
||||
foreach ($personsImages as $personsImage) {
|
||||
if (is_file($personsImage)) {
|
||||
unlink($personsImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$allImages = (new MediaModel('image'))->getAllOfType();
|
||||
foreach ($allImages as $image) {
|
||||
if (str_starts_with($image->file_path, 'podcasts')) {
|
||||
if (str_ends_with($image->file_path, 'banner.jpg') || str_ends_with($image->file_path, 'banner.png')) {
|
||||
$allImages = (new MediaModel('image'))->getAllOfType();
|
||||
foreach ($allImages as $image) {
|
||||
if (str_starts_with($image->file_path, 'podcasts')) {
|
||||
if (str_ends_with($image->file_path, 'banner.jpg') || str_ends_with(
|
||||
$image->file_path,
|
||||
'banner.png'
|
||||
)) {
|
||||
$image->sizes = config('Images')
|
||||
->podcastBannerSizes;
|
||||
} else {
|
||||
$image->sizes = config('Images')
|
||||
->podcastCoverSizes;
|
||||
}
|
||||
} elseif (str_starts_with($image->file_path, 'persons')) {
|
||||
$image->sizes = config('Images')
|
||||
->podcastBannerSizes;
|
||||
} else {
|
||||
$image->sizes = config('Images')
|
||||
->podcastCoverSizes;
|
||||
->personAvatarSizes;
|
||||
}
|
||||
} elseif (str_starts_with($image->file_path, 'persons')) {
|
||||
$image->sizes = config('Images')
|
||||
->personAvatarSizes;
|
||||
$image->setFile(new File(media_path($image->file_path)));
|
||||
|
||||
(new MediaModel('image'))->updateMedia($image);
|
||||
}
|
||||
$image->setFile(new File(media_path($image->file_path)));
|
||||
|
||||
(new MediaModel('image'))->updateMedia($image);
|
||||
}
|
||||
$allAudio = (new MediaModel('audio'))->getAllOfType();
|
||||
foreach ($allAudio as $audio) {
|
||||
$audio->setFile(new File(media_path($audio->file_path)));
|
||||
|
||||
$allAudio = (new MediaModel('audio'))->getAllOfType();
|
||||
foreach ($allAudio as $audio) {
|
||||
$audio->setFile(new File(media_path($audio->file_path)));
|
||||
(new MediaModel('audio'))->updateMedia($audio);
|
||||
}
|
||||
|
||||
(new MediaModel('audio'))->updateMedia($audio);
|
||||
}
|
||||
$allTranscripts = (new MediaModel('transcript'))->getAllOfType();
|
||||
foreach ($allTranscripts as $transcript) {
|
||||
$transcript->setFile(new File(media_path($transcript->file_path)));
|
||||
|
||||
$allTranscripts = (new MediaModel('transcript'))->getAllOfType();
|
||||
foreach ($allTranscripts as $transcript) {
|
||||
$transcript->setFile(new File(media_path($transcript->file_path)));
|
||||
(new MediaModel('transcript'))->updateMedia($transcript);
|
||||
}
|
||||
|
||||
(new MediaModel('transcript'))->updateMedia($transcript);
|
||||
}
|
||||
$allChapters = (new MediaModel('chapters'))->getAllOfType();
|
||||
foreach ($allChapters as $chapters) {
|
||||
$chapters->setFile(new File(media_path($chapters->file_path)));
|
||||
|
||||
$allChapters = (new MediaModel('chapters'))->getAllOfType();
|
||||
foreach ($allChapters as $chapters) {
|
||||
$chapters->setFile(new File(media_path($chapters->file_path)));
|
||||
(new MediaModel('chapters'))->updateMedia($chapters);
|
||||
}
|
||||
|
||||
(new MediaModel('chapters'))->updateMedia($chapters);
|
||||
}
|
||||
$allVideos = (new MediaModel('video'))->getAllOfType();
|
||||
foreach ($allVideos as $video) {
|
||||
$video->setFile(new File(media_path($video->file_path)));
|
||||
|
||||
$allVideos = (new MediaModel('video'))->getAllOfType();
|
||||
foreach ($allVideos as $video) {
|
||||
$video->setFile(new File(media_path($video->file_path)));
|
||||
(new MediaModel('video'))->updateMedia($video);
|
||||
}
|
||||
|
||||
(new MediaModel('video'))->updateMedia($video);
|
||||
}
|
||||
// reset avatar and banner image urls for each podcast actor
|
||||
foreach ($allPodcasts as $podcast) {
|
||||
$actorModel = new ActorModel();
|
||||
$actor = $actorModel->getActorById($podcast->actor_id);
|
||||
|
||||
// reset avatar and banner image urls for each podcast actor
|
||||
foreach ($allPodcasts as $podcast) {
|
||||
$actorModel = new ActorModel();
|
||||
$actor = $actorModel->getActorById($podcast->actor_id);
|
||||
if ($actor !== null) {
|
||||
// update values
|
||||
$actor->avatar_image_url = $podcast->cover->federation_url;
|
||||
$actor->avatar_image_mimetype = $podcast->cover->file_mimetype;
|
||||
$actor->cover_image_url = $podcast->banner->federation_url;
|
||||
$actor->cover_image_mimetype = $podcast->banner->file_mimetype;
|
||||
|
||||
if ($actor !== null) {
|
||||
// update values
|
||||
$actor->avatar_image_url = $podcast->cover->federation_url;
|
||||
$actor->avatar_image_mimetype = $podcast->cover->file_mimetype;
|
||||
$actor->cover_image_url = $podcast->banner->federation_url;
|
||||
$actor->cover_image_mimetype = $podcast->banner->file_mimetype;
|
||||
|
||||
if ($actor->hasChanged()) {
|
||||
$actorModel->update($actor->id, $actor);
|
||||
if ($actor->hasChanged()) {
|
||||
$actorModel->update($actor->id, $actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,11 @@ return [
|
||||
],
|
||||
'housekeeping' => [
|
||||
'title' => 'Housekeeping',
|
||||
'subtitle' => 'Runs various housekeeping tasks, such as rewriting media files metadata (images, audio files, transcripts, chapters, …).',
|
||||
'subtitle' => 'Runs various housekeeping tasks, such as resetting counts and rewriting media files metadata. This may take a while.',
|
||||
'reset_counts' => 'Reset counts',
|
||||
'reset_counts_helper' => 'This option will recalculate and reset all data counts (number of followers, posts, comments, …).',
|
||||
'rewrite_media' => 'Rewrite media metadata',
|
||||
'rewrite_media_helper' => 'This option will delete all superfluous media files and recreate them (images, audio files, transcripts, chapters, …)',
|
||||
'run' => 'Run housekeeping',
|
||||
'runSuccess' => 'Housekeeping has been run successfully!',
|
||||
],
|
||||
|
@ -31,6 +31,10 @@ return [
|
||||
'housekeeping' => [
|
||||
'title' => 'Ménage',
|
||||
'subtitle' => 'Exécute un nombre de tâches de nettoyage, comme la réécriture de métadonnées des fichiers media (images, fichiers audio, transcript, chapitres, …).',
|
||||
'reset_counts' => 'Réinitialiser les compteurs',
|
||||
'reset_counts_helper' => 'Cette option recalcul et réinitialise les compteurs de données (nombre d’abonné·e·s, de publications, de commentaires, …).',
|
||||
'rewrite_media' => 'Réécrire les métadonnées des fichiers média',
|
||||
'rewrite_media_helper' => 'Cette option supprimera tous les fichiers média superflus et les recréera (images, fichiers audio, transcripts, chapitrages, …)',
|
||||
'run' => 'Faire le ménage',
|
||||
'runSuccess' => 'Le ménage a été effectué avec succès !',
|
||||
],
|
||||
|
@ -28,7 +28,10 @@ class PostController extends Controller
|
||||
*/
|
||||
protected $helpers = ['fediverse'];
|
||||
|
||||
protected Post $post;
|
||||
/**
|
||||
* @var Post
|
||||
*/
|
||||
protected $post;
|
||||
|
||||
protected Fediverse $config;
|
||||
|
||||
|
@ -272,6 +272,47 @@ class ActorModel extends BaseModel
|
||||
return $found;
|
||||
}
|
||||
|
||||
public function resetFollowersCount(): int | false
|
||||
{
|
||||
$tablePrefix = config('Fediverse')
|
||||
->tablesPrefix;
|
||||
|
||||
$actorsFollowersCount = $this->db->table($tablePrefix . 'follows')->select(
|
||||
'target_actor_id as id, COUNT(*) as `followers_count`'
|
||||
)
|
||||
->groupBy('id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($actorsFollowersCount !== []) {
|
||||
return $this->updateBatch($actorsFollowersCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resetPostsCount(): int | false
|
||||
{
|
||||
$tablePrefix = config('Fediverse')
|
||||
->tablesPrefix;
|
||||
|
||||
$actorsFollowersCount = $this->db->table($tablePrefix . 'posts')->select(
|
||||
'actor_id as id, COUNT(*) as `posts_count`'
|
||||
)
|
||||
->where([
|
||||
'in_reply_to_id' => null,
|
||||
])
|
||||
->groupBy('actor_id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($actorsFollowersCount !== []) {
|
||||
return $this->updateBatch($actorsFollowersCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function clearCache(Actor $actor): void
|
||||
{
|
||||
$cachePrefix = config('Fediverse')
|
||||
|
@ -276,9 +276,12 @@ class PostModel extends BaseUuidModel
|
||||
}
|
||||
}
|
||||
|
||||
model('ActorModel', false)
|
||||
->where('id', $post->actor_id)
|
||||
->increment('posts_count');
|
||||
if ($post->in_reply_to_id === null) {
|
||||
// increment posts_count only if not reply
|
||||
model('ActorModel', false)
|
||||
->where('id', $post->actor_id)
|
||||
->increment('posts_count');
|
||||
}
|
||||
|
||||
if ($registerActivity) {
|
||||
// set post id and uri to construct NoteObject
|
||||
@ -619,6 +622,64 @@ class PostModel extends BaseUuidModel
|
||||
return $found;
|
||||
}
|
||||
|
||||
public function resetFavouritesCount(): int | false
|
||||
{
|
||||
$tablePrefix = config('Fediverse')
|
||||
->tablesPrefix;
|
||||
|
||||
$postsFavouritesCount = $this->db->table($tablePrefix . 'favourites')->select(
|
||||
'post_id as id, COUNT(*) as `favourites_count`'
|
||||
)
|
||||
->groupBy('id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($postsFavouritesCount !== []) {
|
||||
$this->uuidUseBytes = false;
|
||||
return $this->updateBatch($postsFavouritesCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resetReblogsCount(): int | false
|
||||
{
|
||||
$tablePrefix = config('Fediverse')
|
||||
->tablesPrefix;
|
||||
|
||||
$postsReblogsCount = $this->select($tablePrefix . 'posts.id, COUNT(*) as `replies_count`')
|
||||
->join($tablePrefix . 'posts as p2', $tablePrefix . 'posts.id = p2.reblog_of_id')
|
||||
->groupBy($tablePrefix . 'posts.id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($postsReblogsCount !== []) {
|
||||
$this->uuidUseBytes = false;
|
||||
return $this->updateBatch($postsReblogsCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resetRepliesCount(): int | false
|
||||
{
|
||||
$tablePrefix = config('Fediverse')
|
||||
->tablesPrefix;
|
||||
|
||||
$postsRepliesCount = $this->select($tablePrefix . 'posts.id, COUNT(*) as `replies_count`')
|
||||
->join($tablePrefix . 'posts as p2', $tablePrefix . 'posts.id = p2.in_reply_to_id')
|
||||
->groupBy($tablePrefix . 'posts.id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($postsRepliesCount !== []) {
|
||||
$this->uuidUseBytes = false;
|
||||
return $this->updateBatch($postsRepliesCount, 'id');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function clearCache(Post $post): void
|
||||
{
|
||||
$cachePrefix = config('Fediverse')
|
||||
|
@ -77,6 +77,9 @@
|
||||
title="<?= lang('Settings.housekeeping.title') ?>"
|
||||
subtitle="<?= lang('Settings.housekeeping.subtitle') ?>" >
|
||||
|
||||
<Forms.Toggler name="reset_counts" value="yes" size="small" checked="true" hint="<?= lang('Settings.housekeeping.reset_counts_helper') ?>"><?= lang('Settings.housekeeping.reset_counts') ?></Forms.Toggler>
|
||||
<Forms.Toggler name="rewrite_media" value="yes" size="small" checked="true" hint="<?= lang('Settings.housekeeping.rewrite_media_helper') ?>"><?= lang('Settings.housekeeping.rewrite_media') ?></Forms.Toggler>
|
||||
|
||||
<Button variant="primary" type="submit" iconLeft="home-gear"><?= lang('Settings.housekeeping.run') ?></Button>
|
||||
|
||||
</Forms.Section>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<footer>
|
||||
<?php if (can_user_interact()): ?>
|
||||
<form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $comment->episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $comment->episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
|
||||
'Comment.likes',
|
||||
[
|
||||
'numberOfLikes' => $comment->likes_count,
|
||||
],
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . $comment->likes_count ?></button>
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
|
||||
<Button uri="<?= route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
|
||||
</form>
|
||||
<?php if ($comment->replies_count): ?>
|
||||
|
@ -6,7 +6,7 @@
|
||||
[
|
||||
'numberOfLikes' => $comment->likes_count,
|
||||
],
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . $comment->likes_count ?></button>
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
|
||||
<Button uri="<?= route_to('post', $podcast->handle, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
|
||||
</form>
|
||||
<?php if ($comment->replies_count): ?>
|
||||
@ -21,12 +21,18 @@
|
||||
) ?>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<button class="inline-flex items-center opacity-50 cursor-not-allowed hover:underline" title="<?= lang(
|
||||
'Comment.like',
|
||||
<?= anchor_popup(
|
||||
route_to('post-remote-action', $podcast->handle, $comment->id, 'favourite'),
|
||||
icon('heart', 'text-xl mr-1 opacity-40') . $comment->likes_count,
|
||||
[
|
||||
'numberOfLikes' => $comment->likes_count,
|
||||
'class' => 'inline-flex items-center hover:underline',
|
||||
'width' => 420,
|
||||
'height' => 620,
|
||||
'title' => lang('Post.favourites', [
|
||||
'numberOfFavourites' => $comment->likes_count,
|
||||
]),
|
||||
],
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 text-skin-muted') . $comment->likes_count ?></button>
|
||||
) ?>
|
||||
<?php if ($comment->replies_count): ?>
|
||||
<?= anchor(
|
||||
route_to('post', $podcast->handle, $comment->id),
|
||||
|
@ -21,13 +21,13 @@
|
||||
<?php else: ?>
|
||||
<footer>
|
||||
<?php if (can_user_interact()): ?>
|
||||
<form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
|
||||
'Comment.likes',
|
||||
[
|
||||
'numberOfLikes' => $comment->likes_count,
|
||||
],
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . lang(
|
||||
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . lang(
|
||||
'Comment.likes',
|
||||
[
|
||||
'numberOfLikes' => $comment->likes_count,
|
||||
|
@ -1,12 +1,12 @@
|
||||
<footer>
|
||||
<?php if (can_user_interact()): ?>
|
||||
<form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $reply->episode->slug, $reply->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $reply->episode->slug, $reply->id) ?>" method="POST" class="flex items-center gap-x-4">
|
||||
<button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
|
||||
'Comment.likes',
|
||||
[
|
||||
'numberOfLikes' => $reply->likes_count,
|
||||
],
|
||||
) ?>"><?= icon('heart', 'text-lg mr-1 opacity-40 group-hover:text-red-600') . $reply->likes_count ?></button>
|
||||
) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button>
|
||||
<Button uri="<?= route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
|
@ -27,7 +27,7 @@
|
||||
<?php else: ?>
|
||||
<div class="px-6 mb-4 post-content"><?= $post->message_html ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($post->episode_id): ?>
|
||||
<?php if ($post->episode_id && $post->in_reply_to_id === null): ?>
|
||||
<?= view('episode/_partials/preview_card', [
|
||||
'index' => $index,
|
||||
'episode' => $post->episode,
|
||||
|
Loading…
x
Reference in New Issue
Block a user