From 756388fc5435f961130eb72bb91cc21894889e62 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Wed, 25 Mar 2026 13:40:33 +0100 Subject: [PATCH 1/5] feat: add user preferences for conversations sort - allow users to sort conversations by recent activity, alphabetical order, or put group/private chat first. Co-Authored-By: Claude Opus 4.6 Co-Authored-By: Rikdekker Signed-off-by: Maksim Sukharev --- docs/capabilities.md | 2 + docs/constants.md | 13 +++++ lib/Capabilities.php | 4 ++ lib/Config.php | 48 +++++++++++++++++++ lib/ResponseDefinitions.php | 4 ++ .../BeforePreferenceSetEventListener.php | 10 ++++ lib/Settings/UserPreference.php | 9 ++++ tests/php/CapabilitiesTest.php | 16 +++++++ 8 files changed, 106 insertions(+) diff --git a/docs/capabilities.md b/docs/capabilities.md index c0b4c7815a7..1a173953c60 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -222,3 +222,5 @@ * `config => call => grid-limit-enforced` (local) - Whether the limit is hard enforced for all participants * `config => feature-hints => current` (local) - The current feature hint count that should be sent to the app config to hide all current feature hints * `config => feature-hints => hidden` (local) - Number of the last hint the administration has hidden via the app config +* `config => conversations => sort-order` (local) - User selected sort order for conversations (`activity` or `alphabetical`) +* `config => conversations => group-mode` (local) - User selected grouping mode for conversations (`none`, `group-first` or `private-first`) diff --git a/docs/constants.md b/docs/constants.md index 83f59caeca1..50c26d6d7f3 100644 --- a/docs/constants.md +++ b/docs/constants.md @@ -58,6 +58,19 @@ * `two-lines` Normal (default) - two-line elements (with display name and last message) * `compact` Compact - one-line elements (with display name) +### Conversations sort options +Required capability: `config => conversations => sort-order` + +* `activity` (default) - Conversations are ordered by last chat or call activity +* `alphabetical` - Conversations are ordered by the display name + +### Conversations group mode +Required capability: `config => conversations => group-mode` + +* `none` (default) - Conversations are not grouped by type +* `group-first` - Conversations are grouped and group (and public) conversations shown first +* `private-first` - Conversations are grouped and private (one-to-one) conversations shown first + ### Conversation attributes Required capability: `conversation-presets` diff --git a/lib/Capabilities.php b/lib/Capabilities.php index 3281d9e2d7c..3641116913a 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -193,6 +193,8 @@ class Capabilities implements IPublicCapability { 'conversations' => [ 'can-create', 'list-style', + 'sort-order', + 'group-mode', 'description-length', ], 'federation' => [ @@ -294,6 +296,8 @@ public function getCapabilities(): array { 'can-create' => $user instanceof IUser && !$this->talkConfig->isNotAllowedToCreateConversations($user), 'force-passwords' => $this->talkConfig->isPasswordEnforced(), 'list-style' => $this->talkConfig->getConversationsListStyle($user?->getUID()), + 'sort-order' => $this->talkConfig->getConversationsSortOrder($user?->getUID()), + 'group-mode' => $this->talkConfig->getConversationsGroupMode($user?->getUID()), 'description-length' => Room::DESCRIPTION_MAXIMUM_LENGTH, 'retention-event' => max(0, $this->appConfig->getAppValueInt('retention_event_rooms', 28)), 'retention-phone' => max(0, $this->appConfig->getAppValueInt('retention_phone_rooms', 7)), diff --git a/lib/Config.php b/lib/Config.php index 5153ea00dc1..65e9da6752c 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -813,6 +813,54 @@ public function getChatStyle(?string $userId): string { return UserPreference::CHAT_STYLE_SPLIT; } + /** + * User setting for conversations sort order + * + * @param ?string $userId + * @return UserPreference::CONVERSATIONS_SORT_ORDER_* + */ + public function getConversationsSortOrder(?string $userId): string { + if ($userId !== null) { + $userSetting = $this->config->getUserValue( + $userId, + 'spreed', + UserPreference::CONVERSATIONS_SORT_ORDER, + ); + + if (in_array($userSetting, [UserPreference::CONVERSATIONS_SORT_ORDER_ACTIVITY, UserPreference::CONVERSATIONS_SORT_ORDER_ALPHABETICAL], true)) { + return $userSetting; + } + } + + return UserPreference::CONVERSATIONS_SORT_ORDER_ACTIVITY; + } + + /** + * User setting for conversations group mode + * + * @param ?string $userId + * @return UserPreference::CONVERSATIONS_GROUP_MODE_* + */ + public function getConversationsGroupMode(?string $userId): string { + if ($userId !== null) { + $userSetting = $this->config->getUserValue( + $userId, + 'spreed', + UserPreference::CONVERSATIONS_GROUP_MODE, + ); + + if (in_array($userSetting, [ + UserPreference::CONVERSATIONS_GROUP_MODE_NONE, + UserPreference::CONVERSATIONS_GROUP_MODE_GROUP_FIRST, + UserPreference::CONVERSATIONS_GROUP_MODE_PRIVATE_FIRST, + ], true)) { + return $userSetting; + } + } + + return UserPreference::CONVERSATIONS_GROUP_MODE_NONE; + } + /** * User setting falling back to admin defined app config */ diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 4a8bca9a1f8..522dd0c5772 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -815,6 +815,10 @@ * retention-phone: non-negative-int, * // Retention period for instant meetings in seconds, `0` means no retention * retention-instant-meetings: non-negative-int, + * // User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * sort-order: 'activity'|'alphabetical', + * // User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * group-mode: 'none'|'group-first'|'private-first', * }, * federation: array{ * // Whether federation is enabled diff --git a/lib/Settings/BeforePreferenceSetEventListener.php b/lib/Settings/BeforePreferenceSetEventListener.php index bacd965650e..fe59b8ad0c5 100644 --- a/lib/Settings/BeforePreferenceSetEventListener.php +++ b/lib/Settings/BeforePreferenceSetEventListener.php @@ -84,6 +84,16 @@ public function validatePreference(string $userId, string $key, string|int|null if ($key === UserPreference::CHAT_STYLE) { return $value === UserPreference::CHAT_STYLE_SPLIT || $value === UserPreference::CHAT_STYLE_UNIFIED; } + if ($key === UserPreference::CONVERSATIONS_SORT_ORDER) { + return $value === UserPreference::CONVERSATIONS_SORT_ORDER_ACTIVITY || $value === UserPreference::CONVERSATIONS_SORT_ORDER_ALPHABETICAL; + } + if ($key === UserPreference::CONVERSATIONS_GROUP_MODE) { + return in_array($value, [ + UserPreference::CONVERSATIONS_GROUP_MODE_NONE, + UserPreference::CONVERSATIONS_GROUP_MODE_GROUP_FIRST, + UserPreference::CONVERSATIONS_GROUP_MODE_PRIVATE_FIRST, + ], true); + } if ($key === UserPreference::LIVE_TRANSCRIPTION_TARGET_LANGUAGE_ID) { // Accept any value, as it will be used for both local and federated diff --git a/lib/Settings/UserPreference.php b/lib/Settings/UserPreference.php index 8c7df0ab972..13cba0c6f70 100644 --- a/lib/Settings/UserPreference.php +++ b/lib/Settings/UserPreference.php @@ -25,5 +25,14 @@ class UserPreference { public const CHAT_STYLE_SPLIT = 'split'; public const CHAT_STYLE_UNIFIED = 'unified'; + public const CONVERSATIONS_SORT_ORDER = 'conversations_sort_order'; + public const CONVERSATIONS_SORT_ORDER_ACTIVITY = 'activity'; + public const CONVERSATIONS_SORT_ORDER_ALPHABETICAL = 'alphabetical'; + + public const CONVERSATIONS_GROUP_MODE = 'conversations_group_mode'; + public const CONVERSATIONS_GROUP_MODE_NONE = 'none'; + public const CONVERSATIONS_GROUP_MODE_GROUP_FIRST = 'group-first'; + public const CONVERSATIONS_GROUP_MODE_PRIVATE_FIRST = 'private-first'; + public const LIVE_TRANSCRIPTION_TARGET_LANGUAGE_ID = 'live_transcription_target_language_id'; } diff --git a/tests/php/CapabilitiesTest.php b/tests/php/CapabilitiesTest.php index 5370b7f7ca8..63a9f979164 100644 --- a/tests/php/CapabilitiesTest.php +++ b/tests/php/CapabilitiesTest.php @@ -100,6 +100,12 @@ public function testGetCapabilitiesGuest(): void { $this->talkConfig->method('getConversationsListStyle') ->willReturn('two-lines'); + $this->talkConfig->method('getConversationsSortOrder') + ->willReturn('activity'); + + $this->talkConfig->method('getConversationsGroupMode') + ->willReturn('none'); + $this->talkConfig->expects($this->once()) ->method('isBreakoutRoomsEnabled') ->willReturn(false); @@ -212,6 +218,8 @@ public function testGetCapabilitiesGuest(): void { 'can-create' => false, 'force-passwords' => false, 'list-style' => 'two-lines', + 'sort-order' => 'activity', + 'group-mode' => 'none', 'description-length' => 2000, 'retention-event' => 28, 'retention-phone' => 7, @@ -306,6 +314,12 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea $this->talkConfig->method('getConversationsListStyle') ->willReturn('two-lines'); + $this->talkConfig->method('getConversationsSortOrder') + ->willReturn('activity'); + + $this->talkConfig->method('getConversationsGroupMode') + ->willReturn('none'); + $this->talkConfig->expects($this->any()) ->method('getSignalingMode') ->willReturn('internal'); @@ -426,6 +440,8 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea 'can-create' => $canCreate, 'force-passwords' => false, 'list-style' => 'two-lines', + 'sort-order' => 'activity', + 'group-mode' => 'none', 'description-length' => 2000, 'retention-event' => 28, 'retention-phone' => 7, From 58a88cf8687fd2b83df688f56c808a96b152223f Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Wed, 25 Mar 2026 13:42:17 +0100 Subject: [PATCH 2/5] chore(assets): Recompile assets Signed-off-by: Maksim Sukharev --- openapi-administration.json | 21 ++++++++++++++++++- openapi-backend-recording.json | 21 ++++++++++++++++++- openapi-backend-signaling.json | 21 ++++++++++++++++++- openapi-backend-sipbridge.json | 21 ++++++++++++++++++- openapi-bots.json | 21 ++++++++++++++++++- openapi-federation.json | 21 ++++++++++++++++++- openapi-full.json | 21 ++++++++++++++++++- openapi.json | 21 ++++++++++++++++++- src/types/openapi/openapi-administration.ts | 10 +++++++++ .../openapi/openapi-backend-recording.ts | 10 +++++++++ .../openapi/openapi-backend-signaling.ts | 10 +++++++++ .../openapi/openapi-backend-sipbridge.ts | 10 +++++++++ src/types/openapi/openapi-bots.ts | 10 +++++++++ src/types/openapi/openapi-federation.ts | 10 +++++++++ src/types/openapi/openapi-full.ts | 10 +++++++++ src/types/openapi/openapi.ts | 10 +++++++++ 16 files changed, 240 insertions(+), 8 deletions(-) diff --git a/openapi-administration.json b/openapi-administration.json index 0fd889f2c27..eb8a3cde2a6 100644 --- a/openapi-administration.json +++ b/openapi-administration.json @@ -348,7 +348,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -390,6 +392,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-backend-recording.json b/openapi-backend-recording.json index a1f221d70fb..97d7a0cd4b8 100644 --- a/openapi-backend-recording.json +++ b/openapi-backend-recording.json @@ -271,7 +271,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -313,6 +315,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-backend-signaling.json b/openapi-backend-signaling.json index 899f9be2b9a..6c3c373319c 100644 --- a/openapi-backend-signaling.json +++ b/openapi-backend-signaling.json @@ -271,7 +271,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -313,6 +315,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-backend-sipbridge.json b/openapi-backend-sipbridge.json index 2f7b09835d4..8ac6d629a58 100644 --- a/openapi-backend-sipbridge.json +++ b/openapi-backend-sipbridge.json @@ -322,7 +322,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -364,6 +366,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-bots.json b/openapi-bots.json index cc4a33c2a91..8189fe5dab7 100644 --- a/openapi-bots.json +++ b/openapi-bots.json @@ -271,7 +271,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -313,6 +315,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-federation.json b/openapi-federation.json index 8b62f32dd3d..da53397695f 100644 --- a/openapi-federation.json +++ b/openapi-federation.json @@ -322,7 +322,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -364,6 +366,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi-full.json b/openapi-full.json index 2db353b447e..3aa9f8a0512 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -505,7 +505,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -547,6 +549,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/openapi.json b/openapi.json index f612b57f35d..e78da0e1556 100644 --- a/openapi.json +++ b/openapi.json @@ -458,7 +458,9 @@ "description-length", "retention-event", "retention-phone", - "retention-instant-meetings" + "retention-instant-meetings", + "sort-order", + "group-mode" ], "properties": { "can-create": { @@ -500,6 +502,23 @@ "format": "int64", "description": "Retention period for instant meetings in seconds, `0` means no retention", "minimum": 0 + }, + "sort-order": { + "type": "string", + "enum": [ + "activity", + "alphabetical" + ], + "description": "User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options))" + }, + "group-mode": { + "type": "string", + "enum": [ + "none", + "group-first", + "private-first" + ], + "description": "User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode))" } } }, diff --git a/src/types/openapi/openapi-administration.ts b/src/types/openapi/openapi-administration.ts index 7f9d1f707ba..19275376495 100644 --- a/src/types/openapi/openapi-administration.ts +++ b/src/types/openapi/openapi-administration.ts @@ -358,6 +358,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-backend-recording.ts b/src/types/openapi/openapi-backend-recording.ts index a0de3a01a1f..3c2dd490835 100644 --- a/src/types/openapi/openapi-backend-recording.ts +++ b/src/types/openapi/openapi-backend-recording.ts @@ -172,6 +172,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-backend-signaling.ts b/src/types/openapi/openapi-backend-signaling.ts index b29ca9d8d3f..c0ee2a3eeda 100644 --- a/src/types/openapi/openapi-backend-signaling.ts +++ b/src/types/openapi/openapi-backend-signaling.ts @@ -158,6 +158,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-backend-sipbridge.ts b/src/types/openapi/openapi-backend-sipbridge.ts index 3fa8e81b172..ddf9fd27bd9 100644 --- a/src/types/openapi/openapi-backend-sipbridge.ts +++ b/src/types/openapi/openapi-backend-sipbridge.ts @@ -283,6 +283,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-bots.ts b/src/types/openapi/openapi-bots.ts index 4591277a2ec..a941632d280 100644 --- a/src/types/openapi/openapi-bots.ts +++ b/src/types/openapi/openapi-bots.ts @@ -176,6 +176,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-federation.ts b/src/types/openapi/openapi-federation.ts index 81e1c3b7ba3..ccd5e5a7449 100644 --- a/src/types/openapi/openapi-federation.ts +++ b/src/types/openapi/openapi-federation.ts @@ -294,6 +294,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 10c22a32eba..b6c429e2ca6 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -2646,6 +2646,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index e1fa42d20f8..fea85b1d712 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -2112,6 +2112,16 @@ export type components = { * @description Retention period for instant meetings in seconds, `0` means no retention */ "retention-instant-meetings": number; + /** + * @description User selected sort order for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-sort-options)) + * @enum {string} + */ + "sort-order": "activity" | "alphabetical"; + /** + * @description User selected grouping mode for conversations (see [constants list](https://nextcloud-talk.readthedocs.io/en/latest/constants#conversations-group-mode)) + * @enum {string} + */ + "group-mode": "none" | "group-first" | "private-first"; }; federation: { /** @description Whether federation is enabled */ From 22d46b62c4072dcc9381207aa4e4a416c8866f3c Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Wed, 25 Mar 2026 14:27:55 +0100 Subject: [PATCH 3/5] fix: move conversations sorting logic from store to the component Signed-off-by: Maksim Sukharev --- src/components/Dashboard/TalkDashboard.vue | 8 +++++++- src/components/LeftSidebar/LeftSidebar.spec.js | 6 ++++++ src/components/LeftSidebar/LeftSidebar.vue | 14 ++++++++++++-- src/store/conversationsStore.js | 11 ++--------- src/store/conversationsStore.spec.js | 2 +- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/components/Dashboard/TalkDashboard.vue b/src/components/Dashboard/TalkDashboard.vue index 4d5d432ceda..dd98fee8f1a 100644 --- a/src/components/Dashboard/TalkDashboard.vue +++ b/src/components/Dashboard/TalkDashboard.vue @@ -3,6 +3,8 @@ - SPDX-License-Identifier: AGPL-3.0-or-later -->