@@ -673,6 +673,128 @@ class PerAccountStore extends PerAccountStoreBase with
673673
674674 final AutocompleteViewManager autocompleteViewManager = AutocompleteViewManager ();
675675
676+ /// Whether the user has permission to delete the message, as of [byDate] .
677+ ///
678+ /// For a value of [byDate] , use [ZulipBinding.instance.utcNow] .
679+ // There might be a better place for this to live…but it uses
680+ // message, channel, self-user, and user-group data, so seemed simplest to
681+ // put it here where all that is available.
682+ bool selfCanDeleteMessage (int messageId, {required DateTime byDate}) {
683+ // Compare web's message_delete.get_deletability.
684+
685+ final message = messages[messageId];
686+ if (message == null ) return false ; // TODO(log)
687+
688+ final ZulipStream ? channel;
689+ if (message is StreamMessage ) {
690+ channel = streams[message.streamId];
691+ // TODO(log) if channel null here?
692+ } else {
693+ channel = null ;
694+ }
695+
696+ if (channel != null && channel.isArchived == true ) {
697+ return false ;
698+ }
699+
700+ if (realmCanDeleteAnyMessageGroup != null
701+ && selfHasPermissionForGroupSetting (realmCanDeleteAnyMessageGroup! ,
702+ GroupSettingType .realm, 'can_delete_any_message_group' )) {
703+ // realmCanDeleteAnyMessageGroup always present as of FL 281.
704+ // TODO(server-10) make required, simplify, delete this FL-281 comment
705+ return true ;
706+ }
707+
708+ if (channel != null ) {
709+ if (channel.canDeleteAnyMessageGroup != null
710+ && selfHasPermissionForGroupSetting (channel.canDeleteAnyMessageGroup! ,
711+ GroupSettingType .stream, 'can_delete_any_message_group' )) {
712+ // channel.canDeleteAnyMessageGroup always present as of FL 407.
713+ // TODO(server-11) make required, simplify, delete this FL-407 comment
714+ return true ;
715+ }
716+ }
717+
718+ final sender = getUser (message.senderId);
719+ if (sender == null ) return false ;
720+
721+ if (
722+ sender.userId != selfUserId
723+ && ! (sender.isBot && sender.botOwnerId == selfUserId)
724+ ) {
725+ return false ;
726+ }
727+
728+ // Web returns false here for local-echoed message objects;
729+ // that's impossible here because `message` can't be an [OutboxMessage]
730+ // (it's a [Message] from [MessageStore.messages]).
731+
732+ if (realmCanDeleteOwnMessageGroup != null ) {
733+ // realmCanDeleteOwnMessageGroup always present as of FL 291.
734+ // TODO(server-10) make required, simplify, delete this FL-291 comment
735+ if (! selfHasPermissionForGroupSetting (realmCanDeleteOwnMessageGroup! ,
736+ GroupSettingType .realm, 'can_delete_own_message_group' )) {
737+ if (channel == null ) {
738+ // i.e. this is a DM
739+ return false ;
740+ }
741+
742+ if (
743+ channel.canDeleteOwnMessageGroup == null
744+ || ! selfHasPermissionForGroupSetting (channel.canDeleteOwnMessageGroup! ,
745+ GroupSettingType .stream, 'can_delete_own_message_group' )
746+ ) {
747+ // channel.canDeleteOwnMessageGroup always present as of FL 407.
748+ // TODO(server-11) make required, simplify, delete this FL-407 comment
749+ return false ;
750+ }
751+ }
752+ }
753+
754+ if (
755+ realmDeleteOwnMessagePolicy != null
756+ && ! _selfPassesLegacyDeleteMessagePolicy (messageId, byDate: byDate)
757+ ) {
758+ // realmDeleteOwnMessagePolicy is removed in FL 291
759+ // TODO(server-10) remove that, simplify, delete this FL-291 comment
760+ return false ;
761+ }
762+
763+ if (realmMessageContentDeleteLimitSeconds == null ) {
764+ // i.e., no limit
765+ return true ;
766+ }
767+
768+ return byDate.millisecondsSinceEpoch ~ / 1000 - message.timestamp
769+ <= realmMessageContentDeleteLimitSeconds! ;
770+ }
771+
772+ bool _selfPassesLegacyDeleteMessagePolicy (int messageId, {required DateTime byDate}) {
773+ assert (realmDeleteOwnMessagePolicy != null );
774+ final role = selfUser.role;
775+
776+ // (Could early-return true on [UserRole.unknown],
777+ // but pre-291 servers shouldn't be giving us an unknown role.)
778+
779+ switch (realmDeleteOwnMessagePolicy! ) {
780+ case RealmDeleteOwnMessagePolicy .members:
781+ return true ;
782+ case RealmDeleteOwnMessagePolicy .admins:
783+ return role.isAtLeast (UserRole .administrator);
784+ case RealmDeleteOwnMessagePolicy .fullMembers: {
785+ if (! role.isAtLeast (UserRole .member)) return false ;
786+ if (role == UserRole .member) {
787+ return hasPassedWaitingPeriod (selfUser, byDate: byDate);
788+ }
789+ return true ;
790+ }
791+ case RealmDeleteOwnMessagePolicy .moderators:
792+ return role.isAtLeast (UserRole .moderator);
793+ case RealmDeleteOwnMessagePolicy .everyone:
794+ return true ;
795+ }
796+ }
797+
676798 // End of data.
677799 //|//////////////////////////////////////////////////////////////
678800
0 commit comments