Skip to content

Commit 4d690d9

Browse files
authored
Merge pull request #213 from ddxv/main
Fix sidebars in new app and ranking sections
2 parents 999f007 + 7e6ea11 commit 4d690d9

5 files changed

Lines changed: 114 additions & 113 deletions

File tree

frontend/src/hooks.server.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,11 @@ const cacheAndRoutingHandle: Handle = async ({ event, resolve }) => {
131131
'/categories'
132132
];
133133
const needsCache = cacheDependentPrefixes.some((p) => route.startsWith(p));
134-
if (needsCache && !isInitialized && initializationPromise) {
134+
if (needsCache && !isInitialized) {
135+
// Kick off on-demand init if none is in progress (e.g. start-up attempt failed).
136+
if (!initializationPromise) {
137+
initializationPromise = initializeCache();
138+
}
135139
const CACHE_WAIT_BUDGET_MS = 2000;
136140
const waitStart = Date.now();
137141
await Promise.race([
@@ -305,6 +309,8 @@ async function initializeCache(): Promise<void> {
305309
} catch (error) {
306310
const duration = initStartTime ? Date.now() - initStartTime : 0;
307311
console.error(`[Cache] Failed to initialize cache after ${duration}ms:`, error);
312+
// Reset so the next request can retry initialization (e.g. backend not ready yet).
313+
initializationPromise = null;
308314
}
309315
}
310316

@@ -316,16 +322,19 @@ export const init: ServerInit = () => {
316322
};
317323

318324
export const getCachedData = async (): Promise<CachedData> => {
319-
if (!isInitialized && initializationPromise) {
320-
console.log('[Cache] Waiting for cache initialization...');
321-
const waitStart = Date.now();
322-
await initializationPromise;
323-
const waitDuration = Date.now() - waitStart;
324-
console.log(`[Cache] Cache ready after ${waitDuration}ms wait`);
325-
}
326-
327325
if (!isInitialized) {
328-
console.warn('[Cache] Cache not initialized, returning empty defaults');
326+
if (initializationPromise) {
327+
console.log('[Cache] Waiting for cache initialization...');
328+
const waitStart = Date.now();
329+
await initializationPromise;
330+
const waitDuration = Date.now() - waitStart;
331+
console.log(`[Cache] Cache ready after ${waitDuration}ms wait`);
332+
} else {
333+
// No initialization in progress — start one on-demand (e.g. previous start-up attempt failed).
334+
console.log('[Cache] Cache not initialized, triggering on-demand initialization...');
335+
initializationPromise = initializeCache();
336+
await initializationPromise;
337+
}
329338
}
330339

331340
return cachedData;

frontend/src/lib/AppOverviewSummary.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
app.store === '1' || app.store === 'google' || app.store_id?.includes('.')
1616
);
1717
const platformName = $derived(isAndroid ? 'Android' : 'iOS');
18-
const storeName = $derived(isAndroid ? 'Google Play' : 'App Store');
1918
2019
// Format category name
2120
const categoryName = $derived(

frontend/src/lib/NavTabs.svelte

Lines changed: 65 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,6 @@
2424
<!-- Flat list used inside the mobile hamburger menu -->
2525
<div class="flex flex-col gap-1 {topDivider} mx-2">
2626
{#if !hideLinks}
27-
<!-- RANKINGS group -->
28-
<p class={sectionLabel}>Rankings</p>
29-
<a
30-
href="/rankings/store/1/collection/1/category/1/US"
31-
class={isHighlighted('/rankings') ? topBarHighlightedFont : topBarFont}
32-
>Top Google Play App Ranks</a
33-
>
34-
<div class={myDivider}></div>
35-
<a
36-
href="/rankings/store/2/collection/4/category/120/US"
37-
class={isHighlighted('/rankings') ? topBarHighlightedFont : topBarFont}
38-
>Apple App Store Ranks</a
39-
>
40-
<div class={myDivider}></div>
41-
<a
42-
href="/fastest-growing-apps/google/overall"
43-
class={isHighlighted('/fastest-growing-apps') ? topBarHighlightedFont : topBarFont}
44-
>Top Growth Apps</a
45-
>
46-
<div class={myDivider}></div>
47-
<a
48-
href="/collections/new_monthly/google/overall"
49-
class={isHighlighted('/collections') ? topBarHighlightedFont : topBarFont}>New Apps</a
50-
>
51-
<div class={myDivider}></div>
5227
<!-- B2B INTELLIGENCE group -->
5328
<p class={sectionLabel}>B2B Intelligence</p>
5429
<p class={sectionLabel}>Company Rankings</p>
@@ -117,6 +92,32 @@
11792
>Free SDK Scans</a
11893
>
11994
<div class={myDivider}></div>
95+
<!-- RANKINGS group -->
96+
<p class={sectionLabel}>Rankings</p>
97+
<a
98+
href="/rankings/store/1/collection/1/category/1/US"
99+
class={isHighlighted('/rankings') ? topBarHighlightedFont : topBarFont}
100+
>Top Google Play App Ranks</a
101+
>
102+
<div class={myDivider}></div>
103+
<a
104+
href="/rankings/store/2/collection/4/category/120/US"
105+
class={isHighlighted('/rankings') ? topBarHighlightedFont : topBarFont}
106+
>Apple App Store Ranks</a
107+
>
108+
<div class={myDivider}></div>
109+
<a
110+
href="/fastest-growing-apps/google/overall"
111+
class={isHighlighted('/fastest-growing-apps') ? topBarHighlightedFont : topBarFont}
112+
>Top Growth Apps</a
113+
>
114+
<div class={myDivider}></div>
115+
<a
116+
href="/collections/new_monthly/google/overall"
117+
class={isHighlighted('/collections') ? topBarHighlightedFont : topBarFont}>New Apps</a
118+
>
119+
<div class={myDivider}></div>
120+
120121
<!-- RESOURCES group -->
121122
<p class={sectionLabel}>Resources</p>
122123
<a href="/blog" class={isHighlighted('/blog') ? topBarHighlightedFont : topBarFont}>Blog</a>
@@ -144,47 +145,6 @@
144145
{:else}
145146
<!-- Desktop dropdown bar -->
146147
<div class="flex flex-row gap-1 md:gap-2 xxl:gap-6 text-center items-center mx-2">
147-
<!-- RANKINGS dropdown -->
148-
<div class="relative group">
149-
<button
150-
class="flex items-center gap-0.5 {isHighlighted(
151-
'/rankings',
152-
'/fastest-growing-apps',
153-
'/collections'
154-
)
155-
? topBarHighlightedFont
156-
: topBarFont}"
157-
>
158-
Rankings <ChevronDown class="h-3 w-3 transition-transform group-hover:rotate-180" />
159-
</button>
160-
<div class="absolute left-0 top-full pt-1 hidden group-hover:block z-50 min-w-max">
161-
<div class="card bg-surface-50-950 shadow-xl rounded-md py-1">
162-
<a
163-
href="/rankings/store/1/collection/1/category/1/US"
164-
class={isHighlighted('/rankings') ? dropdownHighlightedItem : dropdownItem}
165-
>Top Google Play App Ranks</a
166-
>
167-
<a
168-
href="/rankings/store/2/collection/4/category/120/US"
169-
class={isHighlighted('/rankings') ? dropdownHighlightedItem : dropdownItem}
170-
>Apple App Store Ranks</a
171-
>
172-
<a
173-
href="/fastest-growing-apps/google/overall"
174-
class={isHighlighted('/fastest-growing-apps') ? dropdownHighlightedItem : dropdownItem}
175-
>Top Growth Apps</a
176-
>
177-
<a
178-
href="/collections/new_monthly/google/overall"
179-
class={isHighlighted('/collections') ? dropdownHighlightedItem : dropdownItem}
180-
>New Apps</a
181-
>
182-
</div>
183-
</div>
184-
</div>
185-
186-
<div class={myDivider}></div>
187-
188148
<!-- B2B INTELLIGENCE dropdown -->
189149
<div class="relative group">
190150
<button
@@ -286,7 +246,46 @@
286246
</div>
287247

288248
<div class={myDivider}></div>
249+
<!-- RANKINGS dropdown -->
250+
<div class="relative group">
251+
<button
252+
class="flex items-center gap-0.5 {isHighlighted(
253+
'/rankings',
254+
'/fastest-growing-apps',
255+
'/collections'
256+
)
257+
? topBarHighlightedFont
258+
: topBarFont}"
259+
>
260+
Rankings <ChevronDown class="h-3 w-3 transition-transform group-hover:rotate-180" />
261+
</button>
262+
<div class="absolute left-0 top-full pt-1 hidden group-hover:block z-50 min-w-max">
263+
<div class="card bg-surface-50-950 shadow-xl rounded-md py-1">
264+
<a
265+
href="/rankings/store/1/collection/1/category/1/US"
266+
class={isHighlighted('/rankings') ? dropdownHighlightedItem : dropdownItem}
267+
>Top Google Play App Ranks</a
268+
>
269+
<a
270+
href="/rankings/store/2/collection/4/category/120/US"
271+
class={isHighlighted('/rankings') ? dropdownHighlightedItem : dropdownItem}
272+
>Apple App Store Ranks</a
273+
>
274+
<a
275+
href="/fastest-growing-apps/google/overall"
276+
class={isHighlighted('/fastest-growing-apps') ? dropdownHighlightedItem : dropdownItem}
277+
>Top Growth Apps</a
278+
>
279+
<a
280+
href="/collections/new_monthly/google/overall"
281+
class={isHighlighted('/collections') ? dropdownHighlightedItem : dropdownItem}
282+
>New Apps</a
283+
>
284+
</div>
285+
</div>
286+
</div>
289287

288+
<div class={myDivider}></div>
290289
<!-- RESOURCES dropdown -->
291290
<div class="relative group">
292291
<button

frontend/src/lib/SideBarRankings.svelte

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,28 @@
2121
page.url.pathname.startsWith(href) ? buttonSelectedClass : buttonDeselectedClass
2222
);
2323
24-
let store = $state(1);
25-
$effect(() => {
26-
store = +page.params.store!;
24+
let store = $derived.by(() => {
25+
const s = +page.params.store!;
26+
return isNaN(s) ? 1 : s;
2727
});
28-
let collection = $state(1);
29-
$effect(() => {
30-
collection = +page.params.collection!;
31-
});
32-
let category = $state(1);
33-
$effect(() => {
34-
category = +page.params.category!;
35-
});
36-
// Logic to adjust collection and category based on the store's value
37-
$effect(() => {
38-
// If store is not a number (NaN), default it to 1
39-
if (isNaN(store)) {
40-
store = 1;
28+
let collection = $derived.by(() => {
29+
const raw = +page.params.collection!;
30+
if (!isNaN(raw)) return raw;
31+
switch (store) {
32+
case 2:
33+
return 4;
34+
default:
35+
return 1;
4136
}
42-
37+
});
38+
let category = $derived.by(() => {
39+
const raw = +page.params.category!;
40+
if (!isNaN(raw)) return raw;
4341
switch (store) {
4442
case 2:
45-
collection = 4;
46-
category = 120;
47-
break;
48-
case 1:
49-
default: // Defaults for store=1 or any other value not explicitly handled
50-
collection = 1;
51-
category = 1;
52-
break;
43+
return 120;
44+
default:
45+
return 1;
5346
}
5447
});
5548
</script>
@@ -89,7 +82,7 @@
8982
{/snippet}
9083
<nav class="list-nav">
9184
<ul>
92-
{#each Object.entries(collectionIDLookup[store]) as [id, values]}
85+
{#each Object.entries(collectionIDLookup[store] ?? {}) as [id, values]}
9386
<li>
9487
<a
9588
href={`/rankings/store/${store}/collection/${values.collection_id}/category/${category}/${country}`}
@@ -115,7 +108,7 @@
115108
{/snippet}
116109
<nav class="list-nav">
117110
<ul>
118-
{#each Object.entries(categoryIDLookup[collection]) as [id, values]}
111+
{#each Object.entries(categoryIDLookup[collection] ?? {}) as [id, values]}
119112
<li>
120113
<a
121114
href={`/rankings/store/${store}/collection/${collection}/category/${values.category_id}/${country}`}

frontend/src/routes/(categorical)/rankings/store/[store]/collection/[collection]/category/[category]/[country]/+page.svelte

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@
1717
let category = $derived(+page.params.category!);
1818
1919
let collectionName = $derived(
20-
prettyName(data.collectionIDLookup[store][collection].collection_name)
20+
prettyName(data.collectionIDLookup[store]?.[collection]?.collection_name ?? '')
2121
);
2222
let categoryName = $derived(
23-
prettyName(data.categoryIDLookup[collection][category].category_name)
23+
prettyName(data.categoryIDLookup[collection]?.[category]?.category_name ?? '')
2424
);
2525
2626
let country = $state(page.params.country || 'US');
2727
28+
let storeName = $derived(data.storeIDLookup[store]?.store_name ?? 'App Store');
29+
2830
function getTitle(): string {
2931
const title =
30-
data.storeIDLookup[store].store_name +
32+
storeName +
3133
' ' +
3234
'Daily App Ranks ' +
3335
collectionName +
@@ -42,7 +44,7 @@
4244
function getDescription(): string {
4345
const description =
4446
'Free app store charts. Top ranked ' +
45-
data.storeIDLookup[store].store_name +
47+
storeName +
4648
' ' +
4749
collectionName +
4850
' ' +
@@ -59,10 +61,9 @@
5961
<meta name="description" content={description} />
6062
<meta
6163
name="keywords"
62-
content="free, free aso, {data.storeIDLookup[store].store_name}, {data.collectionIDLookup[
63-
store
64-
][collection].collection_name}, {data.categoryIDLookup[collection][category]
65-
.category_name}, app rankings, top apps, Google Play charts, iOS App Store charts, free, ASO, marketing, competitor analysis, app category rankings, app performance tracking, mobile app trends"
64+
content="free, free aso, {storeName}, {data.collectionIDLookup[store]?.[collection]
65+
?.collection_name ?? ''}, {data.categoryIDLookup[collection]?.[category]?.category_name ??
66+
''}, app rankings, top apps, Google Play charts, iOS App Store charts, free, ASO, marketing, competitor analysis, app category rankings, app performance tracking, mobile app trends"
6667
/>
6768

6869
<!-- Open Graph meta tags -->
@@ -89,7 +90,7 @@
8990
<p class="">
9091
The {collectionName}
9192
{categoryName} Apps on
92-
{data.storeIDLookup[store].store_name}
93+
{storeName}
9394
in
9495
{country}
9596
</p>

0 commit comments

Comments
 (0)