diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 31 | ||||
-rw-r--r-- | composer.lock | 10 | ||||
-rw-r--r-- | docs/bots.md | 2 | ||||
-rw-r--r-- | lib/Listener/BotListener.php | 4 | ||||
-rw-r--r-- | lib/Model/BotServerMapper.php | 7 | ||||
-rw-r--r-- | lib/Notification/Notifier.php | 21 | ||||
-rw-r--r-- | lib/Service/RoomFormatter.php | 1 | ||||
-rw-r--r-- | package-lock.json | 1734 | ||||
-rw-r--r-- | package.json | 16 | ||||
-rw-r--r-- | src/components/LeftSidebar/LeftSidebar.vue | 6 | ||||
-rw-r--r-- | src/components/MessagesList/MessagesGroup/Message/Message.vue | 100 | ||||
-rw-r--r-- | tests/integration/features/bootstrap/FeatureContext.php | 1 | ||||
-rw-r--r-- | tests/integration/features/chat/bots.feature | 21 | ||||
-rwxr-xr-x | tests/integration/run.sh | 35 | ||||
-rw-r--r-- | tests/php/Notification/NotifierTest.php | 7 |
16 files changed, 1282 insertions, 718 deletions
diff --git a/.gitignore b/.gitignore index bc75f341e..a6a936adc 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,10 @@ /tests/integration/output /drone +# PHP Dev server output (integration tests) +/tests/integration/phpserver.log +/tests/integration/phpserver_fed.log + # Compiled javascript /js diff --git a/CHANGELOG.md b/CHANGELOG.md index a8fef5429..346f09e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,37 @@ # Changelog All notable changes to this project will be documented in this file. + +## 17.1.0 – 2023-09-16 +### Added +- Add support for bots via webhooks + [#10139](https://github.com/nextcloud/spreed/issues/10139) + [#10151](https://github.com/nextcloud/spreed/issues/10151) +- Add Markdown support for chat messages + [#10089](https://github.com/nextcloud/spreed/issues/10089) + [#10090](https://github.com/nextcloud/spreed/issues/10090) +- Allow to filter the conversation list for unread mentions and messages + [#10093](https://github.com/nextcloud/spreed/issues/10093) +- Provide an overview list of open conversations + [#10095](https://github.com/nextcloud/spreed/issues/10095) +- Set a reminder to get notified about a chat messages at a later time + [#10104](https://github.com/nextcloud/spreed/issues/10104) + [#10152](https://github.com/nextcloud/spreed/issues/10152) + [#10155](https://github.com/nextcloud/spreed/issues/10155) +- Show a hint when the call is running since one hour + [#10101](https://github.com/nextcloud/spreed/issues/10101) +- Show the talking time of participants in the right sidebar + [#10145](https://github.com/nextcloud/spreed/issues/10145) + +### Changed +- System messages of the same actions are now grouped + [#10143](https://github.com/nextcloud/spreed/issues/10143) +- Use virtual scrolling for the conversation list to improve the performance + [#10297](https://github.com/nextcloud/spreed/issues/10297) +- Cache the conversation list in the browser storage for better loading experience + [#10273](https://github.com/nextcloud/spreed/issues/10273) +- Update dependencies + ## 17.1.0-rc.4 – 2023-08-31 ### Changed - chore(packaging): Ship dependencies lock files diff --git a/composer.lock b/composer.lock index 24e8fdc7a..5d6299795 100644 --- a/composer.lock +++ b/composer.lock @@ -134,12 +134,12 @@ "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "cb36d570c3b7aae1735599cc4b3614b9ce5c9c79" + "reference": "8999be903f6fa719dc26394ce1022f1bff11ae0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/cb36d570c3b7aae1735599cc4b3614b9ce5c9c79", - "reference": "cb36d570c3b7aae1735599cc4b3614b9ce5c9c79", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/8999be903f6fa719dc26394ce1022f1bff11ae0e", + "reference": "8999be903f6fa719dc26394ce1022f1bff11ae0e", "shasum": "" }, "require": { @@ -171,7 +171,7 @@ "issues": "https://github.com/nextcloud-deps/ocp/issues", "source": "https://github.com/nextcloud-deps/ocp/tree/master" }, - "time": "2023-08-26T00:28:49+00:00" + "time": "2023-09-12T00:29:25+00:00" }, { "name": "psr/clock", @@ -1024,5 +1024,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/docs/bots.md b/docs/bots.md index 573d99968..a4705e01b 100644 --- a/docs/bots.md +++ b/docs/bots.md @@ -39,7 +39,7 @@ if (!hash_equals($digest, strtolower($_SERVER['HTTP_X_NEXTCLOUD_TALK_SIGNATURE'] ### Content -The content format follows the [ActivityPub](https://www.w3.org/TR/activitypub/) dictionary. +The content format follows the [Activity Streams 2.0 Vocabulary](https://www.w3.org/TR/activitystreams-vocabulary/). #### Sample chat message diff --git a/lib/Listener/BotListener.php b/lib/Listener/BotListener.php index 001e7767b..0cea082db 100644 --- a/lib/Listener/BotListener.php +++ b/lib/Listener/BotListener.php @@ -93,7 +93,7 @@ class BotListener implements IEventListener { try { $this->botService->validateBotParameters($event->getName(), $event->getSecret(), $event->getUrl(), $event->getDescription()); } catch (\InvalidArgumentException $e) { - $this->logger->error('Invalid data in bot install event', ['exception' => $e]); + $this->logger->error('Invalid data in bot install event: ' . $e->getMessage(), ['exception' => $e]); throw $e; } @@ -107,7 +107,7 @@ class BotListener implements IEventListener { try { $this->botServerMapper->findByUrl($event->getUrl()); $e = new \InvalidArgumentException('Bot with the same URL and a different secret is already registered'); - $this->logger->error('Invalid data in bot install event', ['exception' => $e]); + $this->logger->error('Invalid data in bot install event: ' . $e->getMessage(), ['exception' => $e]); throw $e; } catch (DoesNotExistException) { } diff --git a/lib/Model/BotServerMapper.php b/lib/Model/BotServerMapper.php index 65f3b60d2..e454ccfa9 100644 --- a/lib/Model/BotServerMapper.php +++ b/lib/Model/BotServerMapper.php @@ -75,8 +75,13 @@ class BotServerMapper extends QBMapper { * @throws DoesNotExistException */ public function findByUrl(string $url): BotServer { - $urlHash = sha1($url); + return $this->findByUrlHash(sha1($url)); + } + /** + * @throws DoesNotExistException + */ + public function findByUrlHash(string $urlHash): BotServer { $query = $this->db->getQueryBuilder(); $query->select('*') ->from($this->getTableName()) diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index d6355f37d..0c8798339 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -34,11 +34,13 @@ use OCA\Talk\Exceptions\RoomNotFoundException; use OCA\Talk\GuestManager; use OCA\Talk\Manager; use OCA\Talk\Model\Attendee; +use OCA\Talk\Model\BotServerMapper; use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\AvatarService; use OCA\Talk\Service\ParticipantService; use OCA\Talk\Webinary; +use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Comments\ICommentsManager; use OCP\Comments\NotFoundException; @@ -87,6 +89,7 @@ class Notifier implements INotifier { protected ITimeFactory $timeFactory, protected Definitions $definitions, protected AddressHandler $addressHandler, + protected BotServerMapper $botServerMapper, ) { $this->commentManager = $commentManager; } @@ -454,7 +457,7 @@ class Notifier implements INotifier { $richSubjectUser = null; $isGuest = false; - if ($subjectParameters['userType'] === 'users') { + if ($subjectParameters['userType'] === Attendee::ACTOR_USERS) { $userId = $subjectParameters['userId']; $userDisplayName = $this->userManager->getDisplayName($userId); @@ -465,6 +468,22 @@ class Notifier implements INotifier { 'name' => $userDisplayName, ]; } + } elseif ($subjectParameters['userType'] === Attendee::ACTOR_BOTS) { + $botId = $subjectParameters['userId']; + try { + $bot = $this->botServerMapper->findByUrlHash(substr($botId, strlen(Attendee::ACTOR_BOT_PREFIX))); + $richSubjectUser = [ + 'type' => 'highlight', + 'id' => $botId, + 'name' => $bot->getName() . ' (Bot)', + ]; + } catch (DoesNotExistException $e) { + $richSubjectUser = [ + 'type' => 'highlight', + 'id' => $botId, + 'name' => 'Bot', + ]; + } } else { $isGuest = true; } diff --git a/lib/Service/RoomFormatter.php b/lib/Service/RoomFormatter.php index f0b834131..4581dfdef 100644 --- a/lib/Service/RoomFormatter.php +++ b/lib/Service/RoomFormatter.php @@ -264,6 +264,7 @@ class RoomFormatter { !($currentParticipant->getPermissions() & Attendee::PERMISSIONS_LOBBY_IGNORE)) { // No participants and chat messages for users in the lobby. $roomData['hasCall'] = false; + $roomData['canLeaveConversation'] = true; return $roomData; } diff --git a/package-lock.json b/package-lock.json index 431dc3fb9..176a44fd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@nextcloud/axios": "^2.4.0", "@nextcloud/browser-storage": "^0.2.0", "@nextcloud/capabilities": "^1.1.0", - "@nextcloud/dialogs": "^4.1.0", + "@nextcloud/dialogs": "^4.2.0", "@nextcloud/event-bus": "^3.1.0", "@nextcloud/files": "^3.0.0-beta.21", "@nextcloud/initial-state": "^2.1.0", @@ -22,14 +22,14 @@ "@nextcloud/moment": "^1.2.1", "@nextcloud/paths": "^2.1.0", "@nextcloud/router": "^2.1.2", - "@nextcloud/vue": "^7.12.4", + "@nextcloud/vue": "^7.12.5", "attachmediastream": "^2.1.0", "crypto-js": "^4.1.1", "debounce": "^1.2.1", "emoji-mart-vue-fast": "^15.0.0", "emoji-regex": "^10.2.1", "escape-html": "^1.0.3", - "extendable-media-recorder": "^9.0.0", + "extendable-media-recorder": "^9.1.0", "extendable-media-recorder-wav-encoder": "^7.0.96", "hark": "^1.2.3", "leaflet": "^1.9.4", @@ -38,7 +38,7 @@ "mockconsole": "0.0.1", "nextcloud-vue-collections": "^0.11.1", "pinia": "^2.1.6", - "ua-parser-js": "^1.0.35", + "ua-parser-js": "^1.0.36", "util": "^0.12.5", "vue": "^2.7.14", "vue-cropperjs": "^4.2.0", @@ -58,21 +58,21 @@ "wildemitter": "^1.2.1" }, "devDependencies": { - "@babel/core": "^7.22.17", + "@babel/core": "^7.22.19", "@babel/preset-env": "^7.22.15", "@nextcloud/babel-config": "^1.0.0", "@nextcloud/browserslist-config": "^3.0.0", "@nextcloud/eslint-config": "^8.2.1", "@nextcloud/stylelint-config": "^2.3.1", "@nextcloud/webpack-vue-config": "^6.0.0", - "@types/jest": "^29.5.4", + "@types/jest": "^29.5.5", "@vue/test-utils": "^1.3.6", "@vue/vue2-jest": "^29.2.6", "babel-loader-exclude-node-modules-except": "^1.2.1", "esbuild-loader": "^4.0.2", "flush-promises": "^1.0.2", - "jest": "^29.6.4", - "jest-environment-jsdom": "^29.6.4", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "jest-localstorage-mock": "^2.4.26", "jest-mock-console": "^2.0.0", "jest-transform-stub": "^2.0.0", @@ -188,20 +188,20 @@ } }, "node_modules/@babel/core": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz", - "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.19.tgz", + "integrity": "sha512-Q8Yj5X4LHVYTbLCKVz0//2D2aDmHF4xzCdEttYvKOnWvErGsa6geHXD6w46x64n5tP69VfeH+IfSrdyH3MLhwA==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.17", + "@babel/helper-module-transforms": "^7.22.19", "@babel/helpers": "^7.22.15", "@babel/parser": "^7.22.16", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.17", - "@babel/types": "^7.22.17", + "@babel/traverse": "^7.22.19", + "@babel/types": "^7.22.19", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -448,15 +448,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", - "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.19.tgz", + "integrity": "sha512-m6h1cJvn+OJ+R3jOHp30faq5xKJ7VbjwDj5RGgHuRlU9hrMeKsGC+JpihkR5w1g7IfseCPPtZ0r7/hB4UKaYlA==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.19" }, "engines": { "node": ">=6.9.0" @@ -558,9 +558,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.19.tgz", + "integrity": "sha512-Tinq7ybnEPFFXhlYOYFiSjespWQk0dq2dRNAiMdRTOYQzEGqnnNyrTxPYHP5r6wGjlF1rFgABdDV0g8EwD6Qbg==", "engines": { "node": ">=6.9.0" } @@ -1815,9 +1815,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", - "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.19.tgz", + "integrity": "sha512-ZCcpVPK64krfdScRbpxF6xA5fz7IOsfMwx1tcACvCzt6JY+0aHkBk7eIU8FRDSZRU5Zei6Z4JfgAxN1bqXGECg==", "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", @@ -1826,7 +1826,7 @@ "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.17", + "@babel/types": "^7.22.19", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1835,12 +1835,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", - "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-validator-identifier": "^7.22.19", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2474,15 +2474,15 @@ } }, "node_modules/@jest/console": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", - "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.6.3", - "jest-util": "^29.6.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -2554,14 +2554,14 @@ } }, "node_modules/@jest/core": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", - "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", - "dependencies": { - "@jest/console": "^29.6.4", - "@jest/reporters": "^29.6.4", - "@jest/test-result": "^29.6.4", - "@jest/transform": "^29.6.4", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", |