feat: Theme studio v2

This commit is contained in:
2026-04-27 03:02:13 +02:00
parent 11c2588e45
commit 1b91eacb5b
52 changed files with 2792 additions and 844 deletions

View File

@@ -21,6 +21,7 @@ import {
} from '../../../domains/profile-avatar';
import { UsersActions } from '../../../store/users/users.actions';
import { selectUsersEntities } from '../../../store/users/users.selectors';
import { ThemeNodeDirective } from '../../../domains/theme';
@Component({
selector: 'app-profile-card',
@@ -28,15 +29,14 @@ import { selectUsersEntities } from '../../../store/users/users.selectors';
imports: [
CommonModule,
NgIcon,
UserAvatarComponent
UserAvatarComponent,
ThemeNodeDirective
],
viewProviders: [provideIcons({ lucideCheck, lucideChevronDown })],
templateUrl: './profile-card.component.html'
})
export class ProfileCardComponent {
readonly user = signal<User>({ id: '', oderId: '', username: '', displayName: '', status: 'offline', role: 'member', joinedAt: 0 });
private readonly store = inject(Store);
private readonly users = this.store.selectSignal(selectUsersEntities);
readonly displayedUser = computed(() => {
const snapshot = this.user();
const entities = this.users();
@@ -60,42 +60,58 @@ export class ProfileCardComponent {
{ value: 'offline', label: 'Invisible', color: 'bg-gray-500' }
];
private readonly store = inject(Store);
private readonly users = this.store.selectSignal(selectUsersEntities);
private readonly userStatus = inject(UserStatusService);
private readonly profileAvatar = inject(ProfileAvatarFacade);
private readonly profileAvatarEditor = inject(ProfileAvatarEditorService);
private readonly syncProfileDrafts = effect(() => {
const user = this.displayedUser();
const editingField = this.editingField();
private readonly syncProfileDrafts = effect(
() => {
const user = this.displayedUser();
const editingField = this.editingField();
if (editingField !== 'displayName') {
this.displayNameDraft.set(user.displayName || '');
}
if (editingField !== 'displayName') {
this.displayNameDraft.set(user.displayName || '');
}
if (editingField !== 'description') {
this.descriptionDraft.set(user.description || '');
}
}, { allowSignalWrites: true });
if (editingField !== 'description') {
this.descriptionDraft.set(user.description || '');
}
},
{ allowSignalWrites: true }
);
currentStatusColor(): string {
switch (this.displayedUser().status) {
case 'online': return 'bg-green-500';
case 'away': return 'bg-yellow-500';
case 'busy': return 'bg-red-500';
case 'offline': return 'bg-gray-500';
case 'disconnected': return 'bg-gray-500';
default: return 'bg-green-500';
case 'online':
return 'bg-green-500';
case 'away':
return 'bg-yellow-500';
case 'busy':
return 'bg-red-500';
case 'offline':
return 'bg-gray-500';
case 'disconnected':
return 'bg-gray-500';
default:
return 'bg-green-500';
}
}
currentStatusLabel(): string {
switch (this.displayedUser().status) {
case 'online': return 'Online';
case 'away': return 'Away';
case 'busy': return 'Do Not Disturb';
case 'offline': return 'Invisible';
case 'disconnected': return 'Offline';
default: return 'Online';
case 'online':
return 'Online';
case 'away':
return 'Away';
case 'busy':
return 'Do Not Disturb';
case 'offline':
return 'Invisible';
case 'disconnected':
return 'Offline';
default:
return 'Online';
}
}
@@ -111,9 +127,7 @@ export class ProfileCardComponent {
isStatusOptionSelected(status: UserStatus | null): boolean {
const currentStatus = this.displayedUser().status;
return status === null
? currentStatus === 'online'
: currentStatus === status;
return status === null ? currentStatus === 'online' : currentStatus === status;
}
onDisplayNameInput(event: Event): void {
@@ -223,10 +237,7 @@ export class ProfileCardComponent {
const user = this.displayedUser();
const description = this.normalizeDescription(this.descriptionDraft());
if (
displayName === this.normalizeDisplayName(user.displayName)
&& description === this.normalizeDescription(user.description)
) {
if (displayName === this.normalizeDisplayName(user.displayName) && description === this.normalizeDescription(user.description)) {
return;
}