diff --git a/frontend/src/app/pages/altitude/chat/chat.component.html b/frontend/src/app/pages/altitude/chat/chat.component.html
index 8170bb8..0e9e0f1 100644
--- a/frontend/src/app/pages/altitude/chat/chat.component.html
+++ b/frontend/src/app/pages/altitude/chat/chat.component.html
@@ -6,6 +6,20 @@
+ @if (showFullscreenPrompt()) {
+
+
+
Enter fullscreen?
+
Would you like to view chat in fullscreen mode?
+
+
+
+
+
+
+
+ }
+
diff --git a/frontend/src/app/pages/altitude/chat/chat.component.scss b/frontend/src/app/pages/altitude/chat/chat.component.scss
index 7f357e8..6d18af0 100644
--- a/frontend/src/app/pages/altitude/chat/chat.component.scss
+++ b/frontend/src/app/pages/altitude/chat/chat.component.scss
@@ -1,3 +1,53 @@
+.fullscreen-prompt-backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: 10000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ background: rgb(0 0 0 / 70%);
+}
+
+.fullscreen-prompt {
+ width: min(420px, 100%);
+ padding: 24px;
+ border-radius: 14px;
+ background: #1f1f1f;
+ color: #ffffff;
+ box-shadow: 0 20px 60px rgb(0 0 0 / 45%);
+ text-align: center;
+
+ h2 {
+ margin: 0 0 10px;
+ }
+
+ p {
+ margin: 0 0 22px;
+ color: rgb(255 255 255 / 75%);
+ }
+}
+
+.fullscreen-prompt-actions {
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+
+ button {
+ cursor: pointer;
+ border: 0;
+ border-radius: 8px;
+ padding: 10px 16px;
+ background: #4f8cff;
+ color: #ffffff;
+ font-weight: 700;
+
+ &.secondary {
+ background: rgb(255 255 255 / 14%);
+ }
+ }
+}
+
.page-layout {
display: flex;
flex-direction: row;
diff --git a/frontend/src/app/pages/altitude/chat/chat.component.ts b/frontend/src/app/pages/altitude/chat/chat.component.ts
index 15cf10b..e351228 100644
--- a/frontend/src/app/pages/altitude/chat/chat.component.ts
+++ b/frontend/src/app/pages/altitude/chat/chat.component.ts
@@ -1,4 +1,4 @@
-import {Component, inject, OnDestroy, OnInit} from '@angular/core';
+import {AfterViewInit, Component, inject, OnDestroy, OnInit, signal} from '@angular/core';
import {Subscription} from 'rxjs';
import {ChatService} from '@pages/altitude/chat/service/chat.service';
import {HeaderComponent} from '@header/header.component';
@@ -21,12 +21,13 @@ import {ChatInfoComponent} from '@pages/altitude/chat/components/chat-info/chat-
styleUrl: './chat.component.scss',
providers: [MiniMessageInteractionService]
})
-export class ChatComponent implements OnInit, OnDestroy {
+export class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
private sub?: Subscription;
private readonly chatService: ChatService = inject(ChatService)
protected readonly messages = this.chatService.messages;
protected readonly servers = this.chatService.servers;
protected readonly selectedServer = this.chatService.selectedServer;
+ protected readonly showFullscreenPrompt = signal(true);
constructor(private interaction: MiniMessageInteractionService) {
interaction.clicks$.subscribe(({action, value}) => {
@@ -40,12 +41,39 @@ export class ChatComponent implements OnInit, OnDestroy {
this.chatService.selectServer(server);
}
+ protected enterFullscreen(): void {
+ this.showFullscreenPrompt.set(false);
+
+ if (!document.fullscreenElement) {
+ document.documentElement.requestFullscreen().catch(() => {
+ // Ignore fullscreen request failures.
+ });
+ }
+ }
+
+ protected skipFullscreen(): void {
+ this.showFullscreenPrompt.set(false);
+ }
+
+
ngOnInit(): void {
this.chatService.connect();
}
+ ngAfterViewInit(): void {
+ document.documentElement.requestFullscreen().catch(() => {
+ console.error('Failed to enter fullscreen');
+ });
+ }
+
ngOnDestroy(): void {
this.sub?.unsubscribe();
- this.chatService.disconnect(); // triggers onCompletion server-side, cleans up the emitter
+ this.chatService.disconnect();
+
+ if (document.fullscreenElement) {
+ document.exitFullscreen().catch(() => {
+ console.error('Failed to exit fullscreen');
+ });
+ }
}
}