feat(ui): Modals vue
Readded modals with vue syntax. Removed not working alert component. Cleaned up.
This commit is contained in:
@@ -1,54 +1,4 @@
|
|||||||
var canPlayCard = false;
|
var canPlayCard = false;
|
||||||
var isInitialized = false;
|
|
||||||
const AlertsComponent = {
|
|
||||||
template: `
|
|
||||||
<div class="fixed-top d-flex flex-column align-items-center mt-3" style="z-index: 1050; pointer-events: none;">
|
|
||||||
<div v-for="alert in alerts" :key="alert.id" class="alert-item">
|
|
||||||
<div
|
|
||||||
class="alert alert-primary d-flex align-items-center p-2 mb-2 w-auto shadow-sm"
|
|
||||||
role="alert"
|
|
||||||
style="width: 25rem; pointer-events: all;">
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="bi flex-shrink-0 me-2" viewBox="0 0 16 16" role="img" aria-label="Warning:">
|
|
||||||
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
|
|
||||||
</svg>
|
|
||||||
<div class="small">
|
|
||||||
<small>{{ alert.message }}</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
alerts: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
alertMessage(message) {
|
|
||||||
const alertData = {
|
|
||||||
id: Date.now(),
|
|
||||||
message: message,
|
|
||||||
isVisible: true,
|
|
||||||
};
|
|
||||||
this.alerts.push(alertData);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.removeAlert(alertData.id);
|
|
||||||
}, 5000);
|
|
||||||
},
|
|
||||||
removeAlert(id) {
|
|
||||||
const index = this.alerts.findIndex(alert => alert.id === id);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.alerts.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const PlayerHandComponent = {
|
const PlayerHandComponent = {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -230,11 +180,7 @@ const ScoreBoardComponent = {
|
|||||||
|
|
||||||
this.playerScores = this.calculateNewScores(playersin, tricklist);
|
this.playerScores = this.calculateNewScores(playersin, tricklist);
|
||||||
|
|
||||||
if (typeof globalThis.alertMessage === 'function') {
|
|
||||||
globalThis.alertMessage(`${playerwon} won the trick!`);
|
|
||||||
} else {
|
|
||||||
console.error("ALERT MESSAGE FAILED: globalThis.alertMessage is NOT a function.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -370,13 +316,23 @@ const LobbyComponent = {
|
|||||||
isHost: false,
|
isHost: false,
|
||||||
maxPlayers: 0,
|
maxPlayers: 0,
|
||||||
players: [],
|
players: [],
|
||||||
|
showKickedModal: false,
|
||||||
|
kickedEventData: null,
|
||||||
|
showSessionClosedModal: false,
|
||||||
|
sessionClosedEventData: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
template: `
|
template: `
|
||||||
<main class="lobby-background vh-100" id="lobbybackground">
|
<main class="lobby-background vh-100" id="lobbybackground">
|
||||||
|
|
||||||
<div class="modal fade" data-backdrop="static" data-keyboard="false" data-focus="true" id="kickedModal" tabindex="-1" role="dialog" aria-labelledby="kickedModalTitle">
|
<div v-if="showKickedModal" class="modal fade show d-block"
|
||||||
|
tabindex="-1"
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="kickedModalTitle"
|
||||||
|
aria-modal="true"
|
||||||
|
style="background-color: rgba(0,0,0,0.5);">
|
||||||
|
|
||||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@@ -384,12 +340,19 @@ const LobbyComponent = {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>You've been kicked from the lobby.</p>
|
<p>You've been kicked from the lobby.</p>
|
||||||
|
<p class="text-muted small">You'll get redirected to the mainmenu in 5 seconds...</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" data-backdrop="static" data-keyboard="false" data-focus="true" id="sessionClosed" tabindex="-1" role="dialog" aria-labelledby="sessionClosedModalTitle">
|
|
||||||
|
<div v-if="showSessionClosedModal" class="modal fade show d-block"
|
||||||
|
tabindex="-1"
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="sessionClosedModalTitle"
|
||||||
|
aria-modal="true"
|
||||||
|
style="background-color: rgba(0,0,0,0.5);">
|
||||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@@ -397,6 +360,7 @@ const LobbyComponent = {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>The session was closed.</p>
|
<p>The session was closed.</p>
|
||||||
|
<p class="text-muted small">You'll get redirected to the mainmenu in 5 seconds...</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -499,18 +463,40 @@ const LobbyComponent = {
|
|||||||
},
|
},
|
||||||
handleKickPlayer(playerId) {
|
handleKickPlayer(playerId) {
|
||||||
globalThis.handleKickPlayer(playerId)
|
globalThis.handleKickPlayer(playerId)
|
||||||
|
},
|
||||||
|
showKickModal(eventData) {
|
||||||
|
this.showKickedModal = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.kickedEventData = eventData;
|
||||||
|
this.showKickedModal = false;
|
||||||
|
|
||||||
|
if (typeof globalThis.receiveGameStateChange === 'function') {
|
||||||
|
globalThis.receiveGameStateChange(this.kickedEventData);
|
||||||
|
} else {
|
||||||
|
console.error("FATAL: receiveGameStateChange ist nicht global definiert.");
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
showSessionClosedModal(eventData) {
|
||||||
|
this.sessionClosedEventData = eventData;
|
||||||
|
this.showSessionClosedModal = true;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSessionClosedModal = false;
|
||||||
|
|
||||||
|
if (typeof globalThis.receiveGameStateChange === 'function') {
|
||||||
|
globalThis.receiveGameStateChange(this.sessionClosedEventData);
|
||||||
|
} else {
|
||||||
|
console.error("FATAL: receiveGameStateChange ist nicht global definiert.");
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function requestCardEvent(eventData) {
|
function requestCardEvent(eventData) {
|
||||||
const player = eventData.player;
|
//TODO: Needs correct implementation of setting the inactive class in the PlayerHandComponent
|
||||||
const handElement = $('#card-slide')
|
|
||||||
handElement.removeClass('inactive');
|
|
||||||
canPlayCard = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function receiveGameStateChange(eventData) {
|
function receiveGameStateChange(eventData) {
|
||||||
const content = eventData.content;
|
const content = eventData.content;
|
||||||
const title = eventData.title || 'Knockout Whist';
|
const title = eventData.title || 'Knockout Whist';
|
||||||
@@ -518,77 +504,8 @@ function receiveGameStateChange(eventData) {
|
|||||||
|
|
||||||
exchangeBody(content, title, url);
|
exchangeBody(content, title, url);
|
||||||
}
|
}
|
||||||
function receiveLobbyUpdateEvent(eventData) {
|
|
||||||
const host = eventData.host;
|
|
||||||
const maxPlayers = eventData.maxPlayers;
|
|
||||||
const players = eventData.players;
|
|
||||||
|
|
||||||
const lobbyPlayersContainer = $('#players');
|
|
||||||
const playerAmountBox = $('#playerAmount');
|
|
||||||
|
|
||||||
let newHtml = ''
|
|
||||||
|
|
||||||
if (host) {
|
|
||||||
players.forEach(user => {
|
|
||||||
|
|
||||||
const inner = user.self ? `<h5 class="card-title">${user.name} (You)</h5>
|
|
||||||
<a href="#" class="btn btn-danger disabled" aria-disabled="true" tabindex="-1">Remove</a>`
|
|
||||||
: ` <h5 class="card-title">${user.name}</h5>
|
|
||||||
<div class="btn btn-danger" onclick="handleKickPlayer('${user.id}')">Remove</div>`
|
|
||||||
|
|
||||||
newHtml += `<div class="col-auto my-auto m-3">
|
|
||||||
<div class="card" style="width: 18rem;">
|
|
||||||
<img src="/assets/images/profile.png" alt="Profile" class="card-img-top w-50 mx-auto mt-3" />
|
|
||||||
<div class="card-body">
|
|
||||||
${inner}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
players.forEach(user => {
|
|
||||||
|
|
||||||
const inner = user.self ? `<h5 class="card-title">${user.name} (You)</h5>` : ` <h5 class="card-title">${user.name}</h5>`
|
|
||||||
|
|
||||||
newHtml += `<div class="col-auto my-auto m-3">
|
|
||||||
<div class="card" style="width: 18rem;">
|
|
||||||
<img src="/assets/images/profile.png" alt="Profile" class="card-img-top w-50 mx-auto mt-3" />
|
|
||||||
<div class="card-body">
|
|
||||||
${inner}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
lobbyPlayersContainer.html(newHtml);
|
|
||||||
playerAmountBox.text(`Players: ${players.length} / ${maxPlayers}`);
|
|
||||||
|
|
||||||
}
|
|
||||||
function receiveKickEvent(eventData) {
|
|
||||||
$('#kickedModal').modal({
|
|
||||||
backdrop: 'static',
|
|
||||||
keyboard: false
|
|
||||||
}).modal('show');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
receiveGameStateChange(eventData)
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
function receiveSessionClosedEvent(eventData) {
|
|
||||||
$('#sessionClosed').modal({
|
|
||||||
backdrop: 'static',
|
|
||||||
keyboard: false
|
|
||||||
}).modal('show');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
receiveGameStateChange(eventData)
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
function receiveRoundEndEvent(eventData) {
|
function receiveRoundEndEvent(eventData) {
|
||||||
const player = eventData.player
|
//TODO: When alert is working, set an alert that shows how won the round and with how much tricks.
|
||||||
const tricks = eventData.tricks
|
|
||||||
alertMessage(`${player} won this round with ${tricks} tricks!`)
|
|
||||||
}
|
}
|
||||||
let playerHandApp = null;
|
let playerHandApp = null;
|
||||||
let scoreBoardApp = null;
|
let scoreBoardApp = null;
|
||||||
@@ -596,19 +513,7 @@ let gameInfoApp = null;
|
|||||||
let trickDisplayApp = null;
|
let trickDisplayApp = null;
|
||||||
let turnApp = null;
|
let turnApp = null;
|
||||||
globalThis.initGameVueComponents = function() {
|
globalThis.initGameVueComponents = function() {
|
||||||
// --- 1. CLEANUP (If already initialized) ---
|
// Initializing PlayerHandComponent
|
||||||
if (playerHandApp) {
|
|
||||||
console.log("Updating Hand View. Unmounting previous instance.");
|
|
||||||
|
|
||||||
playerHandApp.unmount();
|
|
||||||
|
|
||||||
globalThis.updatePlayerHand = undefined;
|
|
||||||
|
|
||||||
onEvent("ReceivedHandEvent", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 2. INITIALIZATION/RE-INITIALIZATION ---
|
|
||||||
|
|
||||||
const app = Vue.createApp(PlayerHandComponent);
|
const app = Vue.createApp(PlayerHandComponent);
|
||||||
|
|
||||||
playerHandApp = app;
|
playerHandApp = app;
|
||||||
@@ -622,7 +527,7 @@ globalThis.initGameVueComponents = function() {
|
|||||||
console.error("FATAL ERROR: PlayerHandComponent mount failed. Check if #player-hand-container exists.");
|
console.error("FATAL ERROR: PlayerHandComponent mount failed. Check if #player-hand-container exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 3. Initialize Scoreboard ---
|
// Initializing Scoreboard
|
||||||
if (scoreBoardApp) return
|
if (scoreBoardApp) return
|
||||||
|
|
||||||
const app2 = Vue.createApp(ScoreBoardComponent)
|
const app2 = Vue.createApp(ScoreBoardComponent)
|
||||||
@@ -638,7 +543,7 @@ globalThis.initGameVueComponents = function() {
|
|||||||
} else {
|
} else {
|
||||||
console.error("FATAL ERROR: Scoreboard mount failed. Check if #score-table exists.");
|
console.error("FATAL ERROR: Scoreboard mount failed. Check if #score-table exists.");
|
||||||
}
|
}
|
||||||
// --- 4. Initialize Gameinfo ---
|
// Initializing Gameinfo
|
||||||
if (gameInfoApp) return
|
if (gameInfoApp) return
|
||||||
|
|
||||||
const app3 = Vue.createApp(GameInfoComponent)
|
const app3 = Vue.createApp(GameInfoComponent)
|
||||||
@@ -654,7 +559,7 @@ globalThis.initGameVueComponents = function() {
|
|||||||
console.error("FATAL ERROR: GameInfo mount failed. Check if #score-table exists.");
|
console.error("FATAL ERROR: GameInfo mount failed. Check if #score-table exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- 5. Initialize TrickCardContainer ---
|
// Initializing TrickCardContainer
|
||||||
if (trickDisplayApp) return;
|
if (trickDisplayApp) return;
|
||||||
const app4 = Vue.createApp(TrickDisplayComponent);
|
const app4 = Vue.createApp(TrickDisplayComponent);
|
||||||
trickDisplayApp = app4;
|
trickDisplayApp = app4;
|
||||||
@@ -669,7 +574,7 @@ globalThis.initGameVueComponents = function() {
|
|||||||
console.error("FATAL ERROR: TrickDisplay mount failed. Check if #trick-cards-container exists.");
|
console.error("FATAL ERROR: TrickDisplay mount failed. Check if #trick-cards-container exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 6. Initialize TurnContainer ---
|
// Initializing TurnContainer
|
||||||
if (turnApp) return;
|
if (turnApp) return;
|
||||||
const app5 = Vue.createApp(TurnComponent)
|
const app5 = Vue.createApp(TurnComponent)
|
||||||
turnApp = app5;
|
turnApp = app5;
|
||||||
@@ -695,6 +600,7 @@ globalThis.initLobbyVueComponents = function(initialLobbyName, initialLobbyId, i
|
|||||||
if (mountedLobby) {
|
if (mountedLobby) {
|
||||||
mountedLobby.setInitialData(initialLobbyName, initialLobbyId);
|
mountedLobby.setInitialData(initialLobbyName, initialLobbyId);
|
||||||
|
|
||||||
|
//Damit beim erstmaligen Betreten der Lobby die Spieler etc. angezeigt werden.
|
||||||
mountedLobby.updateLobbyData({
|
mountedLobby.updateLobbyData({
|
||||||
host: initialIsHost,
|
host: initialIsHost,
|
||||||
maxPlayers: initialMaxPlayers,
|
maxPlayers: initialMaxPlayers,
|
||||||
@@ -702,9 +608,11 @@ globalThis.initLobbyVueComponents = function(initialLobbyName, initialLobbyId, i
|
|||||||
});
|
});
|
||||||
|
|
||||||
globalThis.updateLobbyData = mountedLobby.updateLobbyData;
|
globalThis.updateLobbyData = mountedLobby.updateLobbyData;
|
||||||
|
globalThis.showKickModal = mountedLobby.showKickModal;
|
||||||
|
globalThis.showSessionClosedModal = mountedLobby.showSessionClosedModal;
|
||||||
onEvent("LobbyUpdateEvent", globalThis.updateLobbyData);
|
onEvent("LobbyUpdateEvent", globalThis.updateLobbyData);
|
||||||
|
onEvent("KickEvent", globalThis.showKickModal);
|
||||||
|
onEvent("SessionClosed", globalThis.showSessionClosedModal);
|
||||||
console.log("LobbyComponent successfully mounted and registered events.");
|
console.log("LobbyComponent successfully mounted and registered events.");
|
||||||
} else {
|
} else {
|
||||||
console.error("FATAL ERROR: LobbyComponent mount failed.");
|
console.error("FATAL ERROR: LobbyComponent mount failed.");
|
||||||
@@ -740,8 +648,6 @@ function handleNewRoundEvent(eventData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onEvent("GameStateChangeEvent", receiveGameStateChange)
|
onEvent("GameStateChangeEvent", receiveGameStateChange)
|
||||||
onEvent("RequestCardEvent", requestCardEvent)
|
|
||||||
onEvent("LeftEvent", receiveGameStateChange)
|
onEvent("LeftEvent", receiveGameStateChange)
|
||||||
onEvent("KickEvent", receiveKickEvent)
|
onEvent("RequestCardEvent", requestCardEvent)
|
||||||
onEvent("SessionClosed", receiveSessionClosedEvent)
|
|
||||||
onEvent("RoundEndEvent", receiveRoundEndEvent)
|
onEvent("RoundEndEvent", receiveRoundEndEvent)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
|
||||||
function handlePlayCard(cardidx) {
|
function handlePlayCard(cardidx) {
|
||||||
|
//TODO: Needs implementation
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
function handleSkipDogLife(button) {
|
function handleSkipDogLife(button) {
|
||||||
// TODO needs implementation
|
// TODO needs implementation
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user