diff --git a/lib/api/model/initial_snapshot.dart b/lib/api/model/initial_snapshot.dart index 6be0cadda9..92bc145e08 100644 --- a/lib/api/model/initial_snapshot.dart +++ b/lib/api/model/initial_snapshot.dart @@ -77,6 +77,7 @@ class InitialSnapshot { final int maxFileUploadSizeMib; final Uri? serverEmojiDataUrl; // TODO(server-6) + final int maxMessageLength; @JsonKey(readValue: _readUsersIsActiveFallbackTrue) final List realmUsers; @@ -132,6 +133,7 @@ class InitialSnapshot { required this.realmUsers, required this.realmNonActiveUsers, required this.crossRealmBots, + required this.maxMessageLength, }); factory InitialSnapshot.fromJson(Map json) => diff --git a/lib/api/model/initial_snapshot.g.dart b/lib/api/model/initial_snapshot.g.dart index 75472c1d7f..cfc24ebf66 100644 --- a/lib/api/model/initial_snapshot.g.dart +++ b/lib/api/model/initial_snapshot.g.dart @@ -82,6 +82,7 @@ InitialSnapshot _$InitialSnapshotFromJson(Map json) => json, 'cross_realm_bots') as List) .map((e) => User.fromJson(e as Map)) .toList(), + maxMessageLength: (json['max_message_length'] as num).toInt(), ); Map _$InitialSnapshotToJson(InitialSnapshot instance) => @@ -112,6 +113,7 @@ Map _$InitialSnapshotToJson(InitialSnapshot instance) => 'realm_default_external_accounts': instance.realmDefaultExternalAccounts, 'max_file_upload_size_mib': instance.maxFileUploadSizeMib, 'server_emoji_data_url': instance.serverEmojiDataUrl?.toString(), + 'max_message_length': instance.maxMessageLength, 'realm_users': instance.realmUsers, 'realm_non_active_users': instance.realmNonActiveUsers, 'cross_realm_bots': instance.crossRealmBots, diff --git a/lib/model/store.dart b/lib/model/store.dart index 58a8a70615..9ab4982183 100644 --- a/lib/model/store.dart +++ b/lib/model/store.dart @@ -269,6 +269,7 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess connection: connection, realmUrl: realmUrl, realmWaitingPeriodThreshold: initialSnapshot.realmWaitingPeriodThreshold, + maxMessageLength : initialSnapshot.maxMessageLength, maxFileUploadSizeMib: initialSnapshot.maxFileUploadSizeMib, realmDefaultExternalAccounts: initialSnapshot.realmDefaultExternalAccounts, customProfileFields: _sortCustomProfileFields(initialSnapshot.customProfileFields), @@ -327,7 +328,7 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess required MessageStoreImpl messages, required this.unreads, required this.recentDmConversationsView, - required this.recentSenders, + required this.recentSenders, required this.maxMessageLength, }) : assert(selfUserId == globalStore.getAccount(accountId)!.userId), assert(realmUrl == globalStore.getAccount(accountId)!.realmUrl), assert(realmUrl == connection.realmUrl), @@ -348,6 +349,8 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess UpdateMachine? get updateMachine => _updateMachine; UpdateMachine? _updateMachine; + + set updateMachine(UpdateMachine? value) { assert(_updateMachine == null); assert(value != null); @@ -378,6 +381,7 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess /// For docs, please see [InitialSnapshot.realmWaitingPeriodThreshold]. final int realmWaitingPeriodThreshold; // TODO(#668): update this realm setting final int maxFileUploadSizeMib; // No event for this. + final int maxMessageLength; final Map realmDefaultExternalAccounts; List customProfileFields; /// For docs, please see [InitialSnapshot.emailAddressVisibility]. diff --git a/lib/widgets/compose_box.dart b/lib/widgets/compose_box.dart index 114e392bc7..dc385e23ff 100644 --- a/lib/widgets/compose_box.dart +++ b/lib/widgets/compose_box.dart @@ -118,6 +118,17 @@ class ComposeContentController extends ComposeController int _nextQuoteAndReplyTag = 0; int _nextUploadTag = 0; + num _maxMessageLimit = 0; + + num get maxMessageLimit => _maxMessageLimit; + + // Setter for maxMessageLimit + set maxMessageLimit(num value) { + if (value < 0) { + throw ArgumentError("maxMessageLimit cannot be negative."); + } + _maxMessageLimit = value; + } final Map _quoteAndReplies = {}; final Map _uploads = {}; @@ -260,7 +271,7 @@ class ComposeContentController extends ComposeController // normalized.length is the number of UTF-16 code units, while the server // API expresses the max in Unicode code points. So this comparison will // be conservative and may cut the user off shorter than necessary. - if (textNormalized.length > kMaxMessageLengthCodePoints) + if (textNormalized.length > _maxMessageLimit) ContentValidationError.tooLong, if (_quoteAndReplies.isNotEmpty) @@ -1322,7 +1333,8 @@ class _ComposeBoxState extends State implements ComposeBoxState { @override Widget build(BuildContext context) { final Widget? body; - + final perAccountStore = PerAccountStoreWidget.of(context); + _controller.content.maxMessageLimit = perAccountStore.maxMessageLength; final errorBanner = _errorBanner(context); if (errorBanner != null) { return _ComposeBoxContainer(body: null, errorBanner: errorBanner); diff --git a/test/example_data.dart b/test/example_data.dart index d071307ec4..7e3a86ba43 100644 --- a/test/example_data.dart +++ b/test/example_data.dart @@ -831,6 +831,7 @@ InitialSnapshot initialSnapshot({ int? realmWaitingPeriodThreshold, Map? realmDefaultExternalAccounts, int? maxFileUploadSizeMib, + int? maxMessageLength, Uri? serverEmojiDataUrl, List? realmUsers, List? realmNonActiveUsers, @@ -865,6 +866,7 @@ InitialSnapshot initialSnapshot({ realmWaitingPeriodThreshold: realmWaitingPeriodThreshold ?? 0, realmDefaultExternalAccounts: realmDefaultExternalAccounts ?? {}, maxFileUploadSizeMib: maxFileUploadSizeMib ?? 25, + maxMessageLength: maxMessageLength ?? 10000, serverEmojiDataUrl: serverEmojiDataUrl ?? realmUrl.replace(path: '/static/emoji.json'), realmUsers: realmUsers ?? [],