зеркало из https://github.com/nextcloud/spreed.git
Add system messages for group attendees
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
ff4ed33e8e
Коммит
b9e5fe2bcc
|
@ -261,6 +261,8 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob
|
|||
* `password_removed` - {actor} removed the password for the conversation
|
||||
* `user_added` - {actor} added {user} to the conversation
|
||||
* `user_removed` - {actor} removed {user} from the conversation
|
||||
* `group_added` - {actor} added group {group} to the conversation
|
||||
* `group_removed` - {actor} removed group {group} from the conversation
|
||||
* `moderator_promoted` - {actor} promoted {user} to moderator
|
||||
* `moderator_demoted` - {actor} demoted {user} from moderator
|
||||
* `guest_moderator_promoted` - {actor} promoted {user} to moderator
|
||||
|
|
|
@ -36,6 +36,8 @@ use OCA\Talk\Collaboration\Resources\ConversationProvider;
|
|||
use OCA\Talk\Collaboration\Resources\Listener as ResourceListener;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Dashboard\TalkWidget;
|
||||
use OCA\Talk\Events\AttendeesAddedEvent;
|
||||
use OCA\Talk\Events\AttendeesRemovedEvent;
|
||||
use OCA\Talk\Events\ChatEvent;
|
||||
use OCA\Talk\Events\RoomEvent;
|
||||
use OCA\Talk\Deck\DeckPluginLoader;
|
||||
|
@ -111,6 +113,8 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(UserChangedEvent::class, UserDisplayNameListener::class);
|
||||
$context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, DeckPluginLoader::class);
|
||||
$context->registerEventListener(RegisterOperationsEvent::class, RegisterOperationsListener::class);
|
||||
$context->registerEventListener(AttendeesAddedEvent::class, SystemMessageListener::class);
|
||||
$context->registerEventListener(AttendeesRemovedEvent::class, SystemMessageListener::class);
|
||||
|
||||
$context->registerSearchProvider(ConversationSearch::class);
|
||||
$context->registerSearchProvider(CurrentMessageSearch::class);
|
||||
|
|
|
@ -35,6 +35,8 @@ use OCP\Files\InvalidPathException;
|
|||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IPreview as IPreviewManager;
|
||||
use OCP\IURLGenerator;
|
||||
|
@ -46,6 +48,8 @@ class SystemMessage {
|
|||
|
||||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
/** @var IGroupManager */
|
||||
protected $groupManager;
|
||||
/** @var GuestManager */
|
||||
protected $guestManager;
|
||||
/** @var IPreviewManager */
|
||||
|
@ -62,15 +66,19 @@ class SystemMessage {
|
|||
/** @var string[] */
|
||||
protected $displayNames = [];
|
||||
/** @var string[] */
|
||||
protected $groupNames = [];
|
||||
/** @var string[] */
|
||||
protected $guestNames = [];
|
||||
|
||||
public function __construct(IUserManager $userManager,
|
||||
IGroupManager $groupManager,
|
||||
GuestManager $guestManager,
|
||||
IPreviewManager $previewManager,
|
||||
RoomShareProvider $shareProvider,
|
||||
IRootFolder $rootFolder,
|
||||
IURLGenerator $url) {
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->guestManager = $guestManager;
|
||||
$this->previewManager = $previewManager;
|
||||
$this->shareProvider = $shareProvider;
|
||||
|
@ -270,6 +278,22 @@ class SystemMessage {
|
|||
$parsedMessage = $this->l->t('An administrator removed {user}');
|
||||
}
|
||||
}
|
||||
} elseif ($message === 'group_added') {
|
||||
$parsedParameters['group'] = $this->getGroup($parameters['group']);
|
||||
$parsedMessage = $this->l->t('{actor} added group {group}');
|
||||
if ($currentUserIsActor) {
|
||||
$parsedMessage = $this->l->t('You added group {group}');
|
||||
} elseif ($cliIsActor) {
|
||||
$parsedMessage = $this->l->t('An administrator added group {group}');
|
||||
}
|
||||
} elseif ($message === 'group_removed') {
|
||||
$parsedParameters['group'] = $this->getGroup($parameters['group']);
|
||||
$parsedMessage = $this->l->t('{actor} removed group {group}');
|
||||
if ($currentUserIsActor) {
|
||||
$parsedMessage = $this->l->t('You removed group {group}');
|
||||
} elseif ($cliIsActor) {
|
||||
$parsedMessage = $this->l->t('An administrator removed group {group}');
|
||||
}
|
||||
} elseif ($message === 'moderator_promoted') {
|
||||
$parsedParameters['user'] = $this->getUser($parameters['user']);
|
||||
$parsedMessage = $this->l->t('{actor} promoted {user} to moderator');
|
||||
|
@ -519,6 +543,18 @@ class SystemMessage {
|
|||
];
|
||||
}
|
||||
|
||||
protected function getGroup(string $gid): array {
|
||||
if (!isset($this->groupNames[$gid])) {
|
||||
$this->groupNames[$gid] = $this->getDisplayNameGroup($gid);
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'group',
|
||||
'id' => $gid,
|
||||
'name' => $this->groupNames[$gid],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDisplayName(string $uid): string {
|
||||
$user = $this->userManager->get($uid);
|
||||
if ($user instanceof IUser) {
|
||||
|
@ -527,6 +563,14 @@ class SystemMessage {
|
|||
return $uid;
|
||||
}
|
||||
|
||||
protected function getDisplayNameGroup(string $gid): string {
|
||||
$group = $this->groupManager->get($gid);
|
||||
if ($group instanceof IGroup) {
|
||||
return $group->getDisplayName();
|
||||
}
|
||||
return $gid;
|
||||
}
|
||||
|
||||
protected function getGuest(Room $room, string $actorId): array {
|
||||
if (!isset($this->guestNames[$actorId])) {
|
||||
$this->guestNames[$actorId] = $this->getGuestName($room, $actorId);
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace OCA\Talk\Chat\SystemMessage;
|
|||
|
||||
use OCA\Talk\Chat\ChatManager;
|
||||
use OCA\Talk\Events\AddParticipantsEvent;
|
||||
use OCA\Talk\Events\AttendeesAddedEvent;
|
||||
use OCA\Talk\Events\AttendeesRemovedEvent;
|
||||
use OCA\Talk\Events\ModifyLobbyEvent;
|
||||
use OCA\Talk\Events\ModifyParticipantEvent;
|
||||
use OCA\Talk\Events\ModifyRoomEvent;
|
||||
|
@ -40,14 +42,16 @@ use OCA\Talk\Share\RoomShareProvider;
|
|||
use OCA\Talk\TalkSession;
|
||||
use OCA\Talk\Webinary;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Share\IShare;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
class Listener {
|
||||
class Listener implements IEventListener {
|
||||
|
||||
/** @var IRequest */
|
||||
protected $request;
|
||||
|
@ -331,6 +335,30 @@ class Listener {
|
|||
$dispatcher->addListener(RoomShareProvider::class . '::' . 'share_file_again', $listener);
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if ($event instanceof AttendeesAddedEvent) {
|
||||
$this->attendeesAddedEvent($event);
|
||||
} elseif ($event instanceof AttendeesRemovedEvent) {
|
||||
$this->attendeesRemovedEvent($event);
|
||||
}
|
||||
}
|
||||
|
||||
protected function attendeesAddedEvent(AttendeesAddedEvent $event): void {
|
||||
foreach ($event->getAttendees() as $attendee) {
|
||||
if ($attendee->getActorType() === Attendee::ACTOR_GROUPS) {
|
||||
$this->sendSystemMessage($event->getRoom(), 'group_added', ['group' => $attendee->getActorId()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function attendeesRemovedEvent(AttendeesRemovedEvent $event): void {
|
||||
foreach ($event->getAttendees() as $attendee) {
|
||||
if ($attendee->getActorType() === Attendee::ACTOR_GROUPS) {
|
||||
$this->sendSystemMessage($event->getRoom(), 'group_removed', ['group' => $attendee->getActorId()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function sendSystemMessage(Room $room, string $message, array $parameters = [], Participant $participant = null): void {
|
||||
if ($participant instanceof Participant) {
|
||||
$actorType = $participant->getAttendee()->getActorType();
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Events;
|
||||
|
||||
class AttendeesAddedEvent extends AttendeesEvent {
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Events;
|
||||
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Room;
|
||||
|
||||
class AttendeesEvent extends RoomEvent {
|
||||
/** @var Attendee[] */
|
||||
protected $attendees;
|
||||
|
||||
public function __construct(Room $room,
|
||||
array $attendees) {
|
||||
parent::__construct($room);
|
||||
$this->attendees = $attendees;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attendee[]
|
||||
*/
|
||||
public function getAttendees(): array {
|
||||
return $this->attendees;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Events;
|
||||
|
||||
class AttendeesRemovedEvent extends AttendeesEvent {
|
||||
}
|
|
@ -27,6 +27,8 @@ use OCA\Circles\Model\Circle;
|
|||
use OCA\Circles\Model\Member;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Events\AddParticipantsEvent;
|
||||
use OCA\Talk\Events\AttendeesAddedEvent;
|
||||
use OCA\Talk\Events\AttendeesRemovedEvent;
|
||||
use OCA\Talk\Events\JoinRoomGuestEvent;
|
||||
use OCA\Talk\Events\JoinRoomUserEvent;
|
||||
use OCA\Talk\Events\ModifyParticipantEvent;
|
||||
|
@ -275,6 +277,9 @@ class ParticipantService {
|
|||
$attendee->setParticipantType(Participant::GUEST);
|
||||
$attendee->setLastReadMessage($lastMessage);
|
||||
$this->attendeeMapper->insert($attendee);
|
||||
|
||||
$attendeeEvent = new AttendeesAddedEvent($room, [$attendee]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
}
|
||||
|
||||
$session = $this->sessionService->createSessionForAttendee($attendee);
|
||||
|
@ -306,6 +311,7 @@ class ParticipantService {
|
|||
$lastMessage = (int) $room->getLastMessage()->getId();
|
||||
}
|
||||
|
||||
$attendees = [];
|
||||
foreach ($participants as $participant) {
|
||||
$readPrivacy = Participant::PRIVACY_PUBLIC;
|
||||
if ($participant['actorType'] === Attendee::ACTOR_USERS) {
|
||||
|
@ -323,8 +329,13 @@ class ParticipantService {
|
|||
$attendee->setLastReadMessage($lastMessage);
|
||||
$attendee->setReadPrivacy($readPrivacy);
|
||||
$this->attendeeMapper->insert($attendee);
|
||||
|
||||
$attendees[] = $attendee;
|
||||
}
|
||||
|
||||
$attendeeEvent = new AttendeesAddedEvent($room, $attendees);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
|
||||
$this->dispatcher->dispatch(Room::EVENT_AFTER_USERS_ADD, $event);
|
||||
}
|
||||
|
||||
|
@ -377,6 +388,9 @@ class ParticipantService {
|
|||
$attendee->setParticipantType(Participant::USER);
|
||||
$attendee->setReadPrivacy(Participant::PRIVACY_PRIVATE);
|
||||
$this->attendeeMapper->insert($attendee);
|
||||
|
||||
$attendeeEvent = new AttendeesAddedEvent($room, [$attendee]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
}
|
||||
|
||||
$this->addUsers($room, $newParticipants);
|
||||
|
@ -448,6 +462,9 @@ class ParticipantService {
|
|||
// $attendee->setParticipantType(Participant::USER);
|
||||
// $attendee->setReadPrivacy(Participant::PRIVACY_PRIVATE);
|
||||
// $this->attendeeMapper->insert($attendee);
|
||||
//
|
||||
// $attendeeEvent = new AttendeesAddedEvent($room, [$attendee]);
|
||||
// $this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
// }
|
||||
|
||||
$this->addUsers($room, $newParticipants);
|
||||
|
@ -479,6 +496,9 @@ class ParticipantService {
|
|||
$this->attendeeMapper->insert($attendee);
|
||||
// FIXME handle duplicate invites gracefully
|
||||
|
||||
$attendeeEvent = new AttendeesAddedEvent($room, [$attendee]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
|
||||
return new Participant($room, $attendee, null);
|
||||
}
|
||||
|
||||
|
@ -538,12 +558,15 @@ class ParticipantService {
|
|||
|
||||
if ($participant->getAttendee()->getParticipantType() === Participant::USER_SELF_JOINED) {
|
||||
$this->attendeeMapper->delete($participant->getAttendee());
|
||||
|
||||
$attendeeEvent = new AttendeesRemovedEvent($room, [$participant->getAttendee()]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(Room::EVENT_AFTER_ROOM_DISCONNECT, $event);
|
||||
}
|
||||
|
||||
public function removeAttendee(Room $room, Participant $participant, string $reason): void {
|
||||
public function removeAttendee(Room $room, Participant $participant, string $reason, bool $attendeeEventIsTriggeredAlready = false): void {
|
||||
$isUser = $participant->getAttendee()->getActorType() === Attendee::ACTOR_USERS;
|
||||
|
||||
$sessions = $this->sessionService->getAllSessionsForAttendee($participant->getAttendee());
|
||||
|
@ -560,6 +583,11 @@ class ParticipantService {
|
|||
$this->sessionMapper->deleteByAttendeeId($participant->getAttendee()->getId());
|
||||
$this->attendeeMapper->delete($participant->getAttendee());
|
||||
|
||||
if (!$attendeeEventIsTriggeredAlready) {
|
||||
$attendeeEvent = new AttendeesRemovedEvent($room, [$participant->getAttendee()]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
}
|
||||
|
||||
if ($isUser) {
|
||||
$this->dispatcher->dispatch(Room::EVENT_AFTER_USER_REMOVE, $event);
|
||||
} else {
|
||||
|
@ -584,6 +612,7 @@ class ParticipantService {
|
|||
$groupsInRoom[] = $attendee->getActorId();
|
||||
}
|
||||
|
||||
$attendees = [];
|
||||
foreach ($removedGroup->getUsers() as $user) {
|
||||
try {
|
||||
$participant = $room->getParticipant($user->getUID());
|
||||
|
@ -597,11 +626,15 @@ class ParticipantService {
|
|||
continue;
|
||||
}
|
||||
|
||||
$attendees[] = $participant->getAttendee();
|
||||
if ($participant->getAttendee()->getParticipantType() === Participant::USER) {
|
||||
// Only remove normal users, not moderators/admins
|
||||
$this->removeAttendee($room, $participant, $reason);
|
||||
$this->removeAttendee($room, $participant, $reason, true);
|
||||
}
|
||||
}
|
||||
|
||||
$attendeeEvent = new AttendeesRemovedEvent($room, $attendees);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
}
|
||||
|
||||
public function removeUser(Room $room, IUser $user, string $reason): void {
|
||||
|
@ -623,6 +656,9 @@ class ParticipantService {
|
|||
|
||||
$this->attendeeMapper->delete($attendee);
|
||||
|
||||
$attendeeEvent = new AttendeesRemovedEvent($room, [$attendee]);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
|
||||
$this->dispatcher->dispatch(Room::EVENT_AFTER_USER_REMOVE, $event);
|
||||
}
|
||||
|
||||
|
@ -657,14 +693,20 @@ class ParticipantService {
|
|||
->andWhere($query->expr()->isNull('s.id'));
|
||||
|
||||
$attendeeIds = [];
|
||||
$attendees = [];
|
||||
$result = $query->execute();
|
||||
while ($row = $result->fetch()) {
|
||||
|
||||
$attendeeIds[] = (int) $row['a_id'];
|
||||
$attendees[] = $this->attendeeMapper->createAttendeeFromRow($row);
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
$this->attendeeMapper->deleteByIds($attendeeIds);
|
||||
|
||||
$attendeeEvent = new AttendeesRemovedEvent($room, $attendees);
|
||||
$this->dispatcher->dispatchTyped($attendeeEvent);
|
||||
|
||||
$this->dispatcher->dispatch(Room::EVENT_AFTER_GUESTS_CLEAN, $event);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче