From 252ae185a983b679080243f8dcbbecd493f922c3 Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Sun, 23 Mar 2025 16:44:11 +0000 Subject: [PATCH 1/7] Remove `.flex.flex--maybe-wrap` on settings' tabs as it makes the UI overflow to the right on mobile view --- lib/philomena_web/templates/setting/edit.html.slime | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index bd4139f0..9ff20f31 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -55,7 +55,7 @@ h1 Content Settings br ' Do not share this URL with anyone, it may allow an attacker to compromise your account. - .block__tab.hidden.flex.flex--maybe-wrap data-tab="display" + .block__tab.hidden data-tab="display" div .field => label f, :use_centered_layout @@ -94,7 +94,7 @@ h1 Content Settings => select f, :scale_large_images, scale_options(), class: "input" = error_tag f, :scale_large_images - .block__tab.hidden.flex.flex--maybe-wrap data-tab="comments" + .block__tab.hidden data-tab="comments" div .field => label f, :comments_newest_first, "Newest comments first" @@ -118,7 +118,7 @@ h1 Content Settings => checkbox f, :messages_newest_first .fieldlabel: i Show the newest messages first (enabled) or show the oldest messages at the top of a conversation. Enabling this makes it feel more like a top-posted email quote chain. - .block__tab.hidden.flex.flex--maybe-wrap data-tab="notifications" + .block__tab.hidden data-tab="notifications" div .field => label f, :watch_on_reply, "Subscribe on Reply" @@ -133,7 +133,7 @@ h1 Content Settings => checkbox f, :watch_on_new_topic, class: "checkbox" .fieldlabel: i Subscribe on New Threads means you'll be subscribed to threads automatically as soon as you post, to help you keep track of replies. - .block__tab.hidden.flex.flex--maybe-wrap data-tab="metadata" + .block__tab.hidden data-tab="metadata" div .field => label f, :fancy_tag_field_on_upload, "Fancy tags - uploads" From 6f21be0164ba47d7e7dc47cb031965eae9e2f45e Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Sun, 23 Mar 2025 20:04:14 +0000 Subject: [PATCH 2/7] Settings UI improvements --- assets/css/elements/forms.css | 25 +++ assets/js/settings.ts | 20 +- .../templates/setting/edit.html.slime | 179 ++++++++++-------- lib/philomena_web/views/setting_view.ex | 22 +++ 4 files changed, 161 insertions(+), 85 deletions(-) diff --git a/assets/css/elements/forms.css b/assets/css/elements/forms.css index aec54332..1b002730 100644 --- a/assets/css/elements/forms.css +++ b/assets/css/elements/forms.css @@ -92,6 +92,30 @@ textarea { margin-bottom: 6px; } +.whats-this-button, +.whats-this-button * { + /* font-size: 0.9em; */ + font-style: italic; + cursor: pointer; +} + +.whats-this-button { + color: var(--foreground-half-color); + margin-left: 10px; + + /* + We want this to behave like a button, so double clicking on it + shouldn't trigger a selection + */ + user-select: none; +} + +.whats-this-content { + color: var(--foreground-half-color); + margin: 10px auto; + font-style: italic; +} + .field_with_errors { background: var(--danger-color); } @@ -107,6 +131,7 @@ span.help-block { max-width: 30em; width: 100%; } + /* text input - grow to container size */ .hform__text { flex: 1 0 auto; diff --git a/assets/js/settings.ts b/assets/js/settings.ts index 772e4b76..a940fdf2 100644 --- a/assets/js/settings.ts +++ b/assets/js/settings.ts @@ -2,8 +2,9 @@ * Settings. */ +import { delegate } from 'utils/events'; import { assertNotNull, assertNotUndefined } from './utils/assert'; -import { $, $$, hideIf } from './utils/dom'; +import { $, $$, hideIf, toggleEl } from './utils/dom'; import store from './utils/store'; function setupThemeSettings() { @@ -44,6 +45,22 @@ function setupAutocompleteSettings() { }); } +function setupHelpExpansions() { + document.addEventListener('click', event => { + if (!(event.target instanceof HTMLElement)) { + return; + } + + const helpButton = event.target.closest('.whats-this-button'); + + if (!helpButton || !helpButton.nextElementSibling) { + return; + } + + helpButton.nextElementSibling.classList.toggle('hidden'); + }); +} + export function setupSettings() { if (!$('#js-setting-table')) return; @@ -58,4 +75,5 @@ export function setupSettings() { setupThemeSettings(); setupAutocompleteSettings(); + setupHelpExpansions(); } diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index 9ff20f31..1193d9f8 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -56,96 +56,107 @@ h1 Content Settings ' Do not share this URL with anyone, it may allow an attacker to compromise your account. .block__tab.hidden data-tab="display" - div - .field - => label f, :use_centered_layout - => checkbox f, :use_centered_layout, class: "checkbox" - .fieldlabel: i Align content to the center of the page - try this option out if you browse the site on a tablet or a fairly wide screen. - .field - => label f, :show_sidebar_and_watched_images - => checkbox f, :show_sidebar_and_watched_images, class: "checkbox" - .fieldlabel: i Show the sidebar and new watched images on the homepage (the default) or hide it. - .field - => label f, :hide_vote_counts - => checkbox f, :hide_vote_counts, class: "checkbox" - .fieldlabel: i Hide upvote and downvote counts on images, showing only the overall score - .field - => label f, :images_per_page - => number_input f, :images_per_page, min: 1, max: 50, step: 1, class: "input" - = error_tag f, :images_per_page - .fieldlabel - i - ' This is the number of images per page that are displayed on image listings and searches, up to a maximum of 50. - ' For 1080p monitors, try 24. - .field - label> Theme - => select f, :theme_name, themes(), class: "input" - = error_tag f, :theme_name - .fieldlabel: i General appearance of the theme - .field - label> Theme color - => select f, :theme_color, theme_colors(), class: "input" - = error_tag f, :theme_color - .fieldlabel: i Color of the theme - .fieldlabel: strong Don't forget to save the settings to apply the theme! - .hidden#js-theme-paths data-theme-paths=Jason.encode!(theme_paths()) - .field - => label f, :scale_large_images - => select f, :scale_large_images, scale_options(), class: "input" - = error_tag f, :scale_large_images + = field_with_help( \ + "Align content to the center of the page - try this option out if you " <> \ + "browse the site on a tablet or a fairly wide screen.", + [ \ + checkbox(f, :use_centered_layout, class: "checkbox"), + label(f, :use_centered_layout), + ] \ + ) + + = field_with_help( \ + "Show the sidebar and new watched images on the homepage (the default) or hide it.", + [ \ + checkbox(f, :show_sidebar_and_watched_images, class: "checkbox"), + label(f, :show_sidebar_and_watched_images), + ] \ + ) + + = field_with_help( \ + "Hide upvote and downvote counts on images, showing only the overall score", + [ \ + checkbox(f, :hide_vote_counts, class: "checkbox"), + label(f, :hide_vote_counts), + ] \ + ) + + = field_with_help( \ + "This is the number of images per page that are displayed on image listings and searches, up to a maximum of 50. For 1080p monitors, try 24.", \ + [ \ + number_input(f, :images_per_page, min: 1, max: 50, step: 1, class: "input"), \ + label(f, :images_per_page), \ + error_tag(f, :images_per_page) \ + ] \ + ) + + .field + => select f, :theme_name, themes(), class: "input" + label> Theme + = error_tag f, :theme_name + + .field + => select f, :theme_color, theme_colors(), class: "input" + label> Theme color + = error_tag f, :theme_color + + .block.block--fixed.block--warning Don't forget to save the settings to apply the theme! + + .hidden#js-theme-paths data-theme-paths=Jason.encode!(theme_paths()) + .field + => select f, :scale_large_images, scale_options(), class: "input" + => label f, :scale_large_images + = error_tag f, :scale_large_images .block__tab.hidden data-tab="comments" - div - .field - => label f, :comments_newest_first, "Newest comments first" - => checkbox f, :comments_newest_first - .fieldlabel: i Display the newest comments at the top of the page. - .field - => label f, :comments_always_jump_to_last, "Show latest comment page" - => checkbox f, :comments_always_jump_to_last - .fieldlabel - i - ' This setting takes effect when the previous is disabled. Always jump to the latest page (enabled) or show the first page if the oldest comments are shown at the top of the page. - br - ' Posting will always direct you to the latest page so that you can see your comment in context. - .field - => label f, :comments_per_page - => number_input f, :comments_per_page, min: 1, max: 100, step: 1, class: "input" - = error_tag f, :comments_per_page - .fieldlabel: i This is the number of comments per page that are displayed on image pages. - .field - => label f, :messages_newest_first, "Newest messages first" - => checkbox f, :messages_newest_first - .fieldlabel: i Show the newest messages first (enabled) or show the oldest messages at the top of a conversation. Enabling this makes it feel more like a top-posted email quote chain. + .field + => label f, :comments_newest_first, "Newest comments first" + => checkbox f, :comments_newest_first + .fieldlabel: i Display the newest comments at the top of the page. + .field + => label f, :comments_always_jump_to_last, "Show latest comment page" + => checkbox f, :comments_always_jump_to_last + .fieldlabel + i + ' This setting takes effect when the previous is disabled. Always jump to the latest page (enabled) or show the first page if the oldest comments are shown at the top of the page. + br + ' Posting will always direct you to the latest page so that you can see your comment in context. + .field + => label f, :comments_per_page + => number_input f, :comments_per_page, min: 1, max: 100, step: 1, class: "input" + = error_tag f, :comments_per_page + .fieldlabel: i This is the number of comments per page that are displayed on image pages. + .field + => label f, :messages_newest_first, "Newest messages first" + => checkbox f, :messages_newest_first + .fieldlabel: i Show the newest messages first (enabled) or show the oldest messages at the top of a conversation. Enabling this makes it feel more like a top-posted email quote chain. .block__tab.hidden data-tab="notifications" - div - .field - => label f, :watch_on_reply, "Subscribe on Reply" - => checkbox f, :watch_on_reply, class: "checkbox" - .fieldlabel: i Subscribe on Reply means you'll be subscribed to things (images or topics) automatically as soon as you post a comment or reply, keeping you in the conversation. - .field - => label f, :watch_on_upload, "Subscribe on Upload" - => checkbox f, :watch_on_upload, class: "checkbox" - .fieldlabel: i Subscribe on Upload means you'll be subscribed to images automatically as soon as you upload, to help you keep track of comments. - .field - => label f, :watch_on_new_topic, "Subscribe on New Threads" - => checkbox f, :watch_on_new_topic, class: "checkbox" - .fieldlabel: i Subscribe on New Threads means you'll be subscribed to threads automatically as soon as you post, to help you keep track of replies. + .field + => label f, :watch_on_reply, "Subscribe on Reply" + => checkbox f, :watch_on_reply, class: "checkbox" + .fieldlabel: i Subscribe on Reply means you'll be subscribed to things (images or topics) automatically as soon as you post a comment or reply, keeping you in the conversation. + .field + => label f, :watch_on_upload, "Subscribe on Upload" + => checkbox f, :watch_on_upload, class: "checkbox" + .fieldlabel: i Subscribe on Upload means you'll be subscribed to images automatically as soon as you upload, to help you keep track of comments. + .field + => label f, :watch_on_new_topic, "Subscribe on New Threads" + => checkbox f, :watch_on_new_topic, class: "checkbox" + .fieldlabel: i Subscribe on New Threads means you'll be subscribed to threads automatically as soon as you post, to help you keep track of replies. .block__tab.hidden data-tab="metadata" - div - .field - => label f, :fancy_tag_field_on_upload, "Fancy tags - uploads" - => checkbox f, :fancy_tag_field_on_upload, class: "checkbox" - .field - => label f, :fancy_tag_field_on_edit, "Fancy tags - edits" - => checkbox f, :fancy_tag_field_on_edit, class: "checkbox" - .fieldlabel: i The fancy tag editor gives you autosuggestions and visual representations of the tags, but is sometimes not desired - for instance when dealing with batch uploads where you might want to copy-paste tags. You can choose which type of editor to use by default here. - .field - => label f, :anonymous_by_default - => checkbox f, :anonymous_by_default, class: "checkbox" - .fieldlabel: i Check this box to post images and comments as anonymous by default, even if logged in. + .field + => label f, :fancy_tag_field_on_upload, "Fancy tags - uploads" + => checkbox f, :fancy_tag_field_on_upload, class: "checkbox" + .field + => label f, :fancy_tag_field_on_edit, "Fancy tags - edits" + => checkbox f, :fancy_tag_field_on_edit, class: "checkbox" + .fieldlabel: i The fancy tag editor gives you autosuggestions and visual representations of the tags, but is sometimes not desired - for instance when dealing with batch uploads where you might want to copy-paste tags. You can choose which type of editor to use by default here. + .field + => label f, :anonymous_by_default + => checkbox f, :anonymous_by_default, class: "checkbox" + .fieldlabel: i Check this box to post images and comments as anonymous by default, even if logged in. .block__tab class=local_tab_class(@conn) data-tab="local" .block.block--fixed.block--warning Settings on this tab are saved in the current browser. They are independent of your login. diff --git a/lib/philomena_web/views/setting_view.ex b/lib/philomena_web/views/setting_view.ex index d6826e0e..281cf4a6 100644 --- a/lib/philomena_web/views/setting_view.ex +++ b/lib/philomena_web/views/setting_view.ex @@ -38,4 +38,26 @@ defmodule PhilomenaWeb.SettingView do def staff?(%{role: role}), do: role != "user" def staff?(_), do: false + + def field_with_help(title, children) do + content = + children + |> Enum.intersperse(" ") + |> Enum.concat([ + content_tag :span, class: "whats-this-button" do + [ + content_tag(:i, "", class: "fa-regular fa-question-circle"), + " What's this?" + ] + end, + content_tag :div, class: "whats-this-content hidden" do + [ + title, + tag(:hr) + ] + end + ]) + + content_tag(:div, content, class: "field", title: title) + end end From db77c36451521db455de358bf0cf374ce8e780bb Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Sun, 23 Mar 2025 20:51:29 +0000 Subject: [PATCH 3/7] Add a round dashed border around the "What's this" button and rename it to "Help" --- assets/css/elements/forms.css | 17 +++++++++++------ assets/js/settings.ts | 2 +- lib/philomena_web/views/setting_view.ex | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/assets/css/elements/forms.css b/assets/css/elements/forms.css index 1b002730..a74ef49a 100644 --- a/assets/css/elements/forms.css +++ b/assets/css/elements/forms.css @@ -92,16 +92,21 @@ textarea { margin-bottom: 6px; } -.whats-this-button, -.whats-this-button * { - /* font-size: 0.9em; */ +.field-help-button, +.field-help-button * { font-style: italic; cursor: pointer; } -.whats-this-button { +.field-help-button { + margin-left: 6px; + font-size: 0.8em; color: var(--foreground-half-color); - margin-left: 10px; + border-color: var(--foreground-half-color); + border-style: dashed; + border-width: 1px; + border-radius: 10px; + padding: 4px; /* We want this to behave like a button, so double clicking on it @@ -110,7 +115,7 @@ textarea { user-select: none; } -.whats-this-content { +.field-help-content { color: var(--foreground-half-color); margin: 10px auto; font-style: italic; diff --git a/assets/js/settings.ts b/assets/js/settings.ts index a940fdf2..b12e8226 100644 --- a/assets/js/settings.ts +++ b/assets/js/settings.ts @@ -51,7 +51,7 @@ function setupHelpExpansions() { return; } - const helpButton = event.target.closest('.whats-this-button'); + const helpButton = event.target.closest('.field-help-button'); if (!helpButton || !helpButton.nextElementSibling) { return; diff --git a/lib/philomena_web/views/setting_view.ex b/lib/philomena_web/views/setting_view.ex index 281cf4a6..a9a82a5d 100644 --- a/lib/philomena_web/views/setting_view.ex +++ b/lib/philomena_web/views/setting_view.ex @@ -44,13 +44,13 @@ defmodule PhilomenaWeb.SettingView do children |> Enum.intersperse(" ") |> Enum.concat([ - content_tag :span, class: "whats-this-button" do + content_tag :span, class: "field-help-button" do [ content_tag(:i, "", class: "fa-regular fa-question-circle"), - " What's this?" + " Help" ] end, - content_tag :div, class: "whats-this-content hidden" do + content_tag :div, class: "field-help-content hidden" do [ title, tag(:hr) From 6ae0c27c11bf3b146b6897536e480052d2d03727 Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Mon, 24 Mar 2025 16:12:27 +0000 Subject: [PATCH 4/7] Cover comments, notifications, metadata refactoring --- assets/css/elements/forms.css | 4 + assets/js/settings.ts | 3 +- .../templates/setting/edit.html.slime | 132 ++++++++++++------ lib/philomena_web/views/setting_view.ex | 2 +- 4 files changed, 95 insertions(+), 46 deletions(-) diff --git a/assets/css/elements/forms.css b/assets/css/elements/forms.css index a74ef49a..8d1a53fa 100644 --- a/assets/css/elements/forms.css +++ b/assets/css/elements/forms.css @@ -115,6 +115,10 @@ textarea { user-select: none; } +.field-help-button:hover { + background-color: var(--primary-light-color); +} + .field-help-content { color: var(--foreground-half-color); margin: 10px auto; diff --git a/assets/js/settings.ts b/assets/js/settings.ts index b12e8226..8602aba0 100644 --- a/assets/js/settings.ts +++ b/assets/js/settings.ts @@ -2,9 +2,8 @@ * Settings. */ -import { delegate } from 'utils/events'; import { assertNotNull, assertNotUndefined } from './utils/assert'; -import { $, $$, hideIf, toggleEl } from './utils/dom'; +import { $, $$, hideIf } from './utils/dom'; import store from './utils/store'; function setupThemeSettings() { diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index 1193d9f8..7fecdd8b 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -82,7 +82,8 @@ h1 Content Settings ) = field_with_help( \ - "This is the number of images per page that are displayed on image listings and searches, up to a maximum of 50. For 1080p monitors, try 24.", \ + "The number of images per page that are displayed on image listings " <> \ + "and searches, up to a maximum of 50. For 1080p monitors, try 24.", [ \ number_input(f, :images_per_page, min: 1, max: 50, step: 1, class: "input"), \ label(f, :images_per_page), \ @@ -109,54 +110,99 @@ h1 Content Settings = error_tag f, :scale_large_images .block__tab.hidden data-tab="comments" - .field - => label f, :comments_newest_first, "Newest comments first" - => checkbox f, :comments_newest_first - .fieldlabel: i Display the newest comments at the top of the page. - .field - => label f, :comments_always_jump_to_last, "Show latest comment page" - => checkbox f, :comments_always_jump_to_last - .fieldlabel - i - ' This setting takes effect when the previous is disabled. Always jump to the latest page (enabled) or show the first page if the oldest comments are shown at the top of the page. - br - ' Posting will always direct you to the latest page so that you can see your comment in context. - .field - => label f, :comments_per_page - => number_input f, :comments_per_page, min: 1, max: 100, step: 1, class: "input" - = error_tag f, :comments_per_page - .fieldlabel: i This is the number of comments per page that are displayed on image pages. - .field - => label f, :messages_newest_first, "Newest messages first" - => checkbox f, :messages_newest_first - .fieldlabel: i Show the newest messages first (enabled) or show the oldest messages at the top of a conversation. Enabling this makes it feel more like a top-posted email quote chain. + = field_with_help( \ + "Display the newest comments at the top of the page.", \ + [ \ + checkbox(f, :comments_newest_first, class: "checkbox"), \ + label(f, :comments_newest_first, "Newest comments first"), \ + ] \ + ) + + = field_with_help( \ + "This setting takes effect when the previous is disabled. " <> \ + "Always jump to the latest page (enabled) or show the first page " <> \ + "if the oldest comments are shown at the top of the page.\n" <> \ + "Posting will always direct you to the latest page " <> \ + "so that you can see your comment in context.", + [ \ + checkbox(f, :comments_always_jump_to_last, class: "checkbox"), + label(f, :comments_always_jump_to_last, "Show latest comment page"), + ] \ + ) + + = field_with_help( \ + "The number of comments per page that are displayed on image pages.", + [ \ + number_input(f, :comments_per_page, min: 1, max: 100, step: 1, class: "input"), + label(f, :comments_per_page), + error_tag(f, :comments_per_page), + ] \ + ) + + = field_with_help( \ + "Show the newest messages first (enabled) or show the oldest messages " <> \ + "at the top of a conversation. Enabling this makes it feel more like " <> \ + "a top-posted email quote chain.", + [ \ + checkbox(f, :messages_newest_first, class: "checkbox"), + label(f, :messages_newest_first, "Newest messages first"), + ] \ + ) .block__tab.hidden data-tab="notifications" - .field - => label f, :watch_on_reply, "Subscribe on Reply" - => checkbox f, :watch_on_reply, class: "checkbox" - .fieldlabel: i Subscribe on Reply means you'll be subscribed to things (images or topics) automatically as soon as you post a comment or reply, keeping you in the conversation. - .field - => label f, :watch_on_upload, "Subscribe on Upload" - => checkbox f, :watch_on_upload, class: "checkbox" - .fieldlabel: i Subscribe on Upload means you'll be subscribed to images automatically as soon as you upload, to help you keep track of comments. - .field - => label f, :watch_on_new_topic, "Subscribe on New Threads" - => checkbox f, :watch_on_new_topic, class: "checkbox" - .fieldlabel: i Subscribe on New Threads means you'll be subscribed to threads automatically as soon as you post, to help you keep track of replies. + = field_with_help( \ + "If enabled, you'll be subscribed to things (images or topics) " <> \ + "automatically as soon as you post a comment or reply, keeping " <> \ + "you in the conversation.", + [ \ + checkbox(f, :watch_on_reply, class: "checkbox"), \ + label(f, :watch_on_reply, "Subscribe on Reply"), \ + ] \ + ) + + = field_with_help( \ + "If enabled, you'll be subscribed to images automatically " <> \ + "as soon as you upload, to help you keep track of comments.", + [ \ + checkbox(f, :watch_on_upload, class: "checkbox"), \ + label(f, :watch_on_upload, "Subscribe on Upload"), \ + ] \ + ) + + = field_with_help( \ + "If enabled you'll be subscribed to threads automatically as soon " <> \ + "as you post, to help you keep track of replies.", + [ \ + checkbox(f, :watch_on_new_topic, class: "checkbox"), \ + label(f, :watch_on_new_topic, "Subscribe on New Threads"), \ + ] \ + ) .block__tab.hidden data-tab="metadata" .field - => label f, :fancy_tag_field_on_upload, "Fancy tags - uploads" => checkbox f, :fancy_tag_field_on_upload, class: "checkbox" - .field - => label f, :fancy_tag_field_on_edit, "Fancy tags - edits" - => checkbox f, :fancy_tag_field_on_edit, class: "checkbox" - .fieldlabel: i The fancy tag editor gives you autosuggestions and visual representations of the tags, but is sometimes not desired - for instance when dealing with batch uploads where you might want to copy-paste tags. You can choose which type of editor to use by default here. - .field - => label f, :anonymous_by_default - => checkbox f, :anonymous_by_default, class: "checkbox" - .fieldlabel: i Check this box to post images and comments as anonymous by default, even if logged in. + => label f, :fancy_tag_field_on_upload, "Fancy tags - uploads" + + = field_with_help( \ + "The fancy tag editor gives you autosuggestions and visual " <> \ + "representations of the tags, but is sometimes not desired - " <> \ + "for instance when dealing with batch uploads where you might " <> \ + "want to copy-paste tags. You can choose which type of editor " <> \ + "to use by default here.", + [ \ + checkbox(f, :fancy_tag_field_on_edit, class: "checkbox"), \ + label(f, :fancy_tag_field_on_edit, "Fancy tags - edits"), \ + ] \ + ) + + = field_with_help( \ + "Check this box to post images and comments as anonymous by default, " <> \ + "even if logged in.", + [ \ + checkbox(f, :anonymous_by_default, class: "checkbox"), \ + label(f, :anonymous_by_default), \ + ] \ + ) .block__tab class=local_tab_class(@conn) data-tab="local" .block.block--fixed.block--warning Settings on this tab are saved in the current browser. They are independent of your login. diff --git a/lib/philomena_web/views/setting_view.ex b/lib/philomena_web/views/setting_view.ex index a9a82a5d..928a6e80 100644 --- a/lib/philomena_web/views/setting_view.ex +++ b/lib/philomena_web/views/setting_view.ex @@ -52,7 +52,7 @@ defmodule PhilomenaWeb.SettingView do end, content_tag :div, class: "field-help-content hidden" do [ - title, + raw(text_to_html(title)), tag(:hr) ] end From b4f25790ed7a404b760e9ba36a331fd93550c17f Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Tue, 25 Mar 2025 00:55:57 +0000 Subject: [PATCH 5/7] Add remaining settings UI improvements to the local settings tab --- .../templates/setting/edit.html.slime | 126 ++++++++++++------ 1 file changed, 83 insertions(+), 43 deletions(-) diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index 7fecdd8b..d9c5e37e 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -206,58 +206,90 @@ h1 Content Settings .block__tab class=local_tab_class(@conn) data-tab="local" .block.block--fixed.block--warning Settings on this tab are saved in the current browser. They are independent of your login. + = field_with_help( \ + "Use high quality thumbnails on displays with a high pixel density. " <> \ + "Requires more data than regular thumbnails.", \ + [ \ + checkbox(f, :hidpi, checked: @conn.cookies["hidpi"] == "true"), \ + label(f, :hidpi, "Serve HiDPI thumbnails"), \ + ] \ + ) + + = field_with_help( \ + "Serve WebM/MP4 versions of GIF images when available. Good for " <> \ + "lower-bandwidth connections, but the video versions may have missing " <> \ + "start/end frames, and don't support transparency.", \ + [ \ + checkbox(f, :serve_webm, checked: @conn.cookies["serve_webm"] == "true"), \ + label(f, :serve_webm, "Serve WebM"), \ + ] \ + ) + + = field_with_help( \ + "Use video thumbnails for WebM videos. Does not apply to GIF images.", \ + [ \ + checkbox(f, :webm, checked: @conn.cookies["webm"] == "true"), \ + label(f, :webm, "Use video thumbnails"), \ + ] \ + ) + + = field_with_help( \ + "Automatically enable audio on video pages when they are loaded.", \ + [ \ + checkbox(f, :unmute_videos, checked: @conn.cookies["unmute_videos"] == "true"), \ + label(f, :unmute_videos, "Enable video audio by default"), \ + ] \ + ) + + = field_with_help( \ + "Hide the uploader and date posted information on image pages.", \ + [ \ + checkbox(f, :hide_uploader, checked: @conn.cookies["hide_uploader"] == "true"), \ + label(f, :hide_uploader), \ + ] \ + ) + + = field_with_help( \ + "Don't attempt to filter tag suggestions using your current filter.", \ + [ \ + checkbox(f, :unfilter_tag_suggestions, checked: @conn.cookies["unfilter_tag_suggestions"] == "true"), \ + label(f, :unfilter_tag_suggestions), \ + ] \ + ) + + = field_with_help( \ + "Hide score information for images.", \ + [ \ + checkbox(f, :hide_score, checked: @conn.cookies["hide_score"] == "true"), \ + label(f, :hide_score), \ + ] \ + ) + + = field_with_help( \ + "Show streams marked as NSFW on the channels page.", \ + [ \ + checkbox(f, :chan_nsfw, checked: @conn.cookies["chan_nsfw"] == "true"), \ + label(f, :chan_nsfw, "Show NSFW channels"), \ + ] \ + ) + .field - => label f, :hidpi, "Serve HiDPI thumbnails" - => checkbox f, :hidpi, checked: @conn.cookies["hidpi"] == "true" - .fieldlabel: i Use high quality thumbnails on displays with a high pixel density. Requires more data than regular thumbnails. - .field - => label f, :serve_webm, "Serve WebM" - => checkbox f, :serve_webm, checked: @conn.cookies["serve_webm"] == "true" - .fieldlabel: i Serve WebM/MP4 versions of GIF images when available. Good for lower-bandwidth connections, but the video versions may have missing start/end frames, and do not support transparency. - .field - => label f, :webm, "Use video thumbnails" - => checkbox f, :webm, checked: @conn.cookies["webm"] == "true" - .fieldlabel: i Use video thumbnails for WebM videos. Does not apply to GIF images. - .field - => label f, :unmute_videos, "Enable video audio by default" - => checkbox f, :unmute_videos, checked: @conn.cookies["unmute_videos"] == "true" - .fieldlabel: i Automatically enable audio on video pages when they are loaded. - .field - => label f, :hide_uploader - => checkbox f, :hide_uploader, checked: @conn.cookies["hide_uploader"] == "true" - .fieldlabel: i Hide the uploader and date posted information on image pages. - .field - => label f, :unfilter_tag_suggestions - => checkbox f, :unfilter_tag_suggestions, checked: @conn.cookies["unfilter_tag_suggestions"] == "true" - .fieldlabel: i Don't attempt to filter tag suggestions using your current filter. - .field - => label f, :hide_score - => checkbox f, :hide_score, checked: @conn.cookies["hide_score"] == "true" - .fieldlabel: i Hide score information for images. - .field - => label f, :chan_nsfw, "Show NSFW channels" - => checkbox f, :chan_nsfw, checked: @conn.cookies["chan_nsfw"] == "true" - .fieldlabel: i Show streams marked as NSFW on the channels page. - .field - => label f, :enable_search_ac, "Enable search auto-completion" => checkbox f, :enable_search_ac, checked: @conn.cookies["enable_search_ac"] == "true" + => label f, :enable_search_ac, "Enable search auto-completion" .autocomplete-settings class=if(@conn.cookies["enable_search_ac"] != "true", do: "hidden", else: "") .field - => label f, - :autocomplete_search_history_hidden, - "Hide search history in auto-completion" => checkbox f, :autocomplete_search_history_hidden, checked: @conn.cookies["autocomplete_search_history_hidden"] == "true" + => label f, + :autocomplete_search_history_hidden, + "Hide search history in auto-completion" .autocomplete-search-history-settings[ class=if(@conn.cookies["autocomplete_search_history_hidden"] == "true", do: "hidden", else: "") ] .field - => label f, - :autocomplete_search_history_max_suggestions_when_typing, - "Maximum number of search history suggestions in autocompletion when typing" => number_input f, :autocomplete_search_history_max_suggestions_when_typing, min: 0, @@ -265,12 +297,20 @@ h1 Content Settings step: 1, value: @conn.cookies["autocomplete_search_history_max_suggestions_when_typing"] || 3, class: "input" + => label f, + :autocomplete_search_history_max_suggestions_when_typing, + "Maximum number of search history suggestions in auto-completion when typing" = if staff?(@conn.assigns.current_user) do - .field - => label f, :hide_staff_tools - => checkbox f, :hide_staff_tools, checked: @conn.cookies["hide_staff_tools"] == "true" - .fieldlabel: i Hide most of the staff tools (e.g. IPs, anon names) making your site appear as if you weren't staff, this is useful when browsing in public. + = field_with_help( \ + "Hide most of the staff tools (e.g. IPs, anon names) making your site " <> \ + "appear as if you weren't staff, this is useful when browsing in public.", + [ \ + checkbox(f, :hide_staff_tools, checked: @conn.cookies["hide_staff_tools"] == "true"), + label(f, :hide_staff_tools), + ] \ + ) + = if !@conn.assigns.current_user do .block__tab.hidden data-tab="join-the-herd" From 55989c978babc5bd74847b91b2dba2f06d21e89c Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Tue, 25 Mar 2025 02:34:07 +0000 Subject: [PATCH 6/7] Add checkbox class to local settings --- .../templates/setting/edit.html.slime | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index d9c5e37e..145cecb5 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -210,7 +210,7 @@ h1 Content Settings "Use high quality thumbnails on displays with a high pixel density. " <> \ "Requires more data than regular thumbnails.", \ [ \ - checkbox(f, :hidpi, checked: @conn.cookies["hidpi"] == "true"), \ + checkbox(f, :hidpi, checked: @conn.cookies["hidpi"] == "true", class: "checkbox"), \ label(f, :hidpi, "Serve HiDPI thumbnails"), \ ] \ ) @@ -220,7 +220,7 @@ h1 Content Settings "lower-bandwidth connections, but the video versions may have missing " <> \ "start/end frames, and don't support transparency.", \ [ \ - checkbox(f, :serve_webm, checked: @conn.cookies["serve_webm"] == "true"), \ + checkbox(f, :serve_webm, checked: @conn.cookies["serve_webm"] == "true", class: "checkbox"), \ label(f, :serve_webm, "Serve WebM"), \ ] \ ) @@ -228,7 +228,7 @@ h1 Content Settings = field_with_help( \ "Use video thumbnails for WebM videos. Does not apply to GIF images.", \ [ \ - checkbox(f, :webm, checked: @conn.cookies["webm"] == "true"), \ + checkbox(f, :webm, checked: @conn.cookies["webm"] == "true", class: "checkbox"), \ label(f, :webm, "Use video thumbnails"), \ ] \ ) @@ -236,7 +236,7 @@ h1 Content Settings = field_with_help( \ "Automatically enable audio on video pages when they are loaded.", \ [ \ - checkbox(f, :unmute_videos, checked: @conn.cookies["unmute_videos"] == "true"), \ + checkbox(f, :unmute_videos, checked: @conn.cookies["unmute_videos"] == "true", class: "checkbox"), \ label(f, :unmute_videos, "Enable video audio by default"), \ ] \ ) @@ -244,7 +244,7 @@ h1 Content Settings = field_with_help( \ "Hide the uploader and date posted information on image pages.", \ [ \ - checkbox(f, :hide_uploader, checked: @conn.cookies["hide_uploader"] == "true"), \ + checkbox(f, :hide_uploader, checked: @conn.cookies["hide_uploader"] == "true", class: "checkbox"), \ label(f, :hide_uploader), \ ] \ ) @@ -252,7 +252,7 @@ h1 Content Settings = field_with_help( \ "Don't attempt to filter tag suggestions using your current filter.", \ [ \ - checkbox(f, :unfilter_tag_suggestions, checked: @conn.cookies["unfilter_tag_suggestions"] == "true"), \ + checkbox(f, :unfilter_tag_suggestions, checked: @conn.cookies["unfilter_tag_suggestions"] == "true", class: "checkbox"), \ label(f, :unfilter_tag_suggestions), \ ] \ ) @@ -260,7 +260,7 @@ h1 Content Settings = field_with_help( \ "Hide score information for images.", \ [ \ - checkbox(f, :hide_score, checked: @conn.cookies["hide_score"] == "true"), \ + checkbox(f, :hide_score, checked: @conn.cookies["hide_score"] == "true", class: "checkbox"), \ label(f, :hide_score), \ ] \ ) @@ -268,20 +268,21 @@ h1 Content Settings = field_with_help( \ "Show streams marked as NSFW on the channels page.", \ [ \ - checkbox(f, :chan_nsfw, checked: @conn.cookies["chan_nsfw"] == "true"), \ + checkbox(f, :chan_nsfw, checked: @conn.cookies["chan_nsfw"] == "true", class: "checkbox"), \ label(f, :chan_nsfw, "Show NSFW channels"), \ ] \ ) .field - => checkbox f, :enable_search_ac, checked: @conn.cookies["enable_search_ac"] == "true" + => checkbox f, :enable_search_ac, checked: @conn.cookies["enable_search_ac"] == "true", class: "checkbox" => label f, :enable_search_ac, "Enable search auto-completion" .autocomplete-settings class=if(@conn.cookies["enable_search_ac"] != "true", do: "hidden", else: "") .field => checkbox f, :autocomplete_search_history_hidden, - checked: @conn.cookies["autocomplete_search_history_hidden"] == "true" + checked: @conn.cookies["autocomplete_search_history_hidden"] == "true", + class: "checkbox" => label f, :autocomplete_search_history_hidden, "Hide search history in auto-completion" @@ -306,7 +307,7 @@ h1 Content Settings "Hide most of the staff tools (e.g. IPs, anon names) making your site " <> \ "appear as if you weren't staff, this is useful when browsing in public.", [ \ - checkbox(f, :hide_staff_tools, checked: @conn.cookies["hide_staff_tools"] == "true"), + checkbox(f, :hide_staff_tools, checked: @conn.cookies["hide_staff_tools"] == "true", class: "checkbox"), label(f, :hide_staff_tools), ] \ ) From 14a19882f7390056ea22e66928ef0794fa72ea49 Mon Sep 17 00:00:00 2001 From: MareStare <mare.stare.official@gmail.com> Date: Thu, 27 Mar 2025 01:15:27 +0000 Subject: [PATCH 7/7] Ignore an XSS warning --- lib/philomena_web/views/setting_view.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/philomena_web/views/setting_view.ex b/lib/philomena_web/views/setting_view.ex index 928a6e80..13f0398e 100644 --- a/lib/philomena_web/views/setting_view.ex +++ b/lib/philomena_web/views/setting_view.ex @@ -52,6 +52,8 @@ defmodule PhilomenaWeb.SettingView do end, content_tag :div, class: "field-help-content hidden" do [ + # The `title` is static and doesn't include dynamic user input. + # sobelow_skip ["XSS.Raw"] raw(text_to_html(title)), tag(:hr) ]