@@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart';
7
7
8
8
import '../api/exception.dart' ;
9
9
import '../api/model/events.dart' ;
10
+ import '../api/model/initial_snapshot.dart' ;
10
11
import '../api/model/model.dart' ;
11
12
import '../api/route/messages.dart' ;
12
13
import '../log.dart' ;
@@ -78,6 +79,115 @@ mixin MessageStore on ChannelStore {
78
79
/// Should only be called when there is a failed request,
79
80
/// per [getEditMessageErrorStatus] .
80
81
({String originalRawContent, String newContent}) takeFailedMessageEdit (int messageId);
82
+
83
+ /// Whether the user has permission to delete a message, as of [byDate] .
84
+ ///
85
+ /// For a value of [byDate] , use [ZulipBinding.instance.utcNow] .
86
+ bool selfCanDeleteMessage (int messageId, {required DateTime byDate}) {
87
+ // Compare web's message_delete.get_deletability.
88
+
89
+ final message = messages[messageId];
90
+ if (message == null ) return false ; // TODO(log)
91
+
92
+ final ZulipStream ? channel;
93
+ if (message is StreamMessage ) {
94
+ channel = streams[message.streamId];
95
+ // TODO(log) if channel null here?
96
+ } else {
97
+ channel = null ;
98
+ }
99
+
100
+ if (channel != null && channel.isArchived == true ) {
101
+ return false ;
102
+ }
103
+
104
+ if (realmCanDeleteAnyMessageGroup != null
105
+ && selfHasPermissionForGroupSetting (realmCanDeleteAnyMessageGroup! ,
106
+ GroupSettingType .realm, 'can_delete_any_message_group' )) {
107
+ return true ;
108
+ }
109
+
110
+ if (channel != null ) {
111
+ if (channel.canDeleteAnyMessageGroup != null
112
+ && selfHasPermissionForGroupSetting (channel.canDeleteAnyMessageGroup! ,
113
+ GroupSettingType .stream, 'can_delete_any_message_group' )) {
114
+ return true ;
115
+ }
116
+ }
117
+
118
+ final sender = getUser (message.senderId);
119
+ if (sender == null ) return false ;
120
+
121
+ if (
122
+ sender.userId != selfUserId
123
+ && ! (sender.isBot && sender.botOwnerId == selfUserId)
124
+ ) {
125
+ return false ;
126
+ }
127
+
128
+ // Web returns false here for local-echoed message objects;
129
+ // that's impossible here because `message` can't be an [OutboxMessage]
130
+ // (it's a [Message] from [MessageStore.messages]).
131
+
132
+ if (realmCanDeleteOwnMessageGroup != null ) {
133
+ if (! selfHasPermissionForGroupSetting (realmCanDeleteOwnMessageGroup! ,
134
+ GroupSettingType .realm, 'can_delete_own_message_group' )) {
135
+ if (channel == null ) {
136
+ // i.e. this is a DM
137
+ return false ;
138
+ }
139
+
140
+ if (
141
+ channel.canDeleteOwnMessageGroup == null
142
+ || ! selfHasPermissionForGroupSetting (channel.canDeleteOwnMessageGroup! ,
143
+ GroupSettingType .stream, 'can_delete_own_message_group' )
144
+ ) {
145
+ return false ;
146
+ }
147
+ }
148
+ }
149
+
150
+ if (
151
+ realmDeleteOwnMessagePolicy != null
152
+ && ! _selfPassesLegacyDeleteMessagePolicy (messageId, byDate: byDate)
153
+ ) {
154
+ return false ;
155
+ }
156
+
157
+ if (realmMessageContentDeleteLimitSeconds == null ) {
158
+ // i.e., no limit
159
+ return true ;
160
+ }
161
+
162
+ return byDate.millisecondsSinceEpoch ~ / 1000 - message.timestamp
163
+ <= realmMessageContentDeleteLimitSeconds! ;
164
+ }
165
+
166
+ bool _selfPassesLegacyDeleteMessagePolicy (int messageId, {required DateTime byDate}) {
167
+ assert (realmDeleteOwnMessagePolicy != null );
168
+ final role = selfUser.role;
169
+
170
+ // (Could early-return true on [UserRole.unknown],
171
+ // but pre-291 servers shouldn't be giving us an unknown role.)
172
+
173
+ switch (realmDeleteOwnMessagePolicy! ) {
174
+ case RealmDeleteOwnMessagePolicy .members:
175
+ return true ;
176
+ case RealmDeleteOwnMessagePolicy .admins:
177
+ return role.isAtLeast (UserRole .administrator);
178
+ case RealmDeleteOwnMessagePolicy .fullMembers: {
179
+ if (! role.isAtLeast (UserRole .member)) return false ;
180
+ if (role == UserRole .member) {
181
+ return hasPassedWaitingPeriod (selfUser, byDate: byDate);
182
+ }
183
+ return true ;
184
+ }
185
+ case RealmDeleteOwnMessagePolicy .moderators:
186
+ return role.isAtLeast (UserRole .moderator);
187
+ case RealmDeleteOwnMessagePolicy .everyone:
188
+ return true ;
189
+ }
190
+ }
81
191
}
82
192
83
193
mixin ProxyMessageStore on MessageStore {
0 commit comments