summaryrefslogtreecommitdiff
path: root/app/models/concerns
diff options
context:
space:
mode:
authorSean McGivern <sean@mcgivern.me.uk>2018-10-05 09:25:02 +0000
committerSean McGivern <sean@mcgivern.me.uk>2018-10-05 09:25:02 +0000
commit16d038da1c5c38c02fbc300eb180c64b67a0d908 (patch)
tree22248d5e6673c37b46ec2a0731631e3b3d3b6aa6 /app/models/concerns
parentc350f3ccd8e72d2e655210c74e508e7720763eb7 (diff)
parentd7fa6679cbf01b934c7080b515579c233e5ddad7 (diff)
downloadgitlab-ce-16d038da1c5c38c02fbc300eb180c64b67a0d908.tar.gz
Merge branch 'ce-issue_1984' into 'master'
Backport CE changes from draft_notes addition in EE See merge request gitlab-org/gitlab-ce!22125
Diffstat (limited to 'app/models/concerns')
-rw-r--r--app/models/concerns/diff_positionable_note.rb81
1 files changed, 81 insertions, 0 deletions
diff --git a/app/models/concerns/diff_positionable_note.rb b/app/models/concerns/diff_positionable_note.rb
new file mode 100644
index 00000000000..b61bf29e6ad
--- /dev/null
+++ b/app/models/concerns/diff_positionable_note.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+module DiffPositionableNote
+ extend ActiveSupport::Concern
+
+ included do
+ before_validation :set_original_position, on: :create
+ before_validation :update_position, on: :create, if: :on_text?
+
+ serialize :original_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
+ serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
+ serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
+ end
+
+ %i(original_position position change_position).each do |meth|
+ define_method "#{meth}=" do |new_position|
+ if new_position.is_a?(String)
+ new_position = JSON.parse(new_position) rescue nil
+ end
+
+ if new_position.is_a?(Hash)
+ new_position = new_position.with_indifferent_access
+ new_position = Gitlab::Diff::Position.new(new_position)
+ end
+
+ return if new_position == read_attribute(meth)
+
+ super(new_position)
+ end
+ end
+
+ def on_text?
+ position&.position_type == "text"
+ end
+
+ def on_image?
+ position&.position_type == "image"
+ end
+
+ def supported?
+ for_commit? || self.noteable.has_complete_diff_refs?
+ end
+
+ def active?(diff_refs = nil)
+ return false unless supported?
+ return true if for_commit?
+
+ diff_refs ||= noteable.diff_refs
+
+ self.position.diff_refs == diff_refs
+ end
+
+ def set_original_position
+ return unless position
+
+ self.original_position = self.position.dup unless self.original_position&.complete?
+ end
+
+ def update_position
+ return unless supported?
+ return if for_commit?
+
+ return if active?
+ return unless position
+
+ tracer = Gitlab::Diff::PositionTracer.new(
+ project: self.project,
+ old_diff_refs: self.position.diff_refs,
+ new_diff_refs: self.noteable.diff_refs,
+ paths: self.position.paths
+ )
+
+ result = tracer.trace(self.position)
+ return unless result
+
+ if result[:outdated]
+ self.change_position = result[:position]
+ else
+ self.position = result[:position]
+ end
+ end
+end