[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:
parent
0caec6ab9e
commit
836560f55f
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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 %}
|
||||||
|
Loading…
Reference in New Issue
Block a user