Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use file processor for user avatar #6051

Draft
wants to merge 59 commits into
base: file-upload-image-crop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
afb055f
Add basic file processor for avatar
Cyperghost Nov 6, 2024
882f7a9
Add `wcf1_user.avatarFileID` column
Cyperghost Nov 6, 2024
782ceb5
Add session variable so that the user can delete the previous avatar
Cyperghost Nov 6, 2024
86805f9
Add a new user menu item to manage the avatar
Cyperghost Nov 6, 2024
e027ed5
Add dialog to edit the avatar file id
Cyperghost Nov 7, 2024
2df6b89
Add a command to set the avatar from a user
Cyperghost Nov 7, 2024
dfe7e6e
Support `File` in `AvatarDecorator` as avatar object
Cyperghost Nov 7, 2024
4e8a4f6
Remove old `AvatarEditForm`
Cyperghost Nov 7, 2024
6d92aa3
Load user avatar on `UserListPage`
Cyperghost Nov 7, 2024
74843d4
Use `CloseOverlay` to close the user menu
Cyperghost Nov 7, 2024
2897de9
`WCF.User.Avatar` and `WCF.User.Avatar.Upload` are no longer used
Cyperghost Nov 7, 2024
d785e06
Avatar is now no longer saved in `UserEditForm`
Cyperghost Nov 7, 2024
27faeb7
Do not reload the page in the ACP when editing the user after his ava…
Cyperghost Nov 7, 2024
be50736
Delete old avatar file only if it is set
Cyperghost Nov 7, 2024
8eaed86
Deprecated `UserAvatar`
Cyperghost Nov 8, 2024
16d278a
Move the old user avatar to the new file storage in the `UserRebuildD…
Cyperghost Nov 8, 2024
1d15c2b
Add new constant for the size of the avatar images in `UserAvatarFile…
Cyperghost Nov 8, 2024
1991832
Remove unused function `UserAvatarAction::validateUpload()` and `User…
Cyperghost Nov 8, 2024
315043d
Use `UserAvatarFileProcessor::AVATAR_SIZE` instead of `UserAvatar::AV…
Cyperghost Nov 8, 2024
4cae70a
Delete user avatar files when user accounts are deleted
Cyperghost Nov 8, 2024
614553e
No longer use `wcf1_user_avatar` to load the user's avatar
Cyperghost Nov 8, 2024
27a5982
Add since information
Cyperghost Nov 8, 2024
3f7182f
Use `avatarFileID` instead of `avatarID
Cyperghost Nov 8, 2024
8f06441
Add php doc to `SetAvatar`
Cyperghost Nov 8, 2024
3007ce3
No longer use `avatarID`
Cyperghost Nov 8, 2024
5f0fa41
Move `canEditAvatar()` into `UserProfile`
Cyperghost Nov 8, 2024
c734e90
Use the new dialog to manage the avatar on the UserPage
Cyperghost Nov 8, 2024
526aadf
Add an extra button next to *Edit cover photo* for avatar management
Cyperghost Nov 8, 2024
0944073
Implement `FileRuntimeCache`, which also loads the thumbnails
Cyperghost Nov 11, 2024
21b96a1
Use `FileRuntimeCache`
Cyperghost Nov 11, 2024
af4056e
Import the avatar in `UserImporter` and remove `UserAvatarImporter`
Cyperghost Nov 11, 2024
0f6732c
Removing the user object from the cache after setting the avatar
Cyperghost Nov 11, 2024
4a6b290
Remove unnecessary code
Cyperghost Nov 11, 2024
26b9ee9
Resize or make the avatar quadratic if required
Cyperghost Nov 11, 2024
6156406
Revert "Import the avatar in `UserImporter` and remove `UserAvatarImp…
Cyperghost Nov 18, 2024
e3c7bb4
Add a parameter to optionally copy the file, but it will still be mov…
Cyperghost Nov 18, 2024
bfcd4d3
Insert the avatar into the new file system during import, instead of …
Cyperghost Nov 18, 2024
a2c0339
Open the correct avatar management of the user on the profile page
Cyperghost Nov 26, 2024
b4adf28
Load a 256x256 or 128x128 thumbnail, depending on what thumbnails are…
Cyperghost Nov 26, 2024
2cff601
Apply suggestions from code review
Cyperghost Nov 27, 2024
4ad4afc
Run `tsc`
Cyperghost Nov 27, 2024
b3289a9
Check if `objectIDs` is empty
Cyperghost Nov 27, 2024
91e657f
Check whether the user is in the accessible user groups
Cyperghost Nov 27, 2024
eee7fb8
Avatar size may also be 256x256 and not only a maximum of 128x128
Cyperghost Nov 27, 2024
3f16df7
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Nov 28, 2024
0eb36d5
Run `tsc`
Cyperghost Nov 28, 2024
41f636d
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 2, 2024
043b3fc
Add foreign key for `wcf1_user.avatarFileID` to `wcf1_file.fileID`
Cyperghost Dec 2, 2024
5265f0a
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 4, 2024
662416c
`createExact` renamed to `forExact`
Cyperghost Dec 4, 2024
8e2734d
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 5, 2024
5f9a322
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 6, 2024
f90b328
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 12, 2024
e378fed
Use the user profile header template
Cyperghost Dec 12, 2024
ea529be
Use `File::getFullSizeImageSource()` instead of `File::getLink()`
Cyperghost Dec 12, 2024
70871a7
Add `simpleReplace` and `hideDeleteButton` to the `FileProcessorFormF…
Cyperghost Dec 12, 2024
8705964
Display thumbnail size by file processor
Cyperghost Dec 12, 2024
a44bea3
Merge branch 'file-upload-image-crop' into avatar-file-processor
Cyperghost Dec 16, 2024
001ac17
Unset `uploadResolve`
Cyperghost Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions com.woltlab.wcf/fileDelete.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,7 @@
<file>lib/data/user/option/IUserOptionOutput.class.php</file>
<file>lib/data/user/option/UserOptionOutput.class.php</file>
<file>lib/form/AbstractSecureForm.class.php</file>
<file>lib/form/AvatarEditForm.class.php</file>
<file>lib/form/Form.class.php</file>
<file>lib/form/MailForm.class.php</file>
<file>lib/form/MultifactorAuthenticationAbortForm.class.php</file>
Expand Down Expand Up @@ -2999,6 +3000,8 @@
<file>lib/system/template/plugin/TemplatePluginPrefilterIcon.class.php</file>
<file>lib/system/template/plugin/TemplatePluginPrefilterLang.class.php</file>
<file>lib/system/template/plugin/WordwrapModifierTemplatePlugin.class.php</file>
<file>lib/system/upload/AvatarUploadFileSaveStrategy.class.php</file>
<file>lib/system/upload/AvatarUploadFileValidationStrategy.class.php</file>
<file>lib/system/user/UserCollapsibleContentHandler.class.php</file>
<file>lib/system/user/activity/point/AbstractUserActivityPointObjectProcessor.class.php</file>
<file>lib/system/user/activity/point/DefaultUserActivityPointObjectProcessor.class.php</file>
Expand Down
5 changes: 5 additions & 0 deletions com.woltlab.wcf/objectType.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,11 @@
<definitionname>com.woltlab.wcf.file</definitionname>
<classname>wcf\system\file\processor\AttachmentFileProcessor</classname>
</type>
<type>
<name>com.woltlab.wcf.user.avatar</name>
<definitionname>com.woltlab.wcf.file</definitionname>
<classname>wcf\system\file\processor\UserAvatarFileProcessor</classname>
</type>
<!-- deprecated -->
<type>
<name>com.woltlab.wcf.page.controller</name>
Expand Down
15 changes: 1 addition & 14 deletions com.woltlab.wcf/page.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,6 @@
<title>Benutzerkonto-Sicherheit</title>
</content>
</page>
<page identifier="com.woltlab.wcf.AvatarEdit">
<pageType>system</pageType>
<controller>wcf\form\AvatarEditForm</controller>
<name language="de">Avatar-Verwaltung</name>
<name language="en">Avatar Management</name>
<hasFixedParent>1</hasFixedParent>
<parent>com.woltlab.wcf.AccountManagement</parent>
<content language="en">
<title>Avatar Management</title>
</content>
<content language="de">
<title>Avatar-Verwaltung</title>
</content>
</page>
<page identifier="com.woltlab.wcf.EmailActivation">
<pageType>system</pageType>
<controller>wcf\form\EmailActivationForm</controller>
Expand Down Expand Up @@ -888,6 +874,7 @@ E-Mail: [E-Mail-Adresse der verantwortlichen Stelle]</p><p>Verantwortliche Stell
</page>
</import>
<delete>
<page identifier="com.woltlab.wcf.AvatarEdit"/>
<!-- The notification list is no longer part of the user menu. -->
<page identifier="com.woltlab.wcf.NotificationList"/>
</delete>
Expand Down
1 change: 1 addition & 0 deletions com.woltlab.wcf/templateDelete.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,6 @@
<template>__multilineItemListFormField</template>
<template>email_notification_userRegistration</template>
<template>imageViewer</template>
<template>avatarEdit</template>
</delete>
</data>
82 changes: 0 additions & 82 deletions com.woltlab.wcf/templates/avatarEdit.tpl

This file was deleted.

3 changes: 3 additions & 0 deletions com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
'{unsafe:$field->getPrefixedId()|encodeJS}',
{if $field->isSingleFileUpload()}true{else}false{/if},
{if $field->isBigPreview()}true{else}false{/if},
{if $field->isSimpleReplace()}true{else}false{/if},
{if $field->isHideDeleteButton()}true{else}false{/if},
{if $field->getThumbnailSize() === null}undefined{else}'{$field->getThumbnailSize()|encodeJS}'{/if},
[{implode from=$actionButtons item=actionButton}{
title: '{unsafe:$actionButton['title']|encodeJS}',
icon: {if $actionButton['icon'] === null}undefined{else}'{unsafe:$actionButton['icon']->toHtml()|encodeJS}'{/if},
Expand Down
2 changes: 1 addition & 1 deletion com.woltlab.wcf/templates/user.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
'wcf.user.activityPoint': '{jslang}wcf.user.activityPoint{/jslang}'
});
{/if}

{if $user->canEdit() || ($__wcf->getUser()->userID == $user->userID && $user->canEditOwnProfile())}
WCF.Language.addObject({
'wcf.user.editProfile': '{jslang}wcf.user.editProfile{/jslang}'
Expand Down
8 changes: 7 additions & 1 deletion com.woltlab.wcf/templates/userProfileHeader.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
</div>
{/if}

{if $view->user->canEditAvatar()}
<button type="button" data-edit-avatar="{link controller="UserAvatar" id=$view->user->userID}{/link}" class="button small">
{icon name='circle-user' type='solid'} {lang}wcf.user.avatar.edit{/lang}
</button>
{/if}

{if $view->canEditUser()}
<button type="button" class="jsButtonEditProfile button small">{icon name='pencil'} <span>{lang}wcf.user.editProfile{/lang}</span></button>
{/if}
Expand All @@ -51,7 +57,7 @@
<div class="userProfileHeader__avatar">
<div class="userProfileHeader__avatarBorder">
{if $view->user->userID == $__wcf->user->userID}
<a href="{link controller='AvatarEdit'}{/link}" class="userProfileHeader__avatarEditLink jsTooltip" title="{lang}wcf.user.avatar.edit{/lang}">{unsafe:$view->user->getAvatar()->getImageTag(128)}</a>
<button type="button" data-edit-avatar="{link controller="UserAvatar" id=$view->user->userID}{/link}" class="userProfileHeader__avatarEditLink jsTooltip" title="{lang}wcf.user.avatar.edit{/lang}">{unsafe:$view->user->getAvatar()->getImageTag(128)}</button>
{else}
{unsafe:$view->user->getAvatar()->getImageTag(128)}
{/if}
Expand Down
6 changes: 1 addition & 5 deletions com.woltlab.wcf/userMenu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
<parent>wcf.user.menu.profile</parent>
<showorder>2</showorder>
</usermenuitem>
<usermenuitem name="wcf.user.menu.profile.avatar">
<controller>wcf\form\AvatarEditForm</controller>
<parent>wcf.user.menu.profile</parent>
<showorder>3</showorder>
</usermenuitem>
<usermenuitem name="wcf.user.menu.profile.signature">
<controller>wcf\form\SignatureEditForm</controller>
<parent>wcf.user.menu.profile</parent>
Expand Down Expand Up @@ -63,5 +58,6 @@
</import>
<delete>
<usermenuitem name="wcf.user.menu.community.notification"/>
<usermenuitem name="wcf.user.menu.profile.avatar"/>
</delete>
</data>
4 changes: 4 additions & 0 deletions ts/WoltLabSuite/Core/Bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ export function setup(options: BoostrapOptions): void {
whenFirstSeen(".messageTabMenu", () => {
void import("./Component/Message/MessageTabMenu").then(({ setup }) => setup());
});
whenFirstSeen("[data-edit-avatar]", () => {
void import("./Component/User/Avatar").then(({ setup }) => setup());
});

whenFirstSeen("woltlab-core-pagination", () => {
void import("./Ui/Pagination/JumpToPage").then(({ setup }) => setup());
});
Expand Down
2 changes: 2 additions & 0 deletions ts/WoltLabSuite/Core/Component/File/Upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ export function setup(): void {
void upload(element, resizedFile);
})
.catch((e) => {
element.dispatchEvent(new CustomEvent("cancel"));

if (e === undefined) {
// User closed the dialog.
return;
Expand Down
50 changes: 50 additions & 0 deletions ts/WoltLabSuite/Core/Component/User/Avatar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Handles the user avatar edit buttons.
*
* @author Olaf Braun
* @copyright 2001-2024 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.2
Cyperghost marked this conversation as resolved.
Show resolved Hide resolved
* @woltlabExcludeBundle all
*/

import { promiseMutex } from "WoltLabSuite/Core/Helper/PromiseMutex";
import { wheneverFirstSeen } from "WoltLabSuite/Core/Helper/Selector";
import { dialogFactory } from "WoltLabSuite/Core/Component/Dialog";
import { show as showNotification } from "WoltLabSuite/Core/Ui/Notification";

interface Result {
avatar: string;
}

async function editAvatar(button: HTMLElement): Promise<void> {
const { ok, result } = await dialogFactory().usingFormBuilder().fromEndpoint<Result>(button.dataset.editAvatar!);

if (ok) {
const avatarForm = document.getElementById("avatarForm");
if (avatarForm) {
// In the ACP, the form should not be reloaded after changing the avatar.
avatarForm.querySelector<HTMLImageElement>("img.userAvatarImage")!.src = result.avatar;
showNotification();
} else {
window.location.reload();
}
}
}

export function setup(): void {
wheneverFirstSeen(
"#wcf\\\\action\\\\UserAvatarAction_avatarFileIDContainer woltlab-core-file img",
(img: HTMLImageElement) => {
img.classList.add("userAvatarImage");
img.parentElement!.classList.add("userAvatar");
},
);

wheneverFirstSeen("[data-edit-avatar]", (button) => {
button.addEventListener(
"click",
promiseMutex(() => editAvatar(button)),
);
});
}
Loading
Loading