summaryrefslogtreecommitdiff
path: root/app/models/discussion.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/discussion.rb')
-rw-r--r--app/models/discussion.rb91
1 files changed, 91 insertions, 0 deletions
diff --git a/app/models/discussion.rb b/app/models/discussion.rb
new file mode 100644
index 00000000000..74facfd1c9c
--- /dev/null
+++ b/app/models/discussion.rb
@@ -0,0 +1,91 @@
+class Discussion
+ NUMBER_OF_TRUNCATED_DIFF_LINES = 16
+
+ attr_reader :first_note, :notes
+
+ delegate :created_at,
+ :project,
+ :author,
+
+ :noteable,
+ :for_commit?,
+ :for_merge_request?,
+
+ :line_code,
+ :diff_file,
+ :for_line?,
+ :active?,
+
+ to: :first_note
+
+ delegate :blob, :highlighted_diff_lines, to: :diff_file, allow_nil: true
+
+ def self.for_notes(notes)
+ notes.group_by(&:discussion_id).values.map { |notes| new(notes) }
+ end
+
+ def self.for_diff_notes(notes)
+ notes.group_by(&:line_code).values.map { |notes| new(notes) }
+ end
+
+ def initialize(notes)
+ @first_note = notes.first
+ @notes = notes
+ end
+
+ def id
+ first_note.discussion_id
+ end
+
+ def diff_discussion?
+ first_note.diff_note?
+ end
+
+ def legacy_diff_discussion?
+ notes.any?(&:legacy_diff_note?)
+ end
+
+ def for_target?(target)
+ self.noteable == target && !diff_discussion?
+ end
+
+ def expanded?
+ !diff_discussion? || active?
+ end
+
+ def reply_attributes
+ data = {
+ noteable_type: first_note.noteable_type,
+ noteable_id: first_note.noteable_id,
+ commit_id: first_note.commit_id,
+ discussion_id: self.id,
+ }
+
+ if diff_discussion?
+ data[:note_type] = first_note.type
+
+ data.merge!(first_note.diff_attributes)
+ end
+
+ data
+ end
+
+ # Returns an array of at most 16 highlighted lines above a diff note
+ def truncated_diff_lines
+ prev_lines = []
+
+ highlighted_diff_lines.each do |line|
+ if line.meta?
+ prev_lines.clear
+ else
+ prev_lines << line
+
+ break if for_line?(line)
+
+ prev_lines.shift if prev_lines.length >= NUMBER_OF_TRUNCATED_DIFF_LINES
+ end
+ end
+
+ prev_lines
+ end
+end