[CARDS][Note] AppendCardNote event overhaul

[PLUGINS][Favourite] Added complementary information on user action

[COMPONENTS][Conversation] Fixed AppendCardNote issue where cached query
would only act on Notes with depth > 1
This commit is contained in:
Eliseu Amaro 2021-12-29 17:54:02 +00:00
parent 0caec6ab9e
commit 836560f55f
Signed by: eliseuamaro
GPG Key ID: 96DA09D4B97BC2D5
7 changed files with 83 additions and 80 deletions

View File

@ -118,45 +118,29 @@ class Conversation extends Component
*/ */
public function onAppendCardNote(array $vars, array &$result): bool public function onAppendCardNote(array $vars, array &$result): bool
{ {
// if note is the original, append on end "user replied to this" // If note is the original and user isn't the one who repeated, append on end "user repeated this"
// if note is the reply itself: append on end "in response to user in conversation" // If user is the one who repeated, append on end "you repeated this, remove repeat?"
$check_user = !\is_null(Common::user()); $check_user = !\is_null(Common::user());
$note = $vars['note'];
$complementary_info = ''; // The current Note being rendered
$reply_actor = []; $note = $vars['note'];
$note_replies = $note->getReplies();
// Get actors who replied // Will have actors array, and action string
// Actors are the subjects, action is the verb (in the final phrase)
$reply_actors = [];
$note_replies = $note->getReplies();
// Get actors who repeated the note
foreach ($note_replies as $reply) { foreach ($note_replies as $reply) {
$reply_actor[] = Actor::getByPK($reply->getActorId()); $reply_actors[] = Actor::getByPK($reply->getActorId());
} }
if (\count($reply_actor) < 1) { if (\count($reply_actors) < 1) {
return Event::next; return Event::next;
} }
// Filter out multiple replies from the same actor // Filter out multiple replies from the same actor
$reply_actor = array_unique($reply_actor, \SORT_REGULAR); $reply_actors = array_unique($reply_actors, SORT_REGULAR);
$result[] = ['actors' => $reply_actors, 'action' => 'replied to'];
// Add to complementary info
foreach ($reply_actor as $actor) {
$reply_actor_url = $actor->getUrl();
$reply_actor_nickname = $actor->getNickname();
if ($check_user && $actor->getId() === (Common::actor())->getId()) {
// If the reply is yours
$you_translation = _m('You');
$prepend = "<a href={$reply_actor_url}>{$you_translation}</a>, " . ($prepend = &$complementary_info);
$complementary_info = $prepend;
} else {
// If the repeat is from someone else
$complementary_info .= "<a href={$reply_actor_url}>{$reply_actor_nickname}</a>, ";
}
}
$complementary_info = rtrim(trim($complementary_info), ',');
$complementary_info .= _m(' replied to this note.');
$result[] = Formatting::twigRenderString($complementary_info, []);
return Event::next; return Event::next;
} }

View File

@ -23,8 +23,10 @@ declare(strict_types = 1);
namespace Component\Conversation\Entity; namespace Component\Conversation\Entity;
use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use App\Core\Router\Router; use App\Core\Router\Router;
use App\Entity\Note;
/** /**
* Entity class for Conversations * Entity class for Conversations

View File

@ -21,11 +21,12 @@ declare(strict_types = 1);
namespace Plugin\Favourite\Entity; namespace Plugin\Favourite\Entity;
use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use App\Entity\Note; use App\Entity\Note;
use DateTimeInterface; use DateTimeInterface;
class Favourite extends Entity class NoteFavourite extends Entity
{ {
// {{{ Autocode // {{{ Autocode
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
@ -81,6 +82,20 @@ class Favourite extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
// }}} Autocode // }}} Autocode
public static function getNoteFavouriteActors(Note $note): array
{
return DB::dql(
<<<'EOF'
select a from actor as a
inner join note_favourite as nf
with nf.note_id = :note_id
where a.id = nf.actor_id
order by nf.created DESC
EOF,
['note_id' => $note->getId()],
);
}
public function getNotificationTargetIds(array $ids_already_known = [], ?int $sender_id = null, bool $include_additional = true): array public function getNotificationTargetIds(array $ids_already_known = [], ?int $sender_id = null, bool $include_additional = true): array
{ {
if (!\array_key_exists('object', $ids_already_known)) { if (!\array_key_exists('object', $ids_already_known)) {
@ -102,7 +117,7 @@ class Favourite extends Entity
public static function schemaDef() public static function schemaDef()
{ {
return [ return [
'name' => 'favourite', 'name' => 'note_favourite',
'fields' => [ 'fields' => [
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'note that is the favorite of'], 'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'note that is the favorite of'],
'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'actor who favourited this note'], // note: formerly referenced notice.id, but we can now record remote users' favorites 'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'actor who favourited this note'], // note: formerly referenced notice.id, but we can now record remote users' favorites

View File

@ -37,7 +37,7 @@ use App\Entity\Note;
use App\Util\Common; use App\Util\Common;
use App\Util\Nickname; use App\Util\Nickname;
use DateTime; use DateTime;
use Plugin\Favourite\Entity\Favourite as FavouriteEntity; use Plugin\Favourite\Entity\NoteFavourite as FavouriteEntity;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Favourite extends NoteHandlerPlugin class Favourite extends NoteHandlerPlugin
@ -45,7 +45,7 @@ class Favourite extends NoteHandlerPlugin
public static function favourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity public static function favourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
{ {
$opts = ['note_id' => $note_id, 'actor_id' => $actor_id]; $opts = ['note_id' => $note_id, 'actor_id' => $actor_id];
$note_already_favoured = DB::find('favourite', $opts); $note_already_favoured = DB::find('note_favourite', $opts);
$activity = null; $activity = null;
if (\is_null($note_already_favoured)) { if (\is_null($note_already_favoured)) {
DB::persist(FavouriteEntity::create($opts)); DB::persist(FavouriteEntity::create($opts));
@ -65,7 +65,7 @@ class Favourite extends NoteHandlerPlugin
public static function unfavourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity public static function unfavourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
{ {
$note_already_favoured = DB::find('favourite', ['note_id' => $note_id, 'actor_id' => $actor_id]); $note_already_favoured = DB::find('note_favourite', ['note_id' => $note_id, 'actor_id' => $actor_id]);
$activity = null; $activity = null;
if (!\is_null($note_already_favoured)) { if (!\is_null($note_already_favoured)) {
DB::remove($note_already_favoured); DB::remove($note_already_favoured);
@ -98,7 +98,7 @@ class Favourite extends NoteHandlerPlugin
// If note is favourite, "is_favourite" is 1 // If note is favourite, "is_favourite" is 1
$opts = ['note_id' => $note->getId(), 'actor_id' => $user->getId()]; $opts = ['note_id' => $note->getId(), 'actor_id' => $user->getId()];
$is_favourite = DB::find('favourite', $opts) !== null; $is_favourite = DB::find('note_favourite', $opts) !== null;
// Generating URL for favourite action route // Generating URL for favourite action route
$args = ['id' => $note->getId()]; $args = ['id' => $note->getId()];
@ -125,10 +125,24 @@ class Favourite extends NoteHandlerPlugin
public function onAppendCardNote(array $vars, array &$result) public function onAppendCardNote(array $vars, array &$result)
{ {
// if note is the original, append on end "user favoured this" // If note is the original and user isn't the one who repeated, append on end "user repeated this"
$actor = $vars['actor']; // If user is the one who repeated, append on end "you repeated this, remove repeat?"
$note = $vars['note']; $check_user = !\is_null(Common::user());
// The current Note being rendered
$note = $vars['note'];
// Will have actors array, and action string
// Actors are the subjects, action is the verb (in the final phrase)
$favourite_actors = FavouriteEntity::getNoteFavouriteActors($note);
if (\count($favourite_actors) < 1) {
return Event::next;
}
// Filter out multiple replies from the same actor
$favourite_actors = array_unique($favourite_actors, SORT_REGULAR);
$result[] = ['actors' => $favourite_actors, 'action' => 'favourited'];
return Event::next; return Event::next;
} }

View File

@ -245,57 +245,35 @@ class RepeatNote extends NoteHandlerPlugin
* @param array $result Rendered String containing anchors for Actors that * @param array $result Rendered String containing anchors for Actors that
* repeated the Note * repeated the Note
* *
* @return array|bool * @return bool
*/ */
public function onAppendCardNote(array $vars, array &$result) public function onAppendCardNote(array $vars, array &$result)
{ {
// if note is the original and user isn't the one who repeated, append on end "user repeated this" // If note is the original and user isn't the one who repeated, append on end "user repeated this"
// if user is the one who repeated, append on end "you repeated this, remove repeat?" // If user is the one who repeated, append on end "you repeated this, remove repeat?"
$check_user = !\is_null(Common::user()); $check_user = !\is_null(Common::user());
// The current Note being rendered
$note = $vars['note']; $note = $vars['note'];
$complementary_info = ''; // Will have actors array, and action string
$repeat_actor = []; // Actors are the subjects, action is the verb (in the final phrase)
$repeat_actors = [];
$note_repeats = NoteRepeat::getNoteRepeats($note); $note_repeats = NoteRepeat::getNoteRepeats($note);
// Get actors who replied // Get actors who repeated the note
foreach ($note_repeats as $reply) { foreach ($note_repeats as $repeat) {
$repeat_actor[] = Actor::getByPK($reply->getActorId()); $repeat_actors[] = Actor::getByPK($repeat->getActorId());
} }
if (\count($repeat_actor) < 1) { if (\count($repeat_actors) < 1) {
return Event::next; return Event::next;
} }
// Filter out multiple replies from the same actor // Filter out multiple replies from the same actor
$repeat_actor = array_unique($repeat_actor, SORT_REGULAR); $repeat_actors = array_unique($repeat_actors, SORT_REGULAR);
$result[] = ['actors' => $repeat_actors, 'action' => 'repeated'];
// Add to complementary info return Event::next;
foreach ($repeat_actor as $actor) {
$repeat_actor_url = $actor->getUrl();
$repeat_actor_nickname = $actor->getNickname();
if ($check_user && $actor->getId() === (Common::actor())->getId()) {
// If the repeat is yours
try {
$you_translation = _m('You');
} catch (ServerException $e) {
$you_translation = 'You';
}
$prepend = "<a href={$repeat_actor_url}>{$you_translation}</a>, " . ($prepend = &$complementary_info);
$complementary_info = $prepend;
} else {
// If the repeat is from someone else
$complementary_info .= "<a href={$repeat_actor_url}>{$repeat_actor_nickname}</a>, ";
}
}
$complementary_info = rtrim(trim($complementary_info), ',');
$complementary_info .= ' repeated this note.';
$result[] = Formatting::twigRenderString($complementary_info, []);
return $result;
} }
/** /**

View File

@ -354,7 +354,7 @@ class Note extends Entity
*/ */
public function getReplies(): array public function getReplies(): array
{ {
return Cache::get('note-replies-' . $this->getId(), fn () => DB::dql('select n from note n where n.reply_to = :id', ['id' => $this->getId()])); return DB::findBy('note', ['reply_to' => $this->getId()], order_by: ['created' => 'DESC', 'id' => 'DESC']);
} }
/** /**

View File

@ -134,11 +134,21 @@
{{ block('note_replies') }} {{ block('note_replies') }}
{% for block in handle_event('AppendCardNote', {'note': note, 'actor': note.getActor() }) %}
<aside title="{{ 'Note\'s complementary information' | trans }}" class="note-complementary"> {% for complementary_info in handle_event('AppendCardNote', {'note': note }) %}
{{ block | raw }} <aside title="{{ 'Note\'s complementary information' | trans }}" class="note-complementary">
</aside> {% for complementary_info_actor in complementary_info['actors'] %}
{% if complementary_info_actor is defined %}
<a href="{{ complementary_info_actor.getUrl() }}">{{ complementary_info_actor.getNickname() }}</a>
{% endif %}
{% endfor %}
{% if complementary_info['action'] is defined and not null %}
{{ ' has ' ~ complementary_info['action'] ~ ' this note' | trans }}
{% endif %}
</aside>
{% endfor %} {% endfor %}
</div> </div>
</article> </article>
{% endmacro macro_note %} {% endmacro macro_note %}