@@ -36,54 +36,63 @@ function tierFor(total: number): "bronze" | "silver" | "gold" | "black" {
3636interface Props {
3737 claimable : MorpheusPoolPosition [ ] ;
3838 distributable : MorpheusPoolPosition [ ] ;
39+ collectable : number ;
3940 stakedPools : MorpheusPoolPosition [ ] ;
4041 splitBalances : Partial < Record < MorpheusAsset , number > > ;
4142 busyAsset : MorpheusAsset | null ;
4243 morpheusBusy : boolean ;
4344 morpheusPhase : string ;
4445 distributing : boolean ;
46+ collecting : boolean ;
4547 nowSec : number ;
4648 onClaim : ( asset : MorpheusAsset , referrer : Address ) => void ;
4749 onDistribute : ( asset : MorpheusAsset , referrer : Address ) => void ;
50+ onCollect : ( ) => void ;
4851 onWithdraw : ( asset : MorpheusAsset , staked : number ) => void ;
4952 onClose : ( ) => void ;
5053}
5154
5255export function RewardClaimModal ( {
53- claimable, distributable, stakedPools, splitBalances,
54- busyAsset, morpheusBusy, morpheusPhase, distributing, nowSec,
55- onClaim, onDistribute, onWithdraw, onClose,
56+ claimable, distributable, collectable , stakedPools, splitBalances,
57+ busyAsset, morpheusBusy, morpheusPhase, distributing, collecting , nowSec,
58+ onClaim, onDistribute, onCollect , onWithdraw, onClose,
5659} : Props ) {
5760 const t = useTranslations ( "stake" ) ;
5861
5962 const totalClaimable = claimable . reduce ( ( s , p ) => s + p . pendingMor , 0 ) ;
6063 const totalDistributable = distributable . reduce ( ( s , p ) => s + ( splitBalances [ p . asset ] ?? 0 ) , 0 ) ;
61- const total = totalClaimable + totalDistributable ;
64+ const total = totalClaimable + totalDistributable + collectable ;
6265
63- const stage : "claim" | "distribute" | "done" =
64- claimable . length > 0 ? "claim" : distributable . length > 0 ? "distribute" : "done" ;
66+ const stage : "claim" | "distribute" | "collect" | "done" =
67+ claimable . length > 0 ? "claim"
68+ : distributable . length > 0 ? "distribute"
69+ : collectable > 0 ? "collect"
70+ : "done" ;
6571
66- const isPending = busyAsset != null ;
67- // Reward has landed at the split → let the chest reveal it (idle otherwise).
68- const isOpening = distributable . length > 0 && busyAsset == null ;
72+ const isPending = busyAsset != null || collecting ;
73+ // Reward is out of the pool (at the split, or credited in the warehouse) → let
74+ // the chest reveal it; idle while a tx runs or nothing's waiting.
75+ const isOpening = ( distributable . length > 0 || collectable > 0 ) && ! isPending ;
6976
7077 // Clicking the chest runs the primary next action.
7178 const runPrimary = ( ) => {
7279 if ( claimable . length > 0 ) { const p = claimable [ 0 ] ; onClaim ( p . asset , p . referrer ) ; return ; }
73- if ( distributable . length > 0 ) { const p = distributable [ 0 ] ; onDistribute ( p . asset , p . referrer ) ; }
80+ if ( distributable . length > 0 ) { const p = distributable [ 0 ] ; onDistribute ( p . asset , p . referrer ) ; return ; }
81+ if ( collectable > 0 ) onCollect ( ) ;
7482 } ;
7583
7684 const steps = [
7785 { key : "claim" , label : t ( "lootbox.step1" ) , sub : t ( "lootbox.step1sub" ) } ,
7886 { key : "bridge" , label : t ( "lootbox.step2" ) , sub : t ( "lootbox.step2sub" ) } ,
7987 { key : "distribute" , label : t ( "lootbox.step3" ) , sub : t ( "lootbox.step3sub" ) } ,
88+ { key : "collect" , label : t ( "lootbox.step4" ) , sub : t ( "lootbox.step4sub" ) } ,
8089 ] as const ;
8190
91+ const order = [ "claim" , "bridge" , "distribute" , "collect" ] ;
92+ const currentIdx = stage === "claim" ? 0 : stage === "distribute" ? 2 : stage === "collect" ? 3 : order . length ;
8293 const stepState = ( key : string ) : "done" | "current" | "idle" => {
83- if ( stage === "done" ) return "done" ;
84- if ( stage === "claim" ) return key === "claim" ? "current" : "idle" ;
85- // distribute stage: claim + bridge behind us, distribute is the live step.
86- return key === "distribute" ? "current" : "done" ;
94+ const i = order . indexOf ( key ) ;
95+ return i < currentIdx ? "done" : i === currentIdx ? "current" : "idle" ;
8796 } ;
8897
8998 return (
@@ -173,7 +182,18 @@ export function RewardClaimModal({
173182 </ div >
174183 ) ) }
175184
176- { claimable . length === 0 && distributable . length === 0 && (
185+ { collectable > 0 && (
186+ < div className = "flex items-center justify-between gap-2 rounded-lg border bg-muted/40 px-3 py-2" >
187+ < span className = "text-xs text-muted-foreground" >
188+ < b className = "font-mono text-foreground" > { fmt ( collectable ) } </ b > MOR · { t ( "lootbox.inWarehouse" ) }
189+ </ span >
190+ < Button size = "sm" disabled = { collecting } onClick = { onCollect } className = "h-7" >
191+ { collecting ? t ( "lootbox.collecting" ) : t ( "lootbox.collect" ) }
192+ </ Button >
193+ </ div >
194+ ) }
195+
196+ { claimable . length === 0 && distributable . length === 0 && collectable === 0 && (
177197 < p className = "rounded-lg border bg-muted/40 px-3 py-2 text-xs text-muted-foreground" > { t ( "lootbox.allCollected" ) } </ p >
178198 ) }
179199 </ div >
0 commit comments