2016-07-20 22:18:18 +00:00
|
|
|
class Discussion
|
|
|
|
NUMBER_OF_TRUNCATED_DIFF_LINES = 16
|
|
|
|
|
2016-07-26 04:36:03 +00:00
|
|
|
attr_reader :first_note, :last_note, :notes
|
2016-07-20 22:18:18 +00:00
|
|
|
|
|
|
|
delegate :created_at,
|
|
|
|
:project,
|
|
|
|
:author,
|
|
|
|
|
|
|
|
:noteable,
|
|
|
|
:for_commit?,
|
|
|
|
:for_merge_request?,
|
|
|
|
|
|
|
|
:line_code,
|
|
|
|
:diff_file,
|
|
|
|
:for_line?,
|
|
|
|
:active?,
|
|
|
|
|
|
|
|
to: :first_note
|
|
|
|
|
2016-07-26 04:36:03 +00:00
|
|
|
delegate :resolved_at,
|
|
|
|
:resolved_by,
|
|
|
|
|
|
|
|
to: :last_note
|
|
|
|
|
2016-07-20 22:18:18 +00:00
|
|
|
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
|
2016-07-26 04:36:03 +00:00
|
|
|
@last_note = notes.last
|
2016-07-20 22:18:18 +00:00
|
|
|
@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
|
|
|
|
|
2016-07-26 04:36:03 +00:00
|
|
|
def resolvable?
|
|
|
|
diff_discussion? && notes.any?(&:resolvable?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def resolved?
|
|
|
|
notes.none?(&:to_be_resolved?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_be_resolved?
|
|
|
|
notes.any?(&:to_be_resolved?)
|
|
|
|
end
|
|
|
|
|
2016-07-26 04:37:22 +00:00
|
|
|
def resolve!(current_user)
|
|
|
|
notes.each do |note|
|
|
|
|
note.resolve!(current_user) if note.resolvable?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def unresolve!
|
|
|
|
notes.each do |note|
|
|
|
|
note.unresolve! if note.resolvable?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-07-20 22:18:18 +00:00
|
|
|
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
|