Compare commits

..

12 Commits

Author SHA1 Message Date
Moyasee
50bafbb7f6 refactor: improve notification handling in SidebarProfile component 2026-01-20 19:41:24 +02:00
Zamitto
7293afb618 Merge branch 'release/v3.8.0' 2026-01-15 08:43:06 -03:00
Zamitto
194e7918ca feat: dont setup ww feedback widget if user has no token 2026-01-15 08:42:33 -03:00
Zamitto
979958aca6 feat: update ww webRequest interceptor 2026-01-14 19:37:17 -03:00
Zamitto
6e92e0f79f fix: getLibrary throwing error 2026-01-14 00:37:22 -03:00
Zamitto
aef069d4c7 Merge branch 'release/v3.8.1' 2026-01-14 00:07:53 -03:00
Zamitto
1f447cc478 chore: add sentry var to build-renderer action 2026-01-14 00:05:55 -03:00
Zamitto
5d2dc3616c Merge pull request #1938 from hydralauncher/release/v3.8.1
sync main
2026-01-13 23:43:48 -03:00
Zamitto
1f9972f74e Merge pull request #1937 from hydralauncher/chore/add-sentry
chore: add sentry
2026-01-13 23:43:16 -03:00
Zamitto
3344f68408 feat: add semver for sentry 2026-01-13 23:42:22 -03:00
Zamitto
65be11cc07 chore: add sentry 2026-01-13 23:34:09 -03:00
Zamitto
96140e614c Merge pull request #1917 from hydralauncher/fix/friends-box-display
hotfix: add empty state for friends box and new translation key
2026-01-04 02:59:53 -03:00
8 changed files with 137 additions and 24 deletions

View File

@@ -42,6 +42,7 @@ jobs:
run: yarn build
env:
RENDERER_VITE_EXTERNAL_RESOURCES_URL: ${{ vars.EXTERNAL_RESOURCES_URL }}
RENDERER_VITE_SENTRY_DSN: ${{ vars.SENTRY_DSN }}
- name: Deploy to Cloudflare Pages
env:

View File

@@ -40,6 +40,7 @@
"@primer/octicons-react": "^19.9.0",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@reduxjs/toolkit": "^2.2.3",
"@sentry/react": "^10.33.0",
"@tiptap/extension-bold": "^3.6.2",
"@tiptap/extension-italic": "^3.6.2",
"@tiptap/extension-link": "^3.6.2",

View File

@@ -25,7 +25,7 @@ const getLibrary = async (): Promise<LibraryGame[]> => {
const achievements = await gameAchievementsSublevel.get(key);
unlockedAchievementCount =
achievements?.unlockedAchievements.length ?? 0;
achievements?.unlockedAchievements?.length ?? 0;
}
return {

View File

@@ -138,12 +138,21 @@ export class WindowManager {
(details, callback) => {
if (
details.webContentsId !== this.mainWindow?.webContents.id ||
details.url.includes("chatwoot") ||
details.url.includes("workwonders")
details.url.includes("chatwoot")
) {
return callback(details);
}
if (details.url.includes("workwonders")) {
return callback({
...details,
requestHeaders: {
Origin: "https://workwonders.app",
...details.requestHeaders,
},
});
}
const userAgent = new UserAgent();
callback({

View File

@@ -134,7 +134,10 @@ export function App() {
await workwondersRef.current.initChangelogWidget();
workwondersRef.current.initChangelogWidgetMini();
workwondersRef.current.initFeedbackWidget();
if (token) {
workwondersRef.current.initFeedbackWidget();
}
},
[workwondersRef]
);

View File

@@ -1,7 +1,7 @@
import { useNavigate } from "react-router-dom";
import { BellIcon } from "@primer/octicons-react";
import { useAppSelector, useUserDetails } from "@renderer/hooks";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
import { Avatar } from "../avatar/avatar";
@@ -10,6 +10,8 @@ import { logger } from "@renderer/logger";
import type { NotificationCountResponse } from "@types";
import "./sidebar-profile.scss";
const NOTIFICATION_POLL_INTERVAL_MS = 5 * 60 * 1000;
export function SidebarProfile() {
const navigate = useNavigate();
@@ -20,51 +22,78 @@ export function SidebarProfile() {
const { gameRunning } = useAppSelector((state) => state.gameRunning);
const [notificationCount, setNotificationCount] = useState(0);
const apiNotificationCountRef = useRef(0);
const userDetailsRef = useRef(userDetails);
const fetchNotificationCount = useCallback(async () => {
// Keep userDetailsRef in sync
useEffect(() => {
userDetailsRef.current = userDetails;
}, [userDetails]);
const fetchLocalNotificationCount = useCallback(async () => {
try {
const localCount = await window.electron.getLocalNotificationsCount();
setNotificationCount(localCount + apiNotificationCountRef.current);
} catch (error) {
logger.error("Failed to fetch local notification count", error);
}
}, []);
const fetchFullNotificationCount = useCallback(async () => {
try {
// Always fetch local notification count
const localCount = await window.electron.getLocalNotificationsCount();
// Fetch API notification count only if logged in
let apiCount = 0;
if (userDetails) {
if (userDetailsRef.current) {
try {
const response =
await window.electron.hydraApi.get<NotificationCountResponse>(
"/profile/notifications/count",
{ needsAuth: true }
);
apiCount = response.count;
apiNotificationCountRef.current = response.count;
} catch {
// Ignore API errors
}
} else {
apiNotificationCountRef.current = 0;
}
setNotificationCount(localCount + apiCount);
setNotificationCount(localCount + apiNotificationCountRef.current);
} catch (error) {
logger.error("Failed to fetch notification count", error);
}
}, [userDetails]);
}, []);
useEffect(() => {
fetchNotificationCount();
fetchFullNotificationCount();
const interval = setInterval(fetchNotificationCount, 60000);
const interval = setInterval(
fetchFullNotificationCount,
NOTIFICATION_POLL_INTERVAL_MS
);
return () => clearInterval(interval);
}, [fetchNotificationCount]);
}, [fetchFullNotificationCount]);
useEffect(() => {
if (userDetails) {
fetchFullNotificationCount();
} else {
apiNotificationCountRef.current = 0;
fetchLocalNotificationCount();
}
}, [userDetails, fetchFullNotificationCount, fetchLocalNotificationCount]);
useEffect(() => {
const unsubscribe = window.electron.onLocalNotificationCreated(() => {
fetchNotificationCount();
fetchLocalNotificationCount();
});
return () => unsubscribe();
}, [fetchNotificationCount]);
}, [fetchLocalNotificationCount]);
useEffect(() => {
const handleNotificationsChange = () => {
fetchNotificationCount();
fetchLocalNotificationCount();
};
window.addEventListener("notificationsChanged", handleNotificationsChange);
@@ -74,15 +103,18 @@ export function SidebarProfile() {
handleNotificationsChange
);
};
}, [fetchNotificationCount]);
}, [fetchLocalNotificationCount]);
useEffect(() => {
const unsubscribe = window.electron.onSyncNotificationCount(() => {
fetchNotificationCount();
});
const unsubscribe = window.electron.onSyncNotificationCount(
(notification) => {
apiNotificationCountRef.current = notification.notificationCount;
fetchLocalNotificationCount();
}
);
return () => unsubscribe();
}, [fetchNotificationCount]);
}, [fetchLocalNotificationCount]);
const handleProfileClick = () => {
if (userDetails === null) {

View File

@@ -21,6 +21,7 @@ import resources from "@locales";
import { logger } from "./logger";
import { addCookieInterceptor } from "./cookies";
import * as Sentry from "@sentry/react";
import { levelDBService } from "./services/leveldb.service";
import Catalogue from "./pages/catalogue/catalogue";
import Home from "./pages/home/home";
@@ -36,6 +37,18 @@ import { AchievementNotification } from "./pages/achievements/notification/achie
console.log = logger.log;
Sentry.init({
dsn: import.meta.env.RENDERER_VITE_SENTRY_DSN,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
tracesSampleRate: 0.5,
replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 0,
release: "hydra-launcher@" + (await window.electron.getVersion()),
});
const isStaging = await window.electron.isStaging();
addCookieInterceptor(isStaging);

View File

@@ -2174,6 +2174,60 @@
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz#5b2dd648a960b8fa00d76f2cc4eea2f03daa80f4"
integrity sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==
"@sentry-internal/browser-utils@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-10.33.0.tgz#4a5d98352267b63fcc449efe14627c0fc082089e"
integrity sha512-nDJFHAfiFifBfJB0OF6DV6BIsIV5uah4lDsV4UBAgPBf+YAHclO10y1gi2U/JMh58c+s4lXi9p+PI1TFXZ0c6w==
dependencies:
"@sentry/core" "10.33.0"
"@sentry-internal/feedback@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-10.33.0.tgz#5865b4a68d607bb48d8159a100464ae640a638e7"
integrity sha512-sN/VLWtEf0BeV6w6wldIpTxUQxNVc9o9tjLRQa8je1ZV2FCgXA124Iff/zsowsz82dLqtg7qp6GA5zYXVq+JMA==
dependencies:
"@sentry/core" "10.33.0"
"@sentry-internal/replay-canvas@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-10.33.0.tgz#9ea15b320618ad220e5d8f7c804a0d9ca55b04af"
integrity sha512-MTmP6uoAVzw4CCPeqCgCLsRSiOfGLxgyMFjGTCW3E7t62MJ9S0H5sLsQ34sHxXUa1gFU9UNAjEvRRpZ0JvWrPw==
dependencies:
"@sentry-internal/replay" "10.33.0"
"@sentry/core" "10.33.0"
"@sentry-internal/replay@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/replay/-/replay-10.33.0.tgz#8cfe3a353731fcd81e7afb646b6befeb0f9feb0f"
integrity sha512-UOU9PYxuXnPop3HoQ3l4Q7SZUXJC3Vmfm0Adgad8U03UcrThWIHYc5CxECSrVzfDFNOT7w9o7HQgRAgWxBPMXg==
dependencies:
"@sentry-internal/browser-utils" "10.33.0"
"@sentry/core" "10.33.0"
"@sentry/browser@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-10.33.0.tgz#33284952a1cdf43cdac15ac144c85e81e7cbaa93"
integrity sha512-iWiPjik9zetM84jKfk01UveW1J0+X7w8XmJ8+IrhTyNDBVUWCRJWD8FrksiN1dRSg5mFWgfMRzKMz27hAScRwg==
dependencies:
"@sentry-internal/browser-utils" "10.33.0"
"@sentry-internal/feedback" "10.33.0"
"@sentry-internal/replay" "10.33.0"
"@sentry-internal/replay-canvas" "10.33.0"
"@sentry/core" "10.33.0"
"@sentry/core@10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-10.33.0.tgz#ea4964fbec290503b419ccaf1a313924d30ad1c8"
integrity sha512-ehH1VSUclIHZKEZVdv+klofsFIh8FFzqA6AAV23RtLepptzA8wqQzUGraEuSN25sYcNmYJ0jti5U0Ys+WZv5Dw==
"@sentry/react@^10.33.0":
version "10.33.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-10.33.0.tgz#89a3be88d43e49de90943ad2ac86ee1664048097"
integrity sha512-iMdC2Iw54ibAccatJ5TjoLlIy3VotFteied7JFvOudgj1/2eBBeWthRobZ5p6/nAOpj4p9vJk0DeLrc012sd2g==
dependencies:
"@sentry/browser" "10.33.0"
"@sentry/core" "10.33.0"
"@sindresorhus/is@^4.0.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"