feat(analytics): add optional Aptabase event tracking UI

Integrate Aptabase analytics via a Tauri plugin and add a privacy
notice flow plus a settings dialog to control whether anonymous
usage events are sent. The app now tracks key user actions while
ensuring analytics never blocks core Git operations.

- Add analytics tracking helper and Aptabase plugin wiring
- Persist analytics consent in localStorage and gate tracking
- Introduce notice and settings dialogs, plus new event calls
This commit is contained in:
Christoph Brandau
2026-07-07 17:35:20 +02:00
parent d4ac449074
commit e503786211
13 changed files with 548 additions and 12 deletions
+117 -2
View File
@@ -439,7 +439,13 @@
/* --- App shell --- */
.shell { display: flex; flex-direction: column; height: 100%; background: transparent; }
.shell {
--app-titlebar-height: 42px;
display: flex;
flex-direction: column;
height: 100%;
background: transparent;
}
.shell-body {
display: flex;
@@ -453,10 +459,12 @@
/* --- Titlebar --- */
.titlebar {
position: relative;
z-index: 500;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
height: 42px;
height: var(--app-titlebar-height);
background:
linear-gradient(90deg, rgba(100,108,255,0.16), rgba(65,209,255,0.08), rgba(255,211,67,0.035)),
var(--color-bar);
@@ -2419,6 +2427,10 @@
background-image: none;
}
.app-chrome-backdrop {
top: var(--app-titlebar-height, 42px);
}
.dialog {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
@@ -2485,6 +2497,14 @@
max-height: calc(100vh - 32px);
overflow: auto;
}
.app-settings-dialog,
.analytics-notice-dialog {
display: block;
width: min(620px, calc(100vw - 32px));
height: auto;
max-height: calc(100vh - 32px);
overflow: auto;
}
.clone-repository-dialog {
display: block;
width: min(620px, calc(100vw - 32px));
@@ -2539,6 +2559,101 @@
gap: 14px;
padding: 16px;
}
.app-settings-form {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
}
.settings-section {
display: grid;
gap: 12px;
min-width: 0;
}
.settings-section > header {
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
padding-bottom: 10px;
border-bottom: 1px solid var(--color-border-subtle);
}
.settings-section > header svg {
color: var(--color-accent);
flex: 0 0 auto;
}
.settings-section h3 {
margin: 1px 0 0;
color: var(--color-ink);
font-size: 15px;
font-weight: 750;
}
.settings-toggle-row {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
align-items: start;
gap: 10px;
min-width: 0;
padding: 12px;
border: 1px solid var(--color-border-subtle);
border-radius: 8px;
background: #151827;
color: var(--color-ink-muted);
cursor: pointer;
}
.settings-toggle-row input {
width: 16px;
height: 16px;
margin-top: 2px;
accent-color: var(--color-accent);
}
.settings-toggle-row span {
display: grid;
gap: 4px;
min-width: 0;
}
.settings-toggle-row strong {
color: var(--color-ink);
font-size: 13px;
}
.settings-toggle-row small {
color: var(--color-ink-dim);
font-size: 12px;
line-height: 1.45;
}
.analytics-notice-body {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 14px;
padding: 18px 16px 16px;
}
.analytics-notice-icon {
display: grid;
place-items: center;
width: 44px;
height: 44px;
border: 1px solid rgba(65,209,255,0.28);
border-radius: 10px;
color: var(--color-accent);
background: rgba(65,209,255,0.08);
}
.analytics-notice-copy {
display: grid;
gap: 9px;
min-width: 0;
color: var(--color-ink-muted);
font-size: 13px;
line-height: 1.5;
}
.analytics-notice-copy p {
margin: 0;
}
.analytics-notice-toggle {
grid-column: 1 / -1;
}
.analytics-notice-footer {
align-items: center;
}
.ai-provider-options {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));