Cleaning up comments

This commit is contained in:
2026-03-06 05:21:41 +01:00
parent fe2347b54e
commit 10467dfccb
50 changed files with 51 additions and 885 deletions

View File

@@ -5,24 +5,6 @@ import {
HostListener
} from '@angular/core';
/**
* Reusable confirmation dialog modal.
*
* Usage:
* ```html
* @if (showConfirm()) {
* <app-confirm-dialog
* title="Delete Room?"
* confirmLabel="Delete"
* variant="danger"
* (confirmed)="onDelete()"
* (cancelled)="showConfirm.set(false)"
* >
* <p>This will permanently delete the room.</p>
* </app-confirm-dialog>
* }
* ```
*/
@Component({
selector: 'app-confirm-dialog',
standalone: true,
@@ -32,19 +14,12 @@ import {
}
})
export class ConfirmDialogComponent {
/** Dialog title. */
title = input.required<string>();
/** Label for the confirm button. */
confirmLabel = input<string>('Confirm');
/** Label for the cancel button. */
cancelLabel = input<string>('Cancel');
/** Visual style of the confirm button. */
variant = input<'primary' | 'danger'>('primary');
/** Tailwind width class for the dialog. */
widthClass = input<string>('w-[320px]');
/** Emitted when the user confirms. */
confirmed = output<undefined>();
/** Emitted when the user cancels (backdrop click, Cancel button, or Escape). */
cancelled = output<undefined>();
@HostListener('document:keydown.escape')

View File

@@ -10,30 +10,6 @@ import {
OnInit
} from '@angular/core';
/**
* Generic positioned context-menu overlay with automatic viewport clamping.
*
* Usage:
* ```html
* @if (showMenu()) {
* <app-context-menu [x]="menuX()" [y]="menuY()" (closed)="closeMenu()" [width]="'w-48'">
* <button (click)="doSomething()" class="context-menu-item">Action</button>
* </app-context-menu>
* }
* ```
*
* For pixel-based widths (e.g. sliders), use `[widthPx]` instead of `[width]`:
* ```html
* <app-context-menu [x]="menuX()" [y]="menuY()" [widthPx]="240" (closed)="closeMenu()">
* ...custom content...
* </app-context-menu>
* ```
*
* Built-in item classes are available via the host styles:
* - `.context-menu-item` - normal item
* - `.context-menu-item-danger` - destructive (red) item
* - `.context-menu-divider` - horizontal separator
*/
@Component({
selector: 'app-context-menu',
standalone: true,
@@ -42,34 +18,25 @@ import {
})
/* eslint-disable @typescript-eslint/member-ordering */
export class ContextMenuComponent implements OnInit, AfterViewInit {
/** Horizontal position (px from left). */
// eslint-disable-next-line id-length, id-denylist
x = input.required<number>();
/** Vertical position (px from top). */
// eslint-disable-next-line id-length, id-denylist
y = input.required<number>();
/** Tailwind width class for the panel (default `w-48`). Ignored when `widthPx` is set. */
width = input<string>('w-48');
/** Optional fixed width in pixels (overrides `width`). Useful for custom content like sliders. */
widthPx = input<number | null>(null);
/** Emitted when the menu should close (backdrop click or Escape). */
closed = output<undefined>();
@ViewChild('panel', { static: true }) panelRef!: ElementRef<HTMLDivElement>;
/** Viewport-clamped X position. */
clampedX = signal(0);
/** Viewport-clamped Y position. */
clampedY = signal(0);
ngOnInit(): void {
// Initial clamp with estimated dimensions
this.clampedX.set(this.clampX(this.x(), this.estimateWidth()));
this.clampedY.set(this.clampY(this.y(), 80));
}
ngAfterViewInit(): void {
// Refine with actual rendered dimensions
const rect = this.panelRef.nativeElement.getBoundingClientRect();
this.clampedX.set(this.clampX(this.x(), rect.width));
@@ -87,7 +54,6 @@ export class ContextMenuComponent implements OnInit, AfterViewInit {
if (px)
return px;
// Parse Tailwind w-XX class to approximate pixel width
const match = this.width().match(/w-(\d+)/);
return match ? parseInt(match[1], 10) * 4 : 192;

View File

@@ -13,7 +13,7 @@ import {
Room,
RoomMember,
User
} from '../../../core/models';
} from '../../../core/models/index';
export interface LeaveServerDialogResult {
nextOwnerKey?: string;

View File

@@ -1,20 +1,6 @@
import { NgOptimizedImage } from '@angular/common';
import { Component, input } from '@angular/core';
/**
* Reusable user avatar circle.
*
* Displays the user's image when `avatarUrl` is provided, otherwise
* falls back to a colored circle with the first letter of `name`.
*
* Optional rings (e.g. voice-state colours) can be applied via `ringClass`.
*
* Usage:
* ```html
* <app-user-avatar [name]="user.displayName" [avatarUrl]="user.avatarUrl" size="md" />
* <app-user-avatar [name]="user.displayName" size="sm" ringClass="ring-2 ring-green-500" />
* ```
*/
@Component({
selector: 'app-user-avatar',
standalone: true,
@@ -25,22 +11,16 @@ import { Component, input } from '@angular/core';
}
})
export class UserAvatarComponent {
/** Display name - first character is used as fallback initial. */
name = input.required<string>();
/** Optional avatar image URL. */
avatarUrl = input<string | undefined | null>();
/** Predefined size: `xs` (28px), `sm` (32px), `md` (40px), `lg` (48px). */
size = input<'xs' | 'sm' | 'md' | 'lg'>('sm');
/** Extra ring classes, e.g. `'ring-2 ring-green-500'`. */
ringClass = input<string>('');
/** Compute the first-letter initial. */
initial(): string {
return this.name()?.charAt(0)
?.toUpperCase() ?? '?';
}
/** Map size token to Tailwind dimension classes. */
sizeClasses(): string {
switch (this.size()) {
case 'xs': return 'w-7 h-7';
@@ -50,7 +30,6 @@ export class UserAvatarComponent {
}
}
/** Map size token to explicit pixel dimensions for image optimisation. */
sizePx(): number {
switch (this.size()) {
case 'xs': return 28;
@@ -60,7 +39,6 @@ export class UserAvatarComponent {
}
}
/** Map size token to text size for initials. */
textClass(): string {
switch (this.size()) {
case 'xs': return 'text-xs';

View File

@@ -11,27 +11,6 @@ import { lucideVolume2, lucideVolumeX } from '@ng-icons/lucide';
import { VoicePlaybackService } from '../../../features/voice/voice-controls/services/voice-playback.service';
import { ContextMenuComponent } from '../context-menu/context-menu.component';
/**
* Context-menu overlay that lets the local user adjust the playback
* volume of a specific remote voice-channel participant (0%-200%)
* and toggle per-user mute.
*
* Wraps `<app-context-menu>` for consistent positioning, backdrop,
* escape handling and viewport clamping.
*
* Usage:
* ```html
* @if (showVolumeMenu()) {
* <app-user-volume-menu
* [x]="menuX()"
* [y]="menuY()"
* [peerId]="targetPeerId()"
* [displayName]="targetName()"
* (closed)="showVolumeMenu.set(false)"
* />
* }
* ```
*/
@Component({
selector: 'app-user-volume-menu',
standalone: true,
@@ -42,17 +21,12 @@ import { ContextMenuComponent } from '../context-menu/context-menu.component';
})
/* eslint-disable @typescript-eslint/member-ordering */
export class UserVolumeMenuComponent implements OnInit {
/** Horizontal position (px from left). */
// eslint-disable-next-line id-length, id-denylist
x = input.required<number>();
/** Vertical position (px from top). */
// eslint-disable-next-line id-length, id-denylist
y = input.required<number>();
/** Remote peer identifier (oderId). */
peerId = input.required<string>();
/** Display name shown in the header. */
displayName = input.required<string>();
/** Emitted when the menu should close. */
closed = output<undefined>();
private playback = inject(VoicePlaybackService);