Files
Toju/toju-app/src/app/features/shell/title-bar.component.html
2026-04-01 19:31:00 +02:00

172 lines
5.1 KiB
HTML

<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"
style="-webkit-app-region: drag"
>
<div
class="flex items-center gap-2 min-w-0 relative"
style="-webkit-app-region: no-drag"
>
@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>
@if (showRoomCompatibilityNotice()) {
<span class="inline-flex items-center gap-1 rounded bg-destructive/15 px-2 py-0.5 text-xs text-destructive">
{{ signalServerCompatibilityError() }}
</span>
}
@if (showRoomReconnectNotice()) {
<span class="inline-flex items-center gap-1 rounded bg-destructive/15 px-2 py-0.5 text-xs text-destructive">
<ng-icon
name="lucideRefreshCw"
class="h-3.5 w-3.5 animate-spin"
/>
Reconnecting to signal server…
</span>
}
@if (roomContextMeta()) {
<span class="hidden truncate border-l border-border/70 pl-2 text-xs text-muted-foreground md:inline">
{{ roomContextMeta() }}
</span>
}
} @else {
<div class="flex items-center gap-2 min-w-0">
<span 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()"
>Reconnecting…</span
>
</div>
}
</div>
<div
class="flex items-center gap-2"
style="-webkit-app-region: no-drag"
>
<button
type="button"
class="grid h-8 place-items-center rounded-md px-3 text-sm text-foreground transition-colors hover:bg-secondary"
[class.hidden]="isAuthed()"
(click)="goLogin()"
title="Login"
>
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"
>
@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()"
>
{{ 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>
}
@if (isElectron()) {
<button
type="button"
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-secondary"
title="Minimize"
(click)="minimize()"
>
<ng-icon
name="lucideMinus"
class="w-4 h-4"
/>
</button>
<button
type="button"
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-secondary"
title="Maximize"
(click)="maximize()"
>
<ng-icon
name="lucideSquare"
class="w-4 h-4"
/>
</button>
<button
type="button"
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-destructive/10"
title="Close"
(click)="close()"
>
<ng-icon
name="lucideX"
class="w-4 h-4 text-destructive"
/>
</button>
}
</div>
</div>
<!-- Click-away overlay to close dropdown -->
@if (showMenu()) {
<div
class="fixed inset-0 z-40"
(click)="closeMenu()"
(keydown.enter)="closeMenu()"
(keydown.space)="closeMenu()"
tabindex="0"
role="button"
aria-label="Close menu overlay"
style="-webkit-app-region: no-drag"
></div>
}
@if (showLeaveConfirm() && currentRoom()) {
<app-leave-server-dialog
[room]="currentRoom()!"
[currentUser]="currentUser() ?? null"
(confirmed)="confirmLeave($event)"
(cancelled)="cancelLeave()"
/>
}