add logo
This commit is contained in:
18
src/App.jsx
18
src/App.jsx
@@ -7,7 +7,7 @@ import { LOCATIONS, teleportTo, worldState } from './worldState';
|
||||
import { onAdminChange } from './controls/KeyInput';
|
||||
import ControlPanel from './ui/ControlPanel';
|
||||
import LoadingScreen from './ui/LoadingScreen';
|
||||
import { login as authLogin, initSession, isLoggedIn, saveScore, getHandle, logout } from './lib/auth';
|
||||
import { login as authLogin, initSession, isLoggedIn, loadScore, saveScore, getHandle, logout } from './lib/auth';
|
||||
|
||||
const ACTION_SEQUENCE = ['attack', 'skill', 'jump', 'fly_dodge', 'damage'];
|
||||
const TELEPORT_ANIM = 'fly_dodge';
|
||||
@@ -27,6 +27,7 @@ const VRM_FILES = ['ai.vrm', 'ai_mode.vrm'];
|
||||
export default function App() {
|
||||
const [loadProgress, setLoadProgress] = useState(0);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [showIcon, setShowIcon] = useState(false);
|
||||
const [fadeOut, setFadeOut] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -55,8 +56,9 @@ export default function App() {
|
||||
.then(() => {
|
||||
if (cancelled) return;
|
||||
setLoadProgress(100);
|
||||
setTimeout(() => setLoaded(true), 300);
|
||||
setTimeout(() => setFadeOut(true), 2000);
|
||||
setTimeout(() => setShowIcon(true), 500);
|
||||
setTimeout(() => setLoaded(true), 1500);
|
||||
setTimeout(() => setFadeOut(true), 2500);
|
||||
});
|
||||
|
||||
return () => { cancelled = true; };
|
||||
@@ -69,7 +71,7 @@ export default function App() {
|
||||
<AppMain />
|
||||
</div>
|
||||
)}
|
||||
<LoadingScreen progress={loadProgress} fadeOut={fadeOut} />
|
||||
<LoadingScreen progress={loadProgress} fadeOut={fadeOut} showIcon={showIcon} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -103,12 +105,12 @@ function CrownRow({ tier, score, filter, toggleBgm, playing }) {
|
||||
display: 'flex', alignItems: 'center', gap: 6,
|
||||
}}>
|
||||
<img src={`${BASE_URL}icon/crown.svg`} alt={tier} style={{ width: 16, height: 16, filter }} />
|
||||
<span style={{ color: 'rgba(255,255,255,0.5)', fontSize: '11px', fontFamily: 'monospace' }}>{score}</span>
|
||||
<img
|
||||
src={`${BASE_URL}icon/play.svg`} alt="play"
|
||||
onClick={() => toggleBgm(tier)}
|
||||
style={{ width: 14, height: 14, filter: 'brightness(0) invert(1)', opacity: playing ? 1 : 0.4, cursor: 'pointer' }}
|
||||
/>
|
||||
<span style={{ color: 'rgba(255,255,255,0.5)', fontSize: '11px', fontFamily: 'monospace' }}>{score}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -321,6 +323,12 @@ function AppMain() {
|
||||
setAuthDid(did);
|
||||
const h = await getHandle();
|
||||
if (h) setSavedHandle(h);
|
||||
const saved = await loadScore();
|
||||
if (saved) setCrowns(prev => ({
|
||||
gold: saved.gold || prev.gold,
|
||||
silver: saved.silver || prev.silver,
|
||||
bronze: saved.bronze || prev.bronze,
|
||||
}));
|
||||
}).catch(() => {});
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -79,6 +79,23 @@ export async function getHandle() {
|
||||
} catch { return null }
|
||||
}
|
||||
|
||||
export async function loadScore() {
|
||||
if (!agent) return null
|
||||
const CROWN_MAP = { 1: 'gold', 2: 'silver', 3: 'bronze' }
|
||||
try {
|
||||
const record = await agent.com.atproto.repo.getRecord({
|
||||
repo: agent.assertDid, collection: COLLECTION, rkey: 'self',
|
||||
})
|
||||
const items = record.data.value?.item || []
|
||||
const crowns = { gold: 0, silver: 0, bronze: 0 }
|
||||
for (const item of items) {
|
||||
const tier = CROWN_MAP[item.id]
|
||||
if (tier) crowns[tier] = item.cp
|
||||
}
|
||||
return crowns
|
||||
} catch { return null }
|
||||
}
|
||||
|
||||
export async function saveScore(crowns) {
|
||||
if (!agent) return null
|
||||
|
||||
|
||||
@@ -32,25 +32,33 @@ const labelStyle = {
|
||||
marginTop: 10,
|
||||
};
|
||||
|
||||
export default function LoadingScreen({ progress, fadeOut }) {
|
||||
const BASE_URL = import.meta.env.BASE_URL;
|
||||
|
||||
export default function LoadingScreen({ progress, fadeOut, showIcon }) {
|
||||
return (
|
||||
<div style={{
|
||||
...containerStyle,
|
||||
opacity: fadeOut ? 0 : 1,
|
||||
pointerEvents: fadeOut ? 'none' : 'auto',
|
||||
}}>
|
||||
<div style={barOuterStyle}>
|
||||
<div style={{
|
||||
width: `${progress}%`,
|
||||
height: '100%',
|
||||
background: 'rgba(255,255,255,0.6)',
|
||||
borderRadius: '1px',
|
||||
transition: 'width 0.3s ease',
|
||||
}} />
|
||||
</div>
|
||||
<div style={labelStyle}>
|
||||
{progress < 100 ? `${Math.floor(progress)}%` : 'READY'}
|
||||
</div>
|
||||
{showIcon ? (
|
||||
<img src={`${BASE_URL}icon/ai.svg`} alt="ai" style={{ width: 48, height: 48, opacity: 0.6 }} />
|
||||
) : (
|
||||
<>
|
||||
<div style={barOuterStyle}>
|
||||
<div style={{
|
||||
width: `${progress}%`,
|
||||
height: '100%',
|
||||
background: 'rgba(255,255,255,0.6)',
|
||||
borderRadius: '1px',
|
||||
transition: 'width 0.3s ease',
|
||||
}} />
|
||||
</div>
|
||||
<div style={labelStyle}>
|
||||
{progress < 100 ? `${Math.floor(progress)}%` : 'READY'}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user