From f25d54918287063d6bfa71b150a09c6a0a88db46 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Thu, 2 Jan 2025 13:01:24 +0100 Subject: [PATCH] Foundation for new text content popovers --- ts/WoltLabSuite/Core/Component/Popover.ts | 2 +- .../Core/Component/Popover/SharedCache.ts | 30 ++++++++------ .../Core/Component/Popover/SharedCache.js | 24 ++++++++---- wcfsetup/install/files/style/ui/popover.scss | 39 +++++++++++++++++++ 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/ts/WoltLabSuite/Core/Component/Popover.ts b/ts/WoltLabSuite/Core/Component/Popover.ts index e0bd47174c..e1fdff011f 100644 --- a/ts/WoltLabSuite/Core/Component/Popover.ts +++ b/ts/WoltLabSuite/Core/Component/Popover.ts @@ -143,7 +143,7 @@ class Popover { } type Configuration = { - endpoint: string; + endpoint: string | ((objectId: number) => Promise); identifier: string; selector: string; }; diff --git a/ts/WoltLabSuite/Core/Component/Popover/SharedCache.ts b/ts/WoltLabSuite/Core/Component/Popover/SharedCache.ts index 7e8eb31288..ee8017d8fa 100644 --- a/ts/WoltLabSuite/Core/Component/Popover/SharedCache.ts +++ b/ts/WoltLabSuite/Core/Component/Popover/SharedCache.ts @@ -13,10 +13,23 @@ type ObjectId = number; export class SharedCache { readonly #data = new Map(); - readonly #endpoint: URL; - - constructor(endpoint: string) { - this.#endpoint = new URL(endpoint); + readonly #callback: (objectId: number) => Promise; + + constructor(endpoint: string | ((objectId: number) => Promise)) { + if (typeof endpoint === "string") { + this.#callback = async (objectId: number) => { + const url = new URL(endpoint); + url.searchParams.set("id", objectId.toString()); + const response = await prepareRequest(url).get().fetchAsResponse(); + if (!response?.ok) { + return ""; + } + + return await response.text(); + }; + } else { + this.#callback = endpoint; + } } async get(objectId: ObjectId): Promise { @@ -25,14 +38,7 @@ export class SharedCache { return content; } - this.#endpoint.searchParams.set("id", objectId.toString()); - - const response = await prepareRequest(this.#endpoint).get().fetchAsResponse(); - if (!response?.ok) { - return ""; - } - - content = await response.text(); + content = await this.#callback(objectId); this.#data.set(objectId, content); return content; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Popover/SharedCache.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Popover/SharedCache.js index ae9f172edc..c9e47b4f12 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Popover/SharedCache.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Popover/SharedCache.js @@ -12,21 +12,29 @@ define(["require", "exports", "WoltLabSuite/Core/Ajax/Backend"], function (requi exports.SharedCache = void 0; class SharedCache { #data = new Map(); - #endpoint; + #callback; constructor(endpoint) { - this.#endpoint = new URL(endpoint); + if (typeof endpoint === "string") { + this.#callback = async (objectId) => { + const url = new URL(endpoint); + url.searchParams.set("id", objectId.toString()); + const response = await (0, Backend_1.prepareRequest)(url).get().fetchAsResponse(); + if (!response?.ok) { + return ""; + } + return await response.text(); + }; + } + else { + this.#callback = endpoint; + } } async get(objectId) { let content = this.#data.get(objectId); if (content !== undefined) { return content; } - this.#endpoint.searchParams.set("id", objectId.toString()); - const response = await (0, Backend_1.prepareRequest)(this.#endpoint).get().fetchAsResponse(); - if (!response?.ok) { - return ""; - } - content = await response.text(); + content = await this.#callback(objectId); this.#data.set(objectId, content); return content; } diff --git a/wcfsetup/install/files/style/ui/popover.scss b/wcfsetup/install/files/style/ui/popover.scss index 3e8b41abc7..e529e91217 100644 --- a/wcfsetup/install/files/style/ui/popover.scss +++ b/wcfsetup/install/files/style/ui/popover.scss @@ -95,6 +95,7 @@ max-height: var(--maxHeight); max-width: var(--maxWidth); opacity: 0; + overflow: hidden; padding: var(--padding); position: absolute; transform: translateY(-20px); @@ -114,3 +115,41 @@ display: block; } } + +.popover__layout { + display: flex; + flex-direction: column; + gap: 10px; +} + +.popover__header { + display: grid; + grid-template-areas: + "avatar title" + "avatar time"; + grid-template-columns: min-content 1fr; + grid-template-rows: min-content 1fr; + column-gap: 10px; + margin-bottom: 10px; +} + +.popover__avatar { + grid-area: avatar; +} + +.popover__title { + grid-area: title; + font-weight: 600; + @include wcfFontHeadline; +} + +.popover__title a, +.popover__title a:hover { + color: inherit; +} + +.popover__time { + color: var(--wcfContentDimmedText); + grid-area: time; + @include wcfFontSmall; +} -- 2.20.1