From 93944aad55248bf9671219f41d1c728846246d45 Mon Sep 17 00:00:00 2001 From: Uriel Date: Thu, 22 Aug 2024 17:12:28 +0200 Subject: [PATCH 1/5] start implementing sentry --- .github/workflows/build-gui.yml | 10 +- .github/workflows/gradle.yaml | 38 ++- gui/.gitignore | 3 + gui/package.json | 2 + gui/src/components/SerialDetectionModal.tsx | 2 +- gui/src/components/commons/Input.tsx | 4 +- gui/src/index.tsx | 30 ++ gui/vite.config.ts | 14 +- pnpm-lock.yaml | 321 ++++++++++++++++++++ 9 files changed, 406 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-gui.yml b/.github/workflows/build-gui.yml index 11aa25aed0..be25f1bbbd 100644 --- a/.github/workflows/build-gui.yml +++ b/.github/workflows/build-gui.yml @@ -79,11 +79,15 @@ jobs: node-version-file: '.node-version' cache: 'pnpm' + - name: Install dependencies + shell: bash + run: pnpm i + - name: Build shell: bash - run: | - pnpm i - pnpm run skipbundler --config $( ./gui/scripts/gitversion.mjs ) + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: pnpm run skipbundler --config $( ./gui/scripts/gitversion.mjs ) - if: matrix.os == 'windows-latest' name: Upload a Build Artifact (Windows) diff --git a/.github/workflows/gradle.yaml b/.github/workflows/gradle.yaml index d69ad4fc3f..a224da2c86 100644 --- a/.github/workflows/gradle.yaml +++ b/.github/workflows/gradle.yaml @@ -112,10 +112,13 @@ jobs: node-version-file: '.node-version' cache: 'pnpm' - - name: Build GUI - run: | - pnpm i - cd gui && pnpm run build + - name: Install dependencies + run: pnpm i + + - name: Build + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: cd gui && pnpm run build - name: Build with Gradle run: ./gradlew :server:android:assembleDebug @@ -180,10 +183,13 @@ jobs: node-version-file: '.node-version' cache: 'pnpm' + - name: Install dependencies + run: pnpm i + - name: Build - run: | - pnpm i - pnpm run tauri build --config $( ./gui/scripts/gitversion.mjs ) + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: pnpm run tauri build --config $( ./gui/scripts/gitversion.mjs ) - name: Make GUI tarball run: | @@ -255,11 +261,15 @@ jobs: node-version-file: '.node-version' cache: 'pnpm' - - name: Build + - name: Install dependencies run: | rustup target add x86_64-apple-darwin pnpm i - pnpm run tauri build --target universal-apple-darwin --config $( ./gui/scripts/gitversion.mjs ) + + - name: Build + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: pnpm run tauri build --target universal-apple-darwin --config $( ./gui/scripts/gitversion.mjs ) - name: Modify Application run: | @@ -327,11 +337,15 @@ jobs: node-version-file: '.node-version' cache: 'pnpm' + - name: Install dependencies + shell: bash + run: pnpm i + - name: Build shell: bash - run: | - pnpm i - pnpm run skipbundler --config $( ./gui/scripts/gitversion.mjs ) + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: pnpm run skipbundler --config $( ./gui/scripts/gitversion.mjs ) - name: Bundle to zips shell: bash diff --git a/gui/.gitignore b/gui/.gitignore index a1ac58f664..16713b8fbb 100644 --- a/gui/.gitignore +++ b/gui/.gitignore @@ -31,3 +31,6 @@ yarn-error.log* # eslint .eslintcache + +# Sentry Config File +.env.sentry-build-plugin diff --git a/gui/package.json b/gui/package.json index 0032e15c7b..41a516ac1e 100644 --- a/gui/package.json +++ b/gui/package.json @@ -9,6 +9,8 @@ "@formatjs/intl-localematcher": "^0.2.32", "@react-three/drei": "^9.107.0", "@react-three/fiber": "^8.16.8", + "@sentry/react": "^8.26.0", + "@sentry/vite-plugin": "^2.22.2", "@tauri-apps/api": "2.0.0-beta.14", "@tauri-apps/plugin-dialog": "2.0.0-beta.6", "@tauri-apps/plugin-fs": "2.0.0-beta.6", diff --git a/gui/src/components/SerialDetectionModal.tsx b/gui/src/components/SerialDetectionModal.tsx index 70b6597a06..82ef19dd4f 100644 --- a/gui/src/components/SerialDetectionModal.tsx +++ b/gui/src/components/SerialDetectionModal.tsx @@ -112,7 +112,7 @@ export function SerialDetectionModal() { {l10n.getString('serial_detection-new_device-p1')} -
+
=14.18'} + + '@sentry-internal/feedback@8.26.0': + resolution: {integrity: sha512-hQtw1gg8n6ERK1UH47F7ZI1zOsbhu0J2VX+TrnkpaQR2FgxDW1oe9Ja6oCV4CQKuR4w+1ZI/Kj4imSt0K33kEw==} + engines: {node: '>=14.18'} + + '@sentry-internal/replay-canvas@8.26.0': + resolution: {integrity: sha512-2CFQW6f9aJHIo/DqmqYa9PaYoLn1o36ywc0h8oyGrD4oPCbrnE5F++PmTdc71GBODu41HBn/yoCTLmxOD+UjpA==} + engines: {node: '>=14.18'} + + '@sentry-internal/replay@8.26.0': + resolution: {integrity: sha512-JDY7W2bswlp5c3483lKP4kcb75fHNwGNfwD8x8FsY9xMjv7nxeXjLpR5cCEk1XqPq2+n6w4j7mJOXhEXGiUIKg==} + engines: {node: '>=14.18'} + + '@sentry/babel-plugin-component-annotate@2.22.2': + resolution: {integrity: sha512-6kFAHGcs0npIC4HTt4ULs8uOfEucvMI7VW4hoyk17jhRaW8CbxzxfWCfIeRbDkE8pYwnARaq83tu025Hrk2zgA==} + engines: {node: '>= 14'} + + '@sentry/browser@8.26.0': + resolution: {integrity: sha512-e5s6eKlwLZWzTwQcBwqyAGZMMuQROW9Z677VzwkSyREWAIkKjfH2VBxHATnNGc0IVkNHjD7iH3ixo3C0rLKM3w==} + engines: {node: '>=14.18'} + + '@sentry/bundler-plugin-core@2.22.2': + resolution: {integrity: sha512-TwEEW4FeEJ5Mamp4fGnktfVjzN77KAW0xFQsEPuxZtOAPG17zX/PGvdyRX/TE1jkZWhTzqUDIdgzqlNLjyEnUw==} + engines: {node: '>= 14'} + + '@sentry/cli-darwin@2.33.1': + resolution: {integrity: sha512-+4/VIx/E1L2hChj5nGf5MHyEPHUNHJ/HoG5RY+B+vyEutGily1c1+DM2bum7RbD0xs6wKLIyup5F02guzSzG8A==} + engines: {node: '>=10'} + os: [darwin] + + '@sentry/cli-linux-arm64@2.33.1': + resolution: {integrity: sha512-DbGV56PRKOLsAZJX27Jt2uZ11QfQEMmWB4cIvxkKcFVE+LJP4MVA+MGGRUL6p+Bs1R9ZUuGbpKGtj0JiG6CoXw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux, freebsd] + + '@sentry/cli-linux-arm@2.33.1': + resolution: {integrity: sha512-zbxEvQju+tgNvzTOt635le4kS/Fbm2XC2RtYbCTs034Vb8xjrAxLnK0z1bQnStUV8BkeBHtsNVrG+NSQDym2wg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux, freebsd] + + '@sentry/cli-linux-i686@2.33.1': + resolution: {integrity: sha512-g2LS4oPXkPWOfKWukKzYp4FnXVRRSwBxhuQ9eSw2peeb58ZIObr4YKGOA/8HJRGkooBJIKGaAR2mH2Pk1TKaiA==} + engines: {node: '>=10'} + cpu: [x86, ia32] + os: [linux, freebsd] + + '@sentry/cli-linux-x64@2.33.1': + resolution: {integrity: sha512-IV3dcYV/ZcvO+VGu9U6kuxSdbsV2kzxaBwWUQxtzxJ+cOa7J8Hn1t0koKGtU53JVZNBa06qJWIcqgl4/pCuKIg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux, freebsd] + + '@sentry/cli-win32-i686@2.33.1': + resolution: {integrity: sha512-F7cJySvkpzIu7fnLKNHYwBzZYYwlhoDbAUnaFX0UZCN+5DNp/5LwTp37a5TWOsmCaHMZT4i9IO4SIsnNw16/zQ==} + engines: {node: '>=10'} + cpu: [x86, ia32] + os: [win32] + + '@sentry/cli-win32-x64@2.33.1': + resolution: {integrity: sha512-8VyRoJqtb2uQ8/bFRKNuACYZt7r+Xx0k2wXRGTyH05lCjAiVIXn7DiS2BxHFty7M1QEWUCMNsb/UC/x/Cu2wuA==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@sentry/cli@2.33.1': + resolution: {integrity: sha512-dUlZ4EFh98VFRPJ+f6OW3JEYQ7VvqGNMa0AMcmvk07ePNeK/GicAWmSQE4ZfJTTl80ul6HZw1kY01fGQOQlVRA==} + engines: {node: '>= 10'} + hasBin: true + + '@sentry/core@8.26.0': + resolution: {integrity: sha512-g/tVmTZD4GNbLFf++hKJfBpcCAtduFEMLnbfa9iT/QEZjlmP+EzY+GsH9bafM5VsNe8DiOUp+kJKWtShzlVdBA==} + engines: {node: '>=14.18'} + + '@sentry/react@8.26.0': + resolution: {integrity: sha512-dYoC0xzcqq8zmNMFoTWidhA7mVd3RDz/nAUn6C8yK/hkKA7bUknYCkhpESGLZfHaGwSKzeXRXKd/o/cgUVM9eA==} + engines: {node: '>=14.18'} + peerDependencies: + react: ^16.14.0 || 17.x || 18.x || 19.x + + '@sentry/types@8.26.0': + resolution: {integrity: sha512-zKmh6SWsJh630rpt7a9vP4Cm4m1C2gDTUqUiH565CajCL/4cePpNWYrNwalSqsOSL7B9OrczA1+n6a6XvND+ng==} + engines: {node: '>=14.18'} + + '@sentry/utils@8.26.0': + resolution: {integrity: sha512-xvlPU9Hd2BlyT+FhWHGNwnxWqdVRk2AHnDtVcW4Ma0Ri5EwS+uy4Jeik5UkSv8C5RVb9VlxFmS8LN3I1MPJsLw==} + engines: {node: '>=14.18'} + + '@sentry/vite-plugin@2.22.2': + resolution: {integrity: sha512-LJSNTw75UJq77v2jCan8cRh0w1u6W30jxQsbqF7YyyhhfjPTyFUXYday9RDDe84qDEnspbZmgeTSWTvaTGsBRg==} + engines: {node: '>= 14'} + '@tailwindcss/forms@0.5.7': resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} peerDependencies: @@ -1993,6 +2095,10 @@ packages: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} engines: {node: '>= 10.0.0'} + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -2442,6 +2548,10 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + draco3d@1.5.7: resolution: {integrity: sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==} @@ -2977,6 +3087,13 @@ packages: hls.js@1.3.5: resolution: {integrity: sha512-uybAvKS6uDe0MnWNEPnO0krWVr+8m2R0hJ/viql8H3MVK+itq8gGQuIYoFHL3rECkIpNH98Lw8YuuWMKZxp3Ew==} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} @@ -3375,6 +3492,10 @@ packages: '@types/three': '>=0.144.0' three: '>=0.144.0' + magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} + engines: {node: '>=12'} + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -3476,6 +3597,15 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} @@ -3891,6 +4021,10 @@ packages: peerDependencies: prettier: ^3.0.0 + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + promise-worker-transferable@1.0.4: resolution: {integrity: sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==} @@ -3901,6 +4035,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -4400,6 +4537,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + troika-three-text@0.49.1: resolution: {integrity: sha512-lXGWxgjJP9kw4i4Wh+0k0Q/7cRfS6iOME4knKht/KozPu9GcFA9NnNpRvehIhrUawq9B0ZRw+0oiFHgRO+4Wig==} peerDependencies: @@ -4510,6 +4650,9 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unplugin@1.0.1: + resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} + update-browserslist-db@1.0.16: resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} hasBin: true @@ -4576,10 +4719,16 @@ packages: webgl-sdf-generator@1.1.1: resolution: {integrity: sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==} + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webpack-sources@3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} + webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + webpack@5.91.0: resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} engines: {node: '>=10.13.0'} @@ -4590,6 +4739,9 @@ packages: webpack-cli: optional: true + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -6245,6 +6397,126 @@ snapshots: '@rushstack/eslint-patch@1.10.3': {} + '@sentry-internal/browser-utils@8.26.0': + dependencies: + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry-internal/feedback@8.26.0': + dependencies: + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry-internal/replay-canvas@8.26.0': + dependencies: + '@sentry-internal/replay': 8.26.0 + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry-internal/replay@8.26.0': + dependencies: + '@sentry-internal/browser-utils': 8.26.0 + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry/babel-plugin-component-annotate@2.22.2': {} + + '@sentry/browser@8.26.0': + dependencies: + '@sentry-internal/browser-utils': 8.26.0 + '@sentry-internal/feedback': 8.26.0 + '@sentry-internal/replay': 8.26.0 + '@sentry-internal/replay-canvas': 8.26.0 + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry/bundler-plugin-core@2.22.2': + dependencies: + '@babel/core': 7.24.7 + '@sentry/babel-plugin-component-annotate': 2.22.2 + '@sentry/cli': 2.33.1 + dotenv: 16.4.5 + find-up: 5.0.0 + glob: 9.3.5 + magic-string: 0.30.8 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@sentry/cli-darwin@2.33.1': + optional: true + + '@sentry/cli-linux-arm64@2.33.1': + optional: true + + '@sentry/cli-linux-arm@2.33.1': + optional: true + + '@sentry/cli-linux-i686@2.33.1': + optional: true + + '@sentry/cli-linux-x64@2.33.1': + optional: true + + '@sentry/cli-win32-i686@2.33.1': + optional: true + + '@sentry/cli-win32-x64@2.33.1': + optional: true + + '@sentry/cli@2.33.1': + dependencies: + https-proxy-agent: 5.0.1 + node-fetch: 2.7.0 + progress: 2.0.3 + proxy-from-env: 1.1.0 + which: 2.0.2 + optionalDependencies: + '@sentry/cli-darwin': 2.33.1 + '@sentry/cli-linux-arm': 2.33.1 + '@sentry/cli-linux-arm64': 2.33.1 + '@sentry/cli-linux-i686': 2.33.1 + '@sentry/cli-linux-x64': 2.33.1 + '@sentry/cli-win32-i686': 2.33.1 + '@sentry/cli-win32-x64': 2.33.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@sentry/core@8.26.0': + dependencies: + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + + '@sentry/react@8.26.0(react@18.3.1)': + dependencies: + '@sentry/browser': 8.26.0 + '@sentry/core': 8.26.0 + '@sentry/types': 8.26.0 + '@sentry/utils': 8.26.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + + '@sentry/types@8.26.0': {} + + '@sentry/utils@8.26.0': + dependencies: + '@sentry/types': 8.26.0 + + '@sentry/vite-plugin@2.22.2': + dependencies: + '@sentry/bundler-plugin-core': 2.22.2 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + '@tailwindcss/forms@0.5.7(tailwindcss@3.4.4(ts-node@9.1.1(typescript@5.4.5)))': dependencies: mini-svg-data-uri: 1.4.4 @@ -6692,6 +6964,12 @@ snapshots: address@1.2.2: {} + agent-base@6.0.2: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -7207,6 +7485,8 @@ snapshots: dependencies: esutils: 2.0.3 + dotenv@16.4.5: {} + draco3d@1.5.7: {} duplexer@0.1.2: {} @@ -7996,6 +8276,17 @@ snapshots: hls.js@1.3.5: {} + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + human-signals@1.1.1: {} human-signals@2.1.0: {} @@ -8359,6 +8650,10 @@ snapshots: '@types/three': 0.163.0 three: 0.163.0 + magic-string@0.30.8: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + make-error@1.3.6: {} matchmediaquery@0.4.2: @@ -8436,6 +8731,10 @@ snapshots: neo-async@2.6.2: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-releases@2.0.14: {} normalize-path@3.0.0: {} @@ -8881,6 +9180,8 @@ snapshots: prettier: 3.3.2 tslib: 2.6.3 + progress@2.0.3: {} + promise-worker-transferable@1.0.4: dependencies: is-promise: 2.2.2 @@ -8897,6 +9198,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proxy-from-env@1.1.0: {} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -9483,6 +9786,8 @@ snapshots: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + troika-three-text@0.49.1(three@0.163.0): dependencies: bidi-js: 1.0.3 @@ -9614,6 +9919,13 @@ snapshots: universalify@2.0.1: {} + unplugin@1.0.1: + dependencies: + acorn: 8.12.0 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + update-browserslist-db@1.0.16(browserslist@4.23.1): dependencies: browserslist: 4.23.1 @@ -9658,8 +9970,12 @@ snapshots: webgl-sdf-generator@1.1.1: {} + webidl-conversions@3.0.1: {} + webpack-sources@3.2.3: {} + webpack-virtual-modules@0.5.0: {} + webpack@5.91.0: dependencies: '@types/eslint-scope': 3.7.7 @@ -9691,6 +10007,11 @@ snapshots: - esbuild - uglify-js + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 From ec9845364d5fc858b3841a140a9e2cc3d2289cdf Mon Sep 17 00:00:00 2001 From: Uriel Date: Fri, 23 Aug 2024 00:32:22 +0200 Subject: [PATCH 2/5] continue integration --- gui/public/i18n/en/translation.ftl | 13 ++- gui/src/App.tsx | 7 +- gui/src/AppLayout.tsx | 13 ++- gui/src/components/commons/Typography.tsx | 3 + .../components/commons/icon/ArrowIcons.tsx | 19 ++++ .../components/onboarding/pages/WifiCreds.tsx | 2 +- .../body-proportions/BodyProportions.tsx | 2 +- .../autobone-steps/VerifyResults.tsx | 4 +- .../components/settings/SettingsSidebar.tsx | 3 + .../settings/pages/InterfaceSettings.tsx | 87 ++++++++++++++----- .../components/tracker/TrackerSettings.tsx | 4 +- gui/src/hooks/config.ts | 8 +- gui/src/index.tsx | 30 ------- gui/src/utils/sentry.ts | 66 ++++++++++++++ 14 files changed, 195 insertions(+), 66 deletions(-) create mode 100644 gui/src/utils/sentry.ts diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index 783ab650a4..c77f45181f 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -271,6 +271,7 @@ settings-sidebar-utils = Utilities settings-sidebar-serial = Serial console settings-sidebar-appearance = Appearance settings-sidebar-notifications = Notifications +settings-sidebar-behavior = Behavior ## SteamVR settings settings-general-steamvr = SteamVR @@ -420,9 +421,6 @@ settings-general-gesture_control-numberTrackersOverThreshold-description = Incre ## Appearance settings settings-interface-appearance = Appearance -settings-general-interface-dev_mode = Developer Mode -settings-general-interface-dev_mode-description = This mode can be useful if you need in-depth data or to interact with connected trackers on a more advanced level. -settings-general-interface-dev_mode-label = Developer Mode settings-general-interface-theme = Color theme settings-general-interface-lang = Select language settings-general-interface-lang-description = Change the default language you want to use. @@ -448,6 +446,12 @@ settings-general-interface-feedback_sound-volume = Feedback sound volume settings-general-interface-connected_trackers_warning = Connected trackers warning settings-general-interface-connected_trackers_warning-description = This option will show a pop-up every time you try exiting SlimeVR while having one or more connected trackers. It reminds you to turn off your trackers when you are done to preserve battery life. settings-general-interface-connected_trackers_warning-label = Connected trackers warning on exit + +## Behavior settings +settings-interface-behavior = Behavior +settings-general-interface-dev_mode = Developer Mode +settings-general-interface-dev_mode-description = This mode can be useful if you need in-depth data or to interact with connected trackers on a more advanced level. +settings-general-interface-dev_mode-label = Developer Mode settings-general-interface-use_tray = Minimize to system tray settings-general-interface-use_tray-description = Lets you close the window without closing the SlimeVR Server so you can continue using it without having the GUI bothering you. settings-general-interface-use_tray-label = Minimize to system tray @@ -459,6 +463,9 @@ settings-general-interface-discord_presence-message = { $amount -> [one] Using 1 tracker *[other] Using { $amount } trackers } +settings-interface-behavior-data_collection = Data collection +settings-interface-behavior-data_collection-description = Data collection +settings-interface-behavior-data_collection-label = Data collection ## Serial settings settings-serial = Serial Console diff --git a/gui/src/App.tsx b/gui/src/App.tsx index cb9ce9bded..0c8454e620 100644 --- a/gui/src/App.tsx +++ b/gui/src/App.tsx @@ -55,12 +55,15 @@ import { AppLayout } from './AppLayout'; import { Preload } from './components/Preload'; import { UnknownDeviceModal } from './components/UnknownDeviceModal'; import { useDiscordPresence } from './hooks/discord-presence'; +import { withSentryReactRouterV6Routing } from '@sentry/react'; export const GH_REPO = 'SlimeVR/SlimeVR-Server'; export const VersionContext = createContext(''); export const DOCS_SITE = 'https://docs.slimevr.dev'; export const SLIMEVR_DISCORD = 'https://discord.gg/slimevr'; +const SentryRoutes = withSentryReactRouterV6Routing(Routes); + function Layout() { const { isMobile } = useBreakpoint('mobile'); useDiscordPresence(); @@ -70,7 +73,7 @@ function Layout() { - + }> }> - + ); } diff --git a/gui/src/AppLayout.tsx b/gui/src/AppLayout.tsx index 8b4f8b94c9..795839a417 100644 --- a/gui/src/AppLayout.tsx +++ b/gui/src/AppLayout.tsx @@ -1,6 +1,8 @@ -import { useLayoutEffect } from 'react'; +import { useEffect, useLayoutEffect } from 'react'; import { useConfig } from './hooks/config'; import { Outlet, useNavigate } from 'react-router-dom'; +import { getSentryOrCompute } from './utils/sentry'; +import { log } from './utils/logging'; export function AppLayout() { const { loading, config } = useConfig(); @@ -33,6 +35,15 @@ export function AppLayout() { } }, [config?.doneOnboarding]); + useEffect(() => { + if (config?.dataCollection !== undefined) { + log( + `${config.dataCollection ? 'Enabled' : 'Disabled'} error logging with Sentry.` + ); + getSentryOrCompute(config.dataCollection); + } + }, [config?.dataCollection]); + // const location = useLocation(); // const navigationType = useNavigationType(); // useEffect(() => { diff --git a/gui/src/components/commons/Typography.tsx b/gui/src/components/commons/Typography.tsx index 2bbd38fb5f..fb1917ede7 100644 --- a/gui/src/components/commons/Typography.tsx +++ b/gui/src/components/commons/Typography.tsx @@ -11,6 +11,7 @@ export function Typography({ italic = false, truncate = false, textAlign, + sentryMask = false, }: { variant?: | 'main-title' @@ -37,6 +38,7 @@ export function Typography({ | 'text-start' | 'text-end'; children?: ReactNode; + sentryMask?: boolean; }) { const tag = useMemo(() => { const tags = { @@ -72,6 +74,7 @@ export function Typography({ truncate && 'leading-3 text-ellipsis', truncate && (config?.textSize ?? 12) > 12 && 'line-clamp-1', truncate && (config?.textSize ?? 12) <= 12 && 'line-clamp-2', + sentryMask && 'sentry-mask', ]), }, children || [] diff --git a/gui/src/components/commons/icon/ArrowIcons.tsx b/gui/src/components/commons/icon/ArrowIcons.tsx index d431e51102..7084edd1cb 100644 --- a/gui/src/components/commons/icon/ArrowIcons.tsx +++ b/gui/src/components/commons/icon/ArrowIcons.tsx @@ -62,3 +62,22 @@ export function ArrowRightIcon() { ); } + +export function ArrowRightLeftIcon() { + return ( + + + + ); +} diff --git a/gui/src/components/onboarding/pages/WifiCreds.tsx b/gui/src/components/onboarding/pages/WifiCreds.tsx index 14dd158256..d161341aba 100644 --- a/gui/src/components/onboarding/pages/WifiCreds.tsx +++ b/gui/src/components/onboarding/pages/WifiCreds.tsx @@ -52,7 +52,7 @@ export function WifiCredsPage() {
{l10n.getString(label)} - + {type === LabelType.GroupPart ? /* Make number rounding so it's based on .5 decimals */ percentageFormat.format(Math.round(value * 200) / 200) diff --git a/gui/src/components/onboarding/pages/body-proportions/autobone-steps/VerifyResults.tsx b/gui/src/components/onboarding/pages/body-proportions/autobone-steps/VerifyResults.tsx index 807154a098..e9b39afe24 100644 --- a/gui/src/components/onboarding/pages/body-proportions/autobone-steps/VerifyResults.tsx +++ b/gui/src/components/onboarding/pages/body-proportions/autobone-steps/VerifyResults.tsx @@ -66,7 +66,9 @@ export function VerifyResultsStep({ {bodyParts?.map(({ bone, label, value }) => (
{label} - {(value * 100).toFixed(2)} CM + + {(value * 100).toFixed(2)} CM +
))} {hasCalibration === ProcessStatus.PENDING && diff --git a/gui/src/components/settings/SettingsSidebar.tsx b/gui/src/components/settings/SettingsSidebar.tsx index 5199bff755..e6e95fbd1f 100644 --- a/gui/src/components/settings/SettingsSidebar.tsx +++ b/gui/src/components/settings/SettingsSidebar.tsx @@ -73,6 +73,9 @@ export function SettingsSidebar() { {l10n.getString('settings-sidebar-notifications')} + + {l10n.getString('settings-sidebar-behavior')} + {l10n.getString('settings-sidebar-appearance')} diff --git a/gui/src/components/settings/pages/InterfaceSettings.tsx b/gui/src/components/settings/pages/InterfaceSettings.tsx index 11cc46d48e..e984edcf6f 100644 --- a/gui/src/components/settings/pages/InterfaceSettings.tsx +++ b/gui/src/components/settings/pages/InterfaceSettings.tsx @@ -16,21 +16,25 @@ import { LangSelector } from '@/components/commons/LangSelector'; import { BellIcon } from '@/components/commons/icon/BellIcon'; import { Range } from '@/components/commons/Range'; import { Dropdown } from '@/components/commons/Dropdown'; +import { ArrowRightLeftIcon } from '@/components/commons/icon/ArrowIcons'; interface InterfaceSettingsForm { appearance: { - devmode: boolean; theme: string; textSize: number; fonts: string; }; + behavior: { + devmode: boolean; + useTray: boolean; + discordPresence: boolean; + dataCollection: boolean; + }; notifications: { watchNewDevices: boolean; feedbackSound: boolean; feedbackSoundVolume: number; connectedTrackersWarning: boolean; - useTray: boolean; - discordPresence: boolean; }; } @@ -41,7 +45,6 @@ export function InterfaceSettings() { const { control, watch, handleSubmit } = useForm({ defaultValues: { appearance: { - devmode: config?.debug ?? defaultConfig.debug, theme: config?.theme ?? defaultConfig.theme, textSize: config?.textSize ?? defaultConfig.textSize, fonts: config?.fonts.join(',') ?? defaultConfig.fonts.join(','), @@ -55,25 +58,32 @@ export function InterfaceSettings() { connectedTrackersWarning: config?.connectedTrackersWarning ?? defaultConfig.connectedTrackersWarning, + }, + behavior: { + devmode: config?.debug ?? defaultConfig.debug, useTray: config?.useTray ?? defaultConfig.useTray ?? false, discordPresence: config?.discordPresence ?? defaultConfig.discordPresence, + dataCollection: config?.dataCollection ?? defaultConfig.dataCollection, }, }, }); const onSubmit = (values: InterfaceSettingsForm) => { setConfig({ - debug: values.appearance.devmode, watchNewDevices: values.notifications.watchNewDevices, feedbackSound: values.notifications.feedbackSound, feedbackSoundVolume: values.notifications.feedbackSoundVolume, + connectedTrackersWarning: values.notifications.connectedTrackersWarning, + theme: values.appearance.theme, fonts: values.appearance.fonts.split(','), textSize: values.appearance.textSize, - connectedTrackersWarning: values.notifications.connectedTrackersWarning, - useTray: values.notifications.useTray, - discordPresence: values.notifications.discordPresence, + + useTray: values.behavior.useTray, + discordPresence: values.behavior.discordPresence, + debug: values.behavior.devmode, + dataCollection: values.behavior.dataCollection, }); }; @@ -186,6 +196,17 @@ export function InterfaceSettings() { )} />
+ + + + } + id="behavior" + > + <> + + {l10n.getString('settings-interface-behavior')} + {l10n.getString('settings-general-interface-use_tray')} @@ -202,7 +223,7 @@ export function InterfaceSettings() { variant="toggle" control={control} outlined - name="notifications.useTray" + name="behavior.useTray" label={l10n.getString( 'settings-general-interface-use_tray-label' )} @@ -224,23 +245,12 @@ export function InterfaceSettings() { variant="toggle" control={control} outlined - name="notifications.discordPresence" + name="behavior.discordPresence" label={l10n.getString( 'settings-general-interface-discord_presence-label' )} />
- - - - } - id="appearance" - > - <> - - {l10n.getString('settings-interface-appearance')} - {l10n.getString('settings-general-interface-dev_mode')} @@ -257,13 +267,46 @@ export function InterfaceSettings() { variant="toggle" control={control} outlined - name="appearance.devmode" + name="behavior.devmode" label={l10n.getString( 'settings-general-interface-dev_mode-label' )} /> + + {l10n.getString('settings-interface-behavior-data_collection')} + +
+ + {l10n.getString( + 'settings-interface-behavior-data_collection-description' + )} + +
+
+ +
+ +
+ + } + id="appearance" + > + <> + + {l10n.getString('settings-interface-appearance')} + +
{l10n.getString('settings-general-interface-theme')} diff --git a/gui/src/components/tracker/TrackerSettings.tsx b/gui/src/components/tracker/TrackerSettings.tsx index e74ed22fed..9d47ea07f9 100644 --- a/gui/src/components/tracker/TrackerSettings.tsx +++ b/gui/src/components/tracker/TrackerSettings.tsx @@ -219,7 +219,7 @@ export function TrackerSettingsPage() { {l10n.getString('tracker-infos-custom_name')} - + {tracker?.tracker.info?.customName || '--'}
@@ -403,7 +403,7 @@ export function TrackerSettingsPage() { )} -
+
{l10n.getString('tracker-settings-name_section')} diff --git a/gui/src/hooks/config.ts b/gui/src/hooks/config.ts index 864591aa12..cb6e335240 100644 --- a/gui/src/hooks/config.ts +++ b/gui/src/hooks/config.ts @@ -37,6 +37,7 @@ export interface Config { mirrorView: boolean; assignMode: AssignMode; discordPresence: boolean; + dataCollection: boolean; } export interface ConfigContext { @@ -62,6 +63,7 @@ export const defaultConfig: Omit = { mirrorView: true, assignMode: AssignMode.Core, discordPresence: false, + dataCollection: false, }; interface CrossStorage { @@ -69,9 +71,9 @@ interface CrossStorage { get(key: string): Promise; } -const tauriStore: CrossStorage = new Store('gui-settings.dat'); +export const TAURI_STORE: CrossStorage = new Store('gui-settings.dat'); -const localStore: CrossStorage = { +export const LOCAL_STORE: CrossStorage = { get: async (key) => localStorage.getItem(key), set: async (key, value) => localStorage.setItem(key, value), }; @@ -84,7 +86,7 @@ export function useConfigProvider(): ConfigContext { const [currConfig, set] = useState(null); const [loading, setLoading] = useState(false); const tauri = useIsTauri(); - const store = useMemo(() => (tauri ? tauriStore : localStore), [tauri]); + const store = useMemo(() => (tauri ? TAURI_STORE : LOCAL_STORE), [tauri]); useDebouncedEffect( () => { diff --git a/gui/src/index.tsx b/gui/src/index.tsx index d54b28e363..666cb682e0 100644 --- a/gui/src/index.tsx +++ b/gui/src/index.tsx @@ -6,36 +6,6 @@ import Modal from 'react-modal'; import App from './App'; import { AppLocalizationProvider } from './i18n/config'; import './index.scss'; -import * as Sentry from '@sentry/react'; - -Sentry.init({ - dsn: 'https://e9ef9f8541352c50cff8600ba520d348@o4507810483535872.ingest.de.sentry.io/4507810579284048', - integrations: [ - Sentry.browserTracingIntegration(), - Sentry.browserProfilingIntegration(), - Sentry.replayIntegration({ - maskAllText: false, - maskAllInputs: false, - blockAllMedia: false, - }), - ], - environment: import.meta.env.MODE, - release: - (__VERSION_TAG__ || __COMMIT_HASH__) + (__GIT_CLEAN__ ? '' : '-dirty'), - // Tracing - tracesSampleRate: import.meta.env.PROD ? 0.5 : 1.0, // Capture 10% of the transactions - // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled - tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/], - // Set profilesSampleRate to 1.0 to profile every transaction. - // Since profilesSampleRate is relative to tracesSampleRate, - // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate - // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would - // results in 25% of transactions being profiled (0.5*0.5=0.25) - profilesSampleRate: 0.2, - // Session Replay - replaysSessionSampleRate: import.meta.env.PROD ? 0.1 : 1.0, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. - replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. -}); Modal.setAppElement('#root'); diff --git a/gui/src/utils/sentry.ts b/gui/src/utils/sentry.ts new file mode 100644 index 0000000000..64751ee314 --- /dev/null +++ b/gui/src/utils/sentry.ts @@ -0,0 +1,66 @@ +import * as Sentry from '@sentry/react'; +import { error, log } from './logging'; +import { useEffect } from 'react'; +import { + createRoutesFromChildren, + matchRoutes, + useLocation, + useNavigationType, +} from 'react-router-dom'; + +export function getSentryOrCompute(enabled = false) { + const client = Sentry.getClient(); + if (client) { + client.getOptions().enabled = enabled; + return client; + } + if (!enabled) return; + + const newClient = Sentry.init({ + dsn: 'https://e9ef9f8541352c50cff8600ba520d348@o4507810483535872.ingest.de.sentry.io/4507810579284048', + integrations: [ + Sentry.reactRouterV6BrowserTracingIntegration({ + useEffect: useEffect, + useLocation, + useNavigationType, + createRoutesFromChildren, + matchRoutes, + }), + Sentry.browserProfilingIntegration(), + Sentry.replayIntegration({ + maskAllText: false, + maskAllInputs: false, + blockAllMedia: false, + }), + ], + environment: import.meta.env.MODE, + release: (__VERSION_TAG__ || __COMMIT_HASH__) + (__GIT_CLEAN__ ? '' : '-dirty'), + // Tracing + tracesSampleRate: import.meta.env.PROD ? 0.5 : 1.0, // Capture 50% of the transactions + // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled + tracePropagationTargets: [ + 'localhost', + /^https:\/\/fw-tool-(?:api|bucket)\.slimevr\.io/, + /^tauri:\/\/localhost/, + /^http:\/\/tauri.localhost/, + ], + // Set profilesSampleRate to 1.0 to profile every transaction. + // Since profilesSampleRate is relative to tracesSampleRate, + // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate + // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would + // results in 25% of transactions being profiled (0.5*0.5=0.25) + profilesSampleRate: 0.2, + // Session Replay + replaysSessionSampleRate: import.meta.env.PROD ? 0.1 : 1.0, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. + replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. + enabled, + }); + + if (!newClient) { + error('Couldn\'t initialize Sentry for error logging'); + } else { + log('Initialized the Sentry client'); + } + + return newClient; +} From 384a0c225252d0e4b34d9f8734b46ef72ff61945 Mon Sep 17 00:00:00 2001 From: Uriel Date: Fri, 23 Aug 2024 17:17:26 +0200 Subject: [PATCH 3/5] smol improvements --- gui/src/AppLayout.tsx | 4 ---- gui/src/utils/sentry.ts | 4 +++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/gui/src/AppLayout.tsx b/gui/src/AppLayout.tsx index 795839a417..2bf511445b 100644 --- a/gui/src/AppLayout.tsx +++ b/gui/src/AppLayout.tsx @@ -2,7 +2,6 @@ import { useEffect, useLayoutEffect } from 'react'; import { useConfig } from './hooks/config'; import { Outlet, useNavigate } from 'react-router-dom'; import { getSentryOrCompute } from './utils/sentry'; -import { log } from './utils/logging'; export function AppLayout() { const { loading, config } = useConfig(); @@ -37,9 +36,6 @@ export function AppLayout() { useEffect(() => { if (config?.dataCollection !== undefined) { - log( - `${config.dataCollection ? 'Enabled' : 'Disabled'} error logging with Sentry.` - ); getSentryOrCompute(config.dataCollection); } }, [config?.dataCollection]); diff --git a/gui/src/utils/sentry.ts b/gui/src/utils/sentry.ts index 64751ee314..7018a30213 100644 --- a/gui/src/utils/sentry.ts +++ b/gui/src/utils/sentry.ts @@ -11,6 +11,7 @@ import { export function getSentryOrCompute(enabled = false) { const client = Sentry.getClient(); if (client) { + log(`${enabled ? 'Enabled' : 'Disabled'} error logging with Sentry.`); client.getOptions().enabled = enabled; return client; } @@ -33,6 +34,7 @@ export function getSentryOrCompute(enabled = false) { blockAllMedia: false, }), ], + beforeSend: (ev) => (newClient?.getOptions().enabled ? ev : null), environment: import.meta.env.MODE, release: (__VERSION_TAG__ || __COMMIT_HASH__) + (__GIT_CLEAN__ ? '' : '-dirty'), // Tracing @@ -57,7 +59,7 @@ export function getSentryOrCompute(enabled = false) { }); if (!newClient) { - error('Couldn\'t initialize Sentry for error logging'); + error('Couldnt initialize Sentry for error logging'); } else { log('Initialized the Sentry client'); } From 9371938a008dd75028c5bf876e85b2926e813be2 Mon Sep 17 00:00:00 2001 From: Uriel Date: Sat, 7 Sep 2024 13:46:01 +0200 Subject: [PATCH 4/5] improve text and config of sentry --- gui/public/i18n/en/translation.ftl | 6 +++--- gui/src/AppLayout.tsx | 6 +++--- .../settings/pages/InterfaceSettings.tsx | 14 +++++++------- gui/src/hooks/config.ts | 4 ++-- gui/src/utils/sentry.ts | 7 ------- 5 files changed, 15 insertions(+), 22 deletions(-) diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index c77f45181f..100d31a788 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -463,9 +463,9 @@ settings-general-interface-discord_presence-message = { $amount -> [one] Using 1 tracker *[other] Using { $amount } trackers } -settings-interface-behavior-data_collection = Data collection -settings-interface-behavior-data_collection-description = Data collection -settings-interface-behavior-data_collection-label = Data collection +settings-interface-behavior-error_tracking = Error tracking via Sentry +settings-interface-behavior-error_tracking-description = we need to write comprehensive and easy to read text for this! +settings-interface-behavior-error_tracking-label = Error tracking ## Serial settings settings-serial = Serial Console diff --git a/gui/src/AppLayout.tsx b/gui/src/AppLayout.tsx index 2bf511445b..d88d20bf87 100644 --- a/gui/src/AppLayout.tsx +++ b/gui/src/AppLayout.tsx @@ -35,10 +35,10 @@ export function AppLayout() { }, [config?.doneOnboarding]); useEffect(() => { - if (config?.dataCollection !== undefined) { - getSentryOrCompute(config.dataCollection); + if (config?.errorTracking !== undefined) { + getSentryOrCompute(config.errorTracking); } - }, [config?.dataCollection]); + }, [config?.errorTracking]); // const location = useLocation(); // const navigationType = useNavigationType(); diff --git a/gui/src/components/settings/pages/InterfaceSettings.tsx b/gui/src/components/settings/pages/InterfaceSettings.tsx index e984edcf6f..e8e5152dd9 100644 --- a/gui/src/components/settings/pages/InterfaceSettings.tsx +++ b/gui/src/components/settings/pages/InterfaceSettings.tsx @@ -28,7 +28,7 @@ interface InterfaceSettingsForm { devmode: boolean; useTray: boolean; discordPresence: boolean; - dataCollection: boolean; + errorTracking: boolean; }; notifications: { watchNewDevices: boolean; @@ -64,7 +64,7 @@ export function InterfaceSettings() { useTray: config?.useTray ?? defaultConfig.useTray ?? false, discordPresence: config?.discordPresence ?? defaultConfig.discordPresence, - dataCollection: config?.dataCollection ?? defaultConfig.dataCollection, + errorTracking: config?.errorTracking ?? defaultConfig.errorTracking, }, }, }); @@ -83,7 +83,7 @@ export function InterfaceSettings() { useTray: values.behavior.useTray, discordPresence: values.behavior.discordPresence, debug: values.behavior.devmode, - dataCollection: values.behavior.dataCollection, + errorTracking: values.behavior.errorTracking, }); }; @@ -275,12 +275,12 @@ export function InterfaceSettings() {
- {l10n.getString('settings-interface-behavior-data_collection')} + {l10n.getString('settings-interface-behavior-error_tracking')}
{l10n.getString( - 'settings-interface-behavior-data_collection-description' + 'settings-interface-behavior-error_tracking-description' )}
@@ -289,9 +289,9 @@ export function InterfaceSettings() { variant="toggle" control={control} outlined - name="behavior.dataCollection" + name="behavior.errorTracking" label={l10n.getString( - 'settings-interface-behavior-data_collection-label' + 'settings-interface-behavior-error_tracking-label' )} />
diff --git a/gui/src/hooks/config.ts b/gui/src/hooks/config.ts index cb6e335240..4160287af7 100644 --- a/gui/src/hooks/config.ts +++ b/gui/src/hooks/config.ts @@ -37,7 +37,7 @@ export interface Config { mirrorView: boolean; assignMode: AssignMode; discordPresence: boolean; - dataCollection: boolean; + errorTracking: boolean; } export interface ConfigContext { @@ -63,7 +63,7 @@ export const defaultConfig: Omit = { mirrorView: true, assignMode: AssignMode.Core, discordPresence: false, - dataCollection: false, + errorTracking: false, }; interface CrossStorage { diff --git a/gui/src/utils/sentry.ts b/gui/src/utils/sentry.ts index 7018a30213..bd43a651cb 100644 --- a/gui/src/utils/sentry.ts +++ b/gui/src/utils/sentry.ts @@ -39,13 +39,6 @@ export function getSentryOrCompute(enabled = false) { release: (__VERSION_TAG__ || __COMMIT_HASH__) + (__GIT_CLEAN__ ? '' : '-dirty'), // Tracing tracesSampleRate: import.meta.env.PROD ? 0.5 : 1.0, // Capture 50% of the transactions - // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled - tracePropagationTargets: [ - 'localhost', - /^https:\/\/fw-tool-(?:api|bucket)\.slimevr\.io/, - /^tauri:\/\/localhost/, - /^http:\/\/tauri.localhost/, - ], // Set profilesSampleRate to 1.0 to profile every transaction. // Since profilesSampleRate is relative to tracesSampleRate, // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate From 716bc7bcf6b6c929b03b73d2af0d68bdfc0c42f1 Mon Sep 17 00:00:00 2001 From: Uriel Date: Thu, 12 Dec 2024 19:00:39 +0100 Subject: [PATCH 5/5] add modal and text --- gui/public/i18n/en/translation.ftl | 17 ++++-- gui/src/AppLayout.tsx | 2 +- gui/src/components/ErrorConsentModal.tsx | 54 +++++++++++++++++++ gui/src/components/TopBar.tsx | 6 +++ gui/src/components/commons/BaseModal.tsx | 6 ++- .../components/settings/SettingsLayout.tsx | 2 +- .../settings/pages/InterfaceSettings.tsx | 7 ++- gui/src/hooks/config.ts | 4 +- gui/src/utils/sentry.ts | 6 +-- 9 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 gui/src/components/ErrorConsentModal.tsx diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index a170d1ef1b..cf2e1bafa4 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -544,9 +544,12 @@ settings-general-interface-discord_presence-message = { $amount -> [one] Using 1 tracker *[other] Using { $amount } trackers } -settings-interface-behavior-error_tracking = Error tracking via Sentry -settings-interface-behavior-error_tracking-description = we need to write comprehensive and easy to read text for this! -settings-interface-behavior-error_tracking-label = Error tracking +settings-interface-behavior-error_tracking = Error collection via Sentry.io +settings-interface-behavior-error_tracking-description = + We send errors, load times and operating system information to be able to fix issues found on SlimeVR, we collect these via Sentry.io. + + We don't collect any of your personal information (not even your IP address), but we do care that you want to give your consent for it. +settings-interface-behavior-error_tracking-label = Send errors to developers ## Serial settings settings-serial = Serial Console @@ -1069,3 +1072,11 @@ unknown_device-modal-description = There is a new tracker with MAC address {$ Do you want to connect it to SlimeVR? unknown_device-modal-confirm = Sure! unknown_device-modal-forget = Ignore it + +## Error collection consent modal +error_collection_modal-title = Can we collect errors? +error_collection_modal-description = { settings-interface-behavior-error_tracking-description } + + You can later change this on the interface section of settings +error_collection_modal-confirm = I agree +error_collection_modal-cancel = I don't want to diff --git a/gui/src/AppLayout.tsx b/gui/src/AppLayout.tsx index d88d20bf87..70708dfcdf 100644 --- a/gui/src/AppLayout.tsx +++ b/gui/src/AppLayout.tsx @@ -36,7 +36,7 @@ export function AppLayout() { useEffect(() => { if (config?.errorTracking !== undefined) { - getSentryOrCompute(config.errorTracking); + getSentryOrCompute(config.errorTracking ?? false); } }, [config?.errorTracking]); diff --git a/gui/src/components/ErrorConsentModal.tsx b/gui/src/components/ErrorConsentModal.tsx new file mode 100644 index 0000000000..f2a40ec1e1 --- /dev/null +++ b/gui/src/components/ErrorConsentModal.tsx @@ -0,0 +1,54 @@ +import { useLocalization } from '@fluent/react'; +import { BaseModal } from './commons/BaseModal'; +import { Button } from './commons/Button'; +import { Typography } from './commons/Typography'; + +export function ErrorConsentModal({ + isOpen = true, + cancel, + accept, +}: { + /** + * Is the parent/sibling component opened? + */ + isOpen: boolean; + /** + * Function to trigger when you still want to close the app + */ + accept: () => void; + /** + * Function to trigger when cancelling app close + */ + cancel?: () => void; +}) { + const { l10n } = useLocalization(); + + return ( + +
+ <> +
+
+ + {l10n.getString('error_collection_modal-title')} + + + {l10n.getString('error_collection_modal-description')} + +
+
+ + + + +
+
+ ); +} diff --git a/gui/src/components/TopBar.tsx b/gui/src/components/TopBar.tsx index 63973af56a..bf195e9ce1 100644 --- a/gui/src/components/TopBar.tsx +++ b/gui/src/components/TopBar.tsx @@ -30,6 +30,7 @@ import { TrayOrExitModal } from './TrayOrExitModal'; import { error } from '@/utils/logging'; import { useDoubleTap } from 'use-double-tap'; import { isTrayAvailable } from '@/utils/tauri'; +import { ErrorConsentModal } from './ErrorConsentModal'; export function VersionTag() { return ( @@ -304,6 +305,11 @@ export function TopBar({ accept={() => closeApp()} cancel={() => setConnectedTrackerWarning(false)} > + setConfig({ errorTracking: true })} + cancel={() => setConfig({ errorTracking: false })} + /> ); } diff --git a/gui/src/components/commons/BaseModal.tsx b/gui/src/components/commons/BaseModal.tsx index 1139a5ec32..fc6b55a596 100644 --- a/gui/src/components/commons/BaseModal.tsx +++ b/gui/src/components/commons/BaseModal.tsx @@ -5,17 +5,19 @@ import ReactModal from 'react-modal'; export function BaseModal({ children, important = false, + closeable = true, ...props }: { isOpen: boolean; children: ReactNode; important?: boolean; + closeable?: boolean; } & ReactModal.Props) { return (
- + {l10n.getString( 'settings-interface-behavior-error_tracking-description' )} @@ -331,7 +330,7 @@ export function InterfaceSettings() {
- = { mirrorView: true, assignMode: AssignMode.Core, discordPresence: false, - errorTracking: false, + errorTracking: null, decorations: false, showNavbarOnboarding: true, }; diff --git a/gui/src/utils/sentry.ts b/gui/src/utils/sentry.ts index bd43a651cb..bb8437a857 100644 --- a/gui/src/utils/sentry.ts +++ b/gui/src/utils/sentry.ts @@ -21,7 +21,7 @@ export function getSentryOrCompute(enabled = false) { dsn: 'https://e9ef9f8541352c50cff8600ba520d348@o4507810483535872.ingest.de.sentry.io/4507810579284048', integrations: [ Sentry.reactRouterV6BrowserTracingIntegration({ - useEffect: useEffect, + useEffect, useLocation, useNavigationType, createRoutesFromChildren, @@ -29,8 +29,8 @@ export function getSentryOrCompute(enabled = false) { }), Sentry.browserProfilingIntegration(), Sentry.replayIntegration({ - maskAllText: false, - maskAllInputs: false, + maskAllText: true, + maskAllInputs: true, blockAllMedia: false, }), ],