This commit is contained in:
albert
2011-05-29 03:47:06 -04:00
parent 969185ad24
commit 9e287726e3
18 changed files with 237 additions and 137 deletions

View File

@@ -19,5 +19,5 @@ gem "simple_form"
gem "mechanize"
gem "nokogiri"
gem "meta_search"
gem "will_paginate", :git => "git://github.com/wantful/will_paginate.git"
gem "will_paginate", :git => "git://github.com/mmack/will_paginate.git", :branch => "rails3.1"
gem "silent-postgres"

View File

@@ -1,8 +1,9 @@
GIT
remote: git://github.com/wantful/will_paginate.git
revision: e1676b5cec9e50e208fc2806b8c78ed1c8824275
remote: git://github.com/mmack/will_paginate.git
revision: 5816b4e8d4382b4b167621a9aea4b8fe72983c37
branch: rails3.1
specs:
will_paginate (2.3.15)
will_paginate (3.1.0)
GIT
remote: http://github.com/EmmanuelOga/ffaker.git

View File

@@ -3,7 +3,7 @@ Danbooru.Note = {
create: function(id) {
var $inner_border = $('<div/>');
$inner_border.addClass("note-box-inner-border");
$inner_border.css({opacity: 0.7});
$inner_border.css({opacity: 0.5});
var $note_box = $('<div/>');
$note_box.addClass("note-box");
@@ -63,6 +63,10 @@ Danbooru.Note = {
);
},
find: function(id) {
return $("#note-container div.note-box[data-id=" + id + "]");
},
resize_inner_border: function($note_box) {
var $inner_border = $note_box.find("div.note-box-inner-border");
$inner_border.css({
@@ -124,7 +128,7 @@ Danbooru.Note = {
},
initialize: function($note_body) {
var $note_box = $("#note-container div.note-box[data-id=" + $note_body.data("id") + "]");
var $note_box = Danbooru.Note.Box.find($note_body.data("id"));
$note_body.css({
top: $note_box.position().top + $note_box.height() + 5,
left: $note_box.position().left
@@ -149,18 +153,22 @@ Danbooru.Note = {
Danbooru.Note.Body.hide_all();
Danbooru.Note.clear_timeouts();
var $note_body = $("#note-container div.note-body[data-id=" + id + "]");
var $note_body = Danbooru.Note.Body.find(id);
$note_body.show();
Danbooru.Note.Body.initialize($note_body);
},
find: function(id) {
return $("#note-container div.note-body[data-id=" + id + "]");
},
hide: function(id) {
var $note_body = $("#note-container div.note-body[data-id=" + id + "]");
var $note_body = Danbooru.Note.Body.find(id);
Danbooru.Note.timeouts.push($.timeout(250).done(function() {$note_body.hide();}));
},
hide_all: function() {
$(".note-body").hide();
$("#note-container div.note-body").hide();
},
resize: function($note_body) {
@@ -250,17 +258,64 @@ Danbooru.Note = {
Danbooru.Note.editing = true;
},
parameterize_note: function($note_box, $note_body) {
var hash = {
note: {
x: $note_box.position().left,
y: $note_box.position().top,
width: $note_box.width(),
height: $note_box.height(),
body: $note_body.html(),
post_id: Danbooru.meta("post-id")
}
}
if ($note_box.data("id").match(/x/)) {
hash.note.html_id = $note_box.data("id");
}
return hash;
},
error_handler: function(xhr, status, exception) {
Danbooru.j_error("There was an error saving the note");
},
success_handler: function(data, status, xhr) {
if (data.html_id) {
var $note_body = Danbooru.Note.Body.find(data.html_id);
var $note_box = Danbooru.Note.Box.find(data.html_id);
$note_body.data("id", data.id).attr("data-id", data.id);
$note_box.data("id", data.id).attr("data-id", data.id);
$note_box.find(".note-box-inner-border").removeClass("unsaved");
}
},
save: function() {
var $this = $(this);
var $textarea = $this.find("textarea");
var id = $this.data("id");
var $note_body = $("#note-container .note-body[data-id=" + id + "]");
var $note_box = $("#note-container .note-box[data-id=" + id + "]");
var $note_body = Danbooru.Note.Body.find(id);
var $note_box = Danbooru.Note.Box.find(id);
var text = $textarea.val();
Danbooru.Note.Body.set_text($note_body, text);
$this.dialog("close");
$note_box.find(".note-box-inner-border").removeClass("unsaved");
console.log("save %d", id);
if (id.match(/\d/)) {
$.ajax("/notes/" + id + ".json", {
type: "PUT",
data: Danbooru.Note.Edit.parameterize_note($note_box, $note_body),
error: Danbooru.Note.Edit.error_handler,
success: Danbooru.Note.Edit.success_handler
});
} else {
$.ajax("/notes.json", {
type: "POST",
data: Danbooru.Note.Edit.parameterize_note($note_box, $note_body),
error: Danbooru.Note.Edit.error_handler,
success: Danbooru.Note.Edit.success_handler
});
}
},
cancel: function() {
@@ -270,29 +325,37 @@ Danbooru.Note = {
delete: function() {
var $this = $(this);
var id = $this.data("id");
console.log("delete %d", id);
$("#note-container .note-box[data-id=" + id + "]").remove();
$("#note-container .note-body[data-id=" + id + "]").remove();
Danbooru.Note.Box.find(id).remove();
Danbooru.Note.Body.find(id).remove();
$(this).dialog("close");
if (id.match(/\d/)) {
$.ajax("/notes/" + id + ".js", {
type: "DELETE"
});
}
},
history: function() {
var $this = $(this);
var id = $this.data("id");
console.log("history %d", id);
$(this).dialog("close");
if (id.match(/\d/)) {
window.href = "/note_versions?search[note_id]=" + id;
}
}
},
TranslationMode: {
start: function() {
$("#note-container").click(Danbooru.Note.TranslationMode.create_note);
$("#translate-button").one("click", Danbooru.Note.TranslationMode.stop).html("Click on image");
$("#translate").one("click", Danbooru.Note.TranslationMode.stop).html("Click on image");
},
stop: function() {
$("#note-container").unbind("click");
$("#translate-button").one("click", Danbooru.Note.TranslationMode.start).html("Translate");
$("#translate").one("click", Danbooru.Note.TranslationMode.start).html("Translate");
},
create_note: function(e) {
@@ -330,7 +393,7 @@ Danbooru.Note = {
scale: function() {
var $image = $("#image");
if ($image.attr("ratio")) {
// TODO: implement
}
},
@@ -355,7 +418,7 @@ Danbooru.Note = {
new: function(x, y) {
var $note_box = Danbooru.Note.Box.create(Danbooru.Note.id);
var $note_body = Danbooru.Note.Body.create(Danbooru.Note.id);
$note_box.offset({
$note_box.css({
top: y,
left: x
});
@@ -376,12 +439,12 @@ Danbooru.Note = {
}
}
$(document).ready(function() {
if ($("#c-posts #a-show").size > 0) {
$(function() {
if ($("#c-posts #a-show").size() > 0) {
Danbooru.Note.Image.resize();
$("#translate-button").one("click", Danbooru.Note.TranslationMode.start);
$("#translate").one("click", Danbooru.Note.TranslationMode.start);
$("#note-container").width($("#image").width()).height($("#image").height());
// $(document).bind("keydown", "ctrl+n", Danbooru.Note.TranslationMode.start);
$(document).bind("keydown", "ctrl+n", Danbooru.Note.TranslationMode.start);
$("#toggle-resize").click(function() {
var $image = $("#image");

View File

@@ -171,15 +171,26 @@
}
Danbooru.Post.initialize_wiki_page_excerpt = function() {
$("#close-wiki-page-excerpt").click(function() {
$("#wiki-page-excerpt").remove();
Danbooru.j_alert("Notice", "You can reenable the wiki excerpt by clearing your cookies.");
if (Danbooru.Cookie.get("hide-wiki-page-excerpt") === "1") {
$("#hide-wiki-page-excerpt").hide();
$("#wiki-page-excerpt-content").hide();
} else {
$("#show-wiki-page-excerpt").hide();
}
$("#hide-wiki-page-excerpt").click(function() {
$("#hide-wiki-page-excerpt").hide();
$("#wiki-page-excerpt-content").hide();
$("#show-wiki-page-excerpt").show();
Danbooru.Cookie.put("hide-wiki-page-excerpt", "1");
});
if (Danbooru.Cookie.get("hide-wiki-page-excerpt") === "1") {
$("#wiki-page-excerpt").remove();
}
$("#show-wiki-page-excerpt").click(function() {
$("#hide-wiki-page-excerpt").show();
$("#wiki-page-excerpt-content").show();
$("#show-wiki-page-excerpt").hide();
Danbooru.Cookie.put("hide-wiki-page-excerpt", "0");
});
}
Danbooru.Post.initialize_post_sections = function() {
@@ -191,8 +202,7 @@
$(e.target).parent("li").addClass("active");
var name = e.target.hash;
$(name).show();
e.stopPropagation();
return false;
e.preventDefault();
});
$("#post-sections li:first-child").addClass("active");

View File

@@ -1,6 +1,6 @@
$(document).ready(function() {
$("footer.nav-links a").click(function(event) {
$("div.users div.new > div").hide();
$(function() {
$("div#c-users div#a-new footer.nav-links a").click(function(event) {
$("div#c-users div#a-new > div").hide();
$(event.target.hash).show();
});

View File

@@ -107,6 +107,10 @@ dt {
font-weight: bold;
}
em {
font-style: italic;
}
h1, h2, h3 {
font-family: Tahoma;
font-weight: bold;
@@ -366,7 +370,7 @@ form.simple_form {
div.input {
margin-bottom: 1em;
input[type=text], input[type=file] {
input[type=text], input[type=file], input[type=password], input[type=email] {
width: 20em;
}
@@ -396,6 +400,7 @@ form.simple_form {
font-weight: normal;
width: auto;
margin-right: 2em;
display: inline;
}
}
}
@@ -478,6 +483,11 @@ div.comments-for-post {
div.author {
width: 20%;
float: left;
h1 {
display: block;
font-size: $h2_size;
}
}
div.content {
@@ -591,14 +601,34 @@ div#c-posts {
div#wiki-page-excerpt {
position: relative;
width: 40em;
padding-right: 1em;
div#hide-or-show-wiki-page-excerpt {
font-size: 1em;
position: absolute;
top: 0;
right: 0;
span {
cursor: pointer;
color: #AAA;
}
span:hover {
color: #333;
}
}
}
span#close-wiki-page-excerpt {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
div#a-show {
menu#post-sections {
font-size: $h3_size;
font-weight: bold;
line-height: 1.25em;
li a {
color: $link_color;
}
}
}
}
@@ -665,8 +695,8 @@ div#sessions {
}
}
h2 {
margin-bottom: 5px;
h1 {
font-size: $h2_size;
}
}
}
@@ -698,8 +728,8 @@ div#c-artists {
/*** Users ***/
div.users {
div.new {
div#c-users {
div#a-new {
max-width: 60em;
p {
@@ -708,9 +738,14 @@ div.users {
li {
margin-left: 1em;
list-style-type: disc;
}
div#account-comparison {
h1 {
font-size: $h2_size;
}
li {
font-size: 0.9em;
line-height: 1.5em;
@@ -879,10 +914,12 @@ div#note-container {
div.note-box {
position: absolute;
border: 1px solid white;
min-width: 100px;
min-height: 100px;
min-width: 20px;
min-height: 20px;
width: 100px;
height: 100px;
cursor: move;
background: #FFE;
background: transparent;
div.note-box-inner-border {
border: 1px solid black;
@@ -893,10 +930,10 @@ div#note-container {
border: 1px solid red;
}
}
div.note-edit-dialog {
font-size: 70%;
}
}
div.note-edit-dialog {
font-size: 70%;
}

View File

@@ -1,6 +1,7 @@
class NotesController < ApplicationController
respond_to :html, :xml, :json
respond_to :html, :xml, :json, :js
before_filter :member_only, :except => [:index, :show]
before_filter :pass_html_id, :only => [:create]
def index
if params[:group_by] == "post"
@@ -17,7 +18,11 @@ class NotesController < ApplicationController
def create
@note = Note.create(params[:note])
respond_with(@note)
respond_with(@note) do |fmt|
fmt.json do
render :json => @note.to_json(:methods => :html_id)
end
end
end
def update
@@ -40,6 +45,12 @@ class NotesController < ApplicationController
end
private
def pass_html_id
if params[:note] && params[:note][:html_id]
response.headers["X-Html-Id"] = params[:note][:html_id]
end
end
def index_by_post
@posts = Post.tag_match(params[:tags]).noted_before(params[:before_date] || Time.now).limit(8)
respond_with(@posts) do |format|

View File

@@ -14,8 +14,7 @@ class Comment < ActiveRecord::Base
scope :hidden, lambda {|user| where("score < ?", user.comment_threshold)}
scope :post_tag_match, lambda {|query| joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query)}
search_method :body_matches
search_method :post_tag_match
search_methods :body_matches, :post_tag_match
def initialize_creator
self.creator_id = CurrentUser.user.id

View File

@@ -1,5 +1,5 @@
class Note < ActiveRecord::Base
attr_accessor :updater_id, :updater_ip_addr
attr_accessor :updater_id, :updater_ip_addr, :html_id
belongs_to :post
belongs_to :creator, :class_name => "User"
belongs_to :updater, :class_name => "User"
@@ -11,10 +11,10 @@ class Note < ActiveRecord::Base
after_save :update_post
after_save :create_version
validate :post_must_not_be_note_locked
attr_accessible :x, :y, :width, :height, :body, :updater_id, :updater_ip_addr, :is_active, :post_id
attr_accessible :x, :y, :width, :height, :body, :updater_id, :updater_ip_addr, :is_active, :post_id, :html_id
scope :active, where("is_active = TRUE")
scope :body_matches, lambda {|query| where("text_index @@ plainto_tsquery(?)", query.scan(/\S+/).join(" & "))}
search_method :body_matches
search_methods :body_matches
def presenter
@presenter ||= NotePresenter.new(self)

View File

@@ -4,7 +4,11 @@
<% end %>
<div class="list-of-comments">
<%= render :partial => "comments/partials/show/comment", :collection => comments %>
<% if comments.empty? %>
<p>There are no comments.</p>
<% else %>
<%= render :partial => "comments/partials/show/comment", :collection => comments %>
<% end %>
</div>
<div class="clearfix"></div>

View File

@@ -1,6 +1,6 @@
<article data-comment-id="<%= comment.id %>">
<div class="author">
<h4><%= link_to comment.creator_name, user_path(comment.creator_id) %></h4>
<h1><%= link_to comment.creator_name, user_path(comment.creator_id) %></h1>
<p>
<%= time_ago_in_words(comment.created_at) %> ago
</p>

View File

@@ -1,2 +1 @@
<%= render :partial => "posts/partials/show/notes", :locals => {:post => post, :notes => post.notes.active} %>
<%= image_tag(post.file_url_for(CurrentUser.user), :alt => post.tag_string, :width => post.image_width_for(CurrentUser.user), :height => post.image_height_for(CurrentUser.user), :id => "image") %>
<%= image_tag(post.file_url_for(CurrentUser.user), :alt => post.tag_string, :width => post.image_width_for(CurrentUser.user), :height => post.image_height_for(CurrentUser.user), :id => "image", "data-width" => post.image_width, "data-height" => post.image_height) %>

View File

@@ -1,3 +1,3 @@
<% notes.each do |note| %>
<%= content_tag(:article, "data-width" => note.width, "data-height" => note.height, "data-x" => note.x, "data-y" => note.y, "data-body" => note.formatted_body) %>
<%= content_tag(:article, "", "data-width" => note.width, "data-height" => note.height, "data-x" => note.x, "data-y" => note.y, "data-body" => note.body) %>
<% end %>

View File

@@ -2,7 +2,7 @@
<%= resize_image_links(post, CurrentUser.user) %>
<li><%= link_to "Favorite", favorite_path(post), :remote => true, :method => :post, :id => "add-to-favorites" %></li>
<li><%= link_to "Unfavorite", favorite_path(post), :remote => true, :method => :delete, :id => "remove-from-favorites" %></li>
<li><%= link_to "Translate", "#", :id => "translate" %></li>
<li><%= link_to "Translate", "#", :id => "translate", :title => "Shortcut is CTRL+N" %></li>
<li><%= link_to "Flag", new_post_flag_path(:post_id => post.id), :id => "flag" %></li>
<li><%= link_to "Appeal", new_post_appeal_path(:post_id => post.id), :id => "appeal" %></li>
<% if CurrentUser.is_janitor? %>

View File

@@ -30,12 +30,9 @@
</aside>
<section id="content">
<h1>Post</h1>
<%= render :partial => "posts/partials/show/notices", :locals => {:post => @post} %>
<section id="image-container">
<h2>Image</h2>
<div id="note-container"></div>
<%= @post.presenter.image_html(self) %>
</section>
@@ -47,17 +44,14 @@
</menu>
<section id="comments">
<h2>Comments</h2>
<%= render :partial => "comments/partials/index/list", :locals => {:comments => @post.comments, :post => @post, :show_header => false} %>
</section>
<section id="notes">
<h2>Notes</h2>
<%= render :partial => "notes/note", :collection => @post.notes.active %>
</section>
<section id="edit">
<h2>Edit</h2>
<%= render :partial => "posts/partials/show/edit", :locals => {:post => @post} %>
</section>
</section>

View File

@@ -1,36 +1,28 @@
<div id="sessions">
<div id="new">
<section>
<h3>Sign In</h3>
<%= form_tag(session_path) do %>
<h1>Login</h1>
<%= form_tag(session_path, :class => "simple_form") do %>
<%= hidden_field_tag "url", params[:url] %>
<table width="100%">
<tfoot>
<tr>
<td></td>
<td><%= submit_tag "Login" %></td>
</tr>
</tfoot>
<tbody>
<tr>
<th width="15%">
<%= label_tag :name %>
</th>
<td width="85%">
<%= text_field_tag :name %>
</td>
</tr>
<tr>
<th><%= label_tag :password %></th>
<td><%= password_field_tag :password %></td>
</tr>
</tbody>
</table>
<div class="input">
<label for="name">Name</label>
<%= text_field_tag :name %>
</div>
<div class="input">
<label for="password">Password</label>
<%= password_field_tag :password %>
</div>
<div class="input">
<%= submit_tag "Submit" %>
</div>
<% end %>
</section>
<aside>
<h3>Help</h3>
<h1>Help</h1>
<ul>
<li><%= link_to "I don't have an account", new_user_path %></li>
<li><%= link_to "I forgot my password", reset_password_path %></li>
@@ -41,5 +33,5 @@
</div>
<% content_for(:page_title) do %>
/sign in
/login
<% end %>

View File

@@ -1,6 +1,6 @@
<div class="users">
<div class="new">
<h3>Registration</h3>
<div id="c-users">
<div id="a-new">
<h1>Registration</h1>
<div id="p1">
<p><%= Danbooru.config.app_name %> is ad-sponsored and does not require an account to view. But in order to start uploading, editing, or creating content on this site, you will need to register. <em>Make sure you read and agree to the <%= link_to "terms of service", terms_of_service_path %> before registering. <strong>This site is open to web crawlers, therefore any name you choose will be public!</strong></em></p>
@@ -64,33 +64,14 @@
</li>
</ul>
<% form_for(@user) do |f| %>
<%= simple_form_for(@user) do |f| %>
<%= error_messages_for("user") %>
<table width="100%">
<tbody>
<tr>
<th width="15%"><%= f.label :name %></th>
<td width="85%"><%= f.text_field :name %></td>
</tr>
<tr>
<th><%= f.label :password %></th>
<td><%= f.password_field :password %></td>
</tr>
<tr>
<th><%= f.label :password_confirmation %></th>
<td><%= f.password_field :password_confirmation %></td>
</tr>
<tr>
<th><%= f.label :email %></th>
<td><%= f.text_field :email %></td>
</tr>
<tr>
<td></td>
<td><%= submit_tag "Submit" %></td>
</tr>
</tbody>
</table>
<%= f.input :name %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.input :email %>
<%= f.button :submit %>
<% end %>
<footer class="nav-links">
@@ -100,3 +81,6 @@
</div>
</div>
<% content_for(:page_title) do %>
/users/signup
<% end %>

View File

@@ -4,16 +4,22 @@
-->
<div id="wiki-page-excerpt">
<span class="ui-icon ui-icon-closethick" id="close-wiki-page-excerpt"></span>
<h1>Wiki</h1>
<div id="hide-or-show-wiki-page-excerpt">
<span id="hide-wiki-page-excerpt">(hide)</span>
<span id="show-wiki-page-excerpt">(show)</span>
</div>
<% if wiki_page %>
<div id="wiki-page-excerpt" class="prose">
<%= format_text(wiki_page.presenter.excerpt) %>
<div id="wiki-page-excerpt-content">
<% if wiki_page %>
<div class="prose">
<%= format_text(wiki_page.presenter.excerpt) %>
<p>Read the <%= link_to "full article", wiki_page_path(wiki_page.id) %>.</p>
</div>
<% else %>
<p>There is currently no wiki page for the tag "<%= tag %>". You can <%= link_to "create one", new_wiki_page_path(:wiki_page => {:title => tag}) %>.</p>
<% end %>
<p>Read the <%= link_to "full article", wiki_page_path(wiki_page.id) %>.</p>
</div>
<% else %>
<p>There is currently no wiki page for the tag "<%= tag %>". You can <%= link_to "create one", new_wiki_page_path(:wiki_page => {:title => tag}) %>.</p>
<% end %>
</div>
</div>