Commit 6323cdda687283f956c1199f45eeb4340ab83464

Authored by Aleksei Kvitinskii
2 parents b946da44 0b0e0225

Merge branch 'dev' into issue-184

app/assets/images/ajax-loader.gif

6.66 KB | W: | H:

4.08 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
app/assets/javascripts/application.js
... ... @@ -21,6 +21,6 @@ $(function(){
21 21 $('select#tag').selectmenu({style:'popup', width:200});
22 22 });
23 23  
24   -function updatePage(){
25   - $.ajax({type: "GET", url: location.href, dataType: "script"});
  24 +function updatePage(data){
  25 + $.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
26 26 }
... ...
app/assets/javascripts/note.js 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +var NoteList = {
  2 +
  3 +first_id: 0,
  4 +last_id: 0,
  5 +resource_name: null,
  6 +
  7 +init:
  8 + function(resource_name, first_id, last_id) {
  9 + this.resource_name = resource_name;
  10 + this.first_id = first_id;
  11 + this.last_id = last_id;
  12 + this.initRefresh();
  13 + this.initLoadMore();
  14 + },
  15 +
  16 +getOld:
  17 + function() {
  18 + $('.loading').show();
  19 + $.ajax({
  20 + type: "GET",
  21 + url: location.href,
  22 + data: "first_id=" + this.first_id,
  23 + complete: function(){ $('.loading').hide()},
  24 + dataType: "script"});
  25 + },
  26 +
  27 +append:
  28 + function(id, html) {
  29 + this.first_id = id;
  30 + $("#notes-list").append(html);
  31 + this.initLoadMore();
  32 + },
  33 +
  34 +prepend:
  35 + function(id, html) {
  36 + this.last_id = id;
  37 + $("#notes-list").prepend(html);
  38 + },
  39 +
  40 +getNew:
  41 + function() {
  42 + // refersh notes list
  43 + $.ajax({
  44 + type: "GET",
  45 + url: location.href,
  46 + data: "last_id=" + this.last_id,
  47 + dataType: "script"});
  48 + },
  49 +
  50 +initRefresh:
  51 + function() {
  52 + // init timer
  53 + var int = setInterval("NoteList.getNew()", 20000);
  54 + },
  55 +
  56 +initLoadMore:
  57 + function() {
  58 + $(window).bind('scroll', function(){
  59 + if($(window).scrollTop() == $(document).height() - $(window).height()){
  60 + $(window).unbind('scroll');
  61 + NoteList.getOld();
  62 + }
  63 + });
  64 + }
  65 +}
... ...
app/assets/stylesheets/projects.css.scss
... ... @@ -421,31 +421,6 @@ input.ssh_project_url {
421 421 list-style:none;
422 422 margin:0px;
423 423 padding:0px;
424   -
425   - li {
426   - display:list-item;
427   - padding:8px;
428   - margin:0px;
429   - background: #F7FBFC;
430   - border-top: 1px solid #E2EAEE;
431   -
432   - &:first-child {
433   - border-top: none;
434   - }
435   - &:nth-child(2n+1) {
436   - background: white;
437   - }
438   - p {
439   - margin-bottom: 4px;
440   - font-size: 13px;
441   - color:#111;
442   - }
443   - }
444   - cite {
445   - &.ago {
446   - color:#666;
447   - }
448   - }
449 424 }
450 425  
451 426 .notes_count {
... ... @@ -460,14 +435,6 @@ input.ssh_project_url {
460 435 right: 6px;
461 436 top: 6px;
462 437 }
463   -.note_author {
464   - float:left;
465   - width:60px;
466   -}
467   -.note_content {
468   - float:left;
469   - width:650px;
470   -}
471 438  
472 439 .issue_notes {
473 440 .note_content {
... ... @@ -556,8 +523,7 @@ input.ssh_project_url {
556 523  
557 524 }
558 525 .commit,
559   -.message,
560   -#notes-list{
  526 +.message{
561 527 .author {
562 528 background: #eaeaea;
563 529 color: #333;
... ... @@ -574,7 +540,7 @@ input.ssh_project_url {
574 540 font-size:14px;
575 541 }
576 542  
577   -.wall_page {
  543 +#new_note {
578 544 #note_note {
579 545 height:25px;
580 546 }
... ... @@ -719,3 +685,11 @@ table.highlighttable pre{
719 685 .project-refs-select {
720 686 width:200px;
721 687 }
  688 +
  689 +body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
  690 +body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
  691 +body.project-page #notes-list .note img{float: left; margin-right: 10px;}
  692 +body.project-page #notes-list .note span.note-title{display: block;}
  693 +body.project-page #notes-list .note span.note-title{margin-bottom: 10px}
  694 +body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;}
  695 +body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;}
... ...
app/assets/stylesheets/style.scss
... ... @@ -292,7 +292,7 @@ body.login-page{background-color: #f1f1f1; padding-top: 10%}
292 292  
293 293 /* General */
294 294 #container{background-color: white; overflow: hidden;}
295   -/*#container{margin: auto; width: 980px; border: 1px solid rgba(0,0,0,.22); border-top: 0; box-shadow: 0 0 0px 4px rgba(0,0,0,.04)}*/
  295 +body.collapsed #container{margin: auto; width: 980px; border: 1px solid rgba(0,0,0,.22); border-top: 0; box-shadow: 0 0 0px 4px rgba(0,0,0,.04)}
296 296  
297 297  
298 298  
... ...
app/controllers/application_controller.rb
1 1 class ApplicationController < ActionController::Base
2 2 before_filter :authenticate_user!
  3 + before_filter :view_style
  4 +
3 5 protect_from_forgery
4 6  
5 7 helper_method :abilities, :can?
... ... @@ -73,4 +75,12 @@ class ApplicationController &lt; ActionController::Base
73 75 def require_non_empty_project
74 76 redirect_to @project unless @project.repo_exists?
75 77 end
  78 +
  79 + def view_style
  80 + if params[:view_style] == "collapsed"
  81 + cookies[:view_style] = "collapsed"
  82 + elsif params[:view_style] == "fluid"
  83 + cookies[:view_style] = ""
  84 + end
  85 + end
76 86 end
... ...
app/controllers/commits_controller.rb
... ... @@ -28,12 +28,15 @@ class CommitsController &lt; ApplicationController
28 28  
29 29 def show
30 30 @commit = project.repo.commits(params[:id]).first
31   - @notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit")
  31 + @notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit").order("created_at DESC").limit(20)
32 32 @note = @project.notes.new(:noteable_id => @commit.id, :noteable_type => "Commit")
33 33  
34   - respond_to do |format|
35   - format.html # show.html.erb
36   - format.js
  34 + respond_to do |format|
  35 + format.html
  36 + format.js do
  37 + @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]
  38 + @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]
  39 + end
37 40 end
38 41 end
39 42 end
... ...
app/controllers/issues_controller.rb
... ... @@ -35,8 +35,16 @@ class IssuesController &lt; ApplicationController
35 35 end
36 36  
37 37 def show
38   - @notes = @issue.notes.order("created_at ASC")
  38 + @notes = @issue.notes.order("created_at DESC").limit(20)
39 39 @note = @project.notes.new(:noteable => @issue)
  40 +
  41 + respond_to do |format|
  42 + format.html
  43 + format.js do
  44 + @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]
  45 + @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]
  46 + end
  47 + end
40 48 end
41 49  
42 50 def create
... ...
app/controllers/projects_controller.rb
... ... @@ -86,13 +86,15 @@ class ProjectsController &lt; ApplicationController
86 86 def wall
87 87 @note = Note.new
88 88 @notes = @project.common_notes.order("created_at DESC")
  89 + @notes = @notes.fresh.limit(20)
89 90  
90   - @notes = case params[:view]
91   - when "week" then @notes.since((Date.today - 7.days).at_beginning_of_day)
92   - when "all" then @notes.all
93   - when "day" then @notes.since(Date.today.at_beginning_of_day)
94   - else @notes.fresh.limit(10)
95   - end
  91 + respond_to do |format|
  92 + format.html
  93 + format.js do
  94 + @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]
  95 + @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]
  96 + end
  97 + end
96 98 end
97 99  
98 100 #
... ...
app/helpers/application_helper.rb
... ... @@ -4,6 +4,14 @@ module ApplicationHelper
4 4 "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon"
5 5 end
6 6  
  7 + def body_class(default_class = nil)
  8 + main = content_for(:body_class).blank? ?
  9 + default_class :
  10 + content_for(:body_class)
  11 +
  12 + [main, cookies[:view_style]].join(" ")
  13 + end
  14 +
7 15 def commit_name(project, commit)
8 16 if project.commit.id == commit.id
9 17 "master"
... ...
app/views/commits/index.html.haml
... ... @@ -12,7 +12,7 @@
12 12 \/
13 13 %a{:href => "#"}= params[:path].split("/").join(" / ")
14 14  
15   -.right= render "projects/refs"
  15 +.right= render :partial => "projects/refs", :locals => { :destination => project_commits_path(@project) }
16 16  
17 17 %div{:id => dom_id(@project)}
18 18 = render "commits"
... ...
app/views/commits/show.js.haml
1   --#:plain
2   - $("#side-commit-preview").remove();
3   - var side = $("<div id='side-commit-preview'></div>");
4   - side.html("#{escape_javascript(render "commits/show")}");
5   - $("##{dom_id(@project)}").parent().append(side);
6   - $("##{dom_id(@project)}").addClass("span-14");
7   -:plain
8   - $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  1 += render "notes/load"
... ...
app/views/issues/show.html.haml
1 1 %h2
2 2 = "Issue ##{@issue.id} - #{html_escape(@issue.title)}"
3 3 .left.width-65p
4   - -#= simple_format html_escape(@issue.content)
5 4 .issue_notes= render "notes/notes"
  5 +
  6 + .loading{ :style => "display:none;"}
  7 + %center= image_tag "ajax-loader.gif"
6 8 .right.width-30p
7 9 .span-8
8   - - if @issue.closed
9   - %center.success Closed
10   - - else
11   - %center.error Open
12 10 %table.round-borders
13 11 %tr
14 12 %td Title:
... ... @@ -54,4 +52,3 @@
54 52 = link_to 'Edit', edit_project_issue_path(@project, @issue), :class => "lbutton positive", :remote => true
55 53 .right= link_to 'Destroy', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{@issue.id}"
56 54 .clear
57   -
... ...
app/views/issues/show.js.haml
1   -:plain
2   - $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  1 += render "notes/load"
... ...
app/views/layouts/_head_panel.html.erb
1 1 <!-- Page Header -->
2 2 <header>
3   -<h1 class="logo">
4   - <a href="/">GITLAB</a></h1>
5   - <div class="login-top">
6   - <%= link_to profile_path, :class => "pic" do %>
7   - <%= image_tag gravatar_icon(current_user.email) %>
8   - <% end %>
9   - <%= link_to profile_path, :class => "username" do %>
10   - <%= current_user.name %>
11   - <% end %>
12   - <%= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete %>
  3 + <h1 class="logo">
  4 + <a href="/">GITLAB</a>
  5 + </h1>
  6 + <div class="account-box">
  7 + <%= link_to profile_path, :class => "pic" do %>
  8 + <%= image_tag gravatar_icon(current_user.email) %>
  9 + <% end %>
  10 +
  11 + <a href="#" class="arrow-up"></a>
  12 +
  13 + <div class="account-links">
  14 + <%= link_to profile_path, :class => "username" do %>
  15 + <%#= current_user.name %>
  16 + Your profile
  17 + <% end %>
  18 + <%= link_to "Fluid layout", url_for( :view_style => 'fluid' ) if cookies[:view_style] == "collapsed"%>
  19 + <%= link_to "Fixed layout", url_for( :view_style => 'collapsed' ) unless cookies[:view_style] == "collapsed"%>
  20 + <%= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete %>
13 21 </div>
14   - <div class="search">
15   - <%= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" %>
16   - </div>
  22 + </div><!-- .account-box -->
  23 +
  24 + <div class="search">
  25 + <%= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" %>
  26 + </div>
17 27 <!-- .login-top -->
18 28 <nav>
19 29 <%= link_to dashboard_path, :class => current_page?(root_path) ? "current dashboard" : "dashboard" do %>
... ... @@ -26,23 +36,10 @@
26 36 <span></span>Admin
27 37 <% end %>
28 38 </nav>
  39 +
29 40 </header>
30 41 <!-- eo Page Header -->
31 42  
32   -<div id="header-panel" style="display:none">
33   - <div class="container">
34   - <div class="span-24">
35   - <div class="span-10">
36   - <span class="search-holder">
37   - </span>
38   - </div>
39   - <div class="right">
40   - <%= link_to truncate(@project.name, :length => 20), project_path(@project), :class => "current button" if @project && !@project.new_record? %>
41   - </div>
42   - </div>
43   - </div>
44   -</div>
45   -
46 43 <% if current_user %>
47 44 <%= javascript_tag do %>
48 45 $(function() {
... ...
app/views/layouts/admin.html.haml
... ... @@ -9,7 +9,7 @@
9 9 = javascript_tag do
10 10 REQ_URI = "#{request.env["REQUEST_URI"]}";
11 11 REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
12   - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)}
  12 + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
13 13 #container
14 14 = render :partial => "layouts/flash"
15 15 = render :partial => "layouts/head_panel"
... ...
app/views/layouts/application.html.haml
... ... @@ -13,7 +13,7 @@
13 13 = javascript_tag do
14 14 REQ_URI = "#{request.env["REQUEST_URI"]}";
15 15 REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
16   - %body{ :class => yield(:body_class), :id => yield(:boyd_id)}
  16 + %body{ :class => body_class, :id => yield(:boyd_id)}
17 17 #container
18 18 = render :partial => "layouts/flash"
19 19 = render :partial => "layouts/head_panel"
... ...
app/views/layouts/profile.html.haml
... ... @@ -9,7 +9,7 @@
9 9 = javascript_tag do
10 10 REQ_URI = "#{request.env["REQUEST_URI"]}";
11 11 REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
12   - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)}
  12 + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
13 13 #container
14 14 = render :partial => "layouts/flash"
15 15 = render :partial => "layouts/head_panel"
... ...
app/views/layouts/project.html.haml
... ... @@ -9,7 +9,7 @@
9 9 = javascript_tag do
10 10 REQ_URI = "#{request.env["REQUEST_URI"]}";
11 11 REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
12   - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)}
  12 + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
13 13 #container
14 14 = render :partial => "layouts/flash"
15 15 = render :partial => "layouts/head_panel"
... ...
app/views/notes/_load.js.haml 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +- unless @notes.blank?
  2 +
  3 + - if params[:last_id]
  4 + :plain
  5 + NoteList.prepend(#{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  6 +
  7 + - if params[:first_id]
  8 + :plain
  9 + NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  10 +
... ...
app/views/notes/_notes.html.haml
1   -- if controller.action_name == "wall"
2   - %ul#notes-list= render "notes/notes_list"
3   -
4   -- else
5   - %ul#notes-list= render "notes/notes_list"
6   - %br
7   - %br
8   - - if can? current_user, :write_note, @project
9   - = render "notes/form"
  1 +- if can? current_user, :write_note, @project
  2 + = render "notes/form"
  3 +.clear
  4 +%hr
  5 +%ul#notes-list= render "notes/notes_list"
10 6  
11 7 :javascript
12 8 $('.delete-note').live('ajax:success', function() {
... ... @@ -20,8 +16,11 @@
20 16 $("#submit_note").removeAttr("disabled");
21 17 })
22 18  
23   -- if ["issues", "projects"].include?(controller.controller_name)
24   - :javascript
25   - $(function(){
26   - var int =self.setInterval("updatePage()", 20000);
  19 + $(function(){
  20 + $("#note_note").live("click", function(){
  21 + $(this).css("height", "100px");
  22 + $('.attach_holder').show();
27 23 });
  24 +
  25 + NoteList.init("wall", #{@notes.last.try(:id) || 0}, #{@notes.first.try(:id) || 0});
  26 + });
... ...
app/views/notes/_show.html.haml
1   -%li{:id => dom_id(note)}
2   - %div.note_author
3   - = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;"
4   - %div.note_content.left
  1 +%li{:id => dom_id(note), :class => "note"}
  2 + = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;"
  3 + %div.note-author
  4 + %strong= note.author_name
  5 + %cite
  6 + = time_ago_in_words(note.updated_at)
  7 + ago
  8 + - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
  9 + = link_to 'Remove', [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-note right negative"
  10 +
  11 + %div.note-title
5 12 = markdown(note.note)
6 13 - if note.attachment.url
7 14 Attachment:
8 15 = link_to note.attachment_identifier, note.attachment.url, :target => "_blank"
9   - %br
10   - %span.author= note.author.name
11   - %cite.ago
12   - = time_ago_in_words(note.updated_at)
13   - ago
14 16 %br
15   - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
16   - = link_to 'Remove', [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-note right negative"
17 17 .clear
... ...
app/views/notes/create.js.haml
1 1 - if @note.valid?
2 2 :plain
3 3 $("#new_note .errors").remove();
4   - updatePage();
5 4 $('#note_note').val("");
  5 + NoteList.prepend(#{@note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => @note})}");
6 6 - else
7 7 :plain
8 8 $("#new_note").replaceWith("#{escape_javascript(render('form'))}");
... ...
app/views/projects/_refs.html.haml
1   -= form_tag project_commits_path(@project), :method => :get, :class => "project-refs-form" do
  1 += form_tag destination, :method => :get, :class => "project-refs-form" do
2 2 = select_tag "ref", grouped_options_refs, :onchange => "this.form.submit();", :class => "project-refs-select"
3 3  
4 4  
... ...
app/views/projects/_tree.html.haml
... ... @@ -17,7 +17,7 @@
17 17 \/
18 18 = link_to truncate(part, :length => 40), tree_file_project_path(@project, :path => part_path, :commit_id => @commit.try(:id), :branch => @branch, :tag => @tag), :remote => :true
19 19 &nbsp;
20   - .right= render "projects/refs"
  20 + .right= render :partial => "projects/refs", :locals => { :destination => tree_project_path(@project) }
21 21 .clear
22 22  
23 23 #tree-content-holder
... ...
app/views/projects/wall.html.haml
1 1 %div.wall_page
2   - - if can? current_user, :write_note, @project
3   - = render "notes/form"
4   - .right
5   - = form_tag wall_project_path(@project), :method => :get do
6   - .span-2
7   - = radio_button_tag :view, "recent", (params[:view] || "recent") == "recent", :onclick => "this.form.submit()", :id => "recent_view"
8   - = label_tag "recent_view","Recent"
9   - .span-2
10   - = radio_button_tag :view, "day", params[:view] == "day", :onclick => "this.form.submit()", :id => "day_view"
11   - = label_tag "day_view","Today"
12   - .span-2
13   - = radio_button_tag :view, "week", params[:view] == "week", :onclick => "this.form.submit()", :id => "week_view"
14   - = label_tag "week_view","Week"
15   - .span-2
16   - = radio_button_tag :view, "all", params[:view] == "all", :onclick => "this.form.submit()", :id => "all_view"
17   - = label_tag "all_view","All"
18   - .clear
19   - %br
20   - %hr
21   -= render "notes/notes"
  2 + = render "notes/notes"
  3 +
  4 +.loading{ :style => "display:none;"}
  5 + %center= image_tag "ajax-loader.gif"
22 6  
23   -:javascript
24   - $(function(){
25   - $("#note_note").live("click", function(){
26   - $(this).css("height", "100px");
27   - $('.attach_holder').show();
28   - });
29   - });
... ...
app/views/projects/wall.js.haml
1   -:plain
2   - $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  1 += render "notes/load"
... ...