forked from e621ng/e621ng
Merge branch 'master' into master2
This commit is contained in:
commit
9923b01141
@ -19,6 +19,12 @@ class PostsController < ApplicationController
|
|||||||
@query = tag_query.nil? ? [] : tag_query.strip.split(/ /, 2).compact_blank
|
@query = tag_query.nil? ? [] : tag_query.strip.split(/ /, 2).compact_blank
|
||||||
if @query.length == 1
|
if @query.length == 1
|
||||||
@wiki_page = WikiPage.titled(@query[0])
|
@wiki_page = WikiPage.titled(@query[0])
|
||||||
|
|
||||||
|
# redirect?
|
||||||
|
if @wiki_page.present? && @wiki_page.parent.present?
|
||||||
|
@wiki_page = WikiPage.titled(@wiki_page.parent)
|
||||||
|
end
|
||||||
|
|
||||||
@wiki_text = @wiki_page.present? ? @wiki_page.body : ""
|
@wiki_text = @wiki_page.present? ? @wiki_page.body : ""
|
||||||
if @wiki_text.present?
|
if @wiki_text.present?
|
||||||
@wiki_text = @wiki_text
|
@wiki_text = @wiki_text
|
||||||
|
@ -123,9 +123,10 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def wiki_page_params(context)
|
def wiki_page_params(context)
|
||||||
permitted_params = %i[body edit_reason]
|
permitted_params = %i[body category_id edit_reason]
|
||||||
permitted_params += %i[parent] if CurrentUser.is_privileged?
|
permitted_params += %i[parent] if CurrentUser.is_privileged?
|
||||||
permitted_params += %i[is_locked is_deleted skip_secondary_validations] if CurrentUser.is_janitor?
|
permitted_params += %i[is_locked is_deleted skip_secondary_validations] if CurrentUser.is_janitor?
|
||||||
|
permitted_params += %i[category_is_locked] if CurrentUser.is_admin?
|
||||||
permitted_params += %i[title] if context == :create || CurrentUser.is_janitor?
|
permitted_params += %i[title] if context == :create || CurrentUser.is_janitor?
|
||||||
|
|
||||||
params.fetch(:wiki_page, {}).permit(permitted_params)
|
params.fetch(:wiki_page, {}).permit(permitted_params)
|
||||||
|
@ -121,6 +121,10 @@ module ApplicationHelper
|
|||||||
time_tag(time.strftime("%Y-%m-%d %H:%M"), time)
|
time_tag(time.strftime("%Y-%m-%d %H:%M"), time)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact_date(time)
|
||||||
|
time_tag(time.strftime("%Y-%m-%d"), time)
|
||||||
|
end
|
||||||
|
|
||||||
def external_link_to(url, truncate: nil, strip_scheme: false, link_options: {})
|
def external_link_to(url, truncate: nil, strip_scheme: false, link_options: {})
|
||||||
text = url
|
text = url
|
||||||
text = text.gsub(%r!\Ahttps?://!i, "") if strip_scheme
|
text = text.gsub(%r!\Ahttps?://!i, "") if strip_scheme
|
||||||
@ -189,21 +193,6 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def simple_avatar(user, **options)
|
|
||||||
return "" if user.nil?
|
|
||||||
post_id = user.avatar_id
|
|
||||||
deferred_post_ids.add(post_id) if post_id
|
|
||||||
|
|
||||||
klass = options.delete(:class)
|
|
||||||
named = options.delete(:named)
|
|
||||||
tag.a href: home_users_path, class: "simple-avatar #{klass}", data: { id: post_id, name: user.name } do
|
|
||||||
tag.span(class: "simple-avatar-button") do
|
|
||||||
concat tag.span(user.pretty_name, class: "simple-avatar-name") if named
|
|
||||||
concat tag.span(class: "simple-avatar-image", data: { name: user.name[0].capitalize })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_banner(user)
|
def user_banner(user)
|
||||||
return "" if user.nil?
|
return "" if user.nil?
|
||||||
post_id = user.banner_id
|
post_id = user.banner_id
|
||||||
|
@ -17,10 +17,21 @@ module IconHelper
|
|||||||
swatch: %(<path d="M11 17a4 4 0 0 1-8 0V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2Z"/><path d="M16.7 13H19a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H7"/><path d="M 7 17h.01"/><path d="m11 8 2.3-2.3a2.4 2.4 0 0 1 3.404.004L18.6 7.6a2.4 2.4 0 0 1 .026 3.434L9.9 19.8"/>),
|
swatch: %(<path d="M11 17a4 4 0 0 1-8 0V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2Z"/><path d="M16.7 13H19a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H7"/><path d="M 7 17h.01"/><path d="m11 8 2.3-2.3a2.4 2.4 0 0 1 3.404.004L18.6 7.6a2.4 2.4 0 0 1 .026 3.434L9.9 19.8"/>),
|
||||||
settings: %(<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>),
|
settings: %(<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>),
|
||||||
log_in: %(<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" x2="3" y1="12" y2="12"/>),
|
log_in: %(<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" x2="3" y1="12" y2="12"/>),
|
||||||
|
user: %(<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>),
|
||||||
|
|
||||||
# Utility
|
# Utility
|
||||||
|
plus: %(<path d="M5 12h14"/><path d="M12 5v14"/>),
|
||||||
times: %(<path d="M18 6 6 18"/><path d="m6 6 12 12"/>),
|
times: %(<path d="M18 6 6 18"/><path d="m6 6 12 12"/>),
|
||||||
reset: %(<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/>),
|
reset: %(<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/>),
|
||||||
|
replace: %(<path d="M14 4a2 2 0 0 1 2-2"/><path d="M16 10a2 2 0 0 1-2-2"/><path d="M20 2a2 2 0 0 1 2 2"/><path d="M22 8a2 2 0 0 1-2 2"/><path d="m3 7 3 3 3-3"/><path d="M6 10V5a3 3 0 0 1 3-3h1"/><rect x="2" y="14" width="8" height="8" rx="2"/>),
|
||||||
|
upload: %(<path d="M12 13v8"/><path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242"/><path d="m8 17 4-4 4 4"/>),
|
||||||
|
stamp: %(<path d="M19.27 13.73A2.5 2.5 0 0 0 17.5 13h-11A2.5 2.5 0 0 0 4 15.5V17a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-1.5c0-.66-.26-1.3-.73-1.77Z"/><path d="M14 13V8.5C14 7 15 7 15 5a3 3 0 0 0-3-3c-1.66 0-3 1-3 3s1 2 1 3.5V13"/>),
|
||||||
|
power: %(<path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.77.04"/>),
|
||||||
|
circle_help: %(<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/>),
|
||||||
|
notepad: %(<path d="M8 2v4"/><path d="M12 2v4"/><path d="M16 2v4"/><path d="M16 4h2a2 2 0 0 1 2 2v2"/><path d="M20 12v2"/><path d="M20 18v2a2 2 0 0 1-2 2h-1"/><path d="M13 22h-2"/><path d="M7 22H6a2 2 0 0 1-2-2v-2"/><path d="M4 14v-2"/><path d="M4 8V6a2 2 0 0 1 2-2h2"/><path d="M8 10h6"/><path d="M8 14h8"/><path d="M8 18h5"/>),
|
||||||
|
flag_left: %(<path d="M17 22V2L7 7l10 5"/>),
|
||||||
|
ticket: %(<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>),
|
||||||
|
key_square: %(<path d="M12.4 2.7a2.5 2.5 0 0 1 3.4 0l5.5 5.5a2.5 2.5 0 0 1 0 3.4l-3.7 3.7a2.5 2.5 0 0 1-3.4 0L8.7 9.8a2.5 2.5 0 0 1 0-3.4z"/><path d="m14 7 3 3"/><path d="m9.4 10.6-6.814 6.814A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814"/>),
|
||||||
|
|
||||||
# Pagination
|
# Pagination
|
||||||
chevron_left: %(<path d="m15 18-6-6 6-6"/>),
|
chevron_left: %(<path d="m15 18-6-6 6-6"/>),
|
||||||
@ -28,7 +39,9 @@ module IconHelper
|
|||||||
ellipsis: %(<circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/>),
|
ellipsis: %(<circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/>),
|
||||||
|
|
||||||
# Posts
|
# Posts
|
||||||
|
search: %(<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>),
|
||||||
fullscreen: %(<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><rect width="10" height="8" x="7" y="8" rx="1"/>),
|
fullscreen: %(<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><rect width="10" height="8" x="7" y="8" rx="1"/>),
|
||||||
|
anchor: %(<path d="M12 22V8"/><path d="M5 12H2a10 10 0 0 0 20 0h-3"/><circle cx="12" cy="5" r="3"/>),
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
def svg_icon(name, *args)
|
def svg_icon(name, *args)
|
||||||
|
@ -1,6 +1,29 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module PaginationHelper
|
module PaginationHelper
|
||||||
|
def approximate_count(records)
|
||||||
|
return "" if records.pagination_mode != :numbered
|
||||||
|
|
||||||
|
if records.total_pages > records.max_numbered_pages
|
||||||
|
pages = records.max_numbered_pages
|
||||||
|
schar = "over "
|
||||||
|
count = pages * records.records_per_page
|
||||||
|
title = "Over #{count} results found.\nActual result count may be much larger."
|
||||||
|
else
|
||||||
|
pages = records.total_pages
|
||||||
|
schar = "~"
|
||||||
|
count = pages * records.records_per_page
|
||||||
|
title = "Approximately #{count} results found.\nActual result count may differ."
|
||||||
|
end
|
||||||
|
|
||||||
|
tag.span(class: "approximate-count", title: title, data: { count: count, pages: pages, per: records.max_numbered_pages }) do
|
||||||
|
concat schar
|
||||||
|
concat number_to_human(count, precision: 2, format: "%n%u", units: { thousand: "k" })
|
||||||
|
concat " "
|
||||||
|
concat "result".pluralize(count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def sequential_paginator(records)
|
def sequential_paginator(records)
|
||||||
tag.nav(class: "pagination sequential", aria: { label: "Pagination" }) do
|
tag.nav(class: "pagination sequential", aria: { label: "Pagination" }) do
|
||||||
return "" if records.try(:none?)
|
return "" if records.try(:none?)
|
||||||
@ -64,12 +87,12 @@ module PaginationHelper
|
|||||||
html = "".html_safe
|
html = "".html_safe
|
||||||
|
|
||||||
if disabled
|
if disabled
|
||||||
html << tag.span(class: "next", id: "paginator-next", data: { shortcut: "a left" }) do
|
html << tag.span(class: "next", id: "paginator-next", data: { shortcut: "d right" }) do
|
||||||
concat tag.span("Next")
|
concat tag.span("Next")
|
||||||
concat svg_icon(:chevron_right)
|
concat svg_icon(:chevron_right)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
html << link_to(link, class: "next", id: "paginator-prev", rel: "next", data: { shortcut: "a left" }) do
|
html << link_to(link, class: "next", id: "paginator-next", rel: "next", data: { shortcut: "d right" }) do
|
||||||
concat tag.span("Next")
|
concat tag.span("Next")
|
||||||
concat svg_icon(:chevron_right)
|
concat svg_icon(:chevron_right)
|
||||||
end
|
end
|
||||||
|
@ -11,4 +11,47 @@ module UsersHelper
|
|||||||
domain = email.split("@").last
|
domain = email.split("@").last
|
||||||
link_to "»", users_path(search: { email_matches: "*@#{domain}" })
|
link_to "»", users_path(search: { email_matches: "*@#{domain}" })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def simple_avatar(user, **options)
|
||||||
|
return "" if user.nil?
|
||||||
|
post_id = user.avatar_id
|
||||||
|
deferred_post_ids.add(post_id) if post_id
|
||||||
|
|
||||||
|
klass = options.delete(:class)
|
||||||
|
named = options.delete(:named)
|
||||||
|
tag.a href: user_path(user), class: "simple-avatar placeholder #{klass}", data: { id: post_id, name: user.name } do
|
||||||
|
tag.span(class: "avatar-button") do
|
||||||
|
concat tag.span(user.pretty_name, class: "avatar-name") if named
|
||||||
|
concat tag.span(class: "avatar-image", data: { name: user.name[0].capitalize })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def profile_avatar(user, **options)
|
||||||
|
return if user.nil?
|
||||||
|
post_id = user.avatar_id
|
||||||
|
deferred_post_ids.add(post_id) if post_id
|
||||||
|
|
||||||
|
klass = options.delete(:class)
|
||||||
|
|
||||||
|
render "/application/profile_avatar", user: user, post_id: post_id, klass: klass
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_level_badge(user)
|
||||||
|
return if user.nil?
|
||||||
|
|
||||||
|
tag.span(class: "level-badge level-#{user.level_string.downcase}") do
|
||||||
|
user.level_string.upcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_feedback_badge(user)
|
||||||
|
return if user.nil?
|
||||||
|
|
||||||
|
feedbacks = user.feedback_pieces
|
||||||
|
deleted = CurrentUser.user.is_staff? ? feedbacks[:deleted] : 0
|
||||||
|
active = feedbacks[:positive] + feedbacks[:neutral] + feedbacks[:negative]
|
||||||
|
|
||||||
|
render "/application/feedback_badge", user: user, positive: feedbacks[:positive], neutral: feedbacks[:neutral], negative: feedbacks[:negative], deleted: deleted, active: active
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -67,6 +67,13 @@ PostSearch.initialize_controls = function () {
|
|||||||
$("body").attr("data-st-fullscreen", fullscreen);
|
$("body").attr("data-st-fullscreen", fullscreen);
|
||||||
LStorage.Posts.Fullscreen = fullscreen;
|
LStorage.Posts.Fullscreen = fullscreen;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let stickySearch = LStorage.Posts.StickySearch;
|
||||||
|
$("#search-sticky").on("click", () => {
|
||||||
|
stickySearch = !stickySearch;
|
||||||
|
$("body").attr("data-st-ssearch", stickySearch);
|
||||||
|
LStorage.Posts.StickySearch = stickySearch;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
170
app/javascript/src/javascripts/tabs.js
Normal file
170
app/javascript/src/javascripts/tabs.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
class Tabs {
|
||||||
|
|
||||||
|
constructor ($element) {
|
||||||
|
this.$menu = $element;
|
||||||
|
|
||||||
|
const id = this.$menu.attr("id");
|
||||||
|
const pagesWrap = $(`tabs-content[for="${id}"]`);
|
||||||
|
if (!pagesWrap) {
|
||||||
|
console.error("E6.Tabs", "No content");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create page and search indices
|
||||||
|
this.index = new TabIndex(pagesWrap, this.$menu);
|
||||||
|
|
||||||
|
// Bootstrap search
|
||||||
|
const input = this.$menu.find("input[name='search']").on("input", (event, crabs) => {
|
||||||
|
const val = (input.val() + "").trim();
|
||||||
|
this.index.find(val);
|
||||||
|
|
||||||
|
// Set the query param
|
||||||
|
if (crabs) return;
|
||||||
|
|
||||||
|
const url = new URL(window.location);
|
||||||
|
if (!val) url.searchParams.delete("find");
|
||||||
|
else url.searchParams.set("find", input.val() + "");
|
||||||
|
url.searchParams.delete("tab");
|
||||||
|
|
||||||
|
window.history.pushState({}, "", url);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bootstrap tab buttons
|
||||||
|
const firstButtonName = this.$menu.find("button").first().attr("name");
|
||||||
|
this.$menu.on("click", "button", (event, crabs) => {
|
||||||
|
const button = $(event.currentTarget);
|
||||||
|
const name = button.attr("name");
|
||||||
|
if (!name) return;
|
||||||
|
|
||||||
|
// Toggle the page
|
||||||
|
this.index.openPage(name);
|
||||||
|
this.$menu.find("button.active").removeClass("active");
|
||||||
|
button.addClass("active");
|
||||||
|
input.val("");
|
||||||
|
|
||||||
|
// Set the query param
|
||||||
|
if (crabs) return;
|
||||||
|
|
||||||
|
const url = new URL(window.location);
|
||||||
|
if (name == firstButtonName) url.searchParams.delete("tab");
|
||||||
|
else url.searchParams.set("tab", name);
|
||||||
|
url.searchParams.delete("find");
|
||||||
|
|
||||||
|
window.history.pushState({}, "", url);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Attempt to restore previous state
|
||||||
|
const queryParams = new URLSearchParams(window.location.search);
|
||||||
|
if (queryParams.get("tab")) {
|
||||||
|
// No error handling: if the button does not exist nothing loads
|
||||||
|
this.$menu.find(`button[name="${queryParams.get("tab")}"]`).trigger("click", [ true ]);
|
||||||
|
input.val("");
|
||||||
|
} else if (queryParams.get("find")) {
|
||||||
|
input.val(queryParams.get("find"), [ true ]);
|
||||||
|
input.trigger("input");
|
||||||
|
} else {
|
||||||
|
// Just open the first tab
|
||||||
|
this.$menu.find("button").first().click();
|
||||||
|
input.val("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TabIndex {
|
||||||
|
|
||||||
|
constructor (wrapper, $menu) {
|
||||||
|
|
||||||
|
this.$menu = $menu;
|
||||||
|
|
||||||
|
this.pages = {};
|
||||||
|
this.search = {};
|
||||||
|
this._allEntries = wrapper.children("tab-entry");
|
||||||
|
for (const one of this._allEntries) {
|
||||||
|
const $one = $(one);
|
||||||
|
|
||||||
|
const tab = $one.attr("tab");
|
||||||
|
if (tab) {
|
||||||
|
if (!this.pages[tab]) this.pages[tab] = [];
|
||||||
|
this.pages[tab].push($one);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Not a great way of doing this.
|
||||||
|
// Entries with the same search string will get overwriten.
|
||||||
|
const search = $one.attr("search");
|
||||||
|
if (search) this.search[search] = $one;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.groups = {};
|
||||||
|
this._allGroups = wrapper.children("tab-group");
|
||||||
|
for (const one of this._allGroups) {
|
||||||
|
const $one = $(one);
|
||||||
|
const name = $one.attr("name");
|
||||||
|
if (!name) return;
|
||||||
|
this.groups[name] = $one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show all entries on a specific tab
|
||||||
|
* @param {string} name Tab name
|
||||||
|
*/
|
||||||
|
openPage (name) {
|
||||||
|
|
||||||
|
if (!name || !this.pages[name]) {
|
||||||
|
console.error("E6.Tabs", name, "does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate tab entries
|
||||||
|
const groups = new Set();
|
||||||
|
this._allEntries.removeClass("active");
|
||||||
|
for (const entry of this.pages[name]) {
|
||||||
|
entry.addClass("active");
|
||||||
|
if (entry.attr("group"))
|
||||||
|
groups.add(entry.attr("group"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate group headers
|
||||||
|
this._allGroups.removeClass("active");
|
||||||
|
for (const group of groups)
|
||||||
|
this.groups[group].addClass("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find settings inputs based on keywords
|
||||||
|
* @param {string} query Search query
|
||||||
|
*/
|
||||||
|
find (query) {
|
||||||
|
this._allEntries.removeClass("active");
|
||||||
|
this._allGroups.removeClass("active");
|
||||||
|
|
||||||
|
// Restore the previous session
|
||||||
|
if (query.length == 0) {
|
||||||
|
this.$menu.find("button").first().trigger("click", [ false ]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const terms = query.split(" ");
|
||||||
|
const groups = new Set();
|
||||||
|
for (const [tags, $element] of Object.entries(this.search)) {
|
||||||
|
for (const term of terms) {
|
||||||
|
if (!tags.includes(term)) continue;
|
||||||
|
$element.addClass("active");
|
||||||
|
if ($element.attr("group"))
|
||||||
|
groups.add($element.attr("group"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate group headers
|
||||||
|
this._allGroups.removeClass("active");
|
||||||
|
for (const group of groups)
|
||||||
|
this.groups[group].addClass("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
for (const one of $("tabs-menu"))
|
||||||
|
new Tabs($(one));
|
||||||
|
});
|
@ -39,8 +39,8 @@ Takedown.add_posts_by_tags_preview = function (id) {
|
|||||||
$("#takedown-add-posts-tags-warning").html(preview_text).show();
|
$("#takedown-add-posts-tags-warning").html(preview_text).show();
|
||||||
$("#takedown-add-posts-tags").prop("disabled", true);
|
$("#takedown-add-posts-tags").prop("disabled", true);
|
||||||
$("#takedown-add-posts-tags-preview").hide();
|
$("#takedown-add-posts-tags-preview").hide();
|
||||||
$("#takedown-add-posts-tags-confirm").show();
|
$("#takedown-add-posts-tags-confirm").css("display", "inline-block");
|
||||||
$("#takedown-add-posts-tags-cancel").show();
|
$("#takedown-add-posts-tags-cancel").css("display", "inline-block");
|
||||||
}).fail(function (data) {
|
}).fail(function (data) {
|
||||||
Utility.error(data.responseText);
|
Utility.error(data.responseText);
|
||||||
});
|
});
|
||||||
|
@ -3,17 +3,23 @@ import LStorage from "./utility/storage";
|
|||||||
|
|
||||||
const Theme = {};
|
const Theme = {};
|
||||||
|
|
||||||
Theme.Values = ["Main", "Extra", "StickyHeader", "ForumNotif", "Palette", "Navbar", "Gestures"];
|
Theme.Values = {
|
||||||
|
"Theme": ["Main", "Extra", "Palette", "Font", "StickyHeader", "Navbar", "Gestures", "ForumNotif"],
|
||||||
|
"Posts": ["WikiExcerpt", "StickySearch"],
|
||||||
|
};
|
||||||
|
|
||||||
for (const one of Theme.Values) {
|
for (const [label, settings] of Object.entries(Theme.Values)) {
|
||||||
Object.defineProperty(Theme, one, {
|
for (const one of settings) {
|
||||||
get () { return LStorage.Theme[one]; },
|
Object.defineProperty(Theme, one, {
|
||||||
set (value) {
|
get () { return LStorage.Theme[one]; },
|
||||||
// No value checking, we die like men
|
set (value) {
|
||||||
LStorage.Theme[one] = value;
|
// This has the unintended side effect of setting
|
||||||
$("body").attr("data-th-" + one.toLowerCase(), value);
|
// attribute values that don't exist on the body.
|
||||||
},
|
LStorage[label][one] = value;
|
||||||
});
|
$("body").attr("data-th-" + one.toLowerCase(), value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Theme.initialize_selector = function () {
|
Theme.initialize_selector = function () {
|
||||||
@ -24,13 +30,15 @@ Theme.initialize_selector = function () {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const one of Theme.Values) {
|
for (const [label, settings] of Object.entries(Theme.Values)) {
|
||||||
$("#theme_" + one.toLowerCase())
|
for (const one of settings)
|
||||||
.val(LStorage.Theme[one] + "")
|
$(`#${label}_${one}`)
|
||||||
.on("change", (event) => {
|
.val(LStorage[label][one] + "")
|
||||||
const data = event.target.value;
|
.on("change", (event) => {
|
||||||
Theme[one] = data;
|
const data = event.target.value;
|
||||||
});
|
console.log("change", one, data);
|
||||||
|
Theme[one] = data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,12 +50,6 @@ Theme.initialize_buttons = function () {
|
|||||||
LStorage.Site.Mascot = 0;
|
LStorage.Site.Mascot = 0;
|
||||||
$("#mascot-value").text(LStorage.Site.Mascot);
|
$("#mascot-value").text(LStorage.Site.Mascot);
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#wiki-excerpt-value").text(LStorage.Posts.WikiExcerpt);
|
|
||||||
$("#wiki-excerpt-reset").on("click", () => {
|
|
||||||
LStorage.Posts.WikiExcerpt = 1;
|
|
||||||
$("#wiki-excerpt-value").text(LStorage.Posts.WikiExcerpt);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
@ -9,8 +9,9 @@ Thumbnails.initialize = function () {
|
|||||||
const replacedPosts = [];
|
const replacedPosts = [];
|
||||||
|
|
||||||
// Avatar special case
|
// Avatar special case
|
||||||
for (const post of $(".simple-avatar")) {
|
for (const post of $(".simple-avatar.placeholder, .profile-avatar.placeholder")) {
|
||||||
const $post = $(post);
|
const $post = $(post);
|
||||||
|
$post.removeClass("placeholder");
|
||||||
|
|
||||||
const postID = $post.data("id");
|
const postID = $post.data("id");
|
||||||
if (!postID) continue;
|
if (!postID) continue;
|
||||||
@ -20,7 +21,11 @@ Thumbnails.initialize = function () {
|
|||||||
|
|
||||||
$("<img>")
|
$("<img>")
|
||||||
.attr("src", postData["preview_url"])
|
.attr("src", postData["preview_url"])
|
||||||
.appendTo($post.find("span.simple-avatar-image"));
|
.appendTo($post.find("span.avatar-image"));
|
||||||
|
|
||||||
|
if ($post.hasClass("profile-avatar"))
|
||||||
|
$post.attr("href", "/posts/" + postID);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
app/javascript/src/javascripts/users.js
Normal file
25
app/javascript/src/javascripts/users.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import LStorage from "./utility/storage";
|
||||||
|
|
||||||
|
const Users = {};
|
||||||
|
|
||||||
|
Users.init_section = function ($wrapper) {
|
||||||
|
const $header = $wrapper.find(".profile-section-header").first();
|
||||||
|
const $body = $(".profile-section-body").first();
|
||||||
|
const name = $wrapper.attr("name");
|
||||||
|
if (!name || !$header.length || !$body.length) return;
|
||||||
|
|
||||||
|
let state = LStorage.Users[name];
|
||||||
|
if (state) $wrapper.removeClass("hidden");
|
||||||
|
|
||||||
|
$header.on("click", () => {
|
||||||
|
$wrapper.toggleClass("hidden", state);
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
LStorage.Users[name] = state;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
for (const one of $((".profile-section")))
|
||||||
|
Users.init_section($((one)));
|
||||||
|
});
|
@ -57,6 +57,9 @@ LStorage.Theme = {
|
|||||||
/** @returns {string} Colorblind-friendly palette (default / deut / trit) */
|
/** @returns {string} Colorblind-friendly palette (default / deut / trit) */
|
||||||
Palette: ["theme-palette", "default"],
|
Palette: ["theme-palette", "default"],
|
||||||
|
|
||||||
|
/** @returns {string} Font family (verdana / leto / lexend / dyslexic ) */
|
||||||
|
Font: ["theme-font", "Verdana"],
|
||||||
|
|
||||||
/** @returns {string} Position of the navbar on the post page (top / bottom / both / none) */
|
/** @returns {string} Position of the navbar on the post page (top / bottom / both / none) */
|
||||||
Navbar: ["theme-nav", "top"],
|
Navbar: ["theme-nav", "top"],
|
||||||
|
|
||||||
@ -91,6 +94,9 @@ LStorage.Posts = {
|
|||||||
|
|
||||||
/** @returns {boolean} True if the search should be displayed in fullscreen */
|
/** @returns {boolean} True if the search should be displayed in fullscreen */
|
||||||
Fullscreen: ["e6.posts.fusk", false],
|
Fullscreen: ["e6.posts.fusk", false],
|
||||||
|
|
||||||
|
/** @returns {boolean} True if the search should be displayed in fullscreen */
|
||||||
|
StickySearch: ["e6.posts.ssearch", false],
|
||||||
};
|
};
|
||||||
StorageUtils.bootstrapMany(LStorage.Posts);
|
StorageUtils.bootstrapMany(LStorage.Posts);
|
||||||
|
|
||||||
@ -184,6 +190,17 @@ LStorage.Blacklist = {
|
|||||||
StorageUtils.bootstrapSome(LStorage.Blacklist, ["Collapsed"]);
|
StorageUtils.bootstrapSome(LStorage.Blacklist, ["Collapsed"]);
|
||||||
|
|
||||||
|
|
||||||
|
// Users page config
|
||||||
|
LStorage.Users = {
|
||||||
|
/** @returns {boolean} True to show staff stats, false to hide them */
|
||||||
|
StaffStats: ["e6.users.staffstats", false],
|
||||||
|
|
||||||
|
/** @returns {boolean} True to show user stats, false to hide them */
|
||||||
|
StaffNotes: ["e6.users.staffnotes", false],
|
||||||
|
};
|
||||||
|
StorageUtils.bootstrapMany(LStorage.Users);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patches the add, delete, and clear methods for the filter cache set.
|
* Patches the add, delete, and clear methods for the filter cache set.
|
||||||
* Otherwise, modifying the set with these methods would not update the local storage
|
* Otherwise, modifying the set with these methods would not update the local storage
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
@import "base/base";
|
@import "base/base";
|
||||||
@import "base/links";
|
@import "base/links";
|
||||||
@import "base/fontawesome";
|
@import "base/fontawesome";
|
||||||
|
@import "base/fonts";
|
||||||
|
|
||||||
@import "common/standard_variables";
|
@import "common/standard_variables";
|
||||||
@import "common/standard_elements";
|
@import "common/standard_elements";
|
||||||
@ -42,6 +43,10 @@
|
|||||||
@import "common/user_styles.scss";
|
@import "common/user_styles.scss";
|
||||||
@import "common/voting.scss";
|
@import "common/voting.scss";
|
||||||
|
|
||||||
|
@import "views/application/application";
|
||||||
|
@import "views/posts/posts";
|
||||||
|
@import "views/users/users";
|
||||||
|
|
||||||
@import "specific/admin_dashboards.scss";
|
@import "specific/admin_dashboards.scss";
|
||||||
@import "specific/api_keys.scss";
|
@import "specific/api_keys.scss";
|
||||||
@import "specific/artists.scss";
|
@import "specific/artists.scss";
|
||||||
@ -68,8 +73,6 @@
|
|||||||
@import "specific/popular.scss";
|
@import "specific/popular.scss";
|
||||||
@import "specific/post_delete.scss";
|
@import "specific/post_delete.scss";
|
||||||
@import "specific/post_flags.scss";
|
@import "specific/post_flags.scss";
|
||||||
@import "specific/post_index.scss";
|
|
||||||
@import "specific/post_mode_menu.scss";
|
|
||||||
@import "specific/posts.scss";
|
@import "specific/posts.scss";
|
||||||
@import "specific/post_replacements.scss";
|
@import "specific/post_replacements.scss";
|
||||||
@import "specific/post_versions.scss";
|
@import "specific/post_versions.scss";
|
||||||
|
161
app/javascript/src/styles/base/_fonts.scss
Normal file
161
app/javascript/src/styles/base/_fonts.scss
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// Picker
|
||||||
|
body {
|
||||||
|
&[data-th-font="Lato"] { font-family: "Lato", $base_font_family; }
|
||||||
|
&[data-th-font="Lexend"] { font-family: "Lexend", $base_font_family; }
|
||||||
|
&[data-th-font="Monospace"] { font-family: monospace, monospace; }
|
||||||
|
&[data-th-font="OpenDyslexic"] { font-family: "OpenDyslexic", $base_font_family; }
|
||||||
|
&[data-th-font="OpenSans"] { font-family: "OpenSans", $base_font_family; }
|
||||||
|
&[data-th-font="ComicSans"] { font-family: "Comic Sans MS", "Comic Sans", cursive; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Font Definitions **/
|
||||||
|
// Lato
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lato";
|
||||||
|
src: url("/public/fonts/Lato/Lato-Regular.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lato/Lato-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lato";
|
||||||
|
src: url("/public/fonts/Lato/Lato-Bold.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lato/Lato-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lato";
|
||||||
|
src: url("/public/fonts/Lato/Lato-Italic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lato/Lato-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lato";
|
||||||
|
src: url("/public/fonts/Lato/Lato-BoldItalic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lato/Lato-BoldItalic.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Lexend
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lexend";
|
||||||
|
src: url("/public/fonts/Lexend/Lexend-Regular.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lexend/Lexend-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lexend";
|
||||||
|
src: url("/public/fonts/Lexend/Lexend-Bold.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lexend/Lexend-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lexend";
|
||||||
|
src: url("/public/fonts/Lexend/Lexend-Italic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lexend/Lexend-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Lexend";
|
||||||
|
src: url("/public/fonts/Lexend/Lexend-BoldItalic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/Lexend/Lexend-BoldItalic.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// OpenDyslexic
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenDyslexic";
|
||||||
|
src: url("/public/fonts/OpenDyslexic/OpenDyslexic-Regular.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenDyslexic/OpenDyslexic-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenDyslexic";
|
||||||
|
src: url("/public/fonts/OpenDyslexic/OpenDyslexic-Bold.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenDyslexic/OpenDyslexic-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenDyslexic";
|
||||||
|
src: url("/public/fonts/OpenDyslexic/OpenDyslexic-Italic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenDyslexic/OpenDyslexic-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenDyslexic";
|
||||||
|
src: url("/public/fonts/OpenDyslexic/OpenDyslexic-BoldItalic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenDyslexic/OpenDyslexic-BoldItalic.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// OpenSans
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenSans";
|
||||||
|
src: url("/public/fonts/OpenSans/OpenSans-Regular.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenSans/OpenSans-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenSans";
|
||||||
|
src: url("/public/fonts/OpenSans/OpenSans-Bold.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenSans/OpenSans-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenSans";
|
||||||
|
src: url("/public/fonts/OpenSans/OpenSans-Italic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenSans/OpenSans-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "OpenSans";
|
||||||
|
src: url("/public/fonts/OpenSans/OpenSans-BoldItalic.woff2") format("woff2"),
|
||||||
|
url("/public/fonts/OpenSans/OpenSans-BoldItalic.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
@ -19,3 +19,15 @@
|
|||||||
@function themed($key) {
|
@function themed($key) {
|
||||||
@return var(--#{$key});
|
@return var(--#{$key});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin with-theme($key, $value) {
|
||||||
|
body[data-th-#{$key}="#{$value}"] {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin with-setting($key, $value) {
|
||||||
|
body[data-st-#{$key}="#{$value}"] {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,7 +20,7 @@ $dtext_h3_size: 1.6em;
|
|||||||
$dtext_h4_size: 1.4em;
|
$dtext_h4_size: 1.4em;
|
||||||
$dtext_h5_size: 1.2em;
|
$dtext_h5_size: 1.2em;
|
||||||
$dtext_h6_size: 1em;
|
$dtext_h6_size: 1em;
|
||||||
$base_font_family: Verdana, sans-serif;
|
$base_font_family: Verdana, Geneva, sans-serif;
|
||||||
|
|
||||||
$box-shadow-size: 2px 2px 5px;
|
$box-shadow-size: 2px 2px 5px;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ footer.footer-wrapper {
|
|||||||
margin-right: -3.25rem;
|
margin-right: -3.25rem;
|
||||||
|
|
||||||
background: themed("color-background") themed("image-background");
|
background: themed("color-background") themed("image-background");
|
||||||
border-radius: 50%;
|
border-radius: 25%;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,12 @@
|
|||||||
line-height: st-value(100);
|
line-height: st-value(100);
|
||||||
padding: st-value(100) / 2;
|
padding: st-value(100) / 2;
|
||||||
height: st-value(100) * 2;
|
height: st-value(100) * 2;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
// TODO What if button is on a light background
|
// TODO What if button is on a light background
|
||||||
background: $button-background;
|
background: $button-background;
|
||||||
color: $button-text-color;
|
color: $button-text-color;
|
||||||
&:hover { background: $button-background-hover; }
|
&:hover, &:active { background: $button-background-hover; }
|
||||||
|
|
||||||
& > svg {
|
& > svg {
|
||||||
// Icon should be slightly larger than text,
|
// Icon should be slightly larger than text,
|
||||||
@ -64,3 +65,57 @@
|
|||||||
padding: (st-value(100) / 2) 0;
|
padding: (st-value(100) / 2) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Colored buttons
|
||||||
|
.st-button.danger {
|
||||||
|
background: palette("background-red");
|
||||||
|
&:hover, &:active {
|
||||||
|
background: palette("background-red-d5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Toggle switch
|
||||||
|
label.st-toggle {
|
||||||
|
display: flex;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 0.75rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
background-color: themed("color-foreground");
|
||||||
|
// transition: background-color 200ms;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0;
|
||||||
|
|
||||||
|
box-shadow: inset 0 0 0.25rem #00000060;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
position: absolute;
|
||||||
|
top: -0.125rem;
|
||||||
|
left: 0rem;
|
||||||
|
|
||||||
|
background: themed("color-link");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
transition: left 100ms, background-color 200ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input[type="checkbox"][disabled].st-toggle + label.st-toggle {
|
||||||
|
background: palette("background-grey");
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
input[type="checkbox"].st-toggle { display: none; }
|
||||||
|
input[type="checkbox"].st-toggle:checked + label.st-toggle {
|
||||||
|
// background-color: palette("background-green-d5");
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
left: 1.5rem;
|
||||||
|
background: themed("color-link-active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,5 +17,5 @@ $st-values: (
|
|||||||
@function padding($value) { @return st-value(($value)); }
|
@function padding($value) { @return st-value(($value)); }
|
||||||
@mixin st-padding($value) { padding: padding(($value)); }
|
@mixin st-padding($value) { padding: padding(($value)); }
|
||||||
|
|
||||||
@function radius($value) { @return st-value($value); }
|
@function radius($value: 025) { @return st-value($value); }
|
||||||
@mixin st-radius($value) { border-radius: radius($value); }
|
@mixin st-radius($value: 025) { border-radius: radius($value); }
|
||||||
|
@ -5,7 +5,7 @@ nav.navigation {
|
|||||||
grid-template-rows: min-content min-content min-content min-content auto;
|
grid-template-rows: min-content min-content min-content min-content auto;
|
||||||
|
|
||||||
width: 100%; // otherwise narrow when fixed
|
width: 100%; // otherwise narrow when fixed
|
||||||
z-index: 20; // otherwise post labels layered above
|
z-index: 200; // above post labels and notes
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
|
||||||
@ -76,11 +76,11 @@ nav.navigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a.simple-avatar {
|
a.simple-avatar {
|
||||||
.simple-avatar-button {
|
.avatar-button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
|
|
||||||
.simple-avatar-name {
|
.avatar-name {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|
||||||
@include window-smaller-than(32rem) {
|
@include window-smaller-than(32rem) {
|
||||||
@ -88,7 +88,7 @@ nav.navigation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple-avatar-image {
|
.avatar-image {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -119,7 +119,7 @@ nav.navigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include window-smaller-than(32rem) {
|
@include window-smaller-than(32rem) {
|
||||||
&.sign-in .simple-avatar-image {
|
&.sign-in .avatar-image {
|
||||||
background: themed("color-foreground");
|
background: themed("color-foreground");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,6 +187,8 @@ nav.navigation {
|
|||||||
padding: 1rem 0.5rem;
|
padding: 1rem 0.5rem;
|
||||||
}
|
}
|
||||||
li.current a { background-color: themed("color-foreground"); }
|
li.current a { background-color: themed("color-foreground"); }
|
||||||
|
|
||||||
|
li.nav-hidden { display: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-secondary {
|
.nav-secondary {
|
||||||
@ -493,18 +495,18 @@ nav.navigation, html.nav-toggled nav.navigation {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.simple-avatar-button {
|
.avatar-button {
|
||||||
background: none;
|
background: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 0.875rem;
|
line-height: 0.875rem;
|
||||||
|
|
||||||
.simple-avatar-name {
|
.avatar-name {
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple-avatar-image {
|
.avatar-image {
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
background: themed("color-foreground");
|
background: themed("color-foreground");
|
||||||
@ -526,9 +528,9 @@ nav.navigation, html.nav-toggled nav.navigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stage 2: account label
|
// Stage 2: account label
|
||||||
.collapse-2 .simple-avatar-name { display: none; }
|
.collapse-2 .avatar-name { display: none; }
|
||||||
@include window-larger-than(65rem) {
|
@include window-larger-than(65rem) {
|
||||||
.collapse-2 .simple-avatar-name { display: unset; }
|
.collapse-2 .avatar-name { display: unset; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,10 +564,10 @@ body.c-static.a-home {
|
|||||||
position: static;
|
position: static;
|
||||||
height: unset;
|
height: unset;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
.simple-avatar-button {
|
.avatar-button {
|
||||||
height: unset;
|
height: unset;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.simple-avatar-image { display: none; }
|
.avatar-image { display: none; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ div#notice {
|
|||||||
top: 1rem;
|
top: 1rem;
|
||||||
left: 25%;
|
left: 25%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
z-index: 100;
|
z-index: 500;
|
||||||
|
|
||||||
color: themed("color-text");
|
color: themed("color-text");
|
||||||
background-color: themed("color-success");
|
background-color: themed("color-success");
|
||||||
|
@ -102,7 +102,7 @@ nav.pagination {
|
|||||||
|
|
||||||
|
|
||||||
// Sequential paginator
|
// Sequential paginator
|
||||||
.paginator.sequential {
|
nav.pagination.sequential {
|
||||||
gap: 5rem;
|
gap: 5rem;
|
||||||
a span { display: block; }
|
a span { display: block; }
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
textarea {
|
textarea {
|
||||||
|
|
||||||
// Override default texarea styles
|
// Override default texarea styles
|
||||||
font-family: Verdana, sans-serif;
|
font-family: $base_font_family;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
padding: 0.5rem 0 0.5rem 0.5rem;
|
padding: 0.5rem 0 0.5rem 0.5rem;
|
||||||
@ -30,7 +30,7 @@
|
|||||||
// Disable manual resizing
|
// Disable manual resizing
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
||||||
border-radius: 3px 0 0 3px;
|
border-radius: 0.25rem 0 0 0.25rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
@ -43,19 +43,27 @@
|
|||||||
font-size: unset;
|
font-size: unset;
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
|
|
||||||
font-size: 1rem;
|
display: flex;
|
||||||
line-height: 1rem;
|
align-items: center;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|
||||||
border-radius: 0 3px 3px 0;
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
background: white;
|
background: white;
|
||||||
|
color: black;
|
||||||
|
|
||||||
span { display: none; }
|
svg {
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
margin: -0.25rem 0 -0.25rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include window-larger-than(800px) {
|
@include window-larger-than(800px) {
|
||||||
textarea, button[type="submit"] {
|
textarea { font-size: 0.85rem; }
|
||||||
font-size: 0.85rem;
|
button[type="submit"] svg {
|
||||||
|
height: 1.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
margin: -0.125rem 0 -0.125rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,6 @@ table.search {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.aligned-vertical {
|
table.aligned-vertical {
|
||||||
@extend .search;
|
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
height: 1.75em;
|
height: 1.75em;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ body.c-static.a-home {
|
|||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 3px 0 0 3px;
|
border-radius: 0.25rem 0 0 0.25rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
|
||||||
@ -57,9 +57,14 @@ body.c-static.a-home {
|
|||||||
|
|
||||||
button[type="submit"] {
|
button[type="submit"] {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 0 3px 3px 0;
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
padding: 0 0.5em;
|
padding: 0 0.5rem;
|
||||||
font-size: 1rem;
|
|
||||||
|
svg {
|
||||||
|
height: 1.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
margin: -0.125rem 0 -0.125rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,287 +0,0 @@
|
|||||||
body.c-posts.a-index, body.c-favorites.a-index {
|
|
||||||
#page {
|
|
||||||
// Override the theme to instead
|
|
||||||
// project it upon the content area
|
|
||||||
background: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exhibit A
|
|
||||||
// Makes the content area take up the
|
|
||||||
// full height of the page. Yes, really.
|
|
||||||
#page, #c-posts, #c-favorites, #a-index {
|
|
||||||
// I hate both this and myself
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-index {
|
|
||||||
display: grid;
|
|
||||||
|
|
||||||
grid-template-areas:
|
|
||||||
"search "
|
|
||||||
"content"
|
|
||||||
"sidebar";
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: min-content 1fr min-content;
|
|
||||||
|
|
||||||
flex: 1; // See Exhibit A
|
|
||||||
|
|
||||||
// 1. Searchbox
|
|
||||||
.search {
|
|
||||||
grid-area: search;
|
|
||||||
|
|
||||||
padding: 0.5rem 0.25rem;
|
|
||||||
background-color: #152f56;
|
|
||||||
background-color: themed("color-foreground");
|
|
||||||
box-shadow: inset 0px -0.25rem 0.25rem -0.25rem themed("color-background");
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: $h3-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-controls {
|
|
||||||
display: none;
|
|
||||||
flex-flow: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Content
|
|
||||||
.content {
|
|
||||||
display: flex; // See Exhibit A
|
|
||||||
flex-flow: column;
|
|
||||||
|
|
||||||
grid-area: content;
|
|
||||||
|
|
||||||
// Imported from #page
|
|
||||||
padding: 0.5rem 0.25rem themed("content-padding-bottom");
|
|
||||||
background-color: #152f56;
|
|
||||||
background-color: themed("color-foreground");
|
|
||||||
background-image: themed("image-foreground");
|
|
||||||
background-position: themed("image-foreground-position");
|
|
||||||
background-repeat: themed("image-foreground-repeat");
|
|
||||||
|
|
||||||
// Quick tag edit
|
|
||||||
#edit-dialog textarea {
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual content area:
|
|
||||||
// posts and pagination
|
|
||||||
.post-index-gallery {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
gap: 1rem;
|
|
||||||
|
|
||||||
flex: 1; // See Exhibit A
|
|
||||||
|
|
||||||
.posts-container {
|
|
||||||
flex: 1; // See Exhibit A
|
|
||||||
grid-auto-rows: min-content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Sidebar
|
|
||||||
.sidebar {
|
|
||||||
grid-area: sidebar;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
gap: 1em;
|
|
||||||
|
|
||||||
padding: 0.5rem 0.25rem;
|
|
||||||
background-color: #152f56;
|
|
||||||
background-color: themed("color-foreground");
|
|
||||||
box-shadow: inset 0px 0.25rem 0.25rem -0.25rem themed("color-background");
|
|
||||||
|
|
||||||
// Mode selection
|
|
||||||
#mode-box-mode, #mode-box #set-id {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
// Match the searchbox
|
|
||||||
padding: 0.5em;
|
|
||||||
font-family: Verdana, sans-serif;
|
|
||||||
font-size: 1.05em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Desktop
|
|
||||||
.post-index {
|
|
||||||
@include window-larger-than(50rem) {
|
|
||||||
grid-template-areas:
|
|
||||||
"search content"
|
|
||||||
"sidebar content";
|
|
||||||
grid-template-columns: 14rem 1fr;
|
|
||||||
grid-template-rows: min-content 1fr;
|
|
||||||
|
|
||||||
.search {
|
|
||||||
box-shadow: inset -0.25rem 0px 0.25rem -0.25rem themed("color-background");
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
border-top-left-radius: 0.25rem;
|
|
||||||
padding: 0.5rem;
|
|
||||||
|
|
||||||
.search-controls {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
box-shadow: inset -0.25rem 0px 0.25rem -0.25rem themed("color-background");
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
border-bottom-left-radius: 0.25rem;
|
|
||||||
padding: 0.5rem
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fullscreen
|
|
||||||
body.c-posts.a-index[data-st-fullscreen="true"] {
|
|
||||||
// Desktop-only, for obvious reasons
|
|
||||||
@include window-larger-than(50rem) {
|
|
||||||
.post-index {
|
|
||||||
grid-template-areas:
|
|
||||||
"search "
|
|
||||||
"content";
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
|
|
||||||
.search {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
border-radius: 0.25rem 0.25rem 0 0;
|
|
||||||
box-shadow: inset 0px -0.25rem 0.25rem -0.25rem themed("color-background");
|
|
||||||
|
|
||||||
.post-search {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-controls {
|
|
||||||
display: flex;
|
|
||||||
justify-content: right;
|
|
||||||
align-self: end;
|
|
||||||
margin: 0 0 0 0.5rem;
|
|
||||||
|
|
||||||
.st-button.w100 {
|
|
||||||
width: unset;
|
|
||||||
span { display: none; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sidebar { display: none; }
|
|
||||||
.content {
|
|
||||||
border-radius: 0 0 0.25rem 0.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FEATURES
|
|
||||||
// Wiki Excerpt
|
|
||||||
.wiki-excerpt {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
background: themed("color-section");
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
|
|
||||||
&.hidden { display: none; }
|
|
||||||
|
|
||||||
// header
|
|
||||||
h3 {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
font-size: 1rem;
|
|
||||||
padding: 0.5rem;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
transition: transform 0.25s;
|
|
||||||
|
|
||||||
height: 1.5rem;
|
|
||||||
width: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wiki-excerpt-dismiss { margin-left: auto; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// body
|
|
||||||
.styled-dtext {
|
|
||||||
background: linear-gradient(to top, themed("color-section"), themed("color-text"));
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
background-clip: text;
|
|
||||||
color: transparent;
|
|
||||||
|
|
||||||
min-height: 0rem;
|
|
||||||
max-height: 0rem;
|
|
||||||
max-width: 50rem;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
|
|
||||||
transition: max-height 0.25s;
|
|
||||||
|
|
||||||
// Disable links
|
|
||||||
pointer-events: none;
|
|
||||||
cursor: unset;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: unset;
|
|
||||||
text-decoration: underline;
|
|
||||||
&::after { content: none; }
|
|
||||||
}
|
|
||||||
|
|
||||||
p:last-child { margin-bottom: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// wiki link
|
|
||||||
.wiki-excerpt-readmore {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
height: 3rem;
|
|
||||||
max-width: 50rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
// Makes the button appear in the middle of the animation
|
|
||||||
transition: visibility 0s 0.125s;
|
|
||||||
visibility: hidden;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
background: themed("color-section");
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.open{
|
|
||||||
.wiki-excerpt-toggle svg { transform: rotate(90deg); }
|
|
||||||
.styled-dtext {
|
|
||||||
max-height: 10rem;
|
|
||||||
min-height: 2rem;
|
|
||||||
}
|
|
||||||
.wiki-excerpt-readmore { visibility: visible; }
|
|
||||||
}
|
|
||||||
|
|
||||||
&.loading {
|
|
||||||
h3::after, .styled-dtext { transition: none; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,7 +15,7 @@ div#c-users {
|
|||||||
gap: 1em;
|
gap: 1em;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
max-width: 1600px;
|
max-width: 100rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,107 +76,7 @@ div#c-users {
|
|||||||
// Middle section: uploads and favorites
|
// Middle section: uploads and favorites
|
||||||
.blacklist-ui { padding: 0; }
|
.blacklist-ui { padding: 0; }
|
||||||
|
|
||||||
.posts-section {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
gap: 1em;
|
|
||||||
|
|
||||||
.profile-sample {
|
|
||||||
display: grid;
|
|
||||||
grid-template: "p-header"
|
|
||||||
"p-links"
|
|
||||||
"p-posts";
|
|
||||||
gap: 0.5em 0;
|
|
||||||
|
|
||||||
@include window-larger-than(800px) {
|
|
||||||
grid-template: "p-header p-links"
|
|
||||||
"p-posts p-posts";
|
|
||||||
grid-template-columns: 12em 1fr;
|
|
||||||
gap: 0 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-sample-header a, .profile-sample-links a {
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
align-content: center;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
padding: 0.5em;
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: themed("color-section");
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: themed("color-section-lighten-5");
|
|
||||||
}
|
|
||||||
&:focus, &:active {
|
|
||||||
outline: 0;
|
|
||||||
color: themed("color-link-active");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-sample-header {
|
|
||||||
grid-area: p-header;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-size: 1.25em;
|
|
||||||
font-weight: bold;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include window-larger-than(800px) {
|
|
||||||
a { border-radius: 6px 6px 0 0; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-sample-links {
|
|
||||||
grid-area: p-links;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
gap: 0.5rem;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding: 0.5em;
|
|
||||||
color: themed("color-text-muted");
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacer { display: none; }
|
|
||||||
.profile-comments-link {
|
|
||||||
grid-row: 1 / 3;
|
|
||||||
grid-column: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include window-larger-than(800px) {
|
|
||||||
display: flex;
|
|
||||||
a { height: min-content; }
|
|
||||||
.spacer { display: block; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-sample-posts {
|
|
||||||
grid-area: p-posts;
|
|
||||||
display: flex;
|
|
||||||
overflow: auto;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
gap: 1em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background: var(--color-section);
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
// Desktop
|
|
||||||
@include window-larger-than(800px) {
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Bottom section: about me and commission info
|
// Bottom section: about me and commission info
|
||||||
@ -200,29 +100,6 @@ div#c-users {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div#a-edit {
|
|
||||||
h1 {
|
|
||||||
margin: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.input {
|
|
||||||
margin-bottom: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.input span.hint {
|
|
||||||
display: block;
|
|
||||||
max-width: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
color: themed("color-link-active");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User signup and login
|
// User signup and login
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
@import "avatar";
|
||||||
|
@import "feedback_badge";
|
||||||
|
@import "level_badge";
|
41
app/javascript/src/styles/views/application/_avatar.scss
Normal file
41
app/javascript/src/styles/views/application/_avatar.scss
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
.profile-avatar {
|
||||||
|
.avatar-image {
|
||||||
|
display: flex;
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
background: themed("color-section");
|
||||||
|
@include st-radius;
|
||||||
|
|
||||||
|
// Letter if no avatar image
|
||||||
|
&::after {
|
||||||
|
content: attr(data-initial);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
font-size: 5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: themed("color-foreground");
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On top of the letter
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
@include st-radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
103
app/javascript/src/styles/views/application/_feedback_badge.scss
Normal file
103
app/javascript/src/styles/views/application/_feedback_badge.scss
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
$hex-size: 1.25rem;
|
||||||
|
|
||||||
|
.user-record {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
height: $hex-size * 0.6; // 0.75rem
|
||||||
|
width: $hex-size; // 1.25rem
|
||||||
|
margin: ($hex-size / 5) 0; // 0.25rem 0
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: ($hex-size / 5 * 4) * 0.9;
|
||||||
|
svg { width: ($hex-size / 5 * 4) * 0.9; }
|
||||||
|
|
||||||
|
background: palette("plain-black");
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
// Place corners under the text
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
&::before, &::after {
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
border-left: ($hex-size / 2) solid transparent;
|
||||||
|
border-right: ($hex-size / 2) solid transparent;
|
||||||
|
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: -($hex-size / 5);
|
||||||
|
border-bottom: ($hex-size / 5) solid palette("plain-black");
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: -($hex-size / 5);
|
||||||
|
border-top: ($hex-size / 5) solid palette("plain-black");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Variations
|
||||||
|
&.deleted {
|
||||||
|
background: palette("background-yellow");
|
||||||
|
&::before { border-bottom-color: palette("background-yellow"); }
|
||||||
|
&::after { border-top-color: palette("background-yellow"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.negative {
|
||||||
|
background: palette("background-red");
|
||||||
|
&::before { border-bottom-color: palette("background-red"); }
|
||||||
|
&::after { border-top-color: palette("background-red"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.neutral {
|
||||||
|
background: palette("background-grey");
|
||||||
|
&::before { border-bottom-color: palette("background-grey"); }
|
||||||
|
&::after { border-top-color: palette("background-grey"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.positive {
|
||||||
|
background: palette("background-green");
|
||||||
|
&::before { border-bottom-color: palette("background-green"); }
|
||||||
|
&::after { border-top-color: palette("background-green"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.user-records-list {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
&:hover .user-record {
|
||||||
|
&.deleted {
|
||||||
|
background: palette("background-yellow-d5");
|
||||||
|
&::before { border-bottom-color: palette("background-yellow-d5"); }
|
||||||
|
&::after { border-top-color: palette("background-yellow-d5"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.negative {
|
||||||
|
background: palette("background-red-d5");
|
||||||
|
&::before { border-bottom-color: palette("background-red-d5"); }
|
||||||
|
&::after { border-top-color: palette("background-red-d5"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.neutral {
|
||||||
|
background: palette("background-grey-d5");
|
||||||
|
&::before { border-bottom-color: palette("background-grey-d5"); }
|
||||||
|
&::after { border-top-color: palette("background-grey-d5"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.positive {
|
||||||
|
background: palette("background-green-d5");
|
||||||
|
&::before { border-bottom-color: palette("background-green-d5"); }
|
||||||
|
&::after { border-top-color: palette("background-green-d5"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
$user-levels: (
|
||||||
|
"unactivated"
|
||||||
|
"blocked"
|
||||||
|
"member"
|
||||||
|
"privileged"
|
||||||
|
"former-staff"
|
||||||
|
"janitor"
|
||||||
|
"moderator"
|
||||||
|
"admin"
|
||||||
|
);
|
||||||
|
$user-level-text: (
|
||||||
|
"moderator": #ffffff,
|
||||||
|
"janitor": #ffffff,
|
||||||
|
);
|
||||||
|
|
||||||
|
.level-badge {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: black;
|
||||||
|
|
||||||
|
background: themed("color-user-member");
|
||||||
|
padding: 0.1rem 0.25rem;
|
||||||
|
@include st-radius;
|
||||||
|
|
||||||
|
@each $level in $user-levels {
|
||||||
|
&.level-#{$level} {
|
||||||
|
background: themed("color-user-" + $level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@each $level, $color in $user-level-text {
|
||||||
|
&.level-#{$level} {
|
||||||
|
color: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.level-unactivated {
|
||||||
|
background: themed("palette-background-red");
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
19
app/javascript/src/styles/views/posts/_posts.scss
Normal file
19
app/javascript/src/styles/views/posts/_posts.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Main themes
|
||||||
|
@import "index/index";
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
@import "index/index.desktop";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Features
|
||||||
|
@import "index/partials/mode_menu";
|
||||||
|
@import "index/partials/wiki_excerpt";
|
||||||
|
@import "index/partials/stats";
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
@include with-setting("fullscreen", "true") {
|
||||||
|
@import "index/partials/fullscreen";
|
||||||
|
}
|
||||||
|
@include with-setting("ssearch", "true") {
|
||||||
|
@import "index/partials/sticky";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
// Desktop-only
|
||||||
|
// Rollout at 50rem
|
||||||
|
.post-index {
|
||||||
|
grid-template-areas:
|
||||||
|
"search content"
|
||||||
|
"sidebar content";
|
||||||
|
grid-template-columns: 15rem 1fr;
|
||||||
|
grid-template-rows: min-content 1fr;
|
||||||
|
|
||||||
|
.search {
|
||||||
|
box-shadow: inset -0.25rem 0px 0.25rem -0.25rem themed("color-background");
|
||||||
|
padding: 0.5rem 0.75rem 0.5rem 0.5rem;
|
||||||
|
|
||||||
|
// Align the controls properly
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.search-controls {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
justify-content: right;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1.633rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
|
||||||
|
padding: 0.25rem;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
background: themed("color-foreground");
|
||||||
|
border-radius: 0 0 0.25rem 0.25rem;
|
||||||
|
|
||||||
|
button {
|
||||||
|
height: 1.5rem;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 1.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
margin: -0.125rem 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
box-shadow: inset -0.25rem 0px 0.25rem -0.25rem themed("color-background");
|
||||||
|
padding: 0.5rem 0.75rem 0.5rem 0.5rem;
|
||||||
|
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
|
padding: 0.5rem 0.75rem themed("content-padding-bottom");
|
||||||
|
}
|
||||||
|
}
|
108
app/javascript/src/styles/views/posts/index/_index.scss
Normal file
108
app/javascript/src/styles/views/posts/index/_index.scss
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
body.c-posts.a-index, body.c-favorites.a-index {
|
||||||
|
#page {
|
||||||
|
// Override the theme to instead
|
||||||
|
// project it upon the content area
|
||||||
|
background: var(--color-foreground);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exhibit A
|
||||||
|
// Makes the content area take up the
|
||||||
|
// full height of the page. Yes, really.
|
||||||
|
#page, #c-posts, #c-favorites, #a-index {
|
||||||
|
// I hate both this and myself
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Post gallery
|
||||||
|
.post-index {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
grid-template-areas:
|
||||||
|
"search "
|
||||||
|
"content"
|
||||||
|
"sidebar";
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: min-content 1fr min-content;
|
||||||
|
|
||||||
|
flex: 1; // See Exhibit A
|
||||||
|
|
||||||
|
// 1. Searchbox
|
||||||
|
.search {
|
||||||
|
grid-area: search;
|
||||||
|
|
||||||
|
padding: 0.5rem 0.25rem;
|
||||||
|
box-shadow: inset 0px -0.25rem 0.25rem -0.25rem themed("color-background");
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: $h3-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-controls { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Content
|
||||||
|
.content {
|
||||||
|
display: flex; // See Exhibit A
|
||||||
|
flex-flow: column;
|
||||||
|
|
||||||
|
grid-area: content;
|
||||||
|
|
||||||
|
// Imported from #page
|
||||||
|
padding: 0.5rem 0.25rem themed("content-padding-bottom");
|
||||||
|
background-color: #152f56;
|
||||||
|
background-color: themed("color-foreground");
|
||||||
|
background-image: themed("image-foreground");
|
||||||
|
background-position: themed("image-foreground-position");
|
||||||
|
background-repeat: themed("image-foreground-repeat");
|
||||||
|
|
||||||
|
// Quick tag edit
|
||||||
|
#edit-dialog textarea {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual content area:
|
||||||
|
// posts and pagination
|
||||||
|
.post-index-gallery {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
flex: 1; // See Exhibit A
|
||||||
|
|
||||||
|
.posts-container {
|
||||||
|
flex: 1; // See Exhibit A
|
||||||
|
grid-auto-rows: min-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Sidebar
|
||||||
|
.sidebar {
|
||||||
|
grid-area: sidebar;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
gap: 1em;
|
||||||
|
|
||||||
|
padding: 0.5rem 0.25rem;
|
||||||
|
box-shadow: inset 0px 0.25rem 0.25rem -0.25rem themed("color-background");
|
||||||
|
|
||||||
|
// By popular demand
|
||||||
|
font-size: 150%;
|
||||||
|
|
||||||
|
// Mode selection
|
||||||
|
#mode-box-mode, #mode-box #set-id {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
// Match the searchbox
|
||||||
|
padding: 0.5em;
|
||||||
|
font-family: $base_font_family;
|
||||||
|
font-size: 1.05em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// Fullscreen mode
|
||||||
|
// Only relevant on desktop
|
||||||
|
.post-index {
|
||||||
|
grid-template-areas:
|
||||||
|
"search "
|
||||||
|
"content";
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
border-radius: 0.25rem 0.25rem 0 0;
|
||||||
|
box-shadow: inset 0px -0.25rem 0.25rem -0.25rem themed("color-background");
|
||||||
|
|
||||||
|
margin: 0.25rem 0 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: right;
|
||||||
|
z-index: 11; // above posts and labels
|
||||||
|
|
||||||
|
.post-search { width: 100%; }
|
||||||
|
|
||||||
|
#search-fullscreen {
|
||||||
|
background: themed("color-button-active");
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-controls { right: 0.25rem; }
|
||||||
|
}
|
||||||
|
.sidebar { display: none; }
|
||||||
|
.content {
|
||||||
|
border-radius: 0 0 0.25rem 0.25rem;
|
||||||
|
.posts-index-stats { margin-right: 5rem; }
|
||||||
|
}
|
||||||
|
}
|
@ -32,4 +32,4 @@ $modes: (
|
|||||||
|
|
||||||
input { flex: 1; }
|
input { flex: 1; }
|
||||||
button { padding: 0 0.25em; }
|
button { padding: 0 0.25em; }
|
||||||
}
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
.posts-index-stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
|
||||||
|
margin: -0.5rem 0rem 0.25rem;
|
||||||
|
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 0.75rem;
|
||||||
|
color: #fffa;
|
||||||
|
font-family: monospace;
|
||||||
|
|
||||||
|
& > span { cursor: help; }
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
.post-index .search {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
background: themed("color-foreground");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
// on top of thumbnail labels
|
||||||
|
z-index: 11;
|
||||||
|
|
||||||
|
#search-sticky {
|
||||||
|
background: themed("color-button-active");
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-th-sheader="true"] {
|
||||||
|
.post-index .search { top: 3.75rem; }
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
.wiki-excerpt {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
background: themed("color-section");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
&.hidden { display: none; }
|
||||||
|
|
||||||
|
// header
|
||||||
|
h3 {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
transition: transform 0.25s;
|
||||||
|
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-excerpt-dismiss { margin-left: auto; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// body
|
||||||
|
.styled-dtext {
|
||||||
|
background: linear-gradient(to top, themed("color-section"), themed("color-text"));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
|
||||||
|
min-height: 0rem;
|
||||||
|
max-height: 0rem;
|
||||||
|
max-width: 50rem;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
|
||||||
|
transition: max-height 0.25s;
|
||||||
|
|
||||||
|
// Disable links
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: unset;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: unset;
|
||||||
|
text-decoration: underline;
|
||||||
|
&::after { content: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quote visual bug
|
||||||
|
blockquote { background: unset; }
|
||||||
|
|
||||||
|
// Remove offset caused by paragraphs
|
||||||
|
p:last-child { margin-bottom: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// wiki link
|
||||||
|
.wiki-excerpt-readmore {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
height: 3rem;
|
||||||
|
max-width: 50rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
// Makes the button appear in the middle of the animation
|
||||||
|
transition: visibility 0s 0.125s;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
background: themed("color-section");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open{
|
||||||
|
.wiki-excerpt-toggle svg { transform: rotate(90deg); }
|
||||||
|
.styled-dtext {
|
||||||
|
max-height: 10rem;
|
||||||
|
min-height: 2rem;
|
||||||
|
}
|
||||||
|
.wiki-excerpt-readmore { visibility: visible; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
h3::after, .styled-dtext { transition: none; }
|
||||||
|
}
|
||||||
|
}
|
2
app/javascript/src/styles/views/users/_users.scss
Normal file
2
app/javascript/src/styles/views/users/_users.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import "show/show";
|
||||||
|
@import "edit/edit";
|
200
app/javascript/src/styles/views/users/edit/_edit.scss
Normal file
200
app/javascript/src/styles/views/users/edit/_edit.scss
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
body.c-users.a-edit {
|
||||||
|
|
||||||
|
form.simple_form {
|
||||||
|
background: unset;
|
||||||
|
padding: unset;
|
||||||
|
margin: unset;
|
||||||
|
|
||||||
|
input[type="text"], input[type="number"], textarea, select {
|
||||||
|
width: 100%;
|
||||||
|
max-width: unset;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-account-buttons tab-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
.st-button {
|
||||||
|
white-space: nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tab-submit {
|
||||||
|
input[type="submit"] {
|
||||||
|
background: themed("color-tag-artist");
|
||||||
|
font-size: 1.25rem;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
margin: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
&:hover, &:active { background: themed("color-tag-artist-alt"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Tabs section
|
||||||
|
tabs-menu {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 50rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
// TODO Smooth drag when overflowing
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
& > button {
|
||||||
|
background: unset;
|
||||||
|
color: themed("color-link");
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-bottom: 2px solid themed("color-section");
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: themed("color-section");
|
||||||
|
border-radius: 0.25rem 0.25rem 0 0;
|
||||||
|
&:first-child {
|
||||||
|
border-bottom-left-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span.spacer {
|
||||||
|
flex: 1;
|
||||||
|
border-bottom: 2px solid themed("color-section");
|
||||||
|
}
|
||||||
|
|
||||||
|
input[name="search"] {
|
||||||
|
border-radius: 0 0 0.25rem 0.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tabs structure
|
||||||
|
tabs-content {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
max-width: 50rem;
|
||||||
|
|
||||||
|
tab-group {
|
||||||
|
display: none;
|
||||||
|
&.active { display: flex; }
|
||||||
|
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
padding: 0.5rem 0.75rem 0.5rem;
|
||||||
|
margin: 0.5rem 0 0;
|
||||||
|
|
||||||
|
background: themed("color-section-lighten-5");
|
||||||
|
border-radius: 0.25rem 0.25rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tab-entry {
|
||||||
|
display: none !important;
|
||||||
|
&.active { display: grid !important; }
|
||||||
|
&.flex.active { display: flex !important; }
|
||||||
|
grid-template-areas: "head" "body" "hint";
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
background: themed("color-section");
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
tab-head {
|
||||||
|
grid-area: head;
|
||||||
|
margin-left: 0.25em;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
|
||||||
|
label { font-weight: normal; }
|
||||||
|
}
|
||||||
|
|
||||||
|
tab-body {
|
||||||
|
grid-area: body;
|
||||||
|
}
|
||||||
|
|
||||||
|
tab-hint {
|
||||||
|
grid-area: hint;
|
||||||
|
|
||||||
|
font-size: 90%;
|
||||||
|
color: themed("color-text-muted");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.inline {
|
||||||
|
grid-template-areas: "head body" "hint hint";
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
|
||||||
|
tab-body { justify-self: end; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.blocky {
|
||||||
|
grid-template-areas: "body";
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bigtext {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-areas: "head" "body" "hint";
|
||||||
|
}
|
||||||
|
|
||||||
|
&.buttony tab-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 4rem;
|
||||||
|
|
||||||
|
input[type="text"] { border-radius: 0.25rem 0 0 0.25rem !important; }
|
||||||
|
input[disabled] { cursor: not-allowed; }
|
||||||
|
a.st-button {
|
||||||
|
border-radius: 0 0.25rem 0.25rem 0 !important;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tab-submit {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
|
||||||
|
background: themed("color-section");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
width: min-content;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
tabs-menu {
|
||||||
|
input[name="search"] {
|
||||||
|
width: unset;
|
||||||
|
border-radius: 0.25rem 0.25rem 0.25rem 0;
|
||||||
|
border-bottom: 2px solid themed("color-section");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs-content {
|
||||||
|
tab-entry {
|
||||||
|
grid-template-areas: "head body" ". hint";
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
&.inline {
|
||||||
|
grid-template-areas: "head hint body";
|
||||||
|
grid-template-columns: 8fr 7fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
app/javascript/src/styles/views/users/show/_show.scss
Normal file
10
app/javascript/src/styles/views/users/show/_show.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
body.c-users.a-show {
|
||||||
|
|
||||||
|
@import "partials/about";
|
||||||
|
@import "partials/ban_banner";
|
||||||
|
@import "partials/card";
|
||||||
|
@import "partials/post_summary";
|
||||||
|
@import "partials/profile_section";
|
||||||
|
@import "partials/staff_info";
|
||||||
|
@import "partials/user_info";
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
tabs-menu, tabs-content {
|
||||||
|
max-width: 100rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-tabs[data-has-about="false"][data-has-artinfo="false"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-about-section, .profile-artinfo-section {
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
tab-head {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
tabs-menu { display: none; }
|
||||||
|
tabs-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 15rem 1fr;
|
||||||
|
grid-template-rows: min-content min-content;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-user-info {
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-areas: unset;
|
||||||
|
grid-row: 1 / 4;
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-about-section {
|
||||||
|
display: flex !important;
|
||||||
|
grid-column: 2 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-artinfo-section {
|
||||||
|
display: flex !important;
|
||||||
|
grid-column: 2 / -1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
.profile-ban {
|
||||||
|
background: var(--palette-background-red);
|
||||||
|
padding: 0.5rem;
|
||||||
|
@include st-radius;
|
||||||
|
|
||||||
|
.styled-dtext p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
.profile-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content auto;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
// Info block
|
||||||
|
.profile-info {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-name {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: themed("color-text");
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-joined {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: themed("color-text-muted");
|
||||||
|
margin-top: -0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-quickie {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry > a {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"icon header"
|
||||||
|
"icon title ";
|
||||||
|
column-gap: 0.25rem;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 7rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
@include st-radius;
|
||||||
|
background: themed("color-section");
|
||||||
|
|
||||||
|
&:hover { background: themed("color-section-lighten-5"); }
|
||||||
|
|
||||||
|
.entry-icon {
|
||||||
|
grid-area: icon;
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
color: themed("color-link-active");
|
||||||
|
}
|
||||||
|
.entry-header {
|
||||||
|
grid-area: header;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
line-height: 1.1rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.entry-title {
|
||||||
|
grid-area: title;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 0.9rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-extra {
|
||||||
|
a, a:visited { color: themed("color-text-muted"); }
|
||||||
|
a:hover, a:active { color: themed("color-link-active"); }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
.posts-section {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
gap: 1em;
|
||||||
|
|
||||||
|
// Hack to fix spacing on mobile
|
||||||
|
margin-top: 1rem;
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sample {
|
||||||
|
display: grid;
|
||||||
|
grid-template: "p-header"
|
||||||
|
"p-links"
|
||||||
|
"p-posts";
|
||||||
|
gap: 0.5em 0;
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
grid-template: "p-header p-links"
|
||||||
|
"p-posts p-posts";
|
||||||
|
grid-template-columns: 12em 1fr;
|
||||||
|
gap: 0 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sample-header a, .profile-sample-links a {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-content: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
padding: 0.5em;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: themed("color-section");
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: themed("color-section-lighten-5");
|
||||||
|
}
|
||||||
|
&:focus, &:active {
|
||||||
|
outline: 0;
|
||||||
|
color: themed("color-link-active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sample-header {
|
||||||
|
grid-area: p-header;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(800px) {
|
||||||
|
a { border-radius: 6px 6px 0 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sample-links {
|
||||||
|
grid-area: p-links;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding: 0.5em;
|
||||||
|
color: themed("color-text-muted");
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer { display: none; }
|
||||||
|
.profile-comments-link {
|
||||||
|
grid-row: 1 / 3;
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
display: flex;
|
||||||
|
a { height: min-content; }
|
||||||
|
.spacer { display: block; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sample-posts {
|
||||||
|
grid-area: p-posts;
|
||||||
|
display: flex;
|
||||||
|
overflow: auto;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
gap: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
|
background: var(--color-section);
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
// Desktop
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
.profile-section {
|
||||||
|
background: themed("color-section");
|
||||||
|
|
||||||
|
.profile-section-header {
|
||||||
|
background: themed("color-section-lighten-5");
|
||||||
|
@include st-radius;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "⮟";
|
||||||
|
display: inline-flex;
|
||||||
|
transition: transform 200ms;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-section-body {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 0 0 radius() radius();
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collapsed
|
||||||
|
&.hidden {
|
||||||
|
.profile-section-header::before {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-section-body {
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
.profile-staff-info {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
gap: 0.25rem 1rem;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block { grid-column: 1 / -1; }
|
||||||
|
h4.block { margin-bottom: -0.25rem; }
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
grid-template-columns: min-content 1fr min-content 1fr;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
.profile-user-info {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: repeat(auto-fit, minmax(min-content, 5rem));
|
||||||
|
background: themed("color-section");
|
||||||
|
@include st-radius;
|
||||||
|
|
||||||
|
@include window-larger-than(38rem) { grid-template-columns: 1fr 1fr; }
|
||||||
|
@include window-larger-than(50rem) { grid-template-columns: 1fr; }
|
||||||
|
|
||||||
|
.profile-line {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr min-content;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
border-bottom: 2px solid themed("color-foreground");
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
// Not necessary, but it aligns
|
||||||
|
// with the -extra line better
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25em;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-number {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-extra {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
font-size: 90%;
|
||||||
|
color: themed("color-text-muted");
|
||||||
|
|
||||||
|
margin-left: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stats display section
|
||||||
|
&-show {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem 2rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
text-align: center;
|
||||||
|
width: 5rem;
|
||||||
|
& > span { color: themed("color-text-muted"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dot-separated, less important
|
||||||
|
&-list {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25em;
|
||||||
|
|
||||||
|
a:not(:last-child)::after {
|
||||||
|
content: "•";
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
color: themed("color-text-muted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child { border-bottom: none; }
|
||||||
|
}
|
||||||
|
}
|
@ -487,6 +487,8 @@ class Artist < ApplicationRecord
|
|||||||
|
|
||||||
if params[:is_linked].to_s.truthy?
|
if params[:is_linked].to_s.truthy?
|
||||||
q = q.where("linked_user_id IS NOT NULL")
|
q = q.where("linked_user_id IS NOT NULL")
|
||||||
|
elsif params[:is_linked].to_s.falsy?
|
||||||
|
q = q.where("linked_user_id IS NULL")
|
||||||
end
|
end
|
||||||
|
|
||||||
case params[:order]
|
case params[:order]
|
||||||
|
@ -80,10 +80,14 @@ class Tag < ApplicationRecord
|
|||||||
|
|
||||||
def category_for(tag_name)
|
def category_for(tag_name)
|
||||||
Cache.fetch("tc:#{tag_name}") do
|
Cache.fetch("tc:#{tag_name}") do
|
||||||
Tag.where(name: tag_name).pick(:category).to_i
|
category_for!(tag_name).to_i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def category_for!(tag_name)
|
||||||
|
Tag.where(name: tag_name).pick(:category)
|
||||||
|
end
|
||||||
|
|
||||||
def categories_for(tag_names, disable_cache: false)
|
def categories_for(tag_names, disable_cache: false)
|
||||||
if disable_cache
|
if disable_cache
|
||||||
tag_cats = {}
|
tag_cats = {}
|
||||||
|
@ -574,6 +574,11 @@ class User < ApplicationRecord
|
|||||||
base_upload_limit + (pieces[:approved] / 10) - (pieces[:deleted] / 4) - pieces[:pending]
|
base_upload_limit + (pieces[:approved] / 10) - (pieces[:deleted] / 4) - pieces[:pending]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload_limit_max
|
||||||
|
pieces = upload_limit_pieces
|
||||||
|
base_upload_limit + (pieces[:approved] / 10) - (pieces[:deleted] / 4)
|
||||||
|
end
|
||||||
|
|
||||||
def upload_limit_pieces
|
def upload_limit_pieces
|
||||||
@upload_limit_pieces ||= begin
|
@upload_limit_pieces ||= begin
|
||||||
deleted_count = Post.deleted.for_user(id).count
|
deleted_count = Post.deleted.for_user(id).count
|
||||||
@ -739,6 +744,28 @@ class User < ApplicationRecord
|
|||||||
user_status.ticket_count
|
user_status.ticket_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def feedback_pieces
|
||||||
|
@feedback_pieces ||= begin
|
||||||
|
count = {
|
||||||
|
deleted: 0,
|
||||||
|
negative: 0,
|
||||||
|
neutral: 0,
|
||||||
|
positive: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
feedback.each do |one|
|
||||||
|
if one.is_deleted
|
||||||
|
count[:deleted] += 1
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
count[one.category.to_sym] += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def positive_feedback_count
|
def positive_feedback_count
|
||||||
feedback.active.positive.count
|
feedback.active.positive.count
|
||||||
end
|
end
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class WikiPage < ApplicationRecord
|
class WikiPage < ApplicationRecord
|
||||||
class RevertError < Exception ; end
|
class RevertError < Exception; end
|
||||||
|
|
||||||
before_validation :normalize_title
|
before_validation :normalize_title
|
||||||
before_validation :normalize_other_names
|
before_validation :normalize_other_names
|
||||||
before_validation :normalize_parent
|
before_validation :normalize_parent
|
||||||
|
before_save :log_changes
|
||||||
|
before_save :update_tag, if: :tag_changed?
|
||||||
|
before_destroy :validate_not_used_as_help_page
|
||||||
|
before_destroy :log_destroy
|
||||||
after_save :create_version
|
after_save :create_version
|
||||||
|
after_save :update_help_page, if: :saved_change_to_title?
|
||||||
|
|
||||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||||
validates :title, uniqueness: { :case_sensitive => false }
|
|
||||||
|
validates :title, uniqueness: { case_sensitive: false }
|
||||||
validates :title, presence: true
|
validates :title, presence: true
|
||||||
validates :title, tag_name: true, if: :title_changed?
|
validates :title, tag_name: true, if: :title_changed?
|
||||||
validates :body, presence: { unless: -> { is_deleted? || other_names.present? || parent.present? } }
|
validates :body, presence: { unless: -> { is_deleted? || other_names.present? || parent.present? } }
|
||||||
@ -19,12 +26,8 @@ class WikiPage < ApplicationRecord
|
|||||||
validate :validate_redirect
|
validate :validate_redirect
|
||||||
validate :validate_not_locked
|
validate :validate_not_locked
|
||||||
|
|
||||||
before_destroy :validate_not_used_as_help_page
|
|
||||||
before_destroy :log_destroy
|
|
||||||
before_save :log_changes
|
|
||||||
after_save :update_help_page, if: :saved_change_to_title?
|
|
||||||
|
|
||||||
attr_accessor :skip_secondary_validations, :edit_reason
|
attr_accessor :skip_secondary_validations, :edit_reason
|
||||||
|
|
||||||
array_attribute :other_names
|
array_attribute :other_names
|
||||||
belongs_to_creator
|
belongs_to_creator
|
||||||
belongs_to_updater
|
belongs_to_updater
|
||||||
@ -33,19 +36,19 @@ class WikiPage < ApplicationRecord
|
|||||||
has_many :versions, -> { order("wiki_page_versions.id ASC") }, class_name: "WikiPageVersion", dependent: :destroy
|
has_many :versions, -> { order("wiki_page_versions.id ASC") }, class_name: "WikiPageVersion", dependent: :destroy
|
||||||
has_one :help_page, foreign_key: "wiki_page", primary_key: "title"
|
has_one :help_page, foreign_key: "wiki_page", primary_key: "title"
|
||||||
|
|
||||||
def log_destroy
|
|
||||||
ModAction.log(:wiki_page_delete, {wiki_page: title, wiki_page_id: id})
|
|
||||||
end
|
|
||||||
|
|
||||||
def log_changes
|
def log_changes
|
||||||
if title_changed? && !new_record?
|
if title_changed? && !new_record?
|
||||||
ModAction.log(:wiki_page_rename, {new_title: title, old_title: title_was})
|
ModAction.log(:wiki_page_rename, { new_title: title, old_title: title_was })
|
||||||
end
|
end
|
||||||
if is_locked_changed?
|
if is_locked_changed?
|
||||||
ModAction.log(is_locked ? :wiki_page_lock : :wiki_page_unlock, {wiki_page: title})
|
ModAction.log(is_locked ? :wiki_page_lock : :wiki_page_unlock, { wiki_page: title })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def log_destroy
|
||||||
|
ModAction.log(:wiki_page_delete, { wiki_page: title, wiki_page_id: id })
|
||||||
|
end
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
def titled(title)
|
def titled(title)
|
||||||
find_by(title: WikiPage.normalize_name(title))
|
find_by(title: WikiPage.normalize_name(title))
|
||||||
@ -123,7 +126,7 @@ class WikiPage < ApplicationRecord
|
|||||||
|
|
||||||
module ApiMethods
|
module ApiMethods
|
||||||
def method_attributes
|
def method_attributes
|
||||||
super + [:creator_name, :category_id]
|
super + %i[creator_name category_id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -140,9 +143,92 @@ class WikiPage < ApplicationRecord
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module TagMethods
|
||||||
|
def tag
|
||||||
|
@tag ||= super
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_id
|
||||||
|
return @category_id if instance_variable_defined?(:@category_id)
|
||||||
|
@category_id = tag&.category
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_id=(value)
|
||||||
|
return if value.blank? || value.to_i == category_id
|
||||||
|
category_id_will_change!
|
||||||
|
@category_id = value.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_is_locked
|
||||||
|
return @category_is_locked if instance_variable_defined?(:@category_is_locked)
|
||||||
|
@category_is_locked = tag&.is_locked || false
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_is_locked=(value)
|
||||||
|
return if value == category_is_locked
|
||||||
|
category_is_locked_will_change!
|
||||||
|
@category_is_locked = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_id_changed?
|
||||||
|
attribute_changed?("category_id")
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_id_will_change!
|
||||||
|
attribute_will_change!("category_id")
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_is_locked_changed?
|
||||||
|
attribute_changed?("category_is_locked")
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_is_locked_will_change!
|
||||||
|
attribute_will_change!("category_is_locked")
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_update_map
|
||||||
|
{}.tap do |updates|
|
||||||
|
updates[:category] = @category_id if category_id_changed?
|
||||||
|
updates[:is_locked] = @category_is_locked if category_is_locked_changed?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_changed?
|
||||||
|
tag_update_map.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_tag
|
||||||
|
updates = tag_update_map
|
||||||
|
@tag = Tag.find_or_create_by_name(title)
|
||||||
|
|
||||||
|
return if updates.empty?
|
||||||
|
unless @tag.category_editable_by?(CurrentUser.user)
|
||||||
|
reload_tag_attributes
|
||||||
|
errors.add(:category_id, "Cannot be changed")
|
||||||
|
throw(:abort)
|
||||||
|
end
|
||||||
|
|
||||||
|
@tag.update(updates)
|
||||||
|
@tag.save
|
||||||
|
|
||||||
|
if @tag.invalid?
|
||||||
|
errors.add(:category_id, @tag.errors.full_messages.join(", "))
|
||||||
|
throw(:abort)
|
||||||
|
end
|
||||||
|
|
||||||
|
reload_tag_attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def reload_tag_attributes
|
||||||
|
remove_instance_variable(:@category_id) if instance_variable_defined?(:@category_id)
|
||||||
|
remove_instance_variable(:@category_is_locked) if instance_variable_defined?(:@category_is_locked)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
extend SearchMethods
|
extend SearchMethods
|
||||||
include ApiMethods
|
include ApiMethods
|
||||||
include HelpPageMethods
|
include HelpPageMethods
|
||||||
|
include TagMethods
|
||||||
|
|
||||||
def user_not_limited
|
def user_not_limited
|
||||||
allowed = CurrentUser.can_wiki_edit_with_reason
|
allowed = CurrentUser.can_wiki_edit_with_reason
|
||||||
@ -156,7 +242,7 @@ class WikiPage < ApplicationRecord
|
|||||||
def validate_not_locked
|
def validate_not_locked
|
||||||
if is_locked? && !CurrentUser.is_janitor?
|
if is_locked? && !CurrentUser.is_janitor?
|
||||||
errors.add(:is_locked, "and cannot be updated")
|
errors.add(:is_locked, "and cannot be updated")
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -203,7 +289,12 @@ class WikiPage < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def normalize_title
|
def normalize_title
|
||||||
self.title = title.downcase.tr(" ", "_")
|
title = self.title.downcase.tr(" ", "_")
|
||||||
|
if title =~ /\A(#{Tag.categories.regexp}):(.+)\Z/
|
||||||
|
self.category_id = Tag.categories.value_for($1)
|
||||||
|
title = $2
|
||||||
|
end
|
||||||
|
self.title = title
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize_other_names
|
def normalize_other_names
|
||||||
@ -226,16 +317,12 @@ class WikiPage < ApplicationRecord
|
|||||||
@skip_secondary_validations = value.to_s.truthy?
|
@skip_secondary_validations = value.to_s.truthy?
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_id
|
|
||||||
Tag.category_for(title)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pretty_title
|
def pretty_title
|
||||||
title&.tr("_", " ") || ''
|
title&.tr("_", " ") || ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def pretty_title_with_category
|
def pretty_title_with_category
|
||||||
return pretty_title if category_id == 0
|
return pretty_title if category_id.blank? || category_id == 0
|
||||||
"#{Tag.category_for_value(category_id)}: #{pretty_title}"
|
"#{Tag.category_for_value(category_id)}: #{pretty_title}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -274,10 +361,6 @@ class WikiPage < ApplicationRecord
|
|||||||
else
|
else
|
||||||
match
|
match
|
||||||
end
|
end
|
||||||
end.map {|x| x.downcase.tr(" ", "_").to_s}.uniq
|
end.map { |x| x.downcase.tr(" ", "_").to_s }.uniq
|
||||||
end
|
|
||||||
|
|
||||||
def visible?
|
|
||||||
true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,6 @@ class WikiPageVersion < ApplicationRecord
|
|||||||
belongs_to_updater
|
belongs_to_updater
|
||||||
user_status_counter :wiki_edit_count, foreign_key: :updater_id
|
user_status_counter :wiki_edit_count, foreign_key: :updater_id
|
||||||
belongs_to :artist, optional: true
|
belongs_to :artist, optional: true
|
||||||
delegate :visible?, to: :wiki_page
|
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
def for_user(user_id)
|
def for_user(user_id)
|
||||||
|
@ -53,6 +53,11 @@ class UserPresenter
|
|||||||
= <abbr title="User Upload Limit Remaining">#{user.upload_limit}</abbr>}.html_safe
|
= <abbr title="User Upload Limit Remaining">#{user.upload_limit}</abbr>}.html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload_limit_short
|
||||||
|
return "none" if user.can_upload_free?
|
||||||
|
"#{user.upload_limit} / #{user.upload_limit_max}"
|
||||||
|
end
|
||||||
|
|
||||||
def uploads
|
def uploads
|
||||||
posts = Post.tag_match("user:#{user.name}").limit(8)
|
posts = Post.tag_match("user:#{user.name}").limit(8)
|
||||||
PostsDecorator.decorate_collection(posts)
|
PostsDecorator.decorate_collection(posts)
|
||||||
|
34
app/views/application/_feedback_badge.erb
Normal file
34
app/views/application/_feedback_badge.erb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<a
|
||||||
|
href="<%= user_feedbacks_path(search: { user_id: user.id }) %>"
|
||||||
|
class="user-records-list"
|
||||||
|
data-negative="<%= negative %>"
|
||||||
|
data-neutral="<%= negative %>"
|
||||||
|
data-positive="<%= neutral %>"
|
||||||
|
data-total="<%= positive - negative %>"
|
||||||
|
>
|
||||||
|
<% if deleted > 0 %>
|
||||||
|
<span class="user-record deleted"><%= deleted %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if negative > 0 %>
|
||||||
|
<span class="user-record negative"><%= negative %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if neutral > 0 %>
|
||||||
|
<span class="user-record neutral"><%= neutral %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if positive > 0 %>
|
||||||
|
<span class="user-record positive"><%= positive %></span>
|
||||||
|
<% end %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<% if CurrentUser.is_moderator? && CurrentUser.user != user && active == 0 %>
|
||||||
|
<a
|
||||||
|
href="<%= new_user_feedback_path(user_feedback: { user_id: user.id, category: "neutral" }) %>"
|
||||||
|
class="user-records-list"
|
||||||
|
title="New Feedback"
|
||||||
|
>
|
||||||
|
<span class="user-record neutral"><%= svg_icon(:plus) %></span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
11
app/views/application/_profile_avatar.erb
Normal file
11
app/views/application/_profile_avatar.erb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<a
|
||||||
|
href="<%= user_path(user) %>"
|
||||||
|
class="profile-avatar placeholder<%= klass.nil? ? "" : klass%>"
|
||||||
|
data-id="<%= post_id %>"
|
||||||
|
data-name="<%= user.name %>"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="avatar-image"
|
||||||
|
data-initial="<%= user.name[0].capitalize%>"
|
||||||
|
></span>
|
||||||
|
</a>
|
@ -3,6 +3,6 @@
|
|||||||
<%= f.input :url_matches, label: "URL", as: :string %>
|
<%= f.input :url_matches, label: "URL", as: :string %>
|
||||||
<%= f.user :creator %>
|
<%= f.user :creator %>
|
||||||
<%= f.input :has_tag, label: "Has tag?", collection: [["Yes", true], ["No", false]], include_blank: true %>
|
<%= f.input :has_tag, label: "Has tag?", collection: [["Yes", true], ["No", false]], include_blank: true %>
|
||||||
<%= f.input :is_linked, label: "Linked Only", as: :boolean %>
|
<%= f.input :is_linked, label: "Linked?", collection: [["Yes", true], ["No", false]], include_blank: true %>
|
||||||
<%= f.input :order, collection: [["Recently created", "created_at"], ["Last updated", "updated_at"], ["Name", "name"], ["Post count", "post_count"]] %>
|
<%= f.input :order, collection: [["Recently created", "created_at"], ["Last updated", "updated_at"], ["Name", "name"], ["Post count", "post_count"]] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
<% if CurrentUser.is_anonymous? %>
|
||||||
|
<%= decorated_nav_link_to("Log In", :log_in, new_session_path, class: "nav-hidden") %>
|
||||||
|
<% else %>
|
||||||
|
<%= decorated_nav_link_to("Profile", :user, user_path(CurrentUser.user), class: "nav-hidden") %>
|
||||||
|
<% end %>
|
||||||
|
<%= decorated_nav_link_to("Artists", :brush, artists_path) %>
|
||||||
<%= decorated_nav_link_to("Posts", :images, posts_path) %>
|
<%= decorated_nav_link_to("Posts", :images, posts_path) %>
|
||||||
<%= decorated_nav_link_to("Pools", :library, gallery_pools_path) %>
|
<%= decorated_nav_link_to("Pools", :library, gallery_pools_path) %>
|
||||||
<%= decorated_nav_link_to("Sets", :group, post_sets_path) %>
|
<%= decorated_nav_link_to("Sets", :group, post_sets_path) %>
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
</a>
|
</a>
|
||||||
<% if CurrentUser.is_anonymous? %>
|
<% if CurrentUser.is_anonymous? %>
|
||||||
<a href="<%= new_session_path %>" class="simple-avatar nav-controls-profile collapse-2">
|
<a href="<%= new_session_path %>" class="simple-avatar nav-controls-profile collapse-2">
|
||||||
<span class="simple-avatar-button sign-in">
|
<span class="avatar-button sign-in">
|
||||||
<span class="simple-avatar-name">
|
<span class="avatar-name">
|
||||||
Sign In
|
Sign In
|
||||||
</span>
|
</span>
|
||||||
<span class="simple-avatar-image">
|
<span class="avatar-image">
|
||||||
<%= svg_icon(:log_in) %>
|
<%= svg_icon(:log_in) %>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
"th-sheader": localStorage.getItem("theme-sheader") || false,
|
"th-sheader": localStorage.getItem("theme-sheader") || false,
|
||||||
"th-forumnotif": localStorage.getItem("theme-forumnotif") || false,
|
"th-forumnotif": localStorage.getItem("theme-forumnotif") || false,
|
||||||
"th-palette": localStorage.getItem("theme-palette") || "default",
|
"th-palette": localStorage.getItem("theme-palette") || "default",
|
||||||
|
"th-font": localStorage.getItem("theme-font") || "Verdana",
|
||||||
"th-nav": localStorage.getItem("theme-nav") || "top",
|
"th-nav": localStorage.getItem("theme-nav") || "top",
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
"st-fullscreen": localStorage.getItem("e6.posts.fusk") || false,
|
"st-fullscreen": localStorage.getItem("e6.posts.fusk") || false,
|
||||||
|
"st-ssearch": localStorage.getItem("e6.posts.ssearch") || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
var b = document.body;
|
var b = document.body;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<%= render "ads/leaderboard", tag_string: @post_set.ad_tag_string %>
|
<%= render "ads/leaderboard", tag_string: @post_set.ad_tag_string %>
|
||||||
<%= render "posts/partials/index/edit" %>
|
<%= render "posts/partials/index/edit" %>
|
||||||
|
<%= render "posts/partials/index/stats", :post_set => @post_set %>
|
||||||
<%= render "posts/partials/index/posts", :post_set => @post_set %>
|
<%= render "posts/partials/index/posts", :post_set => @post_set %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= text_area_tag("tags", tags, placeholder: "Search posts by tag (title:\"video name\")", rows: 1, data: { shortcut: "q", autocomplete: "tag-query" }) %>
|
<%= text_area_tag("tags", tags, placeholder: "Search posts by tag (title:\"video name\")", rows: 1, data: { shortcut: "q", autocomplete: "tag-query" }) %>
|
||||||
<%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit", title: "Search") %>
|
<%= tag.button(svg_icon(:search), type: "submit", title: "Search") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<div class="search-controls">
|
<div class="search-controls">
|
||||||
<button id="search-fullscreen" class="st-button w100 stealth">
|
<button id="search-fullscreen" class="st-button" title="Fullscreen mode">
|
||||||
<%= svg_icon(:fullscreen) %>
|
<%= svg_icon(:fullscreen) %>
|
||||||
<span>Fullscreen</span>
|
</button>
|
||||||
|
<button id="search-sticky" class="st-button" title="Sticky searchbar">
|
||||||
|
<%= svg_icon(:anchor) %>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
3
app/views/posts/partials/index/_stats.html.erb
Normal file
3
app/views/posts/partials/index/_stats.html.erb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div class="posts-index-stats">
|
||||||
|
<%= approximate_count(post_set.posts) %>
|
||||||
|
</div>
|
@ -1,15 +1,12 @@
|
|||||||
<% if CurrentUser.can_view_staff_notes? %>
|
<% if CurrentUser.can_view_staff_notes? %>
|
||||||
<div class="staff-notes-section styled-dtext">
|
<div class="profile-section hidden" name="StaffNotes">
|
||||||
<details>
|
<div class="profile-section-header">Staff Notes (<%= user.staff_notes.count %>)</div>
|
||||||
<summary>Staff Notes (<%= user.staff_notes.count %>)</summary>
|
<div class="profile-section-body styled-dtext">
|
||||||
<div>
|
<%= render "staff_notes/partials/list_of_notes", staff_notes: user.staff_notes.limit(15), show_receiver_name: false %>
|
||||||
<h4><%= link_to "Staff Notes", staff_notes_path(search: { user_id: user.id }) %></h4>
|
<div class="new-staff-note">
|
||||||
<%= render "staff_notes/partials/list_of_notes", staff_notes: user.staff_notes.limit(15), show_receiver_name: false %>
|
<p><%= link_to "Create »", new_staff_note_path(search: { user_id: user.id }), class: "expand-new-staff-note" %></p>
|
||||||
<div class="new-staff-note">
|
<%= render "staff_notes/partials/new", user: user, staff_note: StaffNote.new(user_id: user.id), hidden: true %>
|
||||||
<p><%= link_to "Create »", new_staff_note_path(search: { user_id: user.id }), class: "expand-new-staff-note" %></p>
|
</div>
|
||||||
<%= render "staff_notes/partials/new", user: user, staff_note: StaffNote.new(user_id: user.id), hidden: true %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<!-- Primary Searchbar -->
|
<!-- Primary Searchbar -->
|
||||||
<div class="home-search">
|
<div class="home-search">
|
||||||
<%= text_field_tag("tags", "", autofocus: "autofocus", placeholder: "Search posts by tag (title:\"video name\")", data: { shortcut: "q", autocomplete: "tag-query" }) %>
|
<%= text_field_tag("tags", "", autofocus: "autofocus", placeholder: "Search posts by tag (title:\"video name\")", data: { shortcut: "q", autocomplete: "tag-query" }) %>
|
||||||
<%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit") %>
|
<%= tag.button(svg_icon(:search), type: "submit") %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Secondary search buttons -->
|
<!-- Secondary search buttons -->
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
This means that they will not persist across multiple devices, or in incognito mode.
|
This means that they will not persist across multiple devices, or in incognito mode.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label for="theme_main">Theme</label>
|
<label for="Theme_Main">Theme</label>
|
||||||
<select id="theme_main">
|
<select id="Theme_Main">
|
||||||
<option value="hexagon">Hexagon</option>
|
<option value="hexagon">Hexagon</option>
|
||||||
<option value="bloodlust">Bloodlust</option>
|
<option value="bloodlust">Bloodlust</option>
|
||||||
<option value="pony">Pony</option>
|
<option value="pony">Pony</option>
|
||||||
@ -25,8 +25,8 @@
|
|||||||
<option value="hotdog">Hotdog</option>
|
<option value="hotdog">Hotdog</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="theme_extra">Embellishments</label>
|
<label for="Theme_Extra">Embellishments</label>
|
||||||
<select id="theme_extra">
|
<select id="Theme_Extra">
|
||||||
<option value="none">(None)</option>
|
<option value="none">(None)</option>
|
||||||
<option value="aurora">Aurora</option>
|
<option value="aurora">Aurora</option>
|
||||||
<option value="autumn">Autumn</option>
|
<option value="autumn">Autumn</option>
|
||||||
@ -37,42 +37,68 @@
|
|||||||
<option value="winter">Eternal Winter</option>
|
<option value="winter">Eternal Winter</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="theme_stickyheader">Sticky Header</label>
|
|
||||||
<select id="theme_stickyheader">
|
|
||||||
<option value="false">Disabled</option>
|
|
||||||
<option value="true">Enabled</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<label for="theme_forumnotif">Forum Activity Dot</label>
|
|
||||||
<select id="theme_forumnotif">
|
|
||||||
<option value="false">Disabled</option>
|
|
||||||
<option value="true">Enabled</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<h3>Accessibility</h3>
|
<h3>Accessibility</h3>
|
||||||
<label for="theme_palette">Palette</label>
|
<label for="Theme_Palette">Palette</label>
|
||||||
<select id="theme_palette">
|
<select id="Theme_Palette">
|
||||||
<option value="default">Default</option>
|
<option value="default">Default</option>
|
||||||
<option value="deut">Protanopia & Deuteranopia</option>
|
<option value="deut">Protanopia & Deuteranopia</option>
|
||||||
<option value="trit">Tritanopia</option>
|
<option value="trit">Tritanopia</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<label for="Theme_Font">Font</label>
|
||||||
|
<select id="Theme_Font">
|
||||||
|
<option value="Verdana">Verdana</option>
|
||||||
|
<option value="Lato">Lato</option>
|
||||||
|
<option value="Lexend">Lexend</option>
|
||||||
|
<option value="Monospace">Monospace</option>
|
||||||
|
<option value="OpenDyslexic">Open Dyslexic</option>
|
||||||
|
<option value="OpenSans">Open Sans</option>
|
||||||
|
<option value="ComicSans">Comic Sans</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Features</h3>
|
||||||
|
<label for="Theme_ForumNotif">Forum Activity Dot</label>
|
||||||
|
<select id="Theme_ForumNotif">
|
||||||
|
<option value="false">Disabled</option>
|
||||||
|
<option value="true">Enabled</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="Posts_WikiExcerpt">Wiki Excerpt</label>
|
||||||
|
<select id="Posts_WikiExcerpt">
|
||||||
|
<option value="0">Collapsed</option>
|
||||||
|
<option value="1">Expanded</option>
|
||||||
|
<option value="2">Disabled</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<h3>Navigation</h3>
|
<h3>Navigation</h3>
|
||||||
<label for="theme_navbar">Navbar location</label>
|
<label for="Theme_StickyHeader">Sticky Header</label>
|
||||||
<select id="theme_navbar">
|
<select id="Theme_StickyHeader">
|
||||||
|
<option value="false">Disabled</option>
|
||||||
|
<option value="true">Enabled</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="Posts_StickySearch">Sticky Searchbar</label>
|
||||||
|
<select id="Posts_StickySearch">
|
||||||
|
<option value="false">Disabled</option>
|
||||||
|
<option value="true">Enabled</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="Theme_Navbar">Navbar location</label>
|
||||||
|
<select id="Theme_Navbar">
|
||||||
<option value="top">Top (default)</option>
|
<option value="top">Top (default)</option>
|
||||||
<option value="bottom">Bottom</option>
|
<option value="bottom">Bottom</option>
|
||||||
<option value="both">Both</option>
|
<option value="both">Both</option>
|
||||||
<option value="none">Off (not recommended)</option>
|
<option value="none">Off (not recommended)</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="theme_gestures">Mobile Gestures</label>
|
<label for="Theme_Gestures">Mobile Gestures</label>
|
||||||
<select id="theme_gestures">
|
<select id="Theme_Gestures">
|
||||||
<option value="false">Disabled</option>
|
<option value="false">Disabled</option>
|
||||||
<option value="true">Enabled</option>
|
<option value="true">Enabled</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="hint">Swipe left for next page/image. Swipe right for previous page/image.</div>
|
<div class="hint">Swipe left for next page/image. Swipe right for previous page/image.</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -85,14 +111,6 @@
|
|||||||
<%= svg_icon(:reset) %>
|
<%= svg_icon(:reset) %>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<label for="wiki-excerpt-reset">Wiki Excerpt</label>
|
|
||||||
<span id="wiki-excerpt-value"></span>
|
|
||||||
<button class="st-button" id="wiki-excerpt-reset">
|
|
||||||
<%= svg_icon(:reset) %>
|
|
||||||
Reset
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% content_for(:page_title) do %>
|
<% content_for(:page_title) do %>
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<div class="about-section">
|
|
||||||
<% if user.profile_about.present? %>
|
|
||||||
<div class="profile-about-entry" id="about-info">
|
|
||||||
<h3>About</h3>
|
|
||||||
<div class="content dtext-container"><%= format_text(user.profile_about, allow_color: true) %></div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% if user.profile_artinfo.present? %>
|
|
||||||
<div class="profile-about-entry" id="about-artinfo">
|
|
||||||
<h3>Artist Information</h3>
|
|
||||||
<div class="content dtext-container"><%= format_text(user.profile_artinfo, allow_color: true) %></div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
@ -1,156 +0,0 @@
|
|||||||
<div class="stats-section">
|
|
||||||
<div class="profile-avatar">
|
|
||||||
<%= user_avatar @user %>
|
|
||||||
</div>
|
|
||||||
<div class="profile-stats">
|
|
||||||
<h1><%= link_to_user @user %></h1>
|
|
||||||
<div class="user-statistics">
|
|
||||||
<div class="column">
|
|
||||||
<span>Join Date</span>
|
|
||||||
<span><%= compact_time @user.created_at %></span>
|
|
||||||
|
|
||||||
<span>Level</span>
|
|
||||||
<span><%= "(Unactivated)" unless user.is_verified? %> <%= presenter.level %></span>
|
|
||||||
|
|
||||||
<% if user.is_banned? && user.recent_ban %>
|
|
||||||
<span>Ban reason</span>
|
|
||||||
<span class="dtext-container"><%= format_text presenter.ban_reason %></span>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<span>Posts</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.active_upload_count(self) %>
|
|
||||||
[<%= link_to "pending", posts_path(tags: "user:#{user.name} status:pending") %>]
|
|
||||||
(<%= link_to "comments on", comments_path(group_by: :comment, search: {poster_id: user.id}) %>)
|
|
||||||
<% if CurrentUser.is_moderator? %>
|
|
||||||
(<%= link_to "votes", action: "index", controller: "post_votes", search: { user_name: user.name } %>)
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Deleted</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.deleted_upload_count(self) %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Replaced</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.replaced_upload_count(self) %>
|
|
||||||
[<%= link_to "pending", post_replacements_path(search: { creator_name: user.name }) %>]
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Rejected</span>
|
|
||||||
<span><%= presenter.rejected_replacements_count(self) %></span>
|
|
||||||
|
|
||||||
<span>Favorites</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.favorite_count(self) %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Forum Posts</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.forum_post_count(self) %>
|
|
||||||
(<%= link_to "mentions", forum_posts_path(search: { body_matches: user.name }) %>)
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Comments</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.comment_count(self) %> on <%= presenter.commented_posts_count(self) %> posts
|
|
||||||
(<%= link_to "mentions", comments_path(group_by: :comment, search:{ body_matches: user.name }) %>)
|
|
||||||
<% if CurrentUser.is_moderator? %>
|
|
||||||
(<%= link_to "votes", action: "index", controller: "comment_votes", search: { user_name: user.name } %>)
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<% if user.can_approve_posts? || Post.where(approver: user).exists? %>
|
|
||||||
<span>Approvals</span>
|
|
||||||
<span><%= presenter.approval_count(self) %></span>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if CurrentUser.user.id == user.id || CurrentUser.is_janitor? %>
|
|
||||||
<% if presenter.previous_names(self).present? %>
|
|
||||||
<span>Previous Names</span>
|
|
||||||
<span><%= presenter.previous_names(self) %> -> <%= user.name %></span>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if CurrentUser.is_admin? %>
|
|
||||||
<span>Email</span>
|
|
||||||
<span>
|
|
||||||
<%= user.email %>
|
|
||||||
<%= email_domain_search(user.email) %>
|
|
||||||
</span>
|
|
||||||
<span>Last IP</span>
|
|
||||||
<span><%= link_to_ip(user.last_ip_addr) %></span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
<span>Feedback</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.feedbacks %>
|
|
||||||
<%= link_to("List", user_feedbacks_path(search: { user_id: @user.id })) %>
|
|
||||||
<% if CurrentUser.is_moderator? && @user.feedback.active.count == 0 %>
|
|
||||||
| <%= link_to("Create", new_user_feedback_path(user_feedback: { user_id: @user.id, category: "neutral" })) %>
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Permissions</span>
|
|
||||||
<span><%= presenter.permissions %></span>
|
|
||||||
|
|
||||||
<span>Upload Limit</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.upload_limit(self) %>
|
|
||||||
<% if CurrentUser.user.id == user.id %>
|
|
||||||
(<%= link_to "help", upload_limit_users_path %>)
|
|
||||||
<% else %>
|
|
||||||
(<%= link_to "help", wiki_page_path(id: "upload_limit") %>)
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Post Changes</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.post_version_count(self) %>
|
|
||||||
<% if CurrentUser.is_moderator? && UserRevert.can_revert?(user) %>
|
|
||||||
[<%= link_to "revert all", new_user_revert_path(user_id: user.id) %>]
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>Wiki Changes</span>
|
|
||||||
<span><%= presenter.wiki_page_version_count(self) %></span>
|
|
||||||
|
|
||||||
<span>Note Changes</span>
|
|
||||||
<span><%= presenter.note_version_count(self) %> on <%= presenter.noted_posts_count(self) %> posts</span>
|
|
||||||
|
|
||||||
<span>Artist Changes</span>
|
|
||||||
<span><%= presenter.artist_version_count(self) %></span>
|
|
||||||
|
|
||||||
<span>Pool Changes</span>
|
|
||||||
<span><%= presenter.pool_version_count(self) %></span>
|
|
||||||
|
|
||||||
<% if CurrentUser.user.id == user.id || CurrentUser.is_janitor? %>
|
|
||||||
<span>Flags</span>
|
|
||||||
<span><%= presenter.flag_count(self) %></span>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if CurrentUser.user.id == user.id || CurrentUser.is_moderator? %>
|
|
||||||
<span>Tickets</span>
|
|
||||||
<span>
|
|
||||||
<%= presenter.ticket_count(self) %>
|
|
||||||
<% if CurrentUser.is_moderator? %>
|
|
||||||
[<%= link_to "pending", tickets_path(search: { creator_id: user.id, status: "pending" }) %>]
|
|
||||||
[<%= link_to "accused", tickets_path(search: { accused_id: user.id }) %>]
|
|
||||||
<% end %>
|
|
||||||
</span>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if CurrentUser.id == user.id %>
|
|
||||||
<span>API Key</span>
|
|
||||||
<span>
|
|
||||||
<%= link_to (CurrentUser.api_key ? "View" : "Generate"), user_api_key_path(CurrentUser.user) %>
|
|
||||||
(<%= link_to "help", help_page_path(id: "api") %>)
|
|
||||||
</span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,137 +1,36 @@
|
|||||||
<div id="c-users">
|
<div id="c-users"><div id="a-edit">
|
||||||
<div id="a-edit">
|
<h1>Settings</h1>
|
||||||
<h1>Settings</h1>
|
|
||||||
|
|
||||||
<%= custom_form_for @user do |f| %>
|
<tabs-menu id="settings-tabs">
|
||||||
<h2 id="edit-options">
|
<button role="tab" name="basic">Basic</button>
|
||||||
<%= link_to "Basic", "#basic-settings", :class => "active" %>
|
<button role="tab" name="advanced">Advanced</button>
|
||||||
| <%= link_to "Advanced", "#advanced-settings" %>
|
<button role="tab" name="blacklist">Blacklist</button>
|
||||||
<% if CurrentUser.user.id == @user.id %>
|
<span class="spacer"></span>
|
||||||
| <%= link_to "Change password", edit_user_password_path(:user_id => @user.id), :id => "change-password" %>
|
<input type="text" name="search" placeholder="Search Settings" />
|
||||||
| <%= link_to "Delete account", maintenance_user_deletion_path, :id => "delete-account" %>
|
</tabs-menu>
|
||||||
<% end %>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<fieldset id="basic-settings-section">
|
<%= custom_form_for @user do |form| %>
|
||||||
<div class="input">
|
<tabs-content for="settings-tabs">
|
||||||
<label>Name</label>
|
<%= render "users/partials/edit/basic", form: form %>
|
||||||
|
<%= render "users/partials/edit/advanced", form: form %>
|
||||||
|
<%= render "users/partials/edit/blacklist", form: form %>
|
||||||
|
<tab-submit>
|
||||||
|
<%= form.button :submit, "Save Settings" %>
|
||||||
|
</tab-submit>
|
||||||
|
</tabs-content>
|
||||||
|
<% end %>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
<p><%= link_to "Request a name change", new_user_name_change_request_path %></p>
|
<noscript>
|
||||||
</div>
|
<style>
|
||||||
|
tabs-menu { display: none !important; }
|
||||||
<div class="input">
|
tab-group { display: flex !important; }
|
||||||
<label>Email</label>
|
tab-entry { display: grid !important; }
|
||||||
<p>
|
</style>
|
||||||
<% if CurrentUser.user.email.present? %>
|
</noscript>
|
||||||
<%= CurrentUser.user.email %>
|
|
||||||
<% else %>
|
|
||||||
<em>blank</em>
|
|
||||||
<% end %>
|
|
||||||
–
|
|
||||||
<%= link_to "Change your email", new_maintenance_user_email_change_path %>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%= f.input :avatar_id, as: :string, label: "Avatar Post ID" %>
|
|
||||||
|
|
||||||
<%= f.input :profile_about, as: :dtext, label: "About Me", limit: Danbooru.config.user_about_max_size, allow_color: true %>
|
|
||||||
|
|
||||||
<%= f.input :profile_artinfo, as: :dtext, label: "Commission Info", limit: Danbooru.config.user_about_max_size, allow_color: true %>
|
|
||||||
|
|
||||||
<%= f.input :time_zone, :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 size, scaled to fit, scaled to fit vertically, or show resized #{Danbooru.config.large_image_width} pixel sample version.", :label => "Default image width", :collection => [["Original", "original"], ["Fit (Horizontal)", "fit"], ["Fit (Vertical)", "fitv"], ["Sample (#{Danbooru.config.large_image_width}px)", "large"]], :include_blank => false %>
|
|
||||||
|
|
||||||
<%= f.input :per_page, :label => "Posts per page", :as => :select, :collection => (25..250), :include_blank => false %>
|
|
||||||
|
|
||||||
<%= f.input :enable_safe_mode, :label => "Safe mode", :hint => "Show only safe images. Hide questionable and explicit images.", :as => :select, :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
|
||||||
|
|
||||||
<%= f.input :blacklisted_tags, :hint => "Put any tag combinations you never want to see here. Each combination should go on a separate line. <a href='/help/blacklist'>View help.</a>".html_safe, autocomplete: "tag-query", input_html: { size: "40x5" } %>
|
|
||||||
|
|
||||||
<%= f.input :blacklist_users, hint: "Hide comments, blips and forum posts from users that have been blacklisted, in addition to posts.", as: :select, include_blank: false, collection: [["Yes", "true"], ["No", "false"]] %>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset id="advanced-settings-section">
|
|
||||||
<%= f.input :style_usernames, :as => :select, :label => "Colored usernames",
|
|
||||||
:hint => raw("Color each user's name depending on their level. See #{link_to 'the legend', wiki_page_path(id: 'e621:colored_usernames')} for what the colors are."),
|
|
||||||
:include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
|
|
||||||
|
|
||||||
<%= f.input :enable_keyboard_navigation, :as => :select, :include_blank => false, :label => "Enable keyboard shortcuts", :collection => [["Yes", "true"], ["No", "false"]],
|
|
||||||
hint: raw("Enables the use of keyboard shortcuts for a majority of site actions related to posts. A list of keyboard shortcuts is available #{link_to 'here', keyboard_shortcuts_path}.")%>
|
|
||||||
|
|
||||||
<%= f.input :enable_auto_complete, :as => :select, :collection => [["Yes", "true"], ["No", "false"]], :include_blank => false,
|
|
||||||
hint: "Enables auto-completion on most tag and user entry fields." %>
|
|
||||||
|
|
||||||
<%= f.input :enable_privacy_mode, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
|
|
||||||
hint: "Prevent showing your favorites to others users (except staff)." %>
|
|
||||||
|
|
||||||
<%= f.input :show_post_statistics, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
|
|
||||||
hint: "Show post statistics below posts on search pages." %>
|
|
||||||
|
|
||||||
<%= f.input :description_collapsed_initially, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
|
|
||||||
hint: "Don't expand post descriptions on page load." %>
|
|
||||||
|
|
||||||
<%= f.input :hide_comments, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
|
|
||||||
hint: "Do not show the comments section on post pages." %>
|
|
||||||
|
|
||||||
<% unless CurrentUser.is_janitor? %>
|
|
||||||
<%= f.input :disable_user_dmails, label: "Disable DMails", hint: "Prevent other users from sending you DMails. You will be prevented from sending DMails to non-staff members while this option is enabled. Staff are always allowed to send you DMails.",
|
|
||||||
:as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= f.input :disable_cropped_thumbnails, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
|
|
||||||
hint: "Disables displaying cropped thumbnails on the mobile layout of the site in favor of scaled thumbnails. Has no effect on the desktop site." %>
|
|
||||||
|
|
||||||
<%= f.input :show_hidden_comments, label: "Show Own Hidden Comments", :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
|
|
||||||
hint: "Show your own hidden comments on comment pages." %>
|
|
||||||
|
|
||||||
<% if @user.post_upload_count >= 10 %>
|
|
||||||
<%= f.input :enable_compact_uploader, label: "Enable Compact Uploader", as: :select,
|
|
||||||
collection: [["No", "false"], ["Yes", "true"]], include_blank: false,
|
|
||||||
hint: "Enables a more compact and less guided post uploader." %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="input text optional field_with_hint">
|
|
||||||
<label class="text optional" for="user_dmail_filter_attributes_words">Dmail filter</label>
|
|
||||||
<%= hidden_field_tag "user[dmail_filter_attributes][id]", @user.dmail_filter.try(:id) %>
|
|
||||||
<%= text_field_tag "user[dmail_filter_attributes][words]", @user.dmail_filter.try(:words), :id => "user_dmail_filter_attributes_words", :class => "text optional", :size => 40 %>
|
|
||||||
<span class="hint">A list of banned words (space delimited). Any dmail you receive with a banned word will automatically be deleted.</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%= f.input :favorite_tags, :label => "Frequent tags", :hint => "A list of tags that you use often. They will appear when using the list of Related Tags.", autocomplete: "tag-query", input_html: { rows: 5 } %>
|
|
||||||
|
|
||||||
<%= f.input :disable_responsive_mode, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false, :hint => "Disable alternative layout for mobile and tablet." %>
|
|
||||||
|
|
||||||
<%= f.input :custom_style, :label => "Custom <a href='https://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>
|
|
||||||
|
|
||||||
<%= f.button :submit, "Submit" %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% content_for(:page_title) do %>
|
<% content_for(:page_title) do %>
|
||||||
Settings
|
Settings
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% content_for(:html_header) do %>
|
|
||||||
<%= javascript_tag nonce: true do -%>
|
|
||||||
$(function() {
|
|
||||||
$("#advanced-settings-section").hide();
|
|
||||||
$("#edit-options a:not(#delete-account):not(#change-password)").on("click", function(e) {
|
|
||||||
var $target = $(e.target);
|
|
||||||
$("h2 a").removeClass("active");
|
|
||||||
$("#basic-settings-section,#advanced-settings-section").hide();
|
|
||||||
$target.addClass("active");
|
|
||||||
$($target.attr("href") + "-section").show();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
<% end -%>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "secondary_links" %>
|
<%= render "secondary_links" %>
|
||||||
|
166
app/views/users/partials/edit/_advanced.html.erb
Normal file
166
app/views/users/partials/edit/_advanced.html.erb
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<% tab_name = "advanced" %>
|
||||||
|
|
||||||
|
<!-- Accessibility -->
|
||||||
|
<tab-group name="accessibility">Accessibility</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="keyboard hotkeys shortcut navigation enable disable">
|
||||||
|
<tab-head>Enable Keyboard Shortcuts</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :enable_keyboard_navigation, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :enable_keyboard_navigation, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
The full list of shortcuts is available <%= link_to "here", keyboard_shortcuts_path %>.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="auto complete autocomplete suggestions enable disable">
|
||||||
|
<tab-head>Enable Auto Complete</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :enable_auto_complete, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :enable_auto_complete, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Tag and user name suggestions.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="users colored usernames level rank">
|
||||||
|
<tab-head>Colored Usernames</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :style_usernames, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :style_usernames, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Color names depending on the user's level.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Privacy & Messaging -->
|
||||||
|
<tab-group name="privacy">Privacy & Messaging</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="privacy" class="inline" search="posts favorites hide disable private privacy">
|
||||||
|
<tab-head>Hide Favorites</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :enable_privacy_mode, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :enable_privacy_mode, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Prevent your favorites from being publicly visible.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="privacy" class="inline" search="dmails filter banned block enable disable toggle">
|
||||||
|
<tab-head>Disable DMails</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :disable_user_dmails, as: :boolean, class: "st-toggle", disabled: CurrentUser.is_staff? %>
|
||||||
|
<%= form.label :disable_user_dmails, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Prevent other users from sending you DMails.
|
||||||
|
<% if CurrentUser.is_staff? %>
|
||||||
|
<br />Staff members are not allowed to disable DMails.
|
||||||
|
<% end %>
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="privacy" search="dmails filter banned block">
|
||||||
|
<tab-head>DMail Filters</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= hidden_field_tag "user[dmail_filter_attributes][id]", @user.dmail_filter.try(:id) %>
|
||||||
|
<%= text_field_tag "user[dmail_filter_attributes][words]", @user.dmail_filter.try(:words), id: "user_dmail_filter_attributes_words", class: "text optional", size: 40 %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
A list of banned words (space delimited). Any dmail you receive with a banned word will automatically be deleted.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Posts -->
|
||||||
|
<tab-group name="tags">Posts & Tags</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide posts thumbnails statistics stats search">
|
||||||
|
<tab-head>Show Statistics</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :show_post_statistics, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :show_post_statistics, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Show post stats below posts on search pages.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide collapse expand posts descriptions">
|
||||||
|
<tab-head>Collapse Descriptions</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :description_collapsed_initially, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :description_collapsed_initially, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Do not expand post descriptions on page load.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="tags" class="bigtext" search="posts tags frequent favorite related">
|
||||||
|
<tab-head>Frequent Tags</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :favorite_tags, label: false, autocomplete: "tag-query", rows: 5 %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
A list of tags that you use often.<br />They will appear when using the list of Related Tags.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<% if @user.post_upload_count >= 10 %>
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide compact uploader posts">
|
||||||
|
<tab-head>Compact Uploader</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :enable_compact_uploader, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :enable_compact_uploader, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
A more compact and less guided post uploader.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Mobile -->
|
||||||
|
<tab-group name="mobile">Mobile / Tablet</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="mobile" class="inline" search="enable disable responsive mode mobile tablet">
|
||||||
|
<tab-head>Disable Responsive Mode</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :disable_responsive_mode, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :disable_responsive_mode, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Disable alternative layout for mobile and tablet.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="mobile" class="inline" search="enable disable cropped thumbnails mobile tablet">
|
||||||
|
<tab-head>Disable Cropped Thumbnails</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :disable_cropped_thumbnails, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :disable_cropped_thumbnails, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
No effect on the desktop site.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Customization -->
|
||||||
|
<tab-group name="customization">Customization</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="customization" class="bigtext" search="customize css styles">
|
||||||
|
<tab-head>Custom CSS</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :custom_style, label: false, rows: 8 %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Apply <a href="https://en.wikipedia.org/wiki/Cascading_Style_Sheets">CSS Styles</a> to the whole website.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
155
app/views/users/partials/edit/_basic.html.erb
Normal file
155
app/views/users/partials/edit/_basic.html.erb
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<% tab_name = "basic" %>
|
||||||
|
|
||||||
|
<!-- Account -->
|
||||||
|
<tab-group name="account">Account</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="account" class="buttony" search="update change user profile account name username">
|
||||||
|
<tab-head>Username</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<input type="text" value="<%= CurrentUser.user.pretty_name %>" disabled><%= link_to "Edit", new_user_name_change_request_path, class: "st-button" %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="account" class="buttony" search="update change user profile account email e-mail address">
|
||||||
|
<tab-head>Email</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<input type="text" value="<%= CurrentUser.user.email.presence || "blank" %>" disabled><%= link_to "Edit", new_maintenance_user_email_change_path, class: "st-button" %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="account" class="" id="settings-account-buttons" search="update change user profile account delete password">
|
||||||
|
<tab-head></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= link_to "Change password", edit_user_password_path(user_id: @user.id), class: "st-button" %>
|
||||||
|
<%= link_to "Delete account", maintenance_user_deletion_path, class: "st-button danger" %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="account" search="user account timezone">
|
||||||
|
<tab-head>Time Zone</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :time_zone,
|
||||||
|
label: false,
|
||||||
|
include_blank: false
|
||||||
|
%>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="account" class="inline" search="user account email notify notifications">
|
||||||
|
<tab-head>Email Notifications</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :receive_email_notifications, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :receive_email_notifications, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- General -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Profile -->
|
||||||
|
<tab-group name="profile">Profile</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="profile" search="update change user avatar profile image pfp">
|
||||||
|
<tab-head><%= form.label :avatar_id, "Avatar Post ID" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :avatar_id, as: :string, label: false %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
The image with this ID will be set as your avatar.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="profile" class="bigtext" search="user profile about me">
|
||||||
|
<tab-head><%= form.label :profile_about, "About Me" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :profile_about,
|
||||||
|
as: :dtext,
|
||||||
|
label: false,
|
||||||
|
rows: 8,
|
||||||
|
limit: Danbooru.config.user_about_max_size,
|
||||||
|
allow_color: true
|
||||||
|
%>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="profile" class="bigtext" search="user profile commission info">
|
||||||
|
<tab-head><%= form.label :profile_artinfo, "Commission Info" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :profile_artinfo,
|
||||||
|
as: :dtext,
|
||||||
|
label: false,
|
||||||
|
rows: 8,
|
||||||
|
limit: Danbooru.config.user_about_max_size,
|
||||||
|
allow_color: true
|
||||||
|
%>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Posts -->
|
||||||
|
<tab-group name="posts">Posts</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" search="default images width fit horizontal vertical sample large original display show scale posts">
|
||||||
|
<tab-head><%= form.label :default_image_size, "Default image width" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :default_image_size,
|
||||||
|
label: false,
|
||||||
|
collection: [["Original", "original"], ["Fit (Horizontal)", "fit"], ["Fit (Vertical)", "fitv"], ["Sample (#{Danbooru.config.large_image_width}px)", "large"]],
|
||||||
|
include_blank: false
|
||||||
|
%>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Show original image size, scaled to fit, scaled to fit vertically, or show resized 850 pixel sample version.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" search="posts number page display show">
|
||||||
|
<tab-head><%= form.label :per_page, "Posts per page" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :per_page, label: false, as: :select, collection: (25..250).step(25), include_blank: false %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" search="comments score rating upvotes downvotes display show hide">
|
||||||
|
<tab-head><%= form.label :comment_threshold %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :comment_threshold, label: false %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Comments below this score will be hidden by default.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts comments show hide display hidden">
|
||||||
|
<tab-head><%= form.label :hide_comments %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :hide_comments, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :hide_comments, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Do not show the comments section on post pages.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts comments show hide display own hidden">
|
||||||
|
<tab-head><%= form.label :show_hidden_comments, "Show own hidden comments" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :show_hidden_comments, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :show_hidden_comments, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Show your hidden comments on comment pages.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts display show hide mode explicit questionable safe rated rating">
|
||||||
|
<tab-head><%= form.label :enable_safe_mode, "Safe mode" %></tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :enable_safe_mode, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :enable_safe_mode, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Only show images rated safe.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
25
app/views/users/partials/edit/_blacklist.html.erb
Normal file
25
app/views/users/partials/edit/_blacklist.html.erb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<% tab_name = "blacklist" %>
|
||||||
|
|
||||||
|
<!-- Accessibility -->
|
||||||
|
<tab-group name="blacklisting">Blacklist</tab-group>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="blacklisting" class="bigtext" search="posts blacklisted filtered tags blocked">
|
||||||
|
<tab-head>Blacklisted Tags</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :blacklisted_tags, label: false, autocomplete: "tag-query", rows: 8 %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Put any tag combinations you never want to see here. Each combination should go on a separate line. <a href='/help/blacklist'>View help.</a>
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
||||||
|
|
||||||
|
<tab-entry tab="<%= tab_name %>" group="blacklisting" class="inline" search="posts blacklisted filter users comments blips forum">
|
||||||
|
<tab-head>Blacklist Users</tab-head>
|
||||||
|
<tab-body>
|
||||||
|
<%= form.input_field :blacklist_users, as: :boolean, class: "st-toggle" %>
|
||||||
|
<%= form.label :blacklist_users, "!", class: "st-toggle" %>
|
||||||
|
</tab-body>
|
||||||
|
<tab-hint>
|
||||||
|
Hide comments, blips and forum posts from users that have been blacklisted, in addition to posts.
|
||||||
|
</tab-hint>
|
||||||
|
</tab-entry>
|
17
app/views/users/partials/show/_about.html.erb
Normal file
17
app/views/users/partials/show/_about.html.erb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<% if has_about %>
|
||||||
|
<tab-entry tab="about" class="profile-about-section flex">
|
||||||
|
<tab-head>About</tab-head>
|
||||||
|
<tab-body class="content dtext-container">
|
||||||
|
<%= format_text(user.profile_about, allow_color: true) %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if has_artinfo %>
|
||||||
|
<tab-entry tab="artinfo" class="profile-artinfo-section flex">
|
||||||
|
<tab-head>Artist Information</tab-head>
|
||||||
|
<tab-body class="content dtext-container">
|
||||||
|
<%= format_text(user.profile_artinfo, allow_color: true) %>
|
||||||
|
</tab-body>
|
||||||
|
</tab-entry>
|
||||||
|
<% end %>
|
5
app/views/users/partials/show/_ban_banner.html.erb
Normal file
5
app/views/users/partials/show/_ban_banner.html.erb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<% if user.is_banned? && user.recent_ban %>
|
||||||
|
<div class="profile-ban dtext-container">
|
||||||
|
<%= format_text presenter.ban_reason %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
20
app/views/users/partials/show/_card.html.erb
Normal file
20
app/views/users/partials/show/_card.html.erb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<div class="profile-card">
|
||||||
|
<div class="profile-avatar">
|
||||||
|
<%= profile_avatar(@user) %>
|
||||||
|
</div>
|
||||||
|
<div class="profile-info">
|
||||||
|
<span class="profile-name">
|
||||||
|
<%= link_to_user(@user) %>
|
||||||
|
<%= user_feedback_badge(@user) %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-joined">
|
||||||
|
Joined <%= compact_date @user.created_at %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-rank">
|
||||||
|
<%= user_level_badge(@user) %>
|
||||||
|
<% unless @user.is_verified? %>
|
||||||
|
<span class="level-badge level-unactivated">UNACTIVATED</span>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
0
app/views/users/partials/show/_mentions.html.erb
Normal file
0
app/views/users/partials/show/_mentions.html.erb
Normal file
@ -4,7 +4,7 @@
|
|||||||
<div class="profile-sample profile-uploads">
|
<div class="profile-sample profile-uploads">
|
||||||
|
|
||||||
<div class="profile-sample-header">
|
<div class="profile-sample-header">
|
||||||
<%= link_to "Uploads", posts_path(:tags => "user:#{user.name}"), class: "title" %>
|
<%= link_to "Uploads", posts_path(tags: "user:#{user.name}"), class: "title" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="profile-sample-links">
|
<div class="profile-sample-links">
|
||||||
@ -29,11 +29,11 @@
|
|||||||
<div class="profile-sample profile-favorites">
|
<div class="profile-sample profile-favorites">
|
||||||
|
|
||||||
<div class="profile-sample-header">
|
<div class="profile-sample-header">
|
||||||
<%= link_to "Favorites", favorites_path(:user_id => user.id), class: "title" %>
|
<%= link_to "Favorites", favorites_path(user_id: user.id), class: "title" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="profile-sample-links">
|
<div class="profile-sample-links">
|
||||||
<%= link_to(sanitize("<b>#{user.favorite_count}</b> total"), favorites_path(:user_id => user.id)) %>
|
<%= link_to(sanitize("<b>#{user.favorite_count}</b> total"), favorites_path(user_id: user.id)) %>
|
||||||
<% if user.enable_privacy_mode? || user.is_blocked? %>
|
<% if user.enable_privacy_mode? || user.is_blocked? %>
|
||||||
<span>[hidden]</span>
|
<span>[hidden]</span>
|
||||||
<% end %>
|
<% end %>
|
34
app/views/users/partials/show/_staff_info.html.erb
Normal file
34
app/views/users/partials/show/_staff_info.html.erb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<div class="profile-section hidden" name="StaffStats">
|
||||||
|
<div class="profile-section-header">Staff Info</div>
|
||||||
|
<div class="profile-section-body profile-staff-info">
|
||||||
|
<% if presenter.previous_names(self).present? %>
|
||||||
|
<h4 class="block">Previous Names</h4>
|
||||||
|
<span class="block"><%= presenter.previous_names(self) %> -> <%= user.name %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if CurrentUser.is_admin? %>
|
||||||
|
<h4>Email</h4>
|
||||||
|
<span>
|
||||||
|
<%= user.email %>
|
||||||
|
<%= email_domain_search(user.email) %>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<h4>Last IP</h4>
|
||||||
|
<span><%= link_to_ip(user.last_ip_addr) %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if CurrentUser.is_moderator? %>
|
||||||
|
<h4>Votes</h4>
|
||||||
|
<span>
|
||||||
|
<%= link_to "Posts", action: "index", controller: "post_votes", search: { user_name: user.name } %>
|
||||||
|
| <%= link_to "Comments", action: "index", controller: "comment_votes", search: { user_name: user.name } %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<h4>Pending</h4>
|
||||||
|
<span>
|
||||||
|
<%= link_to "Posts", posts_path(tags: "user:#{user.name} status:pending") %>
|
||||||
|
| <%= link_to "Replacements", post_replacements_path(search: { creator_name: user.name }) %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
129
app/views/users/partials/show/_user_info.html.erb
Normal file
129
app/views/users/partials/show/_user_info.html.erb
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<tab-entry tab="stats" class="profile-user-info">
|
||||||
|
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:message_square) %> Comments</h4>
|
||||||
|
<span class="profile-line-number">
|
||||||
|
<%= presenter.comment_count(self) %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
<%= link_to "[mentions]", comments_path(group_by: :comment, search: { body_matches: user.name }) %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:lectern) %> Forum posts</h4>
|
||||||
|
<span class="profile-line-number">
|
||||||
|
<%= presenter.forum_post_count(self) %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
<%= link_to "[mentions]", forum_posts_path(search: { body_matches: user.name }) %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if user.can_approve_posts? || Post.where(approver: user).exists? %>
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:stamp) %> Approvals</h4>
|
||||||
|
<span class="profile-line-number">
|
||||||
|
<%= presenter.approval_count(self) %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:upload) %> Upload Limit</h4>
|
||||||
|
<span class="profile-line-number">
|
||||||
|
<% if CurrentUser.user.id == user.id %>
|
||||||
|
<%= link_to presenter.upload_limit_short, upload_limit_users_path %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to presenter.upload_limit_short, wiki_page_path(id: "upload_limit") %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
Max number of unapproved posts at a time.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:replace) %> Changes</h4>
|
||||||
|
<span class="profile-line-extra profile-line-show">
|
||||||
|
|
||||||
|
<% if user.post_update_count != 0 %>
|
||||||
|
<a href="<%= post_versions_path(lr: user.id, search: { updater_id: user.id }) %>" class="entry">
|
||||||
|
<h5><%= user.post_update_count %></h5>
|
||||||
|
<span>Post</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if user.pool_version_count != 0 %>
|
||||||
|
<a href="<%= pool_versions_path(search: { updater_id: user.id }) %>" class="entry">
|
||||||
|
<h5><%= user.pool_version_count %></h5>
|
||||||
|
<span>Pool</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if user.artist_version_count != 0 %>
|
||||||
|
<a href="<%= artist_versions_path(search: { updater_id: user.id }) %>" class="entry">
|
||||||
|
<h5><%= user.artist_version_count %></h5>
|
||||||
|
<span>Artist</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if user.wiki_page_version_count != 0 %>
|
||||||
|
<a href="<%= wiki_page_versions_path(search: { updater_id: user.id }) %>" class="entry">
|
||||||
|
<h5><%= user.wiki_page_version_count %></h5>
|
||||||
|
<span>Wiki</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if user.note_version_count != 0 %>
|
||||||
|
<a href="<%= note_versions_path(search: { updater_id: user.id }) %>" class="entry">
|
||||||
|
<h5><%= user.note_version_count %></h5>
|
||||||
|
<span>Note</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if CurrentUser.user.id == user.id || CurrentUser.is_approver? %>
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:flag_left) %> Flags</h4>
|
||||||
|
<span class="profile-line-number"><%= presenter.flag_count(self) %></span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if CurrentUser.user.id == user.id || CurrentUser.is_moderator? %>
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:ticket) %> Tickets</h4>
|
||||||
|
<span class="profile-line-number"><%= presenter.ticket_count(self) %></span>
|
||||||
|
<% if CurrentUser.is_moderator? %>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
[<%= link_to "pending", tickets_path(search: { creator_id: user.id, status: "pending" }) %>]
|
||||||
|
[<%= link_to "accused", tickets_path(search: { accused_id: user.id }) %>]
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if CurrentUser.user.id == user.id %>
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:key_square) %> API Key</h4>
|
||||||
|
<span class="profile-line-number">
|
||||||
|
<%= link_to (CurrentUser.api_key ? "View" : "Generate"), user_api_key_path(CurrentUser.user) %>
|
||||||
|
</span>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
(<%= link_to "help", help_page_path(id: "api") %>)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% permissions = presenter.permissions %>
|
||||||
|
<% unless permissions.empty? %>
|
||||||
|
<div class="profile-line">
|
||||||
|
<h4><%= svg_icon(:power) %> Permissions</h4>
|
||||||
|
<span class="profile-line-extra">
|
||||||
|
<%= permissions %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</tab-entry>
|
@ -1,10 +1,41 @@
|
|||||||
<div id="c-users">
|
<div id="c-users">
|
||||||
<div id="a-show">
|
<div id="a-show">
|
||||||
<%= render "statistics", :presenter => @presenter, :user => @user %>
|
|
||||||
<%= render "staff_notes/partials/for_user", user: @user %>
|
<!-- Header -->
|
||||||
|
<%= render "/users/partials/show/card", :presenter => @presenter, :user => @user %>
|
||||||
|
<%= render "/users/partials/show/ban_banner", :presenter => @presenter, :user => @user %>
|
||||||
|
|
||||||
|
<% if CurrentUser.is_staff? %>
|
||||||
|
<!-- Staff Info -->
|
||||||
|
<%= render "/users/partials/show/staff_info", :presenter => @presenter, :user => @user %>
|
||||||
|
<%= render "staff_notes/partials/for_user", user: @user %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- Blacklist -->
|
||||||
<%= render "posts/partials/common/inline_blacklist" %>
|
<%= render "posts/partials/common/inline_blacklist" %>
|
||||||
<%= render "post_summary", presenter: @presenter, user: @user %>
|
|
||||||
<%= render "about", presenter: @presenter, user: @user %>
|
<!-- Central panel -->
|
||||||
|
<% has_about = @user.profile_about.present? %>
|
||||||
|
<% has_artinfo = @user.profile_artinfo.present? %>
|
||||||
|
<tabs-menu
|
||||||
|
id="profile-tabs"
|
||||||
|
data-has-about="<%= has_about %>"
|
||||||
|
data-has-artinfo="<%= has_artinfo %>"
|
||||||
|
>
|
||||||
|
<% if has_about %>
|
||||||
|
<button role="tab" name="about">About</button>
|
||||||
|
<% end %>
|
||||||
|
<% if has_artinfo %>
|
||||||
|
<button role="tab" name="artinfo">Commission Info</button>
|
||||||
|
<% end %>
|
||||||
|
<button role="tab" name="stats">Stats</button>
|
||||||
|
</tabs-menu>
|
||||||
|
|
||||||
|
<tabs-content for="profile-tabs">
|
||||||
|
<%= render "/users/partials/show/user_info", :presenter => @presenter, :user => @user %>
|
||||||
|
<%= render "/users/partials/show/about", presenter: @presenter, user: @user, has_about: has_about, has_artinfo: has_artinfo %>
|
||||||
|
<%= render "/users/partials/show/post_summary", presenter: @presenter, user: @user %>
|
||||||
|
</tabs-content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -2,23 +2,19 @@
|
|||||||
<div id="a-diff">
|
<div id="a-diff">
|
||||||
<h1>Wiki Page: <%= @thispage.title %></h1>
|
<h1>Wiki Page: <%= @thispage.title %></h1>
|
||||||
|
|
||||||
<% if @thispage.visible? %>
|
<p>Showing differences between <%= compact_time @thispage.updated_at %> (<%= link_to_user @thispage.updater %>) and <%= compact_time @otherpage.updated_at %> (<%= link_to_user @otherpage.updater %>)</p>
|
||||||
<p>Showing differences between <%= compact_time @thispage.updated_at %> (<%= link_to_user @thispage.updater %>) and <%= compact_time @otherpage.updated_at %> (<%= link_to_user @otherpage.updater %>)</p>
|
|
||||||
|
|
||||||
<% if @thispage.parent != @otherpage.parent %>
|
<% if @thispage.parent != @otherpage.parent %>
|
||||||
<div class="wiki-redirect-history">
|
<div class="wiki-redirect-history">
|
||||||
Page redirect changed
|
Page redirect changed
|
||||||
from <%= @thispage.parent.blank? ? "none" : link_to(@thispage.parent, show_or_new_wiki_pages_path(title: @thispage.parent)) %>
|
from <%= @thispage.parent.blank? ? "none" : link_to(@thispage.parent, show_or_new_wiki_pages_path(title: @thispage.parent)) %>
|
||||||
to <%= @otherpage.parent.blank? ? "none" : link_to(@otherpage.parent, show_or_new_wiki_pages_path(title: @otherpage.parent)) %>.
|
to <%= @otherpage.parent.blank? ? "none" : link_to(@otherpage.parent, show_or_new_wiki_pages_path(title: @otherpage.parent)) %>.
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<%= text_diff(@thispage.body, @otherpage.body) %>
|
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
|
||||||
<p>The artist requested removal of this page.</p>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<%= text_diff(@thispage.body, @otherpage.body) %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -10,11 +10,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div id="wiki-page-body" class="dtext dtext-container">
|
<div id="wiki-page-body" class="dtext dtext-container">
|
||||||
<% if @wiki_page_version.visible? %>
|
<%= format_text(@wiki_page_version.body) %>
|
||||||
<%= format_text(@wiki_page_version.body) %>
|
|
||||||
<% else %>
|
|
||||||
<p>The artist has requested removal of this page.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,22 +12,28 @@
|
|||||||
|
|
||||||
<%= f.input :body, as: :dtext, limit: Danbooru.config.wiki_page_max_size, allow_color: true %>
|
<%= f.input :body, as: :dtext, limit: Danbooru.config.wiki_page_max_size, allow_color: true %>
|
||||||
|
|
||||||
|
<%= f.input :category_id,
|
||||||
|
label: "Tag Category",
|
||||||
|
collection: TagCategory::CANONICAL_MAPPING.to_a,
|
||||||
|
include_blank: true,
|
||||||
|
disabled: @wiki_page.category_is_locked && !CurrentUser.is_admin? %>
|
||||||
|
|
||||||
|
<% if CurrentUser.is_admin? %>
|
||||||
|
<%= f.input :category_is_locked, label: "Lock Category", as: :boolean %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= f.input :parent, label: "Redirects to", autocomplete: "wiki-page", input_html: { disabled: !CurrentUser.is_privileged? } %>
|
<%= f.input :parent, label: "Redirects to", autocomplete: "wiki-page", input_html: { disabled: !CurrentUser.is_privileged? } %>
|
||||||
|
|
||||||
<% if CurrentUser.is_janitor? && @wiki_page.is_deleted? %>
|
|
||||||
<%= f.input :is_deleted, :label => "Deleted", :hint => "Uncheck to restore this wiki page" %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if CurrentUser.is_janitor? %>
|
<% if CurrentUser.is_janitor? %>
|
||||||
<%= f.input :is_locked, :label => "Locked" %>
|
<%= f.input :is_locked, :label => "Lock Page" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= f.input :edit_reason, label: "Edit Reason" %>
|
|
||||||
|
|
||||||
<% if CurrentUser.is_janitor? && @wiki_page.errors[:title]&.any? { |error| error.include?("Move the posts and update any wikis linking to this page first.") } %>
|
<% if CurrentUser.is_janitor? && @wiki_page.errors[:title]&.any? { |error| error.include?("Move the posts and update any wikis linking to this page first.") } %>
|
||||||
<%= f.input :skip_secondary_validations, as: :boolean, label: "Force rename", hint: "Ignore the renaming requirements" %>
|
<%= f.input :skip_secondary_validations, as: :boolean, label: "Force rename", hint: "Ignore the renaming requirements" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= f.input :edit_reason, label: "Edit Reason" %>
|
||||||
|
|
||||||
<%= f.button :submit, "Submit" %>
|
<%= f.button :submit, "Submit" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,11 +17,8 @@
|
|||||||
<% if @wiki_page.tag.present? %>
|
<% if @wiki_page.tag.present? %>
|
||||||
<%= subnav_link_to "Posts (#{@wiki_page.tag.post_count})", posts_path(tags: @wiki_page.title) %>
|
<%= subnav_link_to "Posts (#{@wiki_page.tag.post_count})", posts_path(tags: @wiki_page.title) %>
|
||||||
|
|
||||||
<% if CurrentUser.is_member? %>
|
<% if CurrentUser.is_janitor?%>
|
||||||
<%= subnav_link_to "Edit Tag Type", edit_tag_path(@wiki_page.tag) %>
|
<%= subnav_link_to "Fix Tag Count", new_tag_correction_path(tag_id: @wiki_page.tag.id) %>
|
||||||
<% if CurrentUser.is_janitor? %>
|
|
||||||
<%= subnav_link_to "Fix Tag Count", new_tag_correction_path(tag_id: @wiki_page.tag.id) %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
@ -40,6 +37,8 @@
|
|||||||
<%= subnav_link_to "Report", new_ticket_path(disp_id: @wiki_page.id, qtype: "wiki") %>
|
<%= subnav_link_to "Report", new_ticket_path(disp_id: @wiki_page.id, qtype: "wiki") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
<% elsif @wiki_page_version %>
|
<% elsif @wiki_page_version %>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
|
||||||
|
@ -5,11 +5,7 @@
|
|||||||
<section id="content">
|
<section id="content">
|
||||||
<h1>Edit Wiki</h1>
|
<h1>Edit Wiki</h1>
|
||||||
|
|
||||||
<% if @wiki_page.visible? %>
|
<%= render "form" %>
|
||||||
<%= render "form" %>
|
|
||||||
<% else %>
|
|
||||||
<p>The artist requested removal of this page.</p>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= wiki_page_alias_and_implication_list(@wiki_page)%>
|
<%= wiki_page_alias_and_implication_list(@wiki_page)%>
|
||||||
<%= wiki_page_post_previews(@wiki_page) %>
|
<%= wiki_page_post_previews(@wiki_page) %>
|
||||||
|
@ -21,17 +21,13 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div id="wiki-page-body" class="dtext-container">
|
<div id="wiki-page-body" class="dtext-container">
|
||||||
<% if wiki_content.visible? %>
|
<%= format_text(wiki_content.body, allow_color: true, max_thumbs: 75) %>
|
||||||
<%= format_text(wiki_content.body, allow_color: true, max_thumbs: 75) %>
|
|
||||||
|
|
||||||
<% if wiki_content.artist %>
|
<% if wiki_content.artist %>
|
||||||
<p><%= link_to "View artist", wiki_content.artist %></p>
|
<p><%= link_to "View artist", wiki_content.artist %></p>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= wiki_page_alias_and_implication_list(wiki_content) %>
|
|
||||||
<% else %>
|
|
||||||
<p>This artist has requested removal of their information.</p>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= wiki_page_alias_and_implication_list(wiki_content) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= wiki_page_post_previews(wiki_content) %>
|
<%= wiki_page_post_previews(wiki_content) %>
|
||||||
|
@ -8,23 +8,26 @@ destroyed_feedback_ids = []
|
|||||||
CurrentUser.as_system do
|
CurrentUser.as_system do
|
||||||
ModAction.where(action: "user_feedback_destroy")
|
ModAction.where(action: "user_feedback_destroy")
|
||||||
# On July 24, 2024, we deployed the ability to soft-delete feedback records.
|
# On July 24, 2024, we deployed the ability to soft-delete feedback records.
|
||||||
# We only care about restoring destroyed feedbacks that were destroyed before this date.
|
# We only restore feedback that was destroyed before this date.
|
||||||
# Any entries after this are "real" destructions, that do not need to be restored.
|
# Any entries after this are intentional destructions that do not need to be restored.
|
||||||
.where("created_at < ?", CUTOFF_DATE = Date.new(2024, 8, 1))
|
.where("created_at < ?", CUTOFF_DATE = Date.new(2024, 8, 1))
|
||||||
.find_in_batches(batch_size: 10_000) do |batch|
|
.find_in_batches(batch_size: 10_000) do |batch|
|
||||||
feedback_data = batch.map do |mod_action|
|
feedback_data = batch.filter_map do |mod_action|
|
||||||
record_id = mod_action.values["record_id"].to_i
|
record_id = mod_action.values["record_id"]
|
||||||
|
category = mod_action.values["type"]
|
||||||
|
body = mod_action.values["reason"]
|
||||||
|
|
||||||
|
# Old mod actions do not contain the necessary information. Skip them.
|
||||||
|
next if record_id.nil? || category.nil? || body.nil?
|
||||||
|
|
||||||
destroyed_feedback_ids << record_id
|
destroyed_feedback_ids << record_id
|
||||||
|
|
||||||
# old mod actions do not contain the necessary information. we skip them.
|
|
||||||
next if mod_action.values["type"].nil? || mod_action.values["reason"].nil?
|
|
||||||
|
|
||||||
{
|
{
|
||||||
id: record_id,
|
id: record_id.to_i,
|
||||||
user_id: mod_action.values["user_id"].to_i,
|
user_id: mod_action.values["user_id"].to_i,
|
||||||
creator_id: User.system.id, # placeholder
|
creator_id: User.system.id, # placeholder
|
||||||
category: mod_action.values["type"],
|
category: category,
|
||||||
body: mod_action.values["reason"]&.strip,
|
body: body.strip,
|
||||||
created_at: Date.new(1970, 1, 1), # placeholder
|
created_at: Date.new(1970, 1, 1), # placeholder
|
||||||
updated_at: mod_action.created_at,
|
updated_at: mod_action.created_at,
|
||||||
updater_id: mod_action.creator_id,
|
updater_id: mod_action.creator_id,
|
||||||
|
BIN
public/fonts/Lato/Lato-Bold.woff
Normal file
BIN
public/fonts/Lato/Lato-Bold.woff
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-Bold.woff2
Normal file
BIN
public/fonts/Lato/Lato-Bold.woff2
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-BoldItalic.woff
Normal file
BIN
public/fonts/Lato/Lato-BoldItalic.woff
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-BoldItalic.woff2
Normal file
BIN
public/fonts/Lato/Lato-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-Italic.woff
Normal file
BIN
public/fonts/Lato/Lato-Italic.woff
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-Italic.woff2
Normal file
BIN
public/fonts/Lato/Lato-Italic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-Regular.woff
Normal file
BIN
public/fonts/Lato/Lato-Regular.woff
Normal file
Binary file not shown.
BIN
public/fonts/Lato/Lato-Regular.woff2
Normal file
BIN
public/fonts/Lato/Lato-Regular.woff2
Normal file
Binary file not shown.
BIN
public/fonts/Lexend/Lexend-Bold.woff
Normal file
BIN
public/fonts/Lexend/Lexend-Bold.woff
Normal file
Binary file not shown.
BIN
public/fonts/Lexend/Lexend-Bold.woff2
Normal file
BIN
public/fonts/Lexend/Lexend-Bold.woff2
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user