feat(settings/clock/alarm): implement (achievements)
This commit is contained in:
Binary file not shown.
133
app/components/Settings/BottomScreen/Menus/Clock/Alarm.vue
Normal file
133
app/components/Settings/BottomScreen/Menus/Clock/Alarm.vue
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { SettingsBottomScreenNumberInput as NumberInput } from "#components";
|
||||||
|
|
||||||
|
const APP_COLOR_TO_FONT_COLOR: Record<string, string> = {
|
||||||
|
"#61829a": "#fbfbfb", // cyan
|
||||||
|
"#ba4900": "#fbe3d3", // maroon
|
||||||
|
"#fb0018": "#fbcbd3", // red
|
||||||
|
"#fb8afb": "#fbebfb", // pink
|
||||||
|
"#fb9200": "#fbf3e3", // orange
|
||||||
|
"#f3e300": "#fbfbdb", // yellow
|
||||||
|
"#aafb00": "#fbfbfb", // lime
|
||||||
|
"#00fb00": "#fbfbfb", // green
|
||||||
|
"#00a238": "#fbfbfb", // dark green
|
||||||
|
"#49db8a": "#ebfbf3", // duck
|
||||||
|
"#30baf3": "#fbfbfb", // light blue
|
||||||
|
"#0059f3": "#dbebfb", // blue
|
||||||
|
"#000092": "#ebebfb", // dark blue
|
||||||
|
"#8a00d3": "#f3dbfb", // purple
|
||||||
|
"#d300eb": "#fbfbfb", // magenta
|
||||||
|
"#fb0092": "#ebe3f3", // fuschia
|
||||||
|
};
|
||||||
|
|
||||||
|
const { assets } = useAssets();
|
||||||
|
const achievementAssets =
|
||||||
|
assets.images.settings.bottomScreen.clock.achievements;
|
||||||
|
const { onRender, onClick } = useScreen();
|
||||||
|
|
||||||
|
const app = useAppStore();
|
||||||
|
const store = useSettingsStore();
|
||||||
|
const achievements = useAchievementsStore();
|
||||||
|
const confirmationModal = useConfirmationModal();
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
store.closeSubMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
confirmationModal.open({
|
||||||
|
text: $t("settings.clock.alarm.resetConfirmation"),
|
||||||
|
onConfirm: () => {
|
||||||
|
achievements.reset();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVisitAll = () => {
|
||||||
|
throw new Error("Not implemented");
|
||||||
|
};
|
||||||
|
|
||||||
|
onClick((x, y) => {
|
||||||
|
const viewAllRect = achievementAssets.viewAllButton.rect;
|
||||||
|
if (rectContains([127, 2, viewAllRect.width, viewAllRect.height], [x, y])) {
|
||||||
|
handleVisitAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useKeyDown((key) => {
|
||||||
|
if (key === "NDS_X") {
|
||||||
|
handleVisitAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onRender((ctx) => {
|
||||||
|
assets.images.home.topScreen.background.draw(ctx, 0, 0);
|
||||||
|
|
||||||
|
// slash divider
|
||||||
|
ctx.textBaseline = "top";
|
||||||
|
ctx.fillStyle = "#515151";
|
||||||
|
ctx.fillRect(7 * 16 - 1, 4 * 16 - 1, 16 * 3 + 1, 16 * 3 + 1);
|
||||||
|
ctx.fillStyle = achievements.allObtained ? app.color.hex : "#797979";
|
||||||
|
ctx.fillRect(7 * 16, 4 * 16, 16 * 3 - 1, 16 * 3 - 1);
|
||||||
|
ctx.font = "39px NDS39";
|
||||||
|
ctx.letterSpacing = "2px";
|
||||||
|
ctx.fillStyle = achievements.allObtained
|
||||||
|
? APP_COLOR_TO_FONT_COLOR[app.color.hex]!
|
||||||
|
: "#fbfbfb";
|
||||||
|
ctx.fillText("/", 7 * 16 + 3, 4 * 16 + 4);
|
||||||
|
});
|
||||||
|
|
||||||
|
onRender((ctx) => {
|
||||||
|
achievementAssets.viewAllButton.draw(ctx, 127, 2);
|
||||||
|
achievementAssets.smallTrophy.draw(ctx, 131, 6);
|
||||||
|
|
||||||
|
const GAP = 4;
|
||||||
|
|
||||||
|
ctx.font = "10px NDS10";
|
||||||
|
ctx.textBaseline = "top";
|
||||||
|
ctx.fillStyle = "#010101";
|
||||||
|
const { actualBoundingBoxRight: textWidth } = ctx.measureText("View All");
|
||||||
|
|
||||||
|
const totalWidth = achievementAssets.X.rect.width + GAP + textWidth;
|
||||||
|
const left = Math.ceil(
|
||||||
|
145 +
|
||||||
|
(achievementAssets.viewAllButton.rect.width - 18) / 2 -
|
||||||
|
totalWidth / 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
achievementAssets.X.draw(ctx, left, 7);
|
||||||
|
fillTextHCentered(
|
||||||
|
ctx,
|
||||||
|
"View All",
|
||||||
|
left + achievementAssets.X.rect.width + GAP,
|
||||||
|
7,
|
||||||
|
textWidth,
|
||||||
|
);
|
||||||
|
}, 1000);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NumberInput
|
||||||
|
:model-value="achievements.achievements.length"
|
||||||
|
title="Obtained"
|
||||||
|
:x="4 * 16 - 1"
|
||||||
|
:selected="achievements.allObtained"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NumberInput
|
||||||
|
:model-value="ACHIEVEMENTS.length"
|
||||||
|
title="Total"
|
||||||
|
:x="9 * 16 - 1"
|
||||||
|
:selected="achievements.allObtained"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CommonButtons
|
||||||
|
:y-offset="confirmationModal.buttonsYOffset"
|
||||||
|
b-label="Cancel"
|
||||||
|
a-label="Reset"
|
||||||
|
@activate-b="handleCancel()"
|
||||||
|
@activate-a="handleReset()"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -11,6 +11,7 @@ import UserUserName from "./User/UserName.vue";
|
|||||||
import UserPersonalMessage from "./User/PersonalMessage.vue";
|
import UserPersonalMessage from "./User/PersonalMessage.vue";
|
||||||
|
|
||||||
import ClockMenu from "./Clock/Menu.vue";
|
import ClockMenu from "./Clock/Menu.vue";
|
||||||
|
import ClockAlarm from "./Clock/Alarm.vue";
|
||||||
import ClockDate from "./Clock/Date.vue";
|
import ClockDate from "./Clock/Date.vue";
|
||||||
import ClockTime from "./Clock/Time.vue";
|
import ClockTime from "./Clock/Time.vue";
|
||||||
import TouchScreenMenu from "./TouchScreen/Menu.vue";
|
import TouchScreenMenu from "./TouchScreen/Menu.vue";
|
||||||
@@ -172,6 +173,7 @@ const viewComponents: Record<string, Component> = {
|
|||||||
optionsLanguage: OptionsLanguage,
|
optionsLanguage: OptionsLanguage,
|
||||||
optionsGbaMode: OptionsGbaMode,
|
optionsGbaMode: OptionsGbaMode,
|
||||||
|
|
||||||
|
clockAlarm: ClockAlarm,
|
||||||
clockDate: ClockDate,
|
clockDate: ClockDate,
|
||||||
clockTime: ClockTime,
|
clockTime: ClockTime,
|
||||||
|
|
||||||
|
|||||||
@@ -72,8 +72,12 @@ export const useAchievementsStore = defineStore("achievements", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// TODO: rename to unlocked
|
||||||
achievements: computed(() => storage.value.unlocked),
|
achievements: computed(() => storage.value.unlocked),
|
||||||
advancement: computed(() => storage.value.advancement),
|
advancement: computed(() => storage.value.advancement),
|
||||||
|
allObtained: computed(
|
||||||
|
() => storage.value.unlocked.length === ACHIEVEMENTS.length,
|
||||||
|
),
|
||||||
unlock,
|
unlock,
|
||||||
reset,
|
reset,
|
||||||
isUnlocked: computed(
|
isUnlocked: computed(
|
||||||
|
|||||||
@@ -54,6 +54,13 @@
|
|||||||
"title": "Clock",
|
"title": "Clock",
|
||||||
"description": "Change date, time, and alarm settings.",
|
"description": "Change date, time, and alarm settings.",
|
||||||
|
|
||||||
|
"alarm": {
|
||||||
|
"title": "Achievements",
|
||||||
|
"description": "Manage your achievements.",
|
||||||
|
"resetButton": "Reset Achievements",
|
||||||
|
"resetConfirmation": "Reset all achievements?"
|
||||||
|
},
|
||||||
|
|
||||||
"date": {
|
"date": {
|
||||||
"title": "Date",
|
"title": "Date",
|
||||||
"description": "Today's date."
|
"description": "Today's date."
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 68 B |
Binary file not shown.
|
After Width: | Height: | Size: 110 B |
Binary file not shown.
|
After Width: | Height: | Size: 134 B |
Binary file not shown.
|
After Width: | Height: | Size: 64 B |
Binary file not shown.
|
After Width: | Height: | Size: 204 B |
Reference in New Issue
Block a user