summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--CHANGELOG.md31
-rw-r--r--composer.lock10
-rw-r--r--docs/bots.md2
-rw-r--r--lib/Listener/BotListener.php4
-rw-r--r--lib/Model/BotServerMapper.php7
-rw-r--r--lib/Notification/Notifier.php21
-rw-r--r--lib/Service/RoomFormatter.php1
-rw-r--r--package-lock.json1734
-rw-r--r--package.json16
-rw-r--r--src/components/LeftSidebar/LeftSidebar.vue6
-rw-r--r--src/components/MessagesList/MessagesGroup/Message/Message.vue100
-rw-r--r--tests/integration/features/bootstrap/FeatureContext.php1
-rw-r--r--tests/integration/features/chat/bots.feature21
-rwxr-xr-xtests/integration/run.sh35
-rw-r--r--tests/php/Notification/NotifierTest.php7
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",