mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-05-21 17:54:30 +00:00
feat: cleaner UI for version detection
This commit is contained in:
@@ -1282,7 +1282,7 @@ async fn check_game_update(app: AppHandle, instance_id: String, url: String) ->
|
||||
|
||||
let local_timestamp = fs::read_to_string(×tamp_file).unwrap_or_default();
|
||||
if local_timestamp.is_empty() {
|
||||
return Ok(false);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let response = reqwest::Client::new().head(&url).send().await.map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -20,6 +20,7 @@ const HomeView = memo(function HomeView() {
|
||||
downloadingId,
|
||||
isGameRunning,
|
||||
stopGame,
|
||||
updatesAvailable,
|
||||
} = useGame();
|
||||
|
||||
const isFocusedSection = focusSection === "menu";
|
||||
@@ -54,10 +55,10 @@ const HomeView = memo(function HomeView() {
|
||||
isDanger: isGameRunning,
|
||||
disabled: isDownloading,
|
||||
},
|
||||
{ label: "Help & Options", action: () => setActiveView("settings"), disabled: false },
|
||||
{ label: "Versions", action: () => setActiveView("versions"), disabled: false },
|
||||
{ label: "Workshop", action: () => setActiveView("workshop"), disabled: false },
|
||||
{ label: "Developer Tools", action: () => setActiveView("devtools"), disabled: false },
|
||||
{ label: "Help & Options", action: () => setActiveView("settings"), disabled: false, id: "settings" },
|
||||
{ label: "Versions", action: () => setActiveView("versions"), disabled: false, id: "versions" },
|
||||
{ label: "Workshop", action: () => setActiveView("workshop"), disabled: false, id: "workshop" },
|
||||
{ label: "Developer Tools", action: () => setActiveView("devtools"), disabled: false, id: "devtools" },
|
||||
],
|
||||
[
|
||||
isDownloading,
|
||||
@@ -131,7 +132,16 @@ const HomeView = memo(function HomeView() {
|
||||
opacity: btn.disabled ? 0.5 : 1,
|
||||
}}
|
||||
>
|
||||
<span className="w-full text-center">{btn.label}</span>
|
||||
<div className="w-full h-full flex items-center justify-center relative">
|
||||
<span>{btn.label}</span>
|
||||
{btn.id === "versions" && Object.values(updatesAvailable || {}).some((v) => v) && (
|
||||
<img
|
||||
src="/images/Update_Icon.png"
|
||||
className="absolute right-4 w-6 h-6 object-contain"
|
||||
style={{ imageRendering: "pixelated", filter: "drop-shadow(0 0 2px rgba(255, 255, 0, 0.8)) sepia(100%) saturate(500%) hue-rotate(5deg) brightness(1.2)" }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -61,6 +61,7 @@ const VersionsView = memo(function VersionsView() {
|
||||
updateCustomEdition: onUpdateEdition,
|
||||
downloadingId,
|
||||
downloadProgress,
|
||||
updatesAvailable,
|
||||
} = useGame();
|
||||
const [focusIndex, setFocusIndex] = useState<number>(0);
|
||||
const [focusBtn, setFocusBtn] = useState<number>(0);
|
||||
@@ -488,7 +489,10 @@ const VersionsView = memo(function VersionsView() {
|
||||
src="/images/Update_Icon.png"
|
||||
alt="Update"
|
||||
className="w-6 h-6 object-contain"
|
||||
style={{ imageRendering: "pixelated" }}
|
||||
style={{
|
||||
imageRendering: "pixelated",
|
||||
filter: updatesAvailable?.[edition.id] ? "brightness(1.5) sepia(1) saturate(5) hue-rotate(15deg) drop-shadow(0 0 4px rgba(255,255,0,0.8))" : "none"
|
||||
}}
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
|
||||
@@ -73,7 +73,8 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) {
|
||||
gameRaw.installs, gameRaw.isGameRunning, gameRaw.downloadProgress,
|
||||
gameRaw.downloadingId, gameRaw.editions, gameRaw.isRunnerDownloading,
|
||||
gameRaw.runnerDownloadProgress, gameRaw.error, gameRaw.updateCustomEdition,
|
||||
gameRaw.handleUninstall, gameRaw.handleCancelDownload, gameRaw.gameUpdateMessage, configRaw.profile
|
||||
gameRaw.handleUninstall, gameRaw.handleCancelDownload, gameRaw.gameUpdateMessage, configRaw.profile,
|
||||
gameRaw.updatesAvailable
|
||||
]);
|
||||
|
||||
const audio = useMemo(() => audioRaw, [
|
||||
|
||||
@@ -43,7 +43,7 @@ const PARTNERSHIP_SERVERS = [
|
||||
{
|
||||
name: "Kowhaifans Clubhouse",
|
||||
ip: "lce.kowhaifan.net",
|
||||
port: 1026,
|
||||
port: 25565,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -86,26 +86,42 @@ export function useGameManager({
|
||||
setInstalls(results.filter((id): id is string => id !== null));
|
||||
}, [editions]);
|
||||
|
||||
const [updatesAvailable, setUpdatesAvailable] = useState<Record<string, boolean>>({});
|
||||
|
||||
const checkForGameUpdates = useCallback(async () => {
|
||||
if (!profile) return;
|
||||
const edition = editions.find(e => e.id === profile);
|
||||
if (!edition) return;
|
||||
try {
|
||||
const isUpdate = await TauriService.checkGameUpdate(profile, edition.url);
|
||||
if (isUpdate) {
|
||||
setGameUpdateMessage(`An update is available for ${edition.name}!`);
|
||||
} else {
|
||||
setGameUpdateMessage(null);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const checks = await Promise.all(
|
||||
editions.map(async (edition) => {
|
||||
if (!installs.includes(edition.id)) return [edition.id, false] as const;
|
||||
try {
|
||||
const isUpdate = await TauriService.checkGameUpdate(edition.id, edition.url);
|
||||
return [edition.id, isUpdate] as const;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return [edition.id, false] as const;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const newUpdates: Record<string, boolean> = {};
|
||||
for (const [id, hasUpdate] of checks) {
|
||||
newUpdates[id as string] = hasUpdate as boolean;
|
||||
}
|
||||
}, [profile, editions]);
|
||||
setUpdatesAvailable(newUpdates);
|
||||
|
||||
const updatedGames = editions.filter(e => newUpdates[e.id]);
|
||||
if (updatedGames.length > 0) {
|
||||
if (updatedGames.length === 1) {
|
||||
setGameUpdateMessage(`An update is available for ${updatedGames[0].name}!`);
|
||||
} else {
|
||||
setGameUpdateMessage(`Updates are available for ${updatedGames.length} versions!`);
|
||||
}
|
||||
} else {
|
||||
setGameUpdateMessage(null);
|
||||
}
|
||||
}, [editions, installs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (installs.includes(profile)) {
|
||||
checkForGameUpdates();
|
||||
}
|
||||
checkForGameUpdates();
|
||||
}, [profile, installs, checkForGameUpdates]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -270,5 +286,6 @@ export function useGameManager({
|
||||
checkInstalls,
|
||||
gameUpdateMessage,
|
||||
setGameUpdateMessage,
|
||||
updatesAvailable,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ export default function App() {
|
||||
onClose={() => game.setGameUpdateMessage(null)}
|
||||
onClick={() => {
|
||||
game.setGameUpdateMessage(null);
|
||||
game.toggleInstall(config.profile);
|
||||
setActiveView("versions");
|
||||
}}
|
||||
title="Game Update Available!"
|
||||
variant="update"
|
||||
|
||||
Reference in New Issue
Block a user