Commit 494ae878 authored by Riyad Preukschas's avatar Riyad Preukschas
Browse files

Refactor discussion reply

parent 80473329b27b
......@@ -63,18 +63,19 @@ var NoteList = {
// reply to diff notes
$(document).on("click",
".js-diff-note-reply-button",
NoteList.replyToDiffNote);
".js-discussion-reply-button",
NoteList.replyToDiscussionNote);
// hide diff note form
$(document).on("click",
".js-hide-diff-note-form",
NoteList.removeDiffNoteForm);
".js-close-discussion-note-form",
NoteList.removeDiscussionNoteForm);
// do some diff note specific housekeeping when removing a diff note
// do some specific housekeeping when removing a diff or discussion note
$(document).on("click",
".diff_file .js-note-delete",
NoteList.removeDiffNote);
".diff_file .js-note-delete," +
".discussion .js-note-delete",
NoteList.removeDiscussionNote);
// remove a note (in general)
$(document).on("click",
......@@ -102,14 +103,14 @@ var NoteList = {
*/
addDiffNote: function(e) {
// find the form
var form = $(".js-note-forms .js-diff-note-form");
var form = $(".js-note-forms .js-discussion-note-form");
var row = $(this).closest("tr");
var nextRow = row.next();
// does it already have notes?
if (nextRow.is(".notes_holder")) {
$.proxy(NoteList.replyToDiffNote,
nextRow.find(".js-diff-note-reply-button")
$.proxy(NoteList.replyToDiscussionNote,
nextRow.find(".js-discussion-reply-button")
).call();
} else {
// add a notes row and insert the form
......@@ -117,7 +118,7 @@ var NoteList = {
form.clone().appendTo(row.next().find(".notes_content"));
// show the form
NoteList.setupDiffNoteForm($(this), row.next().find("form"));
NoteList.setupDiscussionNoteForm($(this), row.next().find("form"));
}
e.preventDefault();
......@@ -131,11 +132,15 @@ var NoteList = {
*
* Note: must be called before removeNote()
*/
removeDiffNote: function() {
removeDiscussionNote: function() {
var notes = $(this).closest(".notes");
// check if this is the last note for this line
if (notes.find(".note").length === 1) {
// for discussions
notes.closest(".discussion").remove();
// for diff lines
notes.closest("tr").remove();
}
},
......@@ -146,15 +151,15 @@ var NoteList = {
* Shows the reply button again.
* Removes the form and if necessary it's temporary row.
*/
removeDiffNoteForm: function(e) {
removeDiscussionNoteForm: function(e) {
var form = $(this).closest("form");
var row = form.closest("tr");
// show the reply button (will only work for replys)
form.prev(".js-diff-note-reply-button").show();
form.prev(".js-discussion-reply-button").show();
if (row.is(".js-temp-notes-holder")) {
// remove temporary row
// remove temporary row for diff lines
row.remove();
} else {
// only remove the form
......@@ -179,10 +184,9 @@ var NoteList = {
*
* Shows the note form below the notes.
*/
replyToDiffNote: function() {
replyToDiscussionNote: function() {
// find the form
var form = $(".js-note-forms .js-diff-note-form");
var form = $(".js-note-forms .js-discussion-note-form");
// hide reply button
$(this).hide();
......@@ -190,7 +194,7 @@ var NoteList = {
form.clone().insertAfter($(this));
// show the form
NoteList.setupDiffNoteForm($(this), $(this).next("form"));
NoteList.setupDiscussionNoteForm($(this), $(this).next("form"));
},
/**
......@@ -201,7 +205,7 @@ var NoteList = {
* Note: "this" must have the "discussionId", "lineCode", "noteableType" and
* "noteableId" data attributes set.
*/
setupDiffNoteForm: function(data_holder, form) {
setupDiscussionNoteForm: function(data_holder, form) {
// setup note target
form.attr("rel", data_holder.data("discussionId"));
form.find("#note_line_code").val(data_holder.data("lineCode"));
......@@ -210,10 +214,10 @@ var NoteList = {
// setup interaction
disableButtonIfEmptyField(form.find(".js-note-text"), form.find(".js-comment-button"));
setupGfmAutoComplete();
GitLab.GfmAutoComplete.setup();
// cleanup after successfully creating a diff note
form.on("ajax:success", NoteList.removeDiffNoteForm);
form.on("ajax:success", NoteList.removeDiscussionNoteForm);
form.show();
},
......@@ -249,11 +253,11 @@ var NoteList = {
this.bottom_id = newNoteIds.last();
$("#notes-list").html(html);
// init infinite scrolling
this.initLoadMore();
// init getting new notes
if (this.reversed) {
// init infinite scrolling
this.initLoadMore();
// init getting new notes
this.initRefreshNew();
}
},
......@@ -377,9 +381,9 @@ var NoteList = {
appendNewNote:
function(id, html) {
if (this.reversed) {
$("#new-notes-list").prepend(html);
$("#notes-list").prepend(html);
} else {
$("#new-notes-list").append(html);
$("#notes-list").append(html);
}
this.updateVotes();
},
......
......@@ -46,9 +46,12 @@ ul.notes {
@extend .borders;
background-color: #F9F9F9;
}
.diff_file .note {
border-bottom: 0px;
padding: 0px;
.diff_file .notes {
/* reset */
background: inherit;
border: none;
@include box-shadow(none);
}
.discussion-hidden .note {
@extend .cgray;
......@@ -59,6 +62,9 @@ ul.notes {
border-color: #ddd;
padding: 8px;
}
.reply-btn {
margin-top: 8px;
}
}
}
......@@ -92,7 +98,7 @@ ul.notes {
}
}
.diff_file tr.notes_holder {
.diff_file .notes_holder {
font-family: $sansFontFamily;
font-size: 13px;
line-height: 18px;
......@@ -112,38 +118,9 @@ ul.notes {
}
}
.comment-btn {
.reply-btn {
margin-top: 8px;
}
// TODO: start cleanup
form {
// hide it by default
display: none;
margin: 8px 0;
.note_actions {
margin:0;
padding-top: 10px;
.buttons {
float:left;
width:300px;
}
.options {
.labels {
float:left;
padding-left:10px;
label {
padding: 6px 0;
margin: 0;
width:120px;
}
}
}
}
}
// TODO: end cleanup
}
/**
......@@ -185,6 +162,7 @@ ul.notes {
top: 0;
}
// TODO: start cleaup
.issue_notes,
.wiki_notes {
.note_content {
......@@ -193,6 +171,7 @@ ul.notes {
}
}
/* for loading indicator */
.notes-status {
margin: 18px;
}
......@@ -205,6 +184,7 @@ p.notify_controls input{
p.notify_controls span{
font-weight: 700;
}
// TODO: end cleaup
/**
* add line note button on the side of diffs
......@@ -242,56 +222,49 @@ p.notify_controls span{
* Note Forms
*/
.comment-btn {
.comment-btn,
.reply-btn {
@extend .save-btn;
}
.new_discussion_note {
// hide it by default
display: none;
margin: 8px 5px 8px 0;
// TODO: start cleanup
.note_actions {
margin:0;
padding-top: 10px;
.buttons {
float:left;
width:300px;
}
.options {
.labels {
float:left;
padding-left:10px;
label {
padding: 6px 0;
margin: 0;
width:120px;
}
}
}
}
// TODO: end cleanup
}
.new_note {
textarea {
height:80px;
width:99%;
font-size:14px;
}
}
.note-forms {
.new_diff_note {
display: none;
}
}
#new_note {
// TODO: start cleanup
.attach_holder {
display:none;
}
}
.preview_note {
margin: 2px;
border: 1px solid #ddd;
padding: 10px;
min-height: 60px;
background:#f5f5f5;
}
form.new_note {
.input-file {
font: 500px monospace;
opacity: 0;
filter: alpha(opacity=0);
position: absolute;
z-index: 1;
top: 0;
right: 0;
padding: 0;
margin: 0;
}
.note_advanced_opts {
h6 {
line-height: 32px;
padding-right: 15px;
}
}
.attachments {
position: relative;
......@@ -301,18 +274,17 @@ form.new_note {
margin:0 0 5px !important;
.input_file {
.file_upload {
position: absolute;
right: 14px;
top: 7px;
}
.file_name {
line-height: 30px;
width: 240px;
height: 28px;
overflow: hidden;
}
.file_upload {
position: absolute;
right:14px;
top:7px;
}
.input-file {
width: 260px;
height: 41px;
......@@ -320,9 +292,41 @@ form.new_note {
}
}
}
.input-file {
font: 500px monospace;
opacity:0;
filter: alpha(opacity=0);
position: absolute;
z-index: 1;
top:0;
right:0;
padding:0;
margin: 0;
}
.note_advanced_opts {
h6 {
line-height: 32px;
padding-right: 15px;
}
}
.note-text {
border: 1px solid #aaa;
box-shadow:none;
}
// TODO: end cleanup
}
// hide the new discussion note form template
.note-forms {
.new_discussion_note {
display: none;
}
}
.note-text {
border: 1px solid #aaa;
box-shadow: none;
.preview_note {
margin: 2px;
border: 1px solid #ddd;
padding: 10px;
min-height: 60px;
background:#f5f5f5;
}
......@@ -13,10 +13,14 @@ def show
@commit = result[:commit]
git_not_found! unless @commit
@suppress_diff = result[:suppress_diff]
@note = result[:note]
@line_notes = result[:line_notes]
@notes_count = result[:notes_count]
@suppress_diff = result[:suppress_diff]
@note = result[:note]
@line_notes = result[:line_notes]
@notes_count = result[:notes_count]
@target_type = :commit
@target_id = @commit.id
@comments_allowed = @reply_allowed = true
@comments_target = { noteable_type: 'Commit',
noteable_id: @commit.id }
......
......@@ -38,6 +38,8 @@ def edit
def show
@note = @project.notes.new(noteable: @issue)
@target_type = :issue
@target_id = @issue.id
respond_to do |format|
format.html
......
......@@ -21,6 +21,9 @@ def index
end
def show
@target_type = :merge_request
@target_id = @merge_request.id
respond_to do |format|
format.html
format.js
......
......@@ -6,13 +6,11 @@ class NotesController < ProjectResourceController
respond_to :js
def index
@target_note = Note.new(noteable_type: params[:target_type].camelize,
noteable_id: params[:target_id])
@target = @target_note.noteable
@notes = Notes::LoadContext.new(project, current_user, params).execute
@target_type = params[:target_type].camelize
@target_id = params[:target_id]
if params[:target_type] == "merge_request"
@mixed_targets = true
@discussions = discussions_from_notes
end
......@@ -21,6 +19,8 @@ def index
def create
@note = Notes::CreateContext.new(project, current_user, params).execute
@target_type = params[:target_type].camelize
@target_id = params[:target_id]
respond_to do |format|
format.html {redirect_to :back}
......@@ -58,7 +58,7 @@ def discussions_from_notes
next if discussion_ids.include?(note.discussion_id)
# don't group notes for the main target
if for_main_target?(note)
if note_for_main_target?(note)
discussions << [note]
else
discussions << discussion_notes_for(note)
......@@ -70,7 +70,7 @@ def discussions_from_notes
end
# Helps to distinguish e.g. commit notes in mr notes list
def for_main_target?(note)
!@mixed_targets || (@target.class.name == note.noteable_type && !note.for_diff_line?)
def note_for_main_target?(note)
@target_type.camelize == note.noteable_type && !note.for_diff_line?
end
end
......@@ -75,7 +75,10 @@ def files
def wall
return render_404 unless @project.wall_enabled
@note = Note.new
@target_type = :wall
@target_id = nil
@note = @project.notes.new
respond_to do |format|
format.html
......
......@@ -50,6 +50,8 @@ def update
def show
@note = @project.notes.new(noteable: @snippet)
@target_type = :snippet
@target_id = @snippet.id
end
def destroy
......
module NotesHelper
# Helps to distinguish e.g. commit notes in mr notes list
def note_for_main_target?(note)
!@mixed_targets || (@target.class.name == note.noteable_type && !note.for_diff_line?)
@target_type.camelize == note.noteable_type && !note.for_diff_line?
end
def note_target_fields
hidden_field_tag(:target_type, @target_type) +
hidden_field_tag(:target_id, @target_id)
end
def link_to_commit_diff_line_note(note)
......
= render "commits/commit_box"
= render "commits/diffs", diffs: @commit.diffs
= render "notes/notes_with_form", tid: @commit.id, tt: "commit"
= render "notes/notes_with_form"
:javascript
$(function(){
......
......@@ -61,4 +61,4 @@
= markdown @issue.description
.issue_notes.voting_notes#notes= render "notes/notes_with_form", tid: @issue.id, tt: "issue"
.issue_notes.voting_notes#notes= render "notes/notes_with_form"
......@@ -16,7 +16,7 @@
Diff
.merge_request_notes.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
= render("notes/notes_with_form", tid: @merge_request.id, tt: "merge_request")
= render "notes/notes_with_form"
.merge-request-diffs
= render "merge_requests/show/diffs" if @diffs
.status
......
:plain
$(".merge-request-notes").html("#{escape_javascript(render notes/notes_with_form", tid: @merge_request.id, tt: "merge_request")}");
$(".merge-request-notes").html("#{escape_javascript(render notes/notes_with_form")}");
.note-form-holder
= form_for [@project, @note], remote: "true", multipart: true do |f|
= note_target_fields
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type
%h3.page_title Leave a comment
-if @note.errors.any?
.alert-message.block-message.error
- @note.errors.full_messages.each do |msg|
%div= msg
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type
= f.text_area :note, size: 255, class: 'js-note-text js-gfm-input'
#preview-note.preview_note.hide
.hint
......
- if note.valid?
:plain
// hide and reset the form
var form = $("form[rel='#{note.discussion_id}']");
var row = form.closest("tr");
// is this the first note?
// is this the first note of discussion?
var row = $("form[rel='#{note.discussion_id}']").closest("tr");
if (row.is(".js-temp-notes-holder")) {
// insert the note and the reply button after it
row.after("#{escape_javascript(render "notes/diff_notes_with_reply", notes: [note])}");
} else {
// instert new note before reply button
row.find(".notes").append("#{escape_javascript(render "notes/note", note: note)}");
// will be added again below
row.next().find(".note").remove();
}
// append new note to all discussions
$(".notes[rel='#{note.discussion_id}']").append("#{escape_javascript(render "notes/note", note: note)}");
= form_for [@project, @note], remote: true, html: { multipart: true, class: "new_note new_diff_note js-diff-note-form" } do |f|
.span10
-if @note.errors.any?
.alert-message.block-message.error
- @note.errors.full_messages.each do |msg|
%div= msg
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type