mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-08-20 04:27:29 +00:00
feat: better back button
This commit is contained in:
parent
0f44a3761c
commit
cfdc295f0b
|
|
@ -3,11 +3,18 @@ package com.emerald.legacy
|
|||
import android.os.Bundle
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
|
||||
class MainActivity : TauriActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
WindowCompat.getInsetsController(window, window.decorView).apply {
|
||||
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
hide(WindowInsetsCompat.Type.statusBars())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWebViewCreate(webView: WebView) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, memo, useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useUI, useAudio } from "../../context/LauncherContext";
|
||||
import { usePlatform } from "../../hooks/usePlatform";
|
||||
|
||||
interface CreditCategory {
|
||||
category: string;
|
||||
|
|
@ -31,6 +32,7 @@ interface CreditCategory {
|
|||
const CreditsView = memo(function CreditsView() {
|
||||
const { setActiveView } = useUI();
|
||||
const { playPressSound } = useAudio();
|
||||
const { isAndroid } = usePlatform();
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const credits: CreditCategory[] = [
|
||||
|
|
@ -242,25 +244,27 @@ const CreditsView = memo(function CreditsView() {
|
|||
|
||||
return (
|
||||
<div className="relative w-full h-full flex items-center justify-center overflow-hidden">
|
||||
<button
|
||||
onClick={() => {
|
||||
playPressSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
className="fixed bottom-8 left-8 z-50 h-10 flex items-center justify-center gap-2 px-4 text-xl mc-text-shadow outline-none border-none"
|
||||
style={{
|
||||
backgroundImage: isHovered
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
color: isHovered ? "#FFFF55" : "white",
|
||||
}}
|
||||
>
|
||||
Back to Menu
|
||||
</button>
|
||||
{!isAndroid && (
|
||||
<button
|
||||
onClick={() => {
|
||||
playPressSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
className="fixed bottom-8 left-8 z-50 h-10 flex items-center justify-center gap-2 px-4 text-xl mc-text-shadow outline-none border-none"
|
||||
style={{
|
||||
backgroundImage: isHovered
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
color: isHovered ? "#FFFF55" : "white",
|
||||
}}
|
||||
>
|
||||
Back to Menu
|
||||
</button>
|
||||
)}
|
||||
|
||||
<motion.div
|
||||
initial={{ y: "50%" }}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useState, useEffect, memo } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { usePlatform } from "../../hooks/usePlatform";
|
||||
import {
|
||||
useUI,
|
||||
useAudio,
|
||||
|
|
@ -15,6 +16,7 @@ import { ScreenshotImage } from "../common/ScreenshotImage";
|
|||
const ScreenshotsView = memo(function ScreenshotsView() {
|
||||
const { setActiveView } = useUI();
|
||||
const { playPressSound, playBackSound } = useAudio();
|
||||
const { isAndroid } = usePlatform();
|
||||
const { editions } = useGame();
|
||||
const { animationsEnabled } = useConfig();
|
||||
const [screenshots, setScreenshots] = useState<ScreenshotInfo[]>([]);
|
||||
|
|
@ -239,30 +241,32 @@ const ScreenshotsView = memo(function ScreenshotsView() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-6 mb-4 flex justify-center">
|
||||
<button
|
||||
onClick={handleBack}
|
||||
className={`
|
||||
w-72 h-10 flex items-center justify-center text-xl mc-text-shadow border-none outline-none transition-all text-white
|
||||
hover:text-[#FFFF55]
|
||||
`}
|
||||
style={{
|
||||
backgroundImage: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/button_highlighted.png')";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Background.png')";
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
{!isAndroid && (
|
||||
<div className="w-full mt-6 mb-4 flex justify-center">
|
||||
<button
|
||||
onClick={handleBack}
|
||||
className={`
|
||||
w-72 h-10 flex items-center justify-center text-xl mc-text-shadow border-none outline-none transition-all text-white
|
||||
hover:text-[#FFFF55]
|
||||
`}
|
||||
style={{
|
||||
backgroundImage: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/button_highlighted.png')";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Background.png')";
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<AnimatePresence>
|
||||
{selectedScreenshot && (
|
||||
|
|
|
|||
|
|
@ -925,7 +925,7 @@ const SettingsView = memo(function SettingsView() {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{(() => {
|
||||
{!isAndroid && (() => {
|
||||
const backIndex = settingsItems.findIndex((i) => i.id === "back");
|
||||
const backItem = settingsItems[backIndex];
|
||||
if (!backItem || backItem.type !== "button") return null;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
} from "../../context/LauncherContext";
|
||||
import SkinViewer from "../common/SkinViewer";
|
||||
import CapePreview from "../common/CapePreview";
|
||||
import { usePlatform } from "../../hooks/usePlatform";
|
||||
|
||||
interface SavedSkin {
|
||||
id: string;
|
||||
|
|
@ -101,6 +102,7 @@ const HeadPreview = memo(function HeadPreview({ src }: { src: string }) {
|
|||
const SkinsView = memo(function SkinsView() {
|
||||
const { setActiveView, setIsUiHidden } = useUI();
|
||||
const { playPressSound, playBackSound } = useAudio();
|
||||
const { isAndroid } = usePlatform();
|
||||
const { skinUrl, setSkinUrl, setSkinIsSlim, capeUrl, setCapeUrl } = useSkin();
|
||||
|
||||
const [focusIndex, setFocusIndex] = useState<number | null>(null);
|
||||
|
|
@ -722,25 +724,27 @@ const SkinsView = memo(function SkinsView() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
data-index={BACK_BUTTON_INDEX}
|
||||
onMouseEnter={() => setFocusIndex(BACK_BUTTON_INDEX)}
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className={`w-72 h-14 shrink-0 flex items-center justify-center transition-colors text-2xl mc-text-shadow mt-2 outline-none border-none hover:text-[#FFFF55] ${focusIndex === BACK_BUTTON_INDEX ? "text-[#FFFF55]" : "text-white"}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusIndex === BACK_BUTTON_INDEX
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
{!isAndroid && (
|
||||
<button
|
||||
data-index={BACK_BUTTON_INDEX}
|
||||
onMouseEnter={() => setFocusIndex(BACK_BUTTON_INDEX)}
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className={`w-72 h-14 shrink-0 flex items-center justify-center transition-colors text-2xl mc-text-shadow mt-2 outline-none border-none hover:text-[#FFFF55] ${focusIndex === BACK_BUTTON_INDEX ? "text-[#FFFF55]" : "text-white"}`}
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusIndex === BACK_BUTTON_INDEX
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
)}
|
||||
|
||||
{showImportModal && viewMode === "skin" && (
|
||||
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4">
|
||||
|
|
|
|||
|
|
@ -914,27 +914,29 @@ const VersionsView = memo(function VersionsView() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
data-index={editions.length + 2}
|
||||
onMouseEnter={() => setFocusIndex(editions.length + 2)}
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className="w-48 h-10 flex items-center justify-center text-xl mc-text-shadow outline-none border-none text-white"
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusIndex === editions.length + 2
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
{!isAndroid && (
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
data-index={editions.length + 2}
|
||||
onMouseEnter={() => setFocusIndex(editions.length + 2)}
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className="w-48 h-10 flex items-center justify-center text-xl mc-text-shadow outline-none border-none text-white"
|
||||
style={{
|
||||
backgroundImage:
|
||||
focusIndex === editions.length + 2
|
||||
? "url('/images/button_highlighted.png')"
|
||||
: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CustomTUModal
|
||||
isOpen={isImportModalOpen}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
type CustomEdition,
|
||||
} from "../../services/TauriService";
|
||||
import { PluginManager } from "../../plugins/PluginManager";
|
||||
import { usePlatform } from "../../hooks/usePlatform";
|
||||
import { BASE_EDITIONS } from "../../hooks/useGameManager";
|
||||
const REGISTRY_URL =
|
||||
"https://raw.githubusercontent.com/LCE-Hub/LCE-Workshop/refs/heads/main/registry.json";
|
||||
|
|
@ -183,6 +184,7 @@ const WorkshopView = memo(function WorkshopView({
|
|||
}: WorkshopViewProps) {
|
||||
const { setActiveView } = useUI();
|
||||
const { playPressSound, playBackSound } = useAudio();
|
||||
const { isAndroid } = usePlatform();
|
||||
const config = useConfig();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const gridRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -1109,30 +1111,32 @@ const WorkshopView = memo(function WorkshopView({
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-6 mb-4 flex justify-center">
|
||||
<button
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className="w-72 h-10 flex items-center justify-center text-xl mc-text-shadow hover:text-[#FFFF55] text-white border-none outline-none transition-all"
|
||||
style={{
|
||||
backgroundImage: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/button_highlighted.png')";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Background.png')";
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
{!isAndroid && (
|
||||
<div className="w-full mt-6 mb-4 flex justify-center">
|
||||
<button
|
||||
onClick={() => {
|
||||
playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className="w-72 h-10 flex items-center justify-center text-xl mc-text-shadow hover:text-[#FFFF55] text-white border-none outline-none transition-all"
|
||||
style={{
|
||||
backgroundImage: "url('/images/Button_Background.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/button_highlighted.png')";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Background.png')";
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<AnimatePresence>
|
||||
{selectedPkg && (
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ export default function App() {
|
|||
animate={{ opacity: 1 }}
|
||||
className={`flex flex-col h-full z-10 w-full relative ${showHeader ? "pt-12" : ""}`}
|
||||
>
|
||||
{!config.legacyMode && (
|
||||
{!config.legacyMode && !isAndroid && (
|
||||
<motion.div {...uiFade} className="absolute top-10 left-8 z-50">
|
||||
<button
|
||||
onClick={() => {
|
||||
|
|
@ -477,6 +477,46 @@ export default function App() {
|
|||
</motion.div>
|
||||
)}
|
||||
|
||||
{isAndroid && activeView !== "main" && (
|
||||
<motion.div {...uiFade} className="absolute top-10 left-8 z-50">
|
||||
<button
|
||||
onClick={() => {
|
||||
audio.playBackSound();
|
||||
setActiveView("main");
|
||||
}}
|
||||
className="outline-none border-none flex items-center justify-center w-10 h-10 cursor-pointer"
|
||||
aria-label="Back"
|
||||
style={{
|
||||
backgroundImage: "url('/images/Button_Square.png')",
|
||||
backgroundSize: "100% 100%",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
onMouseEnter={(e) =>
|
||||
((e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Square_Highlighted.png')")
|
||||
}
|
||||
onMouseLeave={(e) =>
|
||||
((e.currentTarget as HTMLButtonElement).style.backgroundImage =
|
||||
"url('/images/Button_Square.png')")
|
||||
}
|
||||
>
|
||||
<svg
|
||||
width="26"
|
||||
height="26"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#FFFFFF"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="square"
|
||||
strokeLinejoin="miter"
|
||||
className="drop-shadow-[2px_2px_0_rgba(0,0,0,0.8)]"
|
||||
>
|
||||
<polyline points="15 18 9 12 15 6" />
|
||||
</svg>
|
||||
</button>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{!config.legacyMode && (
|
||||
<motion.div
|
||||
{...uiFade}
|
||||
|
|
|
|||
Loading…
Reference in a new issue