Skip to content

Commit b725eb0

Browse files
author
James O'Claire
committed
Organize revenue and update app descriptions
1 parent 542c099 commit b725eb0

File tree

5 files changed

+104
-55
lines changed

5 files changed

+104
-55
lines changed

frontend/src/lib/AppOverviewSummary.svelte

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import type { AppFullDetail } from '../types';
3-
import { formatNumber } from '$lib/utils/formatNumber';
3+
import { formatNumber, getRevenueBucket } from '$lib/utils/formatNumber';
44
55
interface Props {
66
app: AppFullDetail;
@@ -83,6 +83,31 @@
8383
const weeklyInstalls = $derived(app.installs_sum_1w ? formatNumber(app.installs_sum_1w) : null);
8484
const weeklyRatings = $derived(app.ratings_sum_1w ? formatNumber(app.ratings_sum_1w) : null);
8585
const monthlyInstalls = $derived(app.installs_sum_4w ? formatNumber(app.installs_sum_4w) : null);
86+
const monthlyActiveUsers = $derived(
87+
app.monthly_active_users && app.monthly_active_users > 0
88+
? formatNumber(app.monthly_active_users)
89+
: null
90+
);
91+
const monthlyAdRevenue = $derived(Number(app.monthly_ad_revenue) || 0);
92+
const monthlyIapRevenue = $derived(Number(app.monthly_iap_revenue) || 0);
93+
const monthlyRevenueTotal = $derived(monthlyAdRevenue + monthlyIapRevenue);
94+
const monthlyRevenueBucket = $derived(
95+
monthlyRevenueTotal > 0 ? getRevenueBucket(monthlyRevenueTotal) : null
96+
);
97+
const monthlyAdRevenueShare = $derived(
98+
monthlyRevenueTotal > 0 ? Math.round((monthlyAdRevenue / monthlyRevenueTotal) * 100) : 0
99+
);
100+
const monthlyIapRevenueShare = $derived(
101+
monthlyRevenueTotal > 0 ? 100 - monthlyAdRevenueShare : 0
102+
);
103+
const releaseMonthYear = $derived(
104+
app.release_date
105+
? new Date(app.release_date).toLocaleDateString('en-US', {
106+
month: 'short',
107+
year: 'numeric'
108+
})
109+
: null
110+
);
86111
87112
// Format date helper
88113
const formatDate = (dateStr: string | undefined | null): string | null => {
@@ -100,7 +125,8 @@
100125
101126
// Ad and API tracking info
102127
const adCreativeCount = $derived(app.ad_creative_count ?? 0);
103-
const hasAdMonetization = $derived((app?.ad_monetized_creative_count ?? 0) > 0);
128+
const adMonetizedCreativeCount = $derived(app.ad_monetized_creative_count ?? 0);
129+
const hasAdMonetization = $derived(adMonetizedCreativeCount > 0);
104130
const apiLastCrawled = $derived(formatDate(app.api_last_crawled));
105131
const sdkLastCrawled = $derived(formatDate(app.sdk_last_crawled));
106132
@@ -113,25 +139,43 @@
113139
<h2 class="text-lg font-bold">{app.name} Summary</h2>
114140
<p>
115141
<strong>{app.name}</strong> is a
116-
{#if monetization}{monetization}{/if}
142+
{#if monetization}{monetization}{:else}mobile{/if}
117143
{platformName} app
118-
{#if categoryName}in the <span class="font-medium">{categoryName}</span> category{/if}{#if app.developer_name},
119-
developed by <span class="font-medium">{app.developer_name}</span>{/if}.
120-
{#if appAge}
121-
First released {appAge} ago{#if app.release_date}
122-
({new Date(app.release_date).toLocaleDateString('en-US', {
123-
month: 'short',
124-
year: 'numeric'
125-
})}){/if},{/if}
144+
{#if categoryName}in <span class="font-medium">{categoryName}</span>{/if}
145+
{#if app.developer_name}
146+
by <span class="font-medium">{app.developer_name}</span>{/if}.
147+
{#if releaseMonthYear}
148+
Released in <span class="font-semibold">{releaseMonthYear}</span>
149+
{#if appAge}({appAge} ago){/if}.
150+
{/if}
126151
{#if installsFormatted && isAndroid}
127-
the app has accumulated <span class="font-semibold">{installsFormatted}+</span> total installs
152+
It has about <span class="font-semibold">{installsFormatted}+</span> installs
128153
{/if}
129154
{#if ratingsFormatted}
130-
{#if installsFormatted && isAndroid}and{:else}the app has{/if}
155+
{#if installsFormatted && isAndroid}and{:else}It has{/if}
131156
<span class="font-semibold">{ratingsFormatted}</span> ratings
132157
{#if app.rating}
133158
with a <span class="font-semibold">{Number(app.rating).toFixed(2)}★</span> ({ratingQuality})
134-
average rating{/if}.
159+
average
160+
{/if}.
161+
{/if}
162+
{#if monthlyActiveUsers || monthlyRevenueBucket}
163+
Based on AppGoblin estimates,
164+
{#if monthlyActiveUsers}
165+
it reaches roughly <span class="font-semibold">{monthlyActiveUsers}</span> monthly active users
166+
{/if}
167+
{#if monthlyActiveUsers && monthlyRevenueBucket}and{/if}
168+
{#if monthlyRevenueBucket}
169+
generates around <span class="font-semibold">{monthlyRevenueBucket}</span> monthly revenue ({monthlyIapRevenueShare}%
170+
IAP / {monthlyAdRevenueShare}% ads)
171+
{/if}.
172+
{/if}
173+
{#if app.store_last_updated || app.version_code || app.content_rating}
174+
Store metadata{#if app.store_last_updated}: updated <span class="font-semibold"
175+
>{formatDate(app.store_last_updated)}</span
176+
>{/if}{#if app.version_code}, version <span class="font-semibold">{app.version_code}</span
177+
>{/if}{#if app.content_rating}, rated <span class="font-semibold">{app.content_rating}</span
178+
>{/if}.
135179
{/if}
136180
</p>
137181

@@ -157,14 +201,17 @@
157201
<p>
158202
<span class="font-medium text-primary-800-200">Advertising:</span>
159203
{#if adCreativeCount > 0}
160-
We've tracked <a href="{appBasePath}/ad-creatives" class="font-semibold"
204+
AppGoblin has tracked <a href="{appBasePath}/ad-creatives" class="font-semibold"
161205
>{formatNumber(adCreativeCount)} ad creatives</a
162-
> where this app is running paid user acquisition campaigns.
206+
> this app uses for paid user acquisition across ad networks.
163207
{/if}
164-
{#if hasAdMonetization}
165-
{#if adCreativeCount > 0}Additionally, the{:else}The{/if} app has been identified as showing
166-
<a href="{appBasePath}/monetized-ads">monetized advertisements</a> based on detected ad network
167-
creatives.
208+
{#if adMonetizedCreativeCount > 0}
209+
{#if adCreativeCount > 0}AppGoblin also{/if}
210+
{#if adCreativeCount === 0}AppGoblin{/if} detected
211+
<a href="{appBasePath}/monetized-ads" class="font-semibold"
212+
>{formatNumber(adMonetizedCreativeCount)} monetized ad creatives</a
213+
>
214+
shown inside the app.
168215
{/if}
169216
</p>
170217
{/if}

frontend/src/lib/AppSDKOverview.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</script>
1717

1818
{#if typeof myPackageInfo == 'string'}
19-
<p>Permissions, SDKs and trackers info not yet available for this app.</p>
19+
<p>Permissions, SDKs and trackers info not yet available for {myapp.name}.</p>
2020
{:else if myPackageInfo.company_categories && myapp.sdk_successful_last_crawled}
2121
<div class="">
2222
<p class="p-2 md:p-4">
@@ -41,6 +41,7 @@
4141
<WhiteCard>
4242
{#snippet title()}
4343
<span class="text-sm font-semibold">
44+
AppGoblin saw {myapp.name} uses
4445
{myPackageInfo.company_categories[category].length}
4546
{companyTypes.types.find((x: { url_slug: string }) => x.url_slug === category)
4647
?.name || category}

frontend/src/lib/FastestGrowingAppsTable.svelte

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,18 +318,21 @@
318318
<a
319319
href="/apps/{row.original.store_id}"
320320
style="cursor: pointer;"
321-
class="text-xs md:text-sm font-medium text-blue-600 hover:text-blue-800"
321+
class="block max-w-[170px] md:max-w-[260px] text-xs md:text-sm font-medium text-blue-600 hover:text-blue-800"
322322
>
323323
<div class="flex items-center gap-2">
324324
<img
325325
src={row.original.app_icon_url}
326326
alt={row.original.app_name}
327327
class="w-8 h-8 shrink-0 rounded"
328328
/>
329-
<div class="flex flex-col min-w-0">
330-
<span class="text-xs md:text-sm truncate">{row.original.app_name}</span>
331-
<span class="text-[10px] md:text-xs text-surface-500 truncate"
332-
>{row.original.developer_name}</span
329+
<div class="flex flex-col min-w-0 max-w-[120px] md:max-w-[210px]">
330+
<span class="text-xs md:text-sm truncate" title={row.original.app_name}
331+
>{row.original.app_name}</span
332+
>
333+
<span
334+
class="text-[10px] md:text-xs text-surface-500 truncate"
335+
title={row.original.developer_name}>{row.original.developer_name}</span
333336
>
334337
</div>
335338
</div>

frontend/src/lib/RatingInstallsLarge.svelte

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,28 @@
3636
<!-- Installs -->
3737
<div class="flex items-start sm:items-center gap-2">
3838
{#if app.installs && app.installs != 0}
39-
<div class="text-primary-600-400">
39+
<div class="text-primary-900-100">
4040
<IconDownload />
4141
</div>
4242
<div class="leading-tight">
4343
<span class="font-semibold text-base md:text-lg">{formatNumber(app.installs)}</span>
44-
<span class="text-primary-600-400 text-sm ml-1">installs</span>
44+
<span class="text-sm ml-1">installs</span>
4545
</div>
4646
{:else if app.rating_count != 0}
47-
<div class="text-primary-600-400">
47+
<div class="text-primary-900-100">
4848
<IconDownload />
4949
</div>
5050
<div class="leading-tight">
5151
<span class="font-semibold text-base md:text-lg">
5252
~{formatNumber(app_install_estimate_min)} - {formatNumber(app_install_estimate_max)}
5353
</span>
54-
<span class="text-primary-600-400 text-sm ml-1">est. installs</span>
54+
<span class="text-sm ml-1">est. installs</span>
5555
</div>
5656
{:else}
57-
<div class="text-primary-600-400">
57+
<div class="text-primary-900-100">
5858
<IconDownload />
5959
</div>
60-
<span class="text-primary-600-400 text-sm">Installs not yet available</span>
60+
<span class="text-sm">Installs not yet available</span>
6161
{/if}
6262
</div>
6363

@@ -67,11 +67,11 @@
6767
<Star class="w-5 h-5" />
6868
<div class="leading-tight">
6969
<span class="font-semibold text-base md:text-lg">{formatNumber(app.rating_count)}</span>
70-
<span class="text-primary-600-400 text-sm ml-1">ratings</span>
70+
<span class="text-sm ml-1">ratings</span>
7171
</div>
7272
{:else}
73-
<Star class="w-5 h-5 text-primary-600-400" />
74-
<span class="text-primary-600-400 text-sm">Ratings not yet available</span>
73+
<Star class="w-5 h-5 text-primary-900-100" />
74+
<span class="text-sm">Ratings not yet available</span>
7575
{/if}
7676
</div>
7777
</div>
@@ -81,16 +81,16 @@
8181
<!-- Monthly Active Users -->
8282
<div class="flex items-start sm:items-center gap-2">
8383
{#if monthlyActiveUsers > 0}
84-
<UsersIcon class="w-5 h-5 text-primary-600-400" />
84+
<UsersIcon class="w-5 h-5" />
8585
<div class="leading-tight">
8686
<span class="font-semibold text-base md:text-lg"
8787
>{formatNumber(monthlyActiveUsers)}</span
8888
>
89-
<span class="text-primary-600-400 text-sm ml-1">monthly active users</span>
89+
<span class="text-sm ml-1">monthly active users</span>
9090
</div>
9191
{:else}
92-
<UsersIcon class="w-5 h-5 text-primary-600-400" />
93-
<span class="text-primary-600-400 text-sm">MAU not available</span>
92+
<UsersIcon class="w-5 h-5 text-primary-900-100" />
93+
<span class="text-primary-900-100 text-sm">MAU not available</span>
9494
{/if}
9595
</div>
9696

@@ -103,7 +103,7 @@
103103
<span class="font-semibold text-base md:text-lg text-success-900-100"
104104
>{getRevenueBucket(monthlyTotalRevenue)}</span
105105
>
106-
<span class="text-primary-600-400 text-sm ml-1">monthly revenue est.</span>
106+
<span class="text-sm ml-1">monthly revenue est.</span>
107107
</div>
108108
<!-- Revenue split visualization -->
109109
<div class="flex items-center gap-2 mt-1">
@@ -125,33 +125,31 @@
125125
<span class="w-2 h-2 rounded-full bg-success-800-200"></span>
126126
<span class="text-success-800-200">IAP {monthlyIapRevenueShare}%</span>
127127
</span>
128-
<span class="text-primary-600-400">·</span>
128+
<span class="text-primary-900-100">·</span>
129129
<span class="flex items-center gap-1">
130130
<span class="w-2 h-2 rounded-full bg-primary-800-200"></span>
131131
<span class="text-primary-800-200">Ad {monthlyAdRevenueShare}%</span>
132132
</span>
133133
</div>
134134
</div>
135135
{:else}
136-
<DollarSignIcon class="w-5 h-5 text-primary-600-400" />
137-
<span class="text-primary-600-400 text-sm">Revenue not available</span>
136+
<DollarSignIcon class="w-5 h-5 text-primary-900-100" />
137+
<span class="text-primary-900-100 text-sm">Revenue not available</span>
138138
{/if}
139139
</div>
140140
</div>
141141

142142
<!-- Install Trends -->
143143
{#if app.installs_sum_1w > 0 || app.installs_sum_4w > 0}
144144
<div class="col-span-1 md:col-span-2 border-t border-primary-200-800 pt-3 space-y-2">
145-
<div class="text-xs font-medium text-primary-600-400 uppercase tracking-wide">
146-
Install Trends
147-
</div>
145+
<div class="text-xs font-medium uppercase tracking-wide">Install Trends</div>
148146
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
149147
{#if app.installs_sum_1w > 0}
150148
<div
151149
class="flex items-start sm:items-center justify-between gap-2 bg-primary-50-900/20 rounded px-3 py-2"
152150
>
153151
<div class="flex items-center gap-2 min-w-0">
154-
<span class="text-sm text-primary-600-400">Weekly</span>
152+
<span class="text-sm">Weekly</span>
155153
<span class="font-medium text-sm">+{formatNumber(app.installs_sum_1w)}</span>
156154
</div>
157155
{#if app.installs_z_score_2w > 1}
@@ -160,12 +158,12 @@
160158
<span class="text-xs font-medium">Trending</span>
161159
</div>
162160
{:else if app.installs_z_score_2w < -1}
163-
<div class="flex items-center gap-1 text-danger-600">
161+
<div class="flex items-center gap-1 text-danger-600-400">
164162
<TrendingDownIcon class="w-4 h-4" />
165163
<span class="text-xs font-medium">Declining</span>
166164
</div>
167165
{:else}
168-
<span class="text-xs text-primary-600-400">Steady</span>
166+
<span class="text-xs">Steady</span>
169167
{/if}
170168
</div>
171169
{/if}
@@ -174,7 +172,7 @@
174172
class="flex items-start sm:items-center justify-between gap-2 bg-primary-50-900/20 rounded px-3 py-2"
175173
>
176174
<div class="flex items-center gap-2 min-w-0">
177-
<span class="text-sm text-primary-600-400">Monthly</span>
175+
<span class="text-sm">Monthly</span>
178176
<span class="font-medium text-sm">+{formatNumber(app.installs_sum_4w)}</span>
179177
</div>
180178
{#if app.installs_z_score_4w > 1}
@@ -183,12 +181,12 @@
183181
<span class="text-xs font-medium">Trending</span>
184182
</div>
185183
{:else if app.installs_z_score_4w < -1}
186-
<div class="flex items-center gap-1 text-danger-600">
184+
<div class="flex items-center gap-1 text-danger-600-400">
187185
<TrendingDownIcon class="w-4 h-4" />
188186
<span class="text-xs font-medium">Declining</span>
189187
</div>
190188
{:else}
191-
<span class="text-xs text-primary-600-400">Steady</span>
189+
<span class="text-xs">Steady</span>
192190
{/if}
193191
</div>
194192
{/if}

frontend/src/routes/apps/[id]/+page.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@
121121
</span>
122122
</div>
123123
<div class="flex items-center gap-2">
124-
<span class="font-medium">Store First Crawled:</span>
124+
<span class="font-medium">AppGoblin First Crawled:</span>
125125
<span class="text-primary-900-100">{data.myapp.created_at}</span>
126126
</div>
127127
<div class="flex items-center gap-2">
128-
<span class="font-medium">Store Last Crawled:</span>
128+
<span class="font-medium">AppGoblin Last Crawled:</span>
129129
<span class="text-primary-900-100">{data.myapp.updated_at}</span>
130130
</div>
131131
</div>
@@ -163,7 +163,7 @@
163163
</WhiteCard>
164164
<WhiteCard>
165165
{#snippet title()}
166-
SDK Tracking Status
166+
AppGoblin SDK Scans
167167
{/snippet}
168168
<div class="space-y-2 p-2">
169169
{#if data.myapp.sdk_last_crawled}

0 commit comments

Comments
 (0)