From: Cyperghost Date: Wed, 18 Dec 2024 10:13:17 +0000 (+0100) Subject: Change cover photo instantly when a new file is uploaded or deleted X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2e02d697d795fddd392f3114b25db0fa16dcb783;p=GitHub%2FWoltLab%2FWCF.git Change cover photo instantly when a new file is uploaded or deleted --- diff --git a/com.woltlab.wcf/templates/userProfileHeader.tpl b/com.woltlab.wcf/templates/userProfileHeader.tpl index e9dcca9213..cdc58d0d80 100644 --- a/com.woltlab.wcf/templates/userProfileHeader.tpl +++ b/com.woltlab.wcf/templates/userProfileHeader.tpl @@ -21,7 +21,7 @@ >
- +
diff --git a/ts/WoltLabSuite/Core/Component/User/CoverPhoto.ts b/ts/WoltLabSuite/Core/Component/User/CoverPhoto.ts index 1bd2e52b89..b19674a7d3 100644 --- a/ts/WoltLabSuite/Core/Component/User/CoverPhoto.ts +++ b/ts/WoltLabSuite/Core/Component/User/CoverPhoto.ts @@ -14,11 +14,12 @@ import { dialogFactory } from "WoltLabSuite/Core/Component/Dialog"; import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend"; import { show as showNotification } from "WoltLabSuite/Core/Ui/Notification"; import * as FormBuilderManager from "WoltLabSuite/Core/Form/Builder/Manager"; -import WoltlabCoreFile from "WoltLabSuite/Core/Component/File/woltlab-core-file"; import { fire as fireEvent } from "WoltLabSuite/Core/Event/Handler"; import { getPhrase } from "WoltLabSuite/Core/Language"; import DomUtil from "WoltLabSuite/Core/Dom/Util"; import { escapeHTML } from "WoltLabSuite/Core/StringUtil"; +import { registerCallback } from "WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor"; +import WoltlabCoreFile from "WoltLabSuite/Core/Component/File/woltlab-core-file"; type ResponseGetForm = { dialog: string; @@ -27,65 +28,18 @@ type ResponseGetForm = { }; async function editCoverPhoto(button: HTMLElement): Promise { - const defaultCoverPhoto = button.dataset.defaultCoverPhoto; const json = (await prepareRequest(button.dataset.editCoverPhoto!).get().fetchAsJson()) as ResponseGetForm; const dialog = dialogFactory().fromHtml(json.dialog).withoutControls(); - const coverPhotoElement = getCoverPhotoElement(); - const coverPhotoNotice = document.getElementById("coverPhotoNotice"); - const oldCoverPhoto = getCoverPhotoUrl(coverPhotoElement); dialog.addEventListener("afterClose", () => { - const file = dialog.querySelector("woltlab-core-file"); - const coverPhotoUrl = file?.link ?? defaultCoverPhoto ?? ""; - const coverPhotoStyle = `url("${coverPhotoUrl}")`; - if (FormBuilderManager.hasForm(json.formId)) { FormBuilderManager.unregisterForm(json.formId); } - - if (oldCoverPhoto === coverPhotoUrl || oldCoverPhoto === coverPhotoStyle) { - // nothing changed - return; - } - - if (coverPhotoElement instanceof HTMLImageElement && coverPhotoUrl) { - coverPhotoElement.src = coverPhotoUrl; - } else { - // ACP cover photo management - if (!coverPhotoElement && coverPhotoUrl) { - coverPhotoNotice!.parentElement!.appendChild( - DomUtil.createFragmentFromHtml( - `
`, - ), - ); - coverPhotoNotice!.remove(); - } else if (coverPhotoElement && !coverPhotoUrl) { - coverPhotoElement.parentElement!.appendChild( - DomUtil.createFragmentFromHtml( - `${getPhrase("wcf.user.coverPhoto.noImage")}`, - ), - ); - coverPhotoElement.remove(); - } - } - - showNotification(); - fireEvent("com.woltlab.wcf.user", "coverPhoto", { - url: coverPhotoUrl, - }); }); dialog.show(json.title); } -function getCoverPhotoUrl(coverPhotoElement: HTMLElement | null): string | undefined { - if (coverPhotoElement instanceof HTMLImageElement) { - return coverPhotoElement.src; - } else { - return coverPhotoElement?.style.backgroundImage; - } -} - function getCoverPhotoElement(): HTMLElement | null { return ( document.querySelector(".userProfileHeader__coverPhotoImage") ?? @@ -95,6 +49,55 @@ function getCoverPhotoElement(): HTMLElement | null { export function setup(): void { wheneverFirstSeen("[data-edit-cover-photo]", (button) => { + const defaultCoverPhoto = button.dataset.defaultCoverPhoto; + + registerCallback("wcf\\action\\UserCoverPhotoAction_coverPhotoFileID", (fileId: number | undefined) => { + const coverPhotoElement = getCoverPhotoElement(); + + if (coverPhotoElement && parseInt(coverPhotoElement.dataset.objectId!) === fileId) { + // nothing changed + return; + } + + const file = document.querySelector( + `#wcf\\\\action\\\\UserCoverPhotoAction_coverPhotoFileIDContainer woltlab-core-file[file-id="${fileId}"]`, + ); + const coverPhotoNotice = document.getElementById("coverPhotoNotice"); + const coverPhotoUrl = file?.link ?? defaultCoverPhoto ?? ""; + const coverPhotoStyle = `url("${coverPhotoUrl}")`; + + if (coverPhotoElement instanceof HTMLImageElement && coverPhotoUrl) { + coverPhotoElement.src = coverPhotoUrl; + + coverPhotoElement.dataset.objectId = fileId?.toString() || ""; + } else { + // ACP cover photo management + if (!coverPhotoElement && coverPhotoUrl) { + coverPhotoNotice!.parentElement!.appendChild( + DomUtil.createFragmentFromHtml( + `
`, + ), + ); + coverPhotoNotice!.remove(); + } else if (coverPhotoElement && !coverPhotoUrl) { + coverPhotoElement.parentElement!.appendChild( + DomUtil.createFragmentFromHtml( + `${getPhrase("wcf.user.coverPhoto.noImage")}`, + ), + ); + coverPhotoElement.remove(); + } else if (coverPhotoElement && coverPhotoUrl) { + coverPhotoElement.style.backgroundImage = coverPhotoStyle; + coverPhotoElement.dataset.objectId = fileId?.toString() || ""; + } + } + + showNotification(); + fireEvent("com.woltlab.wcf.user", "coverPhoto", { + url: coverPhotoUrl, + }); + }); + button.addEventListener( "click", promiseMutex(() => editCoverPhoto(button)), diff --git a/wcfsetup/install/files/acp/templates/userAdd.tpl b/wcfsetup/install/files/acp/templates/userAdd.tpl index eb7b38bb4e..5fd96b3a77 100644 --- a/wcfsetup/install/files/acp/templates/userAdd.tpl +++ b/wcfsetup/install/files/acp/templates/userAdd.tpl @@ -726,7 +726,7 @@
{if $userCoverPhoto} -
+
{else} {lang}wcf.user.coverPhoto.noImage{/lang} {/if} diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/User/CoverPhoto.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/User/CoverPhoto.js index df15562c28..62c7ddc65d 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/User/CoverPhoto.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/User/CoverPhoto.js @@ -7,65 +7,63 @@ * @since 6.2 * @woltlabExcludeBundle all */ -define(["require", "exports", "tslib", "WoltLabSuite/Core/Helper/PromiseMutex", "WoltLabSuite/Core/Helper/Selector", "WoltLabSuite/Core/Component/Dialog", "WoltLabSuite/Core/Ajax/Backend", "WoltLabSuite/Core/Ui/Notification", "WoltLabSuite/Core/Form/Builder/Manager", "WoltLabSuite/Core/Event/Handler", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/Dom/Util", "WoltLabSuite/Core/StringUtil"], function (require, exports, tslib_1, PromiseMutex_1, Selector_1, Dialog_1, Backend_1, Notification_1, FormBuilderManager, Handler_1, Language_1, Util_1, StringUtil_1) { +define(["require", "exports", "tslib", "WoltLabSuite/Core/Helper/PromiseMutex", "WoltLabSuite/Core/Helper/Selector", "WoltLabSuite/Core/Component/Dialog", "WoltLabSuite/Core/Ajax/Backend", "WoltLabSuite/Core/Ui/Notification", "WoltLabSuite/Core/Form/Builder/Manager", "WoltLabSuite/Core/Event/Handler", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/Dom/Util", "WoltLabSuite/Core/StringUtil", "WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor"], function (require, exports, tslib_1, PromiseMutex_1, Selector_1, Dialog_1, Backend_1, Notification_1, FormBuilderManager, Handler_1, Language_1, Util_1, StringUtil_1, FileProcessor_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setup = setup; FormBuilderManager = tslib_1.__importStar(FormBuilderManager); Util_1 = tslib_1.__importDefault(Util_1); async function editCoverPhoto(button) { - const defaultCoverPhoto = button.dataset.defaultCoverPhoto; const json = (await (0, Backend_1.prepareRequest)(button.dataset.editCoverPhoto).get().fetchAsJson()); const dialog = (0, Dialog_1.dialogFactory)().fromHtml(json.dialog).withoutControls(); - const coverPhotoElement = getCoverPhotoElement(); - const coverPhotoNotice = document.getElementById("coverPhotoNotice"); - const oldCoverPhoto = getCoverPhotoUrl(coverPhotoElement); dialog.addEventListener("afterClose", () => { - const file = dialog.querySelector("woltlab-core-file"); - const coverPhotoUrl = file?.link ?? defaultCoverPhoto ?? ""; - const coverPhotoStyle = `url("${coverPhotoUrl}")`; if (FormBuilderManager.hasForm(json.formId)) { FormBuilderManager.unregisterForm(json.formId); } - if (oldCoverPhoto === coverPhotoUrl || oldCoverPhoto === coverPhotoStyle) { - // nothing changed - return; - } - if (coverPhotoElement instanceof HTMLImageElement && coverPhotoUrl) { - coverPhotoElement.src = coverPhotoUrl; - } - else { - // ACP cover photo management - if (!coverPhotoElement && coverPhotoUrl) { - coverPhotoNotice.parentElement.appendChild(Util_1.default.createFragmentFromHtml(`
`)); - coverPhotoNotice.remove(); - } - else if (coverPhotoElement && !coverPhotoUrl) { - coverPhotoElement.parentElement.appendChild(Util_1.default.createFragmentFromHtml(`${(0, Language_1.getPhrase)("wcf.user.coverPhoto.noImage")}`)); - coverPhotoElement.remove(); - } - } - (0, Notification_1.show)(); - (0, Handler_1.fire)("com.woltlab.wcf.user", "coverPhoto", { - url: coverPhotoUrl, - }); }); dialog.show(json.title); } - function getCoverPhotoUrl(coverPhotoElement) { - if (coverPhotoElement instanceof HTMLImageElement) { - return coverPhotoElement.src; - } - else { - return coverPhotoElement?.style.backgroundImage; - } - } function getCoverPhotoElement() { return (document.querySelector(".userProfileHeader__coverPhotoImage") ?? document.getElementById("coverPhotoPreview")); } function setup() { (0, Selector_1.wheneverFirstSeen)("[data-edit-cover-photo]", (button) => { + const defaultCoverPhoto = button.dataset.defaultCoverPhoto; + (0, FileProcessor_1.registerCallback)("wcf\\action\\UserCoverPhotoAction_coverPhotoFileID", (fileId) => { + const coverPhotoElement = getCoverPhotoElement(); + if (coverPhotoElement && parseInt(coverPhotoElement.dataset.objectId) === fileId) { + // nothing changed + return; + } + const file = document.querySelector(`#wcf\\\\action\\\\UserCoverPhotoAction_coverPhotoFileIDContainer woltlab-core-file[file-id="${fileId}"]`); + const coverPhotoNotice = document.getElementById("coverPhotoNotice"); + const coverPhotoUrl = file?.link ?? defaultCoverPhoto ?? ""; + const coverPhotoStyle = `url("${coverPhotoUrl}")`; + if (coverPhotoElement instanceof HTMLImageElement && coverPhotoUrl) { + coverPhotoElement.src = coverPhotoUrl; + coverPhotoElement.dataset.objectId = fileId?.toString() || ""; + } + else { + // ACP cover photo management + if (!coverPhotoElement && coverPhotoUrl) { + coverPhotoNotice.parentElement.appendChild(Util_1.default.createFragmentFromHtml(`
`)); + coverPhotoNotice.remove(); + } + else if (coverPhotoElement && !coverPhotoUrl) { + coverPhotoElement.parentElement.appendChild(Util_1.default.createFragmentFromHtml(`${(0, Language_1.getPhrase)("wcf.user.coverPhoto.noImage")}`)); + coverPhotoElement.remove(); + } + else if (coverPhotoElement && coverPhotoUrl) { + coverPhotoElement.style.backgroundImage = coverPhotoStyle; + coverPhotoElement.dataset.objectId = fileId?.toString() || ""; + } + } + (0, Notification_1.show)(); + (0, Handler_1.fire)("com.woltlab.wcf.user", "coverPhoto", { + url: coverPhotoUrl, + }); + }); button.addEventListener("click", (0, PromiseMutex_1.promiseMutex)(() => editCoverPhoto(button))); }); } diff --git a/wcfsetup/install/files/lib/data/user/cover/photo/DefaultUserCoverPhoto.class.php b/wcfsetup/install/files/lib/data/user/cover/photo/DefaultUserCoverPhoto.class.php index 91660d3136..00ad124e03 100644 --- a/wcfsetup/install/files/lib/data/user/cover/photo/DefaultUserCoverPhoto.class.php +++ b/wcfsetup/install/files/lib/data/user/cover/photo/DefaultUserCoverPhoto.class.php @@ -44,4 +44,10 @@ class DefaultUserCoverPhoto implements IUserCoverPhoto { return StyleHandler::getInstance()->getStyle()->getCoverPhoto($forceWebP); } + + #[\Override] + public function getObjectID(): ?int + { + return null; + } } diff --git a/wcfsetup/install/files/lib/data/user/cover/photo/IUserCoverPhoto.class.php b/wcfsetup/install/files/lib/data/user/cover/photo/IUserCoverPhoto.class.php index ef7c32cdf5..ce1be6d9dd 100644 --- a/wcfsetup/install/files/lib/data/user/cover/photo/IUserCoverPhoto.class.php +++ b/wcfsetup/install/files/lib/data/user/cover/photo/IUserCoverPhoto.class.php @@ -30,4 +30,9 @@ interface IUserCoverPhoto * Returns the file name of this cover photo. */ public function getFilename(?bool $forceWebP = null): string; + + /** + * Returns the object ID of this cover photo. + */ + public function getObjectID(): ?int; } diff --git a/wcfsetup/install/files/lib/data/user/cover/photo/UserCoverPhoto.class.php b/wcfsetup/install/files/lib/data/user/cover/photo/UserCoverPhoto.class.php index 87936fa97e..54aec222da 100644 --- a/wcfsetup/install/files/lib/data/user/cover/photo/UserCoverPhoto.class.php +++ b/wcfsetup/install/files/lib/data/user/cover/photo/UserCoverPhoto.class.php @@ -56,6 +56,12 @@ final class UserCoverPhoto implements IUserCoverPhoto return $this->file->filename; } + #[\Override] + public function getObjectID(): ?int + { + return $this->file->fileID; + } + /** * Returns the minimum and maximum dimensions for cover photos. */