mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-19 09:13:57 +00:00
Merge pull request #1498 from hydralauncher/feat/auto-install-on-linux-and-friend-request-notification
feat: auto install update option on linux + new friend request notification
This commit is contained in:
13
.github/workflows/trigger-lp.yml
vendored
Normal file
13
.github/workflows/trigger-lp.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Trigger Landing Page Build
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Trigger Landing Page build
|
||||
run: curl --location --request POST '${{ secrets.LP_TRIGGER_DEPLOY_URL }}'
|
||||
File diff suppressed because one or more lines are too long
@@ -340,7 +340,9 @@
|
||||
"import_theme": "Import theme",
|
||||
"import_theme_description": "You will import {{theme}} from the theme store",
|
||||
"error_importing_theme": "Error importing theme",
|
||||
"theme_imported": "Theme imported successfully"
|
||||
"theme_imported": "Theme imported successfully",
|
||||
"enable_friend_request_notifications": "When a friend request is received",
|
||||
"enable_auto_install": "Download updates automatically"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download complete",
|
||||
@@ -351,7 +353,9 @@
|
||||
"new_update_available": "Version {{version}} available",
|
||||
"restart_to_install_update": "Restart Hydra to install the update",
|
||||
"notification_achievement_unlocked_title": "Achievement unlocked for {{game}}",
|
||||
"notification_achievement_unlocked_body": "{{achievement}} and other {{count}} were unlocked"
|
||||
"notification_achievement_unlocked_body": "{{achievement}} and other {{count}} were unlocked",
|
||||
"new_friend_request_description": "You have received a new friend request",
|
||||
"new_friend_request_title": "New friend request"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Open Hydra",
|
||||
|
||||
@@ -304,7 +304,6 @@
|
||||
"no_email_account": "No has configurado un correo aún",
|
||||
"no_subscription": "Disfruta Hydra de la mejor manera",
|
||||
"no_users_blocked": "No tienes usuarios bloqueados",
|
||||
"notifications": "Notificaciones",
|
||||
"renew_subscription": "Renovar Hydra Cloud",
|
||||
"subscription_active_until": "Tu Hydra Cloud está activa hasta {{date}}",
|
||||
"subscription_expired_at": "Tú suscripción expiró el {{date}}",
|
||||
@@ -341,7 +340,9 @@
|
||||
"torbox_account_linked": "Cuenta de TorBox vinculada",
|
||||
"torbox_description": "TorBox es tu servicio premium de seedbox que rivaliza incluso a los mejores servidores del mercado.",
|
||||
"unset_theme": "Desactivar tema",
|
||||
"web_store": "Tienda Web"
|
||||
"web_store": "Tienda Web",
|
||||
"enable_friend_request_notifications": "Cuando se recibe una solicitud de amistad",
|
||||
"enable_auto_install": "Descargar actualizaciones automáticamente"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Descarga completada",
|
||||
@@ -352,7 +353,9 @@
|
||||
"new_update_available": "Version {{version}} disponible",
|
||||
"restart_to_install_update": "Reinicia Hydra para instalar la actualización",
|
||||
"notification_achievement_unlocked_title": "Logro desbloqueado de {{game}}",
|
||||
"notification_achievement_unlocked_body": "{{achievement}} y otros {{count}} fueron desbloqueados"
|
||||
"notification_achievement_unlocked_body": "{{achievement}} y otros {{count}} fueron desbloqueados",
|
||||
"new_friend_request_title": "Nueva solicitud de amistad",
|
||||
"new_friend_request_description": "Has recibido una nueva solicitud de amistad"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Abrir Hydra",
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
},
|
||||
"header": {
|
||||
"search": "Buscar jogos",
|
||||
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Resultados da busca",
|
||||
@@ -328,7 +327,9 @@
|
||||
"import_theme": "Importar tema",
|
||||
"import_theme_description": "Você irá importar {{theme}} da loja de temas",
|
||||
"error_importing_theme": "Erro ao importar tema",
|
||||
"theme_imported": "Tema importado com sucesso"
|
||||
"theme_imported": "Tema importado com sucesso",
|
||||
"enable_friend_request_notifications": "Quando um pedido de amizade é recebido",
|
||||
"enable_auto_install": "Baixar atualizações automaticamente"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download concluído",
|
||||
@@ -337,7 +338,9 @@
|
||||
"repack_count_one": "{{count}} novo repack",
|
||||
"repack_count_other": "{{count}} novos repacks",
|
||||
"new_update_available": "Versão {{version}} disponível",
|
||||
"restart_to_install_update": "Reinicie o Hydra para instalar a nova versão"
|
||||
"restart_to_install_update": "Reinicie o Hydra para instalar a nova versão",
|
||||
"new_friend_request_title": "Novo pedido de amizade",
|
||||
"new_friend_request_description": "Você recebeu um novo pedido de amizade"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Abrir Hydra",
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
},
|
||||
"header": {
|
||||
"search": "Procurar jogos",
|
||||
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Transferências",
|
||||
"search_results": "Resultados da pesquisa",
|
||||
@@ -281,6 +280,7 @@
|
||||
"blocked_users": "Utilizadores bloqueados",
|
||||
"user_unblocked": "Utilizador desbloqueado",
|
||||
"enable_achievement_notifications": "Quando uma conquista é desbloqueada",
|
||||
"enable_friend_request_notifications": "Quando um pedido de amizade é recebido",
|
||||
"launch_minimized": "Iniciar Hydra minimizado",
|
||||
"disable_nsfw_alert": "Desativar alertas NSFW",
|
||||
"seed_after_download_complete": "Semear após concluir o download",
|
||||
@@ -338,7 +338,9 @@
|
||||
"repack_count_one": "{{count}} novo repack",
|
||||
"repack_count_other": "{{count}} novos repacks",
|
||||
"new_update_available": "Versão {{version}} disponível",
|
||||
"restart_to_install_update": "Reinicia o Hydra para instalar a nova versão"
|
||||
"restart_to_install_update": "Reinicia o Hydra para instalar a nova versão",
|
||||
"new_friend_request_title": "Novo pedido de amizade",
|
||||
"new_friend_request_description": "Recebeste um novo pedido de amizade"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Abrir o Hydra",
|
||||
|
||||
@@ -338,7 +338,9 @@
|
||||
"import_theme": "Импортировать тему",
|
||||
"import_theme_description": "Вы импортируете {{theme}} из магазина тем",
|
||||
"error_importing_theme": "Ошибка при импорте темы",
|
||||
"theme_imported": "Тема успешно импортирована"
|
||||
"theme_imported": "Тема успешно импортирована",
|
||||
"enable_friend_request_notifications": "При получении запроса на добавление в друзья",
|
||||
"enable_auto_install": "Загружать обновления автоматически"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Загрузка завершена",
|
||||
@@ -349,7 +351,9 @@
|
||||
"new_update_available": "Доступна новая версия {{version}}",
|
||||
"restart_to_install_update": "Перезапустите Hydra для установки обновления",
|
||||
"notification_achievement_unlocked_title": "Достижение разблокировано для {{game}}",
|
||||
"notification_achievement_unlocked_body": "были разблокированы {{achievement}} и другие {{count}}"
|
||||
"notification_achievement_unlocked_body": "были разблокированы {{achievement}} и другие {{count}}",
|
||||
"new_friend_request_title": "Новый запрос на добавление в друзья",
|
||||
"new_friend_request_description": "Вы получили новый запрос на добавление в друзья"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Открыть Hydra",
|
||||
|
||||
@@ -31,3 +31,5 @@ export const achievementSoundPath = app.isPackaged
|
||||
export const backupsPath = path.join(app.getPath("userData"), "Backups");
|
||||
|
||||
export const appVersion = app.getVersion() + (isStaging ? "-staging" : "");
|
||||
|
||||
export const MAIN_LOOP_INTERVAL = 1500;
|
||||
|
||||
@@ -4,11 +4,15 @@ import updater from "electron-updater";
|
||||
|
||||
const { autoUpdater } = updater;
|
||||
|
||||
const restartAndInstallUpdate = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
export const restartAndInstallUpdate = () => {
|
||||
autoUpdater.removeAllListeners();
|
||||
if (app.isPackaged) {
|
||||
autoUpdater.quitAndInstall(false);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("restartAndInstallUpdate", restartAndInstallUpdate);
|
||||
const restartAndInstallUpdateEvent = async (
|
||||
_event: Electron.IpcMainInvokeEvent
|
||||
) => restartAndInstallUpdate();
|
||||
|
||||
registerEvent("restartAndInstallUpdate", restartAndInstallUpdateEvent);
|
||||
|
||||
@@ -1,17 +1,59 @@
|
||||
import { MAIN_LOOP_INTERVAL } from "@main/constants";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { HydraApi } from "@main/services";
|
||||
import { HydraApi, WindowManager } from "@main/services";
|
||||
import { publishNewFriendRequestNotification } from "@main/services/notifications";
|
||||
import { UserNotLoggedInError } from "@shared";
|
||||
import type { FriendRequestSync } from "@types";
|
||||
|
||||
const syncFriendRequests = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
return HydraApi.get<FriendRequestSync>(`/profile/friend-requests/sync`).catch(
|
||||
(err) => {
|
||||
if (err instanceof UserNotLoggedInError) {
|
||||
return { friendRequests: [] };
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
interface SyncState {
|
||||
friendRequestCount: number | null;
|
||||
tick: number;
|
||||
}
|
||||
|
||||
const ticksToUpdate = (2 * 60 * 1000) / MAIN_LOOP_INTERVAL; // 2 minutes
|
||||
|
||||
const syncState: SyncState = {
|
||||
friendRequestCount: null,
|
||||
tick: 0,
|
||||
};
|
||||
|
||||
registerEvent("syncFriendRequests", syncFriendRequests);
|
||||
const syncFriendRequests = async () => {
|
||||
return HydraApi.get<FriendRequestSync>(`/profile/friend-requests/sync`)
|
||||
.then((res) => {
|
||||
if (
|
||||
syncState.friendRequestCount != null &&
|
||||
syncState.friendRequestCount < res.friendRequestCount
|
||||
) {
|
||||
publishNewFriendRequestNotification();
|
||||
}
|
||||
|
||||
syncState.friendRequestCount = res.friendRequestCount;
|
||||
|
||||
WindowManager.mainWindow?.webContents.send(
|
||||
"on-sync-friend-requests",
|
||||
res
|
||||
);
|
||||
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err instanceof UserNotLoggedInError) {
|
||||
return { friendRequestCount: 0 } as FriendRequestSync;
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
|
||||
const syncFriendRequestsEvent = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
return syncFriendRequests();
|
||||
};
|
||||
|
||||
export const watchFriendRequests = async () => {
|
||||
if (syncState.tick % ticksToUpdate === 0) {
|
||||
await syncFriendRequests();
|
||||
}
|
||||
|
||||
syncState.tick++;
|
||||
};
|
||||
|
||||
registerEvent("syncFriendRequests", syncFriendRequestsEvent);
|
||||
|
||||
@@ -3,18 +3,21 @@ import { DownloadManager } from "./download";
|
||||
import { watchProcesses } from "./process-watcher";
|
||||
import { AchievementWatcherManager } from "./achievements/achievement-watcher-manager";
|
||||
import { UpdateManager } from "./update-manager";
|
||||
import { watchFriendRequests } from "@main/events/profile/sync-friend-requests";
|
||||
import { MAIN_LOOP_INTERVAL } from "@main/constants";
|
||||
|
||||
export const startMainLoop = async () => {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
await Promise.allSettled([
|
||||
watchProcesses(),
|
||||
watchFriendRequests(),
|
||||
DownloadManager.watchDownloads(),
|
||||
AchievementWatcherManager.watchAchievements(),
|
||||
DownloadManager.getSeedStatus(),
|
||||
UpdateManager.checkForUpdatePeriodically(),
|
||||
]);
|
||||
|
||||
await sleep(1500);
|
||||
await sleep(MAIN_LOOP_INTERVAL);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ import { logger } from "../logger";
|
||||
import { WindowManager } from "../window-manager";
|
||||
import type { Game, UserPreferences } from "@types";
|
||||
import { db, levelKeys } from "@main/level";
|
||||
import { restartAndInstallUpdate } from "@main/events/autoupdater/restart-and-install-update";
|
||||
|
||||
async function downloadImage(url: string | null) {
|
||||
if (!url) return undefined;
|
||||
@@ -72,10 +73,33 @@ export const publishNotificationUpdateReadyToInstall = async (
|
||||
ns: "notifications",
|
||||
}),
|
||||
icon: trayIcon,
|
||||
}).show();
|
||||
})
|
||||
.on("click", () => {
|
||||
restartAndInstallUpdate();
|
||||
})
|
||||
.show();
|
||||
};
|
||||
|
||||
export const publishNewFriendRequestNotification = async () => {};
|
||||
export const publishNewFriendRequestNotification = async () => {
|
||||
const userPreferences = await db.get<string, UserPreferences | null>(
|
||||
levelKeys.userPreferences,
|
||||
{
|
||||
valueEncoding: "json",
|
||||
}
|
||||
);
|
||||
|
||||
if (!userPreferences?.friendRequestNotificationsEnabled) return;
|
||||
|
||||
new Notification({
|
||||
title: t("new_friend_request_title", {
|
||||
ns: "notifications",
|
||||
}),
|
||||
body: t("new_friend_request_description", {
|
||||
ns: "notifications",
|
||||
}),
|
||||
icon: trayIcon,
|
||||
}).show();
|
||||
};
|
||||
|
||||
export const publishCombinedNewAchievementNotification = async (
|
||||
achievementCount,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import updater, { UpdateInfo } from "electron-updater";
|
||||
import { logger, WindowManager } from "@main/services";
|
||||
import { AppUpdaterEvent } from "@types";
|
||||
import { AppUpdaterEvent, UserPreferences } from "@types";
|
||||
import { app } from "electron";
|
||||
import { publishNotificationUpdateReadyToInstall } from "@main/services/notifications";
|
||||
|
||||
const isAutoInstallAvailable =
|
||||
process.platform !== "darwin" && process.env.PORTABLE_EXECUTABLE_FILE == null;
|
||||
import { db, levelKeys } from "@main/level";
|
||||
import { MAIN_LOOP_INTERVAL } from "@main/constants";
|
||||
|
||||
const { autoUpdater } = updater;
|
||||
const sendEventsForDebug = false;
|
||||
const ticksToUpdate = (50 * 60 * 1000) / MAIN_LOOP_INTERVAL; // 50 minutes
|
||||
|
||||
export class UpdateManager {
|
||||
private static hasNotified = false;
|
||||
@@ -16,7 +16,7 @@ export class UpdateManager {
|
||||
private static checkTick = 0;
|
||||
|
||||
private static mockValuesForDebug() {
|
||||
this.sendEvent({ type: "update-available", info: { version: "1.3.0" } });
|
||||
this.sendEvent({ type: "update-available", info: { version: "3.3.1" } });
|
||||
this.sendEvent({ type: "update-downloaded" });
|
||||
}
|
||||
|
||||
@@ -24,7 +24,27 @@ export class UpdateManager {
|
||||
WindowManager.mainWindow?.webContents.send("autoUpdaterEvent", event);
|
||||
}
|
||||
|
||||
public static checkForUpdates() {
|
||||
private static async isAutoInstallEnabled() {
|
||||
if (process.platform === "darwin") return false;
|
||||
if (process.platform === "win32") {
|
||||
return process.env.PORTABLE_EXECUTABLE_FILE == null;
|
||||
}
|
||||
|
||||
if (process.platform === "linux") {
|
||||
const userPreferences = await db.get<string, UserPreferences | null>(
|
||||
levelKeys.userPreferences,
|
||||
{
|
||||
valueEncoding: "json",
|
||||
}
|
||||
);
|
||||
|
||||
return userPreferences?.enableAutoInstall === true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async checkForUpdates() {
|
||||
autoUpdater
|
||||
.once("update-available", (info: UpdateInfo) => {
|
||||
this.sendEvent({ type: "update-available", info });
|
||||
@@ -39,6 +59,8 @@ export class UpdateManager {
|
||||
}
|
||||
});
|
||||
|
||||
const isAutoInstallAvailable = await this.isAutoInstallEnabled();
|
||||
|
||||
if (app.isPackaged) {
|
||||
autoUpdater.autoDownload = isAutoInstallAvailable;
|
||||
autoUpdater.checkForUpdates().then((result) => {
|
||||
@@ -52,7 +74,7 @@ export class UpdateManager {
|
||||
}
|
||||
|
||||
public static checkForUpdatePeriodically() {
|
||||
if (this.checkTick % 2000 == 0) {
|
||||
if (this.checkTick % ticksToUpdate == 0) {
|
||||
this.checkForUpdates();
|
||||
}
|
||||
this.checkTick++;
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
SeedingStatus,
|
||||
GameAchievement,
|
||||
Theme,
|
||||
FriendRequestSync,
|
||||
} from "@types";
|
||||
import type { AuthPage, CatalogueCategory } from "@shared";
|
||||
import type { AxiosProgressEvent } from "axios";
|
||||
@@ -306,6 +307,15 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
ipcRenderer.invoke("processProfileImage", imagePath),
|
||||
getFriendRequests: () => ipcRenderer.invoke("getFriendRequests"),
|
||||
syncFriendRequests: () => ipcRenderer.invoke("syncFriendRequests"),
|
||||
onSyncFriendRequests: (cb: (friendRequests: FriendRequestSync) => void) => {
|
||||
const listener = (
|
||||
_event: Electron.IpcRendererEvent,
|
||||
friendRequests: FriendRequestSync
|
||||
) => cb(friendRequests);
|
||||
ipcRenderer.on("on-sync-friend-requests", listener);
|
||||
return () =>
|
||||
ipcRenderer.removeListener("on-sync-friend-requests", listener);
|
||||
},
|
||||
updateFriendRequest: (userId: string, action: FriendRequestAction) =>
|
||||
ipcRenderer.invoke("updateFriendRequest", userId, action),
|
||||
sendFriendRequest: (userId: string) =>
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
setUserDetails,
|
||||
setProfileBackground,
|
||||
setGameRunning,
|
||||
setFriendRequestCount,
|
||||
} from "@renderer/features";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UserFriendModal } from "./pages/shared-modals/user-friend-modal";
|
||||
@@ -51,7 +52,6 @@ export function App() {
|
||||
isFriendsModalVisible,
|
||||
friendRequetsModalTab,
|
||||
friendModalUserId,
|
||||
syncFriendRequests,
|
||||
hideFriendsModal,
|
||||
fetchUserDetails,
|
||||
updateUserDetails,
|
||||
@@ -123,7 +123,7 @@ export function App() {
|
||||
.then((response) => {
|
||||
if (response) {
|
||||
updateUserDetails(response);
|
||||
syncFriendRequests();
|
||||
window.electron.syncFriendRequests();
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -134,23 +134,27 @@ export function App() {
|
||||
$script.src = `${import.meta.env.RENDERER_VITE_EXTERNAL_RESOURCES_URL}/bundle.js?t=${Date.now()}`;
|
||||
document.head.appendChild($script);
|
||||
});
|
||||
}, [fetchUserDetails, syncFriendRequests, updateUserDetails, dispatch]);
|
||||
}, [fetchUserDetails, updateUserDetails, dispatch]);
|
||||
|
||||
const onSignIn = useCallback(() => {
|
||||
fetchUserDetails().then((response) => {
|
||||
if (response) {
|
||||
updateUserDetails(response);
|
||||
syncFriendRequests();
|
||||
window.electron.syncFriendRequests();
|
||||
showSuccessToast(t("successfully_signed_in"));
|
||||
}
|
||||
});
|
||||
}, [
|
||||
fetchUserDetails,
|
||||
syncFriendRequests,
|
||||
t,
|
||||
showSuccessToast,
|
||||
updateUserDetails,
|
||||
]);
|
||||
}, [fetchUserDetails, t, showSuccessToast, updateUserDetails]);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = window.electron.onSyncFriendRequests((result) => {
|
||||
dispatch(setFriendRequestCount(result.friendRequestCount));
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = window.electron.onGamesRunning((gamesRunning) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { PeopleIcon } from "@primer/octicons-react";
|
||||
import { useAppSelector, useUserDetails } from "@renderer/hooks";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal";
|
||||
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||
@@ -9,19 +9,13 @@ import { Avatar } from "../avatar/avatar";
|
||||
import { AuthPage } from "@shared";
|
||||
import "./sidebar-profile.scss";
|
||||
|
||||
const LONG_POLLING_INTERVAL = 120_000;
|
||||
|
||||
export function SidebarProfile() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation("sidebar");
|
||||
|
||||
const {
|
||||
userDetails,
|
||||
friendRequestCount,
|
||||
showFriendsModal,
|
||||
syncFriendRequests,
|
||||
} = useUserDetails();
|
||||
const { userDetails, friendRequestCount, showFriendsModal } =
|
||||
useUserDetails();
|
||||
|
||||
const { gameRunning } = useAppSelector((state) => state.gameRunning);
|
||||
|
||||
@@ -34,16 +28,6 @@ export function SidebarProfile() {
|
||||
navigate(`/profile/${userDetails.id}`);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const pollingInterval = setInterval(() => {
|
||||
syncFriendRequests();
|
||||
}, LONG_POLLING_INTERVAL);
|
||||
|
||||
return () => {
|
||||
clearInterval(pollingInterval);
|
||||
};
|
||||
}, [syncFriendRequests]);
|
||||
|
||||
const friendsButton = useMemo(() => {
|
||||
if (!userDetails) return null;
|
||||
|
||||
|
||||
5
src/renderer/src/declaration.d.ts
vendored
5
src/renderer/src/declaration.d.ts
vendored
@@ -280,7 +280,10 @@ declare global {
|
||||
path: string
|
||||
) => Promise<{ imagePath: string; mimeType: string }>;
|
||||
getFriendRequests: () => Promise<FriendRequest[]>;
|
||||
syncFriendRequests: () => Promise<FriendRequestSync>;
|
||||
syncFriendRequests: () => Promise<void>;
|
||||
onSyncFriendRequests: (
|
||||
cb: (friendRequests: FriendRequestSync) => void
|
||||
) => () => Electron.IpcRenderer;
|
||||
updateFriendRequest: (
|
||||
userId: string,
|
||||
action: FriendRequestAction
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
setFriendRequests,
|
||||
setFriendsModalVisible,
|
||||
setFriendsModalHidden,
|
||||
setFriendRequestCount,
|
||||
} from "@renderer/features";
|
||||
import type {
|
||||
FriendRequestAction,
|
||||
@@ -88,24 +87,15 @@ export function useUserDetails() {
|
||||
]
|
||||
);
|
||||
|
||||
const syncFriendRequests = useCallback(async () => {
|
||||
return window.electron
|
||||
.syncFriendRequests()
|
||||
.then((sync) => {
|
||||
dispatch(setFriendRequestCount(sync.friendRequestCount));
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [dispatch]);
|
||||
|
||||
const fetchFriendRequests = useCallback(async () => {
|
||||
return window.electron
|
||||
.getFriendRequests()
|
||||
.then((friendRequests) => {
|
||||
syncFriendRequests();
|
||||
window.electron.syncFriendRequests();
|
||||
dispatch(setFriendRequests(friendRequests));
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [dispatch, syncFriendRequests]);
|
||||
}, [dispatch]);
|
||||
|
||||
const showFriendsModal = useCallback(
|
||||
(initialTab: UserFriendModalTab, userId: string) => {
|
||||
@@ -167,7 +157,6 @@ export function useUserDetails() {
|
||||
patchUser,
|
||||
sendFriendRequest,
|
||||
fetchFriendRequests,
|
||||
syncFriendRequests,
|
||||
updateFriendRequestState,
|
||||
blockUser,
|
||||
unblockUser,
|
||||
|
||||
@@ -20,6 +20,7 @@ export function SettingsBehavior() {
|
||||
runAtStartup: false,
|
||||
startMinimized: false,
|
||||
disableNsfwAlert: false,
|
||||
enableAutoInstall: false,
|
||||
seedAfterDownloadComplete: false,
|
||||
showHiddenAchievementsDescription: false,
|
||||
});
|
||||
@@ -34,6 +35,7 @@ export function SettingsBehavior() {
|
||||
runAtStartup: userPreferences.runAtStartup ?? false,
|
||||
startMinimized: userPreferences.startMinimized ?? false,
|
||||
disableNsfwAlert: userPreferences.disableNsfwAlert ?? false,
|
||||
enableAutoInstall: userPreferences.enableAutoInstall ?? false,
|
||||
seedAfterDownloadComplete:
|
||||
userPreferences.seedAfterDownloadComplete ?? false,
|
||||
showHiddenAchievementsDescription:
|
||||
@@ -99,6 +101,16 @@ export function SettingsBehavior() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{window.electron.platform === "linux" && (
|
||||
<CheckboxField
|
||||
label={t("enable_auto_install")}
|
||||
checked={form.enableAutoInstall}
|
||||
onChange={() =>
|
||||
handleChange({ enableAutoInstall: !form.enableAutoInstall })
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<CheckboxField
|
||||
label={t("disable_nsfw_alert")}
|
||||
checked={form.disableNsfwAlert}
|
||||
|
||||
@@ -32,6 +32,7 @@ export function SettingsGeneral() {
|
||||
downloadNotificationsEnabled: false,
|
||||
repackUpdatesNotificationsEnabled: false,
|
||||
achievementNotificationsEnabled: false,
|
||||
friendRequestNotificationsEnabled: false,
|
||||
language: "",
|
||||
|
||||
customStyles: window.localStorage.getItem("customStyles") || "",
|
||||
@@ -82,6 +83,8 @@ export function SettingsGeneral() {
|
||||
userPreferences.repackUpdatesNotificationsEnabled ?? false,
|
||||
achievementNotificationsEnabled:
|
||||
userPreferences.achievementNotificationsEnabled ?? false,
|
||||
friendRequestNotificationsEnabled:
|
||||
userPreferences.friendRequestNotificationsEnabled ?? false,
|
||||
language: language ?? "en",
|
||||
}));
|
||||
}
|
||||
@@ -171,6 +174,17 @@ export function SettingsGeneral() {
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
<CheckboxField
|
||||
label={t("enable_friend_request_notifications")}
|
||||
checked={form.friendRequestNotificationsEnabled}
|
||||
onChange={() =>
|
||||
handleChange({
|
||||
friendRequestNotificationsEnabled:
|
||||
!form.friendRequestNotificationsEnabled,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,11 +76,13 @@ export interface UserPreferences {
|
||||
runAtStartup?: boolean;
|
||||
startMinimized?: boolean;
|
||||
disableNsfwAlert?: boolean;
|
||||
enableAutoInstall?: boolean;
|
||||
seedAfterDownloadComplete?: boolean;
|
||||
showHiddenAchievementsDescription?: boolean;
|
||||
downloadNotificationsEnabled?: boolean;
|
||||
repackUpdatesNotificationsEnabled?: boolean;
|
||||
achievementNotificationsEnabled?: boolean;
|
||||
friendRequestNotificationsEnabled?: boolean;
|
||||
}
|
||||
|
||||
export interface ScreenState {
|
||||
|
||||
Reference in New Issue
Block a user