feat: Add opt-out setting for anonymous usage reporting (#743)
* refactor: align VS Code update checks with web runtime parity - VS Code now uses file-based installId (shared with web server) - Accepts platform/arch from webview for consistent behavior - Usage data collection now matches web implementation * feat: Add opt-out setting for anonymous usage reporting in Appearance - Add privacy control in Appearance settings to opt-out of anonymous usage reports - Usage data includes only app version, platform, and runtime - no personal data or code collected - Setting persists across all runtimes and controls the reportUsage parameter in update checks
This commit is contained in:
committed by
GitHub
parent
53c2a0d919
commit
64b55025e1
@@ -110,6 +110,7 @@ const VisualSectionContent: React.FC = () => {
|
||||
'spacing',
|
||||
'inputBarOffset',
|
||||
...(!isVSCode ? ['terminalQuickKeys' as const] : []),
|
||||
'reportUsage',
|
||||
]} />;
|
||||
};
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ const normalizeUserMessageRenderingMode = (mode: unknown): 'markdown' | 'plain'
|
||||
return mode === 'markdown' ? 'markdown' : 'plain';
|
||||
};
|
||||
|
||||
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'activityRenderMode' | 'stickyUserHeader' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'reasoning' | 'showToolFileIcons' | 'expandedTools' | 'queueMode' | 'terminalQuickKeys' | 'persistDraft' | 'inputSpellcheck';
|
||||
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'activityRenderMode' | 'stickyUserHeader' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'reasoning' | 'showToolFileIcons' | 'expandedTools' | 'queueMode' | 'terminalQuickKeys' | 'persistDraft' | 'inputSpellcheck' | 'reportUsage';
|
||||
|
||||
interface OpenChamberVisualSettingsProps {
|
||||
/** Which settings to show. If undefined, shows all. */
|
||||
@@ -210,6 +210,14 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
|
||||
const [themesReloading, setThemesReloading] = React.useState(false);
|
||||
const [chatRenderPreviewTick, setChatRenderPreviewTick] = React.useState(0);
|
||||
const reportUsage = useUIStore(state => state.reportUsage);
|
||||
const setReportUsage = useUIStore(state => state.setReportUsage);
|
||||
|
||||
// Sync reportUsage changes to server settings
|
||||
const handleReportUsageChange = React.useCallback((enabled: boolean) => {
|
||||
setReportUsage(enabled);
|
||||
void updateDesktopSettings({ reportUsage: enabled });
|
||||
}, [setReportUsage]);
|
||||
|
||||
const shouldAnimateChatPreview = isSettingsDialogOpen
|
||||
&& (visibleSettings ? visibleSettings.includes('chatRenderMode') : true);
|
||||
@@ -1244,6 +1252,42 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* --- Privacy & Data --- */}
|
||||
{shouldShow('reportUsage') && (
|
||||
<div className="space-y-3">
|
||||
<section className="px-2 pb-2 pt-0">
|
||||
<h4 className="typography-ui-header font-medium text-foreground mb-2">Privacy</h4>
|
||||
<div className="flex items-start gap-2 py-1.5">
|
||||
<Checkbox
|
||||
checked={reportUsage}
|
||||
onChange={handleReportUsageChange}
|
||||
ariaLabel="Send anonymous usage reports"
|
||||
/>
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<div
|
||||
className="group flex cursor-pointer"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-pressed={reportUsage}
|
||||
onClick={() => handleReportUsageChange(!reportUsage)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
handleReportUsageChange(!reportUsage);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span className="typography-ui-label text-foreground">Send anonymous usage reports</span>
|
||||
</div>
|
||||
<span className="typography-meta text-muted-foreground pointer-events-none">
|
||||
Helps us understand which app versions are actively used so we can prioritize improvements. Only app version, platform, and runtime are collected - no personal data or code.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user