forked from e621ng/e621ng
Merge branch 'master' into master2
This commit is contained in:
commit
77b01aa5f8
@ -24,7 +24,7 @@ module ApplicationHelper
|
|||||||
|
|
||||||
tag.li(id: id, class: klass) do
|
tag.li(id: id, class: klass) do
|
||||||
link_to(url, id: "#{id}-link", **options) do
|
link_to(url, id: "#{id}-link", **options) do
|
||||||
concat tag.i(class: icon)
|
concat svg_icon(icon)
|
||||||
concat " "
|
concat " "
|
||||||
concat tag.span(text)
|
concat tag.span(text)
|
||||||
end
|
end
|
||||||
@ -189,6 +189,21 @@ 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: user_path(user), 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
|
||||||
|
49
app/helpers/icon_helper.rb
Normal file
49
app/helpers/icon_helper.rb
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module IconHelper
|
||||||
|
# https://lucide.dev/
|
||||||
|
PATHS = {
|
||||||
|
# Navigation
|
||||||
|
hamburger: %(<line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/>),
|
||||||
|
brush: %(<path d="m9.06 11.9 8.07-8.06a2.85 2.85 0 1 1 4.03 4.03l-8.06 8.08"/><path d="M7.07 14.94c-1.66 0-3 1.35-3 3.02 0 1.33-2.5 1.52-2 2.02 1.08 1.1 2.49 2.02 4 2.02 2.2 0 4-1.8 4-4.04a3.01 3.01 0 0 0-3-3.02z"/>),
|
||||||
|
images: %(<path d="M18 22H4a2 2 0 0 1-2-2V6"/><path d="m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18"/><circle cx="12" cy="8" r="2"/><rect width="16" height="16" x="6" y="2" rx="2"/>),
|
||||||
|
library: %(<path d="m16 6 4 14"/><path d="M12 6v14"/><path d="M8 8v12"/><path d="M4 4v16"/>),
|
||||||
|
group: %(<path d="M3 7V5c0-1.1.9-2 2-2h2"/><path d="M17 3h2c1.1 0 2 .9 2 2v2"/><path d="M21 17v2c0 1.1-.9 2-2 2h-2"/><path d="M7 21H5c-1.1 0-2-.9-2-2v-2"/><rect width="7" height="5" x="7" y="7" rx="1"/><rect width="7" height="5" x="10" y="12" rx="1"/>),
|
||||||
|
tags: %(<path d="m15 5 6.3 6.3a2.4 2.4 0 0 1 0 3.4L17 19"/><path d="M9.586 5.586A2 2 0 0 0 8.172 5H3a1 1 0 0 0-1 1v5.172a2 2 0 0 0 .586 1.414L8.29 18.29a2.426 2.426 0 0 0 3.42 0l3.58-3.58a2.426 2.426 0 0 0 0-3.42z"/><circle cx="6.5" cy="9.5" r=".5" fill="currentColor"/>),
|
||||||
|
megaphone: %(<path d="m3 11 18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/>),
|
||||||
|
message_square: %(<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>),
|
||||||
|
lectern: %(<path d="M16 12h3a2 2 0 0 0 1.902-1.38l1.056-3.333A1 1 0 0 0 21 6H3a1 1 0 0 0-.958 1.287l1.056 3.334A2 2 0 0 0 5 12h3"/><path d="M18 6V3a1 1 0 0 0-1-1h-3"/><rect width="8" height="12" x="8" y="10" rx="1"/>),
|
||||||
|
|
||||||
|
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"/>),
|
||||||
|
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"/>),
|
||||||
|
|
||||||
|
# Pagination
|
||||||
|
chevron_left: %(<path d="m15 18-6-6 6-6"/>),
|
||||||
|
chevron_right: %(<path d="m9 18 6-6-6-6"/>),
|
||||||
|
ellipsis: %(<circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/>),
|
||||||
|
|
||||||
|
# Posts
|
||||||
|
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"/>),
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
def svg_icon(name, *args)
|
||||||
|
options = args.extract_options!
|
||||||
|
width = options[:width] || 24
|
||||||
|
height = options[:height] || 24
|
||||||
|
|
||||||
|
tag.svg(
|
||||||
|
"xmlns": "http://www.w3.org/2000/svg",
|
||||||
|
"width": width,
|
||||||
|
"height": height,
|
||||||
|
"viewbox": "0 0 24 24",
|
||||||
|
"fill": "none",
|
||||||
|
"stroke": "currentColor",
|
||||||
|
"stroke-width": 2,
|
||||||
|
"stroke-linecap": "round",
|
||||||
|
"stroke-linejoin": "round",
|
||||||
|
) do
|
||||||
|
raw(PATHS[name]) # rubocop:disable Rails/OutputSafety
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -2,17 +2,23 @@
|
|||||||
|
|
||||||
module PaginationHelper
|
module PaginationHelper
|
||||||
def sequential_paginator(records)
|
def sequential_paginator(records)
|
||||||
with_paginator_wrapper do
|
tag.div(class: "paginator") do
|
||||||
return "" if records.try(:none?)
|
return "" if records.try(:none?)
|
||||||
|
|
||||||
html = "".html_safe
|
html = "".html_safe
|
||||||
unless records.is_first_page?
|
|
||||||
html << tag.li(link_to("< Previous", nav_params_for("a#{records[0].id}"), rel: "prev", id: "paginator-prev", data: { shortcut: "a left" }))
|
# Previous
|
||||||
|
html << link_to(records.is_first_page? ? "#" : nav_params_for("a#{records[0].id}"), class: "prev", id: "paginator-prev", rel: "prev", data: { shortcut: "a left", disabled: records.is_first_page? }) do
|
||||||
|
concat svg_icon(:chevron_left)
|
||||||
|
concat tag.span("Prev")
|
||||||
end
|
end
|
||||||
|
|
||||||
unless records.is_last_page?
|
# Next
|
||||||
html << tag.li(link_to("Next >", nav_params_for("b#{records[-1].id}"), rel: "next", id: "paginator-next", data: { shortcut: "d right" }))
|
html << link_to(records.is_last_page? ? "#" : nav_params_for("b#{records[-1].id}"), class: "next", id: "paginator-next", rel: "next", data: { shortcut: "d right", disabled: records.is_last_page? }) do
|
||||||
|
concat tag.span("Next")
|
||||||
|
concat svg_icon(:chevron_right)
|
||||||
end
|
end
|
||||||
|
|
||||||
html
|
html
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -22,64 +28,73 @@ module PaginationHelper
|
|||||||
return sequential_paginator(records)
|
return sequential_paginator(records)
|
||||||
end
|
end
|
||||||
|
|
||||||
with_paginator_wrapper do
|
tag.div(class: "paginator", data: { total: [records.total_pages, records.max_numbered_pages].min, current: records.current_page }) do
|
||||||
html = "".html_safe
|
html = "".html_safe
|
||||||
icon_left = tag.i(class: "fa-solid fa-chevron-left")
|
|
||||||
if records.current_page >= 2
|
# Previous
|
||||||
html << tag.li(class: "arrow") { link_to(icon_left, nav_params_for(records.current_page - 1), rel: "prev", id: "paginator-prev", data: { shortcut: "a left" }) }
|
has_prev = records.current_page < 2
|
||||||
else
|
html << link_to(has_prev ? "#" : nav_params_for(records.current_page - 1), class: "prev", id: "paginator-prev", rel: "prev", data: { shortcut: "a left", disabled: has_prev }) do
|
||||||
html << tag.li(class: "arrow") { tag.span(icon_left) }
|
concat svg_icon(:chevron_left)
|
||||||
|
concat tag.span("Prev")
|
||||||
end
|
end
|
||||||
|
|
||||||
paginator_pages(records).each do |page|
|
# Break
|
||||||
html << numbered_paginator_item(page, records)
|
html << tag.div(class: "break")
|
||||||
|
|
||||||
|
# Numbered
|
||||||
|
paginator_pages(records).each do |page, klass|
|
||||||
|
html << numbered_paginator_item(page, klass, records)
|
||||||
end
|
end
|
||||||
|
|
||||||
icon_right = tag.i(class: "fa-solid fa-chevron-right")
|
# Next
|
||||||
if records.current_page < records.total_pages
|
has_next = records.current_page >= records.total_pages
|
||||||
html << tag.li(class: "arrow") { link_to(icon_right, nav_params_for(records.current_page + 1), rel: "next", id: "paginator-next", data: { shortcut: "d right" }) }
|
html << link_to(has_next ? "#" : nav_params_for(records.current_page + 1), class: "next", id: "paginator-next", rel: "next", data: { shortcut: "d right", disabled: has_next }) do
|
||||||
else
|
concat tag.span("Next")
|
||||||
html << tag.li(class: "arrow") { tag.span(icon_right) }
|
concat svg_icon(:chevron_right)
|
||||||
end
|
end
|
||||||
|
|
||||||
html
|
html
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def with_paginator_wrapper(&)
|
|
||||||
tag.div(class: "paginator") do
|
|
||||||
tag.menu(&)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def paginator_pages(records)
|
def paginator_pages(records)
|
||||||
window = 4
|
small_window = 2
|
||||||
|
large_window = 4
|
||||||
|
|
||||||
last_page = [records.total_pages, records.max_numbered_pages].min
|
last_page = [records.total_pages, records.max_numbered_pages].min
|
||||||
left = [2, records.current_page - window].max
|
left_sm = [2, records.current_page - small_window].max
|
||||||
right = [records.current_page + window, last_page - 1].min
|
left_lg = [2, records.current_page - large_window].max
|
||||||
|
right_sm = [records.current_page + small_window, last_page - 1].min
|
||||||
|
right_lg = [records.current_page + large_window, last_page - 1].min
|
||||||
|
small_range = left_sm..right_sm
|
||||||
|
|
||||||
[
|
result = [
|
||||||
1,
|
[1, "first"],
|
||||||
("..." unless left == 2),
|
]
|
||||||
(left..right).to_a,
|
result.push([0, "spacer"]) unless left_lg == 2
|
||||||
("..." unless right == last_page - 1),
|
(left_lg..right_lg).each do |page|
|
||||||
(last_page unless last_page <= 1),
|
result.push([page, small_range.member?(page) ? "sm" : "lg"])
|
||||||
].flatten.compact
|
end
|
||||||
|
result.push([0, "spacer"]) unless right_lg == last_page - 1
|
||||||
|
result.push([last_page, "last"]) unless last_page <= 1
|
||||||
|
|
||||||
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def numbered_paginator_item(page, records)
|
def numbered_paginator_item(page, klass, records)
|
||||||
return "" if page.to_i > records.max_numbered_pages
|
return "" if page.to_i > records.max_numbered_pages
|
||||||
|
|
||||||
html = "".html_safe
|
html = "".html_safe
|
||||||
if page == "..."
|
if page == 0
|
||||||
html << tag.li(class: "more") { tag.i(class: "fa-solid fa-ellipsis") }
|
html << link_to(svg_icon(:ellipsis), nav_params_for(0), class: "spacer")
|
||||||
elsif page == records.current_page
|
elsif page == records.current_page
|
||||||
html << tag.li(class: "current-page") { tag.span(page) }
|
html << tag.span(page, class: "page current")
|
||||||
else
|
else
|
||||||
html << tag.li(class: "numbered-page") { link_to(page, nav_params_for(page)) }
|
html << link_to(page, nav_params_for(page), class: "page #{klass}")
|
||||||
end
|
end
|
||||||
|
|
||||||
html
|
html
|
||||||
end
|
end
|
||||||
|
|
||||||
|
43
app/javascript/src/javascripts/home.js
Normal file
43
app/javascript/src/javascripts/home.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Page from "./utility/page";
|
||||||
|
|
||||||
|
const Home = {};
|
||||||
|
|
||||||
|
Home.init = function () {
|
||||||
|
|
||||||
|
const $form = $("#home-search-form");
|
||||||
|
const $tags = $("#tags");
|
||||||
|
|
||||||
|
let isEmpty = !$tags.val();
|
||||||
|
let wasEmpty = isEmpty;
|
||||||
|
if (isEmpty) $form.addClass("empty");
|
||||||
|
|
||||||
|
$tags.on("input", () => {
|
||||||
|
wasEmpty = isEmpty;
|
||||||
|
isEmpty = !$tags.val();
|
||||||
|
|
||||||
|
if (isEmpty && !wasEmpty) $form.addClass("empty");
|
||||||
|
else if (!isEmpty && wasEmpty) $form.removeClass("empty");
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".home-buttons a").on("click", (event) => {
|
||||||
|
if (isEmpty) return; // Act like regular links
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
const extraTags = $(event.currentTarget).attr("tags");
|
||||||
|
if (extraTags) {
|
||||||
|
$tags.val((index, value) => {
|
||||||
|
return value + " " + extraTags;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$form.trigger("submit");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
if (!Page.matches("static", "home")) return;
|
||||||
|
Home.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Home;
|
@ -2,7 +2,7 @@ const Navigation = {};
|
|||||||
|
|
||||||
Navigation.init = function () {
|
Navigation.init = function () {
|
||||||
const wrapper = $("html");
|
const wrapper = $("html");
|
||||||
$("#nav-toggle, .nav-offset-left, .nav-offset-bottom").on("click", (event) => {
|
$("#nav-toggle, .nav-offset-left, .nav-offset-bott").on("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
wrapper.toggleClass("nav-toggled");
|
wrapper.toggleClass("nav-toggled");
|
||||||
|
@ -10,7 +10,6 @@ NewsUpdate.initialize = function () {
|
|||||||
let newsOpen = false;
|
let newsOpen = false;
|
||||||
$("#news-header, #news-show").on("click", (event) => {
|
$("#news-header, #news-show").on("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log("click");
|
|
||||||
|
|
||||||
newsOpen = !newsOpen;
|
newsOpen = !newsOpen;
|
||||||
$("#news").toggleClass("open", newsOpen);
|
$("#news").toggleClass("open", newsOpen);
|
||||||
|
19
app/javascript/src/javascripts/paginator.js
Normal file
19
app/javascript/src/javascripts/paginator.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const Paginator = {};
|
||||||
|
|
||||||
|
Paginator.init_fasttravel = function (button) {
|
||||||
|
button.on("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const value = prompt("Navigate to page");
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
window.location.replace(button.attr("href").replace("page=0", "page=" + value));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
for (const one of $(".paginator a.spacer").get())
|
||||||
|
Paginator.init_fasttravel($(one));
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Paginator;
|
@ -35,12 +35,10 @@ PostModeMenu.change_tag_script = function (e) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const newScriptID = Number(e.key);
|
const newScriptID = Number(e.key);
|
||||||
console.log(newScriptID, LStorage.Posts.TagScript.ID);
|
|
||||||
if (!newScriptID || newScriptID == LStorage.Posts.TagScript.ID)
|
if (!newScriptID || newScriptID == LStorage.Posts.TagScript.ID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LStorage.Posts.TagScript.ID = newScriptID;
|
LStorage.Posts.TagScript.ID = newScriptID;
|
||||||
console.log("settings", LStorage.Posts.TagScript.ID, LStorage.Posts.TagScript.Content);
|
|
||||||
$("#tag-script-field").val(LStorage.Posts.TagScript.Content);
|
$("#tag-script-field").val(LStorage.Posts.TagScript.Content);
|
||||||
PostModeMenu.show_notice(newScriptID);
|
PostModeMenu.show_notice(newScriptID);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import LStorage from "./utility/storage";
|
import LStorage from "./utility/storage";
|
||||||
|
import Page from "./utility/page";
|
||||||
|
|
||||||
const PostSearch = {};
|
const PostSearch = {};
|
||||||
|
|
||||||
@ -10,6 +11,8 @@ PostSearch.init = function () {
|
|||||||
$(".wiki-excerpt").each((index, element) => {
|
$(".wiki-excerpt").each((index, element) => {
|
||||||
PostSearch.initialize_wiki_preview($(element));
|
PostSearch.initialize_wiki_preview($(element));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PostSearch.initialize_controls();
|
||||||
};
|
};
|
||||||
|
|
||||||
PostSearch.initialize_input = function ($form) {
|
PostSearch.initialize_input = function ($form) {
|
||||||
@ -39,21 +42,35 @@ PostSearch.initialize_input = function ($form) {
|
|||||||
|
|
||||||
PostSearch.initialize_wiki_preview = function ($preview) {
|
PostSearch.initialize_wiki_preview = function ($preview) {
|
||||||
let visible = LStorage.Posts.WikiExcerpt;
|
let visible = LStorage.Posts.WikiExcerpt;
|
||||||
if (visible)
|
if (visible) $preview.addClass("open");
|
||||||
$preview.removeClass("hidden");
|
window.setTimeout(() => { // Disable the rollout on first load
|
||||||
|
$preview.removeClass("loading");
|
||||||
|
}, 250);
|
||||||
|
|
||||||
$($preview.find("a.wiki-excerpt-toggle")).on("click", (event) => {
|
$($preview.find("h3.wiki-excerpt-toggle")).on("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
visible = !visible;
|
visible = !visible;
|
||||||
$preview.toggleClass("hidden", !visible);
|
$preview.toggleClass("open", visible);
|
||||||
LStorage.Posts.WikiExcerpt = visible;
|
LStorage.Posts.WikiExcerpt = visible;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PostSearch.initialize_controls = function () {
|
||||||
|
let fullscreen = LStorage.Posts.Fullscreen;
|
||||||
|
$("#search-fullscreen").on("click", () => {
|
||||||
|
fullscreen = !fullscreen;
|
||||||
|
$("body").attr("data-st-fullscreen", fullscreen);
|
||||||
|
LStorage.Posts.Fullscreen = fullscreen;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
if (!Page.matches("posts", "index") && !Page.matches("favorites"))
|
||||||
|
return;
|
||||||
|
|
||||||
PostSearch.init();
|
PostSearch.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ Shortcuts.initialize_data_shortcuts = function () {
|
|||||||
|
|
||||||
Shortcuts.keydown(keys, namespace, event => {
|
Shortcuts.keydown(keys, namespace, event => {
|
||||||
const e = $(`[data-shortcut="${keys}"]`).get(0);
|
const e = $(`[data-shortcut="${keys}"]`).get(0);
|
||||||
|
if ($e.data("disabled")) return;
|
||||||
if ($e.is("input, textarea")) {
|
if ($e.is("input, textarea")) {
|
||||||
$e.trigger("focus").selectEnd();
|
$e.trigger("focus").selectEnd();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,7 @@ import LStorage from "./utility/storage";
|
|||||||
|
|
||||||
const Theme = {};
|
const Theme = {};
|
||||||
|
|
||||||
Theme.Values = ["Main", "Extra", "StickyHeader", "Palette", "Navbar", "Gestures"];
|
Theme.Values = ["Main", "Extra", "StickyHeader", "ForumNotif", "Palette", "Navbar", "Gestures"];
|
||||||
|
|
||||||
for (const one of Theme.Values) {
|
for (const one of Theme.Values) {
|
||||||
Object.defineProperty(Theme, one, {
|
Object.defineProperty(Theme, one, {
|
||||||
|
@ -8,6 +8,23 @@ Thumbnails.initialize = function () {
|
|||||||
const posts = $(".post-thumb.placeholder, .thumb-placeholder-link");
|
const posts = $(".post-thumb.placeholder, .thumb-placeholder-link");
|
||||||
const replacedPosts = [];
|
const replacedPosts = [];
|
||||||
|
|
||||||
|
// Avatar special case
|
||||||
|
for (const post of $(".simple-avatar")) {
|
||||||
|
const $post = $(post);
|
||||||
|
|
||||||
|
const postID = $post.data("id");
|
||||||
|
if (!postID) continue;
|
||||||
|
|
||||||
|
const postData = postsData[postID];
|
||||||
|
if (!postData || !postData["preview_url"]) continue;
|
||||||
|
|
||||||
|
$("<img>")
|
||||||
|
.attr("src", postData["preview_url"])
|
||||||
|
.appendTo($post.find("span.simple-avatar-image"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset of the deferred posts
|
||||||
for (const post of posts) {
|
for (const post of posts) {
|
||||||
const $post = $(post);
|
const $post = $(post);
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ LStorage.Theme = {
|
|||||||
|
|
||||||
/** @returns {boolean} True if the sticky header is enabled */
|
/** @returns {boolean} True if the sticky header is enabled */
|
||||||
StickyHeader: ["theme-sheader", false],
|
StickyHeader: ["theme-sheader", false],
|
||||||
|
|
||||||
|
/** @returns {boolean} True if the forum notification dot is enabled */
|
||||||
|
ForumNotif: ["theme-forumnotif", false],
|
||||||
};
|
};
|
||||||
StorageUtils.bootstrapMany(LStorage.Theme);
|
StorageUtils.bootstrapMany(LStorage.Theme);
|
||||||
|
|
||||||
@ -85,6 +88,9 @@ LStorage.Posts = {
|
|||||||
|
|
||||||
/** @returns {boolean} True if the wiki excerpt should be visible */
|
/** @returns {boolean} True if the wiki excerpt should be visible */
|
||||||
WikiExcerpt: ["e6.posts.wiki", true],
|
WikiExcerpt: ["e6.posts.wiki", true],
|
||||||
|
|
||||||
|
/** @returns {boolean} True if the search should be displayed in fullscreen */
|
||||||
|
Fullscreen: ["e6.posts.fusk", false],
|
||||||
};
|
};
|
||||||
StorageUtils.bootstrapMany(LStorage.Posts);
|
StorageUtils.bootstrapMany(LStorage.Posts);
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
@import "base/links";
|
@import "base/links";
|
||||||
@import "base/fontawesome";
|
@import "base/fontawesome";
|
||||||
|
|
||||||
|
@import "common/standard_variables";
|
||||||
|
@import "common/standard_elements";
|
||||||
|
|
||||||
@import "common/footer";
|
@import "common/footer";
|
||||||
@import "common/helper_classes";
|
@import "common/helper_classes";
|
||||||
@import "common/helper_palette";
|
@import "common/helper_palette";
|
||||||
|
@ -1,73 +1,84 @@
|
|||||||
footer#page-footer {
|
footer.footer-wrapper {
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 2fr;
|
|
||||||
gap: 0.5rem 0;
|
|
||||||
|
|
||||||
padding: 0.5rem 0 1rem;
|
|
||||||
margin: 1rem 0 0;
|
|
||||||
|
|
||||||
background: var(--color-foreground);
|
background: var(--color-foreground);
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
.footer-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content min-content;
|
||||||
|
grid-template-areas:
|
||||||
|
"logo . "
|
||||||
|
"left right";
|
||||||
|
justify-items: center;
|
||||||
|
gap: 0.5rem 0;
|
||||||
|
|
||||||
|
width: min-content;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo {
|
||||||
|
grid-area: logo;
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 5rem;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
// Aligning the logo with the line below
|
||||||
|
margin-right: -3.25rem;
|
||||||
|
|
||||||
|
background: themed("color-background") themed("image-background");
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.footer-left, .footer-right {
|
.footer-left, .footer-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
gap: 0.25em;
|
box-sizing: border-box;
|
||||||
padding: 0 0.5rem;
|
width: 100%;
|
||||||
|
gap: 0.25rem;
|
||||||
font-size: 1.25em;
|
|
||||||
|
font-size: 1rem;
|
||||||
a, span {
|
|
||||||
line-height: 1.25em;
|
a, span { white-space: nowrap; }
|
||||||
}
|
span { line-height: 1.25em; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-left {
|
.footer-left {
|
||||||
align-items: end;
|
grid-area: left;
|
||||||
border-right: 1px solid var(--color-section);
|
padding-right: 1rem;
|
||||||
|
|
||||||
|
text-align: right;
|
||||||
|
border-right: 1px solid var(--color-section-lighten-5);
|
||||||
}
|
}
|
||||||
|
.footer-right {
|
||||||
.footer-logo {
|
grid-area: right;
|
||||||
grid-column: 1 / -1;
|
padding-left: 1rem;
|
||||||
grid-row: 1;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Desktop
|
// Desktop-ish
|
||||||
footer#page-footer {
|
footer.footer-wrapper {
|
||||||
@include window-larger-than(800px) {
|
@include window-larger-than(450px) {
|
||||||
grid-template-columns: 1fr min-content 1fr;
|
.footer-grid {
|
||||||
|
grid-template-areas: "logo left right";
|
||||||
.footer-left, .footer-right {
|
padding: 1rem 0;
|
||||||
font-size: unset;
|
|
||||||
flex-flow: row;
|
|
||||||
align-items: center;
|
|
||||||
border: 0;
|
|
||||||
gap: 0;
|
|
||||||
|
|
||||||
a:not(:last-child)::after {
|
|
||||||
content: "";
|
|
||||||
width: 4px;
|
|
||||||
height: 4px;
|
|
||||||
background: white;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 2px;
|
|
||||||
margin: 0.125rem 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.footer-running { display: none; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-left { justify-content: right; }
|
|
||||||
|
|
||||||
.footer-logo {
|
.footer-logo {
|
||||||
grid-column: unset;
|
display: flex;
|
||||||
grid-row: unset;
|
align-items: center;
|
||||||
|
padding-right: 2rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 6rem;
|
||||||
|
margin-right: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
app/javascript/src/styles/common/_standard_elements.scss
Normal file
59
app/javascript/src/styles/common/_standard_elements.scss
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Standard button
|
||||||
|
// Could be applied to either a button or a link
|
||||||
|
// Semi-expected to have an icon
|
||||||
|
.st-button {
|
||||||
|
$button-font-size: st-value(100);
|
||||||
|
$button-background: themed("color-section-lighten-5");
|
||||||
|
$button-background-hover: themed("color-section-lighten-10");
|
||||||
|
$button-text-color: themed("color-text");
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
gap: st-value(100) / 4;
|
||||||
|
border-radius: radius(025);
|
||||||
|
|
||||||
|
// Button final size
|
||||||
|
// Font 1rem
|
||||||
|
// Padding 2 * 0.5rem
|
||||||
|
font-size: st-value(100);
|
||||||
|
line-height: st-value(100);
|
||||||
|
padding: st-value(100) / 2;
|
||||||
|
height: st-value(100) * 2;
|
||||||
|
|
||||||
|
// TODO What if button is on a light background
|
||||||
|
background: $button-background;
|
||||||
|
color: $button-text-color;
|
||||||
|
&:hover { background: $button-background-hover; }
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
// Icon should be slightly larger than text,
|
||||||
|
// with padding to fill the entire button height
|
||||||
|
height: st-value(100) * 1.5; // 1.5rem
|
||||||
|
width: st-value(100) * 1.5; // 1.5rem
|
||||||
|
margin: -#{st-value(100) / 2} 0; // 0.5rem
|
||||||
|
padding: st-value(100) / 4; // 0.25rem
|
||||||
|
|
||||||
|
border-radius: radius(025);
|
||||||
|
}
|
||||||
|
& > span {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
// Do not overflow text
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full width button
|
||||||
|
&.w100 { width: 100%; }
|
||||||
|
|
||||||
|
&.stealth {
|
||||||
|
background: none;
|
||||||
|
padding: (st-value(100) / 2) 0;
|
||||||
|
|
||||||
|
svg { background: $button-background; }
|
||||||
|
span { color: themed("color-link"); }
|
||||||
|
&:hover {
|
||||||
|
svg { background: $button-background-hover; }
|
||||||
|
span { color: themed("color-link-hover"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
app/javascript/src/styles/common/_standard_variables.scss
Normal file
21
app/javascript/src/styles/common/_standard_variables.scss
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
// Standard variables for typography and UI elements
|
||||||
|
|
||||||
|
$st-values: (
|
||||||
|
000: 0rem,
|
||||||
|
025: 0.25rem,
|
||||||
|
050: 0.50rem,
|
||||||
|
075: 0.75rem,
|
||||||
|
100: 1rem,
|
||||||
|
);
|
||||||
|
|
||||||
|
@function st-value($name) {
|
||||||
|
@return map-get($map: $st-values, $key: $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function padding($value) { @return st-value(($value)); }
|
||||||
|
@mixin st-padding($value) { padding: padding(($value)); }
|
||||||
|
|
||||||
|
@function radius($value) { @return st-value($value); }
|
||||||
|
@mixin st-radius($value) { border-radius: radius($value); }
|
@ -6,6 +6,7 @@ nav.navigation {
|
|||||||
|
|
||||||
width: 100%; // otherwise narrow when fixed
|
width: 100%; // otherwise narrow when fixed
|
||||||
z-index: 20; // otherwise post labels layered above
|
z-index: 20; // otherwise post labels layered above
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
|
||||||
/* Top bar, always visible */
|
/* Top bar, always visible */
|
||||||
@ -13,16 +14,18 @@ nav.navigation {
|
|||||||
grid-area: logo;
|
grid-area: logo;
|
||||||
|
|
||||||
background-color: themed("color-background");
|
background-color: themed("color-background");
|
||||||
|
height: 3.75rem;
|
||||||
|
|
||||||
a.nav-logo-link {
|
a.nav-logo-link {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
// Height: 3.75rem
|
// Height: 3.75rem
|
||||||
// - padding 0.25 * 2 = 0.5
|
// - padding 0.125 * 2 = 0.25
|
||||||
// - image 3.25
|
// - image 3.5
|
||||||
height: 3.25rem;
|
height: 3.5rem;
|
||||||
width: 3.25rem;
|
width: 4rem;
|
||||||
margin: 0.25rem;
|
margin: 0.125rem;
|
||||||
|
|
||||||
background-image: url("main-logo.svg");
|
background-image: url("main-logo.svg");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@ -37,160 +40,208 @@ nav.navigation {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row-reverse;
|
flex-flow: row-reverse;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
padding-right: 0.5em;
|
|
||||||
background-color: themed("color-background");
|
background-color: themed("color-background");
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
height: 3.75rem;
|
||||||
|
|
||||||
// Height: 3.75rem
|
// Height: 3.75rem
|
||||||
// - wrapper padding 0.875 * 2 = 1.75
|
// - link padding 0.625 * 2 = 1.25
|
||||||
// - link padding 0.25 * 2 = 0.5
|
// - internal size 2.5
|
||||||
// - font size 1.5
|
|
||||||
padding: 0.875rem;
|
|
||||||
|
|
||||||
& > a {
|
& > a {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.25em;
|
padding: 0.625rem 0.5rem;
|
||||||
|
|
||||||
padding: 0.25rem 0.5rem;
|
& > span {
|
||||||
background: themed("color-foreground");
|
display: flex;
|
||||||
border-radius: 6px;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
height: 2.5rem;
|
||||||
|
min-width: 2.5rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
|
||||||
& > i {
|
background: themed("color-foreground");
|
||||||
font-size: 1.5rem;
|
|
||||||
color: themed("color-link-active");
|
color: themed("color-link-active");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover > span, &:active > span { background: themed("color-section"); }
|
||||||
|
&:focus { outline: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
a.simple-avatar {
|
||||||
|
.simple-avatar-button {
|
||||||
|
padding: 0;
|
||||||
|
gap: 0;
|
||||||
|
|
||||||
|
.simple-avatar-name {
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
@include window-smaller-than(32rem) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-avatar-image {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
background: themed("color-section");
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
object-fit: cover;
|
||||||
|
|
||||||
|
z-index: 1; // above the letter
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: attr(data-name);
|
||||||
|
position: absolute;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-smaller-than(32rem) {
|
||||||
|
&.sign-in .simple-avatar-image {
|
||||||
|
background: themed("color-foreground");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent toggled menus from being too wide */
|
/* Offset elements on the left and bottom */
|
||||||
.nav-offset-left {
|
// Needed to track clicks outside the menu area
|
||||||
grid-area: offleft;
|
@each $name in ("left", "bott") {
|
||||||
display: none; // flex
|
.nav-offset-#{$name} {
|
||||||
background: #00000050;
|
grid-area: off#{$name};
|
||||||
}
|
display: none; // flex
|
||||||
|
background: #00000050;
|
||||||
.nav-offset-bottom {
|
}
|
||||||
grid-area: offbott;
|
|
||||||
display: none; // flex
|
|
||||||
background: #00000050;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toggled menus, hidden by default */
|
/* Toggled menus, hidden by default */
|
||||||
.nav-primary {
|
// Naming areas
|
||||||
grid-area: primary;
|
@each $name in (primary, secondary, tools, help) {
|
||||||
display: none; // flex
|
.nav-#{$name} {
|
||||||
flex-flow: column;
|
grid-area: $name;
|
||||||
|
display: none;
|
||||||
|
|
||||||
background-color: themed("color-section");
|
li {
|
||||||
font-size: 1.5em;
|
padding: 0;
|
||||||
|
|
||||||
li {
|
& > a {
|
||||||
padding: 0;
|
display: flex;
|
||||||
a {
|
align-items: center;
|
||||||
display: block;
|
gap: 0.5rem;
|
||||||
border-bottom: 1px solid themed("color-foreground");
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
// "Comments" is usually the longest and might wrap
|
white-space: nowrap;
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
i {
|
svg {
|
||||||
width: 1.5rem;
|
margin: -0.25rem 0;
|
||||||
color: themed("color-link-active");
|
color: themed("color-link-active");
|
||||||
text-align: center;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.current a { background-color: themed("color-foreground"); }
|
|
||||||
&.forum-updated {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: "";
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
|
|
||||||
background: var(--palette-text-red);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
right: 0.2em;
|
|
||||||
top: 1em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-secondary {
|
// Common top
|
||||||
grid-area: secondary;
|
.nav-primary, .nav-secondary {
|
||||||
display: none; // flex
|
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
|
||||||
background-color: themed("color-foreground");
|
|
||||||
font-size: 1.35em;
|
|
||||||
height: 440px;
|
|
||||||
|
|
||||||
// Prevent the tools / help buttons from being pushed
|
// Prevent the tools / help buttons from being pushed
|
||||||
// way too low on pages with a lot of secondary links
|
// way too low on pages with a lot of secondary links
|
||||||
overflow: scroll;
|
height: 422px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
li a {
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-primary {
|
||||||
|
background-color: themed("color-section");
|
||||||
|
font-size: 1.25rem;
|
||||||
|
|
||||||
|
li > a {
|
||||||
|
border-bottom: 1px solid themed("color-foreground");
|
||||||
|
line-height: 1.25rem;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
}
|
||||||
|
li.current a { background-color: themed("color-foreground"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-secondary {
|
||||||
|
background-color: themed("color-foreground");
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
padding: 0;
|
& > a {
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
border-bottom: 1px solid themed("color-section");
|
border-bottom: 1px solid themed("color-section");
|
||||||
padding: 0.5em;
|
line-height: 1.2rem;
|
||||||
|
padding: 0.7rem;
|
||||||
|
|
||||||
|
white-space: wrap; // forum menus are long
|
||||||
}
|
}
|
||||||
|
|
||||||
&.divider {
|
&.divider {
|
||||||
border-bottom: 1px solid themed("color-section");
|
border-bottom: 1px solid themed("color-section");
|
||||||
height: 0.25em;
|
height: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
form input[type="text"] {
|
form input[type="text"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
// Reduced font size to make the search
|
font-size: 1.25rem;
|
||||||
// box less claustrophobic
|
padding: 0.5rem 0.5rem;
|
||||||
font-size: 1em;
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tools {
|
// Common bottom
|
||||||
grid-area: tools;
|
.nav-tools, .nav-help {
|
||||||
|
|
||||||
display: none; // grid
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
grid-template-rows: min-content;
|
grid-template-rows: min-content;
|
||||||
|
font-size: 1.1rem;
|
||||||
padding: 1rem;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
background-color: themed("color-section");
|
background-color: themed("color-section");
|
||||||
|
|
||||||
|
li > a {
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
padding: 0.7rem 1rem;
|
||||||
|
line-height: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tools {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
border-top: 1px solid themed("color-foreground");
|
border-top: 1px solid themed("color-foreground");
|
||||||
|
padding: 1rem 1rem 0.5rem;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
padding: 0;
|
a { background: themed("color-section-lighten-5"); }
|
||||||
|
|
||||||
&.nav-tools-login { grid-column: 1 / -1; }
|
&.nav-tools-login { grid-column: 1 / -1; }
|
||||||
|
|
||||||
& > a {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
background: themed("color-section-lighten-5");
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
font-size: 125%;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
i { color: themed("color-link-active"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.anonymous li.nav-tools-themes {
|
&.anonymous li.nav-tools-themes {
|
||||||
@ -199,42 +250,19 @@ nav.navigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-help {
|
.nav-help {
|
||||||
grid-area: help;
|
|
||||||
|
|
||||||
display: none; // grid
|
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
grid-template-rows: min-content;
|
padding: 0.5rem 1rem 1rem;
|
||||||
|
|
||||||
padding: 1rem;
|
|
||||||
gap: 1rem;
|
|
||||||
|
|
||||||
background: themed("color-section");
|
|
||||||
|
|
||||||
li {
|
li {
|
||||||
padding: 0;
|
a { background: themed("color-section-darken-5"); }
|
||||||
|
|
||||||
&.nav-help-discord,
|
&.nav-help-discord,
|
||||||
&.nav-help-subscribestar {
|
&.nav-help-subscribestar {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > a {
|
& > a img {
|
||||||
display: flex;
|
height: 1.5rem;
|
||||||
|
margin: -0.2rem 0;
|
||||||
background: themed("color-section-darken-5");
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
font-size: 125%;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.25em;
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 1.25em;
|
|
||||||
margin: -0.5em 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to put the wiki/help links before discord/sstar on mobile
|
// Hack to put the wiki/help links before discord/sstar on mobile
|
||||||
@ -255,6 +283,29 @@ body[data-th-sheader="true"] nav.navigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Forum notification
|
||||||
|
body[data-th-forumnotif="true"] nav.navigation .nav-primary li.forum-updated {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
background: palette("text-red");
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
right: 0.2rem;
|
||||||
|
top: 1.25rem;
|
||||||
|
|
||||||
|
@include window-larger-than(800px) {
|
||||||
|
top: 0.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mobile toggle
|
// Mobile toggle
|
||||||
html.nav-toggled {
|
html.nav-toggled {
|
||||||
|
|
||||||
@ -279,14 +330,14 @@ html.nav-toggled {
|
|||||||
// Allow scrolling when the menu is too long
|
// Allow scrolling when the menu is too long
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
.nav-primary, .nav-secondary, .nav-offset-left, .nav-offset-bottom {
|
.nav-primary, .nav-secondary, .nav-offset-left, .nav-offset-bott {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.nav-tools, .nav-help {
|
.nav-tools, .nav-help {
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
.nav-primary, .nav-tools, .nav-help {
|
.nav-primary, .nav-tools, .nav-help {
|
||||||
box-shadow: -1px 0 5px -1px var(--color-background);
|
box-shadow: -3px 3px 5px -1px themed("color-background");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,74 +345,68 @@ html.nav-toggled {
|
|||||||
|
|
||||||
// Desktop
|
// Desktop
|
||||||
nav.navigation, html.nav-toggled nav.navigation {
|
nav.navigation, html.nav-toggled nav.navigation {
|
||||||
@include window-larger-than(800px) {
|
@include window-larger-than(50rem) {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"logo primary help tools "
|
"logo primary help help controls"
|
||||||
"logo secondary secondary secondary"
|
"logo secondary secondary tools controls";
|
||||||
;
|
grid-template-columns: min-content min-content minmax(0, 1fr) min-content 3.25rem;
|
||||||
grid-template-columns: min-content min-content minmax(0, 1fr) min-content;
|
grid-template-rows: 1.5rem 1.75rem;
|
||||||
grid-template-rows: 1.75em 2em;
|
|
||||||
|
|
||||||
padding: 0 1em 0.5em;
|
padding: 0 1rem 0.5rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: unset;
|
height: unset;
|
||||||
|
|
||||||
background: var(--color-background);
|
background: themed("color-background");
|
||||||
overflow-y: hidden; // overrides mobile hack allowing the menu scrolling
|
overflow-y: hidden; // overrides mobile hack allowing the menu scrolling
|
||||||
|
|
||||||
.nav-logo {
|
.nav-logo a.nav-logo-link {
|
||||||
a.nav-logo-link { margin: 0.25rem 0.5rem 0 0; }
|
height: 3.25rem;
|
||||||
|
width: 3.25rem;
|
||||||
|
margin: 0.25rem 0.5rem 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-offset-left, .nav-offset-bottom, .nav-controls { display: none; }
|
.mobile { display: none; }
|
||||||
|
|
||||||
.nav-primary {
|
// All link ribbons
|
||||||
|
.desktop {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row;
|
flex-flow: row;
|
||||||
|
|
||||||
background: unset;
|
font-size: 0.875rem;
|
||||||
font-size: 1.05em;
|
box-shadow: unset;
|
||||||
padding: 0 0.25em;
|
|
||||||
|
|
||||||
li {
|
li a {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
a {
|
padding: 0 0.625rem;
|
||||||
align-content: center;
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
border-bottom: 0;
|
.nav-primary {
|
||||||
padding: 0 0.75em;
|
background: unset;
|
||||||
i { display: none; }
|
height: unset;
|
||||||
}
|
padding-left: 0.25rem;
|
||||||
|
|
||||||
&.forum-updated::after {
|
li a {
|
||||||
top: 0.2em;
|
border-bottom: 0;
|
||||||
}
|
svg { display: none; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-secondary {
|
.nav-secondary {
|
||||||
display: flex;
|
|
||||||
flex-flow: row;
|
|
||||||
height: unset;
|
height: unset;
|
||||||
|
|
||||||
padding: 0 0.25em;
|
padding: 0 0.25rem;
|
||||||
font-size: 1.05em;
|
border-radius: 0.25rem 0 0 0.25rem;
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
// Silly fix for too many links
|
overflow: hidden; // Silly fix for too many links
|
||||||
overflow: hidden;
|
z-index: 1; // above the avatar
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: flex;
|
a { border-bottom: 0; }
|
||||||
|
|
||||||
a {
|
|
||||||
align-content: center;
|
|
||||||
|
|
||||||
border-bottom: 0;
|
|
||||||
padding: 0 0.75em;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.divider {
|
&.divider {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -371,50 +416,46 @@ nav.navigation, html.nav-toggled nav.navigation {
|
|||||||
&::after { content: "|"; }
|
&::after { content: "|"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form input[type="text"] {
|
||||||
display: flex;
|
width: 12rem;
|
||||||
align-items: center;
|
padding: 0.25rem 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
input[type="text"] { min-width: 10em; }
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tools, .nav-help {
|
.nav-tools, .nav-help {
|
||||||
display: flex;
|
|
||||||
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: unset;
|
background: unset;
|
||||||
border: none;
|
border: none;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
|
|
||||||
li {
|
li a {
|
||||||
display: flex;
|
gap: 0.25rem;
|
||||||
|
|
||||||
a {
|
background: unset;
|
||||||
align-content: center;
|
text-align: unset;
|
||||||
|
border-radius: 0;
|
||||||
background: unset;
|
|
||||||
font-size: 1.05em;
|
|
||||||
padding: 0 0.75em;
|
|
||||||
text-align: unset;
|
|
||||||
white-space: nowrap;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tools {
|
.nav-tools {
|
||||||
|
background: themed("color-foreground");
|
||||||
// Otherwise help gets layered above it
|
|
||||||
// When the viewport is narrow (but not mobile)
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
background: var(--color-background);
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
i { color: themed("color-link"); }
|
padding: 0 0.5rem;
|
||||||
&:hover i { color: themed("color-link-hover"); }
|
|
||||||
|
svg {
|
||||||
|
color: themed("color-link");
|
||||||
|
height: 1.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
}
|
||||||
|
&:hover svg { color: themed("color-link-hover"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.nav-tools-themes, &.nav-tools-settings {
|
&.nav-tools-themes, &.nav-tools-settings {
|
||||||
@ -422,26 +463,123 @@ nav.navigation, html.nav-toggled nav.navigation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.nav-help {
|
|
||||||
li a img { display: none; }
|
|
||||||
|
|
||||||
|
.nav-help {
|
||||||
|
|
||||||
|
// At small resolutions, overflow can
|
||||||
|
// cause scrollbars to appear
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
li a img { display: none; }
|
||||||
li.current a {
|
li.current a {
|
||||||
background-color: themed("color-foreground");
|
background-color: themed("color-foreground");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-primary, .nav-tools, .nav-help { box-shadow: unset; }
|
.nav-controls {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
height: 3.25rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0.25rem 0 0;
|
||||||
|
|
||||||
|
#nav-toggle { display: none; }
|
||||||
|
|
||||||
|
a.simple-avatar {
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.simple-avatar-button {
|
||||||
|
background: none;
|
||||||
|
color: inherit;
|
||||||
|
align-items: start;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 0.875rem;
|
||||||
|
|
||||||
|
.simple-avatar-name {
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-avatar-image {
|
||||||
|
height: 3rem;
|
||||||
|
width: 3rem;
|
||||||
|
background: themed("color-foreground");
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2.75rem;
|
||||||
|
height: 2.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icon collapse
|
||||||
|
// Stage 1: discord and subscribestar buttons
|
||||||
|
.collapse-1 { display: none; }
|
||||||
|
@include window-larger-than(77rem) {
|
||||||
|
.collapse-1 { display: flex; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage 2: account label
|
||||||
|
.collapse-2 .simple-avatar-name { display: none; }
|
||||||
|
@include window-larger-than(65rem) {
|
||||||
|
.collapse-2 .simple-avatar-name { display: unset; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tweak for the secondary menu on desktop
|
// Tweak for the secondary menu on desktop
|
||||||
body.c-static.a-home {
|
body.c-static.a-home {
|
||||||
@include window-larger-than(800px) {
|
@include window-larger-than(50rem) {
|
||||||
nav.navigation, menu.nav-logo, menu.nav-secondary {
|
|
||||||
|
nav.navigation {
|
||||||
|
|
||||||
|
// Center and align the navbar
|
||||||
|
grid-template-areas: "logo primary help controls";
|
||||||
|
grid-template-columns: repeat(4, min-content);
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
// Remove padding to prevent a scrollbar
|
||||||
|
// at low desktop resolutions
|
||||||
|
padding: 0 0 0.5rem;
|
||||||
|
|
||||||
|
#nav-subscribestar, #nav-discord, .nav-secondary, .nav-tools { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match the background colors
|
||||||
|
nav.navigation, menu.nav-logo, menu.nav-secondary, menu.nav-controls {
|
||||||
background: unset;
|
background: unset;
|
||||||
}
|
}
|
||||||
menu.nav-tools {
|
menu.nav-tools {
|
||||||
background: var(--bg-color);
|
background: var(--bg-color);
|
||||||
}
|
}
|
||||||
|
menu.nav-controls {
|
||||||
|
position: static;
|
||||||
|
height: unset;
|
||||||
|
padding: 0;
|
||||||
|
.simple-avatar-button {
|
||||||
|
height: unset;
|
||||||
|
align-items: center;
|
||||||
|
.simple-avatar-image { display: none; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-smaller-than(50rem) {
|
||||||
|
// Only show the primary navbar on mobile
|
||||||
|
// since the secondary is empty anyways
|
||||||
|
nav.navigation {
|
||||||
|
grid-template-areas:
|
||||||
|
"logo logo controls"
|
||||||
|
"offleft primary primary "
|
||||||
|
"offleft tools tools "
|
||||||
|
"offleft help help "
|
||||||
|
"offleft offbott offbott ";
|
||||||
|
|
||||||
|
.nav-secondary { display: none; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ div#page div#news {
|
|||||||
|
|
||||||
&.open {
|
&.open {
|
||||||
max-height: none;
|
max-height: none;
|
||||||
|
|
||||||
|
#news-body { pointer-events: unset; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#news-header {
|
#news-header {
|
||||||
@ -26,26 +28,27 @@ div#page div#news {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0.5rem 0.5rem 0;
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#news-body {
|
#news-body {
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
margin-top: 5px;
|
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
padding: 0 0.5rem 0.5rem;
|
padding: 0 0.5rem 0.5rem;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#news-dismiss {
|
#news-dismiss {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.5rem;
|
right: 0;
|
||||||
top: 0.25rem;
|
top: 0;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.15rem;
|
font-size: 1.25rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,101 @@
|
|||||||
|
.paginator {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
justify-content: space-evenly;
|
||||||
|
background-color: themed("color-foreground");
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
div.paginator {
|
width: max-content;
|
||||||
display: block;
|
margin: 0 auto;
|
||||||
padding: 2em 0 1em 0;
|
|
||||||
text-align: center;
|
|
||||||
clear: both;
|
|
||||||
|
|
||||||
menu {
|
& > a, & > span {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 2.15rem;
|
||||||
|
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
padding: 0.75rem 0.3rem; // otherwise large page numbers wrap
|
||||||
|
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: themed("color-section");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
& > a[data-disabled="true"] {
|
||||||
a {
|
color: var(--color-text);
|
||||||
margin: 0 0.25em;
|
pointer-events: none;
|
||||||
padding: 0.25em 0.75em;
|
}
|
||||||
|
|
||||||
|
// Ordering
|
||||||
|
// Oh boy
|
||||||
|
.page {
|
||||||
|
order: 20;
|
||||||
|
&.lg { display: none; }
|
||||||
|
&.current { cursor: default; }
|
||||||
|
}
|
||||||
|
.prev {
|
||||||
|
order: 1;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.spacer {
|
||||||
|
order: 20;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&:last-child { display: none; }
|
||||||
|
svg {
|
||||||
|
height: 1rem;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.next {
|
||||||
|
order: 9;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.break {
|
||||||
|
order: 10;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tablet
|
||||||
|
@include window-larger-than(35rem) {
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.125rem;
|
||||||
|
|
||||||
|
a, span {
|
||||||
|
order: 0 !important;
|
||||||
|
min-width: 2.25rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
.break { display: none; }
|
||||||
background: $paginator-hover-background;
|
.spacer {
|
||||||
color: $paginator-hover-color;
|
padding: inherit;
|
||||||
|
svg { transform: unset; }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.more {
|
.prev { margin-right: 1rem; }
|
||||||
color: $paginator-more-color;
|
.next { margin-left: 1rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(50rem) {
|
||||||
|
a, span {
|
||||||
|
padding: 0.75rem 0.5rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
.prev, .next {
|
||||||
margin: 0 0.25em;
|
span { display: none; }
|
||||||
padding: 0.25em 0.75em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include window-larger-than(65rem) {
|
||||||
|
a.page.lg { display: flex; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,14 +59,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guest-warning {
|
|
||||||
.guest-warning-dialog {
|
|
||||||
top: 5vh;
|
|
||||||
height: 90vh;
|
|
||||||
width: 80vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
div#page {
|
div#page {
|
||||||
|
|
||||||
> div /* div#c-$controller */
|
> div /* div#c-$controller */
|
||||||
|
@ -1,33 +1,55 @@
|
|||||||
.guest-warning {
|
.guest-warning {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100vh;
|
left: 0;
|
||||||
width: 100vw;
|
right: 0;
|
||||||
z-index: 500;
|
bottom: 0;
|
||||||
background-color: themed("color-background");
|
z-index: 1000;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
background: themed("color-background");
|
||||||
|
|
||||||
.guest-warning-dialog {
|
.guest-warning-dialog {
|
||||||
z-index: 500;
|
margin: 20vh 0.5em 0;
|
||||||
position: relative;
|
|
||||||
top: 20vh;
|
height: min-content;
|
||||||
margin-left: auto;
|
max-width: 360px;
|
||||||
margin-right: auto;
|
|
||||||
height: 40vh;
|
|
||||||
width: 40vw;
|
|
||||||
overflow-x: scroll;
|
|
||||||
background-color: themed("color-section");
|
|
||||||
|
|
||||||
.dialog-header {
|
.dialog-header {
|
||||||
padding: $padding-050 $base-padding;
|
padding: 0 0.5em;
|
||||||
background-color: themed("color-section-lighten-5");
|
margin-bottom: 0.5em;
|
||||||
border-bottom: 1px solid themed("color-background");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
padding: $padding-050 $base-padding;
|
background: var(--color-foreground);
|
||||||
|
padding: 2em 1em 1em;
|
||||||
|
border-radius: 3px 3px 0 0;
|
||||||
|
|
||||||
|
p:last-child { margin-bottom: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
padding: $padding-050 $base-padding;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
background: var(--color-foreground);
|
||||||
|
padding: 1em 1em 2em;
|
||||||
|
border-radius: 0 0 3px 3px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: var(--color-section-lighten-5);
|
||||||
|
color: var(--color-link);
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-section-lighten-10);
|
||||||
|
color: var(--color-link-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,12 @@ body.c-static.a-home {
|
|||||||
background-color: var(--bg-color);
|
background-color: var(--bg-color);
|
||||||
background-image: var(--bg-image);
|
background-image: var(--bg-image);
|
||||||
|
|
||||||
|
background-position-y: 3.75rem;
|
||||||
|
|
||||||
|
@include window-larger-than(800px) {
|
||||||
|
background-position-y: unset;
|
||||||
|
}
|
||||||
|
|
||||||
#page {
|
#page {
|
||||||
background: none;
|
background: none;
|
||||||
margin: 8rem auto 0;
|
margin: 8rem auto 0;
|
||||||
@ -20,7 +26,7 @@ body.c-static.a-home {
|
|||||||
|
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.25rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +79,10 @@ body.c-static.a-home {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#home-search-form:not(.empty) .home-buttons a span::before {
|
||||||
|
content: "Search ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Footer
|
// Footer
|
||||||
.home-footer-top {
|
.home-footer-top {
|
||||||
@ -86,7 +96,7 @@ body.c-static.a-home {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
border-radius: 0.5rem 0.5rem 0 0;
|
border-radius: 0.25rem 0.25rem 0 0;
|
||||||
|
|
||||||
@include window-larger-than(480px) {
|
@include window-larger-than(480px) {
|
||||||
margin: 0.5rem 0.5rem 0;
|
margin: 0.5rem 0.5rem 0;
|
||||||
@ -109,7 +119,7 @@ body.c-static.a-home {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|
||||||
border-radius: 0 0 0.5rem 0.5rem;
|
border-radius: 0 0 0.25rem 0.25rem;
|
||||||
|
|
||||||
@include window-larger-than(480px) {
|
@include window-larger-than(480px) {
|
||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
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 {
|
.post-index {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
||||||
@ -7,24 +26,46 @@
|
|||||||
"sidebar";
|
"sidebar";
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: min-content 1fr min-content;
|
grid-template-rows: min-content 1fr min-content;
|
||||||
gap: 1em;
|
|
||||||
|
flex: 1; // See Exhibit A
|
||||||
|
|
||||||
// 1. Searchbox
|
// 1. Searchbox
|
||||||
.search {
|
.search {
|
||||||
grid-area: 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 {
|
h1 {
|
||||||
font-size: $h3-size;
|
font-size: $h3-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-controls {
|
||||||
|
display: none;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Content
|
// 2. Content
|
||||||
.content {
|
.content {
|
||||||
|
display: flex; // See Exhibit A
|
||||||
|
flex-flow: column;
|
||||||
|
|
||||||
grid-area: content;
|
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
|
// Quick tag edit
|
||||||
#edit-dialog textarea {
|
#edit-dialog textarea {
|
||||||
margin-bottom: 0.25em;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual content area:
|
// Actual content area:
|
||||||
@ -32,86 +73,13 @@
|
|||||||
.post-index-gallery {
|
.post-index-gallery {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
gap: 1em;
|
gap: 1rem;
|
||||||
|
|
||||||
.wiki-excerpt {
|
flex: 1; // See Exhibit A
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
position: relative;
|
|
||||||
padding: 1em 1em 0;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
background: var(--color-section);
|
.posts-container {
|
||||||
max-width: 60em;
|
flex: 1; // See Exhibit A
|
||||||
|
grid-auto-rows: min-content;
|
||||||
.wiki-excerpt-toggle {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 1em;
|
|
||||||
outline: none;
|
|
||||||
|
|
||||||
transition: transform 0.25s;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
@include font-awesome-icon;
|
|
||||||
content: unicode("f0d8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.styled-dtext {
|
|
||||||
background: linear-gradient(to top, var(--color-section), var(--color-text));
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
background-clip: text;
|
|
||||||
color: transparent;
|
|
||||||
max-height: 10em;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
transition: max-height 0.25s;
|
|
||||||
|
|
||||||
// Disable links
|
|
||||||
pointer-events: none;
|
|
||||||
cursor: unset;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: unset;
|
|
||||||
text-decoration: underline;
|
|
||||||
&::after { content: none; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wiki-excerpt-readmore {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 3em;
|
|
||||||
|
|
||||||
// Makes the button appear in the middle of the animation
|
|
||||||
transition: visibility 0s 0.125s;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
background: var(--color-section);
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.hidden{
|
|
||||||
.wiki-excerpt-toggle { transform: rotate(-90deg); }
|
|
||||||
.styled-dtext {
|
|
||||||
max-height: 0;
|
|
||||||
}
|
|
||||||
.wiki-excerpt-readmore { visibility: hidden; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.paginator {
|
|
||||||
padding: 1em 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,6 +92,11 @@
|
|||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
gap: 1em;
|
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 selection
|
||||||
#mode-box-mode, #mode-box #set-id {
|
#mode-box-mode, #mode-box #set-id {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -139,11 +112,170 @@
|
|||||||
|
|
||||||
// Desktop
|
// Desktop
|
||||||
.post-index {
|
.post-index {
|
||||||
@include window-larger-than(800px) {
|
@include window-larger-than(50rem) {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"search content"
|
"search content"
|
||||||
"sidebar content";
|
"sidebar content";
|
||||||
grid-template-columns: 15em 1fr;
|
grid-template-columns: 14rem 1fr;
|
||||||
grid-template-rows: min-content 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;
|
||||||
|
|
||||||
|
// header
|
||||||
|
h3 {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.5rem 1rem 0.5rem 1.5rem;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
@include font-awesome-icon;
|
||||||
|
content: unicode("f0da");
|
||||||
|
|
||||||
|
transition: transform 0.25s;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// body
|
||||||
|
.styled-dtext {
|
||||||
|
background: linear-gradient(to top, themed("color-section"), themed("color-text"));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
|
||||||
|
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::after { transform: rotate(90deg); }
|
||||||
|
.styled-dtext {
|
||||||
|
max-height: 10rem;
|
||||||
|
}
|
||||||
|
.wiki-excerpt-readmore { visibility: visible; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
h3::after, .styled-dtext { transition: none; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ $modes: (
|
|||||||
);
|
);
|
||||||
|
|
||||||
@each $mode, $color in $modes {
|
@each $mode, $color in $modes {
|
||||||
#page[data-mode-menu="#{$mode}"] {
|
#page[data-mode-menu="#{$mode}"] .content {
|
||||||
background-color: $color;
|
background-color: $color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#has-parent-relationship-preview, #has-children-relationship-preview {
|
#has-parent-relationship-preview, #has-children-relationship-preview {
|
||||||
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
div#c-static {
|
div#c-static {
|
||||||
div#a-site-map {
|
div#a-site-map {
|
||||||
width: 80em;
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
max-width: 80em;
|
||||||
|
|
||||||
section {
|
section {
|
||||||
width: 20em;
|
width: 20em;
|
||||||
float: left;
|
ul { margin-bottom: 1.5em; }
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: $h3-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,8 +249,9 @@ div#c-users {
|
|||||||
|
|
||||||
div.input {
|
div.input {
|
||||||
input[type="text"], input[type="email"], input[type="password"], select {
|
input[type="text"], input[type="email"], input[type="password"], select {
|
||||||
width: 100%;
|
// z_responsive is the absolute worst
|
||||||
max-width: unset;
|
width: 100% !important;
|
||||||
|
max-width: unset !important;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,27 @@
|
|||||||
module GitHelper
|
module GitHelper
|
||||||
def self.init
|
def self.init
|
||||||
if Rails.root.join("REVISION").exist?
|
if Rails.root.join("REVISION").exist?
|
||||||
@hash = Rails.root.join("REVISION").read.strip
|
@hash = @tag = Rails.root.join("REVISION").read.strip
|
||||||
elsif system("type git > /dev/null && git rev-parse --show-toplevel > /dev/null")
|
elsif system("type git > /dev/null && git rev-parse --show-toplevel > /dev/null")
|
||||||
@hash = `git rev-parse HEAD`.strip
|
@hash = `git rev-parse HEAD`.strip
|
||||||
|
@tag = `git describe --abbrev=0`
|
||||||
else
|
else
|
||||||
@hash = ""
|
@hash = @tag = ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.tag
|
||||||
|
@tag
|
||||||
|
end
|
||||||
|
|
||||||
def self.hash
|
def self.hash
|
||||||
@hash
|
@hash
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.version
|
||||||
|
@tag.presence || short_hash
|
||||||
|
end
|
||||||
|
|
||||||
def self.short_hash
|
def self.short_hash
|
||||||
@hash[0..8]
|
@hash[0..8]
|
||||||
end
|
end
|
||||||
@ -22,4 +31,13 @@ module GitHelper
|
|||||||
def self.commit_url(commit_hash)
|
def self.commit_url(commit_hash)
|
||||||
"#{Danbooru.config.source_code_url}/commit/#{commit_hash}"
|
"#{Danbooru.config.source_code_url}/commit/#{commit_hash}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.release_url(tag_name)
|
||||||
|
"#{Danbooru.config.source_code_url}/releases/tag/#{tag_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.version_url
|
||||||
|
return release_url(@tag) if @tag.present?
|
||||||
|
commit_url(@hash)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,9 +38,6 @@ class UserFeedback < ApplicationRecord
|
|||||||
|
|
||||||
def log_destroy
|
def log_destroy
|
||||||
ModAction.log(:user_feedback_destroy, { user_id: user_id, reason: body, type: category, record_id: id })
|
ModAction.log(:user_feedback_destroy, { user_id: user_id, reason: body, type: category, record_id: id })
|
||||||
deletion_user = "\"#{CurrentUser.name}\":/users/#{CurrentUser.id}"
|
|
||||||
creator_user = "\"#{creator.name}\":/users/#{creator.id}"
|
|
||||||
StaffNote.create(body: "#{deletion_user} deleted #{category} feedback, created #{created_at.to_date} by #{creator_user}: #{body}", user_id: user_id, creator: User.system)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<% if comment.should_see?(CurrentUser.user) || (current_page?(:controller => "comments", :action => "show") && CurrentUser.id == comment.creator_id) %>
|
<% if comment.should_see?(CurrentUser.user) || (params[:controller] == "comments" && params[:action] == "show" && CurrentUser.id == comment.creator_id) %>
|
||||||
<article class="comment comment-post-grid <%= "below-threshold" if comment.below_threshold? %>" data-post-id="<%= comment.post_id %>"
|
<article class="comment comment-post-grid <%= "below-threshold" if comment.below_threshold? %>" data-post-id="<%= comment.post_id %>"
|
||||||
data-comment-id="<%= comment.id %>" data-score="<%= comment.score %>"
|
data-comment-id="<%= comment.id %>" data-score="<%= comment.score %>"
|
||||||
data-creator="<%= comment.creator&.name.downcase %>" data-is-sticky="<%= comment.is_sticky %>" data-creator-id="<%= comment.creator_id %>"
|
data-creator="<%= comment.creator&.name.downcase %>" data-is-sticky="<%= comment.is_sticky %>" data-creator-id="<%= comment.creator_id %>"
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<%= decorated_nav_link_to("Posts", "fas fa-images", posts_path) %>
|
<%= decorated_nav_link_to("Artists", :brush, artists_path) %>
|
||||||
<%= decorated_nav_link_to("Pools", "fas fa-book", gallery_pools_path) %>
|
<%= decorated_nav_link_to("Posts", :images, posts_path) %>
|
||||||
<%= decorated_nav_link_to("Sets", "fas fa-clone", post_sets_path) %>
|
<%= decorated_nav_link_to("Pools", :library, gallery_pools_path) %>
|
||||||
<%= decorated_nav_link_to("Tags", "fas fa-tags", tags_path) %>
|
<%= decorated_nav_link_to("Sets", :group, post_sets_path) %>
|
||||||
<%= decorated_nav_link_to("Blips", "fas fa-bullhorn", blips_path) %>
|
<%= decorated_nav_link_to("Tags", :tags, tags_path) %>
|
||||||
<%= decorated_nav_link_to("Comments", "fas fa-comment-alt", comments_path(group_by: "post")) %>
|
<%= decorated_nav_link_to("Blips", :megaphone, blips_path) %>
|
||||||
<%= decorated_nav_link_to("Forum", "fas fa-chalkboard", forum_topics_path, class: (CurrentUser.has_forum_been_updated? ? "forum-updated" : nil)) %>
|
<%= decorated_nav_link_to("Comments", :message_square, comments_path(group_by: "post")) %>
|
||||||
|
<%= decorated_nav_link_to("Forum", :lectern, forum_topics_path, class: (CurrentUser.has_forum_been_updated? ? "forum-updated" : nil)) %>
|
||||||
|
@ -3,45 +3,45 @@
|
|||||||
<a href="/" class="nav-logo-link"></a>
|
<a href="/" class="nav-logo-link"></a>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu class="nav-primary">
|
<menu class="nav-primary desktop">
|
||||||
<%= render "layouts/main_links" %>
|
<%= render "layouts/main_links" %>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu class="nav-offset-left"></menu>
|
<menu class="nav-offset-left mobile"></menu>
|
||||||
<menu class="nav-offset-bottom"></menu>
|
<menu class="nav-offset-bott mobile"></menu>
|
||||||
|
|
||||||
<menu class="nav-secondary <%= "empty" unless content_for(:secondary_links) %>">
|
<menu class="nav-secondary desktop <%= "empty" unless content_for(:secondary_links) %>">
|
||||||
<%= yield :secondary_links %>
|
<%= yield :secondary_links %>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu class="nav-controls">
|
<menu class="nav-controls desktop">
|
||||||
<a href="" id="nav-toggle">
|
<a role="button" href="" id="nav-toggle" class="nav-controls-toggle">
|
||||||
<i class="fas fa-bars"></i>
|
<span><%= svg_icon(:hamburger) %></span>
|
||||||
</a>
|
</a>
|
||||||
<% if CurrentUser.is_anonymous? %>
|
<% if CurrentUser.is_anonymous? %>
|
||||||
<%= link_to(new_session_path, class: "nav-tools-login") do %>
|
<a href="<%= new_session_path %>" class="simple-avatar nav-controls-profile collapse-2">
|
||||||
<i class="fas fa-sign-in-alt"></i>
|
<span class="simple-avatar-button sign-in">
|
||||||
Sign in
|
<span class="simple-avatar-name">
|
||||||
<% end %>
|
Sign In
|
||||||
|
</span>
|
||||||
|
<span class="simple-avatar-image">
|
||||||
|
<%= svg_icon(:log_in) %>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= link_to(user_path(CurrentUser.user), class: "nav-tools-login") do %>
|
<%= simple_avatar(CurrentUser.user, named: true, class: "nav-controls-profile collapse-2") %>
|
||||||
<i class="far fa-user-circle"></i>
|
|
||||||
Profile
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu class="nav-tools <%= CurrentUser.is_anonymous? ? "anonymous" : "" %>">
|
<menu class="nav-tools desktop <%= CurrentUser.is_anonymous? ? "anonymous" : "" %>">
|
||||||
<%= decorated_nav_link_to("Themes", "fas fa-swatchbook", theme_path, class: "nav-tools-themes") %>
|
<%= decorated_nav_link_to("Themes", :swatch, theme_path, class: "nav-tools-themes") %>
|
||||||
<% if CurrentUser.is_anonymous? %>
|
<% unless CurrentUser.is_anonymous? %>
|
||||||
<%= decorated_nav_link_to("Sign in", "fas fa-sign-in-alt", new_session_path, class: "nav-tools-login") %>
|
<%= decorated_nav_link_to("Settings", :settings, edit_user_path(CurrentUser.user), class: "nav-tools-settings") %>
|
||||||
<% else %>
|
|
||||||
<%= decorated_nav_link_to("Settings", "fas fa-cog", edit_user_path(CurrentUser.user), class: "nav-tools-settings") %>
|
|
||||||
<%= decorated_nav_link_to("Account #{unread_dmails(CurrentUser.user)}", "far fa-user-circle", home_users_path, class: "nav-tools-login") %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu class="nav-help <%= CurrentUser.is_anonymous? ? "anonymous" : "" %>">
|
<menu class="nav-help desktop <%= CurrentUser.is_anonymous? ? "anonymous" : "" %>">
|
||||||
<%= nav_link_to("Wiki", wiki_pages_path(title: "help:home"), class: "nav-help-wiki") %>
|
<%= nav_link_to("Wiki", wiki_pages_path(title: "help:home"), class: "nav-help-wiki") %>
|
||||||
<%= nav_link_to("Help", help_pages_path, class: "nav-help-help") %>
|
<%= nav_link_to("Help", help_pages_path, class: "nav-help-help") %>
|
||||||
<%= nav_link_to("More", site_map_path, class: "nav-help-map") %>
|
<%= nav_link_to("More", site_map_path, class: "nav-help-map") %>
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
<%= javascript_tag nonce: true do -%>
|
<%= javascript_tag nonce: true do -%>
|
||||||
(function() {
|
(function() {
|
||||||
try {
|
try {
|
||||||
var theme = localStorage.getItem('theme') || 'hexagon';
|
const values = {
|
||||||
var extra = localStorage.getItem('theme-extra') || 'none';
|
// Theme
|
||||||
var sheader = localStorage.getItem('theme-sheader') || false;
|
"th-main": localStorage.getItem("theme") || "hexagon",
|
||||||
var palette = localStorage.getItem('theme-palette') || 'default';
|
"th-extra": localStorage.getItem("theme-extra") || "none",
|
||||||
var nav = localStorage.getItem('theme-nav') || 'top';
|
"th-sheader": localStorage.getItem("theme-sheader") || false,
|
||||||
|
"th-forumnotif": localStorage.getItem("theme-forumnotif") || false,
|
||||||
|
"th-palette": localStorage.getItem("theme-palette") || "default",
|
||||||
|
"th-nav": localStorage.getItem("theme-nav") || "top",
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
"st-fullscreen": localStorage.getItem("e6.posts.fusk") || false,
|
||||||
|
};
|
||||||
|
|
||||||
var b = document.body;
|
var b = document.body;
|
||||||
b.setAttribute('data-th-main', theme);
|
for (const [name, value] of Object.entries(values)) {
|
||||||
b.setAttribute('data-th-extra', extra);
|
b.setAttribute("data-" + name, value);
|
||||||
b.setAttribute('data-th-sheader', sheader);
|
}
|
||||||
b.setAttribute('data-th-palette', palette);
|
|
||||||
b.setAttribute('data-th-nav', nav);
|
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
})();
|
})();
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
<% if CurrentUser.is_anonymous? %>
|
<% if CurrentUser.is_anonymous? %>
|
||||||
<%= render "static/guest_warning" %>
|
<%= render "static/guest_warning" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<%= yield :layout %>
|
<%= yield :layout %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= render "static/deferred_posts" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<% if news_update.present? %>
|
<% if news_update.present? %>
|
||||||
<div class="ui-state-highlight site-notice" style="display: none;" id="news" data-id="<%= news_update.id %>">
|
<div class="ui-state-highlight site-notice" style="display: none;" id="news" data-id="<%= news_update.id %>">
|
||||||
<a href="" id="news-dismiss" title="Dismiss"><i class="fas fa-times"></i></a>
|
<a href="" role="button" id="news-dismiss" title="Dismiss"><i class="fas fa-times"></i></a>
|
||||||
<h6 id="news-header">News: <%= news_update.created_at.strftime("%b %d, %Y") %>
|
<h6 id="news-header">News: <%= news_update.created_at.strftime("%b %d, %Y") %>
|
||||||
<a href="" id="news-show">Show</a>
|
<a href="" role="button" id="news-show">Show</a>
|
||||||
</h6>
|
</h6>
|
||||||
<div id="news-body" class="dtext-container"><%= format_text(news_update.message) %></div>
|
<div id="news-body" class="dtext-container"><%= format_text(news_update.message) %></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<%= render "posts/partials/common/search", title: "Posts", tags: params[:tags] %>
|
<%= render "posts/partials/common/search", title: "Posts", tags: params[:tags] %>
|
||||||
|
<%= render "posts/partials/index/controls" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
|
6
app/views/posts/partials/index/_controls.html.erb
Normal file
6
app/views/posts/partials/index/_controls.html.erb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<div class="search-controls">
|
||||||
|
<button id="search-fullscreen" class="st-button w100 stealth">
|
||||||
|
<%= svg_icon(:fullscreen) %>
|
||||||
|
<span>Fullscreen</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
@ -33,9 +33,7 @@
|
|||||||
<% if CurrentUser.is_privileged? %>
|
<% if CurrentUser.is_privileged? %>
|
||||||
<span id="tag-script-ui" style="display: none;">
|
<span id="tag-script-ui" style="display: none;">
|
||||||
<input id="tag-script-field" data-autocomplete="tag-edit" placeholder="Enter tag script" style="display: none;"/>
|
<input id="tag-script-field" data-autocomplete="tag-edit" placeholder="Enter tag script" style="display: none;"/>
|
||||||
<% if CurrentUser.is_staff? %>
|
<button id="tag-script-all">All</button>
|
||||||
<button id="tag-script-all">All</button>
|
|
||||||
<% end %>
|
|
||||||
</span>
|
</span>
|
||||||
<input id="quick-mode-reason" placeholder="Reason" style="display: none;"/>
|
<input id="quick-mode-reason" placeholder="Reason" style="display: none;"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
<div id="posts" class="post-index-gallery user-disable-cropped-<%= Danbooru.config.enable_image_cropping? && CurrentUser.user.disable_cropped_thumbnails? %>">
|
<div id="posts" class="post-index-gallery user-disable-cropped-<%= Danbooru.config.enable_image_cropping? && CurrentUser.user.disable_cropped_thumbnails? %>">
|
||||||
<% if @wiki_text.present? %>
|
<% if @wiki_text.present? %>
|
||||||
<section class="wiki-excerpt hidden">
|
<section class="wiki-excerpt loading">
|
||||||
<h3><%= @wiki_page.pretty_title %></h3>
|
<h3 role="button" class="wiki-excerpt-toggle"><%= @wiki_page.pretty_title %></h3>
|
||||||
<a href="" class="wiki-excerpt-toggle" role="button"></a>
|
|
||||||
<%= format_text(@wiki_text, allow_color: true, max_thumbs: 0) %>
|
<%= format_text(@wiki_text, allow_color: true, max_thumbs: 0) %>
|
||||||
<a href="<%= wiki_page_path(@wiki_page) %>" class="wiki-excerpt-readmore"><span>Read More</span></a>
|
<a href="<%= wiki_page_path(@wiki_page) %>" class="wiki-excerpt-readmore"><span>Read More</span></a>
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,20 +1,29 @@
|
|||||||
<footer id="page-footer">
|
<footer class="footer-wrapper">
|
||||||
<span class="footer-left">
|
<div class="footer-grid">
|
||||||
<%= link_to "Rules", terms_of_service_path %>
|
<span class="footer-logo">
|
||||||
<%= link_to "Takedowns", takedown_static_path %>
|
<a href="/"><%= image_pack_tag("main-logo.svg") %></a>
|
||||||
<%= link_to "Privacy", privacy_policy_path %>
|
</span>
|
||||||
<%= link_to "Contact", contact_path %>
|
<span class="footer-left">
|
||||||
<%= link_to "Advertising", help_page_path(id: "advertising") %>
|
<%= link_to "Rules", terms_of_service_path %>
|
||||||
</span>
|
<%= link_to "Takedowns", takedown_static_path %>
|
||||||
<span class="footer-logo">
|
<%= link_to "Privacy", privacy_policy_path %>
|
||||||
<a href="/"><%= image_pack_tag("main-logo.svg", class: "footer-logo", title: "Running #{Danbooru.config.software_name} #{GitHelper.short_hash}") %></a>
|
<%= link_to "Contact", contact_path %>
|
||||||
</span>
|
<%= link_to "Advertising", help_page_path(id: "advertising") %>
|
||||||
<span class="footer-right">
|
</span>
|
||||||
<span class="footer-running">Running <%= Danbooru.config.software_name %> <%= link_to GitHelper.short_hash.to_s, GitHelper.commit_url(GitHelper.hash) %></span>
|
<span class="footer-right">
|
||||||
<%= link_to "Themes / Gestures", theme_path %>
|
<span class="footer-running">Running e621ng</span>
|
||||||
<% if CurrentUser.user.enable_keyboard_navigation %>
|
<span class="footer-version">
|
||||||
<%= link_to "Keyboard Shortcuts", keyboard_shortcuts_path %>
|
<% if GitHelper.version.empty? %>
|
||||||
<% end %>
|
v. unknown
|
||||||
<%= link_to disable_mobile_mode? ? "Mobile mode: OFF": "Mobile mode: ON", disable_mobile_mode_path, :rel => "nofollow" %>
|
<% else %>
|
||||||
</span>
|
v. <%= link_to GitHelper.version, GitHelper.version_url %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<%= link_to "Themes / Gestures", theme_path %>
|
||||||
|
<% if CurrentUser.user.enable_keyboard_navigation %>
|
||||||
|
<%= link_to "Keyboard Shortcuts", keyboard_shortcuts_path %>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to disable_mobile_mode? ? "Mobile mode: OFF": "Mobile mode: ON", disable_mobile_mode_path, :rel => "nofollow" %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
<h1 class="dialog-header">Over 18?</h1>
|
<h1 class="dialog-header">Over 18?</h1>
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<p>
|
<p>
|
||||||
You must be over the age of 18 and agree
|
You must be <b>18 years or older</b> and agree to the <%= link_to "terms of service", terms_of_service_path, target: "_blank" %> to access this website.
|
||||||
to <%= link_to "the terms of service", terms_of_service_path, target: "_blank" %> to access this page.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
By default a limited blacklist has been applied hiding content that is commonly objected to. You may remove
|
Content that is commonly considered objectionable is blacklisted by default.
|
||||||
items from this blacklist by using the blacklist menu item.
|
You may remove tags from this blacklist using the corresponding menu item.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
|
@ -4,24 +4,27 @@
|
|||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
<section class="home-section">
|
<section class="home-section">
|
||||||
<h1><%= Danbooru.config.app_name %></h1>
|
<h1><%= Danbooru.config.app_name %></h1><br/>
|
||||||
<br/>
|
<%= form_tag(posts_path, method: "get", id: "home-search-form") do %>
|
||||||
|
|
||||||
<%= form_tag(posts_path, method: "get", class: "home-search") do %>
|
<!-- Primary Searchbar -->
|
||||||
<%= text_field_tag("tags", "", autofocus: "autofocus", placeholder: "Search posts by tag (title:\"video name\")", data: { shortcut: "q", autocomplete: "tag-query" }) %>
|
<div class="home-search">
|
||||||
<%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit") %>
|
<%= 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") %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Secondary search buttons -->
|
||||||
|
<div class="home-buttons">
|
||||||
|
<a href="<%= posts_path %>" tags="">
|
||||||
|
<i class="fas fa-splotch"></i>
|
||||||
|
<span>Latest</span>
|
||||||
|
</a>
|
||||||
|
<a href="<%= posts_path(tags: "order:rank") %>" tags="order:rank">
|
||||||
|
<i class="fas fa-fire-alt"></i>
|
||||||
|
<span>Popular</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="home-buttons">
|
|
||||||
<a href="/posts">
|
|
||||||
<i class="fas fa-splotch"></i>
|
|
||||||
Latest
|
|
||||||
</a>
|
|
||||||
<a href="/popular">
|
|
||||||
<i class="fas fa-fire-alt"></i>
|
|
||||||
Popular
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<% if news_update = NewsUpdate.recent %>
|
<% if news_update = NewsUpdate.recent %>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div id="a-site-map">
|
<div id="a-site-map">
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Posts</h1></li>
|
<li><h3>Posts</h3></li>
|
||||||
<li><%= link_to("Listing", posts_path) %></li>
|
<li><%= link_to("Listing", posts_path) %></li>
|
||||||
<li><%= link_to("Upload", new_upload_path) %></li>
|
<li><%= link_to("Upload", new_upload_path) %></li>
|
||||||
<% if CurrentUser.is_janitor? %>
|
<% if CurrentUser.is_janitor? %>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<li><%= link_to("Help", help_page_path(id: "posts")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "posts")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Post Events</h1></li>
|
<li><h3>Post Events</h3></li>
|
||||||
<li><%= link_to("Listing", post_events_path) %></li>
|
<li><%= link_to("Listing", post_events_path) %></li>
|
||||||
<li><%= link_to("Tag Changes", post_versions_path) %></li>
|
<li><%= link_to("Tag Changes", post_versions_path) %></li>
|
||||||
<li><%= link_to("Approvals", post_approvals_path) %></li>
|
<li><%= link_to("Approvals", post_approvals_path) %></li>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<li><%= link_to("Replacements", post_replacements_path) %></li>
|
<li><%= link_to("Replacements", post_replacements_path) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Tools</h1></li>
|
<li><h3>Tools</h3></li>
|
||||||
<li><%= link_to("News Updates", news_updates_path) %></li>
|
<li><%= link_to("News Updates", news_updates_path) %></li>
|
||||||
<li><%= link_to("Mascots", mascots_path) %></li>
|
<li><%= link_to("Mascots", mascots_path) %></li>
|
||||||
<li><%= link_to("Source Code", Danbooru.config.source_code_url) %></li>
|
<li><%= link_to("Source Code", Danbooru.config.source_code_url) %></li>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<li><%= link_to("DB Export", "/db_export/") %></li>
|
<li><%= link_to("DB Export", "/db_export/") %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Artists</h1></li>
|
<li><h3>Artists</h3></li>
|
||||||
<li><%= link_to("Listing", artists_path) %></li>
|
<li><%= link_to("Listing", artists_path) %></li>
|
||||||
<li><%= link_to("Avoid Posting Entries", avoid_postings_path) %></li>
|
<li><%= link_to("Avoid Posting Entries", avoid_postings_path) %></li>
|
||||||
<li><%= link_to("Avoid Posting List", avoid_posting_static_path) %></li>
|
<li><%= link_to("Avoid Posting List", avoid_posting_static_path) %></li>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Tags</h1></li>
|
<li><h3>Tags</h3></li>
|
||||||
<li><%= link_to("Listing", tags_path) %></li>
|
<li><%= link_to("Listing", tags_path) %></li>
|
||||||
<li><%= link_to("Aliases", tag_aliases_path) %></li>
|
<li><%= link_to("Aliases", tag_aliases_path) %></li>
|
||||||
<li><%= link_to("Implications", tag_implications_path) %></li>
|
<li><%= link_to("Implications", tag_implications_path) %></li>
|
||||||
@ -53,13 +53,13 @@
|
|||||||
<li><%= link_to("Help", help_page_path(id: "tags")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "tags")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Notes</h1></li>
|
<li><h3>Notes</h3></li>
|
||||||
<li><%= link_to("Listing", notes_path) %></li>
|
<li><%= link_to("Listing", notes_path) %></li>
|
||||||
<li><%= link_to("Changes", note_versions_path) %></li>
|
<li><%= link_to("Changes", note_versions_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "notes")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "notes")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Pools</h1></li>
|
<li><h3>Pools</h3></li>
|
||||||
<li><%= link_to("Listing", gallery_pools_path) %></li>
|
<li><%= link_to("Listing", gallery_pools_path) %></li>
|
||||||
<li><%= link_to("Changes", pool_versions_path) %></li>
|
<li><%= link_to("Changes", pool_versions_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "pools")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "pools")) %></li>
|
||||||
@ -67,30 +67,30 @@
|
|||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Comments</h1></li>
|
<li><h3>Comments</h3></li>
|
||||||
<li><%= link_to("Listing", comments_path) %></li>
|
<li><%= link_to("Listing", comments_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "comments")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "comments")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Forum</h1></li>
|
<li><h3>Forum</h3></li>
|
||||||
<li><%= link_to("Listing", forum_topics_path) %></li>
|
<li><%= link_to("Listing", forum_topics_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "forum")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "forum")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Wiki</h1></li>
|
<li><h3>Wiki</h3></li>
|
||||||
<li><%= link_to("Listing", wiki_pages_path) %></li>
|
<li><%= link_to("Listing", wiki_pages_path) %></li>
|
||||||
<li><%= link_to("Changes", wiki_page_versions_path) %></li>
|
<li><%= link_to("Changes", wiki_page_versions_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "wiki")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "wiki")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Blips</h1></li>
|
<li><h3>Blips</h3></li>
|
||||||
<li><%= link_to("Listing", blips_path) %></li>
|
<li><%= link_to("Listing", blips_path) %></li>
|
||||||
<li><%= link_to("Help", help_page_path(id: "blips")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "blips")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Users</h1></li>
|
<li><h3>Users</h3></li>
|
||||||
<li><%= link_to("Listing", users_path) %></li>
|
<li><%= link_to("Listing", users_path) %></li>
|
||||||
<li><%= link_to("Bans", bans_path) %></li>
|
<li><%= link_to("Bans", bans_path) %></li>
|
||||||
<% if CurrentUser.is_anonymous? %>
|
<% if CurrentUser.is_anonymous? %>
|
||||||
@ -105,7 +105,7 @@
|
|||||||
<li><%= link_to("Help", help_page_path(id: "accounts")) %></li>
|
<li><%= link_to("Help", help_page_path(id: "accounts")) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><h1>Admin</h1></li>
|
<li><h3>Admin</h3></li>
|
||||||
<% if CurrentUser.is_moderator? %>
|
<% if CurrentUser.is_moderator? %>
|
||||||
<li><%= link_to("Mod Dashboard", moderator_dashboard_path) %></li>
|
<li><%= link_to("Mod Dashboard", moderator_dashboard_path) %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -43,6 +43,12 @@
|
|||||||
<option value="true">Enabled</option>
|
<option value="true">Enabled</option>
|
||||||
</select>
|
</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">
|
||||||
|
56
db/fixes/123_convert_staffnote_to_deleted_feedback.rb
Executable file
56
db/fixes/123_convert_staffnote_to_deleted_feedback.rb
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", "environment"))
|
||||||
|
|
||||||
|
destroyed_feedback_ids = []
|
||||||
|
|
||||||
|
CurrentUser.as_system do
|
||||||
|
ModAction.where(action: "user_feedback_destroy")
|
||||||
|
# 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.
|
||||||
|
# Any entries after this are "real" destructions, that do not need to be restored.
|
||||||
|
.where("created_at < ?", CUTOFF_DATE = Date.new(2024, 8, 1))
|
||||||
|
.find_in_batches(batch_size: 10_000) do |batch|
|
||||||
|
feedback_data = batch.map do |mod_action|
|
||||||
|
record_id = mod_action.values["record_id"].to_i
|
||||||
|
destroyed_feedback_ids << record_id
|
||||||
|
|
||||||
|
{
|
||||||
|
id: record_id,
|
||||||
|
user_id: mod_action.values["user_id"].to_i,
|
||||||
|
creator_id: User.system.id, # placeholder
|
||||||
|
category: mod_action.values["type"],
|
||||||
|
body: mod_action.values["reason"]&.strip,
|
||||||
|
created_at: Date.new(1970, 1, 1), # placeholder
|
||||||
|
updated_at: mod_action.created_at,
|
||||||
|
updater_id: mod_action.creator_id,
|
||||||
|
is_deleted: true,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
UserFeedback.insert_all(feedback_data) if feedback_data.any?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CurrentUser.as_system do
|
||||||
|
ModAction.where(action: "user_feedback_create")
|
||||||
|
.where("values->>'record_id' IN (?)", destroyed_feedback_ids.map(&:to_s))
|
||||||
|
.find_in_batches(batch_size: 10_000) do |batch|
|
||||||
|
batch.each do |mod_action|
|
||||||
|
record_id = mod_action.values["record_id"].to_i
|
||||||
|
next unless destroyed_feedback_ids.include?(record_id)
|
||||||
|
|
||||||
|
UserFeedback.where(id: record_id).update_all(
|
||||||
|
creator_id: mod_action.creator_id,
|
||||||
|
created_at: mod_action.created_at,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
StaffNote.where(creator: User.system)
|
||||||
|
.where("body LIKE ?", "%deleted%feedback%")
|
||||||
|
.find_in_batches(batch_size: 10_000) do |batch|
|
||||||
|
StaffNote.where(id: batch.map(&:id)).delete_all
|
||||||
|
end
|
@ -93,7 +93,7 @@ class UserFeedbacksControllerTest < ActionDispatch::IntegrationTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "delete a feedback" do
|
should "delete a feedback" do
|
||||||
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 2 }) do
|
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 1 }) do
|
||||||
delete_auth user_feedback_path(@user_feedback), @critic
|
delete_auth user_feedback_path(@user_feedback), @critic
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -101,7 +101,7 @@ class UserFeedbacksControllerTest < ActionDispatch::IntegrationTest
|
|||||||
context "by a moderator" do
|
context "by a moderator" do
|
||||||
should "allow destroying feedbacks they created" do
|
should "allow destroying feedbacks they created" do
|
||||||
as(@mod) { @user_feedback = create(:user_feedback, user: @user) }
|
as(@mod) { @user_feedback = create(:user_feedback, user: @user) }
|
||||||
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 2 }) do
|
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 1 }) do
|
||||||
delete_auth user_feedback_path(@user_feedback), @mod
|
delete_auth user_feedback_path(@user_feedback), @mod
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -126,13 +126,13 @@ class UserFeedbacksControllerTest < ActionDispatch::IntegrationTest
|
|||||||
context "by an admin" do
|
context "by an admin" do
|
||||||
should "allow destroying feedbacks they created" do
|
should "allow destroying feedbacks they created" do
|
||||||
as(@admin) { @user_feedback = create(:user_feedback, user: @user) }
|
as(@admin) { @user_feedback = create(:user_feedback, user: @user) }
|
||||||
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 2 }) do
|
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 1 }) do
|
||||||
delete_auth user_feedback_path(@user_feedback), @admin
|
delete_auth user_feedback_path(@user_feedback), @admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
should "allow destroying feedbacks they did not create" do
|
should "allow destroying feedbacks they did not create" do
|
||||||
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 2 }) do
|
assert_difference({ "UserFeedback.count" => -1, "ModAction.count" => 1 }) do
|
||||||
delete_auth user_feedback_path(@user_feedback, format: :json), @admin
|
delete_auth user_feedback_path(@user_feedback, format: :json), @admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user