Skip to content

Commit 0454e47

Browse files
authored
Merge pull request #76 from derechtenap/dev-0.2.1
0.2.1 Update
2 parents c85934f + baed706 commit 0454e47

File tree

10 files changed

+2588
-1488
lines changed

10 files changed

+2588
-1488
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use IntelliSense to learn about possible attributes.
33
// Hover to view descriptions of existing attributes.
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5-
"version": "0.2.0",
5+
"version": "0.2.1",
66
"configurations": [
77
{
88
"name": "Nextron: Main",

package-lock.json

Lines changed: 2467 additions & 1465 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "dartsmate",
44
"productName": "DartsMate",
55
"description": "Analyze, track and compare your dart games.",
6-
"version": "0.2.0",
6+
"version": "0.2.1",
77
"author": "DartsMate Contributors",
88
"main": "app/background.js",
99
"repository": "https://github.com/derechtenap/dartsmate",
@@ -22,9 +22,9 @@
2222
"release": "electron-builder --publish always"
2323
},
2424
"dependencies": {
25-
"electron-log": "^5.2.0",
25+
"electron-log": "^5.2.4",
2626
"electron-serve": "^1.3.0",
27-
"electron-store": "^8.1.0"
27+
"electron-store": "^8.2.0"
2828
},
2929
"devDependencies": {
3030
"@mantine/charts": "^7.15.0",
@@ -34,26 +34,26 @@
3434
"@mantine/hooks": "^7.15.0",
3535
"@mantine/modals": "^7.15.0",
3636
"@mantine/notifications": "^7.15.0",
37-
"@next/eslint-plugin-next": "^14.2.15",
38-
"@tabler/icons-react": "^3.19.0",
39-
"@types/node": "^20.10.4",
40-
"@types/react": "^18.3.11",
37+
"@next/eslint-plugin-next": "^14.2.20",
38+
"@tabler/icons-react": "^3.24.0",
39+
"@types/node": "^20.17.10",
40+
"@types/react": "^18.3.16",
4141
"@types/uuid": "^9.0.8",
4242
"@typescript-eslint/eslint-plugin": "^5.62.0",
4343
"@typescript-eslint/parser": "^5.62.0",
4444
"dexie": "^4.0.10",
4545
"dexie-react-hooks": "^1.1.7",
46-
"electron": "^29.0.0-beta.4",
47-
"electron-builder": "^24.9.1",
46+
"electron": "^33.2.1",
47+
"electron-builder": "^24.13.3",
4848
"embla-carousel-react": "^7.1.0",
4949
"eslint": "^8.55.0",
5050
"eslint-config-prettier": "^8.10.0",
5151
"eslint-config-standard-with-typescript": "^34.0.1",
5252
"eslint-plugin-prettier": "^4.2.1",
53-
"next": "^14.2.15",
54-
"next-i18next": "^15.3.1",
55-
"nextron": "^9.1.0",
56-
"postcss": "^8.4.47",
53+
"next": "^14.2.20",
54+
"next-i18next": "^15.4.0",
55+
"nextron": "^9.4.0",
56+
"postcss": "^8.4.49",
5757
"postcss-preset-mantine": "^1.17.0",
5858
"postcss-simple-vars": "^7.0.1",
5959
"prettier": "2.8.8",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { MatchRound } from "types/match";
2+
import { THROWS_PER_ROUND } from "utils/constants";
3+
4+
/**
5+
* Calculates the average score of the first nine throws based on the player's rounds.
6+
*
7+
* @param {MatchRound[]} playerRounds - An array of match rounds containing round data.
8+
* @returns {number} The average score of the first nine throws, or 0 if no rounds are available.
9+
*
10+
*/
11+
const getFirstNineAverage = (playerRounds: MatchRound[]): number => {
12+
if (playerRounds.length === 0) return 0;
13+
14+
const MaxRounds = Math.floor(9 / THROWS_PER_ROUND);
15+
16+
// Take the rounds needed for nine darts and calculate the average of the scores
17+
const firstThreeRounds = playerRounds.slice(0, MaxRounds);
18+
19+
const totalScore = firstThreeRounds.reduce(
20+
(sum, round) => sum + round.roundTotal,
21+
0
22+
);
23+
24+
return totalScore / firstThreeRounds.length;
25+
};
26+
27+
export default getFirstNineAverage;

renderer/lib/playing/stats/isBust.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { Checkout } from "types/match";
2+
3+
/**
4+
* Checks if the current throw results in a bust situation based on the remaining score.
5+
* A bust occurs when a player attempts to throw a score that would exceed the remaining score or violates
6+
* specific throw rules (e.g., attempting a double with a score less than 2).
7+
*
8+
* @param {Checkout} checkout - The type of checkout being attempted. Can be "Any", "Single", "Double" or "Triple".
9+
* @param {number} remainingScore - The remaining score to be reduced. Should be a positive number.
10+
* @returns {boolean} - Returns `true` if it's a bust, `false` otherwise.
11+
*
12+
* @example
13+
* isBust("Double", 1); // returns true (because a Double requires at least 2 points)
14+
* isBust("Triple", 2); // returns true (because a Triple requires at least 3 points)
15+
* isBust("Double", 4); // returns false (valid Double checkout with remaining score of 4)
16+
*/
17+
const isBust = (checkout: Checkout, remainingScore: number): boolean => {
18+
if (remainingScore < 0) return true;
19+
20+
if (checkout === "Double" && remainingScore < 2) return true;
21+
if (checkout === "Triple" && remainingScore < 3) return true;
22+
23+
return false;
24+
};
25+
26+
export default isBust;

renderer/pages/[locale]/match/playing.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ import { useRouter } from "next/router";
6060
import { useElapsedTime } from "use-elapsed-time";
6161
import { modals } from "@mantine/modals";
6262
import addMatchToDatabase from "@/lib/db/matches/addMatch";
63+
import getFirstNineAverage from "@/lib/playing/stats/getFirstNineAverage";
64+
import isBust from "@/lib/playing/stats/isBust";
6365

6466
const PlayingPage: NextPage = () => {
6567
const theme = useMantineTheme();
@@ -177,6 +179,10 @@ const PlayingPage: NextPage = () => {
177179
return false;
178180
}
179181

182+
if (checkout === "Single") {
183+
return !lastThrow.isDouble && !lastThrow.isTriple;
184+
}
185+
180186
if (checkout === "Double") {
181187
return lastThrow.isDouble || lastThrow.isBullseye;
182188
}
@@ -224,7 +230,7 @@ const PlayingPage: NextPage = () => {
224230

225231
const updatedMatchRound: MatchRound = {
226232
elapsedTime: elapsedTime,
227-
isBust: newScoreLeft < 0 ? true : false,
233+
isBust: isBust(checkout, newScoreLeft),
228234
roundAverage:
229235
matchRound.length > 0 ? totalRoundScore / matchRound.length : 0,
230236
roundTotal: totalRoundScore,
@@ -234,7 +240,6 @@ const PlayingPage: NextPage = () => {
234240
? matchRound
235241
: filledThrowDetails.slice(0, THROWS_PER_ROUND),
236242
};
237-
238243
const updatedCurrentPlayer: Player = {
239244
...currentPlayer,
240245
rounds: [...currentPlayer.rounds, updatedMatchRound],
@@ -243,7 +248,8 @@ const PlayingPage: NextPage = () => {
243248
scoreLeft:
244249
isWinner && newScoreLeft === 0
245250
? 0
246-
: newScoreLeft > 0
251+
: // Update score only if >0 and is not a bust!
252+
newScoreLeft > 0 && !isBust(checkout, newScoreLeft)
247253
? newScoreLeft
248254
: currentPlayer.scoreLeft,
249255
};
@@ -427,10 +433,13 @@ const PlayingPage: NextPage = () => {
427433
opacity={0.7}
428434
justify="space-between"
429435
>
430-
{/* TODO: Calc first nine average... */}
431436
<span>
432-
{t("stats.firstNineAvg")}
433-
{""}: 0
437+
{t("stats.firstNineAvg")}:{" "}
438+
<NumberFormatter
439+
decimalScale={2}
440+
defaultValue={0}
441+
value={getFirstNineAverage(players[_idx].rounds)}
442+
/>
434443
</span>
435444
<span>
436445
{t("stats.highestScore")}:{" "}

renderer/pages/[locale]/profile/edit.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
DefaultMantineColor,
1313
Group,
1414
Stack,
15+
Textarea,
1516
TextInput,
1617
Tooltip,
1718
useMantineTheme,
@@ -47,6 +48,22 @@ const EditProfilePage: NextPage = () => {
4748
>(defaultProfile?.color);
4849

4950
const form = useForm<Profile>({
51+
/*
52+
* Providing initial values prevents runtime errors by ensuring the validate
53+
* function has data to work with, even before user input.
54+
*/
55+
initialValues: {
56+
bio: "",
57+
color: "red",
58+
createdAt: 0,
59+
name: {
60+
firstName: "",
61+
lastName: "",
62+
},
63+
username: "",
64+
updatedAt: 0,
65+
uuid: "",
66+
},
5067
validate: {
5168
// Error messages are currently not used. The form only proceeds if all fields are valid.
5269
name: {
@@ -198,6 +215,11 @@ const EditProfilePage: NextPage = () => {
198215
placeholder={t("profile:formLabels.username.placeholder")}
199216
{...form.getInputProps("username")}
200217
/>
218+
<Textarea
219+
label={t("profile:formLabels.bio.label")}
220+
placeholder={t("profile:formLabels.bio.placeholder")}
221+
{...form.getInputProps("bio")}
222+
/>
201223
<Group>
202224
<Button
203225
disabled={!form.isValid() || !form.isTouched()}

renderer/pages/[locale]/profile/index.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const ProfileIndexPage: NextPage = () => {
3535
return (
3636
<DefaultLayout withNavbarOpen>
3737
<Paper component="header" radius={0} p="xl" m={0}>
38-
<Stack>
38+
<Stack gap="lg">
3939
<Group align="start">
4040
<ProfileAvatar
4141
color={defaultProfile.color}
@@ -58,7 +58,19 @@ const ProfileIndexPage: NextPage = () => {
5858
</Tooltip>
5959
</Group>
6060
</Group>
61-
<Group gap="xl" ta="center" grow mt="lg">
61+
<Paper>
62+
<Text
63+
fs={defaultProfile.bio ? "" : "italic"}
64+
c={defaultProfile.bio ? "" : "dimmed"}
65+
>
66+
{defaultProfile.bio ||
67+
t("profile:emptyBioPlaceholder", {
68+
FIRST_NAME: defaultProfile.name.firstName,
69+
})}
70+
</Text>
71+
</Paper>
72+
<Divider />
73+
<Group gap="xl" ta="center" grow>
6274
<Stat text={t("stats.darts")} value={0} />
6375
<Stat text={t("stats.180s")} value={0} />
6476
<Stat text={t("stats.matches")} value={0} />
@@ -71,9 +83,9 @@ const ProfileIndexPage: NextPage = () => {
7183
}}
7284
/>
7385
</Group>
86+
<Divider />
7487
</Stack>
7588
</Paper>
76-
<Divider />
7789
</DefaultLayout>
7890
);
7991
};

renderer/public/locales/de/profile.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"webcam": "Webcam",
5757
"removePhotoUpload": "Bild entfernen",
5858
"exportProfile": "Profil exportieren",
59+
"emptyBioPlaceholder": "{{FIRST_NAME}} hat keine Beschreibung hinzugefügt.",
5960
"notifications": {
6061
"updateProfileSuccess": {
6162
"title": "Profil erfolgreich aktualisiert!",

renderer/public/locales/en/profile.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"webcam": "Webcam",
5757
"removePhotoUpload": "Remove Photo",
5858
"exportProfile": "Export Profile",
59+
"emptyBioPlaceholder": "{{FIRST_NAME}} has not added a description.",
5960
"notifications": {
6061
"updateProfileSuccess": {
6162
"title": "Profile successfully updated!",

0 commit comments

Comments
 (0)