1# frozen_string_literal: true 2 3# Contains functionality shared between `DiffDiscussion` and `LegacyDiffDiscussion`. 4module DiscussionOnDiff 5 extend ActiveSupport::Concern 6 7 NUMBER_OF_TRUNCATED_DIFF_LINES = 16 8 9 included do 10 delegate :line_code, 11 :original_line_code, 12 :note_diff_file, 13 :diff_line, 14 :active?, 15 :created_at_diff?, 16 to: :first_note 17 18 delegate :file_path, 19 :blob, 20 :highlighted_diff_lines, 21 :diff_lines, 22 to: :diff_file, 23 allow_nil: true 24 end 25 26 def diff_discussion? 27 true 28 end 29 30 def file_new_path 31 first_note.position.new_path 32 end 33 34 def on_merge_request_commit? 35 for_merge_request? && commit_id.present? 36 end 37 38 # Returns an array of at most 16 highlighted lines above a diff note 39 def truncated_diff_lines(highlight: true, diff_limit: nil) 40 return [] unless on_text? 41 return [] if diff_line.nil? 42 43 diff_limit = [diff_limit, NUMBER_OF_TRUNCATED_DIFF_LINES].compact.min 44 lines = highlight ? highlighted_diff_lines : diff_lines 45 46 initial_line_index = [diff_line.index - diff_limit + 1, 0].max 47 48 prev_lines = [] 49 50 lines[initial_line_index..diff_line.index].each do |line| 51 if line.meta? 52 prev_lines.clear 53 else 54 prev_lines << line 55 end 56 end 57 58 prev_lines 59 end 60 61 def diff_file 62 strong_memoize(:diff_file) do 63 # Falling back here is important as `note_diff_files` are created async. 64 fetch_preloaded_diff_file || first_note.diff_file 65 end 66 end 67 68 def line_code_in_diffs(diff_refs) 69 if active?(diff_refs) 70 line_code 71 elsif diff_refs && created_at_diff?(diff_refs) 72 original_line_code 73 end 74 end 75 76 private 77 78 def fetch_preloaded_diff_file 79 fetch_preloaded_diff = 80 context_noteable && 81 context_noteable.preloads_discussion_diff_highlighting? && 82 note_diff_file 83 84 context_noteable.discussions_diffs.find_by_id(note_diff_file.id) if fetch_preloaded_diff 85 end 86end 87