diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index 5bb02c52..9baa74c0 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -133,6 +133,7 @@ "mods-not-available": "Für diese Version von Beat Saber sind noch keine Mods verfügbar.", "status": { "no-wineprefix": "Konnte den BSManager WINEPREFIX-Pfad nicht finden. Bitte starte Beat Saber zuerst in BSManager.", + "beatmods-down": "Beatmods ist derzeit nicht erreichbar. Bitte versuchen Sie es später noch einmal. Wenn das Problem weiterhin besteht, informieren Sie uns auf {links}.", "unknown": "Ein unbekannter Fehler ist aufgetreten ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 30668322..6d912f49 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -133,6 +133,7 @@ "mods-not-available": "No mods are available yet for this version of Beat Saber", "status": { "no-wineprefix": "Could not find BSManager WINEPREFIX path. Please launch Beat Saber in BSManager first.", + "beatmods-down": "Beatmods is currently unreachable. Please retry later. If the issue persists, inform us on {links}.", "unknown": "An unknown error occurred ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 06d68788..7a045c3a 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -133,6 +133,7 @@ "mods-not-available": "Aún no hay mods disponibles para esta versión de Beat Saber", "status": { "no-wineprefix": "No se pudo encontrar la ruta del WINEPREFIX de BSManager. Por favor, inicia Beat Saber en BSManager primero.", + "beatmods-down": "Beatmods no está disponible en este momento. Por favor, inténtalo más tarde. Si el problema persiste, infórmanos en {links}.", "unknown": "Se ha producido un error desconocido ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 9bf5d10b..1e9d4811 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -133,6 +133,7 @@ "mods-not-available": "Aucun mod n'est encore disponible pour cette version de Beat Saber", "status": { "no-wineprefix": "Impossible de trouver le chemin WINEPREFIX de BSManager. Veuillez d'abord lancer Beat Saber dans BSManager.", + "beatmods-down": "Beatmods est actuellement inaccessible. Veuillez réessayer plus tard. Si le problème persiste, informez-nous sur {links}.", "unknown": "Une erreur inconnue s'est produite ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/it.json b/assets/jsons/translations/it.json index fc627bb0..09d175eb 100644 --- a/assets/jsons/translations/it.json +++ b/assets/jsons/translations/it.json @@ -133,6 +133,7 @@ "mods-not-available": "Nessuna mod è ancora disponibile per questa versione di Beat Saber", "status": { "no-wineprefix": "Impossibile trovare il percorso del WINEPREFIX di BSManager. Per favore avvia prima Beat Saber in BSManager.", + "beatmods-down": "Beatmods non è attualmente raggiungibile. Riprova più tardi. Se il problema persiste, informaci su {links}.", "unknown": "È accaduto un errore sconosciuto ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index ab297372..49c13446 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -133,6 +133,7 @@ "mods-not-available": "このバージョンで使用できるMODはまだありません。", "status": { "no-wineprefix": "BSManager WINEPREFIXのパスが見つかりませんでした。まずBSManagerでBeat Saberを起動してください。", + "beatmods-down": "現在、Beatmodsにアクセスできません。後でもう一度お試しください。問題が解決しない場合は、{links}でお知らせください。", "unknown": "不明なエラーが発生しました (´・ω・`)" }, "buttons": { diff --git a/assets/jsons/translations/ko.json b/assets/jsons/translations/ko.json index e8e6d500..91054296 100644 --- a/assets/jsons/translations/ko.json +++ b/assets/jsons/translations/ko.json @@ -133,6 +133,7 @@ "mods-not-available": "이 버전에서 사용할 수 있는 모드가 아직 없습니다.", "status": { "no-wineprefix": "BSManager WINEPREFIX 경로를 찾을 수 없습니다. 먼저 BSManager에서 Beat Saber를 실행하세요.", + "beatmods-down": "현재 Beatmods에 접근할 수 없습니다. 나중에 다시 시도해 주세요. 문제가 계속되면 {links}에서 알려주세요.", "unknown": "알 수 없는 오류가 발생했습니다 (´・ω・`)" }, "buttons": { diff --git a/assets/jsons/translations/pt-br.json b/assets/jsons/translations/pt-br.json index 0c017c15..9ded8bce 100644 --- a/assets/jsons/translations/pt-br.json +++ b/assets/jsons/translations/pt-br.json @@ -133,6 +133,7 @@ "mods-not-available": "Nenhum mod está disponível para essa versão de Beat Saber ainda", "status": { "no-wineprefix": "Não foi possível encontrar o caminho WINEPREFIX do BSManager. Por favor, inicie o Beat Saber no BSManager primeiro.", + "beatmods-down": "Beatmods está atualmente inacessível. Tente novamente mais tarde. Se o problema persistir, nos avise no {links}.", "unknown": "Um erro desconhecido aconteceu ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 504869cf..d44a5f6e 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -133,6 +133,7 @@ "mods-not-available": "Не найдены моды для этой версии Beat Saber", "status": { "no-wineprefix": "Не удалось найти путь WINEPREFIX BSManager. Пожалуйста, сначала запустите Beat Saber в BSManager.", + "beatmods-down": "Сейчас Beatmods недоступен. Пожалуйста, попробуйте позже. Если проблема сохраняется, сообщите нам в {links}.", "unknown": "Неизвестная ошибка ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/tl.json b/assets/jsons/translations/tl.json index 4a99478f..5fb2f246 100644 --- a/assets/jsons/translations/tl.json +++ b/assets/jsons/translations/tl.json @@ -133,6 +133,7 @@ "mods-not-available": "Walang mod na available pa para sa bersyon na ito ng Beat Saber", "status": { "no-wineprefix": "Hindi mahanap ang WINEPREFIX path ng BSManager. Pakilunsad muna ang Beat Saber sa BSManager.", + "beatmods-down": "Hindi ma-access ang Beatmods sa ngayon. Pakisubukang muli mamaya. Kung magpapatuloy ang problema, ipaalam sa amin sa {links}.", "unknown": "May naganap na hindi kilalang error ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/uk.json b/assets/jsons/translations/uk.json index 1c69a75e..c41b3692 100644 --- a/assets/jsons/translations/uk.json +++ b/assets/jsons/translations/uk.json @@ -133,6 +133,7 @@ "mods-not-available": "Для цієї версії Beat Saber поки що немає модів", "status": { "no-wineprefix": "Не вдалося знайти шлях до WINEPREFIX BSManager. Будь ласка, спочатку запустіть Beat Saber у BSManager.", + "beatmods-down": "Beatmods зараз недоступний. Будь ласка, спробуйте пізніше. Якщо проблема не зникне, повідомте нас на {links}.", "unknown": "Сталася невідома помилка ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index 8e7aca31..f47cdfc0 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -133,6 +133,7 @@ "mods-not-available": "該版本 BeatSaber 暫無可用 Mod", "status": { "no-wineprefix": "找不到 BSManager WINEPREFIX 路徑。請先在 BSManager 中啟動 Beat Saber。", + "beatmods-down": "Beatmods 目前無法訪問。請稍後再試。如果問題持續,請在 {links} 上告訴我們。", "unknown": "發生了一個錯誤 ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 783309fc..aaf1e5e2 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -133,6 +133,7 @@ "mods-not-available": "该版本 BeatSaber 暂无可用 Mod", "status": { "no-wineprefix": "找不到 BSManager WINEPREFIX 路径。请先在 BSManager 中启动 Beat Saber。", + "beatmods-down": "Beatmods 目前无法访问。请稍后再试。如果问题持续,请在 {links} 上告知我们。", "unknown": "发生了一个错误 ¯\\_(ツ)_/¯" }, "buttons": { diff --git a/src/main/ipcs/bs-mods-ipcs.ts b/src/main/ipcs/bs-mods-ipcs.ts index fd0cc1d9..476f4c55 100644 --- a/src/main/ipcs/bs-mods-ipcs.ts +++ b/src/main/ipcs/bs-mods-ipcs.ts @@ -1,6 +1,7 @@ import { BsModsManagerService } from "../services/mods/bs-mods-manager.service"; import { IpcService } from "../services/ipc.service"; import { from } from "rxjs"; +import { BeatModsApiService } from "main/services/mods/beat-mods-api.service"; const ipc = IpcService.getInstance(); @@ -34,3 +35,7 @@ ipc.on("bs-mods.uninstall-all-mods", (args, reply) => { reply(modsManager.uninstallAllMods(args)); }); +ipc.on("bs-mods.beatmods-up", (_, reply) => { + const beatMods = BeatModsApiService.getInstance(); + reply(from(beatMods.isUp())); +}) diff --git a/src/main/services/mods/beat-mods-api.service.ts b/src/main/services/mods/beat-mods-api.service.ts index 07ba0d79..c8e4bfd6 100644 --- a/src/main/services/mods/beat-mods-api.service.ts +++ b/src/main/services/mods/beat-mods-api.service.ts @@ -26,6 +26,17 @@ export class BeatModsApiService { this.requestService = RequestService.getInstance(); } + public async isUp(): Promise { + try { + // The data in status can be dropped + await this.requestService.getJSON<{}>(`${this.MODS_REPO_API_URL}/status`); + return true; + } catch (error) { + log.error("Could not connect to beatmods", error); + return false; + } + } + private getVersionModsUrl(version: BSVersion): string { const platform: BbmPlatform = version.oculus || version.metadata?.store === BsStore.OCULUS ? BbmPlatform.OculusPC : BbmPlatform.SteamPC; return `${this.MODS_REPO_API_URL}/mods?status=verified&gameVersion=${version.BSVersion}&gameName=BeatSaber&platform=${platform}`; diff --git a/src/renderer/components/modal/modal-types/link-contents-modal.component.tsx b/src/renderer/components/modal/modal-types/link-contents-modal.component.tsx index b0309ba6..71d74d20 100644 --- a/src/renderer/components/modal/modal-types/link-contents-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/link-contents-modal.component.tsx @@ -16,6 +16,7 @@ import { MODEL_TYPE_FOLDERS } from "shared/models/models/constants"; import { PlaylistsManagerService } from "renderer/services/playlists-manager.service"; import { MapsManagerService } from "renderer/services/maps-manager.service"; import { map } from "rxjs"; +import { DISCORD_URL } from "shared/constants"; export const LinkContentModal: ModalComponent = ({options: { data: { version, contentType } }, resolver }) => { const { text: t, element: te } = useTranslationV2(); @@ -97,7 +98,7 @@ export const LinkContentModal: ModalComponent{t("modals.link-contents.warning", {contentType: t(`misc.${contentType}`).toLowerCase()})}

{t("modals.link-contents.what-is-a-symbolic-link")} - {t("modals.link-contents.i-need-help")} + {t("modals.link-contents.i-need-help")}
resolver({ exitCode: ModalExitCode.CANCELED })} withBar={false} text="misc.cancel" /> diff --git a/src/renderer/components/modal/modal-types/unlink-contents-modal.component.tsx b/src/renderer/components/modal/modal-types/unlink-contents-modal.component.tsx index 21abeacd..13178d6d 100644 --- a/src/renderer/components/modal/modal-types/unlink-contents-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/unlink-contents-modal.component.tsx @@ -16,6 +16,7 @@ import { MODEL_TYPE_FOLDERS } from "shared/models/models/constants"; import { useConstant } from "renderer/hooks/use-constant.hook"; import { MapsManagerService } from "renderer/services/maps-manager.service"; import { BsmLink } from "renderer/components/shared/bsm-link.component"; +import { DISCORD_URL } from "shared/constants"; export const UnlinkContentsModal: ModalComponent = ({options: { data: { version, contentType } }, resolver }) => { const { text: t, element: te } = useTranslationV2(); @@ -86,7 +87,7 @@ export const UnlinkContentsModal: ModalComponent
{t("modals.link-contents.what-is-a-symbolic-link")} - {t("modals.link-contents.i-need-help")} + {t("modals.link-contents.i-need-help")}
diff --git a/src/renderer/components/version-viewer/slides/mods/mods-slide.component.tsx b/src/renderer/components/version-viewer/slides/mods/mods-slide.component.tsx index e2c423bd..d8ac7b6b 100644 --- a/src/renderer/components/version-viewer/slides/mods/mods-slide.component.tsx +++ b/src/renderer/components/version-viewer/slides/mods/mods-slide.component.tsx @@ -9,7 +9,7 @@ import BeatWaitingImg from "../../../../../../assets/images/apngs/beat-waiting.p import BeatConflictImg from "../../../../../../assets/images/apngs/beat-conflict.png"; import { useObservable } from "renderer/hooks/use-observable.hook"; import { lastValueFrom } from "rxjs"; -import { useTranslation, useTranslationV2 } from "renderer/hooks/use-translation.hook"; +import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; import { LinkOpenerService } from "renderer/services/link-opener.service"; import { ModalExitCode, ModalService } from "renderer/services/modale.service"; import { ModsDisclaimerModal } from "renderer/components/modal/modal-types/mods-disclaimer-modal.component"; @@ -23,6 +23,8 @@ import Tippy from "@tippyjs/react"; import { ProgressBarService } from "renderer/services/progress-bar.service"; import { Dropzone } from "renderer/components/shared/dropzone.component"; import { ModsGridStatus } from "shared/models/mods/mod-ipc.model"; +import { BsmLink } from "renderer/components/shared/bsm-link.component"; +import { DISCORD_URL, GITHUB_URL } from "shared/constants"; export type ModsSlideRef = { loadMods: () => Promise; @@ -33,7 +35,7 @@ type Props = { version: BSVersion; isActive?: boolean, onDisclamerDecline: () => export const ModsSlide = forwardRef(({ version, isActive, onDisclamerDecline }, forwaredRef) => { const ACCEPTED_DISCLAIMER_KEY = "accepted-mods-disclaimer"; - const { text: t } = useTranslationV2(); + const { text: t, element: te } = useTranslationV2(); const modsManager = useService(BsModsManagerService); const configService = useService(ConfigurationService); @@ -266,12 +268,32 @@ export const ModsSlide = forwardRef(({ version, isActive, o } }, [modsAvailable]); + const renderStatus = () => { + if (gridStatus === ModsGridStatus.BEATMODS_DOWN) { + return + + {te("pages.version-viewer.mods.status.beatmods-down", {links: (<> + + Discord + + / + + GitHub + + )})} + + + } + + return ; + } + const renderContent = () => { if (!isOnline) { return ; } if (gridStatus !== ModsGridStatus.OK) { - return ; + return renderStatus(); } if (!modsAvailable) { return ; @@ -342,13 +364,13 @@ export const ModsSlide = forwardRef(({ version, isActive, o ); }); -function ModStatus({ text, image, spin = false, children }: { text: string; image: string; spin?: boolean, children?: ReactNode}) { - const t = useTranslation(); +function ModStatus({ text, image, spin = false, children }: { text?: string; image: string; spin?: boolean, children?: ReactNode}) { + const { text: t } = useTranslationV2(); return (
 - {t(text)} + {text && {t(text)}} {children}
); diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index ea81c25a..87a3a79f 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -47,6 +47,7 @@ import { tryit } from "shared/helpers/error.helpers"; import { InstallationLocationService } from "renderer/services/installation-location.service"; import { AutoUpdaterService } from "renderer/services/auto-updater.service"; import { OculusDownloaderService } from "renderer/services/bs-version-download/oculus-downloader.service"; +import { DISCORD_URL } from "shared/constants"; export function SettingsPage() { @@ -240,7 +241,7 @@ export function SettingsPage() { const openGithub = () => linkOpener.open("https://github.com/Zagrios/bs-manager"); const openReportBug = () => linkOpener.open("https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=bug&template=-bug--bug-report.md&title=%5BBUG%5D+%3A+"); const openRequestFeatures = () => linkOpener.open("https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=enhancement&template=-feat---feature-request.md&title=%5BFEAT.%5D+%3A+"); - const openDiscord = () => linkOpener.open("https://discord.gg/uSqbHVpKdV"); + const openDiscord = () => linkOpener.open(DISCORD_URL); const openTwitter = () => linkOpener.open("https://twitter.com/BSManager_"); const openLogs = () => lastValueFrom(ipcService.sendV2("open-logs")); diff --git a/src/renderer/services/bs-mods-manager.service.ts b/src/renderer/services/bs-mods-manager.service.ts index dd712cf9..b1d5cf16 100644 --- a/src/renderer/services/bs-mods-manager.service.ts +++ b/src/renderer/services/bs-mods-manager.service.ts @@ -218,6 +218,11 @@ export class BsModsManagerService { } } + const beatModsUp = await lastValueFrom(this.ipcService.sendV2("bs-mods.beatmods-up")).catch(() => false); + if (!beatModsUp) { + return ModsGridStatus.BEATMODS_DOWN; + } + return ModsGridStatus.OK; } diff --git a/src/shared/constants.ts b/src/shared/constants.ts new file mode 100644 index 00000000..3b897d13 --- /dev/null +++ b/src/shared/constants.ts @@ -0,0 +1,4 @@ + +export const DISCORD_URL = "https://discord.gg/uSqbHVpKdV"; +export const GITHUB_URL = "https://github.com/Zagrios/bs-manager"; + diff --git a/src/shared/models/ipc/ipc-routes.ts b/src/shared/models/ipc/ipc-routes.ts index db3748df..ed417586 100644 --- a/src/shared/models/ipc/ipc-routes.ts +++ b/src/shared/models/ipc/ipc-routes.ts @@ -88,6 +88,7 @@ export interface IpcChannelMapping { "bs-mods.install-mods": { request: { mods: BbmFullMod[]; version: BSVersion }, response: Progression }; "bs-mods.uninstall-mods": { request: { mods: BbmFullMod[]; version: BSVersion }, response: Progression }; "bs-mods.uninstall-all-mods": { request: BSVersion, response: Progression }; + "bs-mods.beatmods-up": { request: void, response: boolean }; /* ** bs-playlist-ipcs ** */ "one-click-install-playlist": { request: string, response: Progression }; diff --git a/src/shared/models/mods/mod-ipc.model.ts b/src/shared/models/mods/mod-ipc.model.ts index f97ddd4a..b3ce700d 100644 --- a/src/shared/models/mods/mod-ipc.model.ts +++ b/src/shared/models/mods/mod-ipc.model.ts @@ -16,6 +16,7 @@ export interface UninstallModsResult { export enum ModsGridStatus { OK = "", NO_WINEPREFIX = "no-wineprefix", + BEATMODS_DOWN = "beatmods-down", UNKNOWN = "unknown" }