update
This commit is contained in:
@@ -173,6 +173,7 @@ router.get("/games", async (req, res) => {
|
|||||||
* is_local: false
|
* is_local: false
|
||||||
* current_playing_user: 1
|
* current_playing_user: 1
|
||||||
* turn_order: null
|
* turn_order: null
|
||||||
|
* creator: 1
|
||||||
*/
|
*/
|
||||||
router.get("/games/:id", asyncHandler(async (req, res) => {
|
router.get("/games/:id", asyncHandler(async (req, res) => {
|
||||||
const gameId = parseInt(req.params.id, 10);
|
const gameId = parseInt(req.params.id, 10);
|
||||||
@@ -182,7 +183,7 @@ router.get("/games/:id", asyncHandler(async (req, res) => {
|
|||||||
if (!games.length) throw new ApiError(404, "Game not found");
|
if (!games.length) throw new ApiError(404, "Game not found");
|
||||||
|
|
||||||
const [creatorRows] = await pool.query(
|
const [creatorRows] = await pool.query(
|
||||||
`SELECT u.id, u.username
|
`SELECT u.id
|
||||||
FROM game_players gp
|
FROM game_players gp
|
||||||
JOIN users u ON gp.user = u.id
|
JOIN users u ON gp.user = u.id
|
||||||
WHERE gp.game = ? AND gp.is_creator = TRUE
|
WHERE gp.game = ? AND gp.is_creator = TRUE
|
||||||
@@ -190,7 +191,7 @@ router.get("/games/:id", asyncHandler(async (req, res) => {
|
|||||||
[gameId]
|
[gameId]
|
||||||
);
|
);
|
||||||
|
|
||||||
const creator = creatorRows.lenght ? creatorRows[0] : null;
|
const creator = creatorRows.length ? creatorRows[0].id : null;
|
||||||
|
|
||||||
res.json({ ...games[0], creator});
|
res.json({ ...games[0], creator});
|
||||||
}));
|
}));
|
||||||
@@ -388,7 +389,7 @@ router.patch("/games/:id/lock", asyncHandler(async (req, res) => {
|
|||||||
const currentPlayingUser = turnOrder[0];
|
const currentPlayingUser = turnOrder[0];
|
||||||
await conn.query(
|
await conn.query(
|
||||||
"UPDATE current_games SET is_open = FALSE, turn_order = ?, current_playing_user = ? WHERE id = ?",
|
"UPDATE current_games SET is_open = FALSE, turn_order = ?, current_playing_user = ? WHERE id = ?",
|
||||||
[JSON.stringify(turnOrder), gameId, currentPlayingUser]
|
[JSON.stringify(turnOrder), currentPlayingUser, gameId]
|
||||||
);
|
);
|
||||||
|
|
||||||
await conn.commit();
|
await conn.commit();
|
||||||
|
|||||||
@@ -73,6 +73,12 @@
|
|||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
|
<q-item clickable v-ripple to="/game/online/join">
|
||||||
|
<q-item-section>
|
||||||
|
Join Online Game
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
<q-item clickable v-ripple to="/game">
|
<q-item clickable v-ripple to="/game">
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
Game
|
Game
|
||||||
|
|||||||
@@ -1,7 +1,168 @@
|
|||||||
<template>
|
<template>
|
||||||
CreateOnlineGame
|
<div class="q-pa-md flex flex-center">
|
||||||
|
<q-card
|
||||||
|
class="q-pa-lg shadow-3"
|
||||||
|
style="width: 400px; max-width: 90vw; border-radius: 16px;"
|
||||||
|
>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6 q-mt-md">Online Game</div>
|
||||||
|
|
||||||
|
<div class="text-subtitle2 text-black">
|
||||||
|
Game ID: {{ gameID }}
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6 q-mt-md">Players:</div>
|
||||||
|
|
||||||
|
<li v-for="plr in gamePlayers" :key="plr.username">
|
||||||
|
<div class="text-subtitle2 text-black">{{ plr.username }}</div>
|
||||||
|
</li>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-actions align="center">
|
||||||
|
<q-btn
|
||||||
|
v-if="gameCreator === user.id"
|
||||||
|
label="Start Game!"
|
||||||
|
color="primary"
|
||||||
|
@click="startGame"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
//
|
import { ref, onMounted, onUnmounted } from "vue";
|
||||||
|
import { useQuasar, LocalStorage } from "quasar";
|
||||||
|
import { api } from 'src/boot/axios';
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const $q = useQuasar();
|
||||||
|
const gameID = ref();
|
||||||
|
const gameCreator = ref(null);
|
||||||
|
const gamePlayers = ref([]);
|
||||||
|
const user = ref({ username:"", id:0 });
|
||||||
|
var canUpdate = false
|
||||||
|
|
||||||
|
const storedUser = LocalStorage.getItem("user")
|
||||||
|
if (storedUser) {
|
||||||
|
console.log(storedUser)
|
||||||
|
user.value = storedUser
|
||||||
|
} else {
|
||||||
|
router.push("/user/username")
|
||||||
|
}
|
||||||
|
|
||||||
|
const storedgameID = LocalStorage.getItem("gameID")
|
||||||
|
if (storedgameID) {
|
||||||
|
console.log(storedgameID)
|
||||||
|
gameID.value = storedgameID
|
||||||
|
|
||||||
|
api.get(`/api/games/${gameID.value}`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
|
gameCreator.value = response.data.creator
|
||||||
|
|
||||||
|
canUpdate = true
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
router.push("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update() {
|
||||||
|
if (!canUpdate) {return}
|
||||||
|
|
||||||
|
api.get(`/api/games/${gameID.value}/players`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
gamePlayers.value = response.data
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
api.get(`/api/games/${gameID.value}`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
if (!response.data.is_open) {
|
||||||
|
router.push("/game")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startGame() {
|
||||||
|
|
||||||
|
api.patch(`/api/games/${gameID.value}/lock`, {
|
||||||
|
user: user.value.id
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "positive",
|
||||||
|
message: "Success!",
|
||||||
|
});
|
||||||
|
|
||||||
|
router.push("/game")
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let intervalId = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
update()
|
||||||
|
|
||||||
|
intervalId = setInterval(update, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
96
frontend/src/pages/game/joinOnlineGamePage.vue
Normal file
96
frontend/src/pages/game/joinOnlineGamePage.vue
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<div class="q-pa-md flex flex-center">
|
||||||
|
<q-card
|
||||||
|
class="q-pa-lg shadow-3"
|
||||||
|
style="width: 400px; max-width: 90vw; border-radius: 16px;"
|
||||||
|
>
|
||||||
|
|
||||||
|
<q-card-section class="text-center">
|
||||||
|
<div class="text-h6 q-mt-md">Enter Game ID</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section>
|
||||||
|
<q-input
|
||||||
|
v-model="gameID"
|
||||||
|
filled
|
||||||
|
label="Game ID"
|
||||||
|
type="number"
|
||||||
|
dense
|
||||||
|
style="border-radius: 6px;"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<q-icon name="public" />
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="center">
|
||||||
|
<q-btn
|
||||||
|
label="Go!"
|
||||||
|
color="primary"
|
||||||
|
@click="joinGame"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useQuasar, LocalStorage } from "quasar";
|
||||||
|
import { api } from 'src/boot/axios';
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const $q = useQuasar();
|
||||||
|
const gameID = ref();
|
||||||
|
const user = ref({ username:"", id:0 });
|
||||||
|
|
||||||
|
const storedUser = LocalStorage.getItem("user")
|
||||||
|
if (storedUser) {
|
||||||
|
console.log(storedUser)
|
||||||
|
user.value = storedUser
|
||||||
|
} else {
|
||||||
|
router.push("/user/username")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function joinGame() {
|
||||||
|
if (!gameID.value) {
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: "Please enter a Game ID!",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.post(`/api/games/${gameID.value}/players`, {
|
||||||
|
user: user.value.id
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
|
LocalStorage.setItem("gameID", gameID.value)
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "positive",
|
||||||
|
message: "Success!",
|
||||||
|
});
|
||||||
|
|
||||||
|
router.push("/game/online/create")
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,83 @@
|
|||||||
<template>
|
<template>
|
||||||
Settings
|
<div class="q-pa-lg">
|
||||||
|
<q-card flat bordered class="shadow-2" style="max-width:600px; margin: 0 auto; border-radius:12px;">
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6">User Settings</div>
|
||||||
|
|
||||||
|
<div class="text-subtitle2 text-black">
|
||||||
|
Username: <span class="text-subtitle2 text-grey">{{ user.username }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-subtitle2 text-black">
|
||||||
|
ID: <span class="text-subtitle2 text-grey">{{ user.id }}</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-section>
|
||||||
|
<div class="q-gutter-md">
|
||||||
|
|
||||||
|
<div class="text-h8">Input method</div>
|
||||||
|
|
||||||
|
<q-btn-dropdown color="primary" :label="selected">
|
||||||
|
<q-list>
|
||||||
|
<q-item
|
||||||
|
v-for="opt in options"
|
||||||
|
:key="opt"
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
@click="selectOption(opt)"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ opt }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-btn-dropdown>
|
||||||
|
|
||||||
|
<div class="text-h8">Dart Picker Offset</div>
|
||||||
|
<div class="text-h8">Dart Picker Darts Colours</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-actions align="right">
|
||||||
|
<q-btn flat label="Cancel" @click="resetForm" />
|
||||||
|
<q-btn color="primary" label="Save changes" unelevated @click="onSave" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
//
|
import { ref } from 'vue'
|
||||||
|
import { useQuasar, LocalStorage } from 'quasar'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const $q = useQuasar();
|
||||||
|
const options = ['Dart Picker', 'Numbers']
|
||||||
|
const selected = ref('Input method')
|
||||||
|
const user = ref({ username:"", id:0 });
|
||||||
|
|
||||||
|
const storedUser = LocalStorage.getItem("user")
|
||||||
|
if (storedUser) {
|
||||||
|
console.log(storedUser)
|
||||||
|
user.value = storedUser
|
||||||
|
} else {
|
||||||
|
router.push("/user/username")
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOption(opt) {
|
||||||
|
selected.value = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetForm () {
|
||||||
|
$q.notify({ message: 'Changes discarded', color: 'negative' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSave () {
|
||||||
|
$q.notify({ message: 'Settings saved', color: 'positive' })
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -75,7 +75,7 @@ async function setUsername() {
|
|||||||
message: "Success!",
|
message: "Success!",
|
||||||
});
|
});
|
||||||
|
|
||||||
router.push("/game/select")
|
router.push("/")
|
||||||
})
|
})
|
||||||
|
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const routes = [
|
|||||||
{ path: 'game/select', component: () => import('pages/game/gameModeSelectPage.vue') },
|
{ path: 'game/select', component: () => import('pages/game/gameModeSelectPage.vue') },
|
||||||
{ path: 'game/local/create', component: () => import('pages/game/createLocalGamePage.vue') },
|
{ path: 'game/local/create', component: () => import('pages/game/createLocalGamePage.vue') },
|
||||||
{ path: 'game/online/create', component: () => import('pages/game/createOnlineGamePage.vue') },
|
{ path: 'game/online/create', component: () => import('pages/game/createOnlineGamePage.vue') },
|
||||||
|
{ path: 'game/online/join', component: () => import('pages/game/joinOnlineGamePage.vue') },
|
||||||
|
|
||||||
{ path: 'error', component: () => import('pages/ErrorPage.vue') }
|
{ path: 'error', component: () => import('pages/ErrorPage.vue') }
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user