From ce723776a5d9f35146ed759d3f44bdd0abe787c7 Mon Sep 17 00:00:00 2001 From: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:25:42 -0400 Subject: [PATCH] Make blur work correctly --- package.json | 2 + pnpm-lock.yaml | 28 +++++++++++ src/assets/css/main.css | 8 +++ src/client/index.tsx | 2 +- src/server/handlers/catch-all-handler.tsx | 6 ++- src/server/index.tsx | 2 + src/server/utils/create-ssr-html.tsx | 22 +-------- src/shared/components/app/app.tsx | 49 +++++++++---------- .../components/common/adult-consent-modal.tsx | 41 ++++------------ src/shared/components/common/pictrs-image.tsx | 11 ++--- src/shared/config.ts | 2 +- src/shared/interfaces.ts | 1 + src/shared/utils/helpers/index.ts | 2 - src/shared/utils/helpers/should-blur-nsfw.ts | 13 ----- 14 files changed, 86 insertions(+), 103 deletions(-) delete mode 100644 src/shared/utils/helpers/should-blur-nsfw.ts diff --git a/package.json b/package.json index 4c36ed40..f1d3c2bf 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "classnames": "^2.5.1", "clean-webpack-plugin": "^4.0.0", "cookie": "^0.6.0", + "cookie-parser": "^1.4.6", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.10.0", "date-fns": "^3.6.0", @@ -94,6 +95,7 @@ "@types/autosize": "^4.0.3", "@types/bootstrap": "^5.2.10", "@types/cookie": "^0.6.0", + "@types/cookie-parser": "^1.4.7", "@types/express": "^4.17.21", "@types/html-to-text": "^9.0.4", "@types/lodash.isequal": "^4.5.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ad393bd..98b53136 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: cookie: specifier: ^0.6.0 version: 0.6.0 + cookie-parser: + specifier: ^1.4.6 + version: 1.4.6 copy-webpack-plugin: specifier: ^12.0.2 version: 12.0.2(webpack@5.91.0(webpack-cli@5.1.4)) @@ -210,6 +213,9 @@ importers: '@types/cookie': specifier: ^0.6.0 version: 0.6.0 + '@types/cookie-parser': + specifier: ^1.4.7 + version: 1.4.7 '@types/express': specifier: ^4.17.21 version: 4.17.21 @@ -1207,6 +1213,9 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/cookie-parser@1.4.7': + resolution: {integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==} + '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} @@ -1856,9 +1865,17 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-parser@1.4.6: + resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} + engines: {node: '>= 0.8.0'} + cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie@0.4.1: + resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} + engines: {node: '>= 0.6'} + cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} @@ -5742,6 +5759,10 @@ snapshots: dependencies: '@types/node': 20.11.30 + '@types/cookie-parser@1.4.7': + dependencies: + '@types/express': 4.17.21 + '@types/cookie@0.6.0': {} '@types/eslint-scope@3.7.7': @@ -6479,8 +6500,15 @@ snapshots: convert-source-map@2.0.0: {} + cookie-parser@1.4.6: + dependencies: + cookie: 0.4.1 + cookie-signature: 1.0.6 + cookie-signature@1.0.6: {} + cookie@0.4.1: {} + cookie@0.6.0: {} copy-webpack-plugin@11.0.0(webpack@5.91.0(webpack-cli@5.1.4)): diff --git a/src/assets/css/main.css b/src/assets/css/main.css index a7d7e706..93064d0a 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -461,3 +461,11 @@ br.big { .totp-link { width: fit-content; } + +#app[data-adult-consent] { + filter: blur(10px); + -webkit-filter: blur(10px); + -moz-filter: blur(10px); + -o-filter: blur(10px); + -ms-filter: blur(10px); +} diff --git a/src/client/index.tsx b/src/client/index.tsx index db0a9ef7..27031189 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -1,7 +1,7 @@ import { initializeSite } from "@utils/app"; import { hydrate } from "inferno-hydrate"; import { BrowserRouter } from "inferno-router"; -import { App } from "../shared/components/app/app"; +import App from "../shared/components/app/app"; import { lazyHighlightjs } from "../shared/lazy-highlightjs"; import { loadUserLanguage } from "../shared/services/I18NextService"; import { verifyDynamicImports } from "../shared/dynamic-imports"; diff --git a/src/server/handlers/catch-all-handler.tsx b/src/server/handlers/catch-all-handler.tsx index 33d4d7a6..88b06bdf 100644 --- a/src/server/handlers/catch-all-handler.tsx +++ b/src/server/handlers/catch-all-handler.tsx @@ -6,7 +6,7 @@ import { StaticRouter, matchPath } from "inferno-router"; import { Match } from "inferno-router/dist/Route"; import { renderToString } from "inferno-server"; import { GetSiteResponse, LemmyHttp } from "lemmy-js-client"; -import { App } from "../../shared/components/app/app"; +import App from "../../shared/components/app/app"; import { InitialFetchRequest, IsoDataOptionalSite, @@ -28,6 +28,7 @@ import { } from "../../shared/services/"; import { parsePath } from "history"; import { getQueryString } from "@utils/helpers"; +import { adultConsentCookieKey } from "../../shared/config"; export default async (req: Request, res: Response) => { try { @@ -142,6 +143,9 @@ export default async (req: Request, res: Response) => { site_res: site, routeData, errorPageData, + showAdultConsentModal: + !!site?.site_view.site.content_warning && + !(site.my_user || req.cookies[adultConsentCookieKey]), }; const wrapper = ( diff --git a/src/server/index.tsx b/src/server/index.tsx index 34fc9ccc..cbbd027b 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -14,8 +14,10 @@ import ThemesListHandler from "./handlers/themes-list-handler"; import { setCacheControl, setDefaultCsp } from "./middleware"; import CodeThemeHandler from "./handlers/code-theme-handler"; import { verifyDynamicImports } from "../shared/dynamic-imports"; +import cookieParser from "cookie-parser"; const server = express(); +server.use(cookieParser()); const [hostname, port] = process.env["LEMMY_UI_HOST"] ? process.env["LEMMY_UI_HOST"].split(":") diff --git a/src/server/utils/create-ssr-html.tsx b/src/server/utils/create-ssr-html.tsx index 688b65aa..f6f9ec58 100644 --- a/src/server/utils/create-ssr-html.tsx +++ b/src/server/utils/create-ssr-html.tsx @@ -75,37 +75,19 @@ export async function createSsrHtml( .map(x => ``) .join(""); - // Blurring has to happen even if all style sheets fail to load. - const blurStyles = !site?.site_view.site.content_warning - ? "" - : ` - `; - return ` - ${blurStyles} ${lazyScripts} - ${erudaStr} diff --git a/src/shared/components/app/app.tsx b/src/shared/components/app/app.tsx index a9c8b793..0c08cee0 100644 --- a/src/shared/components/app/app.tsx +++ b/src/shared/components/app/app.tsx @@ -13,39 +13,39 @@ import { Navbar } from "./navbar"; import "./styles.scss"; import { Theme } from "./theme"; import AnonymousGuard from "../common/anonymous-guard"; -import { destroyTippy, setupTippy } from "../../tippy"; import AdultConsentModal from "../common/adult-consent-modal"; -export class App extends Component { +function handleJumpToContent(event) { + event.preventDefault(); +} + +export default class App extends Component { private isoData: IsoDataOptionalSite = setIsoData(this.context); - private readonly mainContentRef = createRef(); private readonly rootRef = createRef(); - componentDidMount(): void { - setupTippy(this.rootRef); - } - - componentWillUnmount(): void { - destroyTippy(); - } - - handleJumpToContent(event) { - event.preventDefault(); - this.mainContentRef.current?.focus(); - } - render() { const siteRes = this.isoData.site_res; const siteView = siteRes?.site_view; return ( - <> - -
+ + {/* This fragment is required to avoid an SSR error*/} + <> + {this.isoData.showAdultConsentModal && ( + + )} +
@@ -53,11 +53,6 @@ export class App extends Component { )} - {siteRes?.site_view.site.content_warning && ( - - )}
{routes.map( @@ -117,8 +112,8 @@ export class App extends Component {
-
- + + ); } } diff --git a/src/shared/components/common/adult-consent-modal.tsx b/src/shared/components/common/adult-consent-modal.tsx index 38ed259c..27c8c05a 100644 --- a/src/shared/components/common/adult-consent-modal.tsx +++ b/src/shared/components/common/adult-consent-modal.tsx @@ -1,12 +1,11 @@ import { Component, LinkedEvent, createRef, linkEvent } from "inferno"; import { modalMixin } from "../mixins/modal-mixin"; -import { adultConsentLocalStorageKey } from "../../config"; -import { setIsoData } from "@utils/app"; -import { IsoDataOptionalSite } from "../../interfaces"; +import { adultConsentCookieKey } from "../../config"; import { mdToHtml } from "../../markdown"; import { I18NextService } from "../../services"; -import { isBrowser } from "@utils/browser"; -import { Helmet } from "inferno-helmet"; +import { isHttps } from "@utils/env"; +import { IsoData } from "../../interfaces"; +import { setIsoData } from "@utils/app"; interface AdultConsentModalProps { contentWarning: string; @@ -35,13 +34,6 @@ class AdultConsentModalInner extends Component { data-bs-backdrop="static" ref={this.modalDivRef} > -
, AdultConsentModalState > { - private isoData: IsoDataOptionalSite = setIsoData(this.context); + private isoData: IsoData = setIsoData(this.context); redirectTimeout: NodeJS.Timeout; state: AdultConsentModalState = { - show: false, + show: this.isoData.showAdultConsentModal, redirectCountdown: Infinity, }; - componentWillMount() { - const siteRes = this.isoData.site_res; - - if (siteRes?.site_view.site.content_warning) { - if (isBrowser()) { - if (localStorage.getItem(adultConsentLocalStorageKey) !== "true") { - this.setState({ show: true }); - } else { - this.setState({ show: false }); - } - } else { - this.setState({ show: true }); - } - } - } - componentDidUpdate() { if (this.state.redirectCountdown === 0) { this.context.router.history.back(); diff --git a/src/shared/components/common/pictrs-image.tsx b/src/shared/components/common/pictrs-image.tsx index 5fb82b5b..1983a85d 100644 --- a/src/shared/components/common/pictrs-image.tsx +++ b/src/shared/components/common/pictrs-image.tsx @@ -1,9 +1,7 @@ import classNames from "classnames"; import { Component } from "inferno"; -import { setIsoData } from "@utils/app"; -import { IsoDataOptionalSite } from "shared/interfaces"; -import { shouldBlurNsfw } from "@utils/helpers"; +import { UserService } from "../../services"; const iconThumbnailSize = 96; const thumbnailSize = 256; @@ -21,8 +19,6 @@ interface PictrsImageProps { } export class PictrsImage extends Component { - private isoData: IsoDataOptionalSite = setIsoData(this.context); - constructor(props: any, context: any) { super(props, context); } @@ -31,7 +27,10 @@ export class PictrsImage extends Component { const { src, icon, iconOverlay, banner, thumbnail, nsfw, pushup, cardTop } = this.props; - const blurImage = nsfw && shouldBlurNsfw(this.isoData.site_res); + const blurImage = + nsfw && + (UserService.Instance.myUserInfo?.local_user_view.local_user.blur_nsfw ?? + true); return ( diff --git a/src/shared/config.ts b/src/shared/config.ts index fc659dcc..37800dd6 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -28,7 +28,7 @@ export const fetchLimit = 20; export const relTags = "noopener nofollow"; export const emDash = "\u2014"; export const authCookieName = "jwt"; -export const adultConsentLocalStorageKey = "adult-consent"; +export const adultConsentCookieKey = "adultConsent"; // No. of max displayed communities per // page on route "/communities" diff --git a/src/shared/interfaces.ts b/src/shared/interfaces.ts index 15c19513..555b3cfe 100644 --- a/src/shared/interfaces.ts +++ b/src/shared/interfaces.ts @@ -16,6 +16,7 @@ export interface IsoData { routeData: T; site_res: GetSiteResponse; errorPageData?: ErrorPageData; + showAdultConsentModal: boolean; } export type IsoDataOptionalSite = Partial< diff --git a/src/shared/utils/helpers/index.ts b/src/shared/utils/helpers/index.ts index 5fcc1e1c..58eec8cc 100644 --- a/src/shared/utils/helpers/index.ts +++ b/src/shared/utils/helpers/index.ts @@ -25,7 +25,6 @@ import validTitle from "./valid-title"; import validURL from "./valid-url"; import dedupByProperty from "./dedup-by-property"; import getApubName from "./apub-name"; -import shouldBlurNsfw from "./should-blur-nsfw"; export { capitalizeFirstLetter, @@ -55,5 +54,4 @@ export { validURL, dedupByProperty, getApubName, - shouldBlurNsfw, }; diff --git a/src/shared/utils/helpers/should-blur-nsfw.ts b/src/shared/utils/helpers/should-blur-nsfw.ts deleted file mode 100644 index 2f52f526..00000000 --- a/src/shared/utils/helpers/should-blur-nsfw.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SiteResponse } from "lemmy-js-client"; -import { adultConsentLocalStorageKey } from "../../config"; -import { UserService } from "../../services"; -import { isBrowser } from "@utils/browser"; - -export default function shouldBlurNsfw(siteRes?: SiteResponse) { - return siteRes?.site_view.site.content_warning - ? !( - (isBrowser() && localStorage.getItem(adultConsentLocalStorageKey)) || - UserService.Instance.myUserInfo - ) - : UserService.Instance.myUserInfo?.local_user_view.local_user.blur_nsfw; -}