Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing Update activity add cover and avatar removal #1492

Merged
merged 2 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/Controller/Api/User/UserDeleteImagesApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Controller\Api\User;

use App\DTO\UserResponseDto;
use App\Event\User\UserEditedEvent;
use App\Factory\UserFactory;
use App\Service\UserManager;
use Nelmio\ApiDocBundle\Attribute\Model;
Expand Down Expand Up @@ -51,7 +52,12 @@ public function avatar(
): JsonResponse {
$headers = $this->rateLimit($apiImageLimiter);

$manager->detachAvatar($this->getUserOrThrow());
$user = $this->getUserOrThrow();
$manager->detachAvatar($user);
/*
* Call edit so the @see UserEditedEvent is triggered and the changes are federated
*/
$manager->edit($user, $manager->createDto($user));

return new JsonResponse(
$this->serializeUser($factory->createDto($this->getUserOrThrow())),
Expand Down Expand Up @@ -94,7 +100,12 @@ public function cover(
): JsonResponse {
$headers = $this->rateLimit($apiImageLimiter);

$manager->detachCover($this->getUserOrThrow());
$user = $this->getUserOrThrow();
$manager->detachCover($user);
/*
* Call edit so the @see UserEditedEvent is triggered and the changes are federated
*/
$manager->edit($user, $manager->createDto($user));

return new JsonResponse(
$this->serializeUser($factory->createDto($this->getUserOrThrow())),
Expand Down
7 changes: 7 additions & 0 deletions src/Controller/User/Profile/UserEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

use App\Controller\AbstractController;
use App\DTO\UserDto;
use App\Exception\ImageDownloadTooLargeException;
use App\Form\UserBasicType;
use App\Form\UserEmailType;
use App\Form\UserPasswordType;
use App\Service\SettingsManager;
use App\Service\UserManager;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Form\FormError;
Expand All @@ -27,6 +29,7 @@ public function __construct(
private readonly UserPasswordHasherInterface $userPasswordHasher,
private readonly TranslatorInterface $translator,
private readonly Security $security,
private readonly SettingsManager $settingsManager,
) {
}

Expand Down Expand Up @@ -176,6 +179,10 @@ private function handleForm(
}

return $form;
} catch (ImageDownloadTooLargeException $e) {
$this->addFlash('error', $this->translator->trans('flash_image_download_too_large_error', ['%bytes%' => $this->settingsManager->getMaxImageByteString()]));

return null;
} catch (\Exception $e) {
return null;
}
Expand Down
7 changes: 6 additions & 1 deletion src/Controller/User/UserAvatarDeleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ public function __invoke(Request $request): Response
{
$this->denyAccessUnlessGranted('edit_profile', $this->getUserOrThrow());

$this->userManager->detachAvatar($this->getUserOrThrow());
$user = $this->getUserOrThrow();
$this->userManager->detachAvatar($user);
/*
* Call edit so the @see UserEditedEvent is triggered and the changes are federated
*/
$this->userManager->edit($user, $this->userManager->createDto($user));

if ($request->isXmlHttpRequest()) {
return new JsonResponse(
Expand Down
7 changes: 6 additions & 1 deletion src/Controller/User/UserCoverDeleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ public function __invoke(Request $request): Response
{
$this->denyAccessUnlessGranted('edit_profile', $this->getUserOrThrow());

$this->userManager->detachCover($this->getUserOrThrow());
$user = $this->getUserOrThrow();
$this->userManager->detachCover($user);
/*
* Call edit so the @see UserEditedEvent is triggered and the changes are federated
*/
$this->userManager->edit($user, $this->userManager->createDto($user));

if ($request->isXmlHttpRequest()) {
return new JsonResponse(
Expand Down
3 changes: 3 additions & 0 deletions src/MessageHandler/ActivityPub/Outbox/UpdateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use App\Service\DeliverManager;
use App\Service\SettingsManager;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

Expand All @@ -38,6 +39,7 @@ public function __construct(
private readonly DeliverManager $deliverManager,
private readonly UpdateWrapper $updateWrapper,
private readonly KernelInterface $kernel,
private readonly LoggerInterface $logger,
) {
parent::__construct($this->entityManager, $this->kernel);
}
Expand Down Expand Up @@ -88,6 +90,7 @@ public function doWork(MessageInterface $message): void
$activity = $this->updateWrapper->buildForActor($entity, $editedByUser);
if ($entity instanceof User) {
$inboxes = $this->userRepository->findAudience($entity);
$this->logger->debug('[UpdateHandler::doWork] sending update user activity for user {u} to {i}', ['u' => $entity->username, 'i' => join(', ', $inboxes)]);
} elseif ($entity instanceof Magazine) {
if ('random' === $entity->name) {
// do not federate the random magazine
Expand Down
9 changes: 9 additions & 0 deletions src/Service/ActivityPubManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ private function updateUser(string $actorUrl): ?User
$this->bus->dispatch(new DeleteImageMessage($user->avatar->getId()));
}
$user->avatar = $newImage;
} elseif (null !== $user->avatar) {
$this->bus->dispatch(new DeleteImageMessage($user->avatar->getId()));
$user->avatar = null;
}

// Only update cover if image is set
Expand All @@ -421,6 +424,9 @@ private function updateUser(string $actorUrl): ?User
$this->bus->dispatch(new DeleteImageMessage($user->cover->getId()));
}
$user->cover = $newImage;
} elseif (null !== $user->cover) {
$this->bus->dispatch(new DeleteImageMessage($user->cover->getId()));
$user->cover = null;
}

if (null !== $user->apFollowersUrl) {
Expand Down Expand Up @@ -565,6 +571,9 @@ private function updateMagazine(string $actorUrl): ?Magazine
$this->bus->dispatch(new DeleteImageMessage($magazine->icon->getId()));
}
$magazine->icon = $newImage;
} elseif (null !== $magazine->icon) {
$this->bus->dispatch(new DeleteImageMessage($magazine->icon->getId()));
$magazine->icon = null;
}

if ($actor['name']) {
Expand Down
40 changes: 37 additions & 3 deletions templates/user/settings/profile.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,54 @@
{{ form_start(form) }}
{{ component('editor_toolbar', {id: 'user_basic_about'}) }}
{{ form_row(form.about, {label: false, attr: {
placeholder: 'about',
'data-controller': 'input-length rich-textarea autogrow',
placeholder: 'about',
'data-controller': 'input-length rich-textarea autogrow',
'data-entry-link-create-target': 'user_about',
'data-action' : 'input-length#updateDisplay',
'data-input-length-max-value' : constant('App\\DTO\\UserDto::MAX_ABOUT_LENGTH')
}}) }}
{{ form_row(form.username, {label: 'username', attr: {
'data-controller': 'input-length autogrow',
'data-controller': 'input-length autogrow',
'data-entry-link-create-target': 'user_about',
'data-action' : 'input-length#updateDisplay',
'data-input-length-max-value' : constant('App\\DTO\\UserDto::MAX_USERNAME_LENGTH')
}}) }}
{{ form_row(form.avatar, {label: 'avatar'}) }}
{% if app.user.avatar is not same as null %}
<div class="actions">
<ul style="width: 100%">
<img width="40"
height="40"
src="{{ asset(app.user.avatar.filePath)|imagine_filter('entry_thumb') }}"
alt="{{ app.user.avatar.altText }}" />
<button formaction="{{ path('user_settings_avatar_delete') }}"
class="btn-link"
aria-label="{{ 'remove_user_avatar'|trans }}"
title="{{ 'remove_user_avatar'|trans }}"
data-action="confirmation#ask" data-confirmation-message-param="{{ 'are_you_sure'|trans }}">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</button>
</ul>
</div>
{% endif %}
{{ form_row(form.cover, {label: 'cover'}) }}
{% if app.user.cover is not same as null %}
<div class="actions">
<ul style="width: 100%">
<img width="40"
height="40"
src="{{ asset(app.user.cover.filePath)|imagine_filter('entry_thumb') }}"
alt="{{ app.user.cover.altText }}" />
<button formaction="{{ path('user_settings_cover_delete') }}"
class="btn-link"
aria-label="{{ 'remove_user_cover'|trans }}"
title="{{ 'remove_user_cover'|trans }}"
data-action="confirmation#ask" data-confirmation-message-param="{{ 'are_you_sure'|trans }}">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</button>
</ul>
</div>
{% endif %}
<div class="row actions">
{{ form_row(form.submit, {label: 'save', attr: {class: 'btn btn__primary'}}) }}
</div>
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ add_comment: Add comment
add_post: Add post
add_media: Add media
remove_media: Remove media
remove_user_avatar: Remove avatar
remove_user_cover: Remove cover
markdown_howto: How does the editor work?
enter_your_comment: Enter your comment
enter_your_post: Enter your post
Expand Down
Loading