feat: Add user metadata changing display name and description with sync
All checks were successful
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Successful in 5m2s
Queue Release Build / build-windows (push) Successful in 16m44s
Queue Release Build / build-linux (push) Successful in 27m12s
Queue Release Build / finalize (push) Successful in 22s
All checks were successful
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Successful in 5m2s
Queue Release Build / build-windows (push) Successful in 16m44s
Queue Release Build / build-linux (push) Successful in 27m12s
Queue Release Build / finalize (push) Successful in 22s
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
Component,
|
||||
effect,
|
||||
inject,
|
||||
signal
|
||||
} from '@angular/core';
|
||||
@@ -37,6 +38,9 @@ export class ProfileCardComponent {
|
||||
readonly avatarAccept = PROFILE_AVATAR_ACCEPT_ATTRIBUTE;
|
||||
readonly avatarError = signal<string | null>(null);
|
||||
readonly avatarSaving = signal(false);
|
||||
readonly editingField = signal<'displayName' | 'description' | null>(null);
|
||||
readonly displayNameDraft = signal('');
|
||||
readonly descriptionDraft = signal('');
|
||||
|
||||
readonly statusOptions: { value: UserStatus | null; label: string; color: string }[] = [
|
||||
{ value: null, label: 'Online', color: 'bg-green-500' },
|
||||
@@ -49,6 +53,19 @@ export class ProfileCardComponent {
|
||||
private readonly store = inject(Store);
|
||||
private readonly profileAvatar = inject(ProfileAvatarFacade);
|
||||
private readonly profileAvatarEditor = inject(ProfileAvatarEditorService);
|
||||
private readonly syncProfileDrafts = effect(() => {
|
||||
const user = this.user();
|
||||
const editingField = this.editingField();
|
||||
|
||||
if (editingField !== 'displayName') {
|
||||
this.displayNameDraft.set(user.displayName || '');
|
||||
}
|
||||
|
||||
if (editingField !== 'description') {
|
||||
this.descriptionDraft.set(user.description || '');
|
||||
}
|
||||
|
||||
}, { allowSignalWrites: true });
|
||||
|
||||
currentStatusColor(): string {
|
||||
switch (this.user().status) {
|
||||
@@ -81,6 +98,31 @@ export class ProfileCardComponent {
|
||||
this.showStatusMenu.set(false);
|
||||
}
|
||||
|
||||
onDisplayNameInput(event: Event): void {
|
||||
this.displayNameDraft.set((event.target as HTMLInputElement).value);
|
||||
}
|
||||
|
||||
onDescriptionInput(event: Event): void {
|
||||
this.descriptionDraft.set((event.target as HTMLTextAreaElement).value);
|
||||
}
|
||||
|
||||
startEdit(field: 'displayName' | 'description'): void {
|
||||
if (!this.editable() || this.editingField() === field) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editingField.set(field);
|
||||
}
|
||||
|
||||
finishEdit(field: 'displayName' | 'description'): void {
|
||||
if (this.editingField() !== field) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.commitProfileDrafts();
|
||||
this.editingField.set(null);
|
||||
}
|
||||
|
||||
pickAvatar(fileInput: HTMLInputElement): void {
|
||||
if (!this.editable() || this.avatarSaving()) {
|
||||
return;
|
||||
@@ -147,4 +189,49 @@ export class ProfileCardComponent {
|
||||
this.avatarSaving.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
private commitProfileDrafts(): void {
|
||||
if (!this.editable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const displayName = this.normalizeDisplayName(this.displayNameDraft());
|
||||
|
||||
if (!displayName) {
|
||||
this.displayNameDraft.set(this.user().displayName || '');
|
||||
return;
|
||||
}
|
||||
|
||||
const user = this.user();
|
||||
const description = this.normalizeDescription(this.descriptionDraft());
|
||||
|
||||
if (
|
||||
displayName === this.normalizeDisplayName(user.displayName)
|
||||
&& description === this.normalizeDescription(user.description)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const profile = {
|
||||
displayName,
|
||||
description,
|
||||
profileUpdatedAt: Date.now()
|
||||
};
|
||||
|
||||
this.store.dispatch(UsersActions.updateCurrentUserProfile({ profile }));
|
||||
this.user.update((user) => ({
|
||||
...user,
|
||||
...profile
|
||||
}));
|
||||
}
|
||||
|
||||
private normalizeDisplayName(value: string | undefined): string {
|
||||
return value?.trim().replace(/\s+/g, ' ') || '';
|
||||
}
|
||||
|
||||
private normalizeDescription(value: string | undefined): string | undefined {
|
||||
const normalized = value?.trim();
|
||||
|
||||
return normalized || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user