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
c92e6d78
Commit
c92e6d78
authored
Sep 05, 2023
by
zhangshize
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add mouse event on deck
parent
5ebda8bb
Pipeline
#23372
canceled with stages
in 3 minutes and 2 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
158 additions
and
72 deletions
+158
-72
src/ui/BuildDeck/index.tsx
src/ui/BuildDeck/index.tsx
+95
-10
src/ui/Shared/DeckCard/index.tsx
src/ui/Shared/DeckCard/index.tsx
+14
-6
src/ui/Shared/DeckZone/index.tsx
src/ui/Shared/DeckZone/index.tsx
+49
-56
No files found.
src/ui/BuildDeck/index.tsx
View file @
c92e6d78
...
@@ -15,6 +15,7 @@ import {
...
@@ -15,6 +15,7 @@ import {
type
MenuProps
,
type
MenuProps
,
Pagination
,
Pagination
,
Space
,
Space
,
message
,
}
from
"
antd
"
;
}
from
"
antd
"
;
import
{
isEqual
}
from
"
lodash-es
"
;
import
{
isEqual
}
from
"
lodash-es
"
;
import
{
type
OverlayScrollbarsComponentRef
}
from
"
overlayscrollbars-react
"
;
import
{
type
OverlayScrollbarsComponentRef
}
from
"
overlayscrollbars-react
"
;
...
@@ -26,12 +27,13 @@ import { proxy, useSnapshot } from "valtio";
...
@@ -26,12 +27,13 @@ import { proxy, useSnapshot } from "valtio";
import
{
subscribeKey
}
from
"
valtio/utils
"
;
import
{
subscribeKey
}
from
"
valtio/utils
"
;
import
{
type
CardMeta
,
searchCards
}
from
"
@/api
"
;
import
{
type
CardMeta
,
searchCards
}
from
"
@/api
"
;
import
{
isToken
}
from
"
@/common
"
;
import
{
is
ExtraDeckCard
,
is
Token
}
from
"
@/common
"
;
import
{
FtsConditions
}
from
"
@/middleware/sqlite/fts
"
;
import
{
FtsConditions
}
from
"
@/middleware/sqlite/fts
"
;
import
{
deckStore
,
type
IDeck
,
initStore
}
from
"
@/stores
"
;
import
{
deckStore
,
type
IDeck
,
initStore
}
from
"
@/stores
"
;
import
{
import
{
Background
,
Background
,
DeckCard
,
DeckCard
,
DeckCardMouseUpEvent
,
DeckZone
,
DeckZone
,
IconFont
,
IconFont
,
Loading
,
Loading
,
...
@@ -159,6 +161,47 @@ export const DeckEditor: React.FC<{
...
@@ -159,6 +161,47 @@ export const DeckEditor: React.FC<{
useEffect
(()
=>
{
useEffect
(()
=>
{
iDeckToEditingDeck
(
deck
).
then
(
editDeckStore
.
set
);
iDeckToEditingDeck
(
deck
).
then
(
editDeckStore
.
set
);
},
[
deck
]);
},
[
deck
]);
const
handleSwitchCard
=
(
type
:
Type
,
card
:
CardMeta
)
=>
{
const
cardType
=
card
.
data
.
type
??
0
;
const
isSide
=
type
===
'
side
'
;
const
targetType
=
isSide
?
(
isExtraDeckCard
(
cardType
)
?
'
extra
'
:
'
main
'
)
:
'
side
'
;
const
{
result
,
reason
}
=
editDeckStore
.
canAdd
(
card
,
targetType
,
type
);
if
(
result
)
{
editDeckStore
.
remove
(
type
,
card
);
editDeckStore
.
add
(
targetType
,
card
);
}
else
{
message
.
error
(
reason
);
}
}
const
showSelectedCard
=
(
card
:
CardMeta
)
=>
{
selectedCard
.
id
=
card
.
id
;
selectedCard
.
open
=
true
;
}
const
handleMouseUp
=
(
type
:
'
main
'
|
'
extra
'
|
'
side
'
,
payload
:
DeckCardMouseUpEvent
)
=>
{
const
{
event
,
card
}
=
payload
;
switch
(
event
.
button
)
{
// 左键
case
0
:
showSelectedCard
(
card
);
break
;
// 中键
case
1
:
handleSwitchCard
(
type
,
card
);
break
;
// 右键
case
2
:
editDeckStore
.
remove
(
type
,
card
);
break
;
default
:
break
;
}
event
.
preventDefault
();
}
return
(
return
(
<
div
className=
{
styles
.
container
}
>
<
div
className=
{
styles
.
container
}
>
<
Space
className=
{
styles
.
title
}
>
<
Space
className=
{
styles
.
title
}
>
...
@@ -215,11 +258,7 @@ export const DeckEditor: React.FC<{
...
@@ -215,11 +258,7 @@ export const DeckEditor: React.FC<{
editDeckStore
.
remove
(
source
,
card
);
editDeckStore
.
remove
(
source
,
card
);
}
}
}
}
}
}
onElementClick=
{
(
card
)
=>
{
onElementMouseUp=
{
(
event
)
=>
handleMouseUp
(
type
,
event
)
}
selectedCard
.
id
=
card
.
id
;
selectedCard
.
open
=
true
;
}
}
onElementRightClick=
{
(
card
)
=>
editDeckStore
.
remove
(
type
,
card
)
}
/>
/>
))
}
))
}
</
ScrollableArea
>
</
ScrollableArea
>
...
@@ -423,6 +462,54 @@ const SearchResults: React.FC<{
...
@@ -423,6 +462,54 @@ const SearchResults: React.FC<{
const
endIndex
=
startIndex
+
itemsPerPage
;
const
endIndex
=
startIndex
+
itemsPerPage
;
const
currentData
=
results
.
slice
(
startIndex
,
endIndex
);
const
currentData
=
results
.
slice
(
startIndex
,
endIndex
);
const
showSelectedCard
=
(
card
:
CardMeta
)
=>
{
selectedCard
.
id
=
card
.
id
;
selectedCard
.
open
=
true
;
};
const
handleAddCardToMain
=
(
card
:
CardMeta
)
=>
{
const
cardType
=
card
.
data
.
type
??
0
;
const
isExtraCard
=
isExtraDeckCard
(
cardType
);
const
type
=
isExtraCard
?
"
extra
"
:
"
main
"
;
const
{
result
,
reason
}
=
editDeckStore
.
canAdd
(
card
,
type
,
"
search
"
);
if
(
result
)
{
editDeckStore
.
add
(
type
,
card
);
}
else
{
message
.
error
(
reason
);
}
}
const
handleAddCardToSide
=
(
card
:
CardMeta
)
=>
{
const
{
result
,
reason
}
=
editDeckStore
.
canAdd
(
card
,
"
side
"
,
"
search
"
);
if
(
result
)
{
editDeckStore
.
add
(
"
side
"
,
card
);
}
else
{
message
.
error
(
reason
);
}
}
/** safari 不支持 onAuxClick,所以使用 mousedown 模拟 */
const
handleMouseUp
=
(
payload
:
DeckCardMouseUpEvent
)
=>
{
const
{
event
,
card
}
=
payload
;
switch
(
event
.
button
)
{
// 左键
case
0
:
showSelectedCard
(
card
);
break
;
// 中键
case
1
:
handleAddCardToSide
(
card
);
break
;
// 右键
case
2
:
handleAddCardToMain
(
card
);
break
;
default
:
break
;
}
}
return
(
return
(
<>
<>
<
div
className=
{
styles
[
"
search-cards
"
]
}
>
<
div
className=
{
styles
[
"
search-cards
"
]
}
>
...
@@ -431,10 +518,8 @@ const SearchResults: React.FC<{
...
@@ -431,10 +518,8 @@ const SearchResults: React.FC<{
value=
{
card
}
value=
{
card
}
key=
{
card
.
id
}
key=
{
card
.
id
}
source=
"search"
source=
"search"
onClick=
{
()
=>
{
onMouseUp=
{
handleMouseUp
}
selectedCard
.
id
=
card
.
id
;
onMouseEnter=
{
()
=>
showSelectedCard
(
card
)
}
selectedCard
.
open
=
true
;
}
}
/>
/>
))
}
))
}
</
div
>
</
div
>
...
...
src/ui/Shared/DeckCard/index.tsx
View file @
c92e6d78
...
@@ -10,13 +10,18 @@ import styles from "./index.module.scss";
...
@@ -10,13 +10,18 @@ import styles from "./index.module.scss";
const
{
assetsPath
}
=
useConfig
();
const
{
assetsPath
}
=
useConfig
();
export
interface
DeckCardMouseUpEvent
{
event
:
React
.
MouseEvent
;
card
:
CardMeta
;
}
/** 组卡页和Side页使用的单张卡片,增加了文字和禁限数量 */
/** 组卡页和Side页使用的单张卡片,增加了文字和禁限数量 */
export
const
DeckCard
:
React
.
FC
<
{
export
const
DeckCard
:
React
.
FC
<
{
value
:
CardMeta
;
value
:
CardMeta
;
source
:
Type
|
"
search
"
;
source
:
Type
|
"
search
"
;
on
RightClick
?:
(
)
=>
void
;
on
MouseUp
?:
(
event
:
DeckCardMouseUpEvent
)
=>
void
;
on
Click
?:
()
=>
void
;
on
MouseEnter
?:
()
=>
void
;
}
>
=
memo
(({
value
,
source
,
on
RightClick
,
onClick
})
=>
{
}
>
=
memo
(({
value
,
source
,
on
MouseUp
,
onMouseEnter
})
=>
{
const
ref
=
useRef
<
HTMLDivElement
>
(
null
);
const
ref
=
useRef
<
HTMLDivElement
>
(
null
);
const
[{
isDragging
},
drag
]
=
useDrag
({
const
[{
isDragging
},
drag
]
=
useDrag
({
type
:
"
Card
"
,
type
:
"
Card
"
,
...
@@ -33,10 +38,13 @@ export const DeckCard: React.FC<{
...
@@ -33,10 +38,13 @@ export const DeckCard: React.FC<{
className=
{
styles
.
card
}
className=
{
styles
.
card
}
ref=
{
ref
}
ref=
{
ref
}
style=
{
{
opacity
:
isDragging
&&
source
!==
"
search
"
?
0
:
1
}
}
style=
{
{
opacity
:
isDragging
&&
source
!==
"
search
"
?
0
:
1
}
}
onClick=
{
onClick
}
onMouseUp=
{
event
=>
onMouseUp
?.({
onContextMenu=
{
(
e
)
=>
{
event
,
card
:
value
,
})
}
onMouseEnter=
{
onMouseEnter
}
onContextMenu=
{
e
=>
{
e
.
preventDefault
();
e
.
preventDefault
();
onRightClick
?.();
}
}
}
}
>
>
{
showText
&&
<
div
className=
{
styles
.
cardname
}
>
{
value
.
text
.
name
}
</
div
>
}
{
showText
&&
<
div
className=
{
styles
.
cardname
}
>
{
value
.
text
.
name
}
</
div
>
}
...
...
src/ui/Shared/DeckZone/index.tsx
View file @
c92e6d78
...
@@ -5,7 +5,7 @@ import { useDrop } from "react-dnd";
...
@@ -5,7 +5,7 @@ import { useDrop } from "react-dnd";
import
{
CardMeta
}
from
"
@/api
"
;
import
{
CardMeta
}
from
"
@/api
"
;
import
{
DeckCard
}
from
"
../DeckCard
"
;
import
{
DeckCard
,
DeckCardMouseUpEvent
}
from
"
../DeckCard
"
;
import
styles
from
"
./index.module.scss
"
;
import
styles
from
"
./index.module.scss
"
;
/** 正在组卡的zone,包括main/extra/side
/** 正在组卡的zone,包括main/extra/side
...
@@ -24,66 +24,59 @@ export const DeckZone: React.FC<{
...
@@ -24,66 +24,59 @@ export const DeckZone: React.FC<{
source
:
Type
|
"
search
"
,
source
:
Type
|
"
search
"
,
destination
:
Type
,
destination
:
Type
,
)
=>
void
;
)
=>
void
;
onElementClick
:
(
card
:
CardMeta
)
=>
void
;
onElementMouseUp
:
(
event
:
DeckCardMouseUpEvent
)
=>
void
;
onElementRightClick
?:
(
card
:
CardMeta
)
=>
void
;
}
>
=
({
}
>
=
({
type
,
type
,
cards
,
cards
,
canAdd
,
canAdd
,
onChange
,
onChange
,
onElementClick
,
onElementMouseUp
:
onElementMouseUp
,
onElementRightClick
,
})
=>
{
})
=>
{
const
{
message
}
=
App
.
useApp
();
const
{
message
}
=
App
.
useApp
();
const
[
allowToDrop
,
setAllowToDrop
]
=
useState
(
false
);
const
[
allowToDrop
,
setAllowToDrop
]
=
useState
(
false
);
const
[{
isOver
},
dropRef
]
=
useDrop
({
const
[{
isOver
},
dropRef
]
=
useDrop
({
accept
:
[
"
Card
"
],
// 指明该区域允许接收的拖放物。可以是单个,也可以是数组
accept
:
[
"
Card
"
],
// 指明该区域允许接收的拖放物。可以是单个,也可以是数组
// 里面的值就是useDrag所定义的type
// 里面的值就是useDrag所定义的type
// 当拖拽物在这个拖放区域放下时触发,这个item就是拖拽物的item(拖拽物携带的数据)
// 当拖拽物在这个拖放区域放下时触发,这个item就是拖拽物的item(拖拽物携带的数据)
drop
:
({
value
,
source
}:
{
value
:
CardMeta
;
source
:
Type
|
"
search
"
})
=>
{
drop
:
({
value
,
source
}:
{
value
:
CardMeta
;
source
:
Type
|
"
search
"
})
=>
{
if
(
type
===
source
)
return
;
if
(
type
===
source
)
return
;
const
{
result
,
reason
}
=
canAdd
(
value
,
type
,
source
);
const
{
result
,
reason
}
=
canAdd
(
value
,
type
,
source
);
if
(
result
)
{
if
(
result
)
{
onChange
(
value
,
source
,
type
);
onChange
(
value
,
source
,
type
);
}
else
{
}
else
{
message
.
error
(
reason
);
message
.
error
(
reason
);
}
}
},
},
hover
:
({
value
,
source
})
=>
{
hover
:
({
value
,
source
})
=>
{
setAllowToDrop
(
setAllowToDrop
(
type
!==
source
?
canAdd
(
value
,
type
,
source
).
result
:
true
,
type
!==
source
?
canAdd
(
value
,
type
,
source
).
result
:
true
,
);
);
},
},
collect
:
(
monitor
)
=>
({
collect
:
(
monitor
)
=>
({
isOver
:
monitor
.
isOver
(),
isOver
:
monitor
.
isOver
(),
}),
}),
});
});
return
(
return
(
<
div
<
div
className=
{
classNames
(
styles
[
type
],
{
className=
{
classNames
(
styles
[
type
],
{
[
styles
.
over
]:
isOver
,
[
styles
.
over
]:
isOver
,
[
styles
[
"
not-allow-to-drop
"
]]:
isOver
&&
!
allowToDrop
,
[
styles
[
"
not-allow-to-drop
"
]]:
isOver
&&
!
allowToDrop
,
})
}
})
}
ref=
{
dropRef
}
ref=
{
dropRef
}
>
>
<
div
className=
{
styles
[
"
card-continer
"
]
}
>
<
div
className=
{
styles
[
"
card-continer
"
]
}
>
{
cards
.
map
((
card
,
i
)
=>
(
{
cards
.
map
((
card
,
i
)
=>
(
<
DeckCard
<
DeckCard
value=
{
card
}
value=
{
card
}
key=
{
card
.
id
+
i
+
type
}
key=
{
card
.
id
+
i
+
type
}
source=
{
type
}
source=
{
type
}
onClick=
{
()
=>
{
onMouseUp=
{
onElementMouseUp
}
onElementClick
(
card
);
/>
}
}
))
}
onRightClick=
{
()
=>
{
<
div
className=
{
styles
[
"
editing-zone-name
"
]
}
>
onElementRightClick
?.(
card
);
{
`${type.toUpperCase()}: ${cards.length}`
}
}
}
</
div
>
/>
))
}
<
div
className=
{
styles
[
"
editing-zone-name
"
]
}
>
{
`${type.toUpperCase()}: ${cards.length}`
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
);
);
};
};
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