From f131c58d1ba4b0ae4e213a819ed6178daa89ee9e Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Wed, 13 Jul 2022 12:03:09 -0700 Subject: [PATCH] Add post hiding This allows users to hide posts that they may find unsavory. On threads themselves in the board view, this adds a minus/plus button that will toggle back and forth if hidden. This also adds a post menu item that will toggle a post being hidden. This also changes the post snippet layout a little bit. This caused minor issues with the other menu items, but it should be fixed in this set of changes too. Signed-off-by: Alek Ratzloff --- board/static/board/post.js | 93 +++++++++++++++++++- board/static/board/style.css | 14 ++- board/templates/board/board_detail.html | 4 +- board/templates/board/post_detail.html | 2 +- board/templates/board/post_snippet.html | 110 +++++++++++++----------- 5 files changed, 167 insertions(+), 56 deletions(-) diff --git a/board/static/board/post.js b/board/static/board/post.js index 0468346..59922bd 100644 --- a/board/static/board/post.js +++ b/board/static/board/post.js @@ -65,7 +65,8 @@ function openMenu(e) { .append($("Actions").addClass("post_menu_item")) .addClass("post_menu_items"); window.menuItemFactories.forEach(factory => { - item = factory(sender.parentElement); + let postElement = $(sender).closest(".post"); + item = factory(postElement[0]); menuList.append( $("
  • ") .addClass("post_menu_item") @@ -204,6 +205,52 @@ function openReportWindow(reportUrl) { reportWindow.show(); } +//////////////////////////////////////////////////////////////////////////////// +// Post hiding +//////////////////////////////////////////////////////////////////////////////// + +function getHiddenPosts() { + let hiddenPosts = JSON.parse(localStorage.getItem("hidden_posts")); + if (hiddenPosts === null) { + return []; + } else { + return hiddenPosts; + } +} + +function addHiddenPost(postId) { + let hiddenPosts = getHiddenPosts(); + if (!hiddenPosts.includes(postId)) { + hiddenPosts.push(postId); + } + localStorage.setItem("hidden_posts", JSON.stringify(hiddenPosts)); +} + +function removeHiddenPost(postId) { + let hiddenPosts = getHiddenPosts().filter((item) => item !== postId); + localStorage.setItem("hidden_posts", JSON.stringify(hiddenPosts)); +} + +function hidePost(postId) { + $(postId + " > .reply").addClass("post_hidden"); + $(postId + " > .post_content").addClass("post_hidden"); + $(postId + " >>> .thread_hide_button") + .addClass("fa-plus-square") + .addClass("thread_show_button") + .removeClass("fa-minus-square") + .removeClass("thread_hide_button"); +} + +function unhidePost(postId) { + $(postId + " > .reply").removeClass("post_hidden"); + $(postId + " > .post_content").removeClass("post_hidden"); + $(postId + " >>> .thread_show_button") + .removeClass("fa-plus-square") + .removeClass("thread_show_button") + .addClass("fa-minus-square") + .addClass("thread_hide_button"); +} + //////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////// @@ -215,7 +262,8 @@ $(window.top).on("load", () => { window.top.jsFrame = new JSFrame(); } }); -$(window).on("load", (e) => { +// This on("load") sets up more events +$(window).on("load", () => { $(".post_image").on("mouseover", (e) => { // Load the original image and display it let thumbnail = e.target; @@ -267,6 +315,29 @@ $(window).on("load", (e) => { }); }); +// Load event that actually does stuff +$(window).on("load", () => { + getHiddenPosts().forEach(item => hidePost(item)); +}); + +// $(document).on("click", ...) is used for dynamic event dispatch. +// Since these elements are going to have their classes changed, doing a typical +// $(".class").on(...) method won't fire on elements that don't have the +// expected class name when the hook is created. +// Don't change this. +$(document).on("click", ".thread_hide_button", (e) => { + e.preventDefault(); + let id = "#" + $(e.target).closest(".post").attr("id"); + hidePost(id); + addHiddenPost(id); +}); +$(document).on("click", ".thread_show_button", (e) => { + e.preventDefault(); + let id = "#" + $(e.target).closest(".post").attr("id"); + unhidePost(id); + removeHiddenPost(id); +}); + window.menuItemFactories = []; window.menuItemFactories.push( (postElement) => @@ -277,4 +348,22 @@ window.menuItemFactories.push( e.preventDefault(); openReportWindow($(postElement).attr("data-report-url")); }) +); +window.menuItemFactories.push( + (postElement) => + $("") + .text("Toggle hide") + .attr("href", "#") + .on("click", (e) => { + e.preventDefault(); + let id = "#" + $(postElement).attr("id"); + let hiddenPosts = getHiddenPosts(); + if (hiddenPosts.includes(id)) { + unhidePost(id); + removeHiddenPost(id); + } else { + hidePost(id); + addHiddenPost(id); + } + }) ); \ No newline at end of file diff --git a/board/static/board/style.css b/board/static/board/style.css index 959e4a8..512f723 100644 --- a/board/static/board/style.css +++ b/board/static/board/style.css @@ -112,7 +112,7 @@ th { float: right; } -.post { +.thread { background-color: var(--post-background); padding: 10px; } @@ -140,6 +140,18 @@ th { text-decoration: line-through; } +.thread_hide_button { + cursor: pointer; +} + +.thread_show_button { + cursor: pointer; +} + +.post_hidden { + display: none; +} + #image_hover { position: fixed; top: 0px; diff --git a/board/templates/board/board_detail.html b/board/templates/board/board_detail.html index c98e58f..6784b6b 100644 --- a/board/templates/board/board_detail.html +++ b/board/templates/board/board_detail.html @@ -31,9 +31,9 @@
    {# posts #} {% for post in threads %} -
    +
    {# TODO we need some way to parameterize the last N threads #} - {% with reply_link=True replies_elided=post.replies.all|length|add:"-3" %} + {% with reply_link=True thread_hide_button=True replies_elided=post.replies.all|length|add:"-3" %} {% include "board/post_snippet.html" %} {% endwith %} diff --git a/board/templates/board/post_detail.html b/board/templates/board/post_detail.html index 68b5f69..6fcf381 100644 --- a/board/templates/board/post_detail.html +++ b/board/templates/board/post_detail.html @@ -40,7 +40,7 @@
    {# posts #} -
    +
    {% include "board/post_snippet.html" %} {% for post in post.replies.all %}
    diff --git a/board/templates/board/post_snippet.html b/board/templates/board/post_snippet.html index c60a9b2..7628263 100644 --- a/board/templates/board/post_snippet.html +++ b/board/templates/board/post_snippet.html @@ -2,6 +2,7 @@ {% load i18n %}
    -{# Post ID, status icons, username, time #} -{% if post.sticky and not post.op %} - -{% endif %} -{% if post.lock and not post.op %} - -{% endif %} -#. -{{post.id}} -{% if post.subject %} - {{post.subject}} -{% endif %} -{% blocktranslate with post_name=post.name|default:"Anonymous" %} -by -{{post_name}} -{% endblocktranslate %} -{% if post.capcode %} -{{post.capcode}} -{% endif %} -{% blocktranslate with post_created=post.created %} -at {{post_created}} -{% endblocktranslate %} -{% if reply_link %} - [{% translate "Reply" %}] -{% endif %} - +
    + {# Hide post button #} + {% if thread_hide_button %} + + {% endif %} -{# Image #} -{% if post.thumbnail %} -{# Image info #} -
    - {% translate "File" %} - {{post.original_image_name}} - ({{post.image.size|measure_bytes}}, {{post.image_width}}x{{post.image_height}}) + {# Post ID, status icons, username, time #} + #. + {{post.id}} + {% if post.subject %} + {{post.subject}} + {% endif %} + {% blocktranslate with post_name=post.name|default:"Anonymous" %} + by + {{post_name}} + {% endblocktranslate %} + {% if post.capcode %} + {{post.capcode}} + {% endif %} + {% blocktranslate with post_created=post.created %} + at {{post_created}} + {% endblocktranslate %} + + {% if post.sticky and not post.op %} + + {% endif %} + {% if post.lock and not post.op %} + + {% endif %} + + {% if reply_link %} + [{% translate "Reply" %}] + {% endif %} +
    -{# Image thumbnail #} -
    - - - -
    -{% endif %} - -{# "X replies elided" dialog for OPs on the board #}
    -{% if replies_elided > 0 %} -
    - - ({% blocktranslate %}{{replies_elided}} replies elided, click reply to view{% endblocktranslate %}) - -{% endif %} + {# Image #} + {% if post.thumbnail %} + {# Image info #} +
    + {% translate "File" %} + {{post.original_image_name}} + ({{post.image.size|measure_bytes}}, {{post.image_width}}x{{post.image_height}}) +
    -{# Post body #} -

    {{post|post_body|safe}}

    + {# Image thumbnail #} +
    + + + +
    + {% endif %} + + {# "X replies elided" dialog for OPs on the board #} + {% if replies_elided > 0 %} +
    + + ({% blocktranslate %}{{replies_elided}} replies elided, click reply to view{% endblocktranslate %}) + + {% endif %} + + {# Post body #} +

    {{post|post_body|safe}}

    \ No newline at end of file