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

Add listable scope attribute for conversations #4706

Merged
merged 34 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
17971cd
Add listable flags attribute for conversations
PVince81 Dec 1, 2020
9646678
Added search provider for listed conversations
PVince81 Dec 1, 2020
f4d2622
WIP add listed conversation to the left sidebar results
PVince81 Dec 1, 2020
353206e
Adjust approach for search results for listable rooms
PVince81 Dec 2, 2020
65238d1
Adjustments for listable rooms after review
PVince81 Dec 2, 2020
fddac32
Tweak left sidebar behavior with listed search results
PVince81 Dec 2, 2020
6f8d1e6
Make it possible to join listed group conversations
PVince81 Dec 2, 2020
4b58da2
Fix filtering of listable rooms
PVince81 Dec 2, 2020
138aeb4
Fix participant service guest user check
PVince81 Dec 2, 2020
3276538
Switch+scroll to joined listed conversation
PVince81 Dec 3, 2020
89f05b4
Add conversation to store early when joining
PVince81 Dec 3, 2020
0aa0dcf
Apply suggestions from code review of listable rooms feature
PVince81 Dec 4, 2020
fea3c64
Post a system message when joining a listable room
PVince81 Dec 4, 2020
74dd434
Don't add conversation to list for guests
PVince81 Dec 4, 2020
506358d
Unit tests for system messages
PVince81 Dec 4, 2020
b7a118a
Check that guests app is enabled when checking
PVince81 Dec 7, 2020
52b88a9
Cleanup listed room code after review
PVince81 Dec 7, 2020
6d75ad2
Added integration tests for joining listable rooms
PVince81 Dec 7, 2020
7748fb9
Extend spreedcheats to allow creating guest account users
PVince81 Dec 8, 2020
0cdd452
Abort php test server on ctrl+c
PVince81 Dec 9, 2020
bcc9f8f
Fix updating listable attribute from occ
PVince81 Dec 9, 2020
10840fd
Fix tests for listable conversations
PVince81 Dec 9, 2020
0e1ed5d
Reword listable in UI by calling it findable
PVince81 Dec 10, 2020
2b54740
Moved ListableSettings into an own component
PVince81 Dec 10, 2020
777c7b6
Changed wording to say visible instead of listable
PVince81 Dec 10, 2020
4d4a484
Added listable settings to new conversation dialog
PVince81 Dec 10, 2020
549e9ec
Small adjustments to listable feature after reviews
PVince81 Dec 11, 2020
fa74ef3
Move listable and locking to new section
PVince81 Dec 11, 2020
5a3a552
Revert "Added search provider for listed conversations"
PVince81 Dec 11, 2020
a4a6c02
Improve room display name protection
PVince81 Dec 11, 2020
f04e3b5
Make listable column smallint
PVince81 Dec 11, 2020
63b020a
Remove redundant isset
PVince81 Dec 11, 2020
71fa517
Adjusted listable docs + increased version
PVince81 Dec 14, 2020
bedea3e
Adjust listable setting field width
PVince81 Dec 14, 2020
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
2 changes: 2 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,14 @@ steps:
environment:
APP_NAME: spreed
CORE_BRANCH: master
GUESTS_BRANCH: master
DATABASEHOST: sqlite
commands:
- bash tests/drone-run-integration-tests.sh || exit 0
- wget https://github.com/raw/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST
- cd ../server
- git clone --depth 1 -b "$GUESTS_BRANCH" https://github.com/nextcloud/guests apps/guests
- ./occ app:enable $APP_NAME
- cd apps/$APP_NAME

Expand Down
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m

]]></description>

<version>11.0.0-dev.9</version>
<version>11.0.0-dev.10</version>
<licence>agpl</licence>

<author>Daniel Calviño Sánchez</author>
Expand Down
17 changes: 17 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@
'apiVersion' => 'v(1|2|3)',
],
],
[
'name' => 'Room#getListedRooms',
'url' => '/api/{apiVersion}/listed-room',
'verb' => 'GET',
'requirements' => [
'apiVersion' => 'v3',
],
],
[
'name' => 'Room#createRoom',
'url' => '/api/{apiVersion}/room',
Expand Down Expand Up @@ -254,6 +262,15 @@
'token' => '^[a-z0-9]{4,30}$',
],
],
[
'name' => 'Room#setListable',
'url' => '/api/{apiVersion}/room/{token}/listable',
'verb' => 'PUT',
'requirements' => [
'apiVersion' => 'v3',
'token' => '^[a-z0-9]{4,30}$',
],
],
[
'name' => 'Room#setPassword',
'url' => '/api/{apiVersion}/room/{token}/password',
Expand Down
1 change: 1 addition & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ title: Capabilities
* `config => previews => max-gif-size` - Maximum size in bytes below which a GIF can be embedded directly in the page at render time. Bigger files will be rendered statically using the preview endpoint instead. Can be set with `occ config:app:set spreed max-gif-size --value=X` where X is the new value in bytes. Defaults to 3 MB.
* `chat-read-status` - On conversation API v3 and the chat API the last common read message is exposed which can be used to update the "read status" flag of own chat messages. The info should be shown only when the user also shares their read status. The user's value can be found in `config => chat => read-privacy`.
* `config => chat => read-privacy` - See `chat-read-status`
* `listable-rooms` - Conversations can searched for even when not joined. A "listable" attribute set on rooms defines the scope of who can find it.
5 changes: 4 additions & 1 deletion docs/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`
`status` | string | Optional: Only available with `includeStatus=true` and for users with a set status
`statusIcon` | string | Optional: Only available with `includeStatus=true` and for users with a set status
`statusMessage` | string | Optional: Only available with `includeStatus=true` and for users with a set status

## System messages

* `conversation_created` - {actor} created the conversation
Expand All @@ -160,6 +160,9 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`
* `call_ended` - Call with {user1}, {user2}, {user3}, {user4} and {user5} (Duration 30:23)
* `read_only_off` - {actor} unlocked the conversation
* `read_only` - {actor} locked the conversation
* `listable_none` - {actor} made the conversation visible for nobody
* `listable_users` - {actor} made the conversation visible for regular users
* `listable_all` - {actor} made the conversation visible for everone which includes users and guests
* `lobby_timer_reached` - The conversation is now open to everyone
* `lobby_none` - {actor} opened the conversation to everyone
* `lobby_non_moderators` - {actor} restricted the conversation to moderators
Expand Down
5 changes: 5 additions & 0 deletions docs/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ title: Constants
* `0` read-write
* `1` read-only

## Listable scope
* `0` participants only
* `1` regular users only, excluding guest app users
* `2` everyone

## Participant types
* `1` owner
* `2` moderator
Expand Down
36 changes: 36 additions & 0 deletions docs/conversation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@
* Base endpoint for API v2 is: `/ocs/v2.php/apps/spreed/api/v2`
* Base endpoint for API v3 is: `/ocs/v2.php/apps/spreed/api/v3`

## Get listed conversations

* Method: `GET`
* Endpoint: `/listed-room`

* Response:
- Status code:
+ `200 OK`
+ `401 Unauthorized` when the user is not logged in

- Header:

field | type | Description
------|------|------------
`searchTerm` | string | search term

- Data: See array definition in `Get user´s conversations`

## Get user´s conversations

* Method: `GET`
Expand Down Expand Up @@ -38,6 +56,7 @@
`participantInCall` | bool | 🏴 v1 | Flag if the current user is in the call (deprecated, use `participantFlags` instead)
`participantFlags` | int | * | Flags of the current user (only available with `in-call-flags` capability)
`readOnly` | int | * | Read-only state for the current user (only available with `read-only-rooms` capability)
`listable` | int | * | Listable scope for the room (only available with `listable-rooms` capability)
`count` | int | 🏴 v1 | **Deprecated:** ~~Number of active users~~ - always returns `0`
`numGuests` | int | 🏴 v1 | Number of active guests
`lastPing` | int | * | Timestamp of the last ping of the current user (should be used for sorting)
Expand Down Expand Up @@ -266,3 +285,20 @@
+ `400 Bad Request` When the the given level is invalid
+ `401 Unauthorized` When the participant is a guest
+ `404 Not Found` When the conversation could not be found for the participant

## Set listable scope for a conversation

* Method: `PUT`
* Endpoint: `/room/{token}/listable`
* Data:

field | type | Description
------|------|------------
`scope` | int | New flags for the conversation

* Response:
- Status code:
+ `200 OK`
+ `400 Bad Request` When the conversation type does not support making it listable (only group and public conversation)
+ `403 Forbidden` When the current user is not a moderator/owner or the conversation is not a public conversation
+ `404 Not Found` When the conversation could not be found for the participant
8 changes: 7 additions & 1 deletion docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Explanations:
* Event name: `OCA\Talk\Controller\RoomController::EVENT_BEFORE_ROOMS_GET`
* Since: 8.0.0


### Create conversation

* Event class: `OCA\Talk\Events\RoomEvent`
Expand Down Expand Up @@ -54,6 +53,13 @@ Explanations:
* After event name: `OCA\Talk\Room::EVENT_AFTER_READONLY_SET`
* Since: 8.0.0

### Set listable

* Event class: `OCA\Talk\Events\ModifyRoomEvent`
* Before event name: `OCA\Talk\Room::EVENT_BEFORE_LISTABLE_SET`
* After event name: `OCA\Talk\Room::EVENT_AFTER_LISTABLE_SET`
* Since: 11.0.0

### Set lobby

* Event class: `OCA\Talk\Events\ModifyLobbyEvent`
Expand Down
1 change: 1 addition & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function getCapabilities(): array {
'invite-groups-and-mails',
'locked-one-to-one-rooms',
'read-only-rooms',
'listable-rooms',
'chat-read-marker',
'webinary-lobby',
'start-call-flag',
Expand Down
21 changes: 21 additions & 0 deletions lib/Chat/Parser/SystemMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,27 @@ public function parseMessage(Message $chatMessage): void {
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator locked the conversation');
}
} elseif ($message === 'listable_none') {
$parsedMessage = $this->l->t('{actor} made the conversation invisible');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You made the conversation invisible');
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator made the conversation invisible');
}
} elseif ($message === 'listable_users') {
$parsedMessage = $this->l->t('{actor} made the conversation visible for registered users only');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You made the conversation visible for registered users only');
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator made the visible for registered users only');
}
} elseif ($message === 'listable_all') {
$parsedMessage = $this->l->t('{actor} made the conversation visible for everyone');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You made the conversation visible for everyone');
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator made the conversation visible for everyone');
}
} elseif ($message === 'lobby_timer_reached') {
$parsedMessage = $this->l->t('The conversation is now open to everyone');
} elseif ($message === 'lobby_none') {
Expand Down
45 changes: 37 additions & 8 deletions lib/Chat/SystemMessage/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ public static function register(IEventDispatcher $dispatcher): void {
$listener->sendSystemMessage($room, 'read_only_off');
}
});
$dispatcher->addListener(Room::EVENT_AFTER_LISTABLE_SET, static function (ModifyRoomEvent $event) {
$room = $event->getRoom();

/** @var self $listener */
$listener = \OC::$server->query(self::class);

if ($event->getNewValue() === Room::LISTABLE_NONE) {
$listener->sendSystemMessage($room, 'listable_none');
} elseif ($event->getNewValue() === Room::LISTABLE_USERS) {
$listener->sendSystemMessage($room, 'listable_users');
} elseif ($event->getNewValue() === Room::LISTABLE_ALL) {
$listener->sendSystemMessage($room, 'listable_all');
}
});
$dispatcher->addListener(Room::EVENT_AFTER_LOBBY_STATE_SET, static function (ModifyLobbyEvent $event) {
if ($event->getNewValue() === $event->getOldValue()) {
return;
Expand All @@ -196,26 +210,36 @@ public static function register(IEventDispatcher $dispatcher): void {
});

$dispatcher->addListener(Room::EVENT_AFTER_USERS_ADD, static function (AddParticipantsEvent $event) {
$participants = $event->getParticipants();
$user = \OC::$server->getUserSession()->getUser();
$userId = $user instanceof IUser ? $user->getUID() : null;

$room = $event->getRoom();

if ($room->getType() === Room::ONE_TO_ONE_CALL) {
return;
}

/** @var self $listener */
$listener = \OC::$server->query(self::class);

$participants = $event->getParticipants();

foreach ($participants as $participant) {
if ($participant['actorType'] !== 'users') {
continue;
}

$userJoinedFileRoom = $room->getObjectType() === 'file' &&
(!isset($participant['participantType']) || $participant['participantType'] !== Participant::USER_SELF_JOINED);
if ($userJoinedFileRoom || $userId !== $participant['actorId']) {
$participantType = null;
if (isset($participant['participantType'])) {
$participantType = $participant['participantType'];
}

$userJoinedFileRoom = $room->getObjectType() === 'file' && $participantType !== Participant::USER_SELF_JOINED;

// add a message "X joined the conversation", whenever user $userId:
if (
// - has joined a file room but not through a public link
$userJoinedFileRoom
// - has been added by another user (and not when creating a conversation)
|| $listener->getUserId() !== $participant['actorId']
// - has joined a listable room on their own
|| $participantType === Participant::USER) {
$listener->sendSystemMessage($room, 'user_added', ['user' => $participant['actorId']]);
}
}
Expand Down Expand Up @@ -314,4 +338,9 @@ protected function sendSystemMessage(Room $room, string $message, array $paramet
$referenceId
);
}

protected function getUserId() {
$user = $this->userSession->getUser();
return $user instanceof IUser ? $user->getUID() : null;
}
}
30 changes: 30 additions & 0 deletions lib/Command/Room/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ protected function configure(): void {
null,
InputOption::VALUE_NONE,
'Creates the room with read-only access only if set'
)->addOption(
'listable',
null,
InputOption::VALUE_REQUIRED,
'Creates the room with the given listable scope'
)->addOption(
'password',
null,
Expand All @@ -95,10 +100,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$groups = $input->getOption('group');
$public = $input->getOption('public');
$readonly = $input->getOption('readonly');
$listable = $input->getOption('listable');
$password = $input->getOption('password');
$owner = $input->getOption('owner');
$moderators = $input->getOption('moderator');

if (!in_array($readOnly, [null, (string)Room::READ_WRITE, (string)Room::READ_ONLY], true)) {
$output->writeln('<error>Invalid value for option "--readonly" given.</error>');
return 1;
}

if (!in_array($listable, [
null,
(string)Room::LISTABLE_NONE,
(string)Room::LISTABLE_USERS,
(string)Room::LISTABLE_ALL,
], true)) {
$output->writeln('<error>Invalid value for option "--listable" given.</error>');
return 1;
}

$roomType = $public ? Room::PUBLIC_CALL : Room::GROUP_CALL;
try {
$room = $this->roomService->createConversation($roomType, $name);
Expand All @@ -116,6 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

$this->setRoomReadOnly($room, $readonly);
$this->setRoomListable($room, (int)$listable);

if ($password !== null) {
$this->setRoomPassword($room, $password);
Expand Down Expand Up @@ -150,6 +172,14 @@ public function completeOptionValues($optionName, CompletionContext $context) {
case 'owner':
case 'moderator':
return $this->completeParticipantValues($context);
case 'readonly':
return [(string)Room::READ_ONLY, (string)Room::READ_WRITE];
case 'listable':
return [
(string)Room::LISTABLE_ALL,
(string)Room::LISTABLE_USERS,
(string)Room::LISTABLE_NONE,
];
}

return parent::completeOptionValues($optionName, $context);
Expand Down
16 changes: 16 additions & 0 deletions lib/Command/Room/TRoomCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ protected function setRoomReadOnly(Room $room, bool $readOnly): void {
}
}

/**
* @param Room $room
* @param int $listable
*
* @throws InvalidArgumentException
*/
protected function setRoomListable(Room $room, int $listable): void {
if ($room->getListable() === $listable) {
return;
}

if (!$room->setListable($listable)) {
throw new InvalidArgumentException('Unable to change room state.');
}
}

/**
* @param Room $room
* @param string $password
Expand Down
Loading