diff options
-rw-r--r-- | config/config.json | 4 | ||||
-rw-r--r-- | i18n/en.json | 4 | ||||
-rw-r--r-- | model/config.go | 94 | ||||
-rw-r--r-- | utils/config.go | 4 | ||||
-rw-r--r-- | webapp/actions/global_actions.jsx | 4 | ||||
-rw-r--r-- | webapp/stores/user_typing_store.jsx | 2 | ||||
-rw-r--r-- | webapp/utils/constants.jsx | 1 |
7 files changed, 70 insertions, 43 deletions
diff --git a/config/config.json b/config/config.json index f538e9686..330db637d 100644 --- a/config/config.json +++ b/config/config.json @@ -38,7 +38,9 @@ "RestrictCustomEmojiCreation": "all", "RestrictPostDelete": "all", "AllowEditPost": "always", - "PostEditTimeLimit": 300 + "PostEditTimeLimit": 300, + "TimeBetweenUserTypingUpdatesMilliseconds": 5000, + "EnableUserTypingMessages": true }, "TeamSettings": { "SiteName": "Mattermost", diff --git a/i18n/en.json b/i18n/en.json index 4b254a42c..7a8c24cbb 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -3536,6 +3536,10 @@ "translation": "To must be greater than From" }, { + "id": "model.config.is_valid.time_between_user_typing.app_error", + "translation": "Time btween user typing updates should not be set less than 1000 milliseconds." + }, + { "id": "model.config.is_valid.cluster_email_batching.app_error", "translation": "Unable to enable email batching when clustering is enabled" }, diff --git a/model/config.go b/model/config.go index 13e795170..4588731b6 100644 --- a/model/config.go +++ b/model/config.go @@ -64,45 +64,47 @@ const ( ) type ServiceSettings struct { - SiteURL *string - ListenAddress string - ConnectionSecurity *string - TLSCertFile *string - TLSKeyFile *string - UseLetsEncrypt *bool - LetsEncryptCertificateCacheFile *string - Forward80To443 *bool - ReadTimeout *int - WriteTimeout *int - MaximumLoginAttempts int - SegmentDeveloperKey string - GoogleDeveloperKey string - EnableOAuthServiceProvider bool - EnableIncomingWebhooks bool - EnableOutgoingWebhooks bool - EnableCommands *bool - EnableOnlyAdminIntegrations *bool - EnablePostUsernameOverride bool - EnablePostIconOverride bool - EnableTesting bool - EnableDeveloper *bool - EnableSecurityFixAlert *bool - EnableInsecureOutgoingConnections *bool - EnableMultifactorAuthentication *bool - EnforceMultifactorAuthentication *bool - AllowCorsFrom *string - SessionLengthWebInDays *int - SessionLengthMobileInDays *int - SessionLengthSSOInDays *int - SessionCacheInMinutes *int - WebsocketSecurePort *int - WebsocketPort *int - WebserverMode *string - EnableCustomEmoji *bool - RestrictCustomEmojiCreation *string - RestrictPostDelete *string - AllowEditPost *string - PostEditTimeLimit *int + SiteURL *string + ListenAddress string + ConnectionSecurity *string + TLSCertFile *string + TLSKeyFile *string + UseLetsEncrypt *bool + LetsEncryptCertificateCacheFile *string + Forward80To443 *bool + ReadTimeout *int + WriteTimeout *int + MaximumLoginAttempts int + SegmentDeveloperKey string + GoogleDeveloperKey string + EnableOAuthServiceProvider bool + EnableIncomingWebhooks bool + EnableOutgoingWebhooks bool + EnableCommands *bool + EnableOnlyAdminIntegrations *bool + EnablePostUsernameOverride bool + EnablePostIconOverride bool + EnableTesting bool + EnableDeveloper *bool + EnableSecurityFixAlert *bool + EnableInsecureOutgoingConnections *bool + EnableMultifactorAuthentication *bool + EnforceMultifactorAuthentication *bool + AllowCorsFrom *string + SessionLengthWebInDays *int + SessionLengthMobileInDays *int + SessionLengthSSOInDays *int + SessionCacheInMinutes *int + WebsocketSecurePort *int + WebsocketPort *int + WebserverMode *string + EnableCustomEmoji *bool + RestrictCustomEmojiCreation *string + RestrictPostDelete *string + AllowEditPost *string + PostEditTimeLimit *int + TimeBetweenUserTypingUpdatesMilliseconds *int64 + EnableUserTypingMessages *bool } type ClusterSettings struct { @@ -1072,6 +1074,16 @@ func (o *Config) SetDefaults() { *o.MetricsSettings.BlockProfileRate = 0 } + if o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds == nil { + o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = new(int64) + *o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = 5000 + } + + if o.ServiceSettings.EnableUserTypingMessages == nil { + o.ServiceSettings.EnableUserTypingMessages = new(bool) + *o.ServiceSettings.EnableUserTypingMessages = true + } + o.defaultWebrtcSettings() } @@ -1303,6 +1315,10 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.write_timeout.app_error", nil, "") } + if *o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds < 1000 { + return NewLocAppError("Config.IsValid", "model.config.is_valid.time_between_user_typing.app_error", nil, "") + } + return nil } diff --git a/utils/config.go b/utils/config.go index 72c30c01b..243e2b984 100644 --- a/utils/config.go +++ b/utils/config.go @@ -311,6 +311,10 @@ func getClientConfig(c *model.Config) map[string]string { props["EnableWebrtc"] = strconv.FormatBool(*c.WebrtcSettings.Enable) + props["MaxNotificationsPerChannel"] = strconv.FormatInt(*c.TeamSettings.MaxNotificationsPerChannel, 10) + props["TimeBetweenUserTypingUpdatesMilliseconds"] = strconv.FormatInt(*c.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds, 10) + props["EnableUserTypingMessages"] = strconv.FormatBool(*c.ServiceSettings.EnableUserTypingMessages) + if IsLicensed { if *License.Features.CustomBrand { props["EnableCustomBrand"] = strconv.FormatBool(*c.TeamSettings.EnableCustomBrand) diff --git a/webapp/actions/global_actions.jsx b/webapp/actions/global_actions.jsx index c8da43f24..beca75509 100644 --- a/webapp/actions/global_actions.jsx +++ b/webapp/actions/global_actions.jsx @@ -454,7 +454,9 @@ export function viewLoggedIn() { let lastTimeTypingSent = 0; export function emitLocalUserTypingEvent(channelId, parentId) { const t = Date.now(); - if ((t - lastTimeTypingSent) > Constants.UPDATE_TYPING_MS) { + const membersInChannel = ChannelStore.getStats(channelId).member_count; + + if (((t - lastTimeTypingSent) > global.window.mm_config.TimeBetweenUserTypingUpdatesMilliseconds) && membersInChannel < global.window.mm_config.MaxNotificationsPerChannel && global.window.mm_config.EnableUserTypingMessages === 'true') { WebSocketClient.userTyping(channelId, parentId); lastTimeTypingSent = t; } diff --git a/webapp/stores/user_typing_store.jsx b/webapp/stores/user_typing_store.jsx index 85c10bfbe..8bbce117f 100644 --- a/webapp/stores/user_typing_store.jsx +++ b/webapp/stores/user_typing_store.jsx @@ -64,7 +64,7 @@ class UserTypingStoreClass extends EventEmitter { Reflect.deleteProperty(this.typingUsers, loc); } this.emitChange(); - }, Constants.UPDATE_TYPING_MS); + }, parseInt(window.mm_config.TimeBetweenUserTypingUpdatesMilliseconds, 10)); this.emitChange(); } diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx index dd9a4486e..bd50534f2 100644 --- a/webapp/utils/constants.jsx +++ b/webapp/utils/constants.jsx @@ -407,7 +407,6 @@ export const Constants = { REPLY_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'viewBox='-158 242 18 18' style='enable-background:new -158 242 18 18;' xml:space='preserve'> <path d='M-142.2,252.6c-2-3-4.8-4.7-8.3-4.8v-3.3c0-0.2-0.1-0.3-0.2-0.3s-0.3,0-0.4,0.1l-6.9,6.2c-0.1,0.1-0.1,0.2-0.1,0.3 c0,0.1,0,0.2,0.1,0.3l6.9,6.4c0.1,0.1,0.3,0.1,0.4,0.1c0.1-0.1,0.2-0.2,0.2-0.4v-3.8c4.2,0,7.4,0.4,9.6,4.4c0.1,0.1,0.2,0.2,0.3,0.2 c0,0,0.1,0,0.1,0c0.2-0.1,0.3-0.3,0.2-0.4C-140.2,257.3-140.6,255-142.2,252.6z M-150.8,252.5c-0.2,0-0.4,0.2-0.4,0.4v3.3l-6-5.5 l6-5.3v2.8c0,0.2,0.2,0.4,0.4,0.4c3.3,0,6,1.5,8,4.5c0.5,0.8,0.9,1.6,1.2,2.3C-144,252.8-147.1,252.5-150.8,252.5z'/> </svg>", SCROLL_BOTTOM_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'viewBox='-239 239 21 23' style='enable-background:new -239 239 21 23;' xml:space='preserve'> <path d='M-239,241.4l2.4-2.4l8.1,8.2l8.1-8.2l2.4,2.4l-10.5,10.6L-239,241.4z M-228.5,257.2l8.1-8.2l2.4,2.4l-10.5,10.6l-10.5-10.6 l2.4-2.4L-228.5,257.2z'/> </svg>", VIDEO_ICON: "<svg width='55%'height='100%'viewBox='0 0 13 8'> <g transform='matrix(1,0,0,1,-507,-146)'> <g transform='matrix(0.0133892,0,0,0.014499,500.635,142.838)'> <path d='M1158,547.286L1158,644.276C1158,684.245 1125.55,716.694 1085.58,716.694L579.341,716.694C539.372,716.694 506.922,684.245 506.922,644.276L506.922,306.322C506.922,266.353 539.371,233.904 579.341,233.903L1085.58,233.903C1125.55,233.904 1158,266.353 1158,306.322L1158,402.939L1359.75,253.14C1365.83,248.362 1373.43,245.973 1382.56,245.973C1386.61,245.973 1390.83,246.602 1395.22,247.859C1408.4,252.134 1414.99,259.552 1414.99,270.113L1414.99,680.485C1414.99,691.046 1408.4,698.464 1395.22,702.739C1390.83,703.996 1386.61,704.624 1382.56,704.624C1373.43,704.624 1365.83,702.236 1359.75,697.458L1158,547.286Z'/> </g> </g> </svg>", - UPDATE_TYPING_MS: 5000, THEMES: { default: { type: 'Organization', |