From 0ac9b949d13b54342ab7b5709d907863114d3f27 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Dec 2025 18:58:32 +0100 Subject: [PATCH 1/6] feat(settings): Introduce conversation presets Signed-off-by: Joas Schilling --- lib/Controller/RoomController.php | 80 +++++++++++++++++-------------- lib/RoomPresets/DefaultPreset.php | 30 ++++++++++++ lib/RoomPresets/Hallway.php | 23 +++++++++ lib/RoomPresets/IPreset.php | 13 +++++ lib/RoomPresets/Parameter.php | 23 +++++++++ lib/RoomPresets/Presentation.php | 26 ++++++++++ lib/RoomPresets/Preset.php | 18 +++++++ lib/RoomPresets/Webinar.php | 29 +++++++++++ lib/Service/RoomPresetService.php | 79 ++++++++++++++++++++++++++++++ 9 files changed, 285 insertions(+), 36 deletions(-) create mode 100644 lib/RoomPresets/DefaultPreset.php create mode 100644 lib/RoomPresets/Hallway.php create mode 100644 lib/RoomPresets/IPreset.php create mode 100644 lib/RoomPresets/Parameter.php create mode 100644 lib/RoomPresets/Presentation.php create mode 100644 lib/RoomPresets/Preset.php create mode 100644 lib/RoomPresets/Webinar.php create mode 100644 lib/Service/RoomPresetService.php diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index c7d76740652..123f2a4fe00 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -53,6 +53,9 @@ use OCA\Talk\Model\Session; use OCA\Talk\Model\Thread; use OCA\Talk\Participant; +use OCA\Talk\RoomPresets\Parameter; +use OCA\Talk\RoomPresets\Preset; +use OCA\Talk\Service\RoomPresetService; use OCA\Talk\ResponseDefinitions; use OCA\Talk\Room; use OCA\Talk\Service\BanService; @@ -153,6 +156,7 @@ public function __construct( protected IURLGenerator $url, protected IL10N $l, protected ThreadService $threadService, + protected RoomPresetService $presetService, ) { parent::__construct($appName, $request); } @@ -590,7 +594,7 @@ protected function formatRoom( * In case the `$roomType` is {@see Room::TYPE_ONE_TO_ONE} only the `$invite` * or `$participants` parameter is supported. * - * @param int $roomType Type of the room + * @param ?int $roomType Type of the room * @psalm-param Room::TYPE_* $roomType * @param string $invite User, group, … ID to invite @deprecated Use the `$participants` array instead * @param string $roomName Name of the room, unless the legacy mode providing `$invite` and `$source` is used, the name must no longer be empty with the `conversation-creation-all` capability (Ignored if `$roomType` is {@see Room::TYPE_ONE_TO_ONE}) @@ -598,24 +602,24 @@ protected function formatRoom( * @param string $objectType Type of the object (Ignored if `$roomType` is {@see Room::TYPE_ONE_TO_ONE}) * @param string $objectId ID of the object (Ignored if `$roomType` is {@see Room::TYPE_ONE_TO_ONE}) * @param string $password The room password (only available with `conversation-creation-password` capability) (Ignored if `$roomType` is not {@see Room::TYPE_PUBLIC}) - * @param 0|1 $readOnly Read only state of the conversation (Default writable) (only available with `conversation-creation-all` capability) - * @psalm-param Room::READ_* $readOnly - * @param 0|1|2 $listable Scope where the conversation is listable (Default not listable for anyone) (only available with `conversation-creation-all` capability) - * @psalm-param Room::LISTABLE_* $listable - * @param int $messageExpiration Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability) - * @psalm-param non-negative-int $messageExpiration - * @param 0|1 $lobbyState Lobby state of the conversation (Default lobby is disabled) (only available with `conversation-creation-all` capability) - * @psalm-param Webinary::LOBBY_* $lobbyState + * @param 0|1|null $readOnly Read only state of the conversation (Default writable) (only available with `conversation-creation-all` capability) + * @psalm-param ?Room::READ_* $readOnly + * @param 0|1|2|null $listable Scope where the conversation is listable (Default not listable for anyone) (only available with `conversation-creation-all` capability) + * @psalm-param ?Room::LISTABLE_* $listable + * @param ?int $messageExpiration Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability) + * @psalm-param ?non-negative-int $messageExpiration + * @param 0|1|null $lobbyState Lobby state of the conversation (Default lobby is disabled) (only available with `conversation-creation-all` capability) + * @psalm-param ?Webinary::LOBBY_* $lobbyState * @param int|null $lobbyTimer Timer when the lobby will be removed (Default null, will not be disabled automatically) (only available with `conversation-creation-all` capability) - * @psalm-param non-negative-int|null $lobbyTimer - * @param 0|1|2 $sipEnabled Whether SIP dial-in shall be enabled (only available with `conversation-creation-all` capability) - * @psalm-param Webinary::SIP_* $sipEnabled - * @param int<0, 255> $permissions Default permissions for participants (only available with `conversation-creation-all` capability) - * @psalm-param int-mask-of $permissions - * @param 0|1 $recordingConsent Whether participants need to agree to a recording before joining a call (only available with `conversation-creation-all` capability) - * @psalm-param RecordingService::CONSENT_REQUIRED_NO|RecordingService::CONSENT_REQUIRED_YES $recordingConsent - * @param 0|1 $mentionPermissions Who can mention at-all in the chat (only available with `conversation-creation-all` capability) - * @psalm-param Room::MENTION_PERMISSIONS_* $mentionPermissions + * @psalm-param ?non-negative-int $lobbyTimer + * @param 0|1|2|null $sipEnabled Whether SIP dial-in shall be enabled (only available with `conversation-creation-all` capability) + * @psalm-param ?Webinary::SIP_* $sipEnabled + * @param int<0, 255>|null $permissions Default permissions for participants (only available with `conversation-creation-all` capability) + * @psalm-param ?int-mask-of $permissions + * @param 0|1|null $recordingConsent Whether participants need to agree to a recording before joining a call (only available with `conversation-creation-all` capability) + * @psalm-param RecordingService::CONSENT_REQUIRED_NO|RecordingService::CONSENT_REQUIRED_YES|null $recordingConsent + * @param 0|1|null $mentionPermissions Who can mention at-all in the chat (only available with `conversation-creation-all` capability) + * @psalm-param ?Room::MENTION_PERMISSIONS_* $mentionPermissions * @param string $description Description for the conversation (limited to 2.000 characters) (only available with `conversation-creation-all` capability) * @param ?non-empty-string $emoji Emoji for the avatar of the conversation (only available with `conversation-creation-all` capability) * @param ?non-empty-string $avatarColor Background color of the avatar (Only considered when an emoji was provided) (only available with `conversation-creation-all` capability) @@ -635,26 +639,27 @@ protected function formatRoom( 'apiVersion' => '(v4)', ])] public function createRoom( - int $roomType = Room::TYPE_GROUP, + ?int $roomType = null, string $invite = '', /* @deprecated */ string $roomName = '', string $source = '', /* @deprecated */ string $objectType = '', string $objectId = '', string $password = '', - int $readOnly = Room::READ_WRITE, - int $listable = Room::LISTABLE_NONE, - int $messageExpiration = 0, - int $lobbyState = Webinary::LOBBY_NONE, + ?int $readOnly = null, + ?int $listable = null, + ?int $messageExpiration = null, + ?int $lobbyState = null, ?int $lobbyTimer = null, - int $sipEnabled = Webinary::SIP_DISABLED, - int $permissions = Attendee::PERMISSIONS_DEFAULT, - int $recordingConsent = RecordingService::CONSENT_REQUIRED_NO, - int $mentionPermissions = Room::MENTION_PERMISSIONS_EVERYONE, + ?int $sipEnabled = null, + ?int $permissions = null, + ?int $recordingConsent = null, + ?int $mentionPermissions = null, string $description = '', ?string $emoji = null, ?string $avatarColor = null, array $participants = [], + ?int $preset = null, ): DataResponse { if ($roomType === Room::TYPE_ONE_TO_ONE) { if ($invite === '' @@ -744,23 +749,26 @@ public function createRoom( $objectId = Room::OBJECT_ID_PHONE_OUTGOING; } + $selectedPreset = Preset::from($preset ?? 0); + + try { $room = $this->roomService->createConversation( - $roomType, + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::ROOM_TYPE, $roomType), $roomName, $user, $objectType, $objectId, $password, - $readOnly, - $listable, - $messageExpiration, - $lobbyState, + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::READ_ONLY, $readOnly), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::LISTABLE, $listable), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::MESSAGE_EXPIRATION, $messageExpiration), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::LOBBY_STATE, $lobbyState), $lobbyTimer, - $sipEnabled, - $permissions, - $recordingConsent, - $mentionPermissions, + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::SIP_ENABLED, $sipEnabled), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::PERMISSIONS, $permissions), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::RECORDING_CONSENT, $recordingConsent), + $this->presetService->getDefaultForPreset($selectedPreset, Parameter::MENTION_PERMISSIONS, $mentionPermissions), $description, $emoji, $avatarColor, diff --git a/lib/RoomPresets/DefaultPreset.php b/lib/RoomPresets/DefaultPreset.php new file mode 100644 index 00000000000..c9e499b02d4 --- /dev/null +++ b/lib/RoomPresets/DefaultPreset.php @@ -0,0 +1,30 @@ + Room::TYPE_GROUP, + Parameter::READ_ONLY => Room::READ_WRITE, + Parameter::LISTABLE => Room::LISTABLE_NONE, + Parameter::MESSAGE_EXPIRATION => 0, + Parameter::LOBBY_STATE => Webinary::LOBBY_NONE, + Parameter::SIP_ENABLED => Webinary::SIP_DISABLED, + Parameter::PERMISSIONS => Attendee::PERMISSIONS_DEFAULT, + Parameter::RECORDING_CONSENT => RecordingService::CONSENT_REQUIRED_NO, + Parameter::MENTION_PERMISSIONS => Room::MENTION_PERMISSIONS_EVERYONE, + }; + } +} diff --git a/lib/RoomPresets/Hallway.php b/lib/RoomPresets/Hallway.php new file mode 100644 index 00000000000..ce0234df61e --- /dev/null +++ b/lib/RoomPresets/Hallway.php @@ -0,0 +1,23 @@ + Room::LISTABLE_USERS, + // If you were not there, you were not there … + Parameter::MESSAGE_EXPIRATION => 3600, + default => null, + }; + } +} diff --git a/lib/RoomPresets/IPreset.php b/lib/RoomPresets/IPreset.php new file mode 100644 index 00000000000..9917606f3cc --- /dev/null +++ b/lib/RoomPresets/IPreset.php @@ -0,0 +1,13 @@ + Room::MENTION_PERMISSIONS_MODERATORS, + Parameter::PERMISSIONS => Attendee::PERMISSIONS_CUSTOM + | Attendee::PERMISSIONS_CALL_JOIN + | Attendee::PERMISSIONS_CHAT, + Parameter::RECORDING_CONSENT => RecordingService::CONSENT_REQUIRED_YES, + default => null, + }; + } +} diff --git a/lib/RoomPresets/Preset.php b/lib/RoomPresets/Preset.php new file mode 100644 index 00000000000..9b59fa8a928 --- /dev/null +++ b/lib/RoomPresets/Preset.php @@ -0,0 +1,18 @@ + Webinary::LOBBY_NON_MODERATORS, + Parameter::MESSAGE_EXPIRATION => Room::MENTION_PERMISSIONS_MODERATORS, + Parameter::PERMISSIONS => Attendee::PERMISSIONS_CUSTOM + | Attendee::PERMISSIONS_CALL_JOIN + | Attendee::PERMISSIONS_CHAT, + Parameter::RECORDING_CONSENT => RecordingService::CONSENT_REQUIRED_YES, + Parameter::ROOM_TYPE => Room::TYPE_PUBLIC, + default => null, + }; + } +} diff --git a/lib/Service/RoomPresetService.php b/lib/Service/RoomPresetService.php new file mode 100644 index 00000000000..9d22bba2884 --- /dev/null +++ b/lib/Service/RoomPresetService.php @@ -0,0 +1,79 @@ +appConfig->hasAppKey(self::CONFIG_PREFIX_FORCE . $configName)) { + return $this->appConfig->getAppValueInt(self::CONFIG_PREFIX_FORCE . $configName); + } + + if ($provided !== null) { + return $provided; + } + + $value = match ($preset) { + Preset::WEBINAR => Webinar::getDefault($parameter), + Preset::PRESENTATION => Presentation::getDefault($parameter), + Preset::HALLWAY => Hallway::getDefault($parameter), + default => null, + }; + + if ($value !== null) { + return $value; + } + + if ($this->appConfig->hasAppKey(self::CONFIG_PREFIX_DEFAULT . $configName)) { + return $this->appConfig->getAppValueInt(self::CONFIG_PREFIX_DEFAULT . $configName); + } + + // Fall through to default preset + return DefaultPreset::getDefault($parameter); + } + + public static function getConfigNameForParameter(Parameter $parameter): string { + $parts = preg_split('/(?=[A-Z])/', $parameter->value); + + $configName = ''; + foreach ($parts as $part) { + if ($configName === '') { + $configName = $part; + } else { + $configName .= '_' . lcfirst($part); + } + } + + return $configName; + } +} From 2a114176dd9d3ee5ffd5684825c354b63388d047 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Dec 2025 15:09:18 +0100 Subject: [PATCH 2/6] fixup! feat(settings): Introduce conversation presets --- lib/Controller/RoomController.php | 6 +++--- lib/RoomPresets/Parameter.php | 3 +-- lib/RoomPresets/Preset.php | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 123f2a4fe00..1ee6ee7d254 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -53,11 +53,10 @@ use OCA\Talk\Model\Session; use OCA\Talk\Model\Thread; use OCA\Talk\Participant; -use OCA\Talk\RoomPresets\Parameter; -use OCA\Talk\RoomPresets\Preset; -use OCA\Talk\Service\RoomPresetService; use OCA\Talk\ResponseDefinitions; use OCA\Talk\Room; +use OCA\Talk\RoomPresets\Parameter; +use OCA\Talk\RoomPresets\Preset; use OCA\Talk\Service\BanService; use OCA\Talk\Service\BreakoutRoomService; use OCA\Talk\Service\ChecksumVerificationService; @@ -67,6 +66,7 @@ use OCA\Talk\Service\PhoneService; use OCA\Talk\Service\RecordingService; use OCA\Talk\Service\RoomFormatter; +use OCA\Talk\Service\RoomPresetService; use OCA\Talk\Service\RoomService; use OCA\Talk\Service\SessionService; use OCA\Talk\Service\ThreadService; diff --git a/lib/RoomPresets/Parameter.php b/lib/RoomPresets/Parameter.php index 34ccd7d1052..2f065546ffd 100644 --- a/lib/RoomPresets/Parameter.php +++ b/lib/RoomPresets/Parameter.php @@ -9,8 +9,7 @@ namespace OCA\Talk\RoomPresets; -enum Parameter: string -{ +enum Parameter: string { case ROOM_TYPE = 'roomType'; case READ_ONLY = 'readOnly'; case LISTABLE = 'listable'; diff --git a/lib/RoomPresets/Preset.php b/lib/RoomPresets/Preset.php index 9b59fa8a928..af754970cbb 100644 --- a/lib/RoomPresets/Preset.php +++ b/lib/RoomPresets/Preset.php @@ -9,8 +9,7 @@ namespace OCA\Talk\RoomPresets; -enum Preset: int -{ +enum Preset: int { case DEFAULT = 0; case WEBINAR = 1; case PRESENTATION = 2; From 2e604ca8a531fa2c58337a853af295fabfc4c19c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Dec 2025 15:10:24 +0100 Subject: [PATCH 3/6] fixup! fixup! feat(settings): Introduce conversation presets --- lib/RoomPresets/DefaultPreset.php | 1 + lib/RoomPresets/Hallway.php | 1 + lib/RoomPresets/Presentation.php | 1 + lib/RoomPresets/Webinar.php | 1 + 4 files changed, 4 insertions(+) diff --git a/lib/RoomPresets/DefaultPreset.php b/lib/RoomPresets/DefaultPreset.php index c9e499b02d4..020f74d1830 100644 --- a/lib/RoomPresets/DefaultPreset.php +++ b/lib/RoomPresets/DefaultPreset.php @@ -14,6 +14,7 @@ use OCA\Talk\Webinary; class DefaultPreset implements IPreset { + #[\Override] public static function getDefault(Parameter $parameter): int { return match ($parameter) { Parameter::ROOM_TYPE => Room::TYPE_GROUP, diff --git a/lib/RoomPresets/Hallway.php b/lib/RoomPresets/Hallway.php index ce0234df61e..17faf53bd11 100644 --- a/lib/RoomPresets/Hallway.php +++ b/lib/RoomPresets/Hallway.php @@ -11,6 +11,7 @@ use OCA\Talk\Room; class Hallway implements IPreset { + #[\Override] public static function getDefault(Parameter $parameter): ?int { return match ($parameter) { // Users but no guest users (by default) diff --git a/lib/RoomPresets/Presentation.php b/lib/RoomPresets/Presentation.php index 57489b03d49..cb72e7039bb 100644 --- a/lib/RoomPresets/Presentation.php +++ b/lib/RoomPresets/Presentation.php @@ -13,6 +13,7 @@ use OCA\Talk\Service\RecordingService; class Presentation implements IPreset { + #[\Override] public static function getDefault(Parameter $parameter): ?int { return match ($parameter) { Parameter::MENTION_PERMISSIONS => Room::MENTION_PERMISSIONS_MODERATORS, diff --git a/lib/RoomPresets/Webinar.php b/lib/RoomPresets/Webinar.php index 75f9adfef42..f828dbd53ef 100644 --- a/lib/RoomPresets/Webinar.php +++ b/lib/RoomPresets/Webinar.php @@ -14,6 +14,7 @@ use OCA\Talk\Webinary; class Webinar implements IPreset { + #[\Override] public static function getDefault(Parameter $parameter): ?int { return match ($parameter) { Parameter::LOBBY_STATE => Webinary::LOBBY_NON_MODERATORS, From 5aff8c1310fea3e64c9cc74f442c344ea8ee1131 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Dec 2025 15:38:42 +0100 Subject: [PATCH 4/6] fixup! fixup! fixup! feat(settings): Introduce conversation presets --- lib/Controller/RoomController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 1ee6ee7d254..571e0e7bcd2 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -625,6 +625,8 @@ protected function formatRoom( * @param ?non-empty-string $avatarColor Background color of the avatar (Only considered when an emoji was provided) (only available with `conversation-creation-all` capability) * @param array> $participants List of participants to add grouped by type (only available with `conversation-creation-all` capability) * @psalm-param TalkInvitationList $participants + * @param 0|1|2|3|null $preset Which preset should be used for not-given (null) parameters (only available with `conversation-preset` capability) + * @psalm-param ?Preset $preset * @return DataResponse|DataResponse|DataResponse * * 200: Room already existed From 1d436cdd7593f24c79389a9562f9767895e84be2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Dec 2025 15:40:17 +0100 Subject: [PATCH 5/6] chore(assets): Recompile assets Signed-off-by: Joas Schilling --- openapi-full.json | 37 +++++++++++++++++----- openapi.json | 37 +++++++++++++++++----- src/types/openapi/openapi-full.ts | 52 ++++++++++++++++++------------- src/types/openapi/openapi.ts | 52 ++++++++++++++++++------------- 4 files changed, 120 insertions(+), 58 deletions(-) diff --git a/openapi-full.json b/openapi-full.json index ad06be8aa82..9ff2d94d6b2 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -15891,6 +15891,8 @@ "roomType": { "type": "integer", "format": "int64", + "nullable": true, + "default": null, "description": "Type of the room" }, "invite": { @@ -15927,7 +15929,8 @@ }, "readOnly": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15936,7 +15939,8 @@ }, "listable": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1, @@ -15947,13 +15951,15 @@ "messageExpiration": { "type": "integer", "format": "int64", - "default": 0, + "nullable": true, + "default": null, "description": "Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability)", "minimum": 0 }, "lobbyState": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15970,7 +15976,8 @@ }, "sipEnabled": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1, @@ -15981,13 +15988,16 @@ "permissions": { "type": "integer", "format": "int64", + "nullable": true, + "default": null, "description": "Default permissions for participants (only available with `conversation-creation-all` capability)", "minimum": 0, "maximum": 255 }, "recordingConsent": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15996,7 +16006,8 @@ }, "mentionPermissions": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -16026,6 +16037,18 @@ "$ref": "#/components/schemas/InvitationList", "default": [], "description": "List of participants to add grouped by type (only available with `conversation-creation-all` capability)" + }, + "preset": { + "type": "integer", + "nullable": true, + "default": null, + "enum": [ + 0, + 1, + 2, + 3 + ], + "description": "Which preset should be used for not-given (null) parameters (only available with `conversation-preset` capability)" } } } diff --git a/openapi.json b/openapi.json index 936e587ca6e..b4ff4933560 100644 --- a/openapi.json +++ b/openapi.json @@ -15796,6 +15796,8 @@ "roomType": { "type": "integer", "format": "int64", + "nullable": true, + "default": null, "description": "Type of the room" }, "invite": { @@ -15832,7 +15834,8 @@ }, "readOnly": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15841,7 +15844,8 @@ }, "listable": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1, @@ -15852,13 +15856,15 @@ "messageExpiration": { "type": "integer", "format": "int64", - "default": 0, + "nullable": true, + "default": null, "description": "Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability)", "minimum": 0 }, "lobbyState": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15875,7 +15881,8 @@ }, "sipEnabled": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1, @@ -15886,13 +15893,16 @@ "permissions": { "type": "integer", "format": "int64", + "nullable": true, + "default": null, "description": "Default permissions for participants (only available with `conversation-creation-all` capability)", "minimum": 0, "maximum": 255 }, "recordingConsent": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15901,7 +15911,8 @@ }, "mentionPermissions": { "type": "integer", - "format": "int64", + "nullable": true, + "default": null, "enum": [ 0, 1 @@ -15931,6 +15942,18 @@ "$ref": "#/components/schemas/InvitationList", "default": [], "description": "List of participants to add grouped by type (only available with `conversation-creation-all` capability)" + }, + "preset": { + "type": "integer", + "nullable": true, + "default": null, + "enum": [ + 0, + 1, + 2, + 3 + ], + "description": "Which preset should be used for not-given (null) parameters (only available with `conversation-preset` capability)" } } } diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 0f6b41369da..e3590939c45 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -8560,8 +8560,9 @@ export interface operations { /** * Format: int64 * @description Type of the room + * @default null */ - roomType?: number; + roomType?: number | null; /** * @deprecated * @description User, group, … ID to invite Deprecated: Use the `$participants` array instead @@ -8595,29 +8596,29 @@ export interface operations { */ password?: string; /** - * Format: int64 * @description Read only state of the conversation (Default writable) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - readOnly?: 0 | 1; + readOnly?: 0 | 1 | null; /** - * Format: int64 * @description Scope where the conversation is listable (Default not listable for anyone) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - listable?: 0 | 1 | 2; + listable?: 0 | 1 | 2 | null; /** * Format: int64 * @description Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability) - * @default 0 + * @default null */ - messageExpiration?: number; + messageExpiration?: number | null; /** - * Format: int64 * @description Lobby state of the conversation (Default lobby is disabled) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - lobbyState?: 0 | 1; + lobbyState?: 0 | 1 | null; /** * Format: int64 * @description Timer when the lobby will be removed (Default null, will not be disabled automatically) (only available with `conversation-creation-all` capability) @@ -8625,28 +8626,29 @@ export interface operations { */ lobbyTimer?: number | null; /** - * Format: int64 * @description Whether SIP dial-in shall be enabled (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - sipEnabled?: 0 | 1 | 2; + sipEnabled?: 0 | 1 | 2 | null; /** * Format: int64 * @description Default permissions for participants (only available with `conversation-creation-all` capability) + * @default null */ - permissions?: number; + permissions?: number | null; /** - * Format: int64 * @description Whether participants need to agree to a recording before joining a call (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - recordingConsent?: 0 | 1; + recordingConsent?: 0 | 1 | null; /** - * Format: int64 * @description Who can mention at-all in the chat (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - mentionPermissions?: 0 | 1; + mentionPermissions?: 0 | 1 | null; /** * @description Description for the conversation (limited to 2.000 characters) (only available with `conversation-creation-all` capability) * @default @@ -8667,6 +8669,12 @@ export interface operations { * @default [] */ participants?: components["schemas"]["InvitationList"]; + /** + * @description Which preset should be used for not-given (null) parameters (only available with `conversation-preset` capability) + * @default null + * @enum {integer|null} + */ + preset?: 0 | 1 | 2 | 3 | null; }; }; }; diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index 9529b534d76..cbdf1bc6b8d 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -8022,8 +8022,9 @@ export interface operations { /** * Format: int64 * @description Type of the room + * @default null */ - roomType?: number; + roomType?: number | null; /** * @deprecated * @description User, group, … ID to invite Deprecated: Use the `$participants` array instead @@ -8057,29 +8058,29 @@ export interface operations { */ password?: string; /** - * Format: int64 * @description Read only state of the conversation (Default writable) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - readOnly?: 0 | 1; + readOnly?: 0 | 1 | null; /** - * Format: int64 * @description Scope where the conversation is listable (Default not listable for anyone) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - listable?: 0 | 1 | 2; + listable?: 0 | 1 | 2 | null; /** * Format: int64 * @description Seconds after which messages will disappear, 0 disables expiration (Default 0) (only available with `conversation-creation-all` capability) - * @default 0 + * @default null */ - messageExpiration?: number; + messageExpiration?: number | null; /** - * Format: int64 * @description Lobby state of the conversation (Default lobby is disabled) (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - lobbyState?: 0 | 1; + lobbyState?: 0 | 1 | null; /** * Format: int64 * @description Timer when the lobby will be removed (Default null, will not be disabled automatically) (only available with `conversation-creation-all` capability) @@ -8087,28 +8088,29 @@ export interface operations { */ lobbyTimer?: number | null; /** - * Format: int64 * @description Whether SIP dial-in shall be enabled (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - sipEnabled?: 0 | 1 | 2; + sipEnabled?: 0 | 1 | 2 | null; /** * Format: int64 * @description Default permissions for participants (only available with `conversation-creation-all` capability) + * @default null */ - permissions?: number; + permissions?: number | null; /** - * Format: int64 * @description Whether participants need to agree to a recording before joining a call (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - recordingConsent?: 0 | 1; + recordingConsent?: 0 | 1 | null; /** - * Format: int64 * @description Who can mention at-all in the chat (only available with `conversation-creation-all` capability) - * @enum {integer} + * @default null + * @enum {integer|null} */ - mentionPermissions?: 0 | 1; + mentionPermissions?: 0 | 1 | null; /** * @description Description for the conversation (limited to 2.000 characters) (only available with `conversation-creation-all` capability) * @default @@ -8129,6 +8131,12 @@ export interface operations { * @default [] */ participants?: components["schemas"]["InvitationList"]; + /** + * @description Which preset should be used for not-given (null) parameters (only available with `conversation-preset` capability) + * @default null + * @enum {integer|null} + */ + preset?: 0 | 1 | 2 | 3 | null; }; }; }; From 0956c95116cb33e5a66abcab60bddd188dd83ed4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Dec 2025 16:45:15 +0100 Subject: [PATCH 6/6] feat(preset): Add list API Signed-off-by: Joas Schilling --- lib/Controller/PresetController.php | 46 +++++++++++++++++++++++++++++ lib/ResponseDefinitions.php | 7 +++++ 2 files changed, 53 insertions(+) create mode 100644 lib/Controller/PresetController.php diff --git a/lib/Controller/PresetController.php b/lib/Controller/PresetController.php new file mode 100644 index 00000000000..41f0b4a167f --- /dev/null +++ b/lib/Controller/PresetController.php @@ -0,0 +1,46 @@ +, array{}> + * + * 200: Successfully got presets + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/preset', requirements: [ + 'apiVersion' => '(v1)', + 'token' => '[a-z0-9]{4,30}', + ])] + public function getPresets(): DataResponse { + return new DataResponse([], Http::STATUS_OK); + } +} diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 2de01080c14..e73c57b8476 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -580,6 +580,13 @@ * sendAt: int, * silent: bool, * } + * + * @psalm-type TalkConversationPreset = { + * // Identifier of the preset, currently known: default, webinar, presentation, hallway + * id: string, + * // Translated name of the preset in user's language + * name: string, + * } */ class ResponseDefinitions { }