mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-09-23 08:32:51 +00:00
feat: enhanced update checker for game and launcher
This commit is contained in:
@@ -26,15 +26,14 @@ interface UIContextType {
|
|||||||
onNavigateToMenu: () => void;
|
onNavigateToMenu: () => void;
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
updateMessage: string | null;
|
updateMessage: string | null;
|
||||||
|
updateUrl: string | null;
|
||||||
clearUpdateMessage: () => void;
|
clearUpdateMessage: () => void;
|
||||||
}
|
}
|
||||||
const UIContext = createContext<UIContextType | undefined>(undefined);
|
const UIContext = createContext<UIContextType | undefined>(undefined);
|
||||||
|
|
||||||
export const ConfigContext = createContext<ReturnType<typeof useAppConfig> | undefined>(undefined);
|
export const ConfigContext = createContext<ReturnType<typeof useAppConfig> | undefined>(undefined);
|
||||||
export const AudioContext = createContext<ReturnType<typeof useAudioController> | undefined>(undefined);
|
export const AudioContext = createContext<ReturnType<typeof useAudioController> | undefined>(undefined);
|
||||||
export const GameContext = createContext<ReturnType<typeof useGameManager> | undefined>(undefined);
|
export const GameContext = createContext<ReturnType<typeof useGameManager> | undefined>(undefined);
|
||||||
export const SkinContext = createContext<ReturnType<typeof useSkinSync> | undefined>(undefined);
|
export const SkinContext = createContext<ReturnType<typeof useSkinSync> | undefined>(undefined);
|
||||||
|
|
||||||
export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
||||||
const [showIntro, setShowIntro] = useState(true);
|
const [showIntro, setShowIntro] = useState(true);
|
||||||
const [logoAnimDone, setLogoAnimDone] = useState(false);
|
const [logoAnimDone, setLogoAnimDone] = useState(false);
|
||||||
@@ -44,7 +43,7 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
|||||||
const [showCredits, setShowCredits] = useState(false);
|
const [showCredits, setShowCredits] = useState(false);
|
||||||
const [focusSection, setFocusSection] = useState<"menu" | "skin">("menu");
|
const [focusSection, setFocusSection] = useState<"menu" | "skin">("menu");
|
||||||
|
|
||||||
const { updateMessage, clearUpdateMessage } = useUpdateCheck();
|
const { updateMessage, updateUrl, clearUpdateMessage } = useUpdateCheck();
|
||||||
|
|
||||||
const configRaw = useAppConfig();
|
const configRaw = useAppConfig();
|
||||||
const gameRaw = useGameManager({
|
const gameRaw = useGameManager({
|
||||||
@@ -181,8 +180,8 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
|||||||
isWindowVisible,
|
isWindowVisible,
|
||||||
showCredits, setShowCredits, focusSection, setFocusSection,
|
showCredits, setShowCredits, focusSection, setFocusSection,
|
||||||
onNavigateToSkin, onNavigateToMenu, connected,
|
onNavigateToSkin, onNavigateToMenu, connected,
|
||||||
updateMessage, clearUpdateMessage
|
updateMessage, updateUrl, clearUpdateMessage
|
||||||
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, clearUpdateMessage]);
|
}), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, updateUrl, clearUpdateMessage]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UIContext.Provider value={uiValue}>
|
<UIContext.Provider value={uiValue}>
|
||||||
|
|||||||
@@ -1,18 +1,51 @@
|
|||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
declare const __BUILD_DATE__: string;
|
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() {
|
export function useUpdateCheck() {
|
||||||
const [updateMessage, setUpdateMessage] = useState<string | null>(null);
|
const [updateMessage, setUpdateMessage] = useState<string | null>(null);
|
||||||
|
const [updateUrl, setUpdateUrl] = useState<string | null>(null);
|
||||||
const checkUpdates = useCallback(async () => {
|
const checkUpdates = useCallback(async () => {
|
||||||
try {
|
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__);
|
const buildDate = new Date(__BUILD_DATE__);
|
||||||
if (latestDate > buildDate) {
|
let isNightly = false;
|
||||||
setUpdateMessage(`Version ${data.tag_name} is now available!`);
|
let latestData = null;
|
||||||
} 9
|
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) {
|
} catch (e) {
|
||||||
console.error("Failed to check for updates:", e);
|
console.error("Failed to check for updates:", e);
|
||||||
}
|
}
|
||||||
@@ -24,6 +57,7 @@ export function useUpdateCheck() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
updateMessage,
|
updateMessage,
|
||||||
|
updateUrl,
|
||||||
clearUpdateMessage: () => setUpdateMessage(null),
|
clearUpdateMessage: () => setUpdateMessage(null),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -45,6 +45,7 @@ export default function App() {
|
|||||||
focusSection,
|
focusSection,
|
||||||
onNavigateToMenu,
|
onNavigateToMenu,
|
||||||
updateMessage,
|
updateMessage,
|
||||||
|
updateUrl,
|
||||||
clearUpdateMessage,
|
clearUpdateMessage,
|
||||||
} = useUI();
|
} = useUI();
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
@@ -159,7 +160,7 @@ export default function App() {
|
|||||||
message={updateMessage}
|
message={updateMessage}
|
||||||
onClose={clearUpdateMessage}
|
onClose={clearUpdateMessage}
|
||||||
onClick={() =>
|
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!"
|
title="Update Available!"
|
||||||
variant="update"
|
variant="update"
|
||||||
|
|||||||
Reference in New Issue
Block a user