Graduate user typing settings to Site Configuration > Posts (#38023)

* [MM-57814][MM-57815] Graduate user typing settings to Site Configuration > Posts

Move ServiceSettings.EnableUserTypingMessages and
ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds out of
System Console > Experimental > Features into the Performance & Limits
section of System Console > Site Configuration > Posts, and reclassify
their access tags from experimental_features to site_posts (preserving
write_restrictable and cloud_restrictable).

The two settings stay adjacent, and the timeout remains disabled while
typing messages are off. The timeout label now states its unit, since
"User Typing Timeout" alone did not convey milliseconds. The i18n ids
move from admin.experimental.* to the Posts page's admin.posts.*
convention; the "E.g.: 5000" placeholder previously shared with the
experimental user status and profile fetching poll interval is now
defined once per setting.

No config keys, defaults, or runtime behavior change.

* [MM-57814][MM-57815] Assert user typing settings are searchable under Posts

Searching the System Console for "typing" now also matches
Site Configuration > Posts, guarding the new location of the user typing
settings. Experimental Features still matches on unrelated help text
about typing a tilde to trigger channel autocomplete.

* [MM-57814][MM-57815] Move user typing settings docs out of Experimental

Document "Enable user typing messages" and "User typing timeout" in the
Posts section of the site configuration settings guide, and drop them
from the experimental configuration settings guide.
This commit is contained in:
Jesse Hallam
2026-08-18 16:32:00 -03:00
committed by GitHub
parent 78d120399f
commit 0bff02c814
6 changed files with 79 additions and 68 deletions
@@ -361,46 +361,6 @@ Set a default theme that applies to all new users on the system.
</tbody>
</table>
### Enable user typing messages
This setting determines whether "user is typing..." messages are displayed below the message box when using Mattermost in a web browser or the desktop app.
<table style={{width: '98%'}}>
<colgroup>
<col style={{width: '98%'}} />
</colgroup>
<tbody>
<tr>
<td>This feature's <code>config.json</code> setting is <code>"EnableUserTypingMessages": true</code> with options <code>true</code> and <code>false</code>.</td>
</tr>
</tbody>
</table>
<Note>
Disabling this experimental configuration setting in larger deployments may improve server performance in the following areas:
- Reduced Server Load: Typing events generate additional websocket traffic. Disabling them can reduce the amount of data that needs to be handled by the server, improving the overall response time and decreasing server load.
- Lower Network Traffic: When typing events are enabled, every keystroke generates a network event. This can lead to a significant amount of network traffic, particularly in busy channels. Disabling these events reduces the amount of information transmitted over the network.
- Client Performance: On the client side, processing typing events requires resources. By not having to handle these events, the client can be more responsive and use less memory and CPU.
</Note>
### User typing timeout
This setting defines how frequently "user is typing..." messages are updated, measured in milliseconds.
<table style={{width: '99%'}}>
<colgroup>
<col style={{width: '99%'}} />
</colgroup>
<tbody>
<tr>
<td>This feature's <code>config.json</code> setting is <code>"TimeBetweenUserTypingUpdatesMilliseconds": 5000</code> with numerical input.</td>
</tr>
</tbody>
</table>
### User's status and profile fetching poll interval
This setting configures the number of milliseconds to wait between fetching user statuses and profiles periodically. Set to `0` to disable.
@@ -1714,6 +1714,52 @@ While drafts can be very useful for maintaining work continuity, especially in c
</tbody>
</table>
### Enable user typing messages
<table>
<colgroup>
<col style={{width: '43%'}} />
<col style={{width: '56%'}} />
</colgroup>
<tbody>
<tr>
<td><p>This setting determines whether "user is typing..." messages are displayed below the message box.</p><ul><li><strong>true</strong>: <strong>(Default)</strong> "User is typing..." messages are displayed below the message box.</li><li><strong>false</strong>: "User is typing..." messages are not displayed.</li></ul></td>
<td><ul><li>System Config path: <strong>Site Configuration &gt; Posts</strong></li><li><code>config.json</code> setting: <code>ServiceSettings</code> &gt; <code>EnableUserTypingMessages</code> &gt; <code>true</code></li><li>Environment variable: <code>MM_SERVICESETTINGS_ENABLEUSERTYPINGMESSAGES</code></li></ul></td>
</tr>
</tbody>
</table>
<Note>
Disabling this configuration setting in larger deployments may improve server performance in the following areas:
- Reduced Server Load: Typing events generate additional websocket traffic. Disabling them can reduce the amount of data that needs to be handled by the server, improving the overall response time and decreasing server load.
- Lower Network Traffic: When typing events are enabled, every keystroke generates a network event. This can lead to a significant amount of network traffic, particularly in busy channels. Disabling these events reduces the amount of information transmitted over the network.
- Client Performance: On the client side, processing typing events requires resources. By not having to handle these events, the client can be more responsive and use less memory and CPU.
</Note>
### User typing timeout
<table>
<colgroup>
<col style={{width: '43%'}} />
<col style={{width: '56%'}} />
</colgroup>
<tbody>
<tr>
<td><p>The number of milliseconds to wait between emitting user typing websocket events, which determines how frequently "user is typing..." messages are updated.</p><p>Numerical input in milliseconds. Default is <strong>5000</strong>. Minimum is 1000.</p></td>
<td><ul><li>System Config path: <strong>Site Configuration &gt; Posts</strong></li><li><code>config.json</code> setting: <code>ServiceSettings</code> &gt; <code>TimeBetweenUserTypingUpdatesMilliseconds</code> &gt; <code>5000</code></li><li>Environment variable: <code>MM_SERVICESETTINGS_TIMEBETWEENUSERTYPINGUPDATESMILLISECONDS</code></li></ul></td>
</tr>
</tbody>
</table>
<Note>
This setting only applies when **Enable user typing messages** is set to **true**.
</Note>
------------------------------------------------------------------------------------------------------------------------
## Content flagging
+2 -2
View File
@@ -435,12 +435,12 @@ type ServiceSettings struct {
EnableCustomEmoji *bool `access:"site_emoji"`
EnableEmojiPicker *bool `access:"site_emoji"`
PostEditTimeLimit *int `access:"user_management_permissions"`
TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"`
TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"site_posts,write_restrictable,cloud_restrictable"`
EnableCrossTeamSearch *bool `access:"write_restrictable,cloud_restrictable"`
EnablePostSearch *bool `access:"write_restrictable,cloud_restrictable"`
EnableFileSearch *bool `access:"write_restrictable"`
MinimumHashtagLength *int `access:"environment_database,write_restrictable,cloud_restrictable"`
EnableUserTypingMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
EnableUserTypingMessages *bool `access:"site_posts,write_restrictable,cloud_restrictable"`
EnableChannelViewedMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
EnableUserStatuses *bool `access:"write_restrictable,cloud_restrictable"`
ExperimentalEnableAuthenticationTransfer *bool `access:"experimental_features"`
@@ -3814,6 +3814,26 @@ const AdminDefinition: AdminDefinitionType = {
return new ValidationResult(true, '');
},
},
{
type: 'bool',
key: 'ServiceSettings.EnableUserTypingMessages',
label: defineMessage({id: 'admin.posts.enableUserTypingMessages.title', defaultMessage: 'Enable User Typing Messages:'}),
help_text: defineMessage({id: 'admin.posts.enableUserTypingMessages.desc', defaultMessage: 'This setting determines whether "user is typing..." messages are displayed below the message box. Disabling the setting in larger deployments may improve server performance.'}),
help_text_markdown: false,
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.POSTS)),
},
{
type: 'number',
key: 'ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds',
label: defineMessage({id: 'admin.posts.timeBetweenUserTypingUpdatesMilliseconds.title', defaultMessage: 'User Typing Timeout (milliseconds):'}),
help_text: defineMessage({id: 'admin.posts.timeBetweenUserTypingUpdatesMilliseconds.desc', defaultMessage: 'The number of milliseconds to wait between emitting user typing websocket events.'}),
help_text_markdown: false,
placeholder: defineMessage({id: 'admin.posts.timeBetweenUserTypingUpdatesMilliseconds.example', defaultMessage: 'E.g.: "5000"'}),
isDisabled: it.any(
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.POSTS)),
it.stateIsFalse('ServiceSettings.EnableUserTypingMessages'),
),
},
],
},
],
@@ -6679,33 +6699,13 @@ const AdminDefinition: AdminDefinitionType = {
help_text_markdown: false,
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
},
{
type: 'bool',
key: 'ServiceSettings.EnableUserTypingMessages',
label: defineMessage({id: 'admin.experimental.enableUserTypingMessages.title', defaultMessage: 'Enable User Typing Messages:'}),
help_text: defineMessage({id: 'admin.experimental.enableUserTypingMessages.desc', defaultMessage: 'This setting determines whether "user is typing..." messages are displayed below the message box. Disabling the setting in larger deployments may improve server performance.'}),
help_text_markdown: false,
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
},
{
type: 'number',
key: 'ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds',
label: defineMessage({id: 'admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.title', defaultMessage: 'User Typing Timeout:'}),
help_text: defineMessage({id: 'admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.desc', defaultMessage: 'The number of milliseconds to wait between emitting user typing websocket events.'}),
help_text_markdown: false,
placeholder: defineMessage({id: 'admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.example', defaultMessage: 'E.g.: "5000"'}),
isDisabled: it.any(
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
it.stateIsFalse('ServiceSettings.EnableUserTypingMessages'),
),
},
{
type: 'number',
key: 'ExperimentalSettings.UsersStatusAndProfileFetchingPollIntervalMilliseconds',
label: defineMessage({id: 'admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.title', defaultMessage: 'User\'s Status and Profile Fetching Poll Interval:'}),
help_text: defineMessage({id: 'admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.desc', defaultMessage: 'The number of milliseconds to wait between fetching user statuses and profiles periodically.'}),
help_text_markdown: false,
placeholder: defineMessage({id: 'admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.example', defaultMessage: 'E.g.: "5000"'}),
placeholder: defineMessage({id: 'admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.example', defaultMessage: 'E.g.: "5000"'}),
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
},
{
+6 -5
View File
@@ -1338,8 +1338,6 @@
"admin.experimental.enableTutorial.title": "Enable Tutorial:",
"admin.experimental.enableUserDeactivation.desc": "When true, users may deactivate their own account from **Settings > Advanced**. If a user deactivates their own account, they will get an email notification confirming they were deactivated. When false, users may not deactivate their own account.",
"admin.experimental.enableUserDeactivation.title": "Enable Account Deactivation:",
"admin.experimental.enableUserTypingMessages.desc": "This setting determines whether \"user is typing...\" messages are displayed below the message box. Disabling the setting in larger deployments may improve server performance.",
"admin.experimental.enableUserTypingMessages.title": "Enable User Typing Messages:",
"admin.experimental.enableWatermark.desc": "When true, authenticated mobile sessions will display a watermark overlay showing the username, domain, date (YYYY-MM-DD), and time (HH:mm) for data loss prevention (DLP) purposes.",
"admin.experimental.enableWatermark.title": "Enable Mobile Watermark:",
"admin.experimental.experimentalEnableAuthenticationTransfer.desc": "When true, users can change their sign-in method to any that is enabled on the server, either via their Profile or the APIs. When false, Users cannot change their sign-in method, regardless of which authentication options are enabled.",
@@ -1371,12 +1369,10 @@
"admin.experimental.PermittedMoveThreadRoles.title": "Permitted Roles",
"admin.experimental.threadAutoFollow.desc": "This setting must be enabled in order to enable Threaded Discussions. When enabled, threads a user starts, participates in, or is mentioned in are automatically followed. A new `Threads` table is added in the database that tracks threads and thread participants, and a `ThreadMembership` table tracks followed threads for each user and the read or unread state of each followed thread. When false, all backend operations to support Threaded Discussions are disabled.",
"admin.experimental.threadAutoFollow.title": "Automatically Follow Threads",
"admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.desc": "The number of milliseconds to wait between emitting user typing websocket events.",
"admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.example": "E.g.: \"5000\"",
"admin.experimental.timeBetweenUserTypingUpdatesMilliseconds.title": "User Typing Timeout:",
"admin.experimental.useChannelInEmailNotifications.desc": "When true, channel and team name appears in email notification subject lines. Useful for servers using only one team. When false, only team name appears in email notification subject line.",
"admin.experimental.useChannelInEmailNotifications.title": "Use Channel Name in Email Notifications:",
"admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.desc": "The number of milliseconds to wait between fetching user statuses and profiles periodically.",
"admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.example": "E.g.: \"5000\"",
"admin.experimental.UsersStatusAndProfileFetchingPollIntervalMilliseconds.title": "User's Status and Profile Fetching Poll Interval:",
"admin.experimental.userStatusAwayTimeout.desc": "This setting defines the number of seconds after which the user's status indicator changes to \"Away\", when they are away from Mattermost.",
"admin.experimental.userStatusAwayTimeout.example": "E.g.: \"300\"",
@@ -2839,6 +2835,8 @@
"admin.posts.burnOnRead.maximumTTL.7days": "7 days",
"admin.posts.burnOnRead.maximumTTL.desc": "Sets the maximum duration that Burn-on-Read messages will be allowed to exist for after they are sent. The message will be deleted after the specified time after it is sent, even if it is not read by all recipients by then.",
"admin.posts.burnOnRead.maximumTTL.title": "Maximum time to live for burn-on-read messages",
"admin.posts.enableUserTypingMessages.desc": "This setting determines whether \"user is typing...\" messages are displayed below the message box. Disabling the setting in larger deployments may improve server performance.",
"admin.posts.enableUserTypingMessages.title": "Enable User Typing Messages:",
"admin.posts.persistentNotifications.desc": "When enabled, users can trigger repeating notifications for the recipients of urgent messages. Learn more about message priority and persistent notifications in our <link>documentation</link>.",
"admin.posts.persistentNotifications.title": "Persistent Notifications",
"admin.posts.persistentNotificationsGuests.desc": "Whether a guest is able to require persistent notifications. Learn more about message priority and persistent notifications in our <link>documentation</link>.",
@@ -2866,6 +2864,9 @@
"admin.posts.sections.priority.title": "Priority & Urgent Notifications",
"admin.posts.sections.threads.description": "Configure threaded discussions and auto-follow defaults.",
"admin.posts.sections.threads.title": "Threads",
"admin.posts.timeBetweenUserTypingUpdatesMilliseconds.desc": "The number of milliseconds to wait between emitting user typing websocket events.",
"admin.posts.timeBetweenUserTypingUpdatesMilliseconds.example": "E.g.: \"5000\"",
"admin.posts.timeBetweenUserTypingUpdatesMilliseconds.title": "User Typing Timeout (milliseconds):",
"admin.privacy.showEmailDescription": "When false, hides the email address of members from everyone except System Administrators and the System Roles with read/write access to Compliance, Billing, or User Management.",
"admin.privacy.showEmailTitle": "Show Email Address:",
"admin.privacy.showFullNameDescription": "When false, hides the full name of members from everyone except System Administrators. Username is shown in place of full name.",
@@ -38,6 +38,10 @@ describe('AdminConsoleIndex.generateIndex', () => {
'site_config/customization',
'authentication/password',
]);
expect(idx.search('typing')).toEqual([
'experimental/features',
'site_config/posts',
]);
expect(idx.search('caracteres')).toEqual([]);
expect(idx.search('notexistingword')).toEqual([]);
});