feat: Theme engine
big changes
This commit is contained in:
@@ -1,17 +1,38 @@
|
||||
<div
|
||||
class="fixed left-16 right-0 top-0 z-50 flex h-10 items-center justify-between border-b border-border bg-card px-4 select-none"
|
||||
appThemeNode="titleBar"
|
||||
class="relative z-50 flex h-10 w-full items-center justify-between border-b border-border bg-card px-4 select-none"
|
||||
style="-webkit-app-region: drag"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-2 min-w-0 relative"
|
||||
style="-webkit-app-region: no-drag"
|
||||
>
|
||||
<span
|
||||
data-theme-slot="icon"
|
||||
class="theme-icon-slot h-6 w-6 shrink-0 items-center justify-center rounded-xl border border-border/70 bg-secondary/70 bg-center bg-cover bg-no-repeat text-[10px] font-semibold uppercase tracking-[0.16em] text-foreground"
|
||||
></span>
|
||||
|
||||
@if (inRoom()) {
|
||||
<ng-icon
|
||||
name="lucideHash"
|
||||
class="w-5 h-5 text-muted-foreground"
|
||||
/>
|
||||
<span class="truncate text-sm font-semibold text-foreground">{{ roomContextTitle() }}</span>
|
||||
<span
|
||||
data-theme-slot="text"
|
||||
class="flex min-w-0 items-center gap-2 text-sm font-semibold text-foreground"
|
||||
>
|
||||
<span class="truncate">{{ roomName() }}</span>
|
||||
|
||||
@if (isVoiceWorkspaceExpanded()) {
|
||||
<span class="shrink-0 text-muted-foreground">/</span>
|
||||
<span class="truncate">{{ connectedVoiceChannelName() }}</span>
|
||||
} @else if (textChannels().length > 0) {
|
||||
<span class="shrink-0 text-muted-foreground">/</span>
|
||||
<span class="flex min-w-0 items-center gap-1 text-foreground">
|
||||
<ng-icon
|
||||
name="lucideHash"
|
||||
class="h-4 w-4 shrink-0 text-muted-foreground"
|
||||
/>
|
||||
<span class="truncate">{{ activeTextChannelName() }}</span>
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
|
||||
@if (showRoomCompatibilityNotice()) {
|
||||
<span class="inline-flex items-center gap-1 rounded bg-destructive/15 px-2 py-0.5 text-xs text-destructive">
|
||||
@@ -36,7 +57,11 @@
|
||||
}
|
||||
} @else {
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<span class="text-sm text-muted-foreground truncate">{{ username() }} | {{ serverName() }}</span>
|
||||
<span
|
||||
data-theme-slot="text"
|
||||
class="text-sm text-muted-foreground truncate"
|
||||
>{{ username() }} | {{ serverName() }}</span
|
||||
>
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded bg-destructive/15 text-destructive"
|
||||
[class.hidden]="!isReconnecting()"
|
||||
@@ -59,57 +84,62 @@
|
||||
Login
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="toggleMenu()"
|
||||
class="ml-2 rounded-md p-2 transition-colors hover:bg-secondary"
|
||||
title="Menu"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideMenu"
|
||||
class="w-5 h-5 text-muted-foreground"
|
||||
/>
|
||||
</button>
|
||||
<!-- Anchored dropdown under the menu button -->
|
||||
@if (showMenu()) {
|
||||
<div class="absolute right-0 top-full z-50 mt-2 w-64 rounded-md border border-border bg-popover p-1 shadow-lg">
|
||||
@if (inRoom()) {
|
||||
<button
|
||||
type="button"
|
||||
(click)="createInviteLink()"
|
||||
[disabled]="creatingInvite()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-60"
|
||||
<div class="relative">
|
||||
<button
|
||||
type="button"
|
||||
(click)="toggleMenu()"
|
||||
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-secondary"
|
||||
title="Menu"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideMenu"
|
||||
class="h-4 w-4 text-muted-foreground"
|
||||
/>
|
||||
</button>
|
||||
|
||||
@if (showMenu()) {
|
||||
<div
|
||||
class="absolute right-0 top-full z-50 mt-2 w-64 rounded-md border border-border bg-popover p-1 shadow-lg"
|
||||
style="-webkit-app-region: no-drag"
|
||||
>
|
||||
@if (inRoom()) {
|
||||
<button
|
||||
type="button"
|
||||
(click)="createInviteLink()"
|
||||
[disabled]="creatingInvite()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
@if (creatingInvite()) {
|
||||
Creating Invite Link…
|
||||
} @else {
|
||||
Create Invite Link
|
||||
}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
(click)="leaveServer()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary"
|
||||
>
|
||||
Leave Server
|
||||
</button>
|
||||
}
|
||||
<div
|
||||
class="px-3 py-2 text-xs leading-5 text-muted-foreground"
|
||||
[class.hidden]="!inviteStatus()"
|
||||
>
|
||||
@if (creatingInvite()) {
|
||||
Creating Invite Link…
|
||||
} @else {
|
||||
Create Invite Link
|
||||
}
|
||||
</button>
|
||||
{{ inviteStatus() }}
|
||||
</div>
|
||||
<div class="mx-2 my-1 h-px bg-border"></div>
|
||||
<button
|
||||
type="button"
|
||||
(click)="leaveServer()"
|
||||
(click)="logout()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary"
|
||||
>
|
||||
Leave Server
|
||||
Logout
|
||||
</button>
|
||||
}
|
||||
<div
|
||||
class="px-3 py-2 text-xs leading-5 text-muted-foreground"
|
||||
[class.hidden]="!inviteStatus()"
|
||||
>
|
||||
{{ inviteStatus() }}
|
||||
</div>
|
||||
<div class="mx-2 my-1 h-px bg-border"></div>
|
||||
<button
|
||||
type="button"
|
||||
(click)="logout()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary"
|
||||
>
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@if (isElectron()) {
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -37,6 +37,7 @@ import { STORAGE_KEY_CURRENT_USER_ID } from '../../core/constants';
|
||||
import { LeaveServerDialogComponent } from '../../shared';
|
||||
import { Room } from '../../shared-kernel';
|
||||
import { VoiceWorkspaceService } from '../../domains/voice-session';
|
||||
import { ThemeNodeDirective } from '../../domains/theme';
|
||||
|
||||
@Component({
|
||||
selector: 'app-title-bar',
|
||||
@@ -44,7 +45,8 @@ import { VoiceWorkspaceService } from '../../domains/voice-session';
|
||||
imports: [
|
||||
CommonModule,
|
||||
NgIcon,
|
||||
LeaveServerDialogComponent
|
||||
LeaveServerDialogComponent,
|
||||
ThemeNodeDirective
|
||||
],
|
||||
viewProviders: [
|
||||
provideIcons({ lucideMinus,
|
||||
@@ -109,23 +111,6 @@ export class TitleBarComponent {
|
||||
|
||||
return voiceChannel?.name || 'Voice Lounge';
|
||||
});
|
||||
roomContextTitle = computed(() => {
|
||||
const room = this.currentRoom();
|
||||
|
||||
if (!room) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (this.isVoiceWorkspaceExpanded()) {
|
||||
return `${room.name} / ${this.connectedVoiceChannelName()}`;
|
||||
}
|
||||
|
||||
if (this.textChannels().length === 0) {
|
||||
return room.name;
|
||||
}
|
||||
|
||||
return `${room.name} / #${this.activeTextChannelName()}`;
|
||||
});
|
||||
roomContextMeta = computed(() => {
|
||||
if (!this.currentRoom()) {
|
||||
return '';
|
||||
|
||||
Reference in New Issue
Block a user