UPDATE: System tray setting
This commit is contained in:
@@ -1,28 +1,28 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
export default function FireflyToolsPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-base-200 flex items-center justify-center p-6">
|
||||
<div className="w-full bg-base-100 shadow-xl rounded-2xl p-8 space-y-8">
|
||||
<h1 className="text-4xl font-bold text-primary text-center">Firefly Tools</h1>
|
||||
return (
|
||||
<div className="min-h-screen bg-base-200 flex items-center justify-center p-6">
|
||||
<div className="w-full bg-base-100 shadow-xl rounded-2xl p-8 space-y-8">
|
||||
<h1 className="text-4xl font-bold text-primary text-center">Firefly Tools</h1>
|
||||
|
||||
{/* Section 1: About SR Tools */}
|
||||
<div className="bg-blue-50 border-l-4 border-blue-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-blue-800 flex items-center gap-2 mb-4">
|
||||
<span>ℹ️</span>
|
||||
<span>About Firefly Tools</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-blue-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">🏠</div>
|
||||
<p>
|
||||
This site is a another version of {" "}
|
||||
<span className="font-semibold text-success">Firefly Tools {" "}</span>
|
||||
developed by {" "}
|
||||
<span className="font-semibold text-warning">Me {"(Kain)"}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
{/* Section 1: About SR Tools */}
|
||||
<div className="bg-blue-50 border-l-4 border-blue-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-blue-800 flex items-center gap-2 mb-4">
|
||||
<span>ℹ️</span>
|
||||
<span>About Firefly Tools</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-blue-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">🏠</div>
|
||||
<p>
|
||||
This site is a another version of {" "}
|
||||
<span className="font-semibold text-success">Firefly Tools {" "}</span>
|
||||
developed by {" "}
|
||||
<span className="font-semibold text-warning">Me {"(Kain)"}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="bg-white border border-blue-200 rounded-lg p-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-blue-600 text-lg">🏆</span>
|
||||
@@ -37,7 +37,7 @@ export default function FireflyToolsPage() {
|
||||
https://srtools.kain.id.vn/
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="bg-white border border-blue-200 rounded-lg p-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-blue-600 text-lg">🔄</span>
|
||||
@@ -53,106 +53,106 @@ export default function FireflyToolsPage() {
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">👨💻</div>
|
||||
<p>The original tool was created by a third-party developer named <span className="font-semibold text-warning">Amazing</span>. This version is directly based on that work, without modification to core logic.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">🔗</div>
|
||||
<p>There is also a more modern version by the same author available at{" "}
|
||||
<a
|
||||
href="https://srtools.neonteam.dev/"
|
||||
className="link link-warning"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
srtools.neonteam.dev
|
||||
</a>
|
||||
{" "}and the original version at{" "}
|
||||
<a
|
||||
href="https://srtools.pages.dev/"
|
||||
className="link link-warning"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
srtools.pages.dev
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">👨💻</div>
|
||||
<p>The original tool was created by a third-party developer named <span className="font-semibold text-warning">Amazing</span>. This version is directly based on that work, without modification to core logic.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-blue-600 text-lg">🔗</div>
|
||||
<p>There is also a more modern version by the same author available at{" "}
|
||||
<a
|
||||
href="https://srtools.neonteam.dev/"
|
||||
className="link link-warning"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
srtools.neonteam.dev
|
||||
</a>
|
||||
{" "}and the original version at{" "}
|
||||
<a
|
||||
href="https://srtools.pages.dev/"
|
||||
className="link link-warning"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
srtools.pages.dev
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 2: Main Features */}
|
||||
<div className="bg-green-50 border-l-4 border-green-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-green-800 flex items-center gap-2 mb-4">
|
||||
<span>🔧</span>
|
||||
<span>Main Features</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-green-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">⚙️</div>
|
||||
<p>Configure characters, light cones, relics, traces, and eidolons easily in your browser.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">🔌</div>
|
||||
<p>Instantly apply setups to <span className="font-semibold text-warning">Firefly GO Server</span> using <span className="font-semibold">Connect PS</span> — no manual file uploads required.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-2xl">✨</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-green-800 text-lg">Extra Settings</h4>
|
||||
<p className="text-green-700 mt-1">
|
||||
Enhance your <span className="font-semibold text-warning">Firefly GO Server</span> experience with extra features:
|
||||
</p>
|
||||
<ul className="list-disc list-inside mt-2 space-y-1 text-green-700">
|
||||
<li>🎭 <span className="font-medium">Hidden Game UI</span> — remove the entire game interface.</li>
|
||||
<li>🚫 <span className="font-medium">Disable Censorship</span> — get rid of Lens Flare censor 💀.</li>
|
||||
<li>🧪 <span className="font-medium">Theorycraft Mode</span> — configure HP, cycles, and more via the web.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/* Section 2: Main Features */}
|
||||
<div className="bg-green-50 border-l-4 border-green-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-green-800 flex items-center gap-2 mb-4">
|
||||
<span>🔧</span>
|
||||
<span>Main Features</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-green-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">⚙️</div>
|
||||
<p>Configure characters, light cones, relics, traces, and eidolons easily in your browser.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">🔌</div>
|
||||
<p>Instantly apply setups to <span className="font-semibold text-warning">Firefly GO Server</span> using <span className="font-semibold">Connect PS</span> — no manual file uploads required.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-2xl">✨</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-green-800 text-lg">Extra Settings</h4>
|
||||
<p className="text-green-700 mt-1">
|
||||
Enhance your <span className="font-semibold text-warning">Firefly GO Server</span> experience with extra features:
|
||||
</p>
|
||||
<ul className="list-disc list-inside mt-2 space-y-1 text-green-700">
|
||||
<li>🎭 <span className="font-medium">Hidden Game UI</span> — remove the entire game interface.</li>
|
||||
<li>🚫 <span className="font-medium">Disable Censorship</span> — get rid of Lens Flare censor 💀.</li>
|
||||
<li>🧪 <span className="font-medium">Theorycraft Mode</span> — configure HP, cycles, and more via the web.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">📂</div>
|
||||
<p>Export and import full builds using <code className="bg-gray-200 px-2 py-1 rounded text-sm">freesr-data.json</code>.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">⚡</div>
|
||||
<p>Fast testing workflow — no sync cooldowns, instant in-game updates.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">📂</div>
|
||||
<p>Export and import full builds using <code className="bg-gray-200 px-2 py-1 rounded text-sm">freesr-data.json</code>.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-green-600 text-lg">⚡</div>
|
||||
<p>Fast testing workflow — no sync cooldowns, instant in-game updates.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 3: Getting Started */}
|
||||
<div className="bg-purple-50 border-l-4 border-purple-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-purple-800 flex items-center gap-2 mb-4">
|
||||
<span>🚀</span>
|
||||
<span>Getting Started</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-purple-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">1️⃣</div>
|
||||
<p>Access the tool through your browser at the self-hosted instance.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">2️⃣</div>
|
||||
<p>Configure your character builds with the intuitive web interface.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">3️⃣</div>
|
||||
<p>Use <span className="font-semibold">Connect PS</span> feature to instantly sync with your private server.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">4️⃣</div>
|
||||
<p>Test your builds in-game with real-time updates and modifications.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Section 3: Getting Started */}
|
||||
<div className="bg-purple-50 border-l-4 border-purple-400 p-6 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold text-purple-800 flex items-center gap-2 mb-4">
|
||||
<span>🚀</span>
|
||||
<span>Getting Started</span>
|
||||
</h2>
|
||||
<div className="space-y-3 text-purple-700">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">1️⃣</div>
|
||||
<p>Access the tool through your browser at the self-hosted instance.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">2️⃣</div>
|
||||
<p>Configure your character builds with the intuitive web interface.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">3️⃣</div>
|
||||
<p>Use <span className="font-semibold">Connect PS</span> feature to instantly sync with your private server.</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-purple-600 text-lg">4️⃣</div>
|
||||
<p>Test your builds in-game with real-time updates and modifications.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center pt-4">
|
||||
<Link to="/" className="btn btn-primary btn-wide">Back to Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div className="text-center pt-4">
|
||||
<Link to="/" className="btn btn-primary btn-wide">Back to Home</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import useLauncherStore from '@/stores/launcherStore';
|
||||
import { motion } from 'motion/react';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { CheckUpdateLauncher, CheckUpdateProxy, CheckUpdateServer, sleep, UpdateLauncher, UpdateProxy, UpdateServer } from '@/helper';
|
||||
import UpdateModal from '@/components/updateModal';
|
||||
|
||||
export default function LauncherPage() {
|
||||
const { gamePath,
|
||||
@@ -21,6 +22,7 @@ export default function LauncherPage() {
|
||||
serverVersion,
|
||||
proxyVersion,
|
||||
} = useSettingStore()
|
||||
|
||||
const {
|
||||
isOpenDownloadDataModal,
|
||||
isOpenUpdateDataModal,
|
||||
@@ -29,6 +31,7 @@ export default function LauncherPage() {
|
||||
setIsOpenUpdateDataModal,
|
||||
setIsOpenSelfUpdateModal
|
||||
} = useModalStore()
|
||||
|
||||
const {
|
||||
isLoading,
|
||||
downloadType,
|
||||
@@ -54,6 +57,33 @@ export default function LauncherPage() {
|
||||
setUpdateData,
|
||||
} = useLauncherStore()
|
||||
|
||||
const widgetLinks = [
|
||||
{
|
||||
tooltip: "Firefly SRAnalysis",
|
||||
href: "https://sranalysis.kain.id.vn/",
|
||||
img: "https://sranalysis.kain.id.vn/ff-sranalysis.png",
|
||||
btnClass: "btn-primary"
|
||||
},
|
||||
{
|
||||
tooltip: "Firefly SRTools",
|
||||
href: "https://srtools.kain.id.vn/",
|
||||
img: "https://srtools.kain.id.vn/ff-srtool.png",
|
||||
btnClass: "btn-secondary"
|
||||
},
|
||||
{
|
||||
tooltip: "Amazing's SRTools (Original UI)",
|
||||
href: "https://srtools.pages.dev/",
|
||||
img: "https://icons.duckduckgo.com/ip3/srtools.pages.dev.ico",
|
||||
btnClass: "btn-primary"
|
||||
},
|
||||
{
|
||||
tooltip: "Amazing's SRTools (Modern UI)",
|
||||
href: "https://srtools.neonteam.dev/",
|
||||
img: "https://icons.duckduckgo.com/ip3/srtools.neonteam.dev.ico",
|
||||
btnClass: "btn-secondary"
|
||||
}
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const check = async () => {
|
||||
if (!serverVersion || !proxyVersion) {
|
||||
@@ -200,18 +230,18 @@ export default function LauncherPage() {
|
||||
setIsDownloading(true)
|
||||
if (updateData.launcher.isUpdate) {
|
||||
await UpdateLauncher(updateData.launcher.version)
|
||||
setUpdateData({...updateData, launcher: { isUpdate: false, isExists: true, version: updateData.launcher.version }})
|
||||
setUpdateData({ ...updateData, launcher: { isUpdate: false, isExists: true, version: updateData.launcher.version } })
|
||||
setIsOpenSelfUpdateModal(true)
|
||||
}
|
||||
if (updateData.server.isUpdate || !updateData.server.isExists) {
|
||||
await UpdateServer(updateData.server.version)
|
||||
setServerReady(true)
|
||||
setUpdateData({...updateData, server: { isUpdate: false, isExists: true, version: updateData.server.version }})
|
||||
setUpdateData({ ...updateData, server: { isUpdate: false, isExists: true, version: updateData.server.version } })
|
||||
}
|
||||
if (updateData.proxy.isUpdate || !updateData.proxy.isExists) {
|
||||
await UpdateProxy(updateData.proxy.version)
|
||||
setProxyReady(true)
|
||||
setUpdateData({...updateData, proxy: { isUpdate: false, isExists: true, version: updateData.proxy.version }})
|
||||
setUpdateData({ ...updateData, proxy: { isUpdate: false, isExists: true, version: updateData.proxy.version } })
|
||||
}
|
||||
|
||||
setDownloadType("")
|
||||
@@ -251,60 +281,21 @@ export default function LauncherPage() {
|
||||
</header>
|
||||
|
||||
<div className="hidden sm:flex fixed top-1/4 left-4 z-10 flex-col space-y-3 bg-black/30 backdrop-blur-md rounded-xl p-3 shadow-lg">
|
||||
|
||||
<div className="tooltip tooltip-right" data-tip="Firefly SRAnalysis">
|
||||
<a
|
||||
className="btn btn-circle btn-primary"
|
||||
target="_blank"
|
||||
href="https://sranalysis.kain.id.vn/"
|
||||
>
|
||||
<img
|
||||
src="https://sranalysis.kain.id.vn/ff-sranalysis.png"
|
||||
alt="SRAnalysis Logo"
|
||||
className="w-8 h-8 rounded-full"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="tooltip tooltip-right" data-tip="Firefly SRTools">
|
||||
<a
|
||||
className="btn btn-circle btn-secondary"
|
||||
target="_blank"
|
||||
href="https://srtools.kain.id.vn/"
|
||||
>
|
||||
<img
|
||||
src="https://srtools.kain.id.vn/ff-srtool.png"
|
||||
alt="SRTools Logo"
|
||||
className="w-8 h-8 rounded-full"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="tooltip tooltip-right" data-tip="Amazing's SRTools (Original UI)">
|
||||
<a
|
||||
className="btn btn-circle btn-primary"
|
||||
target="_blank"
|
||||
href="https://srtools.pages.dev/"
|
||||
>
|
||||
<img
|
||||
src="https://icons.duckduckgo.com/ip3/srtools.pages.dev.ico"
|
||||
alt="SRTools Logo"
|
||||
className="w-8 h-8 rounded-full"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="tooltip tooltip-right" data-tip="Amazing's SRTools (Modern UI)">
|
||||
<a
|
||||
className="btn btn-circle btn-secondary"
|
||||
target="_blank"
|
||||
href="https://srtools.neonteam.dev/"
|
||||
>
|
||||
<img
|
||||
src="https://icons.duckduckgo.com/ip3/srtools.neonteam.dev.ico"
|
||||
alt="SRTools Logo"
|
||||
className="w-8 h-8 rounded-full"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
{widgetLinks.map((link, idx) => (
|
||||
<div key={idx} className="tooltip tooltip-right" data-tip={link.tooltip}>
|
||||
<a
|
||||
className={`btn btn-circle ${link.btnClass}`}
|
||||
target="_blank"
|
||||
href={link.href}
|
||||
>
|
||||
<img
|
||||
src={link.img}
|
||||
alt={link.tooltip}
|
||||
className="w-8 h-8 rounded-full"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="tooltip tooltip-right" data-tip="How to use all tools & commands">
|
||||
<Link
|
||||
@@ -345,32 +336,33 @@ export default function LauncherPage() {
|
||||
</div>
|
||||
<ul tabIndex={0} className="dropdown-content menu bg-base-100 rounded-box z-1 w-52 p-2 shadow-sm">
|
||||
<li><button onClick={handlePickFile}>Change Game Path</button></li>
|
||||
<li><button
|
||||
onClick={async () => {
|
||||
const serverData = await CheckUpdateServer(serverPath, serverVersion)
|
||||
const proxyData = await CheckUpdateProxy(proxyPath, proxyVersion)
|
||||
const launcherData = await CheckUpdateLauncher()
|
||||
setUpdateData({
|
||||
server: serverData,
|
||||
proxy: proxyData,
|
||||
launcher: launcherData
|
||||
})
|
||||
if (launcherData.isUpdate) {
|
||||
setIsOpenSelfUpdateModal(true)
|
||||
return
|
||||
}
|
||||
if (!serverData.isExists || !proxyData.isExists) {
|
||||
setIsOpenDownloadDataModal(true)
|
||||
return
|
||||
}
|
||||
if (serverData.isUpdate || proxyData.isUpdate) {
|
||||
setIsOpenUpdateDataModal(true)
|
||||
return
|
||||
}
|
||||
toast.success("No updates available")
|
||||
}}>
|
||||
Check for Updates
|
||||
</button></li>
|
||||
<li>
|
||||
<button
|
||||
onClick={async () => {
|
||||
const serverData = await CheckUpdateServer(serverPath, serverVersion)
|
||||
const proxyData = await CheckUpdateProxy(proxyPath, proxyVersion)
|
||||
setUpdateData({
|
||||
server: serverData,
|
||||
proxy: proxyData,
|
||||
launcher: updateData.launcher
|
||||
})
|
||||
|
||||
if (!serverData.isExists || !proxyData.isExists) {
|
||||
setIsOpenDownloadDataModal(true)
|
||||
return
|
||||
}
|
||||
if (serverData.isUpdate || proxyData.isUpdate) {
|
||||
setIsOpenUpdateDataModal(true)
|
||||
return
|
||||
}
|
||||
toast.success("No updates available")
|
||||
}}>
|
||||
Check for Updates Server & Proxy
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
</li>
|
||||
<li><button disabled={!serverPath} onClick={() => {
|
||||
if (serverPath) {
|
||||
FSService.OpenFolder("./server")
|
||||
@@ -395,34 +387,35 @@ export default function LauncherPage() {
|
||||
|
||||
{/* Downloading */}
|
||||
{isDownloading && (
|
||||
updateData.proxy.isUpdate
|
||||
|| updateData.server.isUpdate
|
||||
|| !updateData.proxy.isExists
|
||||
updateData.proxy.isUpdate
|
||||
|| updateData.server.isUpdate
|
||||
|| !updateData.proxy.isExists
|
||||
|| !updateData.server.isExists
|
||||
) && (
|
||||
<div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-10 w-[60vw] bg-black/20 backdrop-blur-sm rounded-lg p-4 shadow-lg">
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-center items-center text-sm text-white/80">
|
||||
<span>{downloadType}</span>
|
||||
<div className="flex items-center gap-4 ml-4">
|
||||
<span className="text-cyan-400 font-semibold">{downloadSpeed}</span>
|
||||
<span className="text-white font-bold">{progressDownload.toFixed(1)}%</span>
|
||||
<div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-10 w-[60vw] bg-black/20 backdrop-blur-sm rounded-lg p-4 shadow-lg">
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-center items-center text-sm text-white/80">
|
||||
<span>{downloadType}</span>
|
||||
<div className="flex items-center gap-4 ml-4">
|
||||
<span className="text-cyan-400 font-semibold">{downloadSpeed}</span>
|
||||
<span className="text-white font-bold">{progressDownload.toFixed(1)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full bg-white/20 rounded-full h-2 overflow-hidden">
|
||||
<motion.div
|
||||
className="h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full"
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: `${progressDownload}%` }}
|
||||
transition={{ type: "tween", ease: "linear", duration: 0.03 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center text-xs text-white/60">
|
||||
{progressDownload < 100 ? 'Please wait...' : 'Complete!'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full bg-white/20 rounded-full h-2 overflow-hidden">
|
||||
<motion.div
|
||||
className="h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full"
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: `${progressDownload}%` }}
|
||||
transition={{ type: "tween", ease: "linear", duration: 0.03 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center text-xs text-white/60">
|
||||
{progressDownload < 100 ? 'Please wait...' : 'Complete!'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
{isDownloading && updateData.launcher.isUpdate && (
|
||||
<div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-10 w-[60vw] bg-black/20 backdrop-blur-sm rounded-lg p-4 shadow-lg">
|
||||
<div className="space-y-3 text-sm text-white/80 text-center">
|
||||
@@ -430,10 +423,10 @@ export default function LauncherPage() {
|
||||
<div className="flex justify-center items-center gap-4 ml-4">
|
||||
<span
|
||||
className={`font-bold ${downloadType === "update:launcher:downloading"
|
||||
? "text-yellow-200 text-2xl"
|
||||
: downloadType === "update:launcher:success"
|
||||
? "text-emerald-200 text-xl"
|
||||
: "text-red-200 text-xl"
|
||||
? "text-yellow-200 text-2xl"
|
||||
: downloadType === "update:launcher:success"
|
||||
? "text-emerald-200 text-xl"
|
||||
: "text-red-200 text-xl"
|
||||
}`}
|
||||
>
|
||||
{downloadType === "update:launcher:downloading" && "Updating launcher"}
|
||||
@@ -476,141 +469,38 @@ export default function LauncherPage() {
|
||||
)}
|
||||
|
||||
{/* Modal */}
|
||||
{isOpenUpdateDataModal && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
||||
<div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.1, rotate: 90 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="btn btn-circle btn-md btn-error absolute right-3 top-3"
|
||||
onClick={() => setIsOpenUpdateDataModal(false)}
|
||||
>
|
||||
✕
|
||||
</motion.button>
|
||||
<UpdateModal
|
||||
isOpen={isOpenUpdateDataModal}
|
||||
onClose={() => setIsOpenUpdateDataModal(false)}
|
||||
title="Update Data"
|
||||
message="Do you want to update data server and proxy?"
|
||||
buttons={[
|
||||
{ text: "No", onClick: () => setIsOpenUpdateDataModal(false), variant: "outline" },
|
||||
{ text: "Yes", onClick: async () => { setIsOpenUpdateDataModal(false); await handlerUpdateData() }, variant: "primary" }
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
||||
<h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
|
||||
Update Data
|
||||
</h3>
|
||||
</div>
|
||||
<UpdateModal
|
||||
isOpen={isOpenDownloadDataModal}
|
||||
onClose={() => setIsOpenDownloadDataModal(false)}
|
||||
title="Download Data"
|
||||
message="Data server and proxy download required"
|
||||
buttons={[
|
||||
{ text: "Download", onClick: async () => { setIsOpenDownloadDataModal(false); await handlerUpdateData() }, variant: "primary" }
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="px-6 pb-6">
|
||||
<div className="mb-6">
|
||||
<p className="text-warning text-lg">
|
||||
Do you want to update data server and proxy?
|
||||
</p>
|
||||
</div>
|
||||
<UpdateModal
|
||||
isOpen={isOpenSelfUpdateModal}
|
||||
onClose={() => setIsOpenSelfUpdateModal(false)}
|
||||
title="Update Launcher"
|
||||
message="Do you want to update launcher?"
|
||||
buttons={[
|
||||
{ text: "No", onClick: () => setIsOpenSelfUpdateModal(false), variant: "outline" },
|
||||
{ text: "Yes", onClick: async () => { setIsOpenSelfUpdateModal(false); await handlerUpdateData() }, variant: "primary" }
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end gap-3">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="btn btn-outline btn-error"
|
||||
onClick={() => setIsOpenUpdateDataModal(false)}
|
||||
>
|
||||
No
|
||||
</motion.button>
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
|
||||
onClick={async () => {
|
||||
setIsOpenUpdateDataModal(false)
|
||||
await handlerUpdateData()
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isOpenDownloadDataModal && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
||||
<div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
|
||||
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
||||
<h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
|
||||
Download Data
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className="px-6 pb-6">
|
||||
<div className="mb-6">
|
||||
<p className="text-warning text-lg">
|
||||
Data server and proxy download required
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-3">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
|
||||
onClick={async () => {
|
||||
setIsOpenDownloadDataModal(false)
|
||||
await handlerUpdateData()
|
||||
}}
|
||||
>
|
||||
Download
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isOpenSelfUpdateModal && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
||||
<div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.1, rotate: 90 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="btn btn-circle btn-md btn-error absolute right-3 top-3"
|
||||
onClick={() => setIsOpenSelfUpdateModal(false)}
|
||||
>
|
||||
✕
|
||||
</motion.button>
|
||||
|
||||
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
||||
<h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
|
||||
Update Launcher
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className="px-6 pb-6">
|
||||
<div className="mb-6">
|
||||
<p className="text-warning text-lg">
|
||||
Do you want to update launcher?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-3">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="btn btn-outline btn-error"
|
||||
onClick={() => setIsOpenSelfUpdateModal(false)}
|
||||
>
|
||||
No
|
||||
</motion.button>
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
|
||||
onClick={async () => {
|
||||
setIsOpenSelfUpdateModal(false)
|
||||
await handlerUpdateData()
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user