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

@@ -45,7 +45,11 @@ import { PermissionsSettingsComponent } from './permissions-settings/permissions
import { DebuggingSettingsComponent } from './debugging-settings/debugging-settings.component';
import { UpdatesSettingsComponent } from './updates-settings/updates-settings.component';
import { THIRD_PARTY_LICENSES, type ThirdPartyLicense } from './third-party-licenses';
import { ThemeLibraryService, ThemeService } from '../../../domains/theme';
import {
ThemeLibraryService,
ThemeNodeDirective,
ThemeService
} from '../../../domains/theme';
@Component({
selector: 'app-settings-modal',
@@ -63,7 +67,8 @@ import { ThemeLibraryService, ThemeService } from '../../../domains/theme';
ServerSettingsComponent,
MembersSettingsComponent,
BansSettingsComponent,
PermissionsSettingsComponent
PermissionsSettingsComponent,
ThemeNodeDirective
],
viewProviders: [
provideIcons({
@@ -109,41 +114,19 @@ export class SettingsModalComponent {
selectedSavedTheme = this.themeLibrary.selectedEntry;
readonly globalPages: { id: SettingsPage; label: string; icon: string }[] = [
{ id: 'general',
label: 'General',
icon: 'lucideSettings' },
{ id: 'theme',
label: 'Theme Studio',
icon: 'lucidePalette' },
{ id: 'network',
label: 'Network',
icon: 'lucideGlobe' },
{ id: 'notifications',
label: 'Notifications',
icon: 'lucideBell' },
{ id: 'voice',
label: 'Voice & Audio',
icon: 'lucideAudioLines' },
{ id: 'updates',
label: 'Updates',
icon: 'lucideDownload' },
{ id: 'debugging',
label: 'Debugging',
icon: 'lucideBug' }
{ id: 'general', label: 'General', icon: 'lucideSettings' },
{ id: 'theme', label: 'Theme Studio', icon: 'lucidePalette' },
{ id: 'network', label: 'Network', icon: 'lucideGlobe' },
{ id: 'notifications', label: 'Notifications', icon: 'lucideBell' },
{ id: 'voice', label: 'Voice & Audio', icon: 'lucideAudioLines' },
{ id: 'updates', label: 'Updates', icon: 'lucideDownload' },
{ id: 'debugging', label: 'Debugging', icon: 'lucideBug' }
];
readonly serverPages: { id: SettingsPage; label: string; icon: string }[] = [
{ id: 'server',
label: 'Server',
icon: 'lucideSettings' },
{ id: 'members',
label: 'Members',
icon: 'lucideUsers' },
{ id: 'bans',
label: 'Bans',
icon: 'lucideBan' },
{ id: 'permissions',
label: 'Permissions',
icon: 'lucideShield' }
{ id: 'server', label: 'Server', icon: 'lucideSettings' },
{ id: 'members', label: 'Members', icon: 'lucideUsers' },
{ id: 'bans', label: 'Bans', icon: 'lucideBan' },
{ id: 'permissions', label: 'Permissions', icon: 'lucideShield' }
];
manageableRooms = computed<Room[]>(() => {
@@ -153,16 +136,18 @@ export class SettingsModalComponent {
return [];
return this.savedRooms().filter((room) => {
const viewedRoom = this.currentRoom()?.id === room.id ? this.currentRoom() ?? room : room;
const viewedRoom = this.currentRoom()?.id === room.id ? (this.currentRoom() ?? room) : room;
const role = resolveLegacyRole(viewedRoom, user);
return role === 'host'
|| resolveRoomPermission(viewedRoom, user, 'manageServer')
|| resolveRoomPermission(viewedRoom, user, 'manageRoles')
|| resolveRoomPermission(viewedRoom, user, 'manageChannels')
|| resolveRoomPermission(viewedRoom, user, 'manageBans')
|| resolveRoomPermission(viewedRoom, user, 'kickMembers')
|| resolveRoomPermission(viewedRoom, user, 'banMembers');
return (
role === 'host' ||
resolveRoomPermission(viewedRoom, user, 'manageServer') ||
resolveRoomPermission(viewedRoom, user, 'manageRoles') ||
resolveRoomPermission(viewedRoom, user, 'manageChannels') ||
resolveRoomPermission(viewedRoom, user, 'manageBans') ||
resolveRoomPermission(viewedRoom, user, 'kickMembers') ||
resolveRoomPermission(viewedRoom, user, 'banMembers')
);
});
});
@@ -187,21 +172,23 @@ export class SettingsModalComponent {
if (!server || !user)
return null;
return resolveLegacyRole(this.currentRoom()?.id === server.id ? this.currentRoom() ?? server : server, user);
return resolveLegacyRole(this.currentRoom()?.id === server.id ? (this.currentRoom() ?? server) : server, user);
});
canAccessSelectedServer = computed(() => {
const server = this.selectedServer();
const user = this.currentUser();
return !!server && !!user && (
resolveLegacyRole(server, user) === 'host'
|| resolveRoomPermission(server, user, 'manageServer')
|| resolveRoomPermission(server, user, 'manageRoles')
|| resolveRoomPermission(server, user, 'manageChannels')
|| resolveRoomPermission(server, user, 'manageBans')
|| resolveRoomPermission(server, user, 'kickMembers')
|| resolveRoomPermission(server, user, 'banMembers')
return (
!!server &&
!!user &&
(resolveLegacyRole(server, user) === 'host' ||
resolveRoomPermission(server, user, 'manageServer') ||
resolveRoomPermission(server, user, 'manageRoles') ||
resolveRoomPermission(server, user, 'manageChannels') ||
resolveRoomPermission(server, user, 'manageBans') ||
resolveRoomPermission(server, user, 'kickMembers') ||
resolveRoomPermission(server, user, 'banMembers'))
);
});
@@ -209,11 +196,13 @@ export class SettingsModalComponent {
const server = this.selectedServer();
const user = this.currentUser();
return !!server && !!user && (
resolveLegacyRole(server, user) === 'host'
|| resolveRoomPermission(server, user, 'manageRoles')
|| resolveRoomPermission(server, user, 'kickMembers')
|| resolveRoomPermission(server, user, 'banMembers')
return (
!!server &&
!!user &&
(resolveLegacyRole(server, user) === 'host' ||
resolveRoomPermission(server, user, 'manageRoles') ||
resolveRoomPermission(server, user, 'kickMembers') ||
resolveRoomPermission(server, user, 'banMembers'))
);
});
@@ -221,20 +210,19 @@ export class SettingsModalComponent {
const server = this.selectedServer();
const user = this.currentUser();
return !!server && !!user && (
resolveLegacyRole(server, user) === 'host'
|| resolveRoomPermission(server, user, 'manageBans')
);
return !!server && !!user && (resolveLegacyRole(server, user) === 'host' || resolveRoomPermission(server, user, 'manageBans'));
});
canManageSelectedPermissions = computed(() => {
const server = this.selectedServer();
const user = this.currentUser();
return !!server && !!user && (
resolveLegacyRole(server, user) === 'host'
|| resolveRoomPermission(server, user, 'manageRoles')
|| resolveRoomPermission(server, user, 'manageServer')
return (
!!server &&
!!user &&
(resolveLegacyRole(server, user) === 'host' ||
resolveRoomPermission(server, user, 'manageRoles') ||
resolveRoomPermission(server, user, 'manageServer'))
);
});
@@ -259,9 +247,8 @@ export class SettingsModalComponent {
const hasSelected = !!selectedId && rooms.some((room) => room.id === selectedId);
if (!hasSelected) {
const fallbackId = [targetId, currentRoomId].find((candidateId) =>
!!candidateId && rooms.some((room) => room.id === candidateId)
) ?? rooms[0]?.id ?? null;
const fallbackId =
[targetId, currentRoomId].find((candidateId) => !!candidateId && rooms.some((room) => room.id === candidateId)) ?? rooms[0]?.id ?? null;
this.selectedServerId.set(fallbackId);
}