implement saved searches, move user boolean settings to bitprefs
This commit is contained in:
@@ -497,6 +497,13 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Danbooru.Post.save_search = function() {
|
||||
$.post(
|
||||
"/saved_searches.js",
|
||||
{"saved_search[tag_query]": $("#tags").val()}
|
||||
);
|
||||
}
|
||||
})();
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -18,6 +18,10 @@ article.post-preview {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#saved-searches-nav {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
a.blacklisted-active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
33
app/controllers/saved_searches_controller.rb
Normal file
33
app/controllers/saved_searches_controller.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
class SavedSearchesController < ApplicationController
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@saved_searches = saved_searches.order("name")
|
||||
end
|
||||
|
||||
def create
|
||||
@saved_search = saved_searches.create(:tag_query => params[:tags])
|
||||
end
|
||||
|
||||
def destroy
|
||||
@saved_search = saved_searches.find(params[:id])
|
||||
@saved_search.destroy
|
||||
end
|
||||
|
||||
def edit
|
||||
@saved_search = saved_searches.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@saved_search = saved_searches.find(params[:id])
|
||||
@saved_search.update_attributes(params[:saved_search])
|
||||
flash[:notice] = "Saved search updated"
|
||||
respond_with(@saved_search, :location => saved_searches_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def saved_searches
|
||||
CurrentUser.user.saved_searches
|
||||
end
|
||||
end
|
||||
@@ -209,6 +209,18 @@ class AnonymousUser
|
||||
false
|
||||
end
|
||||
|
||||
def saved_searches
|
||||
[]
|
||||
end
|
||||
|
||||
def has_saved_searches?
|
||||
false
|
||||
end
|
||||
|
||||
def show_saved_searches?
|
||||
false
|
||||
end
|
||||
|
||||
%w(member banned gold builder platinum contributor janitor moderator admin).each do |name|
|
||||
define_method("is_#{name}?") do
|
||||
false
|
||||
|
||||
31
app/models/saved_search.rb
Normal file
31
app/models/saved_search.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
class SavedSearch < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
validates :tag_query, :presence => true
|
||||
validate :validate_count
|
||||
attr_accessible :tag_query, :category
|
||||
before_create :update_user_on_create
|
||||
after_destroy :update_user_on_destroy
|
||||
validates_uniqueness_of :tag_query, :scope => :user_id
|
||||
|
||||
def self.tagged(tags)
|
||||
where(:tag_query => tags).first
|
||||
end
|
||||
|
||||
def validate_count
|
||||
if user.saved_searches.count + 1 > user.max_saved_searches
|
||||
self.errors[:user] << "can only have up to #{user.max_saved_searches} " + "saved search".pluralize(user.max_saved_searches)
|
||||
end
|
||||
end
|
||||
|
||||
def update_user_on_create
|
||||
if !user.has_saved_searches?
|
||||
user.update_attribute(:has_saved_searches, true)
|
||||
end
|
||||
end
|
||||
|
||||
def update_user_on_destroy
|
||||
if user.saved_searches.count == 0
|
||||
user.update_attribute(:has_saved_searches, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,6 +16,22 @@ class User < ActiveRecord::Base
|
||||
ADMIN = 50
|
||||
end
|
||||
|
||||
BOOLEAN_ATTRIBUTES = {
|
||||
:is_banned => 0x0001,
|
||||
:has_mail => 0x0002,
|
||||
:receive_email_notifications => 0x0004,
|
||||
:always_resize_images => 0x0008,
|
||||
:enable_post_navigation => 0x0010,
|
||||
:new_post_navigation_layout => 0x0020,
|
||||
:enable_privacy_mode => 0x0040,
|
||||
:enable_sequential_post_navigation => 0x0080,
|
||||
:hide_deleted_posts => 0x0100,
|
||||
:style_usernames => 0x0200,
|
||||
:enable_auto_complete => 0x0400,
|
||||
:show_deleted_children => 0x0800,
|
||||
:has_saved_searches => 0x1000
|
||||
}
|
||||
|
||||
attr_accessor :password, :old_password
|
||||
attr_accessible :enable_privacy_mode, :enable_post_navigation, :new_post_navigation_layout, :password, :old_password, :password_confirmation, :password_hash, :email, :last_logged_in_at, :last_forum_read_at, :has_mail, :receive_email_notifications, :comment_threshold, :always_resize_images, :favorite_tags, :blacklisted_tags, :name, :ip_addr, :time_zone, :default_image_size, :enable_sequential_post_navigation, :per_page, :hide_deleted_posts, :style_usernames, :enable_auto_complete, :custom_style, :show_deleted_children, :as => [:moderator, :janitor, :contributor, :gold, :member, :anonymous, :default, :builder, :admin]
|
||||
attr_accessible :level, :as => :admin
|
||||
@@ -45,6 +61,7 @@ class User < ActiveRecord::Base
|
||||
has_many :subscriptions, lambda {order("tag_subscriptions.name")}, :class_name => "TagSubscription", :foreign_key => "creator_id"
|
||||
has_many :note_versions, :foreign_key => "updater_id"
|
||||
has_many :dmails, lambda {order("dmails.id desc")}, :foreign_key => "owner_id"
|
||||
has_many :saved_searches
|
||||
belongs_to :inviter, :class_name => "User"
|
||||
after_update :create_mod_action
|
||||
|
||||
@@ -417,6 +434,20 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
module LimitMethods
|
||||
def max_saved_searches
|
||||
if is_platinum?
|
||||
1_000
|
||||
elsif is_gold?
|
||||
200
|
||||
else
|
||||
100
|
||||
end
|
||||
end
|
||||
|
||||
def show_saved_searches?
|
||||
id < 1_000
|
||||
end
|
||||
|
||||
def can_upload?
|
||||
if is_contributor?
|
||||
true
|
||||
@@ -703,6 +734,24 @@ class User < ActiveRecord::Base
|
||||
include CountMethods
|
||||
extend SearchMethods
|
||||
|
||||
BOOLEAN_ATTRIBUTES.each do |boolean_attribute, bit_flag|
|
||||
define_method(boolean_attribute) do
|
||||
bit_prefs & bit_flag > 0
|
||||
end
|
||||
|
||||
define_method("#{boolean_attribute}?") do
|
||||
bit_prefs & bit_flag > 0
|
||||
end
|
||||
|
||||
define_method("#{boolean_attribute}=") do |val|
|
||||
if val.to_s =~ /t|1|y/
|
||||
self.bit_prefs = bit_prefs | bit_flag
|
||||
else
|
||||
self.bit_prefs = bit_prefs - bit_flag
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_default_image_size
|
||||
self.default_image_size = "large"
|
||||
end
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<li><%= link_to "Hot", posts_path(:tags => "order:rank") %></li>
|
||||
<% unless CurrentUser.is_anonymous? %>
|
||||
<li><%= link_to "Favorites", favorites_path %></li>
|
||||
<% if CurrentUser.user.has_saved_searches? %>
|
||||
<li><%= link_to "Saved searches", saved_searches_path %></li>
|
||||
<% end %>
|
||||
<li><%= link_to "Subscriptions", posts_path(:tags => "sub:#{CurrentUser.name}") %></li>
|
||||
<% end %>
|
||||
<li class="nonessential"><%= link_to "Changes", post_versions_path %></li>
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<div id="posts">
|
||||
<%= post_set.presenter.post_previews_html(self) %>
|
||||
<div style="overflow: hidden;">
|
||||
<%= post_set.presenter.post_previews_html(self) %>
|
||||
</div>
|
||||
|
||||
<% if params[:tags] %>
|
||||
<div id="saved-searches-nav">
|
||||
<%= render "saved_searches/interface", :saved_searches => CurrentUser.user.saved_searches %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= numbered_paginator(post_set.posts) %>
|
||||
</div>
|
||||
|
||||
9
app/views/saved_searches/_interface.html.erb
Normal file
9
app/views/saved_searches/_interface.html.erb
Normal file
@@ -0,0 +1,9 @@
|
||||
<% if CurrentUser.user.show_saved_searches? %>
|
||||
|
||||
<% if CurrentUser.user.has_saved_searches? && saved_searches.tagged(params[:tags]) %>
|
||||
<%= button_to "Remove this saved search", saved_search_path(saved_searches.tagged(params[:tags]), :tags => params[:tags]), :remote => true, :method => :delete %>
|
||||
<% elsif CurrentUser.user.is_member? %>
|
||||
<%= button_to "Save this search", saved_searches_path(:tags => params[:tags]), :remote => true, :method => :post %>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
6
app/views/saved_searches/create.js.erb
Normal file
6
app/views/saved_searches/create.js.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<% if @saved_search.errors.any? %>
|
||||
Danbooru.error("<%= j @saved_search.errors.full_messages.join(', ') %>");
|
||||
<% else %>
|
||||
Danbooru.notice("Search '<%= j @saved_search.tag_query %>' was saved");
|
||||
$("#saved-searches-nav").html("<%= j render('saved_searches/interface', :saved_searches => CurrentUser.user.saved_searches) %>");
|
||||
<% end %>
|
||||
3
app/views/saved_searches/destroy.js.erb
Normal file
3
app/views/saved_searches/destroy.js.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
Danbooru.notice("Search '<%= j @saved_search.tag_query %>' was deleted");
|
||||
$("#saved-searches-nav").html("<%= j render('saved_searches/interface', :saved_searches => CurrentUser.user.saved_searches) %>");
|
||||
$("#saved-search-<%= @saved_search.id %>").remove();
|
||||
19
app/views/saved_searches/edit.html.erb
Normal file
19
app/views/saved_searches/edit.html.erb
Normal file
@@ -0,0 +1,19 @@
|
||||
<div id="c-saved-searches">
|
||||
<div id="a-edit">
|
||||
<h1>Edit Saved Search</h1>
|
||||
|
||||
<%= error_messages_for :saved_search %>
|
||||
|
||||
<%= simple_form_for(@saved_search) do |f| %>
|
||||
<%= f.input :tag_query %>
|
||||
<%= f.input :category %>
|
||||
<%= f.button :submit %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "users/secondary_links" %>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
Edit Saved Search - <%= Danbooru.config.app_name %>
|
||||
<% end %>
|
||||
34
app/views/saved_searches/index.html.erb
Normal file
34
app/views/saved_searches/index.html.erb
Normal file
@@ -0,0 +1,34 @@
|
||||
<div id="c-saved-searches">
|
||||
<div id="a-index">
|
||||
<h1>Saved Searches</h1>
|
||||
|
||||
<table class="striped" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="80%">Tags</th>
|
||||
<th width="10%">Category</th>
|
||||
<th width="10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @saved_searches.each do |saved_search| %>
|
||||
<tr id="saved-search-<%= saved_search.id %>">
|
||||
<td><%= link_to saved_search.tag_query, posts_path(:tags => saved_search.tag_query) %></td>
|
||||
<td><%= saved_search.category %></td>
|
||||
<td>
|
||||
<%= link_to "edit", edit_saved_search_path(saved_search) %> |
|
||||
<%= link_to "delete", saved_search_path(saved_search), :method => :delete, :remote => true %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "users/secondary_links" %>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
Saved Searches - <%= Danbooru.config.app_name %>
|
||||
<% end %>
|
||||
@@ -30,8 +30,11 @@
|
||||
</div>
|
||||
|
||||
<%= f.input :time_zone, :include_blank => false %>
|
||||
<%= f.input :receive_email_notifications, :as => :select, :include_blank => false %>
|
||||
|
||||
<%= f.input :receive_email_notifications, :as => :select, :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :comment_threshold, :hint => "Comments below this score will be hidden by default" %>
|
||||
|
||||
<%= f.input :default_image_size, :hint => "Show original image or show resized #{Danbooru.config.large_image_width} pixel version", :label => "Default image width", :collection => [["850px", "large"], ["original", "original"]], :include_blank => false %>
|
||||
|
||||
<% if CurrentUser.user.is_gold? %>
|
||||
@@ -43,23 +46,33 @@
|
||||
|
||||
<fieldset id="advanced-settings-section">
|
||||
<%= f.input :style_usernames, :as => :select, :label => "Colored usernames", :hint => "Color each user's name depending on their level", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
<%= f.input :always_resize_images, :as => :select, :include_blank => false, :label => "Fit images to window", :hint => "Use JavaScript to resize images to fit window" %>
|
||||
<%= f.input :enable_post_navigation, :as => :select, :include_blank => false, :label => "Enable keyboard shortcuts" %>
|
||||
<%= f.input :enable_sequential_post_navigation, :as => :select, :label => "Enable slideshow mode", :hint => "Show prev/next links when viewing a post", :include_blank => false %>
|
||||
|
||||
<%= f.input :always_resize_images, :as => :select, :include_blank => false, :label => "Fit images to window", :hint => "Use JavaScript to resize images to fit window", :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :enable_post_navigation, :as => :select, :include_blank => false, :label => "Enable keyboard shortcuts", :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :enable_sequential_post_navigation, :as => :select, :label => "Enable slideshow mode", :hint => "Show prev/next links when viewing a post", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :new_post_navigation_layout, :as => :select, :label => "Navigation bar position", :include_blank => false, :collection => [["Below", "true"], ["Above", "false"]], :hint => "When browsing pools or slideshows, place navigation links above or below the image" %>
|
||||
|
||||
<%= f.input :hide_deleted_posts, :as => :select, :label => "Deleted post filter", :hint => "Remove deleted posts from search results", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :show_deleted_children, :as => :select, :label => "Show deleted children", :hint => "Indicate that a post has children even if the children are deleted", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
||||
|
||||
<%= f.input :enable_auto_complete, :as => :select, :collection => [["Yes", "true"], ["No", "false"]], :include_blank => false %>
|
||||
|
||||
<div class="input text optional field_with_hint">
|
||||
<label class="text optional" for="user_favorite_tags">Frequent tags</label>
|
||||
<textarea id="user_favorite_tags" class="text optional" rows="5" name="user[favorite_tags]" cols="40"><%= raw @user.favorite_tags %></textarea>
|
||||
<span class="hint">A list of tags that you use often. They will appear when using the list of Related Tags.</span>
|
||||
</div>
|
||||
|
||||
<%= f.input :custom_style, :label => "Custom <a href='http://en.wikipedia.org/wiki/Cascading_Style_Sheets'>CSS</a> style".html_safe, :hint => "Style to apply to the whole site.", :input_html => {:size => "40x5"} %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="change-password-section">
|
||||
<%= f.input :password, :hint => "Leave blank if you don't want to change your password", :label => "New password", :input_html => {:autocomplete => "off"} %>
|
||||
|
||||
<%= f.input :old_password, :as => :password, :input_html => {:autocomplete => "off"} %>
|
||||
</fieldset>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user