From 99d3e21f19ffb5cccb58fdfeac4fb6174e7e65e2 Mon Sep 17 00:00:00 2001
From: Douwe Maan <douwe@selenight.nl>
Date: Tue, 10 May 2016 17:41:46 -0500
Subject: [PATCH] Extract LegacyDiffNote out of Note

---
 app/assets/javascripts/notes.js.coffee        |   2 +
 app/assets/stylesheets/pages/notes.scss       |   3 +-
 app/controllers/projects/commit_controller.rb |  11 +-
 .../projects/compare_controller.rb            |   2 +-
 .../projects/merge_requests_controller.rb     |   7 +-
 app/controllers/projects/notes_controller.rb  |   6 +-
 app/finders/notes_finder.rb                   |   2 +-
 app/helpers/diff_helper.rb                    |  22 +-
 app/helpers/notes_helper.rb                   |  29 ++-
 app/models/legacy_diff_note.rb                | 182 +++++++++++++++
 app/models/note.rb                            | 214 +++---------------
 .../notify/note_merge_request_email.html.haml |   2 +-
 .../projects/diffs/_parallel_view.html.haml   |  10 +-
 app/views/projects/diffs/_text_file.html.haml |   9 +-
 .../notes/_commit_discussion.html.haml        |   0
 .../notes/_diff_notes_with_reply.html.haml    |  18 +-
 .../_diff_notes_with_reply_parallel.html.haml |  20 +-
 .../projects/notes/_discussion.html.haml      |  47 +++-
 app/views/projects/notes/_form.html.haml      |   1 +
 app/views/projects/notes/_note.html.haml      |   9 +-
 app/views/projects/notes/_notes.html.haml     |   9 +-
 .../notes/discussions/_active.html.haml       |  16 --
 .../notes/discussions/_commit.html.haml       |  25 --
 .../notes/discussions/_diff.html.haml         |  28 ---
 .../_legacy_diff_with_notes.html.haml         |  30 +++
 .../notes/discussions/_notes.html.haml        |   7 +
 .../notes/discussions/_outdated.html.haml     |  14 --
 .../20160508215820_add_type_to_notes.rb       |   5 +
 ...508221410_set_type_on_legacy_diff_notes.rb |   5 +
 db/schema.rb                                  |   5 +-
 lib/api/commits.rb                            |   2 +
 lib/api/entities.rb                           |   6 +-
 spec/models/note_spec.rb                      |   8 +-
 33 files changed, 386 insertions(+), 370 deletions(-)
 create mode 100644 app/models/legacy_diff_note.rb
 delete mode 100644 app/views/projects/notes/_commit_discussion.html.haml
 delete mode 100644 app/views/projects/notes/discussions/_active.html.haml
 delete mode 100644 app/views/projects/notes/discussions/_commit.html.haml
 delete mode 100644 app/views/projects/notes/discussions/_diff.html.haml
 create mode 100644 app/views/projects/notes/discussions/_legacy_diff_with_notes.html.haml
 create mode 100644 app/views/projects/notes/discussions/_notes.html.haml
 delete mode 100644 app/views/projects/notes/discussions/_outdated.html.haml
 create mode 100644 db/migrate/20160508215820_add_type_to_notes.rb
 create mode 100644 db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb

diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index efb3e8e2198..6d9d6528f45 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -285,6 +285,7 @@ class @Notes
     form.addClass "js-main-target-form"
 
     form.find("#note_line_code").remove()
+    form.find("#note_type").remove()
 
   ###
   General note form setup.
@@ -472,6 +473,7 @@ class @Notes
   setupDiscussionNoteForm: (dataHolder, form) =>
     # setup note target
     form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}"
+    form.find("#note_type").val dataHolder.data("noteType")
     form.find("#line_type").val dataHolder.data("lineType")
     form.find("#note_commit_id").val dataHolder.data("commitId")
     form.find("#note_line_code").val dataHolder.data("lineCode")
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 624c8249f7e..a3e1ac13a43 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -226,8 +226,7 @@ ul.notes {
   }
 }
 
-.note-action-button,
-.discussion-action-button {
+.note-action-button {
   display: inline-block;
   margin-left: 10px;
   line-height: 24px;
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index a202cb38692..9bcb82ef3f9 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -17,11 +17,12 @@ class Projects::CommitController < Projects::ApplicationController
   def show
     apply_diff_view_cookie!
 
-    @line_notes = commit.notes.inline
+    @grouped_diff_notes = commit.notes.grouped_diff_notes
+
     @note = @project.build_commit_note(commit)
-    @notes = commit.notes.not_inline.fresh
+    @notes = commit.notes.non_diff_notes.fresh
     @noteable = @commit
-    @comments_allowed = @reply_allowed = true
+    @comments_allowed = true
     @comments_target  = {
       noteable_type: 'Commit',
       commit_id: @commit.id
@@ -67,10 +68,10 @@ class Projects::CommitController < Projects::ApplicationController
     create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title} has been successfully reverted.",
                                           success_path: successful_change_path, failure_path: failed_change_path)
   end
-  
+
   def cherry_pick
     assign_change_commit_vars(@commit.cherry_pick_branch_name)
-    
+
     return render_404 if @target_branch.blank?
 
     create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title} has been successfully cherry-picked.",
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 671d5c23024..587b84fd921 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -22,7 +22,7 @@ class Projects::CompareController < Projects::ApplicationController
       @base_commit = @project.merge_base_commit(@base_ref, @head_ref)
       @diffs = compare.diffs(diff_options)
       @diff_refs = [@base_commit, @commit]
-      @line_notes = []
+      @grouped_diff_notes = {}
     end
   end
 
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 9c147b3689e..e571da64e4b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -73,12 +73,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     # but we need it for the "View file @ ..." link by deleted files
     @base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
 
-    @comments_allowed = @reply_allowed = true
+    @comments_allowed = true
     @comments_target = {
       noteable_type: 'MergeRequest',
       noteable_id: @merge_request.id
     }
-    @line_notes = @merge_request.notes.where("line_code is not null")
+
+    @grouped_diff_notes = @merge_request.notes.grouped_diff_notes
 
     respond_to do |format|
       format.html
@@ -300,7 +301,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     # Build a note object for comment form
     @note = @project.notes.new(noteable: @merge_request)
     @notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh
-    @discussions = Note.discussions_from_notes(@notes)
+    @discussions = @notes.discussions
     @noteable = @merge_request
 
     # Get commits from repository
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 707a0d0e5c6..4a57cd29a20 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -96,7 +96,7 @@ class Projects::NotesController < Projects::ApplicationController
   end
 
   def note_to_discussion_html(note)
-    return unless note.for_diff_line?
+    return unless note.diff_note?
 
     if params[:view] == 'parallel'
       template = "projects/notes/_diff_notes_with_reply_parallel"
@@ -120,7 +120,7 @@ class Projects::NotesController < Projects::ApplicationController
   end
 
   def note_to_discussion_with_diff_html(note)
-    return unless note.for_diff_line?
+    return unless note.diff_note?
 
     render_to_string(
       "projects/notes/_discussion",
@@ -158,7 +158,7 @@ class Projects::NotesController < Projects::ApplicationController
   def note_params
     params.require(:note).permit(
       :note, :noteable, :noteable_id, :noteable_type, :project_id,
-      :attachment, :line_code, :commit_id
+      :attachment, :line_code, :commit_id, :type
     )
   end
 
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index fa4c635f55c..c41be333537 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -10,7 +10,7 @@ class NotesFinder
     notes =
       case target_type
       when "commit"
-        project.notes.for_commit_id(target_id).not_inline
+        project.notes.for_commit_id(target_id).non_diff_notes
       when "issue"
         project.issues.find(target_id).notes.nonawards.inc_author
       when "merge_request"
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 9f73edb4553..5f311f3780a 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -55,22 +55,18 @@ module DiffHelper
     end
   end
 
-  def line_comments
-    @line_comments ||= @line_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code)
-  end
-
-  def organize_comments(type_left, type_right, line_code_left, line_code_right)
-    comments_left = comments_right = nil
+  def organize_comments(left, right)
+    notes_left = notes_right = nil
 
-    unless type_left.nil? && type_right == 'new'
-      comments_left = line_comments[line_code_left]
+    unless left[:type].nil? && right[:type] == 'new'
+      notes_left = @grouped_diff_notes[left[:line_code]]
     end
 
-    unless type_left.nil? && type_right.nil?
-      comments_right = line_comments[line_code_right]
+    unless left[:type].nil? && right[:type].nil?
+      notes_right = @grouped_diff_notes[right[:line_code]]
     end
 
-    [comments_left, comments_right]
+    [notes_left, notes_right]
   end
 
   def inline_diff_btn
@@ -96,8 +92,8 @@ module DiffHelper
     ].join(' ').html_safe
   end
 
-  def commit_for_diff(diff)
-    if diff.deleted_file
+  def commit_for_diff(diff_file)
+    if diff_file.deleted_file
       @base_commit || @commit.parent || @commit
     else
       @commit
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 95072b5373f..b401c8385be 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -1,7 +1,7 @@
 module NotesHelper
   # Helps to distinguish e.g. commit notes in mr notes list
   def note_for_main_target?(note)
-    (@noteable.class.name == note.noteable_type && !note.for_diff_line?)
+    @noteable.class.name == note.noteable_type && !note.diff_note?
   end
 
   def note_target_fields(note)
@@ -15,16 +15,6 @@ module NotesHelper
     note.editable? && can?(current_user, :admin_note, note)
   end
 
-  def link_to_commit_diff_line_note(note)
-    if note.for_commit_diff_line?
-      link_to(
-        "#{note.diff_file_name}:L#{note.diff_new_line}",
-        namespace_project_commit_path(@project.namespace, @project,
-                                      note.noteable, anchor: note.line_code)
-      )
-    end
-  end
-
   def noteable_json(noteable)
     {
       id: noteable.id,
@@ -35,7 +25,7 @@ module NotesHelper
   end
 
   def link_to_new_diff_note(line_code, line_type = nil)
-    discussion_id = Note.build_discussion_id(
+    discussion_id = LegacyDiffNote.build_discussion_id(
       @comments_target[:noteable_type],
       @comments_target[:noteable_id] || @comments_target[:commit_id],
       line_code
@@ -45,9 +35,10 @@ module NotesHelper
       noteable_type: @comments_target[:noteable_type],
       noteable_id:   @comments_target[:noteable_id],
       commit_id:     @comments_target[:commit_id],
+      line_type:     line_type,
       line_code:     line_code,
-      discussion_id: discussion_id,
-      line_type:     line_type
+      note_type:     LegacyDiffNote.name,
+      discussion_id: discussion_id
     }
 
     button_tag(class: 'btn add-diff-note js-add-diff-note-button',
@@ -57,18 +48,24 @@ module NotesHelper
     end
   end
 
-  def link_to_reply_diff(note, line_type = nil)
+  def link_to_reply_discussion(note, line_type = nil)
     return unless current_user
 
     data = {
       noteable_type: note.noteable_type,
       noteable_id:   note.noteable_id,
       commit_id:     note.commit_id,
-      line_code:     note.line_code,
       discussion_id: note.discussion_id,
       line_type:     line_type
     }
 
+    if note.diff_note?
+      data.merge!(
+        line_code: note.line_code,
+        note_type: LegacyDiffNote.name
+      )
+    end
+
     button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
                            data: data, title: 'Add a reply'
   end
diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb
new file mode 100644
index 00000000000..b5de85df99f
--- /dev/null
+++ b/app/models/legacy_diff_note.rb
@@ -0,0 +1,182 @@
+class LegacyDiffNote < Note
+  serialize :st_diff
+
+  validates :line_code, presence: true, line_code: true
+
+  before_create :set_diff
+
+  class << self
+    def build_discussion_id(noteable_type, noteable_id, line_code, active = true)
+      [super(noteable_type, noteable_id), line_code, active].join("-")
+    end
+  end
+
+  def diff_note?
+    true
+  end
+
+  def legacy_diff_note?
+    true
+  end
+
+  def discussion_id
+    @discussion_id ||= self.class.build_discussion_id(noteable_type, noteable_id || commit_id, line_code, active?)
+  end
+
+  def find_diff
+    return nil unless noteable
+    return @diff if defined?(@diff)
+
+    # Don't use ||= because nil is a valid value for @diff
+    @diff = noteable.diffs(Commit.max_diff_options).find do |d|
+      Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path
+    end
+  end
+
+  def set_diff
+    # First lets find notes with same diff
+    # before iterating over all mr diffs
+    diff = diff_for_line_code unless for_merge_request?
+    diff ||= find_diff
+
+    self.st_diff = diff.to_hash if diff
+  end
+
+  def diff
+    @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
+  end
+
+  def diff_for_line_code
+    attributes = {
+      noteable_type: noteable_type,
+      line_code: line_code
+    }
+
+    if for_commit?
+      attributes[:commit_id] = commit_id
+    else
+      attributes[:noteable_id] = noteable_id
+    end
+
+    self.class.where(attributes).last.try(:diff)
+  end
+
+  # Check if this note is part of an "active" discussion
+  #
+  # This will always return true for anything except MergeRequest noteables,
+  # which have special logic.
+  #
+  # If the note's current diff cannot be matched in the MergeRequest's current
+  # diff, it's considered inactive.
+  def active?
+    return true if for_commit?
+    return true unless self.diff
+    return false unless noteable
+    return @active if defined?(@active)
+
+    noteable_diff = find_noteable_diff
+
+    if noteable_diff
+      parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line)
+
+      @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line }
+    else
+      @active = false
+    end
+
+    @active
+  end
+
+  def diff_file_index
+    line_code.split('_')[0] if line_code
+  end
+
+  def diff_file_name
+    diff.new_path if diff
+  end
+
+  def file_path
+    if diff.new_path.present?
+      diff.new_path
+    elsif diff.old_path.present?
+      diff.old_path
+    end
+  end
+
+  def diff_old_line
+    line_code.split('_')[1].to_i if line_code
+  end
+
+  def diff_new_line
+    line_code.split('_')[2].to_i if line_code
+  end
+
+  def generate_line_code(line)
+    Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
+  end
+
+  def diff_line
+    return @diff_line if @diff_line
+
+    if diff
+      diff_lines.each do |line|
+        if generate_line_code(line) == self.line_code
+          @diff_line = line.text
+        end
+      end
+    end
+
+    @diff_line
+  end
+
+  def diff_line_type
+    return @diff_line_type if @diff_line_type
+
+    if diff
+      diff_lines.each do |line|
+        if generate_line_code(line) == self.line_code
+          @diff_line_type = line.type
+        end
+      end
+    end
+
+    @diff_line_type
+  end
+
+  def truncated_diff_lines
+    max_number_of_lines = 16
+    prev_match_line = nil
+    prev_lines = []
+
+    highlighted_diff_lines.each do |line|
+      if line.type == "match"
+        prev_lines.clear
+        prev_match_line = line
+      else
+        prev_lines << line
+
+        break if generate_line_code(line) == self.line_code
+
+        prev_lines.shift if prev_lines.length >= max_number_of_lines
+      end
+    end
+
+    prev_lines
+  end
+
+  def diff_lines
+    @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
+  end
+
+  def highlighted_diff_lines
+    Gitlab::Diff::Highlight.new(diff_lines).highlight
+  end
+
+  private
+
+  # Find the diff on noteable that matches our own
+  def find_noteable_diff
+    diffs = noteable.diffs(Commit.max_diff_options)
+    diffs.find { |d| d.new_path == self.diff.new_path }
+  end
+end
diff --git a/app/models/note.rb b/app/models/note.rb
index f26aa1bf63f..3bc55870704 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -1,6 +1,5 @@
-require 'carrierwave/orm/activerecord'
-
 class Note < ActiveRecord::Base
+  extend ActiveModel::Naming
   include Gitlab::CurrentSettings
   include Participable
   include Mentionable
@@ -22,12 +21,10 @@ class Note < ActiveRecord::Base
   delegate :name, :email, to: :author, prefix: true
 
   before_validation :set_award!
-  before_validation :clear_blank_line_code!
 
   validates :note, :project, presence: true
   validates :note, uniqueness: { scope: [:author, :noteable_type, :noteable_id] }, if: ->(n) { n.is_award }
   validates :note, inclusion: { in: Emoji.emojis_names }, if: ->(n) { n.is_award }
-  validates :line_code, line_code: true, allow_blank: true
   # Attachments are deprecated and are handled by Markdown uploader
   validates :attachment, file_size: { maximum: :max_attachment_size }
 
@@ -41,8 +38,6 @@ class Note < ActiveRecord::Base
   scope :awards, ->{ where(is_award: true) }
   scope :nonawards, ->{ where(is_award: false) }
   scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
-  scope :inline, ->{ where("line_code IS NOT NULL") }
-  scope :not_inline, ->{ where(line_code: nil) }
   scope :system, ->{ where(system: true) }
   scope :user, ->{ where(system: false) }
   scope :common, ->{ where(noteable_type: ["", nil]) }
@@ -50,38 +45,31 @@ class Note < ActiveRecord::Base
   scope :inc_author_project, ->{ includes(:project, :author) }
   scope :inc_author, ->{ includes(:author) }
 
+  scope :legacy_diff_notes, ->{ where(type: 'LegacyDiffNote') }
+  scope :non_diff_notes, ->{ where(type: ['Note', nil]) }
+
   scope :with_associations, -> do
     includes(:author, :noteable, :updated_by,
              project: [:project_members, { group: [:group_members] }])
   end
 
-  serialize :st_diff
-  before_create :set_diff, if: ->(n) { n.line_code.present? }
+  before_validation :clear_blank_line_code!
 
   class << self
-    def discussions_from_notes(notes)
-      discussion_ids = []
-      discussions = []
-
-      notes.each do |note|
-        next if discussion_ids.include?(note.discussion_id)
-
-        # don't group notes for the main target
-        if !note.for_diff_line? && note.for_merge_request?
-          discussions << [note]
-        else
-          discussions << notes.select do |other_note|
-            note.discussion_id == other_note.discussion_id
-          end
-          discussion_ids << note.discussion_id
-        end
-      end
+    def model_name
+      ActiveModel::Name.new(self, nil, 'note')
+    end
+
+    def build_discussion_id(noteable_type, noteable_id)
+      [:discussion, noteable_type.try(:underscore), noteable_id].join("-")
+    end
 
-      discussions
+    def discussions
+      all.group_by(&:discussion_id).values
     end
 
-    def build_discussion_id(type, id, line_code)
-      [:discussion, type.try(:underscore), id, line_code].join("-").to_sym
+    def grouped_diff_notes
+      legacy_diff_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code)
     end
 
     # Searches for notes matching the given query.
@@ -116,167 +104,35 @@ class Note < ActiveRecord::Base
     system && SystemNoteService.cross_reference?(note)
   end
 
-  def max_attachment_size
-    current_application_settings.max_attachment_size.megabytes.to_i
-  end
-
-  def find_diff
-    return nil unless noteable
-    return @diff if defined?(@diff)
-
-    # Don't use ||= because nil is a valid value for @diff
-    @diff = noteable.diffs(Commit.max_diff_options).find do |d|
-      Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path
-    end
-  end
-
-  def hook_attrs
-    attributes
-  end
-
-  def set_diff
-    # First lets find notes with same diff
-    # before iterating over all mr diffs
-    diff = diff_for_line_code unless for_merge_request?
-    diff ||= find_diff
-
-    self.st_diff = diff.to_hash if diff
-  end
-
-  def diff
-    @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
-  end
-
-  def diff_for_line_code
-    Note.where(noteable_id: noteable_id, noteable_type: noteable_type, line_code: line_code).last.try(:diff)
-  end
-
-  # Check if this note is part of an "active" discussion
-  #
-  # This will always return true for anything except MergeRequest noteables,
-  # which have special logic.
-  #
-  # If the note's current diff cannot be matched in the MergeRequest's current
-  # diff, it's considered inactive.
-  def active?
-    return true unless self.diff
-    return false unless noteable
-    return @active if defined?(@active)
-
-    noteable_diff = find_noteable_diff
-
-    if noteable_diff
-      parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line)
-
-      @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line }
-    else
-      @active = false
-    end
-
-    @active
+  def diff_note?
+    false
   end
 
-  def diff_file_index
-    line_code.split('_')[0] if line_code
-  end
-
-  def diff_file_name
-    diff.new_path if diff
-  end
-
-  def file_path
-    if diff.new_path.present?
-      diff.new_path
-    elsif diff.old_path.present?
-      diff.old_path
-    end
+  def legacy_diff_note?
+    false
   end
 
-  def diff_old_line
-    line_code.split('_')[1].to_i if line_code
-  end
-
-  def diff_new_line
-    line_code.split('_')[2].to_i if line_code
-  end
-
-  def generate_line_code(line)
-    Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
-  end
-
-  def diff_line
-    return @diff_line if @diff_line
-
-    if diff
-      diff_lines.each do |line|
-        if generate_line_code(line) == self.line_code
-          @diff_line = line.text
-        end
-      end
-    end
-
-    @diff_line
-  end
-
-  def diff_line_type
-    return @diff_line_type if @diff_line_type
-
-    if diff
-      diff_lines.each do |line|
-        if generate_line_code(line) == self.line_code
-          @diff_line_type = line.type
-        end
-      end
-    end
-
-    @diff_line_type
-  end
-
-  def truncated_diff_lines
-    max_number_of_lines = 16
-    prev_match_line = nil
-    prev_lines = []
-
-    highlighted_diff_lines.each do |line|
-      if line.type == "match"
-        prev_lines.clear
-        prev_match_line = line
+  def discussion_id
+    @discussion_id ||=
+      if for_merge_request?
+        [:discussion, :note, id].join("-")
       else
-        prev_lines << line
-
-        break if generate_line_code(line) == self.line_code
-
-        prev_lines.shift if prev_lines.length >= max_number_of_lines
+        self.class.build_discussion_id(noteable_type, noteable_id || commit_id)
       end
-    end
-
-    prev_lines
-  end
-
-  def diff_lines
-    @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
   end
 
-  def highlighted_diff_lines
-    Gitlab::Diff::Highlight.new(diff_lines).highlight
+  def max_attachment_size
+    current_application_settings.max_attachment_size.megabytes.to_i
   end
 
-  def discussion_id
-    @discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code)
+  def hook_attrs
+    attributes
   end
 
   def for_commit?
     noteable_type == "Commit"
   end
 
-  def for_commit_diff_line?
-    for_commit? && for_diff_line?
-  end
-
-  def for_diff_line?
-    line_code.present?
-  end
-
   def for_issue?
     noteable_type == "Issue"
   end
@@ -285,10 +141,6 @@ class Note < ActiveRecord::Base
     noteable_type == "MergeRequest"
   end
 
-  def for_merge_request_diff_line?
-    for_merge_request? && for_diff_line?
-  end
-
   def for_snippet?
     noteable_type == "Snippet"
   end
@@ -361,14 +213,8 @@ class Note < ActiveRecord::Base
     self.line_code = nil if self.line_code.blank?
   end
 
-  # Find the diff on noteable that matches our own
-  def find_noteable_diff
-    diffs = noteable.diffs(Commit.max_diff_options)
-    diffs.find { |d| d.new_path == self.diff.new_path }
-  end
-
   def awards_supported?
-    (for_issue? || for_merge_request?) && !for_diff_line?
+    (for_issue? || for_merge_request?) && !diff_note?
   end
 
   def contains_emoji_only?
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 65f0e4c4068..27e8ea5f5a1 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,4 +1,4 @@
-- if @note.diff_file_name
+- if @note.legacy_diff_note?
   %p.details
     New comment on diff for
     = link_to @note.diff_file_name, @target_url
diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml
index 81948513e43..3d91dc43129 100644
--- a/app/views/projects/diffs/_parallel_view.html.haml
+++ b/app/views/projects/diffs/_parallel_view.html.haml
@@ -30,13 +30,13 @@
           %td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class} #{'empty-cell' if !right[:number]}", data: { linenumber: right[:number] }}
             = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
             - if @comments_allowed && can?(current_user, :create_note, @project)
-              = link_to_new_diff_note(right[:line_code], 'new')
+              = link_to_new_diff_note(new_line_code, 'new')
           %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code} #{'empty-cell' if right[:text].empty?}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
 
-      - if @reply_allowed
-        - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
-        - if comments_left.present? || comments_right.present?
-          = render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right
+      - if @comments_allowed
+        - notes_left, notes_right = organize_comments(left, right)
+        - if notes_left.present? || notes_right.present?
+          = render "projects/notes/diff_notes_with_reply_parallel", notes_left: notes_left, notes_right: notes_right
 
 - if diff_file.diff.diff.blank? && diff_file.mode_changed?
   .file-mode-changed
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index e7169d7b599..d58444a9d5b 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -6,16 +6,15 @@
 %table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
 
   - last_line = 0
-  - raw_diff_lines = diff_file.diff_lines.to_a
   - diff_file.highlighted_diff_lines.each_with_index do |line, index|
     - line_code = generate_line_code(diff_file.file_path, line)
     - last_line = line.new_pos
     = render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: line_code}
 
-    - if @reply_allowed
-      - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
-      - unless comments.empty?
-        = render "projects/notes/diff_notes_with_reply", notes: comments, line: raw_diff_lines[index].text
+    - if @comments_allowed
+      - diff_notes = @grouped_diff_notes[line_code]
+      - if diff_notes
+        = render "projects/notes/diff_notes_with_reply", notes: diff_notes
 
   - if last_line > 0
     = render "projects/diffs/match_line", { line: "",
diff --git a/app/views/projects/notes/_commit_discussion.html.haml b/app/views/projects/notes/_commit_discussion.html.haml
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml
index 39be072855a..8144c1ba49e 100644
--- a/app/views/projects/notes/_diff_notes_with_reply.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml
@@ -1,10 +1,8 @@
-- note = notes.first # example note
--# Check if line want not changed since comment was left
-- if !defined?(line) || line == note.diff_line
-  %tr.notes_holder
-    %td.notes_line{ colspan: 2 }
-    %td.notes_content
-      %ul.notes{ data: { discussion_id: note.discussion_id } }
-        = render notes
-      .discussion-reply-holder
-        = link_to_reply_diff(note)
+- note = notes.first
+%tr.notes_holder
+  %td.notes_line{ colspan: 2 }
+  %td.notes_content
+    %ul.notes{ data: { discussion_id: note.discussion_id } }
+      = render partial: "projects/notes/note", collection: notes, as: :note
+    .discussion-reply-holder
+      = link_to_reply_discussion(note)
diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
index f8aa5e2fa7d..45986b0d1e8 100644
--- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
@@ -1,27 +1,27 @@
-- note1 = notes_left.present? ? notes_left.first : nil
-- note2 = notes_right.present? ? notes_right.first : nil
+- note_left = notes_left.present? ? notes_left.first : nil
+- note_right = notes_right.present? ? notes_right.first : nil
 
 %tr.notes_holder
-  - if note1
+  - if note_left
     %td.notes_line.old
     %td.notes_content.parallel.old
-      %ul.notes{ data: { discussion_id: note1.discussion_id } }
-        = render notes_left
+      %ul.notes{ data: { discussion_id: note_left.discussion_id } }
+        = render partial: "projects/notes/note", collection: notes_left, as: :note
 
       .discussion-reply-holder
-        = link_to_reply_diff(note1, 'old')
+        = link_to_reply_discussion(note_left, 'old')
   - else
     %td.notes_line.old= ""
     %td.notes_content.parallel.old= ""
 
-  - if note2
+  - if note_right
     %td.notes_line.new
     %td.notes_content.parallel.new
-      %ul.notes{ data: { discussion_id: note2.discussion_id } }
-        = render notes_right
+      %ul.notes{ data: { discussion_id: note_right.discussion_id } }
+        = render partial: "projects/notes/note", collection: notes_right, as: :note
 
       .discussion-reply-holder
-        = link_to_reply_diff(note2, 'new')
+        = link_to_reply_discussion(note_right, 'new')
   - else
     %td.notes_line.new= ""
     %td.notes_content.parallel.new= ""
diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml
index 572b00a38c7..40e03050a7d 100644
--- a/app/views/projects/notes/_discussion.html.haml
+++ b/app/views/projects/notes/_discussion.html.haml
@@ -1,13 +1,46 @@
 - note = discussion_notes.first
+- expanded = !note.diff_note? || note.active?
 %li.note.note-discussion.timeline-entry
   .timeline-entry-inner
     .timeline-icon
       = link_to user_path(note.author) do
-        = image_tag avatar_icon(note.author_email), class: "avatar s40"
+        = image_tag avatar_icon(note.author), class: "avatar s40"
     .timeline-content
-      - if note.for_merge_request?
-        - (active_notes, outdated_notes) = discussion_notes.partition(&:active?)
-        = render "projects/notes/discussions/active", discussion_notes: active_notes if active_notes.length > 0
-        = render "projects/notes/discussions/outdated", discussion_notes: outdated_notes if outdated_notes.length > 0
-      - else
-        = render "projects/notes/discussions/commit", discussion_notes: discussion_notes
+      .discussion.js-toggle-container{ class: note.discussion_id }
+        .discussion-header
+          = link_to_member(@project, note.author, avatar: false)
+
+          .inline.discussion-headline-light
+            = note.author.to_reference
+            started a discussion on
+
+            - if note.for_commit?
+              - commit = note.noteable
+              - if commit
+                commit
+                = link_to commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code), class: 'monospace'
+              - else
+                a deleted commit
+            - else
+              - if note.active?
+                = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do
+                  the diff
+              - else
+                the outdated diff
+
+            = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "note-created-ago")
+
+          .discussion-actions
+            = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
+              - if expanded
+                = icon("chevron-up")
+              - else
+                = icon("chevron-down")
+
+              Toggle discussion
+
+        .discussion-body.js-toggle-content{ class: ("hide" unless expanded) }
+          - if note.diff_note?
+            = render "projects/notes/discussions/legacy_diff_with_notes", discussion_notes: discussion_notes
+          - else
+            = render "projects/notes/discussions/notes", discussion_notes: discussion_notes
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index d0ac380f216..67ed38a7b22 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -6,6 +6,7 @@
   = f.hidden_field :line_code
   = f.hidden_field :noteable_id
   = f.hidden_field :noteable_type
+  = f.hidden_field :type
 
   = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
     = render 'projects/zen', f: f, attr: :note, classes: 'note-textarea js-note-text', placeholder: "Write a comment or drag your files here..."
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index aeb7c1d5ee4..9fbc9a45549 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -1,5 +1,8 @@
+- return unless note.author
+- return if note.cross_reference_not_visible_for?(current_user)
+
 - note_editable = note_editable?(note)
-%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} }
+%li.timeline-entry{ id: dom_id(note), class: ["note", "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} }
   .timeline-entry-inner
     .timeline-icon
       %a{href: user_path(note.author)}
@@ -8,8 +11,8 @@
       .note-header
         = link_to_member(note.project, note.author, avatar: false)
         .inline.note-headline-light
-          = "#{note.author.to_reference}"
-          - if !note.system
+          = note.author.to_reference
+          - unless note.system
             commented
           %a{ href: "##{dom_id(note)}" }
             = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
diff --git a/app/views/projects/notes/_notes.html.haml b/app/views/projects/notes/_notes.html.haml
index 62db86fb181..ebf7e8a9cb3 100644
--- a/app/views/projects/notes/_notes.html.haml
+++ b/app/views/projects/notes/_notes.html.haml
@@ -2,14 +2,9 @@
   - @discussions.each do |discussion_notes|
     - note = discussion_notes.first
     - if note_for_main_target?(note)
-      - next if note.cross_reference_not_visible_for?(current_user)
-
-      = render discussion_notes
+      = render partial: "projects/notes/note", object: note, as: :note
     - else
       = render 'projects/notes/discussion', discussion_notes: discussion_notes
 - else
   - @notes.each do |note|
-    - next unless note.author
-    - next if note.cross_reference_not_visible_for?(current_user)
-
-    = render note
+    = render partial: "projects/notes/note", object: note, as: :note
diff --git a/app/views/projects/notes/discussions/_active.html.haml b/app/views/projects/notes/discussions/_active.html.haml
deleted file mode 100644
index 0ea8862a684..00000000000
--- a/app/views/projects/notes/discussions/_active.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-- note = discussion_notes.first
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion"
-      = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do
-        on the diff
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "discussion-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-up
-        Show/hide discussion
-
-  .discussion-body.js-toggle-content
-    = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
diff --git a/app/views/projects/notes/discussions/_commit.html.haml b/app/views/projects/notes/discussions/_commit.html.haml
deleted file mode 100644
index 2a2ead58eeb..00000000000
--- a/app/views/projects/notes/discussions/_commit.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-- note = discussion_notes.first
-- commit = note.noteable
-- commit_description = commit ? 'commit' : 'a deleted commit'
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion on #{commit_description}"
-      - if commit
-        = link_to(commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable), class: 'monospace')
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-up
-        Show/hide discussion
-  .discussion-body.js-toggle-content
-    - if note.for_diff_line?
-      = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
-    - else
-      .panel.panel-default
-        .notes{ data: { discussion_id: discussion_notes.first.discussion_id } }
-          %ul.notes.timeline
-            = render discussion_notes
-        .discussion-reply-holder
-          = link_to_reply_diff(discussion_notes.first)
diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml
deleted file mode 100644
index d46aab000c3..00000000000
--- a/app/views/projects/notes/discussions/_diff.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- diff = note.diff
-- if diff
-  .diff-file
-    .diff-header
-      %span
-        - if diff.deleted_file
-          = diff.old_path
-        - else
-          = diff.new_path
-          - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
-            %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
-    .diff-content.code.js-syntax-highlight
-      %table
-        - note.truncated_diff_lines.each do |line|
-          - type = line.type
-          - line_code = generate_line_code(note.file_path, line)
-          %tr.line_holder{ id: line_code, class: "#{type}" }
-            - if type == "match"
-              %td.old_line.diff-line-num= "..."
-              %td.new_line.diff-line-num= "..."
-              %td.line_content.match= line.text
-            - else
-              %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? "&nbsp;".html_safe : line.old_pos } }
-              %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? "&nbsp;".html_safe : line.new_pos } }
-              %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type)
-
-              - if line_code == note.line_code
-                = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/app/views/projects/notes/discussions/_legacy_diff_with_notes.html.haml b/app/views/projects/notes/discussions/_legacy_diff_with_notes.html.haml
new file mode 100644
index 00000000000..3ab11f6461d
--- /dev/null
+++ b/app/views/projects/notes/discussions/_legacy_diff_with_notes.html.haml
@@ -0,0 +1,30 @@
+- note = discussion_notes.first
+- diff = note.diff
+- return unless diff
+
+.diff-file
+  .diff-header
+    %span
+      - if diff.deleted_file
+        = diff.old_path
+      - else
+        = diff.new_path
+        - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
+          %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
+  .diff-content.code.js-syntax-highlight
+    %table
+      - note.truncated_diff_lines.each do |line|
+        - type = line.type
+        - line_code = generate_line_code(note.file_path, line)
+        %tr.line_holder{ id: line_code, class: "#{type}" }
+          - if type == "match"
+            %td.old_line.diff-line-num= "..."
+            %td.new_line.diff-line-num= "..."
+            %td.line_content.match= line.text
+          - else
+            %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? "&nbsp;".html_safe : line.old_pos } }
+            %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? "&nbsp;".html_safe : line.new_pos } }
+            %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type)
+
+            - if line_code == note.line_code
+              = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/app/views/projects/notes/discussions/_notes.html.haml b/app/views/projects/notes/discussions/_notes.html.haml
new file mode 100644
index 00000000000..e598e3c7c63
--- /dev/null
+++ b/app/views/projects/notes/discussions/_notes.html.haml
@@ -0,0 +1,7 @@
+- note = discussion_notes.first
+.panel.panel-default
+  .notes{ data: { discussion_id: note.discussion_id } }
+    %ul.notes.timeline
+      = render partial: "projects/notes/note", collection: discussion_notes, as: :note
+  .discussion-reply-holder
+    = link_to_reply_discussion(note)
diff --git a/app/views/projects/notes/discussions/_outdated.html.haml b/app/views/projects/notes/discussions/_outdated.html.haml
deleted file mode 100644
index 45141bcd1df..00000000000
--- a/app/views/projects/notes/discussions/_outdated.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- note = discussion_notes.first
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion"
-      on the outdated diff
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-down
-        Show/hide discussion
-  .discussion-body.js-toggle-content.hide
-    = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
diff --git a/db/migrate/20160508215820_add_type_to_notes.rb b/db/migrate/20160508215820_add_type_to_notes.rb
new file mode 100644
index 00000000000..58944d4e651
--- /dev/null
+++ b/db/migrate/20160508215820_add_type_to_notes.rb
@@ -0,0 +1,5 @@
+class AddTypeToNotes < ActiveRecord::Migration
+  def change
+    add_column :notes, :type, :string
+  end
+end
diff --git a/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb
new file mode 100644
index 00000000000..c3f23d89d5a
--- /dev/null
+++ b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb
@@ -0,0 +1,5 @@
+class SetTypeOnLegacyDiffNotes < ActiveRecord::Migration
+  def change
+    execute "UPDATE notes SET type = 'LegacyDiffNote' WHERE line_code IS NOT NULL"
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9b5aa640cb0..e1117a0d858 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -632,10 +632,11 @@ ActiveRecord::Schema.define(version: 20160509201028) do
     t.string   "line_code"
     t.string   "commit_id"
     t.integer  "noteable_id"
-    t.boolean  "system",        default: false, null: false
+    t.boolean  "system",            default: false, null: false
     t.text     "st_diff"
     t.integer  "updated_by_id"
-    t.boolean  "is_award",      default: false, null: false
+    t.boolean  "is_award",          default: false, null: false
+    t.string   "type"
   end
 
   add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 93a3a5ce089..4a11c8e3620 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -107,6 +107,8 @@ module API
 
             break if opts[:line_code]
           end
+
+          opts[:type] = LegacyDiffNote.name if opts[:line_code]
         end
 
         note = ::Notes::CreateService.new(user_project, current_user, opts).execute
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 406f5ea9139..1619199b0a7 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -227,9 +227,9 @@ module API
 
     class CommitNote < Grape::Entity
       expose :note
-      expose(:path) { |note| note.diff_file_name }
-      expose(:line) { |note| note.diff_new_line }
-      expose(:line_type) { |note| note.diff_line_type }
+      expose(:path) { |note| note.diff_file_name if note.legacy_diff_note? }
+      expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? }
+      expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? }
       expose :author, using: Entities::UserBasic
       expose :created_at
     end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 4b788b57882..264888cb376 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -43,12 +43,8 @@ describe Note, models: true do
       expect(note.noteable.id).to eq(commit.id)
     end
 
-    it "should be recognized by #for_diff_line?" do
-      expect(note).to be_for_diff_line
-    end
-
-    it "should be recognized by #for_commit_diff_line?" do
-      expect(note).to be_for_commit_diff_line
+    it "should be recognized by #legacy_diff_note?" do
+      expect(note).to be_legacy_diff_note
     end
   end
 
-- 
GitLab