mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 01:47:43 +00:00
191 lines
4.6 KiB
TypeScript
191 lines
4.6 KiB
TypeScript
import { LitElement, html, css } from 'lit';
|
|
import { customElement, property, state, query } from 'lit/decorators.js';
|
|
import { GameMap, GameType } from '../core/game/Game';
|
|
|
|
@customElement('join-private-lobby-modal')
|
|
export class JoinPrivateLobbyModal extends LitElement {
|
|
@state() private isModalOpen = false;
|
|
@state() private message: string = '';
|
|
@query('#lobbyIdInput') private lobbyIdInput!: HTMLInputElement;
|
|
@state() private hasJoined = false
|
|
|
|
static styles = css`
|
|
.modal-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
z-index: 1000;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
}
|
|
.modal-content {
|
|
background-color: white;
|
|
margin: 15% auto;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
width: 80%;
|
|
max-width: 500px;
|
|
text-align: center;
|
|
}
|
|
.close {
|
|
color: #aaa;
|
|
float: right;
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
cursor: pointer;
|
|
}
|
|
.close:hover,
|
|
.close:focus {
|
|
color: black;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
}
|
|
button {
|
|
padding: 10px 20px;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
background-color: #007bff;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
transition: background-color 0.3s;
|
|
}
|
|
button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
.lobby-id-container {
|
|
display: flex;
|
|
align-items: stretch;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
margin: 20px 0;
|
|
}
|
|
.lobby-id-container input {
|
|
flex-grow: 1;
|
|
max-width: 200px;
|
|
padding: 10px;
|
|
font-size: 16px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
}
|
|
.lobby-id-container button {
|
|
padding: 10px 15px;
|
|
}
|
|
.join-button {
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.message-area {
|
|
margin-top: 10px;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
transition: opacity 0.3s ease;
|
|
opacity: 0;
|
|
height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.message-area.show {
|
|
opacity: 1;
|
|
height: auto;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.message-area.error {
|
|
background-color: #ffebee;
|
|
color: #c62828;
|
|
}
|
|
|
|
.message-area.success {
|
|
background-color: #e8f5e9;
|
|
color: #2e7d32;
|
|
}
|
|
`;
|
|
|
|
render() {
|
|
return html`
|
|
<div class="modal-overlay" style="display: ${this.isModalOpen ? 'block' : 'none'}">
|
|
<div class="modal-content">
|
|
<span class="close" @click=${this.closeAndLeave}>×</span>
|
|
<h2>Join Private Lobby</h2>
|
|
<div class="lobby-id-container">
|
|
<input type="text" id="lobbyIdInput" placeholder="Enter Lobby ID">
|
|
<button @click=${this.pasteFromClipboard}>Paste</button>
|
|
</div>
|
|
<div class="message-area ${this.message ? 'show' : ''}">
|
|
${this.message}
|
|
</div>
|
|
${!this.hasJoined ? html`<button class="join-button" @click=${this.joinLobby}>Join Lobby</button>` : ''}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
public open() {
|
|
this.isModalOpen = true;
|
|
}
|
|
|
|
public close() {
|
|
this.isModalOpen = false;
|
|
this.lobbyIdInput.value = null
|
|
}
|
|
|
|
public closeAndLeave() {
|
|
this.close()
|
|
this.hasJoined = false
|
|
this.message = ""
|
|
this.dispatchEvent(new CustomEvent('leave-lobby', {
|
|
detail: { lobby: this.lobbyIdInput.value },
|
|
bubbles: true,
|
|
composed: true
|
|
}));
|
|
}
|
|
|
|
private async pasteFromClipboard() {
|
|
try {
|
|
const clipText = await navigator.clipboard.readText();
|
|
this.lobbyIdInput.value = clipText;
|
|
} catch (err) {
|
|
console.error('Failed to read clipboard contents: ', err);
|
|
}
|
|
}
|
|
|
|
private joinLobby() {
|
|
const lobbyId = this.lobbyIdInput.value;
|
|
console.log(`Joining lobby with ID: ${lobbyId}`);
|
|
this.message = 'Checking lobby...'; // Set initial message
|
|
|
|
fetch(`/lobby/${lobbyId}/exists`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.exists) {
|
|
this.message = 'Joined successfully! Waiting for game to start...';
|
|
this.hasJoined = true
|
|
this.dispatchEvent(new CustomEvent('join-lobby', {
|
|
detail: {
|
|
lobby: { id: lobbyId },
|
|
gameType: GameType.Private,
|
|
map: GameMap.World,
|
|
},
|
|
bubbles: true,
|
|
composed: true
|
|
}));
|
|
} else {
|
|
this.message = 'Lobby not found. Please check the ID and try again.';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error checking lobby existence:', error);
|
|
this.message = 'An error occurred. Please try again.';
|
|
});
|
|
}
|
|
|
|
} |