Skip to content

Commit e9106d7

Browse files
committed
store chip
1 parent 1eed561 commit e9106d7

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/client/Cosmetics.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ export async function handlePurchase(
3030
}
3131

3232
let __cosmetics: Promise<Cosmetics | null> | null = null;
33+
let __cosmeticsHash: string | null = null;
34+
35+
function simpleHash(str: string): string {
36+
let hash = 0;
37+
for (let i = 0; i < str.length; i++) {
38+
const char = str.charCodeAt(i);
39+
hash = (hash << 5) - hash + char;
40+
hash = hash & hash;
41+
}
42+
return hash.toString(36);
43+
}
44+
3345
export async function fetchCosmetics(): Promise<Cosmetics | null> {
3446
if (__cosmetics !== null) {
3547
return __cosmetics;
@@ -46,6 +58,8 @@ export async function fetchCosmetics(): Promise<Cosmetics | null> {
4658
console.error(`Invalid cosmetics: ${result.error.message}`);
4759
return null;
4860
}
61+
const patternNames = Object.keys(result.data.patterns).sort().join(",");
62+
__cosmeticsHash = simpleHash(patternNames);
4963
return result.data;
5064
} catch (error) {
5165
console.error("Error getting cosmetics:", error);
@@ -55,6 +69,11 @@ export async function fetchCosmetics(): Promise<Cosmetics | null> {
5569
return __cosmetics;
5670
}
5771

72+
export async function getCosmeticsHash(): Promise<string | null> {
73+
await fetchCosmetics();
74+
return __cosmeticsHash;
75+
}
76+
5877
export function patternRelationship(
5978
pattern: Pattern,
6079
colorPalette: { name: string; isArchived?: boolean } | null,

src/client/components/DesktopNavBar.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { LitElement, html } from "lit";
22
import { customElement, state } from "lit/decorators.js";
3+
import { getCosmeticsHash } from "../Cosmetics";
34
import { getGamesPlayed } from "../Utils";
45

56
const HELP_SEEN_KEY = "helpSeen";
7+
const STORE_SEEN_HASH_KEY = "storeSeenHash";
68

79
@customElement("desktop-nav-bar")
810
export class DesktopNavBar extends LitElement {
911
@state() private _helpSeen = localStorage.getItem(HELP_SEEN_KEY) === "true";
12+
@state() private _hasNewCosmetics = false;
1013

1114
createRenderRoot() {
1215
return this;
@@ -23,6 +26,12 @@ export class DesktopNavBar extends LitElement {
2326
this._updateActiveState(current);
2427
});
2528
}
29+
30+
// Check if cosmetics have changed
31+
getCosmeticsHash().then((hash: string) => {
32+
const seenHash = localStorage.getItem(STORE_SEEN_HASH_KEY);
33+
this._hasNewCosmetics = hash !== null && hash !== seenHash;
34+
});
2635
}
2736

2837
disconnectedCallback() {
@@ -49,11 +58,24 @@ export class DesktopNavBar extends LitElement {
4958
return getGamesPlayed() < 10 && !this._helpSeen;
5059
}
5160

61+
private showStoreDot(): boolean {
62+
return this._hasNewCosmetics && !this.showHelpDot();
63+
}
64+
5265
private onHelpClick = () => {
5366
localStorage.setItem(HELP_SEEN_KEY, "true");
5467
this._helpSeen = true;
5568
};
5669

70+
private onStoreClick = () => {
71+
this._hasNewCosmetics = false;
72+
getCosmeticsHash().then((hash: string) => {
73+
if (hash !== null) {
74+
localStorage.setItem(STORE_SEEN_HASH_KEY, hash);
75+
}
76+
});
77+
};
78+
5779
render() {
5880
return html`
5981
<nav
@@ -123,11 +145,18 @@ export class DesktopNavBar extends LitElement {
123145
class="nav-menu-item text-white/70 hover:text-blue-500 font-bold tracking-widest uppercase cursor-pointer transition-colors [&.active]:text-blue-500"
124146
data-page="page-item-store"
125147
data-i18n="main.store"
148+
@click=${this.onStoreClick}
126149
></button>
127-
<span
128-
class="absolute -top-3 -right-2 bg-gradient-to-br from-red-600 to-red-700 text-white text-[9px] font-black tracking-wider px-2 py-0.5 rounded rotate-12 shadow-lg shadow-red-600/50 animate-pulse pointer-events-none"
129-
data-i18n="main.store_new_badge"
130-
></span>
150+
${this.showStoreDot()
151+
? html`
152+
<span
153+
class="absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full animate-ping"
154+
></span>
155+
<span
156+
class="absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"
157+
></span>
158+
`
159+
: ""}
131160
</div>
132161
<button
133162
class="nav-menu-item text-white/70 hover:text-blue-500 font-bold tracking-widest uppercase cursor-pointer transition-colors [&.active]:text-blue-500"

0 commit comments

Comments
 (0)