diff --git a/plugins/RepeatNote/Entity/NoteRepeat.php b/plugins/RepeatNote/Entity/NoteRepeat.php index 00098f0f77..e38c370c45 100644 --- a/plugins/RepeatNote/Entity/NoteRepeat.php +++ b/plugins/RepeatNote/Entity/NoteRepeat.php @@ -76,6 +76,16 @@ class NoteRepeat extends Entity return $this->repeat_of; } + + /** + * @param Note $note + * @return bool Returns true if Note provided is a repeat of another Note + */ + public static function isNoteRepeat(Note $note): bool + { + return DB::count(self::class, ['note_id' => $note->getId()]) > 0; + } + public static function getNoteRepeats(Note $note): array { return DB::dql( diff --git a/plugins/RepeatNote/RepeatNote.php b/plugins/RepeatNote/RepeatNote.php index 5d85cc4f00..92f6ced5c9 100644 --- a/plugins/RepeatNote/RepeatNote.php +++ b/plugins/RepeatNote/RepeatNote.php @@ -31,8 +31,6 @@ use App\Entity\Activity; use App\Entity\Actor; use App\Entity\Note; use App\Util\Common; -use App\Util\Exception\DuplicateFoundException; -use App\Util\Exception\NotFoundException; use App\Util\Exception\ServerException; use App\Util\Formatting; use Component\Language\Entity\Language; @@ -92,11 +90,11 @@ class RepeatNote extends NoteHandlerPlugin public static function unrepeatNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity { - $already_repeated = DB::findBy('note_repeat', ['actor_id' => $actor_id, 'repeat_of' => $note_id])[0] ?? null; + $already_repeated = DB::findBy(NoteRepeat::class, ['actor_id' => $actor_id, 'repeat_of' => $note_id])[0] ?? null; if (!\is_null($already_repeated)) { // If it was repeated, then we can undo it // Find previous repeat activity - $already_repeated_activity = DB::findBy('activity', [ + $already_repeated_activity = DB::findBy(Activity::class, [ 'actor_id' => $actor_id, 'verb' => 'repeat', 'object_type' => 'note', @@ -104,10 +102,10 @@ class RepeatNote extends NoteHandlerPlugin ])[0] ?? null; // Remove the clone note - DB::findBy(Note::class, ['id' => $already_repeated->getNoteId()])[0]->delete(); + DB::findBy(Note::class, ['id' => $already_repeated->getNoteId()])[0]->delete(actor: Actor::getById($actor_id)); // Remove from the note_repeat table - DB::remove(DB::findBy('note_repeat', ['note_id' => $already_repeated->getNoteId()])[0]); + DB::remove(DB::findBy(NoteRepeat::class, ['note_id' => $already_repeated->getNoteId()])[0]); // Log an activity $undo_repeat_activity = Activity::create([ @@ -143,6 +141,30 @@ class RepeatNote extends NoteHandlerPlugin } } + /** + * Filters repeats out of Conversations, and replaces a repeat with the original Note on Actor feed + * + * @return bool + */ + public function onFilterNoteList(?Actor $actor, array &$notes, Request $request) + { + // Replaces repeat with original note on Actor feed + // it's pretty cool + if (str_starts_with($request->get('_route'), 'actor_view_')) { + $notes = array_map( + fn (Note $note) => NoteRepeat::isNoteRepeat($note) + ? Note::getById(NoteRepeat::getByPK($note->getId())->getRepeatOf()) + : $note, + $notes, + ); + return Event::next; + } + + // Filter out repeats altogether + $notes = array_filter($notes, fn (Note $note) => !NoteRepeat::isNoteRepeat($note)); + return Event::next; + } + /** * HTML rendering event that adds the repeat form as a note * action, if a user is logged in @@ -158,22 +180,10 @@ class RepeatNote extends NoteHandlerPlugin // If note is repeated, "is_repeated" is 1, 0 otherwise. $is_repeat = ($note_repeat = DB::findBy('note_repeat', [ - 'actor_id' => $user->getId(), - 'note_id' => $note->getId(), + 'actor_id' => $user->getId(), + 'repeat_of' => $note->getId(), ])) !== [] ? 1 : 0; - // If note was already repeated, do not add the action - try { - if (DB::findOneBy('note_repeat', [ - 'repeat_of' => $note->getId(), - 'actor_id' => $user->getId(), - ])) { - return Event::next; - } - } catch (DuplicateFoundException|NotFoundException) { - // It's okay - } - // Generating URL for repeat action route $args = ['note_id' => $is_repeat === 0 ? $note->getId() : $note_repeat[0]->getRepeatOf()]; $type = Router::ABSOLUTE_PATH;