Some gross optimization of the post index display

This commit is contained in:
Kira 2020-01-23 07:39:59 -08:00
parent 316a3b1d3a
commit 26ff2efae5
3 changed files with 174 additions and 2 deletions

View File

@ -11,7 +11,7 @@ class PostsController < ApplicationController
end
else
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], raw: params[:raw], random: params[:random], format: params[:format], read_only: params[:ro])
@posts = @post_set.posts
@posts = PostsDecorator.decorate_collection(@post_set.posts)
respond_with(@posts) do |format|
format.atom
end

View File

@ -0,0 +1,166 @@
class PostsDecorator < ApplicationDecorator
def self.collection_decorator_class
PaginatedDecorator
end
delegate_all
def preview_class(options)
post = object
klass = ["post-preview", "captioned"]
# Always captioned with new post stats section.
# klass << "captioned" if pool || size || similarity
klass << "post-status-pending" if post.is_pending?
klass << "post-status-flagged" if post.is_flagged?
klass << "post-status-deleted" if post.is_deleted?
klass << "post-status-has-parent" if post.parent_id
klass << "post-status-has-children" if post.has_visible_children?
klass << "post-pos-score" if post.score >= 3
klass << "post-neg-score" if post.score <= -3
klass << "post-rating-safe" if post.rating == 's'
klass << "post-rating-questionable" if post.rating == 'q'
klass << "post-rating-explicit" if post.rating == 'e'
klass << "post-no-blacklist" if options[:no_blacklist]
klass
end
def data_attributes
post = object
attributes = {
"data-id" => post.id,
"data-has-sound" => post.has_tag?('video_with_sound|flash_with_sound'),
"data-tags" => post.tag_string,
"data-rating" => post.rating,
"data-flags" => post.status_flags,
"data-uploader-id" => post.uploader_id,
"data-uploader" => post.uploader_name
}
if post.visible?
attributes["data-file-url"] = post.file_url
attributes["data-large-file-url"] = post.large_file_url
attributes["data-preview-file-url"] = post.preview_file_url
end
attributes
end
def cropped_url(options)
cropped_url = if Danbooru.config.enable_image_cropping && options[:show_cropped] && object.has_cropped? && !CurrentUser.user.disable_cropped_thumbnails?
object.crop_file_url
else
object.preview_file_url
end
cropped_url = Danbooru.config.deleted_preview_url if object.deleteblocked?
cropped_url
end
def score_class(score)
return 'score-neutral' if score == 0
score > 0 ? 'score-positive' : 'score-negative'
end
def stats_section(t)
post = object
status_flags = []
status_flags << 'P' if post.parent_id
status_flags << 'C' if post.has_children?
status_flags << 'U' if post.is_pending?
status_flags << 'F' if post.is_flagged?
post_score_icon = "#{"&uarr;" if post.score > 0}#{"&darr;" if post.score < 0}#{"&varr;" if post.score == 0}"
score = t.tag.span("#{post_score_icon}#{post.score}".html_safe, class: "post-score-score " + score_class(post.score))
favs = t.tag.span("&hearts;#{post.fav_count}".html_safe, class: 'post-score-faves')
comments = t.tag.span "C#{post.comment_count}", class: 'post-score-comments'
rating = t.tag.span(post.rating.upcase, class: "post-score-rating")
status = t.tag.span(status_flags.join(''), class: 'post-score-extras')
t.tag.div score + favs + comments + rating + status, class: 'post-score', id: "post-score-#{post.id}"
end
def preview_html(t, options = {})
post = object
if post.nil?
return "<em>none</em>".html_safe
end
if !options[:show_deleted] && post.is_deleted? && options[:tags] !~ /(?:status:(?:all|any|deleted))|(?:deletedby:)|(?:delreason:)/ && !options[:raw]
return ""
end
if post.loginblocked? || post.safeblocked?
return ""
end
if post.is_ugoira? && !post.has_ugoira_webm?
# ugoira preview gen is async so dont render it immediately
return ""
end
options[:stats] |= !options[:avatar] && !options[:inline]
article_attrs = {
"id" => "post_#{post.id}",
"class" => preview_class(options).join(" ")
}.merge(data_attributes)
link_target = options[:link_target] || post
link_params = {}
if options[:tags].present?
link_params["q"] = options[:tags]
end
if options[:pool_id]
link_params["pool_id"] = options[:pool_id]
end
if options[:post_set_id]
link_params["post_set_id"] = options[:post_set_id]
end
tooltip = "Rating: #{post.rating}\nID: #{post.id}\nDate: #{post.created_at}\nStatus: #{post.status}\nScore: #{post.score}\n\n#{post.tag_string}"
cropped_url = if Danbooru.config.enable_image_cropping && options[:show_cropped] && post.has_cropped? && !CurrentUser.user.disable_cropped_thumbnails?
post.crop_file_url
else
post.preview_file_url
end
cropped_url = Danbooru.config.deleted_preview_url if post.deleteblocked?
preview_url = if post.deleteblocked?
Danbooru.config.deleted_preview_url
else
post.preview_file_url
end
alt_text = post.tag_string
has_cropped = post.has_cropped?
pool = options[:pool]
width = post.image_width
height = post.image_height
similarity = options[:similarity]&.round
size = options[:size] ? post.file_size : nil
img_contents = t.link_to t.polymorphic_path(link_target, link_params) do
t.content_tag(:picture) do
t.concat t.tag.source media: "(max-width: 800px)", srcset: cropped_url
t.concat t.tag.source media: "(min-width: 800px)", srcset: preview_url
t.concat t.tag.img class: "has-cropped-#{has_cropped}", src: preview_url, title: tooltip, alt: alt_text
end
end
desc_contents = if options[:stats] || pool || similarity || size
t.tag.div class: "desc" do
stats_section(t) if options[:stats]
end
else
"".html_safe
end
t.content_tag(:article, nil, article_attrs) do
img_contents + desc_contents
end
end
end

View File

@ -1,6 +1,12 @@
<div id="posts" class="user-disable-cropped-<%= Danbooru.config.enable_image_cropping && CurrentUser.user.disable_cropped_thumbnails? %>">
<div id="posts-container">
<%= post_set.presenter.post_previews_html(self) %>
<% if @posts.empty? %>
<%= render "posts/blank" %>
<% else %>
<% @posts.each do |post| %>
<%= post.preview_html(self, {tags: @post_set.public_tag_string, raw: @post_set.raw, show_cropped: true}) %>
<% end %>
<% end %>
</div>
<% if post_set.hidden_posts.present? %>