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
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
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
MyCard
Neos
Commits
d58472a2
Commit
d58472a2
authored
Aug 06, 2023
by
timel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: waitroom improvement
parent
a1e99135
Pipeline
#22911
canceled with stages
in 1 minute and 13 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
241 additions
and
102 deletions
+241
-102
src/styles/antd.scss
src/styles/antd.scss
+10
-0
src/styles/core.scss
src/styles/core.scss
+1
-0
src/ui/NewWaitRoom/index.module.scss
src/ui/NewWaitRoom/index.module.scss
+30
-26
src/ui/NewWaitRoom/index.tsx
src/ui/NewWaitRoom/index.tsx
+198
-74
src/ui/Shared/IconFont/index.tsx
src/ui/Shared/IconFont/index.tsx
+2
-2
No files found.
src/styles/antd.scss
0 → 100644
View file @
d58472a2
// 全局修改 antd 样式
.ant-btn
{
display
:
flex
;
align-items
:
center
;
}
// 点击按钮产生的波浪扩散效果
.ant-wave
{
color
:
hsla
(
0
,
0%
,
100%
,
0
.3
);
}
src/styles/core.scss
View file @
d58472a2
@charset
"utf-8"
;
@import
url("https://fonts.googleapis.com/css2?family=Electrolize&display=swap")
;
@import
"./antd.scss"
;
body
{
color-scheme
:
dark
;
...
...
src/ui/NewWaitRoom/index.module.scss
View file @
d58472a2
.container
{
// height: calc(100% - var(--header-height));
height
:
100%
;
display
:
flex
;
--side-box-width
:
400px
;
...
...
@@ -57,6 +56,7 @@
.inner
{
background
:
linear-gradient
(
to
right
,
blue
,
rgb
(
0
,
149
,
255
));
}
z-index
:
1
;
}
&
.op
{
box-shadow
:
5px
0
20px
0
rgba
(
255
,
0
,
81
,
0
.1
);
...
...
@@ -85,30 +85,8 @@
margin-left
:
auto
;
}
.btn-large
{
min-width
:
100px
;
height
:
40px
;
background
:
hsla
(
0
,
0%
,
100%
,
0
.1
);
border-radius
:
6px
;
display
:
flex
;
align-items
:
center
;
padding
:
0
16px
0
16px
;
gap
:
8px
;
cursor
:
pointer
;
transition
:
0
.2s
;
.avatars-watch
{
height
:
100%
;
place-items
:
center
;
}
&
>
*
{
transition
:
0
.2s
;
}
&
:hover
>
*
{
opacity
:
0
.8
;
}
&
:active
>
*
{
opacity
:
0
.6
;
}
.avatars-watch
{
padding-left
:
8px
;
}
.btn-sider
{
...
...
@@ -135,7 +113,7 @@
}
}
.
room-name
{
.
status-bar
{
position
:
absolute
;
top
:
40px
;
left
:
0
;
...
...
@@ -147,4 +125,30 @@
font-size
:
13px
;
line-height
:
28px
;
border-radius
:
14px
;
display
:
flex
;
gap
:
8px
;
}
.fake-btn-large
{
min-width
:
88px
;
height
:
40px
;
background
:
hsla
(
0
,
0%
,
100%
,
0
.1
);
border-radius
:
6px
;
display
:
flex
;
align-items
:
center
;
padding
:
0
16px
0
16px
;
gap
:
8px
;
cursor
:
not
-
allowed
;
transition
:
0
.2s
;
position
:
relative
;
&
>
*
{
transition
:
0
.2s
;
}
&
:hover
>
*
{
opacity
:
0
.8
;
}
&
:active
>
*
{
opacity
:
0
.6
;
}
overflow
:
hidden
;
}
src/ui/NewWaitRoom/index.tsx
View file @
d58472a2
import
{
CheckCircleFilled
}
from
"
@ant-design/icons
"
;
import
{
Avatar
,
Button
,
ConfigProvider
,
Skeleton
,
Space
}
from
"
antd
"
;
import
{
Avatar
,
Button
,
ConfigProvider
,
Popover
,
Skeleton
,
Space
}
from
"
antd
"
;
import
classNames
from
"
classnames
"
;
import
{
useState
}
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
type
LoaderFunction
,
useLoaderData
}
from
"
react-router-dom
"
;
import
{
useSnapshot
}
from
"
valtio
"
;
import
{
accountStore
}
from
"
@/stores
"
;
import
{
accountStore
,
type
User
}
from
"
@/stores
"
;
import
{
Background
,
IconFont
,
Select
}
from
"
@/ui/Shared
"
;
import
{
Chat
}
from
"
./Chat
"
;
...
...
@@ -19,25 +19,28 @@ interface Params {
export
const
loader
:
LoaderFunction
=
async
({
params
})
=>
params
;
const
theme
=
{
components
:
{
Button
:
{
lineWidth
:
0
,
fontSizeLG
:
14
,
fontSize
:
12
,
colorBgContainer
:
"
hsla(0, 0%, 100%, 0.05)
"
,
colorPrimaryHover
:
"
#ccc
"
,
colorPrimaryActive
:
"
#aaa
"
,
},
Popover
:
{
colorBgElevated
:
"
hsla(0, 0%, 100%, 0.1)
"
,
},
},
};
export
const
Component
:
React
.
FC
=
()
=>
{
const
_params
=
useLoaderData
<
Params
>
();
const
{
user
}
=
useSnapshot
(
accountStore
);
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
);
return
(
<
ConfigProvider
theme=
{
{
components
:
{
Button
:
{
lineWidth
:
0
,
fontSizeLG
:
14
,
fontSize
:
12
,
colorBgContainer
:
"
hsla(0, 0%, 100%, 0.05)
"
,
colorPrimaryHover
:
"
#ccc
"
,
colorPrimaryActive
:
"
#aaa
"
,
},
},
}
}
>
<
ConfigProvider
theme=
{
theme
}
>
<
div
className=
{
classNames
(
styles
.
container
,
{
[
styles
.
collapsed
]:
collapsed
,
...
...
@@ -54,67 +57,188 @@ export const Component: React.FC = () => {
<
Chat
/>
</
div
>
<
div
className=
{
styles
.
main
}
>
{
/* <div className={styles["room-name"]}>Timel 的房间</div> */
}
<
Space
>
<
Select
title=
"卡组"
showSearch
defaultValue=
"lucy"
style=
{
{
width
:
300
}
}
options=
{
[
{
value
:
"
jack
"
,
label
:
"
Jack
"
},
{
value
:
"
lucy
"
,
label
:
"
Lucy
"
},
{
value
:
"
Yiminghe
"
,
label
:
"
yiminghe
"
},
{
value
:
"
disabled
"
,
label
:
"
Disabled
"
,
disabled
:
true
},
]
}
/>
<
div
className=
{
styles
[
"
btn-large
"
]
}
>
<
IconFont
type=
"icon-record"
size=
{
18
}
/>
加入观战
<
Avatar
.
Group
className=
{
styles
[
"
avatars-watch
"
]
}
>
<
Avatar
src=
"https://xsgames.co/randomusers/avatar.php?g=pixel&key=1"
size=
"small"
/>
<
Avatar
style=
{
{
backgroundColor
:
"
#f56a00
"
}
}
size=
"small"
>
K
</
Avatar
>
<
Avatar
style=
{
{
backgroundColor
:
"
#87d068
"
}
}
size=
"small"
/>
</
Avatar
.
Group
>
</
div
>
<
div
className=
{
styles
[
"
btn-large
"
]
}
>
<
IconFont
type=
"icon-play"
size=
{
12
}
/>
开始游戏
</
div
>
</
Space
>
<
div
className=
{
styles
[
"
both-side-container
"
]
}
>
<
div
className=
{
classNames
(
styles
[
"
side-box
"
],
styles
.
me
)
}
>
<
div
className=
{
styles
.
inner
}
></
div
>
<
div
style=
{
{
position
:
"
relative
"
}
}
>
<
Avatar
src=
{
user
?.
avatar_url
}
size=
{
48
}
/>
<
CheckCircleFilled
className=
{
styles
.
check
}
/>
</
div
>
<
div
className=
{
styles
.
name
}
>
Timel#6675
</
div
>
<
Button
size=
"large"
className=
{
styles
[
"
btn-join
"
]
}
>
决斗准备
</
Button
>
</
div
>
{
/* <div className={styles.battle}>
<IconFont type="icon-battle" size={32} />
{
/* <div className={styles["status-bar"]}>
<LoadingOutlined />
对方正在选择先后
</div> */
}
<
div
className=
{
classNames
(
styles
[
"
side-box
"
],
styles
.
op
)
}
>
<
div
className=
{
styles
.
inner
}
></
div
>
<
Avatar
size=
{
48
}
/>
<
div
className=
{
styles
.
name
}
>
<
Skeleton
.
Input
size=
"small"
/>
</
div
>
<
Button
size=
"large"
className=
{
styles
[
"
btn-join
"
]
}
>
加入决斗
</
Button
>
</
div
>
<
Controller
/>
<
div
className=
{
styles
[
"
both-side-container
"
]
}
>
<
PlayerZone
isReady
who=
{
Who
.
Me
}
user=
{
user
}
btn=
{
<>
{
/* <Button size="large" className={styles["btn-join"]}>
决斗准备
</Button> */
}
<
MoraButton
/>
</>
}
/>
<
PlayerZone
isReady
who=
{
Who
.
Op
}
btn=
{
<
Button
size=
"large"
className=
{
styles
[
"
btn-join
"
]
}
>
加入决斗
</
Button
>
}
/>
</
div
>
</
div
>
</
div
>
</
ConfigProvider
>
);
};
enum
Mora
{
Rock
=
"
rock
"
,
Scissors
=
"
scissors
"
,
Paper
=
"
paper
"
,
}
const
MoraButton
:
React
.
FC
<
{
onClick
?:
()
=>
Promise
<
Mora
>
;
}
>
=
()
=>
{
// TODO: 实现这个onclick
// 防抖
return
(
<
Popover
overlayStyle=
{
{
backdropFilter
:
"
blur(10px)
"
}
}
content=
{
<
Space
>
<
Button
size=
"large"
type=
"text"
icon=
{
<
IconFont
type=
"icon-hand-rock"
size=
{
16
}
/>
}
>
石头
</
Button
>
<
Button
size=
"large"
type=
"text"
icon=
{
<
IconFont
type=
"icon-hand-scissors"
size=
{
16
}
/>
}
>
剪刀
</
Button
>
<
Button
size=
"large"
type=
"text"
icon=
{
<
IconFont
type=
"icon-hand-paper"
size=
{
16
}
/>
}
>
布
</
Button
>
</
Space
>
}
trigger=
"focus"
placement=
"bottom"
>
<
Button
size=
"large"
className=
{
styles
[
"
btn-join
"
]
}
icon=
{
<
IconFont
type=
"icon-mora"
size=
{
20
}
/>
}
>
猜拳
</
Button
>
</
Popover
>
);
};
const
OrderPopup
:
React
.
FC
<
React
.
PropsWithChildren
<
{
open
:
boolean
}
>>
=
({
children
,
open
,
})
=>
{
return
(
<
Popover
overlayStyle=
{
{
backdropFilter
:
"
blur(10px)
"
}
}
open=
{
open
}
content=
{
<
Space
>
<
Button
size=
"large"
type=
"text"
icon=
{
<
IconFont
type=
"icon-one"
size=
{
18
}
/>
}
>
先手
</
Button
>
<
Button
size=
"large"
type=
"text"
icon=
{
<
IconFont
type=
"icon-two"
size=
{
18
}
/>
}
>
后手
</
Button
>
</
Space
>
}
trigger=
"focus"
placement=
"bottom"
>
{
children
}
</
Popover
>
);
};
enum
Who
{
Me
=
"
me
"
,
Op
=
"
op
"
,
}
// 玩家区域: 两侧各有一个
const
PlayerZone
:
React
.
FC
<
{
btn
?:
React
.
ReactNode
;
// 在内部右侧可以放一个按钮
isReady
:
boolean
;
who
?:
Who
;
user
?:
User
;
}
>
=
({
btn
,
isReady
,
who
,
user
})
=>
{
return
(
<
div
className=
{
classNames
(
styles
[
"
side-box
"
],
who
&&
styles
[
who
])
}
>
<
div
className=
{
styles
.
inner
}
></
div
>
<
OrderPopup
open=
{
false
}
>
<
div
style=
{
{
position
:
"
relative
"
}
}
>
<
Avatar
src=
{
user
?.
avatar_url
}
size=
{
48
}
/>
{
isReady
&&
<
CheckCircleFilled
className=
{
styles
.
check
}
/>
}
</
div
>
</
OrderPopup
>
<
div
className=
{
styles
.
name
}
>
{
user
?
user
.
username
:
<
Skeleton
.
Input
size=
"small"
/>
}
</
div
>
{
btn
}
</
div
>
);
};
const
Controller
:
React
.
FC
=
()
=>
{
return
(
<
Space
>
<
Select
title=
"卡组"
showSearch
defaultValue=
"lucy"
style=
{
{
width
:
300
}
}
options=
{
[
{
value
:
"
jack
"
,
label
:
"
Jack
"
},
{
value
:
"
lucy
"
,
label
:
"
Lucy
"
},
{
value
:
"
Yiminghe
"
,
label
:
"
yiminghe
"
},
{
value
:
"
disabled
"
,
label
:
"
Disabled
"
,
disabled
:
true
},
]
}
/>
<
Button
size=
"large"
icon=
{
<
IconFont
type=
"icon-record"
size=
{
18
}
/>
}
>
加入观战
<
Avatar
.
Group
className=
{
styles
[
"
avatars-watch
"
]
}
>
<
Avatar
src=
"https://xsgames.co/randomusers/avatar.php?g=pixel&key=1"
size=
"small"
/>
<
Avatar
style=
{
{
backgroundColor
:
"
#f56a00
"
}
}
size=
"small"
>
K
</
Avatar
>
<
Avatar
style=
{
{
backgroundColor
:
"
#87d068
"
}
}
size=
"small"
/>
</
Avatar
.
Group
>
</
Button
>
<
Button
size=
"large"
icon=
{
<
IconFont
type=
"icon-play"
size=
{
12
}
/>
}
>
开始游戏
</
Button
>
</
Space
>
);
};
src/ui/Shared/IconFont/index.tsx
View file @
d58472a2
import
{
createFromIconfontCN
}
from
"
@ant-design/icons
"
;
const
_IconFont
=
createFromIconfontCN
({
scriptUrl
:
[
"
//at.alicdn.com/t/c/font_4188978_
25l7e0zb6xo
.js
"
],
scriptUrl
:
[
"
//at.alicdn.com/t/c/font_4188978_
6q59nqrc9ix
.js
"
],
});
export
const
IconFont
:
React
.
FC
<
{
...
...
@@ -10,5 +10,5 @@ export const IconFont: React.FC<{
color
?:
string
;
style
?:
React
.
CSSProperties
;
}
>
=
({
type
,
size
=
"
inherit
"
,
style
,
color
=
"
inherit
"
})
=>
(
<
_IconFont
type=
{
type
}
style=
{
{
...
style
,
fontSize
:
size
,
color
}
}
/>
<
_IconFont
type=
{
type
}
style=
{
{
fontSize
:
size
,
color
,
...
style
}
}
/>
);
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