From e91971cf54b005f85b780d78a04259c8e26933da Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Wed, 13 Dec 2023 12:22:36 +0700 Subject: [PATCH] using blurhash for obscuring sensitive image (#342) replaced blur filter usage over sensitive image to obscure the image with blurhash image, using hidden checkbox + css to control visibility and buttons to switch between show and hide sensitive image for image attachment in post and comments, hide the sensitive image by putting blurhash image over along with the show button for entry thumbnail, it works a bit differently: - the sensitive image is hidden by hiding the main image and show existing blurhash background image instead - due to space constraints, the show/hide button is icons only, additionally when in mobile layout and compact view, the hide button will not be shown after the image is revealed --- assets/styles/app.scss | 1 + assets/styles/components/_comment.scss | 6 +- assets/styles/components/_entry.scss | 8 ++ assets/styles/components/_figure_image.scss | 128 ++++++++++++++++++ assets/styles/components/_post.scss | 13 +- .../Components/BlurhashImageComponent.php | 4 +- templates/components/_figure_entry.html.twig | 46 +++++++ templates/components/_figure_image.html.twig | 37 +++++ templates/components/entry.html.twig | 38 ++---- templates/components/entry_comment.html.twig | 14 +- templates/components/post.html.twig | 13 +- templates/components/post_comment.html.twig | 14 +- translations/messages.en.yaml | 4 + 13 files changed, 255 insertions(+), 71 deletions(-) create mode 100644 assets/styles/components/_figure_image.scss create mode 100644 templates/components/_figure_entry.html.twig create mode 100644 templates/components/_figure_image.html.twig diff --git a/assets/styles/app.scss b/assets/styles/app.scss index 2a1433331..35a6389ad 100644 --- a/assets/styles/app.scss +++ b/assets/styles/app.scss @@ -29,6 +29,7 @@ @import 'components/vote'; @import 'components/entry'; @import 'components/comment'; +@import 'components/figure_image'; @import 'components/post'; @import 'components/subject'; @import 'components/login'; diff --git a/assets/styles/components/_comment.scss b/assets/styles/components/_comment.scss index b15e80478..e586bb469 100644 --- a/assets/styles/components/_comment.scss +++ b/assets/styles/components/_comment.scss @@ -165,12 +165,8 @@ $comment-margin-sm: .3rem; } figure { - margin: 0; - } - - figure img { + display: block; margin: .5rem 0; - max-width: 100%; } } diff --git a/assets/styles/components/_entry.scss b/assets/styles/components/_entry.scss index cc8f9c937..9f0f6e2d7 100644 --- a/assets/styles/components/_entry.scss +++ b/assets/styles/components/_entry.scss @@ -171,6 +171,10 @@ border-bottom-left-radius: 0 !important; } + .sensitive-button-label { + line-height: 1rem; + } + @include media-breakpoint-down(lg) { width: 140px; height: calc(140px / 1.5); // 3:2 ratio @@ -185,6 +189,10 @@ margin: 0 10px 10px 10px; height: calc(100% - 10px); width: calc(100% - 10px); + + .sensitive-button-hide { + display: none; + } } .rounded-edges & { diff --git a/assets/styles/components/_figure_image.scss b/assets/styles/components/_figure_image.scss new file mode 100644 index 000000000..48b27c9b0 --- /dev/null +++ b/assets/styles/components/_figure_image.scss @@ -0,0 +1,128 @@ +// main wrapper +.figure-container { + position: relative; + width: fit-content; + height: fit-content; +} + +// main image thumbnail +.figure-thumb { + .thumb { + display: block; + } + + img { + display: block; + width: 100%; + height: 100%; + } +} + +// blurhash image obscuring main image +.figure-blur { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + + img { + width: 100%; + height: 100%; + overflow: hidden; + object-fit: cover; + } +} + +// checkbox to store sensitive state +input.sensitive-state { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + opacity: 0; +} + +// button to toggle sensitive +.sensitive-button { + position: absolute; + + &-label { + background: var(--kbin-button-secondary-bg); + padding: .5rem; + + font-weight: normal; + font-size: .8rem; + text-align: center; + + opacity: .8; + + i { + font-size: 1rem; + } + + .rounded-edges & { + border-radius: var(--kbin-rounded-edges-radius); + } + + &:hover, + &:active { + opacity: 1; + } + } + + &-show { + top: 0; + left: 0; + width: 100%; + height: 100%; + + .sensitive-button-label { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + } + } + + &-hide { + top: .5rem; + right: .5rem; + + .sensitive-button-label { + opacity: .5; + line-height: 1rem; + + i { + font-size: .9rem; + } + + &:hover, + &:active { + opacity: .7; + } + } + } +} + +// the magic part: toggle visibility depending on sensitive state +.sensitive-state { + ~ .sensitive-checked--hide { + display: initial; + } + + ~ .sensitive-checked--show { + display: none; + } +} + +.sensitive-state:checked { + ~ .sensitive-checked--hide { + display: none; + } + + ~ .sensitive-checked--show { + display: revert; + } +} diff --git a/assets/styles/components/_post.scss b/assets/styles/components/_post.scss index 70c872beb..fc68e770b 100644 --- a/assets/styles/components/_post.scss +++ b/assets/styles/components/_post.scss @@ -84,7 +84,7 @@ } } - figure { + > figure { grid-area: avatar; margin: 0; display: none; @@ -152,16 +152,7 @@ figure { display: block; - - img { - margin: .5rem 0; - max-width: 600px; - max-height: 400px; - - @include media-breakpoint-down(sm) { - max-width: 100%; - } - } + margin: .5rem 0; } button { diff --git a/src/Twig/Components/BlurhashImageComponent.php b/src/Twig/Components/BlurhashImageComponent.php index 0316d7a74..cfd8417d0 100644 --- a/src/Twig/Components/BlurhashImageComponent.php +++ b/src/Twig/Components/BlurhashImageComponent.php @@ -22,8 +22,10 @@ public function __construct(private CacheInterface $cache) public function createImage(string $blurhash, int $width = 20, int $height = 20): string { + $context = [$blurhash, $width, $height]; + return $this->cache->get( - 'bh_'.hash('sha256', $blurhash), + 'bh_'.hash('sha256', serialize($context)), function (ItemInterface $item) use ($blurhash, $width, $height) { $item->expiresAfter(3600); diff --git a/templates/components/_figure_entry.html.twig b/templates/components/_figure_entry.html.twig new file mode 100644 index 000000000..6a5757873 --- /dev/null +++ b/templates/components/_figure_entry.html.twig @@ -0,0 +1,46 @@ +{# this fragment is only meant to be used in entry component #} +{% with { + sensitiveId: 'sensitive-check-'~entry.image.id, + isSingle: is_route_name('entry_single'), + route: isSingle ? singleRoute : entry_url(entry) +} %} +
+ + {% if entry.isAdult %} + + {% endif %} + + {{ entry.image.altText }} + + {% if entry.isAdult %} + + + {% endif %} +
+{% endwith %} diff --git a/templates/components/_figure_image.html.twig b/templates/components/_figure_image.html.twig new file mode 100644 index 000000000..90036e094 --- /dev/null +++ b/templates/components/_figure_image.html.twig @@ -0,0 +1,37 @@ +
+
+
+ + {{ image.altText }} + +
+ {% if isAdult %} + {% with {sensitiveId: 'sensitive-check-'~image.id} %} + + + + {% endwith %} + {% endif %} +
+
diff --git a/templates/components/entry.html.twig b/templates/components/entry.html.twig index 0002ec61a..40c22bfda 100644 --- a/templates/components/entry.html.twig +++ b/templates/components/entry.html.twig @@ -88,35 +88,17 @@ {% if SHOW_THUMBNAILS is same as V_TRUE %} {% if entry.image %} {% if entry.type is same as 'link' or entry.type is same as 'video' %} -
- - - {{ entry.image.altText }} - -
+ {{ include('components/_figure_entry.html.twig', { + entry: entry, + singleRoute: entry.url, + setRel: true + }) }} {% elseif entry.type is same as 'image' or entry.type is same as 'article' %} -
- - - {{ entry.image.altText }} - -
+ {{ include('components/_figure_entry.html.twig', { + entry: entry, + singleRoute: uploaded_asset(entry.image.filePath), + lightbox: true + }) }} {% endif %} {% else %}
diff --git a/templates/components/entry_comment.html.twig b/templates/components/entry_comment.html.twig index 3c1fb5041..a3cd49298 100644 --- a/templates/components/entry_comment.html.twig +++ b/templates/components/entry_comment.html.twig @@ -77,15 +77,11 @@ {% endif %}