feat: implement app tracking consent dialog and update tracking state management

This commit is contained in:
2025-12-07 00:46:33 +01:00
parent ad090ce38c
commit d67d58824b
5 changed files with 97 additions and 1 deletions

View File

@@ -15,7 +15,7 @@
{
"title": "EZPPLauncher",
"width": 1000,
"height": 700,
"height": 737,
"decorations": false,
"resizable": false,
"maximizable": false

View File

@@ -65,10 +65,15 @@ export class Config {
}
value(key: string) {
console.log('Accessing config key:', key, this.config[key]);
return {
set: <T>(val: T) => {
this.config[key] = val;
},
exists: () => {
console.log('Checking existence of key:', key, this.config[key] !== undefined);
return this.config[key] !== undefined;
},
get: <T>(fallback: T): T => {
return (this.config[key] as T) ?? fallback;
},

View File

@@ -14,6 +14,8 @@ export const newVersion = writable<Release | undefined>(undefined);
export const launcherStreams = writable<string[]>(['stable']);
export const launcherStream = writable<string>('stable');
export const trackingEnabled = writable<boolean>(false);
export const discordPresence = writable<boolean>(false);
export const presenceLoading = writable<boolean>(false);

View File

@@ -12,6 +12,7 @@
platform,
presenceLoading,
setupValues,
trackingEnabled,
} from '@/global';
import { onMount } from 'svelte';
import OsuCursor from '@/components/ui/osu-cursor/OsuCursor.svelte';
@@ -103,6 +104,7 @@
const config_reduce_animations = $userSettings.value('reduce_animations');
const config_osu_installation_path = $userSettings.value('osu_installation_path');
const config_discord_presence = $userSettings.value('discord_presence');
const config_tracking_enabled = $userSettings.value('tracking_consent');
patch.set(config_patching.get(true));
customCursor.set(config_custom_cursor.get(true));
@@ -110,6 +112,9 @@
reduceAnimations.set(config_reduce_animations.get(false));
osuInstallationPath.set(config_osu_installation_path.get(''));
discordPresence.set(config_discord_presence.get(true));
if (config_tracking_enabled.exists()) {
trackingEnabled.set(config_tracking_enabled.get(false));
}
patch.subscribe((val) => config_patching.set(val));
customCursor.subscribe((val) => config_custom_cursor.set(val));

View File

@@ -21,6 +21,7 @@
serverConnectionFails,
serverPing,
skins,
trackingEnabled,
} from '@/global';
import {
LoaderCircle,
@@ -111,6 +112,7 @@
import { EZPPActionStatus } from '@/types';
import * as presence from '@/presence';
import { expoOut } from 'svelte/easing';
import { onMount } from 'svelte';
const tabs = [
{ name: 'Home', key: 'home', show: true },
@@ -129,6 +131,8 @@
let launchInfo = $state('');
let launchError = $state<Error | undefined>(undefined);
let askForTrackingPermission = $state(false);
let downloadingUpdate = $state(false);
let selectedGamemode = $derived(
@@ -535,6 +539,16 @@
umami.track('app_launch_fail', { error: err });
}
};
onMount(() => {
const config = $userSettings;
const trackingConsent = config.value('tracking_consent');
if (trackingConsent.exists()) {
trackingEnabled.set(trackingConsent.get(false));
} else {
askForTrackingPermission = true;
}
});
</script>
<AlertDialog.Root open={launchError !== undefined}>
@@ -639,6 +653,59 @@
</AlertDialog.Content>
</AlertDialog.Root>
<AlertDialog.Root open={$newVersion === undefined && askForTrackingPermission}>
<AlertDialog.Content
class="bg-theme-950 border-theme-800 p-0"
escapeKeydownBehavior="ignore"
interactOutsideBehavior="ignore"
>
<div
class="flex flex-col items-center justify-center border-b border-theme-800 bg-black/40 rounded-t-lg p-3"
>
<img class="h-20 w-20" src={Logo} alt="logo" />
<span class="font-semibold text-xl">App Tracking Consent</span>
</div>
<div
class="flex flex-col items-center text-sm text-center bg-theme-900 border border-theme-800 rounded-lg mx-3 p-3"
>
<p class="mb-4">
We value your privacy. To enhance your experience and improve our services, we would like to
collect anonymous usage data. This data helps us understand how the application is used and
identify areas for improvement.
</p>
<p class="mb-4">
No personal information is collected, and all data is anonymized. You can choose to enable
or disable this tracking at any time in the application settings.
</p>
<p>
Do you consent to the collection of anonymous usage data to help us improve the application?
</p>
</div>
<div class="flex items-center justify-center mb-3 gap-4 mt-4">
<Button
onclick={async () => {
trackingEnabled.set(true);
const config = $userSettings;
config.value('tracking_consent').set(true);
await config.save();
askForTrackingPermission = false;
}}>Yes, I consent</Button
>
<Button
variant="outline"
onclick={async () => {
trackingEnabled.set(false);
const config = $userSettings;
config.value('tracking_consent').set(false);
await config.save();
askForTrackingPermission = false;
}}>No, I do not consent</Button
>
</div>
</AlertDialog.Content>
</AlertDialog.Root>
<AlertDialog.Root bind:open={$launching}>
<AlertDialog.Content
class="bg-theme-950 border-theme-800 p-0"
@@ -1191,6 +1258,23 @@
class="flex items-center justify-center w-5 h-5"
></Checkbox>
</div>
<div class="flex flex-col">
<Label class="text-sm" for="setting-reduce-animations">App Tracking</Label>
<div class="text-muted-foreground text-xs">
Allow anonymous usage data to be collected to help improve the application.
</div>
</div>
<Checkbox
id="setting-reduce-animations"
checked={$trackingEnabled}
onCheckedChange={async (e) => {
trackingEnabled.set(e);
$userSettings.value('tracking_consent').set(e);
await $userSettings.save();
}}
class="flex items-center justify-center w-5 h-5"
></Checkbox>
</div>
<div
class="grid grid-cols-[0.7fr_auto] gap-y-1 items-center border-theme-800 pl-6 pr-5 pb-4"