1
0
This commit is contained in:
2026-03-08 23:17:26 +09:00
parent 79a2012b31
commit 7f77e542ea
3 changed files with 51 additions and 18 deletions

View File

@@ -7,7 +7,7 @@ import { LOCATIONS, teleportTo, worldState } from './worldState';
import { onAdminChange } from './controls/KeyInput'; import { onAdminChange } from './controls/KeyInput';
import ControlPanel from './ui/ControlPanel'; import ControlPanel from './ui/ControlPanel';
import LoadingScreen from './ui/LoadingScreen'; 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 ACTION_SEQUENCE = ['attack', 'skill', 'jump', 'fly_dodge', 'damage'];
const TELEPORT_ANIM = 'fly_dodge'; const TELEPORT_ANIM = 'fly_dodge';
@@ -27,6 +27,7 @@ const VRM_FILES = ['ai.vrm', 'ai_mode.vrm'];
export default function App() { export default function App() {
const [loadProgress, setLoadProgress] = useState(0); const [loadProgress, setLoadProgress] = useState(0);
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const [showIcon, setShowIcon] = useState(false);
const [fadeOut, setFadeOut] = useState(false); const [fadeOut, setFadeOut] = useState(false);
useEffect(() => { useEffect(() => {
@@ -55,8 +56,9 @@ export default function App() {
.then(() => { .then(() => {
if (cancelled) return; if (cancelled) return;
setLoadProgress(100); setLoadProgress(100);
setTimeout(() => setLoaded(true), 300); setTimeout(() => setShowIcon(true), 500);
setTimeout(() => setFadeOut(true), 2000); setTimeout(() => setLoaded(true), 1500);
setTimeout(() => setFadeOut(true), 2500);
}); });
return () => { cancelled = true; }; return () => { cancelled = true; };
@@ -69,7 +71,7 @@ export default function App() {
<AppMain /> <AppMain />
</div> </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, display: 'flex', alignItems: 'center', gap: 6,
}}> }}>
<img src={`${BASE_URL}icon/crown.svg`} alt={tier} style={{ width: 16, height: 16, filter }} /> <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 <img
src={`${BASE_URL}icon/play.svg`} alt="play" src={`${BASE_URL}icon/play.svg`} alt="play"
onClick={() => toggleBgm(tier)} onClick={() => toggleBgm(tier)}
style={{ width: 14, height: 14, filter: 'brightness(0) invert(1)', opacity: playing ? 1 : 0.4, cursor: 'pointer' }} 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> </div>
); );
} }
@@ -321,6 +323,12 @@ function AppMain() {
setAuthDid(did); setAuthDid(did);
const h = await getHandle(); const h = await getHandle();
if (h) setSavedHandle(h); 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(() => {}); }).catch(() => {});
}, []); }, []);

View File

@@ -79,6 +79,23 @@ export async function getHandle() {
} catch { return null } } 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) { export async function saveScore(crowns) {
if (!agent) return null if (!agent) return null

View File

@@ -32,25 +32,33 @@ const labelStyle = {
marginTop: 10, marginTop: 10,
}; };
export default function LoadingScreen({ progress, fadeOut }) { const BASE_URL = import.meta.env.BASE_URL;
export default function LoadingScreen({ progress, fadeOut, showIcon }) {
return ( return (
<div style={{ <div style={{
...containerStyle, ...containerStyle,
opacity: fadeOut ? 0 : 1, opacity: fadeOut ? 0 : 1,
pointerEvents: fadeOut ? 'none' : 'auto', pointerEvents: fadeOut ? 'none' : 'auto',
}}> }}>
<div style={barOuterStyle}> {showIcon ? (
<div style={{ <img src={`${BASE_URL}icon/ai.svg`} alt="ai" style={{ width: 48, height: 48, opacity: 0.6 }} />
width: `${progress}%`, ) : (
height: '100%', <>
background: 'rgba(255,255,255,0.6)', <div style={barOuterStyle}>
borderRadius: '1px', <div style={{
transition: 'width 0.3s ease', width: `${progress}%`,
}} /> height: '100%',
</div> background: 'rgba(255,255,255,0.6)',
<div style={labelStyle}> borderRadius: '1px',
{progress < 100 ? `${Math.floor(progress)}%` : 'READY'} transition: 'width 0.3s ease',
</div> }} />
</div>
<div style={labelStyle}>
{progress < 100 ? `${Math.floor(progress)}%` : 'READY'}
</div>
</>
)}
</div> </div>
); );
} }