feat: enhanced update checker for game and launcher

This commit is contained in:
neoapps-dev
2026-04-30 19:02:34 +03:00
parent 1ecc47c32f
commit 365a8143ff
3 changed files with 48 additions and 14 deletions

View File

@@ -26,15 +26,14 @@ interface UIContextType {
onNavigateToMenu: () => void;
connected: boolean;
updateMessage: string | null;
updateUrl: string | null;
clearUpdateMessage: () => void;
}
const UIContext = createContext<UIContextType | undefined>(undefined);
export const ConfigContext = createContext<ReturnType<typeof useAppConfig> | undefined>(undefined);
export const AudioContext = createContext<ReturnType<typeof useAudioController> | undefined>(undefined);
export const GameContext = createContext<ReturnType<typeof useGameManager> | undefined>(undefined);
export const SkinContext = createContext<ReturnType<typeof useSkinSync> | undefined>(undefined);
export function LauncherProvider({ children }: { children: React.ReactNode }) {
const [showIntro, setShowIntro] = useState(true);
const [logoAnimDone, setLogoAnimDone] = useState(false);
@@ -44,7 +43,7 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
const [showCredits, setShowCredits] = useState(false);
const [focusSection, setFocusSection] = useState<"menu" | "skin">("menu");
const { updateMessage, clearUpdateMessage } = useUpdateCheck();
const { updateMessage, updateUrl, clearUpdateMessage } = useUpdateCheck();
const configRaw = useAppConfig();
const gameRaw = useGameManager({
@@ -181,8 +180,8 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
isWindowVisible,
showCredits, setShowCredits, focusSection, setFocusSection,
onNavigateToSkin, onNavigateToMenu, connected,
updateMessage, clearUpdateMessage
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, clearUpdateMessage]);
updateMessage, updateUrl, clearUpdateMessage
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, updateUrl, clearUpdateMessage]);
return (
<UIContext.Provider value={uiValue}>

View File

@@ -1,18 +1,51 @@
import { useState, useEffect, useCallback } from "react";
declare const __BUILD_DATE__: string;
const REPO_URL = "https://api.github.com/repos/LCE-Hub/LCE-Emerald-Launcher/releases/latest";
const LATEST_URL = "https://api.github.com/repos/LCE-Hub/LCE-Emerald-Launcher/releases/latest";
const NIGHTLY_URL = "https://api.github.com/repos/LCE-Hub/LCE-Emerald-Launcher/releases/tags/nightly";
export function useUpdateCheck() {
const [updateMessage, setUpdateMessage] = useState<string | null>(null);
const [updateUrl, setUpdateUrl] = useState<string | null>(null);
const checkUpdates = useCallback(async () => {
try {
const response = await fetch(REPO_URL);
if (!response.ok) return;
const data = await response.json();
const latestDate = new Date(data.published_at);
const buildDate = new Date(__BUILD_DATE__);
if (latestDate > buildDate) {
setUpdateMessage(`Version ${data.tag_name} is now available!`);
} 9
let isNightly = false;
let latestData = null;
let latestDate = new Date(0);
try {
const latestResponse = await fetch(LATEST_URL);
if (latestResponse.ok) {
latestData = await latestResponse.json();
latestDate = new Date(latestData.published_at);
if (buildDate > latestDate) {
isNightly = true;
}
} else {
isNightly = true;
}
} catch (e) {
isNightly = true;
}
if (isNightly) {
const nightlyResponse = await fetch(NIGHTLY_URL);
if (!nightlyResponse.ok) return;
const nightlyData = await nightlyResponse.json();
let releaseDate = new Date(nightlyData.published_at || nightlyData.updated_at);
if (nightlyData.assets && nightlyData.assets.length > 0) {
const assetDate = new Date(nightlyData.assets[0].updated_at);
if (assetDate > releaseDate) releaseDate = assetDate;
}
if (releaseDate > buildDate) {
setUpdateMessage(`A new Nightly build is available!`);
setUpdateUrl("https://github.com/LCE-Hub/LCE-Emerald-Launcher/releases/tag/nightly");
}
} else {
if (latestDate > buildDate && latestData) {
setUpdateMessage(`Version ${latestData.tag_name} is now available!`);
setUpdateUrl(latestData.html_url || LATEST_URL);
}
}
} catch (e) {
console.error("Failed to check for updates:", e);
}
@@ -24,6 +57,7 @@ export function useUpdateCheck() {
return {
updateMessage,
updateUrl,
clearUpdateMessage: () => setUpdateMessage(null),
};
}

View File

@@ -45,6 +45,7 @@ export default function App() {
focusSection,
onNavigateToMenu,
updateMessage,
updateUrl,
clearUpdateMessage,
} = useUI();
const config = useConfig();
@@ -159,7 +160,7 @@ export default function App() {
message={updateMessage}
onClose={clearUpdateMessage}
onClick={() =>
TauriService.openUrl("https://github.com/LCE-Hub/LCE-Emerald-Launcher/releases/latest")
TauriService.openUrl(updateUrl || "https://github.com/LCE-Hub/LCE-Emerald-Launcher/releases/latest")
}
title="Update Available!"
variant="update"