Implement (somewhat) functional resource bar

This commit is contained in:
Aelita4 2024-01-30 10:00:43 +01:00
parent 2945828935
commit 564a3942a3
Signed by: Aelita4
GPG Key ID: E44490C2025906C1
14 changed files with 277 additions and 74 deletions

View File

@ -1,32 +1,174 @@
---
import { ObjectId } from 'mongodb';
import { getUserResources } from '../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../lib/lang/langDriver';
interface Props {
loggedIn: string;
import resourceTypes from '../lib/data/resources.json';
const resourceLang = await getLocales(getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), 'resources');
const resources = await getUserResources(new ObjectId(Astro.cookies.get('userid')?.value ?? ''));
const resourceArray = [];
for(const key in resources) {
resourceArray.push({
name: key,
amount: resources[key as never]
});
}
const lang = await getLocales(getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), 'resourcebar');
// const { loggedIn } = Astro.props;
---
<div id="resourcebar">
<div>
<!-- <div style="width: 64px; height: 64px; background-color: red; margin: 10px; border-radius: 10px;"></div> -->
<div>coal</div>
<div class="resourcebar-item-identifier">
<div class="resourcebar-circle-id" data-type="solid"></div>
</div>
<div id="resourcebar-elements" class="resourcebar-elements">
{resourceArray.map(res =>
<div class="resourcebar-item" data-res-type={resourceTypes.find(x => x.name === res.name)?.type ?? "solid"} style={(resourceTypes.find(x => x.name === res.name)?.type ?? "solid") === "solid" ? "" : "display: none;"}>
<div class="resourcebar-item-icon">
<img src={resourceTypes.find(x => x.name === res.name)?.icon ?? "#"} alt={res.name} />
</div>
<div class="resourcebar-item-text-wrapper" data-resname={res.name}>
<div class="resourcebar-item-text">{resourceLang[`Label_${res.name}`]}</div>
<div class="resourcebar-item-amount">{res.amount}</div>
</div>
</div>
)}
</div>
</div>
<style>
/* #resourcebar {
color: pink;
#resourcebar {
color: white;
background-color: blueviolet;
border-radius: 15px;
margin-top: 20px;
display: flex;
flex-direction: row;
}
#resourcebar ul {
.resourcebar-item-identifier {
left: 25px;
flex-shrink: 0;
margin-left: 25px;
}
.resourcebar-circle-id {
width: 50px;
height: 50px;
background-color: #0f0;
border-radius: 25px;
margin-right: 8px;
margin-top: 8px;
margin-bottom: 8px;
}
.resourcebar-elements {
flex-grow: 1;
display: flex;
flex-direction: row;
justify-content: space-evenly;
}
.resourcebar-item {
list-style: none;
display: flex;
flex-direction: row;
padding-left: 15px;
} */
</style>
}
.resourcebar-item-icon {
width: 50px;
height: 50px;
margin-right: 8px;
margin-top: 8px;
margin-bottom: 8px;
}
.resourcebar-item-icon img {
width: 100%;
}
.resourcebar-item-text-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
}
.resourcebar-item-text {
font-size: 1.5em;
}
.resourcebar-item-amount {
font-size: 1.2em;
}
</style>
<script>
setInterval(() => {
const resourcebar = document.getElementById('resourcebar');
const resourcebarItems = resourcebar?.querySelectorAll('.resourcebar-item');
const perSecondProduction = {
"coal": 10,
"iron": 15,
"gold": 20,
"water": 5,
"sulfuricAcid": 1,
"liquidNitrogen": 2,
"hydrogen": 5,
"oxygen": 50,
"helium3": 1
}
resourcebarItems?.forEach(item => {
const resourceName = (item.querySelector('.resourcebar-item-text-wrapper') as HTMLElement)?.dataset.resname ?? '';
const resourceAmount = parseInt(item.querySelector('.resourcebar-item-amount')?.innerHTML ?? '0');
const element = item.querySelector('.resourcebar-item-amount');
if(!element) return;
element.innerHTML = (resourceAmount + perSecondProduction[resourceName as never]).toString();
})
}, 1_000);
document.querySelector(".resourcebar-item-identifier")?.addEventListener("click", () => {
switch((document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement)?.dataset.type) {
case "solid":
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).dataset.type = "liquid";
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).style.backgroundColor = "#00f";
(document.getElementById("resourcebar-elements")?.querySelectorAll(".resourcebar-item") as NodeListOf<HTMLElement>).forEach(item => {
if(item.dataset.resType === "liquid") {
item.style.display = "";
} else {
item.style.display = "none";
}
});
break;
case "liquid":
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).dataset.type = "gas";
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).style.backgroundColor = "#ff0";
(document.getElementById("resourcebar-elements")?.querySelectorAll(".resourcebar-item") as NodeListOf<HTMLElement>).forEach(item => {
if(item.dataset.resType === "gas") {
item.style.display = "";
} else {
item.style.display = "none";
}
});
break;
case "gas":
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).dataset.type = "solid";
(document.querySelector(".resourcebar-item-identifier")?.children[0] as HTMLElement).style.backgroundColor = "#0f0";
(document.getElementById("resourcebar-elements")?.querySelectorAll(".resourcebar-item") as NodeListOf<HTMLElement>).forEach(item => {
if(item.dataset.resType === "solid") {
item.style.display = "";
} else {
item.style.display = "none";
}
});
break;
}
});
</script>

View File

@ -0,0 +1,49 @@
[
{
"name": "coal",
"type": "solid",
"icon": "https://gamepedia.cursecdn.com/minecraft_gamepedia/5/58/Coal_JE4_BE3.png"
},
{
"name": "iron",
"type": "solid",
"icon": "https://vignette.wikia.nocookie.net/minecraft/images/e/e8/New_Iron_IngotB.png/revision/latest?cb=20190520101024"
},
{
"name": "gold",
"type": "solid",
"icon": "https://gamepedia.cursecdn.com/minecraft_gamepedia/5/57/Gold_Ingot_JE3_BE2.png"
},
{
"name": "water",
"type": "liquid",
"icon": "https://ael.ovh/uranium.png"
},
{
"name": "sulfuricAcid",
"type": "liquid",
"icon": "https://ael.ovh/uranium.png"
},
{
"name": "liquidNitrogen",
"type": "liquid",
"icon": "https://ael.ovh/uranium.png"
},
{
"name": "hydrogen",
"type": "gas",
"icon": "https://ael.ovh/uranium.png"
},
{
"name": "oxygen",
"type": "gas",
"icon": "https://ael.ovh/uranium.png"
},
{
"name": "helium3",
"type": "gas",
"icon": "https://ael.ovh/uranium.png"
}
]

View File

@ -39,9 +39,9 @@ export const getUserByAccessToken = async(accessToken: string | AccessToken): Pr
} else return getUserById(accessToken.user as ObjectId)
}
export const getUserResources = async (username: string): Promise<Resources> => {
export const getUserResources = async (id: ObjectId): Promise<Resources> => {
const users = await Users();
const user = await users.findOne({ username });
const user = await users.findOne({ _id: id });
const defaultResources: Resources = {
coal: 0,

View File

@ -1,7 +1,15 @@
{
"Label": {
"coal": "Coal",
"iron": "Iron",
"gold": "Gold"
"coal": "Coal (C)",
"iron": "Iron (Fe)",
"gold": "Gold (Au)",
"water": "Water (H₂O)",
"sulfuricAcid": "Sulfuric Acid (H₂SO₄)",
"liquidNitrogen": "Liquid Nitrogen (N₂)",
"hydrogen": "Hydrogen (H₂)",
"oxygen": "Oxygen (O₂)",
"helium3": "Helium-3 (³He)"
}
}

View File

@ -1,7 +1,7 @@
---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserResources } from '../../lib/db/users';
import { getUserByAccessToken, getUserResources } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
@ -9,10 +9,12 @@ const buildingsList = (await import('../../lib/data/buildings.json')).default;
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
if(loggedToken === null || username === "") return Astro.redirect('/');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const resources = await getUserResources(username);
const resources = await getUserResources(checkUser._id);
const locale = getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
@ -23,12 +25,7 @@ const langBuildings = await getLocales(locale, 'buildings');
<Layout title="Buildings">
<NavBar loggedIn="true" active="buildings" />
<ResourceBar loggedIn="true" />
<ul>
<li>{langResources['Label_coal']}: <span id="coal">{resources.coal * 2}</span></li>
<li>{langResources['Label_iron']}: <span id="iron">{resources.iron * 3}</span></li>
<li>{langResources['Label_gold']}: <span id="gold">{resources.gold * 4}</span></li>
</ul>
<ResourceBar />
{buildingsList.map(cat => (
<div class="building-card">
@ -119,18 +116,6 @@ const langBuildings = await getLocales(locale, 'buildings');
}
</style>
<script>
setInterval(() => {
const coal = document.querySelector('#coal');
const iron = document.querySelector('#iron');
const gold = document.querySelector('#gold');
if(!coal || !iron || !gold) return;
coal.innerHTML = String(parseInt(coal?.innerHTML ?? "0") + 1);
iron.innerHTML = String(parseInt(iron?.innerHTML ?? "0") + 2);
gold.innerHTML = String(parseInt(gold?.innerHTML ?? "0") + 3);
}, 1_000);
const allButtons = document.getElementsByClassName("a-button");
for(const buildingButton of allButtons) {

View File

@ -1,14 +1,16 @@
---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getAllUsers } from '../../lib/db/users';
import { getAllUsers, getUserByAccessToken } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver';
import format from '../../lib/utils/format';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
if(loggedToken === null || username === "") return Astro.redirect('/');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const allUsers = await getAllUsers();

View File

@ -1,28 +1,21 @@
---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserResources, updateUserResources } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import { getUserByAccessToken } from '../../lib/db/users';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
if(loggedToken === null || username === "") return Astro.redirect('/');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const resources = await getUserResources(username);
const langResources = await getLocales(getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), 'resources');
---
<Layout title="chujów sto">
<NavBar loggedIn="true" active="overview" />
<ResourceBar loggedIn="true" />
<ul>
<li>{langResources['Label_coal']}: <span id="coal">{resources.coal * 2}</span></li>
<li>{langResources['Label_iron']}: <span id="iron">{resources.iron * 3}</span></li>
<li>{langResources['Label_gold']}: <span id="gold">{resources.gold * 4}</span></li>
</ul>
<ResourceBar />
</Layout>
<style>
@ -93,17 +86,4 @@ const langResources = await getLocales(getHighestWeightedLanguage(Astro.request.
gap: 2rem;
padding: 0;
}
</style>
<script>
setInterval(() => {
const coal = document.querySelector('#coal');
const iron = document.querySelector('#iron');
const gold = document.querySelector('#gold');
if(!coal || !iron || !gold) return;
coal.innerHTML = String(parseInt(coal?.innerHTML ?? "0") + 1);
iron.innerHTML = String(parseInt(iron?.innerHTML ?? "0") + 2);
gold.innerHTML = String(parseInt(gold?.innerHTML ?? "0") + 3);
}, 1_000)
</script>
</style>

View File

@ -1,15 +1,17 @@
---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserByNickOrEmail, getUserResources, updateUserResources } from '../../lib/db/users';
import { getUserByAccessToken, getUserByNickOrEmail } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import format from '../../lib/utils/format';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
if(loggedToken === null || username === "") return Astro.redirect('/');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const locale = getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));

View File

@ -57,6 +57,13 @@ if(Astro.request.method === "POST") {
secure: true
});
Astro.cookies.set("userid", user._id?.toString() as string, {
path: "/",
maxAge: sessionTime,
sameSite: "lax",
secure: true
});
return Astro.redirect("/game");
} else {
error = "invalid username or password";
@ -66,7 +73,7 @@ if(Astro.request.method === "POST") {
---
<Layout title="Login">
<NavBar loggedIn="false" />
<NavBar loggedIn="false" active="login" />
<form method="POST">
<input type="text" name="username" placeholder="username" /><br />
<input type="password" name="password" placeholder="password" /><br />

View File

@ -3,5 +3,13 @@ if(Astro.cookies.has('sessionToken')) {
Astro.cookies.delete('sessionToken');
}
if(Astro.cookies.has('username')) {
Astro.cookies.delete('uesrname');
}
if(Astro.cookies.has('userid')) {
Astro.cookies.delete('userid');
}
return Astro.redirect('/');
---

View File

@ -104,13 +104,20 @@ if(Astro.request.method === "POST") {
secure: true
});
Astro.cookies.set("userid", user._id?.toString() as string, {
path: "/",
maxAge: sessionTime,
sameSite: "lax",
secure: true
})
return Astro.redirect("/game");
}
}
---
<Layout title="Register">
<NavBar loggedIn="false" />
<NavBar loggedIn="false" active="register" />
<form method="POST">
<input type="text" name="username" placeholder="username" /><br />
<input type="email" name="email" placeholder="email" /><br />

5
src/types/Resource.ts Normal file
View File

@ -0,0 +1,5 @@
export default interface Resource {
name: string;
type: "solid" | "liquid" | "gas";
amount: number;
}

View File

@ -2,4 +2,12 @@ export default interface Resources {
coal: number;
iron: number;
gold: number;
water: number;
sulfuricAcid: number;
liquidNitrogen: number;
hydrogen: number;
oxygen: number;
helium3: number;
}

View File

@ -3,7 +3,7 @@ import type Resources from "./Resources";
import type Building from "./Building";
export default interface User {
_id?: ObjectId;
_id: ObjectId;
username: string;
email: string;
password: string;