feat(contact): notifications system + action
This commit is contained in:
83
app/components/Contact/TopScreen/Notifications.vue
Normal file
83
app/components/Contact/TopScreen/Notifications.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
// text color:
|
||||
const store = useContactStore();
|
||||
|
||||
const notificationImage = useTemplateRef("notificationImage");
|
||||
const titleImage = useTemplateRef("titleImage");
|
||||
|
||||
useRender((ctx) => {
|
||||
if (!notificationImage.value || !titleImage.value) return;
|
||||
|
||||
ctx.font = "10px NDS10";
|
||||
|
||||
// notifications
|
||||
for (let i = store.notifications.length - 1; i >= 0; i--) {
|
||||
const index = store.notifications.length - 1 - i;
|
||||
const y = 169 - 24 * index + store.notificationsYOffset;
|
||||
if (y < -24) break;
|
||||
|
||||
ctx.drawImage(notificationImage.value, 21, y);
|
||||
|
||||
const content = store.notifications[i]!;
|
||||
ctx.fillStyle = content.includes("opened") ? "#00fbba" : "#e3f300";
|
||||
ctx.fillText(store.notifications[i]!, 27, y + 15);
|
||||
}
|
||||
|
||||
// title
|
||||
ctx.globalAlpha = store.isIntro ? store.intro.stage1Opacity : 1;
|
||||
ctx.drawImage(
|
||||
titleImage.value,
|
||||
21,
|
||||
store.isIntro
|
||||
? store.intro.titleY
|
||||
: 169 - 24 * store.notifications.length + store.notificationsYOffset,
|
||||
);
|
||||
|
||||
// notifications count (left bar)
|
||||
const MAX = 36;
|
||||
const MAX_VISIBLE = 8;
|
||||
|
||||
let visibleNotifications = Math.min(store.notifications.length, MAX_VISIBLE);
|
||||
const extraActive =
|
||||
store.notificationsYOffset > 0 && store.notifications.length > MAX_VISIBLE;
|
||||
|
||||
if (extraActive) {
|
||||
visibleNotifications += 1;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "#415969";
|
||||
for (let i = 0; i < visibleNotifications; i++) {
|
||||
ctx.fillRect(3, 161 - i * 4, 12, 2);
|
||||
}
|
||||
|
||||
ctx.fillStyle = "#b2c3db";
|
||||
const startY = 161 - visibleNotifications * 4;
|
||||
const top = MAX - MAX_VISIBLE - (extraActive ? 1 : 0);
|
||||
for (
|
||||
let i = 0;
|
||||
i < store.notifications.length - visibleNotifications && i < top;
|
||||
i++
|
||||
) {
|
||||
if (i === top - 1) {
|
||||
ctx.fillRect(7, startY - i * 4, 4, 2);
|
||||
} else if (i === top - 2) {
|
||||
ctx.fillRect(5, startY - i * 4, 8, 2);
|
||||
} else {
|
||||
ctx.fillRect(3, startY - i * 4, 12, 2);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img
|
||||
ref="notificationImage"
|
||||
src="/assets/images/contact/bottom-screen/notification.png"
|
||||
hidden
|
||||
/>
|
||||
<img
|
||||
ref="titleImage"
|
||||
src="/assets/images/contact/top-screen/title.png"
|
||||
hidden
|
||||
/>
|
||||
</template>
|
||||
@@ -1,24 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const store = useContactStore();
|
||||
|
||||
const titleImage = useTemplateRef("titleImage");
|
||||
|
||||
useRender((ctx) => {
|
||||
if (!titleImage.value) return;
|
||||
|
||||
ctx.globalAlpha = store.isIntro ? store.intro.stage1Opacity : 1;
|
||||
ctx.drawImage(
|
||||
titleImage.value,
|
||||
21,
|
||||
store.isIntro ? store.intro.titleY : SCREEN_HEIGHT - 23,
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img
|
||||
ref="titleImage"
|
||||
src="/assets/images/contact/top-screen/title.png"
|
||||
hidden
|
||||
/>
|
||||
</template>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import Background from "./Background.vue";
|
||||
import LeftBar from "./LeftBar.vue";
|
||||
import Title from "./Title.vue";
|
||||
import Notifications from "./Notifications.vue";
|
||||
|
||||
const store = useContactStore();
|
||||
|
||||
@@ -15,5 +15,6 @@ onMounted(() => {
|
||||
<Background />
|
||||
|
||||
<LeftBar />
|
||||
<Title />
|
||||
|
||||
<Notifications />
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user