# typed: strict # frozen_string_literal: true module ActsAsMessageable class Message < ::ActiveRecord::Base extend T::Sig include ActsAsMessageable::Scopes include Ancestry::InstanceMethods has_ancestry belongs_to :received_messageable, polymorphic: true belongs_to :sent_messageable, polymorphic: true sig { returns(T.nilable(T::Boolean)) } attr_accessor :removed, :restored cattr_accessor :required sig { params(args: T.untyped, kwargs: T.untyped).void } def initialize(*args, **kwargs) @removed = T.let(false, T.nilable(T::Boolean)) @restored = T.let(false, T.nilable(T::Boolean)) super end ActsAsMessageable.rails_api.new(self).attr_accessible( :topic, :body, :opened, :opened_at, :recipient_permanent_delete, :recipient_delete, :sender_permanent_delete, :sender_delete ) ActsAsMessageable.rails_api.new(self).default_scope('created_at desc') # @return [Boolean] whether the message has been read sig { returns(T::Boolean) } def open? opened? end # @return [Boolean] whether the message has been read # @see open? sig { returns(T::Boolean) } def opened? opened_at.present? || super end # Method open message (will mark message as read) # @return [Boolean] whether the message has been open sig { returns(T::Boolean) } def open ActsAsMessageable.rails_api.new(self).update_attributes!(opened_at: DateTime.now) ActsAsMessageable.rails_api.new(self).update_attributes!(opened: true) end alias mark_as_read open alias read open # Method close message (will mark message as unread) # @return [Boolean] whether the message has been closed sig { returns(T::Boolean) } def close ActsAsMessageable.rails_api.new(self).update_attributes!(opened_at: nil) ActsAsMessageable.rails_api.new(self).update_attributes!(opened: false) end alias mark_as_unread close alias unread close sig { returns(ActiveRecord::Base) } def from sent_messageable end sig { returns(ActiveRecord::Base) } def to received_messageable end # @param [ActiveRecord::Base] user # @return [ActiveRecord::Base] real receiver of the mssage sig { params(user: ActiveRecord::Base).returns(ActiveRecord::Base) } def real_receiver(user) user == from ? to : from end # @return [Boolean] whether user is participant of group message # @param [ActiveRecord::Base] user sig { params(user: T.untyped).returns(T::Boolean) } def participant?(user) user.class.group_messages || (to == user) || (from == user) end # @return [Object] conversation tree sig { returns(T.untyped) } def conversation root.subtree end # Method will mark message as removed # @return [TrueClass] sig { returns(TrueClass) } def delete self.removed = true end # Method will mark message as removed # @return [TrueClass] sig { returns(TrueClass) } def restore self.restored = true end # Reply to given message # @param [Hash] args # @option args [String] topic Topic of the message # @option args [String] body Body of the message # @return [ActsAsMessageable::Message] a message that is a response to a given message # @return [Boolean] when user is not participant of the message # @see ActsAsMessageable::Model::InstanceMethods#reply_to sig do params(args: T.any(T::Hash[String, String], String)).returns(T.any(ActsAsMessageable::Message, T::Boolean, ActiveRecord::Base)) end def reply(*args) T.unsafe(to).reply_to(self, *args) end # Method will return list of users in the conversation # @return [Array] users sig { returns(T::Array[ActiveRecord::Base]) } def people conversation.map(&:from).uniq! end end end