Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
N
Neos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
love_飞影
Neos
Commits
c4c2246c
Commit
c4c2246c
authored
Jul 07, 2023
by
timel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimize: card drapdown menu store
parent
2e712f62
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
152 additions
and
143 deletions
+152
-143
src/ui/Duel/PlayMat/Card/index.tsx
src/ui/Duel/PlayMat/Card/index.tsx
+152
-143
No files found.
src/ui/Duel/PlayMat/Card/index.tsx
View file @
c4c2246c
...
...
@@ -4,8 +4,9 @@ import { animated, to, useSpring } from "@react-spring/web";
import
{
Dropdown
,
type
MenuProps
}
from
"
antd
"
;
import
classnames
from
"
classnames
"
;
import
React
,
{
type
CSSProperties
,
useEffect
,
useState
}
from
"
react
"
;
import
{
proxy
,
useSnapshot
}
from
"
valtio
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
type
{
CardMeta
}
from
"
@/api
"
;
import
{
fetchStrings
,
getCardStr
,
...
...
@@ -139,131 +140,16 @@ export const Card: React.FC<{ idx: number }> = React.memo(({ idx }) => {
useEffect
(()
=>
{
setHighlight
(
!!
idleInteractivities
.
length
);
},
[
idleInteractivities
]);
const
menuItems
=
useSnapshot
(
dropdownMenu
);
// <<< 效果 <<<
return
(
<
animated
.
div
className=
{
classnames
(
"
mat-card
"
,
{
highlight
})
}
style=
{
{
transform
:
to
(
[
styles
.
x
,
styles
.
y
,
styles
.
z
,
styles
.
rx
,
styles
.
ry
,
styles
.
rz
],
(
x
,
y
,
z
,
rx
,
ry
,
rz
)
=>
`translate(${x}px, ${y}px) rotateX(${rx}deg) rotateZ(${rz}deg)`
),
"
--z
"
:
styles
.
z
,
"
--ry
"
:
styles
.
ry
,
height
:
styles
.
height
,
zIndex
:
styles
.
zIndex
,
"
--focus-scale
"
:
styles
.
focusScale
,
"
--focus-display
"
:
styles
.
focusDisplay
,
"
--focus-opacity
"
:
styles
.
focusOpacity
,
}
as
any
as
CSSProperties
}
onClick=
{
()
=>
{
if
([
MZONE
,
SZONE
,
HAND
].
includes
(
state
.
location
.
zone
))
{
onCardClick
(
state
);
}
else
if
([
EXTRA
,
GRAVE
,
REMOVED
].
includes
(
state
.
location
.
zone
))
{
onFieldClick
(
state
);
}
}
}
>
<
div
className=
"card-focus"
/>
<
div
className=
"card-shadow"
/>
<
Dropdown
menu=
{
{
items
:
menuItems
.
value
as
any
}
}
placement=
"bottom"
overlayClassName=
"card-dropdown"
arrow
trigger=
{
[
"
click
"
]
}
// disabled={!highlight}
>
<
div
className=
{
classnames
(
"
card-img-wrap
"
,
{
focus
:
classFocus
})
}
>
<
YgoCard
className=
{
classnames
(
"
card-cover
"
)
}
code=
{
snap
.
code
===
0
?
snap
.
meta
.
id
:
snap
.
code
}
/>
<
YgoCard
className=
"card-back"
isBack
/>
</
div
>
</
Dropdown
>
{
snap
.
selected
?
<
div
className=
"card-streamer"
/>
:
<></>
}
</
animated
.
div
>
);
});
const
onCardClick
=
(
card
:
CardType
)
=>
{
// 中央弹窗展示选中卡牌信息
// TODO: 同一张卡片,是否重复点击会关闭CardModal?
displayCardModal
(
card
);
if
(
card
.
idleInteractivities
)
handleDropdownMenu
([
card
],
false
);
// 侧边栏展示超量素材信息
const
overlayMaterials
=
cardStore
.
findOverlay
(
card
.
location
.
zone
,
card
.
location
.
controller
,
card
.
location
.
sequence
);
if
(
overlayMaterials
.
length
>
0
)
{
displayCardListModal
({
isZone
:
false
,
monster
:
card
,
});
}
};
const
onFieldClick
=
(
card
:
CardType
)
=>
{
displayCardListModal
({
isZone
:
true
,
zone
:
card
.
location
.
zone
,
controller
:
card
.
location
.
controller
,
const
[
dropdownMenu
,
setDropdownMenu
]
=
useState
({
items
:
[]
as
DropdownItem
[],
});
// 收集这个zone的所有交互,并且在下拉菜单之中显示
const
cards
=
cardStore
.
at
(
card
.
location
.
zone
,
card
.
location
.
controller
);
handleDropdownMenu
(
cards
,
true
);
};
// >>> 下拉菜单:点击动作 >>>
interface
Interactivy
{
desc
:
string
;
response
:
number
;
effectCode
:
number
|
undefined
;
}
type
DropdownItem
=
NonNullable
<
MenuProps
[
"
items
"
]
>
[
number
]
&
{
onClick
:
()
=>
void
;
};
const
dropdownMenu
=
proxy
({
value
:
[]
as
DropdownItem
[]
});
const
handleEffectActivation
=
(
effectInteractivies
:
Interactivy
[],
meta
?:
any
// FIXME: meta的类型
)
=>
{
if
(
!
effectInteractivies
.
length
)
return
;
else
if
(
effectInteractivies
.
length
===
1
)
{
// 如果只有一个效果,点击直接触发
sendSelectIdleCmdResponse
(
effectInteractivies
[
0
].
response
);
}
else
{
// optionsModal
const
options
=
effectInteractivies
.
map
((
effect
)
=>
{
const
effectMsg
=
meta
&&
effect
.
effectCode
?
getCardStr
(
meta
,
effect
.
effectCode
&
0xf
)
??
"
[:?]
"
:
"
[:?]
"
;
return
{
msg
:
effectMsg
,
response
:
effect
.
response
,
};
});
displayOptionModal
(
fetchStrings
(
"
!system
"
,
556
),
options
);
// 主动发动效果,所以不需要await,但是以后可能要留心
}
};
// 发动效果
// 1. 下拉菜单里面选择[召唤 / 特殊召唤 /.../效果发动]
// 2. 如果是非效果发动,那么直接选择哪张卡(单张卡直接选择那张)
// 3. 如果是效果发动,那么选择哪张卡,然后选择效果
const
handleDropdownMenu
=
(
cards
:
CardType
[],
isField
:
boolean
)
=>
{
// 发动效果
// 1. 下拉菜单里面选择[召唤 / 特殊召唤 /.../效果发动]
// 2. 如果是非效果发动,那么直接选择哪张卡(单张卡直接选择那张)
// 3. 如果是效果发动,那么选择哪张卡,然后选择效果
const
handleDropdownMenu
=
(
cards
:
CardType
[],
isField
:
boolean
)
=>
{
const
map
=
new
Map
<
Interactivity
<
number
>
[
"
interactType
"
],
CardType
[]
>
();
cards
.
forEach
((
card
)
=>
{
card
.
idleInteractivities
.
forEach
(({
interactType
})
=>
{
...
...
@@ -345,7 +231,9 @@ const handleDropdownMenu = (cards: CardType[], isField: boolean) => {
// 选择发动哪个效果
handleEffectActivation
(
card
.
idleInteractivities
.
filter
(({
interactType
})
=>
interactType
===
InteractType
.
ACTIVATE
)
.
filter
(
({
interactType
})
=>
interactType
===
InteractType
.
ACTIVATE
)
.
map
((
x
)
=>
({
desc
:
interactTypeToString
(
x
.
interactType
),
response
:
x
.
response
,
...
...
@@ -355,7 +243,128 @@ const handleDropdownMenu = (cards: CardType[], isField: boolean) => {
);
},
};
dropdownMenu
.
value
=
nonEffectItem
;
hasEffect
&&
dropdownMenu
.
value
.
push
(
effectItem
);
const
items
=
[...
nonEffectItem
];
hasEffect
&&
items
.
push
(
effectItem
);
setDropdownMenu
({
items
});
};
const
onClick
=
()
=>
{
const
onCardClick
=
(
card
:
CardType
)
=>
{
// 中央弹窗展示选中卡牌信息
// TODO: 同一张卡片,是否重复点击会关闭CardModal?
displayCardModal
(
card
);
if
(
card
.
idleInteractivities
.
length
)
handleDropdownMenu
([
card
],
false
);
// 侧边栏展示超量素材信息
const
overlayMaterials
=
cardStore
.
findOverlay
(
card
.
location
.
zone
,
card
.
location
.
controller
,
card
.
location
.
sequence
);
if
(
overlayMaterials
.
length
>
0
)
{
displayCardListModal
({
isZone
:
false
,
monster
:
card
,
});
}
};
const
onFieldClick
=
(
card
:
CardType
)
=>
{
displayCardListModal
({
isZone
:
true
,
zone
:
card
.
location
.
zone
,
controller
:
card
.
location
.
controller
,
});
// 收集这个zone的所有交互,并且在下拉菜单之中显示
const
cards
=
cardStore
.
at
(
card
.
location
.
zone
,
card
.
location
.
controller
);
handleDropdownMenu
(
cards
,
true
);
};
if
([
MZONE
,
SZONE
,
HAND
].
includes
(
state
.
location
.
zone
))
{
onCardClick
(
state
);
}
else
if
([
EXTRA
,
GRAVE
,
REMOVED
].
includes
(
state
.
location
.
zone
))
{
onFieldClick
(
state
);
}
};
// <<< 效果 <<<
return
(
<
animated
.
div
className=
{
classnames
(
"
mat-card
"
,
{
highlight
})
}
style=
{
{
transform
:
to
(
[
styles
.
x
,
styles
.
y
,
styles
.
z
,
styles
.
rx
,
styles
.
ry
,
styles
.
rz
],
(
x
,
y
,
z
,
rx
,
ry
,
rz
)
=>
`translate(${x}px, ${y}px) rotateX(${rx}deg) rotateZ(${rz}deg)`
),
"
--z
"
:
styles
.
z
,
"
--ry
"
:
styles
.
ry
,
height
:
styles
.
height
,
zIndex
:
styles
.
zIndex
,
"
--focus-scale
"
:
styles
.
focusScale
,
"
--focus-display
"
:
styles
.
focusDisplay
,
"
--focus-opacity
"
:
styles
.
focusOpacity
,
}
as
any
as
CSSProperties
}
onClick=
{
onClick
}
>
<
div
className=
"card-focus"
/>
<
div
className=
"card-shadow"
/>
<
Dropdown
menu=
{
dropdownMenu
}
placement=
"bottom"
overlayClassName=
"card-dropdown"
arrow
trigger=
{
[
"
click
"
]
}
// disabled={!highlight} // TODO: 这里的disable要考虑到field的情况,比如额外卡组
>
<
div
className=
{
classnames
(
"
card-img-wrap
"
,
{
focus
:
classFocus
})
}
>
<
YgoCard
className=
{
classnames
(
"
card-cover
"
)
}
code=
{
snap
.
code
===
0
?
snap
.
meta
.
id
:
snap
.
code
}
/>
<
YgoCard
className=
"card-back"
isBack
/>
</
div
>
</
Dropdown
>
{
snap
.
selected
?
<
div
className=
"card-streamer"
/>
:
<></>
}
</
animated
.
div
>
);
});
// >>> 下拉菜单:点击动作 >>>
interface
Interactivy
{
desc
:
string
;
response
:
number
;
effectCode
:
number
|
undefined
;
}
type
DropdownItem
=
NonNullable
<
MenuProps
[
"
items
"
]
>
[
number
]
&
{
onClick
:
()
=>
void
;
};
const
handleEffectActivation
=
(
effectInteractivies
:
Interactivy
[],
meta
?:
CardMeta
)
=>
{
if
(
!
effectInteractivies
.
length
)
return
;
else
if
(
effectInteractivies
.
length
===
1
)
{
// 如果只有一个效果,点击直接触发
sendSelectIdleCmdResponse
(
effectInteractivies
[
0
].
response
);
}
else
{
// optionsModal
const
options
=
effectInteractivies
.
map
((
effect
)
=>
{
const
effectMsg
=
meta
&&
effect
.
effectCode
?
getCardStr
(
meta
,
effect
.
effectCode
&
0xf
)
??
"
[:?]
"
:
"
[:?]
"
;
return
{
msg
:
effectMsg
,
response
:
effect
.
response
,
};
});
displayOptionModal
(
fetchStrings
(
"
!system
"
,
556
),
options
);
// 主动发动效果,所以不需要await,但是以后可能要留心
}
};
// <<< 下拉菜单 <<<
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment