[Users] Redesign the settings page (#926)

This commit is contained in:
Cinder 2025-02-19 07:45:29 -08:00 committed by GitHub
parent 445049a89d
commit 8058179423
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 796 additions and 152 deletions

View File

@ -0,0 +1,170 @@
class Tabs {
constructor ($element) {
this.$menu = $element;
const id = this.$menu.attr("id");
const pagesWrap = $(`tabs-content[for="${id}"]`);
if (!pagesWrap) {
console.error("E6.Tabs", "No content");
return;
}
// Create page and search indices
this.index = new TabIndex(pagesWrap, this.$menu);
// Bootstrap search
const input = this.$menu.find("input[name='search']").on("input", (event, crabs) => {
const val = (input.val() + "").trim();
this.index.find(val);
// Set the query param
if (crabs) return;
const url = new URL(window.location);
if (!val) url.searchParams.delete("find");
else url.searchParams.set("find", input.val() + "");
url.searchParams.delete("tab");
window.history.pushState({}, "", url);
});
// Bootstrap tab buttons
const firstButtonName = this.$menu.find("button").first().attr("name");
this.$menu.on("click", "button", (event, crabs) => {
const button = $(event.currentTarget);
const name = button.attr("name");
if (!name) return;
// Toggle the page
this.index.openPage(name);
this.$menu.find("button.active").removeClass("active");
button.addClass("active");
input.val("");
// Set the query param
if (crabs) return;
const url = new URL(window.location);
if (name == firstButtonName) url.searchParams.delete("tab");
else url.searchParams.set("tab", name);
url.searchParams.delete("find");
window.history.pushState({}, "", url);
});
// Attempt to restore previous state
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.get("tab")) {
// No error handling: if the button does not exist nothing loads
this.$menu.find(`button[name="${queryParams.get("tab")}"]`).trigger("click", [ true ]);
input.val("");
} else if (queryParams.get("find")) {
input.val(queryParams.get("find"), [ true ]);
input.trigger("input");
} else {
// Just open the first tab
this.$menu.find("button").first().click();
input.val("");
}
}
}
class TabIndex {
constructor (wrapper, $menu) {
this.$menu = $menu;
this.pages = {};
this.search = {};
this._allEntries = wrapper.children("tab-entry");
for (const one of this._allEntries) {
const $one = $(one);
const tab = $one.attr("tab");
if (tab) {
if (!this.pages[tab]) this.pages[tab] = [];
this.pages[tab].push($one);
}
// TODO Not a great way of doing this.
// Entries with the same search string will get overwriten.
const search = $one.attr("search");
if (search) this.search[search] = $one;
}
this.groups = {};
this._allGroups = wrapper.children("tab-group");
for (const one of this._allGroups) {
const $one = $(one);
const name = $one.attr("name");
if (!name) return;
this.groups[name] = $one;
}
}
/**
* Show all entries on a specific tab
* @param {string} name Tab name
*/
openPage (name) {
if (!name || !this.pages[name]) {
console.error("E6.Tabs", name, "does not exist");
return;
}
// Activate tab entries
const groups = new Set();
this._allEntries.removeClass("active");
for (const entry of this.pages[name]) {
entry.addClass("active");
if (entry.attr("group"))
groups.add(entry.attr("group"));
}
// Activate group headers
this._allGroups.removeClass("active");
for (const group of groups)
this.groups[group].addClass("active");
}
/**
* Find settings inputs based on keywords
* @param {string} query Search query
*/
find (query) {
this._allEntries.removeClass("active");
this._allGroups.removeClass("active");
// Restore the previous session
if (query.length == 0) {
this.$menu.find("button").first().trigger("click", [ false ]);
return;
}
const terms = query.split(" ");
const groups = new Set();
for (const [tags, $element] of Object.entries(this.search)) {
for (const term of terms) {
if (!tags.includes(term)) continue;
$element.addClass("active");
if ($element.attr("group"))
groups.add($element.attr("group"));
}
}
// Activate group headers
this._allGroups.removeClass("active");
for (const group of groups)
this.groups[group].addClass("active");
}
}
$(() => {
for (const one of $("tabs-menu"))
new Tabs($(one));
});

View File

@ -44,6 +44,7 @@
@import "common/voting.scss"; @import "common/voting.scss";
@import "views/posts/posts"; @import "views/posts/posts";
@import "views/users/users";
@import "specific/admin_dashboards.scss"; @import "specific/admin_dashboards.scss";
@import "specific/api_keys.scss"; @import "specific/api_keys.scss";

View File

@ -21,11 +21,12 @@
line-height: st-value(100); line-height: st-value(100);
padding: st-value(100) / 2; padding: st-value(100) / 2;
height: st-value(100) * 2; height: st-value(100) * 2;
box-sizing: border-box;
// TODO What if button is on a light background // TODO What if button is on a light background
background: $button-background; background: $button-background;
color: $button-text-color; color: $button-text-color;
&:hover { background: $button-background-hover; } &:hover, &:active { background: $button-background-hover; }
& > svg { & > svg {
// Icon should be slightly larger than text, // Icon should be slightly larger than text,
@ -64,3 +65,53 @@
padding: (st-value(100) / 2) 0; padding: (st-value(100) / 2) 0;
} }
} }
// Colored buttons
.st-button.danger {
background: palette("background-red");
&:hover, &:active {
background: palette("background-red-d5")
}
}
// Toggle switch
label.st-toggle {
display: flex;
width: 2.5rem;
height: 1.5rem;
box-sizing: border-box;
position: relative;
background-color: themed("color-foreground");
transition: background-color 500ms;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0;
box-shadow: inset 0 0 0.25rem themed("color-background");
&::after {
content: "";
width: 1rem;
height: 1rem;
position: absolute;
top: 0.25rem;
left: 0.25rem;
background: themed("color-text-muted");
border-radius: 0.25rem;
transition: left 100ms;
}
}
input[type="checkbox"][disabled].st-toggle + label.st-toggle {
background: palette("background-grey");
cursor: not-allowed;
}
input[type="checkbox"].st-toggle { display: none; }
input[type="checkbox"].st-toggle:checked + label.st-toggle {
background-color: palette("background-green-d5");
&::after { left: 1.25rem; }
}

View File

@ -200,29 +200,6 @@ div#c-users {
} }
} }
} }
div#a-edit {
h1 {
margin: 0.5em 0;
}
h2 {
margin: 0.5em 0;
}
div.input {
margin-bottom: 2em;
}
div.input span.hint {
display: block;
max-width: 70%;
}
.active {
color: themed("color-link-active");
}
}
} }
// User signup and login // User signup and login

View File

@ -0,0 +1 @@
@import "edit/edit";

View File

@ -0,0 +1,199 @@
body.c-users.a-edit {
form.simple_form {
background: unset;
padding: unset;
margin: unset;
input[type="text"], input[type="number"], textarea, select {
width: 100%;
max-width: unset;
box-sizing: border-box;
border-radius: 0.25rem;
font-size: 1rem;
padding: 0.25rem;
}
}
#settings-account-buttons tab-body {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.5rem;
.st-button {
white-space: nowrap;
justify-content: center;
}
}
tab-submit {
input[type="submit"] {
background: themed("color-tag-artist");
font-size: 1.25rem;
padding: 0.25rem 1rem;
margin: 0.5rem;
border-radius: 0.25rem;
&:hover, &:active { background: themed("color-tag-artist-alt"); }
}
}
}
// Tabs section
tabs-menu {
margin-top: 0.5rem;
display: flex;
width: 100%;
max-width: 50rem;
flex-wrap: wrap;
// TODO Smooth drag when overflowing
overflow: auto;
& > button {
background: unset;
color: themed("color-link");
padding: 0.5rem 1rem;
border-bottom: 2px solid themed("color-section");
font-size: 1rem;
line-height: 1rem;
&.active {
background: themed("color-section");
border-radius: 0.25rem 0.25rem 0 0;
&:first-child {
border-bottom-left-radius: 0.25rem;
}
}
}
span.spacer {
flex: 1;
border-bottom: 2px solid themed("color-section");
}
input[name="search"] {
border-radius: 0 0 0.25rem 0.25rem;
font-size: 1rem;
line-height: 1rem;
padding: 0.25rem;
width: 100%;
box-sizing: border-box;
}
}
// Tabs structure
tabs-content {
display: flex;
flex-flow: column;
max-width: 50rem;
tab-group {
display: none;
&.active { display: flex; }
font-size: 1rem;
line-height: 1rem;
padding: 0.5rem 0.75rem 0.5rem;
margin: 0.5rem 0 0;
background: themed("color-section-lighten-5");
border-radius: 0.25rem 0.25rem 0 0;
}
tab-entry {
display: none;
&.active { display: grid; }
grid-template-areas: "head" "body" "hint";
grid-template-columns: 1fr;
align-items: center;
gap: 0.25rem;
background: themed("color-section");
padding: 0.5rem;
tab-head {
grid-area: head;
margin-left: 0.25em;
font-size: 0.85rem;
label { font-weight: normal; }
}
tab-body {
grid-area: body;
}
tab-hint {
grid-area: hint;
font-size: 90%;
color: themed("color-text-muted");
}
&.inline {
grid-template-areas: "head body" "hint hint";
grid-template-columns: 2fr 1fr;
tab-body { justify-self: end; }
}
&.blocky {
grid-template-areas: "body";
grid-template-columns: 1fr;
}
&.bigtext {
grid-template-columns: 1fr;
grid-template-areas: "head" "body" "hint";
}
&.buttony tab-body {
display: grid;
grid-template-columns: 1fr 4rem;
input[type="text"] { border-radius: 0.25rem 0 0 0.25rem !important; }
input[disabled] { cursor: not-allowed; }
a.st-button {
border-radius: 0 0.25rem 0.25rem 0 !important;
justify-content: center;
}
}
}
}
tab-submit {
position: sticky;
bottom: 0;
background: themed("color-section");
border-radius: 0.25rem;
width: min-content;
margin-top: 0.5rem;
}
@include window-larger-than(50rem) {
tabs-menu {
input[name="search"] {
width: unset;
border-radius: 0.25rem 0.25rem 0.25rem 0;
border-bottom: 2px solid themed("color-section");
}
}
tabs-content {
tab-entry {
grid-template-areas: "head body" ". hint";
grid-template-columns: 1fr 1fr;
&.inline {
grid-template-areas: "head hint body";
grid-template-columns: 8fr 7fr 1fr;
}
}
}
}

View File

@ -1,137 +1,36 @@
<div id="c-users"> <div id="c-users"><div id="a-edit">
<div id="a-edit"> <h1>Settings</h1>
<h1>Settings</h1>
<%= custom_form_for @user do |f| %> <tabs-menu id="settings-tabs">
<h2 id="edit-options"> <button role="tab" name="basic">Basic</button>
<%= link_to "Basic", "#basic-settings", :class => "active" %> <button role="tab" name="advanced">Advanced</button>
| <%= link_to "Advanced", "#advanced-settings" %> <button role="tab" name="blacklist">Blacklist</button>
<% if CurrentUser.user.id == @user.id %> <span class="spacer"></span>
| <%= link_to "Change password", edit_user_password_path(:user_id => @user.id), :id => "change-password" %> <input type="text" name="search" placeholder="Search Settings" />
| <%= link_to "Delete account", maintenance_user_deletion_path, :id => "delete-account" %> </tabs-menu>
<% end %>
</h2>
<fieldset id="basic-settings-section"> <%= custom_form_for @user do |form| %>
<div class="input"> <tabs-content for="settings-tabs">
<label>Name</label> <%= render "users/partials/edit/basic", form: form %>
<%= render "users/partials/edit/advanced", form: form %>
<%= render "users/partials/edit/blacklist", form: form %>
<tab-submit>
<%= form.button :submit, "Save Settings" %>
</tab-submit>
</tabs-content>
<% end %>
</div></div>
<p><%= link_to "Request a name change", new_user_name_change_request_path %></p> <noscript>
</div> <style>
tabs-menu { display: none !important; }
<div class="input"> tab-group { display: flex !important; }
<label>Email</label> tab-entry { display: grid !important; }
<p> </style>
<% if CurrentUser.user.email.present? %> </noscript>
<%= CurrentUser.user.email %>
<% else %>
<em>blank</em>
<% end %>
<%= link_to "Change your email", new_maintenance_user_email_change_path %>
</p>
</div>
<%= f.input :avatar_id, as: :string, label: "Avatar Post ID" %>
<%= f.input :profile_about, as: :dtext, label: "About Me", limit: Danbooru.config.user_about_max_size, allow_color: true %>
<%= f.input :profile_artinfo, as: :dtext, label: "Commission Info", limit: Danbooru.config.user_about_max_size, allow_color: true %>
<%= f.input :time_zone, :include_blank => false %>
<%= f.input :receive_email_notifications, :as => :select, :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :comment_threshold, :hint => "Comments below this score will be hidden by default." %>
<%= f.input :default_image_size, :hint => "Show original image size, scaled to fit, scaled to fit vertically, or show resized #{Danbooru.config.large_image_width} pixel sample version.", :label => "Default image width", :collection => [["Original", "original"], ["Fit (Horizontal)", "fit"], ["Fit (Vertical)", "fitv"], ["Sample (#{Danbooru.config.large_image_width}px)", "large"]], :include_blank => false %>
<%= f.input :per_page, :label => "Posts per page", :as => :select, :collection => (25..250), :include_blank => false %>
<%= f.input :enable_safe_mode, :label => "Safe mode", :hint => "Show only safe images. Hide questionable and explicit images.", :as => :select, :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :blacklisted_tags, :hint => "Put any tag combinations you never want to see here. Each combination should go on a separate line. <a href='/help/blacklist'>View help.</a>".html_safe, autocomplete: "tag-query", input_html: { size: "40x5" } %>
<%= f.input :blacklist_users, hint: "Hide comments, blips and forum posts from users that have been blacklisted, in addition to posts.", as: :select, include_blank: false, collection: [["Yes", "true"], ["No", "false"]] %>
</fieldset>
<fieldset id="advanced-settings-section">
<%= f.input :style_usernames, :as => :select, :label => "Colored usernames",
:hint => raw("Color each user's name depending on their level. See #{link_to 'the legend', wiki_page_path(id: 'e621:colored_usernames')} for what the colors are."),
:include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :enable_keyboard_navigation, :as => :select, :include_blank => false, :label => "Enable keyboard shortcuts", :collection => [["Yes", "true"], ["No", "false"]],
hint: raw("Enables the use of keyboard shortcuts for a majority of site actions related to posts. A list of keyboard shortcuts is available #{link_to 'here', keyboard_shortcuts_path}.")%>
<%= f.input :enable_auto_complete, :as => :select, :collection => [["Yes", "true"], ["No", "false"]], :include_blank => false,
hint: "Enables auto-completion on most tag and user entry fields." %>
<%= f.input :enable_privacy_mode, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
hint: "Prevent showing your favorites to others users (except staff)." %>
<%= f.input :show_post_statistics, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
hint: "Show post statistics below posts on search pages." %>
<%= f.input :description_collapsed_initially, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
hint: "Don't expand post descriptions on page load." %>
<%= f.input :hide_comments, as: :select, collection: [["No", "false"],["Yes", "true"]], include_blank: false,
hint: "Do not show the comments section on post pages." %>
<% unless CurrentUser.is_janitor? %>
<%= f.input :disable_user_dmails, label: "Disable DMails", hint: "Prevent other users from sending you DMails. You will be prevented from sending DMails to non-staff members while this option is enabled. Staff are always allowed to send you DMails.",
:as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
<% end %>
<%= f.input :disable_cropped_thumbnails, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
hint: "Disables displaying cropped thumbnails on the mobile layout of the site in favor of scaled thumbnails. Has no effect on the desktop site." %>
<%= f.input :show_hidden_comments, label: "Show Own Hidden Comments", :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false,
hint: "Show your own hidden comments on comment pages." %>
<% if @user.post_upload_count >= 10 %>
<%= f.input :enable_compact_uploader, label: "Enable Compact Uploader", as: :select,
collection: [["No", "false"], ["Yes", "true"]], include_blank: false,
hint: "Enables a more compact and less guided post uploader." %>
<% end %>
<div class="input text optional field_with_hint">
<label class="text optional" for="user_dmail_filter_attributes_words">Dmail filter</label>
<%= hidden_field_tag "user[dmail_filter_attributes][id]", @user.dmail_filter.try(:id) %>
<%= text_field_tag "user[dmail_filter_attributes][words]", @user.dmail_filter.try(:words), :id => "user_dmail_filter_attributes_words", :class => "text optional", :size => 40 %>
<span class="hint">A list of banned words (space delimited). Any dmail you receive with a banned word will automatically be deleted.</span>
</div>
<%= f.input :favorite_tags, :label => "Frequent tags", :hint => "A list of tags that you use often. They will appear when using the list of Related Tags.", autocomplete: "tag-query", input_html: { rows: 5 } %>
<%= f.input :disable_responsive_mode, :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false, :hint => "Disable alternative layout for mobile and tablet." %>
<%= f.input :custom_style, :label => "Custom <a href='https://en.wikipedia.org/wiki/Cascading_Style_Sheets'>CSS</a> style".html_safe, :hint => "Style to apply to the whole site.", :input_html => {:size => "40x5"} %>
</fieldset>
<%= f.button :submit, "Submit" %>
<% end %>
</div>
</div>
<% content_for(:page_title) do %> <% content_for(:page_title) do %>
Settings Settings
<% end %> <% end %>
<% content_for(:html_header) do %>
<%= javascript_tag nonce: true do -%>
$(function() {
$("#advanced-settings-section").hide();
$("#edit-options a:not(#delete-account):not(#change-password)").on("click", function(e) {
var $target = $(e.target);
$("h2 a").removeClass("active");
$("#basic-settings-section,#advanced-settings-section").hide();
$target.addClass("active");
$($target.attr("href") + "-section").show();
e.preventDefault();
});
});
<% end -%>
<% end %>
<%= render "secondary_links" %> <%= render "secondary_links" %>

View File

@ -0,0 +1,166 @@
<% tab_name = "advanced" %>
<!-- Accessibility -->
<tab-group name="accessibility">Accessibility</tab-group>
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="keyboard hotkeys shortcut navigation enable disable">
<tab-head>Enable Keyboard Shortcuts</tab-head>
<tab-body>
<%= form.input_field :enable_keyboard_navigation, as: :boolean, class: "st-toggle" %>
<%= form.label :enable_keyboard_navigation, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
The full list of shortcuts is available <%= link_to "here", keyboard_shortcuts_path %>.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="auto complete autocomplete suggestions enable disable">
<tab-head>Enable Auto Complete</tab-head>
<tab-body>
<%= form.input_field :enable_auto_complete, as: :boolean, class: "st-toggle" %>
<%= form.label :enable_auto_complete, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Tag and user name suggestions.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="accessibility" class="inline" search="users colored usernames level rank">
<tab-head>Colored Usernames</tab-head>
<tab-body>
<%= form.input_field :style_usernames, as: :boolean, class: "st-toggle" %>
<%= form.label :style_usernames, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Color names depending on the user's level.
</tab-hint>
</tab-entry>
<!-- Privacy & Messaging -->
<tab-group name="privacy">Privacy & Messaging</tab-group>
<tab-entry tab="<%= tab_name %>" group="privacy" class="inline" search="posts favorites hide disable private privacy">
<tab-head>Hide Favorites</tab-head>
<tab-body>
<%= form.input_field :enable_privacy_mode, as: :boolean, class: "st-toggle" %>
<%= form.label :enable_privacy_mode, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Prevent your favorites from being publicly visible.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="privacy" class="inline" search="dmails filter banned block enable disable toggle">
<tab-head>Disable DMails</tab-head>
<tab-body>
<%= form.input_field :disable_user_dmails, as: :boolean, class: "st-toggle", disabled: CurrentUser.is_staff? %>
<%= form.label :disable_user_dmails, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Prevent other users from sending you DMails.
<% if CurrentUser.is_staff? %>
<br />Staff members are not allowed to disable DMails.
<% end %>
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="privacy" search="dmails filter banned block">
<tab-head>DMail Filters</tab-head>
<tab-body>
<%= hidden_field_tag "user[dmail_filter_attributes][id]", @user.dmail_filter.try(:id) %>
<%= text_field_tag "user[dmail_filter_attributes][words]", @user.dmail_filter.try(:words), id: "user_dmail_filter_attributes_words", class: "text optional", size: 40 %>
</tab-body>
<tab-hint>
A list of banned words (space delimited). Any dmail you receive with a banned word will automatically be deleted.
</tab-hint>
</tab-entry>
<!-- Posts -->
<tab-group name="tags">Posts & Tags</tab-group>
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide posts thumbnails statistics stats search">
<tab-head>Show Statistics</tab-head>
<tab-body>
<%= form.input_field :show_post_statistics, as: :boolean, class: "st-toggle" %>
<%= form.label :show_post_statistics, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Show post stats below posts on search pages.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide collapse expand posts descriptions">
<tab-head>Collapse Descriptions</tab-head>
<tab-body>
<%= form.input_field :description_collapsed_initially, as: :boolean, class: "st-toggle" %>
<%= form.label :description_collapsed_initially, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Do not expand post descriptions on page load.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="tags" class="bigtext" search="posts tags frequent favorite related">
<tab-head>Frequent Tags</tab-head>
<tab-body>
<%= form.input_field :favorite_tags, label: false, autocomplete: "tag-query", rows: 5 %>
</tab-body>
<tab-hint>
A list of tags that you use often.<br />They will appear when using the list of Related Tags.
</tab-hint>
</tab-entry>
<% if @user.post_upload_count >= 10 %>
<tab-entry tab="<%= tab_name %>" group="tags" class="inline" search="show hide compact uploader posts">
<tab-head>Compact Uploader</tab-head>
<tab-body>
<%= form.input_field :enable_compact_uploader, as: :boolean, class: "st-toggle" %>
<%= form.label :enable_compact_uploader, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
A more compact and less guided post uploader.
</tab-hint>
</tab-entry>
<% end %>
<!-- Mobile -->
<tab-group name="mobile">Mobile / Tablet</tab-group>
<tab-entry tab="<%= tab_name %>" group="mobile" class="inline" search="enable disable responsive mode mobile tablet">
<tab-head>Disable Responsive Mode</tab-head>
<tab-body>
<%= form.input_field :disable_responsive_mode, as: :boolean, class: "st-toggle" %>
<%= form.label :disable_responsive_mode, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Disable alternative layout for mobile and tablet.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="mobile" class="inline" search="enable disable cropped thumbnails mobile tablet">
<tab-head>Disable Cropped Thumbnails</tab-head>
<tab-body>
<%= form.input_field :disable_cropped_thumbnails, as: :boolean, class: "st-toggle" %>
<%= form.label :disable_cropped_thumbnails, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
No effect on the desktop site.
</tab-hint>
</tab-entry>
<!-- Customization -->
<tab-group name="customization">Customization</tab-group>
<tab-entry tab="<%= tab_name %>" group="customization" class="bigtext" search="customize css styles">
<tab-head>Custom CSS</tab-head>
<tab-body>
<%= form.input_field :custom_style, label: false, rows: 8 %>
</tab-body>
<tab-hint>
Apply <a href="https://en.wikipedia.org/wiki/Cascading_Style_Sheets">CSS Styles</a> to the whole website.
</tab-hint>
</tab-entry>

View File

@ -0,0 +1,155 @@
<% tab_name = "basic" %>
<!-- Account -->
<tab-group name="account">Account</tab-group>
<tab-entry tab="<%= tab_name %>" group="account" class="buttony" search="update change user profile account name username">
<tab-head>Username</tab-head>
<tab-body>
<input type="text" value="<%= CurrentUser.user.pretty_name %>" disabled><%= link_to "Edit", new_user_name_change_request_path, class: "st-button" %>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="account" class="buttony" search="update change user profile account email e-mail address">
<tab-head>Email</tab-head>
<tab-body>
<input type="text" value="<%= CurrentUser.user.email.presence || "blank" %>" disabled><%= link_to "Edit", new_maintenance_user_email_change_path, class: "st-button" %>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="account" class="" id="settings-account-buttons" search="update change user profile account delete password">
<tab-head></tab-head>
<tab-body>
<%= link_to "Change password", edit_user_password_path(user_id: @user.id), class: "st-button" %>
<%= link_to "Delete account", maintenance_user_deletion_path, class: "st-button danger" %>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="account" search="user account timezone">
<tab-head>Time Zone</tab-head>
<tab-body>
<%= form.input_field :time_zone,
label: false,
include_blank: false
%>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="account" class="inline" search="user account email notify notifications">
<tab-head>Email Notifications</tab-head>
<tab-body>
<%= form.input_field :receive_email_notifications, as: :boolean, class: "st-toggle" %>
<%= form.label :receive_email_notifications, "!", class: "st-toggle" %>
</tab-body>
</tab-entry>
<!-- General -->
<!-- Profile -->
<tab-group name="profile">Profile</tab-group>
<tab-entry tab="<%= tab_name %>" group="profile" search="update change user avatar profile image pfp">
<tab-head><%= form.label :avatar_id, "Avatar Post ID" %></tab-head>
<tab-body>
<%= form.input_field :avatar_id, as: :string, label: false %>
</tab-body>
<tab-hint>
The image with this ID will be set as your avatar.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="profile" class="bigtext" search="user profile about me">
<tab-head><%= form.label :profile_about, "About Me" %></tab-head>
<tab-body>
<%= form.input_field :profile_about,
as: :dtext,
label: false,
rows: 8,
limit: Danbooru.config.user_about_max_size,
allow_color: true
%>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="profile" class="bigtext" search="user profile commission info">
<tab-head><%= form.label :profile_artinfo, "Commission Info" %></tab-head>
<tab-body>
<%= form.input_field :profile_artinfo,
as: :dtext,
label: false,
rows: 8,
limit: Danbooru.config.user_about_max_size,
allow_color: true
%>
</tab-body>
</tab-entry>
<!-- Posts -->
<tab-group name="posts">Posts</tab-group>
<tab-entry tab="<%= tab_name %>" group="posts" search="default images width fit horizontal vertical sample large original display show scale posts">
<tab-head><%= form.label :default_image_size, "Default image width" %></tab-head>
<tab-body>
<%= form.input_field :default_image_size,
label: false,
collection: [["Original", "original"], ["Fit (Horizontal)", "fit"], ["Fit (Vertical)", "fitv"], ["Sample (#{Danbooru.config.large_image_width}px)", "large"]],
include_blank: false
%>
</tab-body>
<tab-hint>
Show original image size, scaled to fit, scaled to fit vertically, or show resized 850 pixel sample version.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="posts" search="posts number page display show">
<tab-head><%= form.label :per_page, "Posts per page" %></tab-head>
<tab-body>
<%= form.input_field :per_page, label: false, as: :select, collection: (25..250).step(25), include_blank: false %>
</tab-body>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="posts" search="comments score rating upvotes downvotes display show hide">
<tab-head><%= form.label :comment_threshold %></tab-head>
<tab-body>
<%= form.input_field :comment_threshold, label: false %>
</tab-body>
<tab-hint>
Comments below this score will be hidden by default.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts comments show hide display hidden">
<tab-head><%= form.label :hide_comments %></tab-head>
<tab-body>
<%= form.input_field :hide_comments, as: :boolean, class: "st-toggle" %>
<%= form.label :hide_comments, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Do not show the comments section on post pages.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts comments show hide display own hidden">
<tab-head><%= form.label :show_hidden_comments, "Show own hidden comments" %></tab-head>
<tab-body>
<%= form.input_field :show_hidden_comments, as: :boolean, class: "st-toggle" %>
<%= form.label :show_hidden_comments, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Show your hidden comments on comment pages.
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="posts" class="inline" search="posts display show hide mode explicit questionable safe rated rating">
<tab-head><%= form.label :enable_safe_mode, "Safe mode" %></tab-head>
<tab-body>
<%= form.input_field :enable_safe_mode, as: :boolean, class: "st-toggle" %>
<%= form.label :enable_safe_mode, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Only show images rated safe.
</tab-hint>
</tab-entry>

View File

@ -0,0 +1,25 @@
<% tab_name = "blacklist" %>
<!-- Accessibility -->
<tab-group name="blacklisting">Blacklist</tab-group>
<tab-entry tab="<%= tab_name %>" group="blacklisting" class="bigtext" search="posts blacklisted filtered tags blocked">
<tab-head>Blacklisted Tags</tab-head>
<tab-body>
<%= form.input_field :blacklisted_tags, label: false, autocomplete: "tag-query", rows: 8 %>
</tab-body>
<tab-hint>
Put any tag combinations you never want to see here. Each combination should go on a separate line. <a href='/help/blacklist'>View help.</a>
</tab-hint>
</tab-entry>
<tab-entry tab="<%= tab_name %>" group="blacklisting" class="inline" search="posts blacklisted filter users comments blips forum">
<tab-head>Blacklist Users</tab-head>
<tab-body>
<%= form.input_field :blacklist_users, as: :boolean, class: "st-toggle" %>
<%= form.label :blacklist_users, "!", class: "st-toggle" %>
</tab-body>
<tab-hint>
Hide comments, blips and forum posts from users that have been blacklisted, in addition to posts.
</tab-hint>
</tab-entry>