diff --git a/src/components/common/AchievementToast.tsx b/src/components/common/AchievementToast.tsx index 546ed5b..f4de54c 100644 --- a/src/components/common/AchievementToast.tsx +++ b/src/components/common/AchievementToast.tsx @@ -98,12 +98,9 @@ export function AchievementToast({
diff --git a/src/components/modals/TeamModal.tsx b/src/components/modals/TeamModal.tsx deleted file mode 100644 index 5afd4cc..0000000 --- a/src/components/modals/TeamModal.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { motion } from "framer-motion"; -import { useState, useEffect } from "react"; - -export default function TeamModal({ - isOpen, - onClose, - playPressSound, - playSfx, -}: { - isOpen: boolean; - onClose: () => void; - playPressSound: () => void; - playSfx: (sound: string) => void; -}) { - const [focusIndex, setFocusIndex] = useState(0); - - const team = [ - { name: "neoapps", url: "https://github.com/neoapps-dev" }, - { name: "KayJann", url: "https://github.com/KayJannOnGit" }, - { name: "Santiago Fisela", url: "https://github.com/PinkLittleKitty" }, - { name: "Leon", url: "https://github.com/hornyalcoholic" }, - { name: "Criador_Mods", url: "https://github.com/CriadorMods" }, - ]; - - useEffect(() => { - if (!isOpen) { - setFocusIndex(0); - return; - } - const handleKey = (e: KeyboardEvent) => { - if (e.key === "Escape") { - playSfx("close_click.wav"); - onClose(); - } else if (e.key === "ArrowDown" || e.key === "Tab") { - e.preventDefault(); - setFocusIndex((prev) => (prev + 1) % (team.length + 1)); - } else if (e.key === "ArrowUp") { - e.preventDefault(); - setFocusIndex((prev) => (prev - 1 + (team.length + 1)) % (team.length + 1)); - } else if (e.key === "Enter") { - if (focusIndex === team.length) { - playSfx("close_click.wav"); - onClose(); - } else { - playPressSound(); - window.open(team[focusIndex].url, "_blank", "noopener,noreferrer"); - } - } - }; - window.addEventListener("keydown", handleKey); - return () => window.removeEventListener("keydown", handleKey); - }, [isOpen, focusIndex]); - - if (!isOpen) return null; - - return ( - -
-

- Emerald Team -

-
- {team.map((dev, idx) => ( - playPressSound()} - onMouseEnter={() => setFocusIndex(idx)} - className={`w-56 h-10 flex items-center justify-center mc-text-shadow text-xl transition-all outline-none border-none bg-transparent ${focusIndex === idx ? "text-[#FFFF55]" : "text-white"}`} - style={{ - backgroundImage: focusIndex === idx - ? "url('/images/button_highlighted.png')" - : "url('/images/Button_Background.png')", - backgroundSize: "100% 100%", - imageRendering: "pixelated", - }} - > - {dev.name} - - ))} -
- -
-
- ); -} diff --git a/src/components/views/CreditsView.tsx b/src/components/views/CreditsView.tsx new file mode 100644 index 0000000..8ed248a --- /dev/null +++ b/src/components/views/CreditsView.tsx @@ -0,0 +1,289 @@ +import { useEffect, memo } from "react"; +import { motion } from "framer-motion"; +import { useUI, useAudio } from "../../context/LauncherContext"; + +interface CreditCategory { + category: string; + icon?: string; + subcategories: { + name: string; + icon: string; + roles: { + role: string; + members: { + name: string; + url: string; + }[]; + }[]; + }[]; +} + +const CreditsView = memo(function CreditsView() { + const { setActiveView } = useUI(); + const { playBackSound } = useAudio(); + + const credits: CreditCategory[] = [ + { + category: "Emerald Team", + icon: "/images/emerald_0.png", + subcategories: [ + { + name: "Leadership", + icon: "", + roles: [ + { + role: "Founder & Maintainer", + members: [ + { name: "KayJann", url: "https://github.com/KayJannOnGit" }, + ], + }, + { + role: "Active Maintainer", + members: [ + { name: "neoapps", url: "https://github.com/neoapps-dev" }, + ], + }, + ], + }, + { + name: "Contributors", + icon: "", + roles: [ + { + role: "", + members: [ + { name: "Santiago Fisela", url: "https://github.com/PinkLittleKitty" }, + { name: "Leon", url: "https://github.com/hornyalcoholic" }, + { name: "Criador_Mods", url: "https://github.com/CriadorMods" }, + ], + }, + ], + }, + ], + }, + { + category: "LCE TEAM", + subcategories: [ + { + name: "neoLegacy", + icon: "/images/neoLegacy.png", + roles: [ + { + role: "Founder", + members: [ + { name: "Piebot", url: "https://github.com/Piebot" }, + ], + }, + ], + }, + { + name: "360 Revived", + icon: "/images/360_revived.png", + roles: [ + { + role: "Founder", + members: [ + { name: "BluTac10", url: "https://github.com/BluTac10" }, + ], + }, + ], + }, + { + name: "Hellish Ends", + icon: "", + roles: [ + { + role: "Founder", + members: [ + { name: "DeadVoxelx", url: "https://github.com/DeadVoxelx" }, + ], + }, + ], + }, + { + name: "Revelations", + icon: "", + roles: [ + { + role: "Founder", + members: [ + { name: "Revela", url: "https://github.com/Revela" }, + ], + }, + ], + }, + { + name: "Portable LCE", + icon: "", + roles: [ + { + role: "Founder", + members: [ + { name: "TBD", url: "#" }, + ], + }, + ], + }, + ], + } + { + category: "SPECIAL THANKS", + icon: "", + subcategories: [ + { + name: "Discord Booster", + icon: "/images/discord.png", + roles: [ + { + role: "", + members: [], + }, + ], + }, + { + name: "Donors", + icon: "", + roles: [ + { + role: "", + members: [], + }, + ], + }, + ], + }, + ]; + + useEffect(() => { + const handleKey = (e: KeyboardEvent) => { + if (document.activeElement?.tagName === "INPUT") return; + if (e.key === "Escape") { + playBackSound(); + setActiveView("main"); + } + }; + window.addEventListener("keydown", handleKey); + return () => window.removeEventListener("keydown", handleKey); + }, [setActiveView, playBackSound]); + + return ( +
+ setActiveView("main")} + className="flex flex-col items-center justify-center space-y-8 py-20" + > + + + {credits.map((cat) => ( +
+

+ {cat.icon && ( + {cat.category} + )} + {cat.category} +

+
+ {cat.subcategories.map((sub) => ( +
+

+ {sub.icon && ( + {sub.name} + )} + {sub.name} +

+
+ {sub.roles.map((role) => ( +
+ {role.role && ( +

+ {role.role} +

+ )} +
+ {role.members.map((member) => ( + + {member.name} + + ))} +
+
+ ))} +
+
+ ))} +
+
+ ))} + +
+
+ LCE Team +
+
+ ESRB Warning +
+
+ +
+

+ Not affiliated with Mojang, Microsoft, or 4J Studios +

+
+
+
+ ); +}); + +export default CreditsView; diff --git a/src/components/views/HomeView.tsx b/src/components/views/HomeView.tsx index 55fdfdf..b944d40 100644 --- a/src/components/views/HomeView.tsx +++ b/src/components/views/HomeView.tsx @@ -9,7 +9,7 @@ import { import type { Edition } from "../../types/edition"; const HomeView = memo(function HomeView() { - const { setActiveView, setShowCredits, focusSection, onNavigateToSkin } = + const { setActiveView, focusSection, onNavigateToSkin } = useUI(); const { profile, legacyMode } = useConfig(); const { playPressSound, playSfx } = useAudio(); @@ -208,12 +208,12 @@ const HomeView = memo(function HomeView() { onClick={() => { if (isFocusedSection) { playSfx("orb.ogg"); - setShowCredits(true); + setActiveView("credits"); } }} className={`text-white hover:text-[#FFFF55] text-xl mc-text-shadow tracking-widest transition-colors mt-1 bg-transparent border-none outline-none ${!isFocusedSection ? "pointer-events-none" : ""}`} > - EMERALD TEAM + CREDITS
)} diff --git a/src/context/LauncherContext.tsx b/src/context/LauncherContext.tsx index 6438304..de19b9b 100644 --- a/src/context/LauncherContext.tsx +++ b/src/context/LauncherContext.tsx @@ -18,8 +18,6 @@ interface UIContextType { isUiHidden: boolean; setIsUiHidden: (hidden: boolean) => void; isWindowVisible: boolean; - showCredits: boolean; - setShowCredits: (show: boolean) => void; focusSection: "menu" | "skin"; setFocusSection: (section: "menu" | "skin") => void; onNavigateToSkin: () => void; @@ -40,7 +38,6 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) { const [activeView, setActiveView] = useState("main"); const [isUiHidden, setIsUiHidden] = useState(false); const [isWindowVisible, setIsWindowVisible] = useState(true); - const [showCredits, setShowCredits] = useState(false); const [focusSection, setFocusSection] = useState<"menu" | "skin">("menu"); const { updateMessage, updateUrl, clearUpdateMessage } = useUpdateCheck(); @@ -191,10 +188,10 @@ export function LauncherProvider({ children }: { children: React.ReactNode }) { activeView, setActiveView, showIntro, setShowIntro, logoAnimDone, setLogoAnimDone, isUiHidden, setIsUiHidden, isWindowVisible, - showCredits, setShowCredits, focusSection, setFocusSection, + focusSection, setFocusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, updateUrl, clearUpdateMessage - }), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, showCredits, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, updateUrl, clearUpdateMessage]); + }), [activeView, showIntro, logoAnimDone, isUiHidden, isWindowVisible, focusSection, onNavigateToSkin, onNavigateToMenu, connected, updateMessage, updateUrl, clearUpdateMessage]); return ( diff --git a/src/pages/App.tsx b/src/pages/App.tsx index e3eecd2..2b318f0 100644 --- a/src/pages/App.tsx +++ b/src/pages/App.tsx @@ -17,8 +17,8 @@ import OptionsEditorView from "../components/views/OptionsEditorView"; import ScreenshotsView from "../components/views/ScreenshotsView"; import SwfView from "../components/views/SwfView"; import LceLiveView from "../components/views/LceLiveView"; +import CreditsView from "../components/views/CreditsView"; import SkinViewer from "../components/common/SkinViewer"; -import TeamModal from "../components/modals/TeamModal"; import PanoramaBackground from "../components/common/PanoramaBackground"; import { ClickParticles } from "../components/common/ClickParticles"; import { CinematicIntro } from "../components/common/CinematicIntro"; @@ -44,8 +44,6 @@ export default function App() { setActiveView, isUiHidden, setIsUiHidden, - showCredits, - setShowCredits, focusSection, onNavigateToMenu, updateMessage, @@ -164,17 +162,6 @@ export default function App() { {config.vfxEnabled && } - - {showCredits && ( - setShowCredits(false)} - playPressSound={audio.playPressSound} - playSfx={audio.playSfx} - /> - )} - -
- - -
+ )} + {activeView !== "credits" && ( + - {audio.splashIndex === -1 - ? `Welcome ${config.username}!` - : audio.splashes[audio.splashIndex]} -
-
+
+ {audio.splashIndex === -1 + ? `Welcome ${config.username}!` + : audio.splashes[audio.splashIndex]} +
+ + )} {activeView === "main" && hasAnyInstall && titleImage === "/images/MenuTitle.png" && ( )} + {activeView === "credits" && ( + + )}