feat: remove mock fight button for production, cleanup fight UI
- Remove "Fight a Classic Bot" button (mock endpoints blocked in prod) - Simplify speech bubble rendering (remove glow/accent layers) - Sound and FightViewer improvements - BotProfilePage enhancements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
bb9a966d4e
commit
56785cfdea
@@ -281,22 +281,45 @@ const tierClass = (t: number) => `tier-${t}`
|
||||
<template v-else>
|
||||
<!-- Header with human + bot character -->
|
||||
<div class="text-center mb-5">
|
||||
<div class="flex items-end justify-between mb-3">
|
||||
<div class="flex items-end justify-between mb-3 relative">
|
||||
<HumanPreview
|
||||
:seed="stats.avatarSeed || stats.name"
|
||||
:archetype="stats.archetype || 'standard'"
|
||||
:size="200"
|
||||
:win-rate="(stats.winRate || 0) / 100"
|
||||
anim="idle"
|
||||
class="drop-shadow-[0_0_12px_rgba(0,0,0,0.6)] shrink-0"
|
||||
class="drop-shadow-[0_0_12px_rgba(0,0,0,0.6)] shrink-0 relative z-10"
|
||||
/>
|
||||
<!-- Wire from gamepad to bot with electricity -->
|
||||
<svg class="absolute bottom-8 left-0 w-full h-24 z-0 pointer-events-none" preserveAspectRatio="none">
|
||||
<defs>
|
||||
<linearGradient id="wire-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#444455"/>
|
||||
<stop offset="50%" stop-color="#555566"/>
|
||||
<stop offset="100%" stop-color="#444455"/>
|
||||
</linearGradient>
|
||||
<filter id="elec-glow">
|
||||
<feGaussianBlur stdDeviation="3" result="blur"/>
|
||||
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- Main wire -->
|
||||
<path d="M 30% 85% Q 45% 40%, 55% 55% T 78% 30%" fill="none" stroke="url(#wire-grad)" stroke-width="3" stroke-linecap="round"/>
|
||||
<!-- Electricity pulse 1 -->
|
||||
<path class="elec-pulse-1" d="M 30% 85% Q 45% 40%, 55% 55% T 78% 30%" fill="none" stroke="#00f0ff" stroke-width="1.5" stroke-linecap="round" filter="url(#elec-glow)" stroke-dasharray="8 20" opacity="0.8"/>
|
||||
<!-- Electricity pulse 2 (reverse) -->
|
||||
<path class="elec-pulse-2" d="M 30% 85% Q 45% 40%, 55% 55% T 78% 30%" fill="none" stroke="#ff2d7b" stroke-width="1" stroke-linecap="round" filter="url(#elec-glow)" stroke-dasharray="5 25" opacity="0.6"/>
|
||||
<!-- Spark nodes -->
|
||||
<circle class="elec-spark-1" cx="45%" cy="55%" r="2" fill="#00f0ff" filter="url(#elec-glow)" opacity="0"/>
|
||||
<circle class="elec-spark-2" cx="62%" cy="45%" r="2" fill="#ff2d7b" filter="url(#elec-glow)" opacity="0"/>
|
||||
</svg>
|
||||
<SpritePreview
|
||||
:seed="stats.avatarSeed || stats.name"
|
||||
:archetype="stats.archetype"
|
||||
:tier="stats.tier"
|
||||
:size="160"
|
||||
:customization="stats.customization || undefined"
|
||||
class="drop-shadow-[0_0_20px_var(--glow)] mx-auto"
|
||||
class="drop-shadow-[0_0_20px_var(--glow)] mx-auto relative z-10"
|
||||
:style="{ '--glow': stats.tierColor + '80' } as any"
|
||||
/>
|
||||
</div>
|
||||
@@ -531,3 +554,31 @@ const tierClass = (t: number) => `tier-${t}`
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Electricity pulses along wire */
|
||||
.elec-pulse-1 {
|
||||
animation: elec-flow 1.2s linear infinite;
|
||||
}
|
||||
.elec-pulse-2 {
|
||||
animation: elec-flow 0.9s linear infinite reverse;
|
||||
}
|
||||
@keyframes elec-flow {
|
||||
0% { stroke-dashoffset: 0; opacity: 0.9; }
|
||||
50% { opacity: 0.4; }
|
||||
100% { stroke-dashoffset: -56; opacity: 0.9; }
|
||||
}
|
||||
|
||||
/* Spark flashes at wire midpoints */
|
||||
.elec-spark-1 {
|
||||
animation: spark-flash 0.8s ease-in-out infinite;
|
||||
}
|
||||
.elec-spark-2 {
|
||||
animation: spark-flash 1.1s ease-in-out infinite 0.4s;
|
||||
}
|
||||
@keyframes spark-flash {
|
||||
0%, 70%, 100% { opacity: 0; r: 1; }
|
||||
75% { opacity: 1; r: 4; }
|
||||
85% { opacity: 0.6; r: 2; }
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,6 @@ const { pubkey, bot, profilePicUrl, isLoggedIn, hasExtension, isLoading, login,
|
||||
const step = ref<string>('login')
|
||||
const error = ref('')
|
||||
const isJoining = ref(false)
|
||||
const isFightingClassic = ref(false)
|
||||
const queueCount = ref(0)
|
||||
let pollHandle: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
@@ -174,25 +173,6 @@ async function fight() {
|
||||
isJoining.value = false
|
||||
}
|
||||
|
||||
async function fightClassicBot() {
|
||||
if (!bot.value || isFightingClassic.value) return
|
||||
isFightingClassic.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
const res = await fetch(`/api/fights/mock/${bot.value.id}`, { method: 'POST' })
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
router.push(`/arena/${data.fightId}`)
|
||||
} else {
|
||||
const data = await res.json()
|
||||
error.value = data.error || 'Failed to start fight.'
|
||||
}
|
||||
} catch {
|
||||
error.value = 'Network error.'
|
||||
}
|
||||
isFightingClassic.value = false
|
||||
}
|
||||
|
||||
function handleSignOut() {
|
||||
logout()
|
||||
step.value = 'login'
|
||||
@@ -533,7 +513,7 @@ function handleSignOut() {
|
||||
font-display font-black text-2xl tracking-[0.2em]
|
||||
hover:bg-neon-pink/20 transition-all neon-border-pink
|
||||
disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
:disabled="isJoining || isFightingClassic"
|
||||
:disabled="isJoining"
|
||||
@click="fight"
|
||||
>
|
||||
{{ isJoining ? 'MATCHING...' : 'FIGHT' }}
|
||||
@@ -542,28 +522,6 @@ function handleSignOut() {
|
||||
Queue up against a real AI bot
|
||||
</p>
|
||||
|
||||
<!-- Classic bot button — instant mock fight -->
|
||||
<button
|
||||
class="w-full py-4 bg-neon-purple/10 border-2 border-neon-purple/50 text-neon-purple
|
||||
font-display font-black text-base tracking-[0.15em]
|
||||
hover:bg-neon-purple/20 hover:border-neon-purple transition-all
|
||||
disabled:opacity-30 disabled:cursor-not-allowed
|
||||
flex items-center justify-center gap-3"
|
||||
:disabled="isJoining || isFightingClassic"
|
||||
@click="fightClassicBot"
|
||||
>
|
||||
<svg class="w-6 h-6 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<rect x="4" y="4" width="16" height="12" rx="2" />
|
||||
<circle cx="9" cy="10" r="1.5" fill="currentColor" stroke="none" />
|
||||
<circle cx="15" cy="10" r="1.5" fill="currentColor" stroke="none" />
|
||||
<line x1="8" y1="20" x2="8" y2="16" />
|
||||
<line x1="16" y1="20" x2="16" y2="16" />
|
||||
</svg>
|
||||
{{ isFightingClassic ? 'STARTING...' : 'FIGHT A CLASSIC BOT' }}
|
||||
</button>
|
||||
<p class="font-mono text-[10px] text-text-muted text-center -mt-1">
|
||||
Instant match against a house bot
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Quick links -->
|
||||
|
||||
Reference in New Issue
Block a user