votes: show votes when hovering over post score.
Make it so you can hover over a post's score to see the list of public upvotes. Also show the upvote count, the downvote count, and the upvote ratio.
This commit is contained in:
@@ -7,7 +7,9 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<span class="post-score"><%= post.score %></span>
|
<span class="post-score">
|
||||||
|
<%= link_to post.score, post_votes_path(search: { post_id: post.id }, variant: :compact) %>
|
||||||
|
</span>
|
||||||
|
|
||||||
<% if can_vote? %>
|
<% if can_vote? %>
|
||||||
<% if downvoted? %>
|
<% if downvoted? %>
|
||||||
|
|||||||
@@ -6,5 +6,11 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
min-width: 1.25em;
|
min-width: 1.25em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-color);
|
||||||
|
&:hover { text-decoration: underline; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
app/components/post_votes_tooltip_component.rb
Normal file
34
app/components/post_votes_tooltip_component.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This component represents the tooltip that displays when you hover over a post's score.
|
||||||
|
class PostVotesTooltipComponent < ApplicationComponent
|
||||||
|
attr_reader :post, :current_user
|
||||||
|
delegate :upvote_icon, :downvote_icon, to: :helpers
|
||||||
|
|
||||||
|
def initialize(post:, current_user:)
|
||||||
|
super
|
||||||
|
@post = post
|
||||||
|
@current_user = current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def votes
|
||||||
|
@post.votes.includes(:user).order(id: :desc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def vote_icon(vote)
|
||||||
|
vote.is_positive? ? upvote_icon : downvote_icon
|
||||||
|
end
|
||||||
|
|
||||||
|
def upvote_ratio
|
||||||
|
return nil if votes.length == 0
|
||||||
|
sprintf("(%.1f%%)", 100.0 * votes.select(&:is_positive?).length / votes.length)
|
||||||
|
end
|
||||||
|
|
||||||
|
def voter_name(vote)
|
||||||
|
if policy(vote).can_see_voter?
|
||||||
|
link_to_user(vote.user, classes: "align-middle")
|
||||||
|
else
|
||||||
|
tag.i("hidden", class: "align-middle")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="post-votes-tooltip thin-scrollbar">
|
||||||
|
<div class="text-center text-muted">
|
||||||
|
+<%= post.up_score %> / <%= post.down_score %> <%= upvote_ratio %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-voters">
|
||||||
|
<% votes.each do |vote| %>
|
||||||
|
<div class="post-voter truncate">
|
||||||
|
<%= vote_icon(vote) %> <%= voter_name(vote) %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import Utility from "../../javascript/src/javascripts/utility.js";
|
||||||
|
import { delegate, hideAll } from 'tippy.js';
|
||||||
|
import 'tippy.js/dist/tippy.css';
|
||||||
|
|
||||||
|
class PostVotesTooltipComponent {
|
||||||
|
// Trigger on the post score link; see PostVotesComponent.
|
||||||
|
static TARGET_SELECTOR = "span.post-votes span.post-score a";
|
||||||
|
static SHOW_DELAY = 125;
|
||||||
|
static HIDE_DELAY = 125;
|
||||||
|
static DURATION = 250;
|
||||||
|
static instance = null;
|
||||||
|
|
||||||
|
static initialize() {
|
||||||
|
if ($(PostVotesTooltipComponent.TARGET_SELECTOR).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PostVotesTooltipComponent.instance = delegate("body", {
|
||||||
|
allowHTML: true,
|
||||||
|
appendTo: document.querySelector("#post-votes-tooltips"),
|
||||||
|
delay: [PostVotesTooltipComponent.SHOW_DELAY, PostVotesTooltipComponent.HIDE_DELAY],
|
||||||
|
duration: PostVotesTooltipComponent.DURATION,
|
||||||
|
interactive: true,
|
||||||
|
maxWidth: "none",
|
||||||
|
target: PostVotesTooltipComponent.TARGET_SELECTOR,
|
||||||
|
theme: "common-tooltip",
|
||||||
|
touch: false,
|
||||||
|
|
||||||
|
onShow: PostVotesTooltipComponent.onShow,
|
||||||
|
onHide: PostVotesTooltipComponent.onHide,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async onShow(instance) {
|
||||||
|
let $target = $(instance.reference);
|
||||||
|
let $tooltip = $(instance.popper);
|
||||||
|
let postId = $target.parents("[data-id]").data("id");
|
||||||
|
|
||||||
|
hideAll({ exclude: instance });
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tooltip.addClass("tooltip-loading");
|
||||||
|
|
||||||
|
instance._request = $.get(`/post_votes?search[post_id]=${postId}`, { variant: "tooltip" });
|
||||||
|
let html = await instance._request;
|
||||||
|
instance.setContent(html);
|
||||||
|
|
||||||
|
$tooltip.removeClass("tooltip-loading");
|
||||||
|
} catch (error) {
|
||||||
|
if (error.status !== 0 && error.statusText !== "abort") {
|
||||||
|
Utility.error(`Error displaying votes for post #${postId} (error: ${error.status} ${error.statusText})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async onHide(instance) {
|
||||||
|
if (instance._request?.state() === "pending") {
|
||||||
|
instance._request.abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(PostVotesTooltipComponent.initialize);
|
||||||
|
|
||||||
|
export default PostVotesTooltipComponent;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.post-votes-tooltip {
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
max-height: 240px;
|
||||||
|
|
||||||
|
.upvote-icon {
|
||||||
|
color: var(--post-upvote-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.downvote-icon {
|
||||||
|
color: var(--post-downvote-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-voter {
|
||||||
|
max-width: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ class PostVotesController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
@post_votes = authorize PostVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
|
@post_votes = authorize PostVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
|
||||||
@post_votes = @post_votes.includes(:user, post: [:uploader, :media_asset]) if request.format.html?
|
@post_votes = @post_votes.includes(:user, post: [:uploader, :media_asset]) if request.format.html?
|
||||||
|
@post = Post.find(params.dig(:search, :post_id)) if params.dig(:search, :post_id).present?
|
||||||
|
|
||||||
respond_with(@post_votes)
|
respond_with(@post_votes)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -193,10 +193,10 @@ module ApplicationHelper
|
|||||||
to_sentence(links, **options)
|
to_sentence(links, **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_user(user, text = nil)
|
def link_to_user(user, text = nil, classes: nil, **options)
|
||||||
return "anonymous" if user.blank?
|
return "anonymous" if user.blank?
|
||||||
|
|
||||||
user_class = "user user-#{user.level_string.downcase}"
|
user_class = "user user-#{user.level_string.downcase} #{classes}"
|
||||||
user_class += " user-post-approver" if user.can_approve_posts?
|
user_class += " user-post-approver" if user.can_approve_posts?
|
||||||
user_class += " user-post-uploader" if user.can_upload_free?
|
user_class += " user-post-uploader" if user.can_upload_free?
|
||||||
user_class += " user-banned" if user.is_banned?
|
user_class += " user-banned" if user.is_banned?
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ module ComponentsHelper
|
|||||||
render PostVotesComponent.new(post: post, **options)
|
render PostVotesComponent.new(post: post, **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_post_votes_tooltip(post, **options)
|
||||||
|
render PostVotesTooltipComponent.new(post: post, **options)
|
||||||
|
end
|
||||||
|
|
||||||
def render_post_navbar(post, **options)
|
def render_post_navbar(post, **options)
|
||||||
render PostNavbarComponent.new(post: post, **options)
|
render PostNavbarComponent.new(post: post, **options)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import PopupMenuComponent from "../../components/popup_menu_component/popup_menu
|
|||||||
import Post from "../src/javascripts/posts.js";
|
import Post from "../src/javascripts/posts.js";
|
||||||
import PostModeMenu from "../src/javascripts/post_mode_menu.js";
|
import PostModeMenu from "../src/javascripts/post_mode_menu.js";
|
||||||
import PostTooltip from "../src/javascripts/post_tooltips.js";
|
import PostTooltip from "../src/javascripts/post_tooltips.js";
|
||||||
|
import PostVotesTooltipComponent from "../../components/post_votes_tooltip_component/post_votes_tooltip_component.js";
|
||||||
import RelatedTag from "../src/javascripts/related_tag.js";
|
import RelatedTag from "../src/javascripts/related_tag.js";
|
||||||
import Shortcuts from "../src/javascripts/shortcuts.js";
|
import Shortcuts from "../src/javascripts/shortcuts.js";
|
||||||
import TagCounter from "../src/javascripts/tag_counter.js";
|
import TagCounter from "../src/javascripts/tag_counter.js";
|
||||||
@@ -64,6 +65,7 @@ Danbooru.PopupMenuComponent = PopupMenuComponent;
|
|||||||
Danbooru.Post = Post;
|
Danbooru.Post = Post;
|
||||||
Danbooru.PostModeMenu = PostModeMenu;
|
Danbooru.PostModeMenu = PostModeMenu;
|
||||||
Danbooru.PostTooltip = PostTooltip;
|
Danbooru.PostTooltip = PostTooltip;
|
||||||
|
Danbooru.PostVotesTooltipComponent = PostVotesTooltipComponent;
|
||||||
Danbooru.RelatedTag = RelatedTag;
|
Danbooru.RelatedTag = RelatedTag;
|
||||||
Danbooru.Shortcuts = Shortcuts;
|
Danbooru.Shortcuts = Shortcuts;
|
||||||
Danbooru.TagCounter = TagCounter;
|
Danbooru.TagCounter = TagCounter;
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ html {
|
|||||||
--post-artist-commentary-container-background: var(--grey-0);
|
--post-artist-commentary-container-background: var(--grey-0);
|
||||||
--post-artist-commentary-container-border-color: var(--grey-1);
|
--post-artist-commentary-container-border-color: var(--grey-1);
|
||||||
|
|
||||||
|
--post-upvote-color: var(--link-color);
|
||||||
|
--post-downvote-color: var(--red-5);
|
||||||
|
|
||||||
--note-body-background: #FFE;
|
--note-body-background: #FFE;
|
||||||
--note-body-text-color: var(--black);
|
--note-body-text-color: var(--black);
|
||||||
--note-body-border-color: var(--black);
|
--note-body-border-color: var(--black);
|
||||||
@@ -418,6 +421,9 @@ body[data-current-user-theme="dark"] {
|
|||||||
--post-artist-commentary-container-background: var(--grey-8);
|
--post-artist-commentary-container-background: var(--grey-8);
|
||||||
--post-artist-commentary-container-border-color: var(--grey-7);
|
--post-artist-commentary-container-border-color: var(--grey-7);
|
||||||
|
|
||||||
|
--post-upvote-color: var(--link-color);
|
||||||
|
--post-downvote-color: var(--red-4);
|
||||||
|
|
||||||
--unsaved-note-box-border-color: var(--red-5);
|
--unsaved-note-box-border-color: var(--red-5);
|
||||||
--movable-note-box-border-color: var(--blue-5);
|
--movable-note-box-border-color: var(--blue-5);
|
||||||
--note-preview-border-color: var(--red-5);
|
--note-preview-border-color: var(--red-5);
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.text-xs { font-size: var(--text-xs); }
|
.text-xs { font-size: var(--text-xs); }
|
||||||
.text-sm { font-size: var(--text-sm); }
|
.text-sm { font-size: var(--text-sm); }
|
||||||
|
|
||||||
|
.truncate {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.leading-none { line-height: 1; }
|
.leading-none { line-height: 1; }
|
||||||
|
|
||||||
.absolute { position: absolute; }
|
.absolute { position: absolute; }
|
||||||
@@ -52,6 +58,9 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.p-0\.5 { padding: 0.5 * $spacer; }
|
.p-0\.5 { padding: 0.5 * $spacer; }
|
||||||
.p-4 { padding: 4 * $spacer; }
|
.p-4 { padding: 4 * $spacer; }
|
||||||
|
|
||||||
|
.pr-2 { padding-right: 2 * $spacer; }
|
||||||
|
.pr-4 { padding-right: 4 * $spacer; }
|
||||||
|
|
||||||
.w-1\/4 { width: 25%; }
|
.w-1\/4 { width: 25%; }
|
||||||
.w-full { width: 100%; }
|
.w-full { width: 100%; }
|
||||||
|
|
||||||
@@ -73,6 +82,60 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.items-center { align-items: center; }
|
.items-center { align-items: center; }
|
||||||
.justify-center { justify-content: center; }
|
.justify-center { justify-content: center; }
|
||||||
|
|
||||||
|
.thin-scrollbar {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 2 * $spacer;
|
||||||
|
overscroll-behavior: contain; // https://caniuse.com/css-overscroll-behavior
|
||||||
|
|
||||||
|
// Firefox only
|
||||||
|
// https://caniuse.com/?search=scrollbar-width
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-width
|
||||||
|
scrollbar-width: thin;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-button {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--post-tooltip-scrollbar-background);
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--post-tooltip-scrollbar-thumb-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb:active {
|
||||||
|
background: var(--post-tooltip-scrollbar-thumb-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: var(--post-tooltip-scrollbar-track-background);
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track:hover {
|
||||||
|
background: var(--post-tooltip-scrollbar-track-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track:active {
|
||||||
|
background: var(--post-tooltip-scrollbar-track-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-corner {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 660px) {
|
@media screen and (min-width: 660px) {
|
||||||
.md\:inline-block { display: inline-block; }
|
.md\:inline-block { display: inline-block; }
|
||||||
.md\:flex { display: flex; }
|
.md\:flex { display: flex; }
|
||||||
|
|||||||
@@ -1,50 +1,6 @@
|
|||||||
$tooltip-line-height: 16px;
|
$tooltip-line-height: 16px;
|
||||||
$tooltip-body-height: $tooltip-line-height * 4; // 4 lines high.
|
$tooltip-body-height: $tooltip-line-height * 4; // 4 lines high.
|
||||||
|
|
||||||
@mixin thin-scrollbar {
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-button {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background: var(--post-tooltip-scrollbar-background);
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: var(--post-tooltip-scrollbar-thumb-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb:active {
|
|
||||||
background: var(--post-tooltip-scrollbar-thumb-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background: var(--post-tooltip-scrollbar-track-background);
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track:hover {
|
|
||||||
background: var(--post-tooltip-scrollbar-track-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track:active {
|
|
||||||
background: var(--post-tooltip-scrollbar-track-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-corner {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tippy-box[data-theme~="post-tooltip"] {
|
.tippy-box[data-theme~="post-tooltip"] {
|
||||||
min-width: 20em;
|
min-width: 20em;
|
||||||
max-width: 40em !important;
|
max-width: 40em !important;
|
||||||
@@ -59,7 +15,6 @@ $tooltip-body-height: $tooltip-line-height * 4; // 4 lines high.
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post-tooltip-body {
|
.post-tooltip-body {
|
||||||
@include thin-scrollbar;
|
|
||||||
max-height: $tooltip-body-height;
|
max-height: $tooltip-body-height;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -101,6 +101,7 @@
|
|||||||
<div id="tooltips">
|
<div id="tooltips">
|
||||||
<div id="post-tooltips"></div>
|
<div id="post-tooltips"></div>
|
||||||
<div id="user-tooltips"></div>
|
<div id="user-tooltips"></div>
|
||||||
|
<div id="post-votes-tooltips"></div>
|
||||||
<div id="popup-menus"></div>
|
<div id="popup-menus"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
7
app/views/post_votes/_search.html.erb
Normal file
7
app/views/post_votes/_search.html.erb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<%= search_form_for(post_votes_path) do |f| %>
|
||||||
|
<%= f.input :user_name, label: "Voter", input_html: { value: params[:search][:user_name], "data-autocomplete": "user" } %>
|
||||||
|
<%= f.input :post_id, label: "Post", input_html: { value: params[:search][:post_id] } %>
|
||||||
|
<%= f.input :post_tags_match, label: "Tags", input_html: { value: params[:search][:post_tags_match], "data-autocomplete": "tag-query" } %>
|
||||||
|
<%= f.input :score, collection: [["+3", "3"], ["+1", "1"], ["-1", "-1"], ["-3", "-3"]], include_blank: true, selected: params[:search][:score] %>
|
||||||
|
<%= f.submit "Search" %>
|
||||||
|
<% end %>
|
||||||
24
app/views/post_votes/index.html+compact.erb
Normal file
24
app/views/post_votes/index.html+compact.erb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<%= render "posts/partials/common/secondary_links" %>
|
||||||
|
|
||||||
|
<div id="c-post-votes">
|
||||||
|
<div id="a-index">
|
||||||
|
<%= render "search" %>
|
||||||
|
|
||||||
|
<%= table_for @post_votes, class: "striped autofit" do |t| %>
|
||||||
|
<% t.column "Score" do |vote| %>
|
||||||
|
<%= link_to sprintf("%+d", vote.score), post_votes_path(search: { score: vote.score }) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% t.column "Voter" do |vote| %>
|
||||||
|
<%= link_to_user vote.user %>
|
||||||
|
<%= link_to "»", post_votes_path(search: { user_name: vote.user.name }) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% t.column "Created" do |vote| %>
|
||||||
|
<%= time_ago_in_words_tagged(vote.created_at) %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= numbered_paginator(@post_votes) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
1
app/views/post_votes/index.html+tooltip.erb
Normal file
1
app/views/post_votes/index.html+tooltip.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render_post_votes_tooltip(@post, current_user: CurrentUser.user) %>
|
||||||
@@ -1,12 +1,6 @@
|
|||||||
<div id="c-post-votes">
|
<div id="c-post-votes">
|
||||||
<div id="a-index">
|
<div id="a-index">
|
||||||
<%= search_form_for(post_votes_path) do |f| %>
|
<%= render "search" %>
|
||||||
<%= f.input :user_name, label: "Voter", input_html: { value: params[:search][:user_name], "data-autocomplete": "user" } %>
|
|
||||||
<%= f.input :post_id, label: "Post", input_html: { value: params[:search][:post_id] } %>
|
|
||||||
<%= f.input :post_tags_match, label: "Tags", input_html: { value: params[:search][:post_tags_match], "data-autocomplete": "tag-query" } %>
|
|
||||||
<%= f.input :score, collection: [["+3", "3"], ["+1", "1"], ["-1", "-1"], ["-3", "-3"]], include_blank: true, selected: params[:search][:score] %>
|
|
||||||
<%= f.submit "Search" %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= table_for @post_votes, class: "striped autofit" do |t| %>
|
<%= table_for @post_votes, class: "striped autofit" do |t| %>
|
||||||
<% t.column "Post" do |vote| %>
|
<% t.column "Post" do |vote| %>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="post-tooltip-body <%= "has-preview" if params[:preview].truthy? %>">
|
<div class="post-tooltip-body thin-scrollbar <%= "has-preview" if params[:preview].truthy? %>">
|
||||||
<div class="post-tooltip-body-left">
|
<div class="post-tooltip-body-left">
|
||||||
<% if params[:preview].truthy? %>
|
<% if params[:preview].truthy? %>
|
||||||
<%= post_preview(@post, show_deleted: true, compact: true) %>
|
<%= post_preview(@post, show_deleted: true, compact: true) %>
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class PostVotesControllerTest < ActionDispatch::IntegrationTest
|
|||||||
context "index action" do
|
context "index action" do
|
||||||
setup do
|
setup do
|
||||||
@user = create(:user, enable_private_favorites: true)
|
@user = create(:user, enable_private_favorites: true)
|
||||||
create(:post_vote, user: @user, score: 1)
|
@upvote = create(:post_vote, user: @user, score: 1)
|
||||||
create(:post_vote, user: @user, score: -1)
|
@downvote = create(:post_vote, user: @user, score: -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "render" do
|
should "render" do
|
||||||
@@ -19,6 +19,16 @@ class PostVotesControllerTest < ActionDispatch::IntegrationTest
|
|||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "render for a compact view" do
|
||||||
|
get post_votes_path(variant: "compact")
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
should "render for a tooltip" do
|
||||||
|
get post_votes_path(search: { post_id: @upvote.post_id }, variant: "tooltip")
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
context "as a user" do
|
context "as a user" do
|
||||||
should "show the user all their own votes" do
|
should "show the user all their own votes" do
|
||||||
get_auth post_votes_path, @user
|
get_auth post_votes_path, @user
|
||||||
|
|||||||
Reference in New Issue
Block a user