diff options
Diffstat (limited to 'app/models/note.rb')
-rw-r--r-- | app/models/note.rb | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/app/models/note.rb b/app/models/note.rb index 5b50ca285c3..3e8aa49a601 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -8,6 +8,7 @@ class Note < ActiveRecord::Base include FasterCacheKeys include CacheMarkdownField include AfterCommitQueue + include ResolvableNote cache_markdown_field :note, pipeline: :note @@ -22,6 +23,9 @@ class Note < ActiveRecord::Base # Attribute used to store the attributes that have ben changed by slash commands. attr_accessor :commands_changes + # The discussion ID for the `DiscussionNote` thread being replied to + attr_accessor :in_reply_to_discussion_id + default_value_for :system, false attr_mentionable :note, pipeline: :note @@ -32,9 +36,6 @@ class Note < ActiveRecord::Base belongs_to :author, class_name: "User" belongs_to :updated_by, class_name: "User" - # Only used by DiffNote, but defined here so that it can be used in `Note.includes` - belongs_to :resolved_by, class_name: "User" - has_many :todos, dependent: :destroy has_many :events, as: :target, dependent: :destroy @@ -52,6 +53,7 @@ class Note < ActiveRecord::Base validates :noteable_id, presence: true, unless: [:for_commit?, :importing?] validates :commit_id, presence: true, if: :for_commit? validates :author, presence: true + validates :discussion_id, presence: true, format: { with: /\A\h{40}\z/ } validate unless: [:for_commit?, :importing?] do |note| unless note.noteable.try(:project) == note.project @@ -71,8 +73,9 @@ class Note < ActiveRecord::Base scope :inc_author, ->{ includes(:author) } scope :inc_relations_for_view, ->{ includes(:project, :author, :updated_by, :resolved_by, :award_emoji) } + scope :discussion_notes, ->{ where(type: 'DiscussionNote') } scope :diff_notes, ->{ where(type: ['LegacyDiffNote', 'DiffNote']) } - scope :non_diff_notes, ->{ where(type: ['Note', nil]) } + scope :non_diff_notes, ->{ where(type: ['Note', 'DiscussionNote', nil]) } scope :with_associations, -> do # FYI noteable cannot be loaded for LegacyDiffNote for commits @@ -98,14 +101,28 @@ class Note < ActiveRecord::Base Digest::SHA1.hexdigest(build_discussion_id(*args)) end + def resolvable? + false + end + def discussions - Discussion.for_notes(all) + Discussion.build_collection(all.fresh) + end + + def find_discussion(discussion_id) + notes = where(discussion_id: discussion_id).fresh.to_a + return if notes.empty? + + Discussion.build(notes) end def grouped_diff_discussions - active_notes = diff_notes.fresh.select(&:active?) - Discussion.for_diff_notes(active_notes). - map { |d| [d.line_code, d] }.to_h + diff_notes. + fresh. + select(&:active?). + group_by(&:line_code). + map { |line_code, notes| [line_code, DiffDiscussion.build(notes)] }. + to_h end # Searches for notes matching the given query. @@ -146,18 +163,10 @@ class Note < ActiveRecord::Base true end - def resolvable? - false - end - - def resolved? + def part_of_discussion? false end - def to_be_resolved? - resolvable? && !resolved? - end - def max_attachment_size current_application_settings.max_attachment_size.megabytes.to_i end @@ -226,7 +235,7 @@ class Note < ActiveRecord::Base end def can_be_award_emoji? - noteable.is_a?(Awardable) + noteable.is_a?(Awardable) && !part_of_discussion? end def contains_emoji_only? @@ -237,6 +246,29 @@ class Note < ActiveRecord::Base note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1] end + def discussion_class + if for_merge_request? + # Notes on merge requests are always in a discussion of their own + SingleNoteDiscussion + else + CommitDiscussion + end + end + + # Returns a discussion containing just this note + def to_discussion + Discussion.build([self]) + end + + # Returns the entire discussion this note is part of + def discussion + if part_of_discussion? + self.noteable.notes.find_discussion(self.discussion_id) + else + to_discussion + end + end + private def keep_around_commit |