diff --git a/package-lock.json b/package-lock.json index cf4dfc19..9dfee9d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -976,10 +976,13 @@ "license": "MIT" }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -997,14 +1000,13 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "dev": true, - "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -1066,13 +1068,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1092,6 +1099,22 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1289,6 +1312,23 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-properties": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", @@ -2137,12 +2177,18 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/form-data": { @@ -2446,12 +2492,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2864,16 +2910,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -2894,6 +2936,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3673,6 +3721,15 @@ "semver-compare": "^1.0.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3976,18 +4033,41 @@ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "dev": true }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, - "license": "(MIT AND BSD-3-Clause)", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shebang-command": { @@ -4247,6 +4327,20 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/to-buffer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", + "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", + "dev": true, + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4311,6 +4405,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -4409,17 +4517,18 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" diff --git a/samples/sample-generic-content-sidekick-plugin/package.json b/samples/sample-generic-content-sidekick-plugin/package.json index 7ed13122..11783a94 100644 --- a/samples/sample-generic-content-sidekick-plugin/package.json +++ b/samples/sample-generic-content-sidekick-plugin/package.json @@ -16,7 +16,6 @@ "scripts": { "build-bundle": "webpack --mode production", "start": "webpack serve --mode development", - "lint": "eslint ./src/*", "build:watch": "rm -rf dist && tsc -w --module CommonJS", "lint": "eslint ./src/*", "lint:fix": "npm run lint -- --fix" diff --git a/samples/sample-media-area-plugin/package.json b/samples/sample-media-area-plugin/package.json index 25f3ae5f..b520c50b 100644 --- a/samples/sample-media-area-plugin/package.json +++ b/samples/sample-media-area-plugin/package.json @@ -19,7 +19,6 @@ "scripts": { "build-bundle": "webpack --mode production", "start": "webpack serve --mode development", - "lint": "eslint ./src/*", "build:watch": "rm -rf dist && tsc -w --module CommonJS", "lint": "eslint ./src/*", "lint:fix": "npm run lint -- --fix", diff --git a/samples/sample-server-commands-plugin/package.json b/samples/sample-server-commands-plugin/package.json index 1f8f319c..1e39fdda 100644 --- a/samples/sample-server-commands-plugin/package.json +++ b/samples/sample-server-commands-plugin/package.json @@ -19,7 +19,6 @@ "scripts": { "build-bundle": "webpack --mode production", "start": "webpack serve --mode development", - "lint": "eslint ./src/*", "build:watch": "rm -rf dist && tsc -w --module CommonJS", "lint": "eslint ./src/*", "lint:fix": "npm run lint -- --fix" diff --git a/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/component.tsx b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/component.tsx index 48037108..9d66e145 100644 --- a/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/component.tsx +++ b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/component.tsx @@ -1,8 +1,14 @@ import * as React from 'react'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; -import { BbbPluginSdk, PluginApi } from 'bigbluebutton-html-plugin-sdk'; -import { SampleUiCommandsPluginProps } from './types'; +import { + BbbPluginSdk, + PluginApi, + MediaAreaOption, + MediaAreaSeparator, +} from 'bigbluebutton-html-plugin-sdk'; +import { PrivateChatSubscriptionResult, SampleUiCommandsPluginProps } from './types'; +import { GET_CHATS_SUBSCRIPTION } from './query'; function SampleUiCommandsPlugin( { pluginUuid: uuid }: SampleUiCommandsPluginProps, @@ -10,12 +16,85 @@ function SampleUiCommandsPlugin( BbbPluginSdk.initialize(uuid); const pluginApi: PluginApi = BbbPluginSdk.getPluginApi(uuid); + const [privateChatId, setPrivateChatId] = useState(null); + const [targetUserId, setTargetUserId] = useState(null); + + // Get all users in the meeting + const { data: usersData } = pluginApi.useUsersBasicInfo(); + + // Get current user to exclude from random selection + const { data: currentUser } = pluginApi.useCurrentUser(); + + // Subscribe to private chats to get chatId after creating + const { data: privateChatsData } = pluginApi.useCustomSubscription?.< + PrivateChatSubscriptionResult + >(GET_CHATS_SUBSCRIPTION) || { data: undefined }; + + // Monitor for the chatId of the private chat we created + useEffect(() => { + if (targetUserId && privateChatsData?.chat) { + const targetChat = privateChatsData.chat.find( + (chat) => chat.participant.userId === targetUserId, + ); + if (targetChat && targetChat.chatId !== privateChatId) { + setPrivateChatId(targetChat.chatId); + } + } + }, [privateChatsData, targetUserId, privateChatId]); + useEffect(() => { - pluginApi.uiCommands.chat.form.open(); - pluginApi.uiCommands.chat.form.fill({ - text: 'Just an example message filled by the plugin', - }); - }, []); + if (privateChatId) { + // Open the private chat panel + pluginApi.uiCommands?.chat.form.open({ + chatId: privateChatId, + }); + + // Fill the private chat form with a hello world message + setTimeout(() => { + pluginApi.uiCommands?.chat.form.fill({ + text: 'Hello World! This message was filled by the plugin.', + }); + }, 500); + } + }, [privateChatId]); + + useEffect(() => { + // Set up the action button dropdown + pluginApi.setMediaAreaItems([ + new MediaAreaSeparator({ + dataTest: 'mediaAreaSeparator', + }), + new MediaAreaOption({ + label: 'Create Private Chat & Say Hello', + icon: { iconName: 'user' }, + tooltip: 'Creates a private chat with a random user and sends Hello World', + allowed: true, + dataTest: 'createPrivateChatButton', + onClick: () => { + // Get a random user (excluding current user) + if (usersData?.user && currentUser) { + const otherUsers = usersData.user.filter( + (user) => user.userId !== currentUser.userId, + ); + + if (otherUsers.length > 0) { + const randomUser = otherUsers[ + Math.floor(Math.random() * otherUsers.length) + ]; + + // Store the target user ID to track the chat creation + setTargetUserId(randomUser.userId); + + // Create private chat with the random user + pluginApi.serverCommands?.chat.createPrivateChat({ + userId: randomUser.userId, + }); + } + } + }, + }), + ]); + }, [usersData, currentUser]); return null; } diff --git a/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/query.ts b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/query.ts new file mode 100644 index 00000000..d79ce71f --- /dev/null +++ b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/query.ts @@ -0,0 +1,11 @@ +export const GET_CHATS_SUBSCRIPTION = ` + subscription PrivateChats { + chat(where: {public: {_eq: false}}) { + chatId + participant { + userId + name + } + } + } +`; diff --git a/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/types.ts b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/types.ts index 93ff5b78..e2b2b8a3 100644 --- a/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/types.ts +++ b/samples/sample-ui-commands-plugin/src/sample-ui-commands-plugin-item/types.ts @@ -1,6 +1,14 @@ -interface SampleUiCommandsPluginProps { +export interface SampleUiCommandsPluginProps { pluginName: string, pluginUuid: string, } -export { SampleUiCommandsPluginProps }; +export interface PrivateChatSubscriptionResult { + chat: Array<{ + chatId: string; + participant: { + userId: string; + name: string; + }; + }>; +} diff --git a/samples/sample-user-list-dropdown-plugin/package.json b/samples/sample-user-list-dropdown-plugin/package.json index 3c5a203a..e8a105bf 100644 --- a/samples/sample-user-list-dropdown-plugin/package.json +++ b/samples/sample-user-list-dropdown-plugin/package.json @@ -18,7 +18,6 @@ "scripts": { "build-bundle": "webpack --mode production", "start": "webpack serve --mode development", - "lint": "eslint ./src/*", "build:watch": "rm -rf dist && tsc -w --module CommonJS", "lint": "eslint ./src/*", "lint:fix": "npm run lint -- --fix" diff --git a/scripts/validate-samples-code.sh b/scripts/validate-samples-code.sh index 6c40a277..3cb63a39 100755 --- a/scripts/validate-samples-code.sh +++ b/scripts/validate-samples-code.sh @@ -11,7 +11,7 @@ THIS_SCRIPT_PATH=$(dirname "$(readlink -f "$0")") # Calculate the absolute path of the project directory. PROJECT_DIR=$(realpath "$THIS_SCRIPT_PATH/..") -for SAMPLE in samples/*/; do +for SAMPLE in $PROJECT_DIR/samples/*/; do if [ -d "$SAMPLE" ]; then # Install dependencies if there is no node_modules if [ ! -d "$SAMPLE/node_modules" ]; then diff --git a/src/data-channel/types.ts b/src/data-channel/types.ts index 1a11a2f9..00ab0ace 100644 --- a/src/data-channel/types.ts +++ b/src/data-channel/types.ts @@ -50,16 +50,17 @@ export interface MapOfPushEntryFunctions { export interface DataChannelEntryResponseType { createdAt: string; + updatedAt: string; channelName: string; subChannelName: string; - fromUserId: string; + createdBy: string; entryId: string; payloadJson: T; pluginName: string; toRoles: string[]; } -export interface UseDataChannelReturnType { +export interface UseDataChannelReturnType { data: GraphqlResponseWrapper[]>, pushEntry: PushEntryFunction, deleteEntry: DeleteEntryFunction, diff --git a/src/server-commands/chat/commands.ts b/src/server-commands/chat/commands.ts index c7f107b8..09463e88 100644 --- a/src/server-commands/chat/commands.ts +++ b/src/server-commands/chat/commands.ts @@ -3,9 +3,35 @@ import { ChatCommandsEnum } from './enum'; import { ChatSendMessageCommandArguments, ChatSendMessageEventArguments, + SendChatMessageArguments, + CreatePrivateChatCommandArguments, } from './types'; export const chat = (pluginName: string) => ({ + /** + * Sends chat message to specific chat. + * + * @param SendChatMessageArguments the text, custom metadata(optional), optional flag + * to tell whether or not the message will be custom, and the chatId; + * Refer to {@link SendChatMessageArguments} to understand the argument + * structure. + */ + sendChatMessage: ( + chatMessageArguments: SendChatMessageArguments, + ) => { + window.dispatchEvent( + new CustomEvent< + ChatSendMessageEventArguments + >(ChatCommandsEnum.SEND_MESSAGE, { + detail: { + pluginName, + ...chatMessageArguments, + custom: chatMessageArguments?.custom || false, + }, + }), + ); + }, + /** * Sends chat message to the public chat. * @@ -56,4 +82,25 @@ export const chat = (pluginName: string) => ({ }), ); }, + + /** + * Creates a private chat with a specific user. + * + * @param createPrivateChatCommandArguments the userId of the user to create a private chat with. + * Refer to {@link CreatePrivateChatCommandArguments} to understand the argument + * structure. + */ + createPrivateChat: ( + createPrivateChatCommandArguments: CreatePrivateChatCommandArguments, + ) => { + window.dispatchEvent( + new CustomEvent< + CreatePrivateChatCommandArguments + >(ChatCommandsEnum.CREATE_PRIVATE_CHAT, { + detail: { + ...createPrivateChatCommandArguments, + }, + }), + ); + }, }); diff --git a/src/server-commands/chat/enum.ts b/src/server-commands/chat/enum.ts index e238ac51..01e088d3 100644 --- a/src/server-commands/chat/enum.ts +++ b/src/server-commands/chat/enum.ts @@ -1,3 +1,4 @@ export enum ChatCommandsEnum { SEND_MESSAGE = 'CHAT_SEND_MESSAGE', + CREATE_PRIVATE_CHAT = 'CHAT_CREATE_PRIVATE_CHAT', } diff --git a/src/server-commands/chat/types.ts b/src/server-commands/chat/types.ts index 1f491784..a9ff5c1f 100644 --- a/src/server-commands/chat/types.ts +++ b/src/server-commands/chat/types.ts @@ -4,17 +4,34 @@ export interface ChatSendMessageCommandArguments { } export interface ChatSendMessageEventArguments - extends ChatSendMessageCommandArguments { + extends ChatSendMessageCommandArguments { pluginName: string; chatId: string; custom: boolean; } +export interface SendChatMessageArguments { + textMessageInMarkdownFormat: string; + chatId: string; + custom?: boolean; + pluginCustomMetadata?: string; +} + +export interface CreatePrivateChatCommandArguments { + userId: string; +} + export interface ServerCommandsChatObject { + sendChatMessage: ( + chatMessageArguments: SendChatMessageArguments + ) => void; sendCustomPublicChatMessage: ( chatSendCustomPublicChatMessageCommandArguments: ChatSendMessageCommandArguments ) => void; sendPublicChatMessage: ( chatSendPublicChatMessageCommandArguments: ChatSendMessageCommandArguments ) => void; + createPrivateChat: ( + createPrivateChatCommandArguments: CreatePrivateChatCommandArguments + ) => void; } diff --git a/src/ui-commands/chat/enums.ts b/src/ui-commands/chat/enums.ts new file mode 100644 index 00000000..209e9a84 --- /dev/null +++ b/src/ui-commands/chat/enums.ts @@ -0,0 +1,3 @@ +export enum ChatUiCommandsEnum { + OPEN_PRIVATE_CHAT = 'OPEN_PRIVATE_CHAT_COMMAND', +} diff --git a/src/ui-commands/chat/form/commands.ts b/src/ui-commands/chat/form/commands.ts index eb2b817a..066a6fe1 100644 --- a/src/ui-commands/chat/form/commands.ts +++ b/src/ui-commands/chat/form/commands.ts @@ -1,12 +1,26 @@ import { ChatFormCommandsEnum } from './enums'; -import { FillChatFormCommandArguments } from './types'; +import { + FillChatFormCommandArguments, + OpenChatFormCommandArguments, +} from './types'; export const form = { /** - * Opens the public chat panel automatically. + * Opens the chat panel automatically. If chatId is provided, opens that specific chat. + * + * @param openChatCommandArgument Optional chatId to open a specific chat panel. + * Refer to {@link OpenChatFormCommandArguments} to understand the argument structure. */ - open: () => { - window.dispatchEvent(new Event(ChatFormCommandsEnum.OPEN)); + open: (openChatCommandArgument?: OpenChatFormCommandArguments) => { + if (openChatCommandArgument) { + window.dispatchEvent( + new CustomEvent(ChatFormCommandsEnum.OPEN, { + detail: openChatCommandArgument, + }), + ); + } else { + window.dispatchEvent(new Event(ChatFormCommandsEnum.OPEN)); + } }, /** diff --git a/src/ui-commands/chat/form/types.ts b/src/ui-commands/chat/form/types.ts index bf49806e..4a8aa1c0 100644 --- a/src/ui-commands/chat/form/types.ts +++ b/src/ui-commands/chat/form/types.ts @@ -2,7 +2,11 @@ export interface FillChatFormCommandArguments { text: string; } +export interface OpenChatFormCommandArguments { + chatId: string; +} + export interface UiCommandsChatFormObject { - open: () => void; + open: (openChatCommandArgument?: OpenChatFormCommandArguments) => void; fill: (FillChatFormCommandArguments: FillChatFormCommandArguments) => void; } diff --git a/src/ui-commands/index.ts b/src/ui-commands/index.ts index dbd5c644..ca5916f4 100644 --- a/src/ui-commands/index.ts +++ b/src/ui-commands/index.ts @@ -1,3 +1,4 @@ export { NotificationTypeUiCommand } from './notification/enums'; export { ChangeEnforcedLayoutTypeEnum, EnforcedLayoutTypeEnum } from './layout/enums'; export { CaptionsLanguageEnum } from './captions/enums'; +export { ChatUiCommandsEnum } from './chat/enums';