Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Select Git revision
Show changes
Commits on Source (6)
Showing
with 304 additions and 219 deletions
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
[ [
"@semantic-release/exec", "@semantic-release/exec",
{ {
"prepareCmd": "./scripts/bundle.sh ${nextRelease.version} && ./scripts/package.sh && npx prettier --write CHANGELOG.md" "prepareCmd": "./scripts/bundle.sh ${nextRelease.version} && ./scripts/package.sh ${nextRelease.version} && npx prettier --write CHANGELOG.md"
} }
], ],
"@semantic-release/npm", "@semantic-release/npm",
......
# [1.0.0-alpha.61](https://code.podlibre.org/podlibre/castopod-host/compare/v1.0.0-alpha.60...v1.0.0-alpha.61) (2021-06-23)
### Bug Fixes
- **release:** add missing version number to castopod-host package
([8f3e9d9](https://code.podlibre.org/podlibre/castopod-host/commit/8f3e9d90c14545d3f84d4469b26a53db4554b4dc))
- **ux:** allow for empty message upon episode publication and warn user on
submit
([33d01b8](https://code.podlibre.org/podlibre/castopod-host/commit/33d01b8d4fd6ebf24e9f011aa705c456c846956c)),
closes [#129](https://code.podlibre.org/podlibre/castopod-host/issues/129)
# [1.0.0-alpha.60](https://code.podlibre.org/podlibre/castopod-host/compare/v1.0.0-alpha.59...v1.0.0-alpha.60) (2021-06-21) # [1.0.0-alpha.60](https://code.podlibre.org/podlibre/castopod-host/compare/v1.0.0-alpha.59...v1.0.0-alpha.60) (2021-06-21)
### Features ### Features
......
...@@ -11,7 +11,7 @@ declare(strict_types=1); ...@@ -11,7 +11,7 @@ declare(strict_types=1);
| |
| NOTE: this constant is updated upon release with Continuous Integration. | NOTE: this constant is updated upon release with Continuous Integration.
*/ */
defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.60'); defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.61');
/* /*
| -------------------------------------------------------------------- | --------------------------------------------------------------------
......
...@@ -5,7 +5,7 @@ declare(strict_types=1); ...@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Config; namespace Config;
use App\Entities\Actor; use App\Entities\Actor;
use App\Entities\Note; use App\Entities\Status;
use App\Entities\User; use App\Entities\User;
use CodeIgniter\Events\Events; use CodeIgniter\Events\Events;
use CodeIgniter\Exceptions\FrameworkException; use CodeIgniter\Exceptions\FrameworkException;
...@@ -120,82 +120,82 @@ Events::on('on_undo_follow', function ($actor, $targetActor): void { ...@@ -120,82 +120,82 @@ Events::on('on_undo_follow', function ($actor, $targetActor): void {
}); });
/** /**
* @param Note $note * @param Status $status
*/ */
Events::on('on_note_add', function ($note): void { Events::on('on_status_add', function ($status): void {
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
$note = $note->reply_to_note; $status = $status->reply_to_status;
} }
if ($note->episode_id) { if ($status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $note->episode_id) ->where('id', $status->episode_id)
->increment('notes_total'); ->increment('statuses_total');
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
// Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs // Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs
// same for other events below // same for other events below
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
}); });
/** /**
* @param Note $note * @param Status $status
*/ */
Events::on('on_note_remove', function ($note): void { Events::on('on_status_remove', function ($status): void {
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
Events::trigger('on_note_remove', $note->reply_to_note); Events::trigger('on_status_remove', $status->reply_to_status);
} }
if ($episodeId = $note->episode_id) { if ($episodeId = $status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->decrement('notes_total', 1 + $note->reblogs_count); ->decrement('statuses_total', 1 + $status->reblogs_count);
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->decrement('reblogs_total', $note->reblogs_count); ->decrement('reblogs_total', $status->reblogs_count);
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->decrement('favourites_total', $note->favourites_count); ->decrement('favourites_total', $status->favourites_count);
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
}); });
/** /**
* @param Actor $actor * @param Actor $actor
* @param Note $note * @param Status $status
*/ */
Events::on('on_note_reblog', function ($actor, $note): void { Events::on('on_status_reblog', function ($actor, $status): void {
if ($episodeId = $note->episode_id) { if ($episodeId = $status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->increment('reblogs_total'); ->increment('reblogs_total');
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->increment('notes_total'); ->increment('statuses_total');
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
if ($actor->is_podcast) { if ($actor->is_podcast) {
...@@ -205,111 +205,111 @@ Events::on('on_note_reblog', function ($actor, $note): void { ...@@ -205,111 +205,111 @@ Events::on('on_note_reblog', function ($actor, $note): void {
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
cache()->deleteMatching("page_note#{$note->in_reply_to_id}"); cache()->deleteMatching("page_status#{$status->in_reply_to_id}");
} }
}); });
/** /**
* @param Note $reblogNote * @param Status $reblogStatus
*/ */
Events::on('on_note_undo_reblog', function ($reblogNote): void { Events::on('on_status_undo_reblog', function ($reblogStatus): void {
$note = $reblogNote->reblog_of_note; $status = $reblogStatus->reblog_of_status;
if ($episodeId = $note->episode_id) { if ($episodeId = $status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->decrement('reblogs_total'); ->decrement('reblogs_total');
model('EpisodeModel') model('EpisodeModel')
->where('id', $episodeId) ->where('id', $episodeId)
->decrement('notes_total'); ->decrement('statuses_total');
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
cache() cache()
->deleteMatching("page_note#{$reblogNote->id}*"); ->deleteMatching("page_status#{$reblogStatus->id}*");
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
cache()->deleteMatching("page_note#{$note->in_reply_to_id}"); cache()->deleteMatching("page_status#{$status->in_reply_to_id}");
} }
if ($reblogNote->actor->is_podcast) { if ($reblogStatus->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$reblogNote->actor->podcast->id}*"); ->deleteMatching("podcast#{$reblogStatus->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$reblogNote->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$reblogStatus->actor->podcast->id}*");
} }
}); });
/** /**
* @param Note $reply * @param Status $reply
*/ */
Events::on('on_note_reply', function ($reply): void { Events::on('on_status_reply', function ($reply): void {
$note = $reply->reply_to_note; $status = $reply->reply_to_status;
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
}); });
/** /**
* @param Note $reply * @param Status $reply
*/ */
Events::on('on_reply_remove', function ($reply): void { Events::on('on_reply_remove', function ($reply): void {
$note = $reply->reply_to_note; $status = $reply->reply_to_status;
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
cache() cache()
->deleteMatching("page_note#{$reply->id}*"); ->deleteMatching("page_status#{$reply->id}*");
}); });
/** /**
* @param Actor $actor * @param Actor $actor
* @param Note $note * @param Status $status
*/ */
Events::on('on_note_favourite', function ($actor, $note): void { Events::on('on_status_favourite', function ($actor, $status): void {
if ($note->episode_id) { if ($status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $note->episode_id) ->where('id', $status->episode_id)
->increment('favourites_total'); ->increment('favourites_total');
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
cache()->deleteMatching("page_note#{$note->in_reply_to_id}*"); cache()->deleteMatching("page_status#{$status->in_reply_to_id}*");
} }
if ($actor->is_podcast) { if ($actor->is_podcast) {
...@@ -321,27 +321,27 @@ Events::on('on_note_favourite', function ($actor, $note): void { ...@@ -321,27 +321,27 @@ Events::on('on_note_favourite', function ($actor, $note): void {
/** /**
* @param Actor $actor * @param Actor $actor
* @param Note $note * @param Status $status
*/ */
Events::on('on_note_undo_favourite', function ($actor, $note): void { Events::on('on_status_undo_favourite', function ($actor, $status): void {
if ($note->episode_id) { if ($status->episode_id) {
model('EpisodeModel') model('EpisodeModel')
->where('id', $note->episode_id) ->where('id', $status->episode_id)
->decrement('favourites_total'); ->decrement('favourites_total');
} }
if ($note->actor->is_podcast) { if ($status->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*"); ->deleteMatching("podcast#{$status->actor->podcast->id}*");
cache() cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$status->actor->podcast->id}*");
} }
cache() cache()
->deleteMatching("page_note#{$note->id}*"); ->deleteMatching("page_status#{$status->id}*");
if ($note->in_reply_to_id !== null) { if ($status->in_reply_to_id !== null) {
cache()->deleteMatching("page_note#{$note->in_reply_to_id}*"); cache()->deleteMatching("page_status#{$status->in_reply_to_id}*");
} }
if ($actor->is_podcast) { if ($actor->is_podcast) {
...@@ -356,7 +356,7 @@ Events::on('on_block_actor', function (int $actorId): void { ...@@ -356,7 +356,7 @@ Events::on('on_block_actor', function (int $actorId): void {
cache() cache()
->deleteMatching('podcast*'); ->deleteMatching('podcast*');
cache() cache()
->deleteMatching('page_note*'); ->deleteMatching('page_status*');
}); });
Events::on('on_unblock_actor', function (int $actorId): void { Events::on('on_unblock_actor', function (int $actorId): void {
...@@ -364,7 +364,7 @@ Events::on('on_unblock_actor', function (int $actorId): void { ...@@ -364,7 +364,7 @@ Events::on('on_unblock_actor', function (int $actorId): void {
cache() cache()
->deleteMatching('podcast*'); ->deleteMatching('podcast*');
cache() cache()
->deleteMatching('page_note*'); ->deleteMatching('page_status*');
}); });
Events::on('on_block_domain', function (string $domainName): void { Events::on('on_block_domain', function (string $domainName): void {
...@@ -372,7 +372,7 @@ Events::on('on_block_domain', function (string $domainName): void { ...@@ -372,7 +372,7 @@ Events::on('on_block_domain', function (string $domainName): void {
cache() cache()
->deleteMatching('podcast*'); ->deleteMatching('podcast*');
cache() cache()
->deleteMatching('page_note*'); ->deleteMatching('page_status*');
}); });
Events::on('on_unblock_domain', function (string $domainName): void { Events::on('on_unblock_domain', function (string $domainName): void {
...@@ -380,5 +380,5 @@ Events::on('on_unblock_domain', function (string $domainName): void { ...@@ -380,5 +380,5 @@ Events::on('on_unblock_domain', function (string $domainName): void {
cache() cache()
->deleteMatching('podcast*'); ->deleteMatching('podcast*');
cache() cache()
->deleteMatching('page_note*'); ->deleteMatching('page_status*');
}); });
...@@ -35,7 +35,7 @@ $routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,32}'); ...@@ -35,7 +35,7 @@ $routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,32}');
$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}'); $routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}');
$routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}'); $routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}');
$routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding'); $routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding');
$routes->addPlaceholder('noteAction', '\bfavourite|\breblog|\breply'); $routes->addPlaceholder('statusAction', '\bfavourite|\breblog|\breply');
$routes->addPlaceholder('embeddablePlayerTheme', '\blight|\bdark|\blight-transparent|\bdark-transparent'); $routes->addPlaceholder('embeddablePlayerTheme', '\blight|\bdark|\blight-transparent|\bdark-transparent');
$routes->addPlaceholder( $routes->addPlaceholder(
'uuid', 'uuid',
...@@ -310,6 +310,15 @@ $routes->group( ...@@ -310,6 +310,15 @@ $routes->group(
'permission:podcast-manage_publications', 'permission:podcast-manage_publications',
], ],
); );
$routes->get(
'publish-cancel',
'EpisodeController::publishCancel/$1/$2',
[
'as' => 'episode-publish-cancel',
'filter' =>
'permission:podcast-manage_publications',
],
);
$routes->get( $routes->get(
'unpublish', 'unpublish',
'EpisodeController::unpublish/$1/$2', 'EpisodeController::unpublish/$1/$2',
...@@ -746,71 +755,71 @@ $routes->post('interact-as-actor', 'AuthController::attemptInteractAsActor', [ ...@@ -746,71 +755,71 @@ $routes->post('interact-as-actor', 'AuthController::attemptInteractAsActor', [
* Overwriting ActivityPub routes file * Overwriting ActivityPub routes file
*/ */
$routes->group('@(:podcastName)', function ($routes): void { $routes->group('@(:podcastName)', function ($routes): void {
$routes->post('notes/new', 'NoteController::attemptCreate/$1', [ $routes->post('statuses/new', 'StatusController::attemptCreate/$1', [
'as' => 'note-attempt-create', 'as' => 'status-attempt-create',
'filter' => 'permission:podcast-manage_publications', 'filter' => 'permission:podcast-manage_publications',
]); ]);
// Note // Status
$routes->group('notes/(:uuid)', function ($routes): void { $routes->group('statuses/(:uuid)', function ($routes): void {
$routes->get('/', 'NoteController::view/$1/$2', [ $routes->get('/', 'StatusController::view/$1/$2', [
'as' => 'note', 'as' => 'status',
'alternate-content' => [ 'alternate-content' => [
'application/activity+json' => [ 'application/activity+json' => [
'namespace' => 'ActivityPub\Controllers', 'namespace' => 'ActivityPub\Controllers',
'controller-method' => 'NoteController/$2', 'controller-method' => 'StatusController/$2',
], ],
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [ 'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
'namespace' => 'ActivityPub\Controllers', 'namespace' => 'ActivityPub\Controllers',
'controller-method' => 'NoteController/$2', 'controller-method' => 'StatusController/$2',
], ],
], ],
]); ]);
$routes->get('replies', 'NoteController/$1/$2', [ $routes->get('replies', 'StatusController/$1/$2', [
'as' => 'note-replies', 'as' => 'status-replies',
'alternate-content' => [ 'alternate-content' => [
'application/activity+json' => [ 'application/activity+json' => [
'namespace' => 'ActivityPub\Controllers', 'namespace' => 'ActivityPub\Controllers',
'controller-method' => 'NoteController::replies/$2', 'controller-method' => 'StatusController::replies/$2',
], ],
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [ 'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
'namespace' => 'ActivityPub\Controllers', 'namespace' => 'ActivityPub\Controllers',
'controller-method' => 'NoteController::replies/$2', 'controller-method' => 'StatusController::replies/$2',
], ],
], ],
]); ]);
// Actions // Actions
$routes->post('action', 'NoteController::attemptAction/$1/$2', [ $routes->post('action', 'StatusController::attemptAction/$1/$2', [
'as' => 'note-attempt-action', 'as' => 'status-attempt-action',
'filter' => 'permission:podcast-interact_as', 'filter' => 'permission:podcast-interact_as',
]); ]);
$routes->post( $routes->post(
'block-actor', 'block-actor',
'NoteController::attemptBlockActor/$1/$2', 'StatusController::attemptBlockActor/$1/$2',
[ [
'as' => 'note-attempt-block-actor', 'as' => 'status-attempt-block-actor',
'filter' => 'permission:fediverse-block_actors', 'filter' => 'permission:fediverse-block_actors',
], ],
); );
$routes->post( $routes->post(
'block-domain', 'block-domain',
'NoteController::attemptBlockDomain/$1/$2', 'StatusController::attemptBlockDomain/$1/$2',
[ [
'as' => 'note-attempt-block-domain', 'as' => 'status-attempt-block-domain',
'filter' => 'permission:fediverse-block_domains', 'filter' => 'permission:fediverse-block_domains',
], ],
); );
$routes->post('delete', 'NoteController::attemptDelete/$1/$2', [ $routes->post('delete', 'StatusController::attemptDelete/$1/$2', [
'as' => 'note-attempt-delete', 'as' => 'status-attempt-delete',
'filter' => 'permission:podcast-manage_publications', 'filter' => 'permission:podcast-manage_publications',
]); ]);
$routes->get( $routes->get(
'remote/(:noteAction)', 'remote/(:statusAction)',
'NoteController::remoteAction/$1/$2/$3', 'StatusController::remoteAction/$1/$2/$3',
[ [
'as' => 'note-remote-action', 'as' => 'status-remote-action',
], ],
); );
}); });
......
...@@ -13,12 +13,12 @@ namespace App\Controllers\Admin; ...@@ -13,12 +13,12 @@ namespace App\Controllers\Admin;
use App\Entities\Episode; use App\Entities\Episode;
use App\Entities\Image; use App\Entities\Image;
use App\Entities\Location; use App\Entities\Location;
use App\Entities\Note;
use App\Entities\Podcast; use App\Entities\Podcast;
use App\Entities\Status;
use App\Models\EpisodeModel; use App\Models\EpisodeModel;
use App\Models\NoteModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use App\Models\SoundbiteModel; use App\Models\SoundbiteModel;
use App\Models\StatusModel;
use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\I18n\Time; use CodeIgniter\I18n\Time;
...@@ -388,7 +388,7 @@ class EpisodeController extends BaseController ...@@ -388,7 +388,7 @@ class EpisodeController extends BaseController
return redirect()->back(); return redirect()->back();
} }
public function publish(): string public function publish(): string | RedirectResponse
{ {
if ($this->episode->publication_status === 'not_published') { if ($this->episode->publication_status === 'not_published') {
helper(['form']); helper(['form']);
...@@ -405,7 +405,10 @@ class EpisodeController extends BaseController ...@@ -405,7 +405,10 @@ class EpisodeController extends BaseController
return view('admin/episode/publish', $data); return view('admin/episode/publish', $data);
} }
throw PageNotFoundException::forPageNotFound(); return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
'error',
lang('Episode.publish_error')
);
} }
public function attemptPublish(): RedirectResponse public function attemptPublish(): RedirectResponse
...@@ -426,7 +429,7 @@ class EpisodeController extends BaseController ...@@ -426,7 +429,7 @@ class EpisodeController extends BaseController
$db = db_connect(); $db = db_connect();
$db->transStart(); $db->transStart();
$newNote = new Note([ $newStatus = new Status([
'actor_id' => $this->podcast->actor_id, 'actor_id' => $this->podcast->actor_id,
'episode_id' => $this->episode->id, 'episode_id' => $this->episode->id,
'message' => $this->request->getPost('message'), 'message' => $this->request->getPost('message'),
...@@ -453,15 +456,15 @@ class EpisodeController extends BaseController ...@@ -453,15 +456,15 @@ class EpisodeController extends BaseController
$this->episode->published_at = Time::now(); $this->episode->published_at = Time::now();
} }
$newNote->published_at = $this->episode->published_at; $newStatus->published_at = $this->episode->published_at;
$noteModel = new NoteModel(); $statusModel = new StatusModel();
if (! $noteModel->addNote($newNote)) { if (! $statusModel->addStatus($newStatus)) {
$db->transRollback(); $db->transRollback();
return redirect() return redirect()
->back() ->back()
->withInput() ->withInput()
->with('errors', $noteModel->errors()); ->with('errors', $statusModel->errors());
} }
$episodeModel = new EpisodeModel(); $episodeModel = new EpisodeModel();
...@@ -478,7 +481,7 @@ class EpisodeController extends BaseController ...@@ -478,7 +481,7 @@ class EpisodeController extends BaseController
return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]); return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
} }
public function publishEdit(): string public function publishEdit(): string | RedirectResponse
{ {
if ($this->episode->publication_status === 'scheduled') { if ($this->episode->publication_status === 'scheduled') {
helper(['form']); helper(['form']);
...@@ -486,7 +489,7 @@ class EpisodeController extends BaseController ...@@ -486,7 +489,7 @@ class EpisodeController extends BaseController
$data = [ $data = [
'podcast' => $this->podcast, 'podcast' => $this->podcast,
'episode' => $this->episode, 'episode' => $this->episode,
'note' => (new NoteModel()) 'status' => (new StatusModel())
->where([ ->where([
'actor_id' => $this->podcast->actor_id, 'actor_id' => $this->podcast->actor_id,
'episode_id' => $this->episode->id, 'episode_id' => $this->episode->id,
...@@ -500,13 +503,17 @@ class EpisodeController extends BaseController ...@@ -500,13 +503,17 @@ class EpisodeController extends BaseController
]); ]);
return view('admin/episode/publish_edit', $data); return view('admin/episode/publish_edit', $data);
} }
throw PageNotFoundException::forPageNotFound();
return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
'error',
lang('Episode.publish_edit_error')
);
} }
public function attemptPublishEdit(): RedirectResponse public function attemptPublishEdit(): RedirectResponse
{ {
$rules = [ $rules = [
'note_id' => 'required', 'status_id' => 'required',
'publication_method' => 'required', 'publication_method' => 'required',
'scheduled_publication_date' => 'scheduled_publication_date' =>
'valid_date[Y-m-d H:i]|permit_empty', 'valid_date[Y-m-d H:i]|permit_empty',
...@@ -542,19 +549,19 @@ class EpisodeController extends BaseController ...@@ -542,19 +549,19 @@ class EpisodeController extends BaseController
$this->episode->published_at = Time::now(); $this->episode->published_at = Time::now();
} }
$note = (new NoteModel())->getNoteById($this->request->getPost('note_id')); $status = (new StatusModel())->getStatusById($this->request->getPost('status_id'));
if ($note !== null) { if ($status !== null) {
$note->message = $this->request->getPost('message'); $status->message = $this->request->getPost('message');
$note->published_at = $this->episode->published_at; $status->published_at = $this->episode->published_at;
$noteModel = new NoteModel(); $statusModel = new StatusModel();
if (! $noteModel->editNote($note)) { if (! $statusModel->editStatus($status)) {
$db->transRollback(); $db->transRollback();
return redirect() return redirect()
->back() ->back()
->withInput() ->withInput()
->with('errors', $noteModel->errors()); ->with('errors', $statusModel->errors());
} }
} }
...@@ -572,7 +579,44 @@ class EpisodeController extends BaseController ...@@ -572,7 +579,44 @@ class EpisodeController extends BaseController
return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]); return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
} }
public function unpublish(): string public function publishCancel(): RedirectResponse
{
if ($this->episode->publication_status === 'scheduled') {
$db = db_connect();
$db->transStart();
$statusModel = new StatusModel();
$status = $statusModel
->where([
'actor_id' => $this->podcast->actor_id,
'episode_id' => $this->episode->id,
])
->first();
$statusModel->removeStatus($status);
$this->episode->published_at = null;
$episodeModel = new EpisodeModel();
if (! $episodeModel->update($this->episode->id, $this->episode)) {
$db->transRollback();
return redirect()
->back()
->withInput()
->with('errors', $episodeModel->errors());
}
$db->transComplete();
return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
}
return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
'error',
lang('Episode.publish_cancel_error')
);
}
public function unpublish(): string | RedirectResponse
{ {
if ($this->episode->publication_status === 'published') { if ($this->episode->publication_status === 'published') {
helper(['form']); helper(['form']);
...@@ -589,7 +633,10 @@ class EpisodeController extends BaseController ...@@ -589,7 +633,10 @@ class EpisodeController extends BaseController
return view('admin/episode/unpublish', $data); return view('admin/episode/unpublish', $data);
} }
throw PageNotFoundException::forPageNotFound(); return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
'error',
lang('Episode.unpublish_error')
);
} }
public function attemptUnpublish(): RedirectResponse public function attemptUnpublish(): RedirectResponse
...@@ -609,13 +656,13 @@ class EpisodeController extends BaseController ...@@ -609,13 +656,13 @@ class EpisodeController extends BaseController
$db->transStart(); $db->transStart();
$allNotesLinkedToEpisode = (new NoteModel()) $allStatusesLinkedToEpisode = (new StatusModel())
->where([ ->where([
'episode_id' => $this->episode->id, 'episode_id' => $this->episode->id,
]) ])
->findAll(); ->findAll();
foreach ($allNotesLinkedToEpisode as $note) { foreach ($allStatusesLinkedToEpisode as $status) {
(new NoteModel())->removeNote($note); (new StatusModel())->removeStatus($status);
} }
// set episode published_at to null to unpublish // set episode published_at to null to unpublish
......
...@@ -13,8 +13,8 @@ namespace App\Controllers; ...@@ -13,8 +13,8 @@ namespace App\Controllers;
use Analytics\AnalyticsTrait; use Analytics\AnalyticsTrait;
use App\Entities\Podcast; use App\Entities\Podcast;
use App\Models\EpisodeModel; use App\Models\EpisodeModel;
use App\Models\NoteModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use App\Models\StatusModel;
use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Exceptions\PageNotFoundException;
class PodcastController extends BaseController class PodcastController extends BaseController
...@@ -64,7 +64,7 @@ class PodcastController extends BaseController ...@@ -64,7 +64,7 @@ class PodcastController extends BaseController
if (! ($cachedView = cache($cacheName))) { if (! ($cachedView = cache($cacheName))) {
$data = [ $data = [
'podcast' => $this->podcast, 'podcast' => $this->podcast,
'notes' => (new NoteModel())->getActorPublishedNotes($this->podcast->actor_id), 'statuses' => (new StatusModel())->getActorPublishedStatuses($this->podcast->actor_id),
]; ];
// if user is logged in then send to the authenticated activity view // if user is logged in then send to the authenticated activity view
......
...@@ -10,21 +10,21 @@ declare(strict_types=1); ...@@ -10,21 +10,21 @@ declare(strict_types=1);
namespace App\Controllers; namespace App\Controllers;
use ActivityPub\Controllers\NoteController as ActivityPubNoteController; use ActivityPub\Controllers\StatusController as ActivityPubStatusController;
use ActivityPub\Entities\Note as ActivityPubNote; use ActivityPub\Entities\Status as ActivityPubStatus;
use Analytics\AnalyticsTrait; use Analytics\AnalyticsTrait;
use App\Entities\Actor; use App\Entities\Actor;
use App\Entities\Note as CastopodNote;
use App\Entities\Podcast; use App\Entities\Podcast;
use App\Entities\Status as CastopodStatus;
use App\Models\EpisodeModel; use App\Models\EpisodeModel;
use App\Models\NoteModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use App\Models\StatusModel;
use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\URI; use CodeIgniter\HTTP\URI;
use CodeIgniter\I18n\Time; use CodeIgniter\I18n\Time;
class NoteController extends ActivityPubNoteController class StatusController extends ActivityPubStatusController
{ {
use AnalyticsTrait; use AnalyticsTrait;
...@@ -50,9 +50,9 @@ class NoteController extends ActivityPubNoteController ...@@ -50,9 +50,9 @@ class NoteController extends ActivityPubNoteController
if ( if (
count($params) > 1 && count($params) > 1 &&
($note = (new NoteModel())->getNoteById($params[1])) !== null ($status = (new StatusModel())->getStatusById($params[1])) !== null
) { ) {
$this->note = $note; $this->status = $status;
unset($params[0]); unset($params[0]);
unset($params[1]); unset($params[1]);
...@@ -72,7 +72,7 @@ class NoteController extends ActivityPubNoteController ...@@ -72,7 +72,7 @@ class NoteController extends ActivityPubNoteController
'_', '_',
array_filter([ array_filter([
'page', 'page',
"note#{$this->note->id}", "status#{$this->status->id}",
service('request') service('request')
->getLocale(), ->getLocale(),
can_user_interact() ? '_authenticated' : null, can_user_interact() ? '_authenticated' : null,
...@@ -83,15 +83,15 @@ class NoteController extends ActivityPubNoteController ...@@ -83,15 +83,15 @@ class NoteController extends ActivityPubNoteController
$data = [ $data = [
'podcast' => $this->podcast, 'podcast' => $this->podcast,
'actor' => $this->actor, 'actor' => $this->actor,
'note' => $this->note, 'status' => $this->status,
]; ];
// if user is logged in then send to the authenticated activity view // if user is logged in then send to the authenticated activity view
if (can_user_interact()) { if (can_user_interact()) {
helper('form'); helper('form');
return view('podcast/note_authenticated', $data); return view('podcast/status_authenticated', $data);
} }
return view('podcast/note', $data, [ return view('podcast/status', $data, [
'cache' => DECADE, 'cache' => DECADE,
'cache_name' => $cacheName, 'cache_name' => $cacheName,
]); ]);
...@@ -116,7 +116,7 @@ class NoteController extends ActivityPubNoteController ...@@ -116,7 +116,7 @@ class NoteController extends ActivityPubNoteController
$message = $this->request->getPost('message'); $message = $this->request->getPost('message');
$newNote = new CastopodNote([ $newStatus = new CastopodStatus([
'actor_id' => interact_as_actor_id(), 'actor_id' => interact_as_actor_id(),
'published_at' => Time::now(), 'published_at' => Time::now(),
'created_by' => user_id(), 'created_by' => user_id(),
...@@ -129,23 +129,23 @@ class NoteController extends ActivityPubNoteController ...@@ -129,23 +129,23 @@ class NoteController extends ActivityPubNoteController
($params = extract_params_from_episode_uri(new URI($episodeUri))) && ($params = extract_params_from_episode_uri(new URI($episodeUri))) &&
($episode = (new EpisodeModel())->getEpisodeBySlug($params['podcastName'], $params['episodeSlug'])) ($episode = (new EpisodeModel())->getEpisodeBySlug($params['podcastName'], $params['episodeSlug']))
) { ) {
$newNote->episode_id = $episode->id; $newStatus->episode_id = $episode->id;
} }
$newNote->message = $message; $newStatus->message = $message;
$noteModel = new NoteModel(); $statusModel = new StatusModel();
if ( if (
! $noteModel ! $statusModel
->addNote($newNote, ! (bool) $newNote->episode_id, true) ->addStatus($newStatus, ! (bool) $newStatus->episode_id, true)
) { ) {
return redirect() return redirect()
->back() ->back()
->withInput() ->withInput()
->with('errors', $noteModel->errors()); ->with('errors', $statusModel->errors());
} }
// Note has been successfully created // Status has been successfully created
return redirect()->back(); return redirect()->back();
} }
...@@ -162,36 +162,36 @@ class NoteController extends ActivityPubNoteController ...@@ -162,36 +162,36 @@ class NoteController extends ActivityPubNoteController
->with('errors', $this->validator->getErrors()); ->with('errors', $this->validator->getErrors());
} }
$newNote = new ActivityPubNote([ $newStatus = new ActivityPubStatus([
'actor_id' => interact_as_actor_id(), 'actor_id' => interact_as_actor_id(),
'in_reply_to_id' => $this->note->id, 'in_reply_to_id' => $this->status->id,
'message' => $this->request->getPost('message'), 'message' => $this->request->getPost('message'),
'published_at' => Time::now(), 'published_at' => Time::now(),
'created_by' => user_id(), 'created_by' => user_id(),
]); ]);
$noteModel = new NoteModel(); $statusModel = new StatusModel();
if (! $noteModel->addReply($newNote)) { if (! $statusModel->addReply($newStatus)) {
return redirect() return redirect()
->back() ->back()
->withInput() ->withInput()
->with('errors', $noteModel->errors()); ->with('errors', $statusModel->errors());
} }
// Reply note without preview card has been successfully created // Reply status without preview card has been successfully created
return redirect()->back(); return redirect()->back();
} }
public function attemptFavourite(): RedirectResponse public function attemptFavourite(): RedirectResponse
{ {
model('FavouriteModel')->toggleFavourite(interact_as_actor(), $this->note); model('FavouriteModel')->toggleFavourite(interact_as_actor(), $this->status);
return redirect()->back(); return redirect()->back();
} }
public function attemptReblog(): RedirectResponse public function attemptReblog(): RedirectResponse
{ {
(new NoteModel())->toggleReblog(interact_as_actor(), $this->note); (new StatusModel())->toggleReblog(interact_as_actor(), $this->status);
return redirect()->back(); return redirect()->back();
} }
...@@ -230,20 +230,20 @@ class NoteController extends ActivityPubNoteController ...@@ -230,20 +230,20 @@ class NoteController extends ActivityPubNoteController
$cacheName = implode( $cacheName = implode(
'_', '_',
array_filter(['page', "note#{$this->note->id}", "remote_{$action}", service('request') ->getLocale()]), array_filter(['page', "status#{$this->status->id}", "remote_{$action}", service('request') ->getLocale()]),
); );
if (! ($cachedView = cache($cacheName))) { if (! ($cachedView = cache($cacheName))) {
$data = [ $data = [
'podcast' => $this->podcast, 'podcast' => $this->podcast,
'actor' => $this->actor, 'actor' => $this->actor,
'note' => $this->note, 'status' => $this->status,
'action' => $action, 'action' => $action,
]; ];
helper('form'); helper('form');
return view('podcast/note_remote_action', $data, [ return view('podcast/status_remote_action', $data, [
'cache' => DECADE, 'cache' => DECADE,
'cache_name' => $cacheName, 'cache_name' => $cacheName,
]); ]);
......
...@@ -157,7 +157,7 @@ class AddEpisodes extends Migration ...@@ -157,7 +157,7 @@ class AddEpisodes extends Migration
'unsigned' => true, 'unsigned' => true,
'default' => 0, 'default' => 0,
], ],
'notes_total' => [ 'statuses_total' => [
'type' => 'INT', 'type' => 'INT',
'unsigned' => true, 'unsigned' => true,
'default' => 0, 'default' => 0,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
declare(strict_types=1); declare(strict_types=1);
/** /**
* Class AddEpisodeIdToNotes Adds episode_id field to activitypub_notes table in database * Class AddEpisodeIdToStatuses Adds episode_id field to activitypub_statuses table in database
* *
* @copyright 2020 Podlibre * @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
...@@ -14,23 +14,23 @@ namespace App\Database\Migrations; ...@@ -14,23 +14,23 @@ namespace App\Database\Migrations;
use CodeIgniter\Database\Migration; use CodeIgniter\Database\Migration;
class AddEpisodeIdToNotes extends Migration class AddEpisodeIdToStatuses extends Migration
{ {
public function up(): void public function up(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
$createQuery = <<<CODE_SAMPLE $createQuery = <<<CODE_SAMPLE
ALTER TABLE {$prefix}activitypub_notes ALTER TABLE {$prefix}activitypub_statuses
ADD COLUMN `episode_id` INT UNSIGNED NULL AFTER `replies_count`, ADD COLUMN `episode_id` INT UNSIGNED NULL AFTER `replies_count`,
ADD FOREIGN KEY {$prefix}activitypub_notes_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE; ADD FOREIGN KEY {$prefix}activitypub_statuses_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE;
CODE_SAMPLE; CODE_SAMPLE;
$this->db->query($createQuery); $this->db->query($createQuery);
} }
public function down(): void public function down(): void
{ {
$this->forge->dropForeignKey('activitypub_notes', 'activitypub_notes_episode_id_foreign'); $this->forge->dropForeignKey('activitypub_statuses', 'activitypub_statuses_episode_id_foreign');
$this->forge->dropColumn('activitypub_notes', 'episode_id'); $this->forge->dropColumn('activitypub_statuses', 'episode_id');
} }
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
declare(strict_types=1); declare(strict_types=1);
/** /**
* Class AddCreatedByToNotes Adds created_by field to activitypub_notes table in database * Class AddCreatedByToStatuses Adds created_by field to activitypub_statuses table in database
* *
* @copyright 2020 Podlibre * @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
...@@ -14,23 +14,23 @@ namespace App\Database\Migrations; ...@@ -14,23 +14,23 @@ namespace App\Database\Migrations;
use CodeIgniter\Database\Migration; use CodeIgniter\Database\Migration;
class AddCreatedByToNotes extends Migration class AddCreatedByToStatuses extends Migration
{ {
public function up(): void public function up(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
$createQuery = <<<CODE_SAMPLE $createQuery = <<<CODE_SAMPLE
ALTER TABLE {$prefix}activitypub_notes ALTER TABLE {$prefix}activitypub_statuses
ADD COLUMN `created_by` INT UNSIGNED AFTER `episode_id`, ADD COLUMN `created_by` INT UNSIGNED AFTER `episode_id`,
ADD FOREIGN KEY {$prefix}activitypub_notes_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE; ADD FOREIGN KEY {$prefix}activitypub_statuses_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE;
CODE_SAMPLE; CODE_SAMPLE;
$this->db->query($createQuery); $this->db->query($createQuery);
} }
public function down(): void public function down(): void
{ {
$this->forge->dropForeignKey('activitypub_notes', 'activitypub_notes_created_by_foreign'); $this->forge->dropForeignKey('activitypub_statuses', 'activitypub_statuses_created_by_foreign');
$this->forge->dropColumn('activitypub_notes', 'created_by'); $this->forge->dropColumn('activitypub_statuses', 'created_by');
} }
} }
...@@ -162,13 +162,13 @@ class AuthSeeder extends Seeder ...@@ -162,13 +162,13 @@ class AuthSeeder extends Seeder
[ [
'name' => 'manage_publications', 'name' => 'manage_publications',
'description' => 'description' =>
'Publish / unpublish episodes & notes of a podcast', 'Publish / unpublish episodes & statuses of a podcast',
'has_permission' => ['podcast_admin'], 'has_permission' => ['podcast_admin'],
], ],
[ [
'name' => 'interact_as', 'name' => 'interact_as',
'description' => 'description' =>
'Interact as the podcast to favourite / share or reply to notes.', 'Interact as the podcast to favourite / share or reply to statuses.',
'has_permission' => ['podcast_admin'], 'has_permission' => ['podcast_admin'],
], ],
], ],
......
...@@ -11,10 +11,10 @@ declare(strict_types=1); ...@@ -11,10 +11,10 @@ declare(strict_types=1);
namespace App\Entities; namespace App\Entities;
use App\Libraries\SimpleRSSElement; use App\Libraries\SimpleRSSElement;
use App\Models\NoteModel;
use App\Models\PersonModel; use App\Models\PersonModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use App\Models\SoundbiteModel; use App\Models\SoundbiteModel;
use App\Models\StatusModel;
use CodeIgniter\Entity\Entity; use CodeIgniter\Entity\Entity;
use CodeIgniter\Files\File; use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Files\UploadedFile; use CodeIgniter\HTTP\Files\UploadedFile;
...@@ -67,7 +67,7 @@ use RuntimeException; ...@@ -67,7 +67,7 @@ use RuntimeException;
* @property string $custom_rss_string * @property string $custom_rss_string
* @property int $favourites_total * @property int $favourites_total
* @property int $reblogs_total * @property int $reblogs_total
* @property int $notes_total * @property int $statuses_total
* @property int $created_by * @property int $created_by
* @property int $updated_by * @property int $updated_by
* @property string $publication_status; * @property string $publication_status;
...@@ -117,9 +117,9 @@ class Episode extends Entity ...@@ -117,9 +117,9 @@ class Episode extends Entity
protected ?array $soundbites = null; protected ?array $soundbites = null;
/** /**
* @var Note[]|null * @var Status[]|null
*/ */
protected ?array $notes = null; protected ?array $statuses = null;
protected ?Location $location = null; protected ?Location $location = null;
...@@ -165,7 +165,7 @@ class Episode extends Entity ...@@ -165,7 +165,7 @@ class Episode extends Entity
'custom_rss' => '?json-array', 'custom_rss' => '?json-array',
'favourites_total' => 'integer', 'favourites_total' => 'integer',
'reblogs_total' => 'integer', 'reblogs_total' => 'integer',
'notes_total' => 'integer', 'statuses_total' => 'integer',
'created_by' => 'integer', 'created_by' => 'integer',
'updated_by' => 'integer', 'updated_by' => 'integer',
]; ];
...@@ -382,19 +382,19 @@ class Episode extends Entity ...@@ -382,19 +382,19 @@ class Episode extends Entity
} }
/** /**
* @return Note[] * @return Status[]
*/ */
public function getNotes(): array public function getStatuses(): array
{ {
if ($this->id === null) { if ($this->id === null) {
throw new RuntimeException('Episode must be created before getting soundbites.'); throw new RuntimeException('Episode must be created before getting soundbites.');
} }
if ($this->notes === null) { if ($this->statuses === null) {
$this->notes = (new NoteModel())->getEpisodeNotes($this->id); $this->statuses = (new StatusModel())->getEpisodeStatuses($this->id);
} }
return $this->notes; return $this->statuses;
} }
public function getLink(): string public function getLink(): string
......
...@@ -10,7 +10,7 @@ declare(strict_types=1); ...@@ -10,7 +10,7 @@ declare(strict_types=1);
namespace App\Entities; namespace App\Entities;
use ActivityPub\Entities\Note as ActivityPubNote; use ActivityPub\Entities\Status as ActivityPubStatus;
use App\Models\EpisodeModel; use App\Models\EpisodeModel;
use RuntimeException; use RuntimeException;
...@@ -18,7 +18,7 @@ use RuntimeException; ...@@ -18,7 +18,7 @@ use RuntimeException;
* @property int|null $episode_id * @property int|null $episode_id
* @property Episode|null $episode * @property Episode|null $episode
*/ */
class Note extends ActivityPubNote class Status extends ActivityPubStatus
{ {
protected ?Episode $episode = null; protected ?Episode $episode = null;
...@@ -41,12 +41,12 @@ class Note extends ActivityPubNote ...@@ -41,12 +41,12 @@ class Note extends ActivityPubNote
]; ];
/** /**
* Returns the note's attached episode * Returns the status' attached episode
*/ */
public function getEpisode(): ?Episode public function getEpisode(): ?Episode
{ {
if ($this->episode_id === null) { if ($this->episode_id === null) {
throw new RuntimeException('Note must have an episode_id before getting episode.'); throw new RuntimeException('Status must have an episode_id before getting episode.');
} }
if ($this->episode === null) { if ($this->episode === null) {
......
...@@ -86,11 +86,11 @@ if (! function_exists('button')) { ...@@ -86,11 +86,11 @@ if (! function_exists('button')) {
} }
if ($options['iconLeft']) { if ($options['iconLeft']) {
$label = icon($options['iconLeft'], 'mr-2') . $label; $label = icon((string) $options['iconLeft'], 'mr-2') . $label;
} }
if ($options['iconRight']) { if ($options['iconRight']) {
$label .= icon($options['iconRight'], 'ml-2'); $label .= icon((string) $options['iconRight'], 'ml-2');
} }
if ($uri !== '') { if ($uri !== '') {
......
...@@ -26,9 +26,9 @@ return [ ...@@ -26,9 +26,9 @@ return [
one {# total share} one {# total share}
other {# total shares} other {# total shares}
}', }',
'total_notes' => '{numberOfTotalNotes, plural, 'total_statuses' => '{numberOfTotalStatuses, plural,
one {# note} one {# total post}
other {# total notes} other {# total posts}
}', }',
'all_podcast_episodes' => 'All podcast episodes', 'all_podcast_episodes' => 'All podcast episodes',
'back_to_podcast' => 'Go back to podcast', 'back_to_podcast' => 'Go back to podcast',
...@@ -36,6 +36,10 @@ return [ ...@@ -36,6 +36,10 @@ return [
'publish' => 'Publish', 'publish' => 'Publish',
'publish_edit' => 'Edit publication', 'publish_edit' => 'Edit publication',
'unpublish' => 'Unpublish', 'unpublish' => 'Unpublish',
'publish_error' => 'Episode is already published.',
'publish_edit_error' => 'Episode is already published.',
'publish_cancel_error' => 'Episode is already published.',
'unpublish_error' => 'Episode is not published.',
'delete' => 'Delete', 'delete' => 'Delete',
'go_to_page' => 'Go to page', 'go_to_page' => 'Go to page',
'create' => 'Add an episode', 'create' => 'Add an episode',
...@@ -112,9 +116,10 @@ return [ ...@@ -112,9 +116,10 @@ return [
'submit_edit' => 'Save episode', 'submit_edit' => 'Save episode',
], ],
'publish_form' => [ 'publish_form' => [
'note' => 'Your note', 'back_to_episode_dashboard' => 'Back to episode dashboard',
'note_hint' => 'status' => 'Your announcement post',
'The message you write will be broadcasted to all your followers in the fediverse.', 'status_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_date' => 'Publication date',
'publication_method' => [ 'publication_method' => [
'now' => 'Now', 'now' => 'Now',
...@@ -126,6 +131,10 @@ return [ ...@@ -126,6 +131,10 @@ return [
'You can schedule the episode release by setting a future publication date. This field must be formatted as YYYY-MM-DD HH:mm', 'You can schedule the episode release by setting a future publication date. This field must be formatted as YYYY-MM-DD HH:mm',
'submit' => 'Publish', 'submit' => 'Publish',
'submit_edit' => 'Edit publication', 'submit_edit' => 'Edit publication',
'cancel_publication' => 'Cancel publication',
'message_warning' => 'You did not write a message for your announcement post!',
'message_warning_hint' => 'Having a message increases social engagement, resulting in a better visibility for your episode.',
'message_warning_submit' => 'Publish anyways',
], ],
'unpublish_form' => [ 'unpublish_form' => [
'disclaimer' => 'disclaimer' =>
......
...@@ -223,9 +223,9 @@ return [ ...@@ -223,9 +223,9 @@ return [
one {<span class="font-semibold">#</span> follower} one {<span class="font-semibold">#</span> follower}
other {<span class="font-semibold">#</span> followers} other {<span class="font-semibold">#</span> followers}
}', }',
'notes' => '{numberOfNotes, plural, 'statuses' => '{numberOfStatuses, plural,
one {<span class="font-semibold">#</span> note} one {<span class="font-semibold">#</span> post}
other {<span class="font-semibold">#</span> notes} other {<span class="font-semibold">#</span> posts}
}', }',
'activity' => 'Activity', 'activity' => 'Activity',
'episodes' => 'Episodes', 'episodes' => 'Episodes',
......
...@@ -10,7 +10,7 @@ declare(strict_types=1); ...@@ -10,7 +10,7 @@ declare(strict_types=1);
return [ return [
'title' => "{actorDisplayName}'s Note", 'title' => "{actorDisplayName}'s Note",
'back_to_actor_notes' => 'Back to {actor} notes', 'back_to_actor_statuses' => 'Back to {actor} notes',
'actor_shared' => '{actor} shared', 'actor_shared' => '{actor} shared',
'reply_to' => 'Reply to @{actorUsername}', 'reply_to' => 'Reply to @{actorUsername}',
'form' => [ 'form' => [
......
...@@ -26,9 +26,9 @@ return [ ...@@ -26,9 +26,9 @@ return [
one {# partage en tout} one {# partage en tout}
other {# partages en tout} other {# partages en tout}
}', }',
'total_notes' => '{numberOfTotalNotes, plural, 'total_statuses' => '{numberOfTotalStatuses, plural,
one {# note} one {# message}
other {# notes} other {# messages}
}', }',
'all_podcast_episodes' => 'Tous les épisodes du podcast', 'all_podcast_episodes' => 'Tous les épisodes du podcast',
'back_to_podcast' => 'Revenir au podcast', 'back_to_podcast' => 'Revenir au podcast',
...@@ -36,6 +36,10 @@ return [ ...@@ -36,6 +36,10 @@ return [
'publish' => 'Publier', 'publish' => 'Publier',
'publish_edit' => 'Modifier la publication', 'publish_edit' => 'Modifier la publication',
'unpublish' => 'Dépublier', 'unpublish' => 'Dépublier',
'publish_error' => 'L’épisode est déjà publié.',
'publish_edit_error' => 'L’épisode est déjà publié.',
'publish_cancel_error' => 'L’épisode est déjà publié.',
'unpublish_error' => 'L’épisode n’est pas publié.',
'delete' => 'Supprimer', 'delete' => 'Supprimer',
'go_to_page' => 'Voir', 'go_to_page' => 'Voir',
'create' => 'Ajouter un épisode', 'create' => 'Ajouter un épisode',
...@@ -115,9 +119,10 @@ return [ ...@@ -115,9 +119,10 @@ return [
'submit_edit' => 'Enregistrer l’épisode', 'submit_edit' => 'Enregistrer l’épisode',
], ],
'publish_form' => [ 'publish_form' => [
'note' => 'Votre note', 'back_to_episode_dashboard' => 'Retour au tableau de bord de l’épisode',
'note_hint' => 'status' => 'Votre message de publication',
'Le message que vous écrirez sera diffusé à toutes les personnes qui vous suivent dans le fédiverse.', 'status_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' => 'Date de publication',
'publication_date_clear' => 'Effacer la date de publication', 'publication_date_clear' => 'Effacer la date de publication',
'publication_date_hint' => 'publication_date_hint' =>
...@@ -132,6 +137,10 @@ return [ ...@@ -132,6 +137,10 @@ return [
'Vous pouvez planifier la sortie de l’épisode en saisissant une date de publication future. Ce champ doit être au format YYYY-MM-DD HH:mm', 'Vous pouvez planifier la sortie de l’épisode en saisissant une date de publication future. Ce champ doit être au format YYYY-MM-DD HH:mm',
'submit' => 'Publier', 'submit' => 'Publier',
'submit_edit' => 'Modifier la publication', 'submit_edit' => 'Modifier la publication',
'cancel_publication' => 'Annuler la publication',
'message_warning' => 'Vous n’avez pas saisi de message pour l’annonce de votre épisode !',
'message_warning_hint' => 'Ajouter un message augmente l’engagement social, menant à une meilleure visibilité pour votre épisode.',
'message_warning_submit' => 'Publish quand même',
], ],
'soundbites' => 'Extraits sonores', 'soundbites' => 'Extraits sonores',
'soundbites_form' => [ 'soundbites_form' => [
......
...@@ -225,9 +225,9 @@ return [ ...@@ -225,9 +225,9 @@ return [
one {<span class="font-semibold">#</span> abonné·e} one {<span class="font-semibold">#</span> abonné·e}
other {<span class="font-semibold">#</span> abonné·e·s} other {<span class="font-semibold">#</span> abonné·e·s}
}', }',
'notes' => '{numberOfNotes, plural, 'notes' => '{numberOfStatuses, plural,
one {<span class="font-semibold">#</span> note} one {<span class="font-semibold">#</span> message}
other {<span class="font-semibold">#</span> notes} other {<span class="font-semibold">#</span> messages}
}', }',
'activity' => 'Activité', 'activity' => 'Activité',
'episodes' => 'Épisodes', 'episodes' => 'Épisodes',
......