Browse Source

header style, ping logic

master
tangmingyou 3 years ago
parent
commit
5a56315b76
  1. 4
      config/dev.js
  2. 29
      src/api/websocket.js
  3. 8
      src/app.js
  4. 1
      src/assets/icon/coin-3.svg
  5. 86
      src/components/style/title.scss
  6. 40
      src/components/title.jsx
  7. 2
      src/pages/lobby/lobby.jsx
  8. 1
      src/store/user.js

4
config/dev.js

@ -10,8 +10,8 @@ module.exports = {
h5: {
devServer: {
//host: '0.0.0.0',
host: '192.168.110.53',
// host: '192.168.3.104',
// host: '192.168.110.53',
host: '192.168.3.101',
port: 10086,
// 设置代理来解决 H5 请求的跨域问题
proxy: {

29
src/api/websocket.js

@ -25,6 +25,7 @@ const websocket = {
msgListener: {}, // {op: func}
waitInitCalls: [],
reconnectInterval: -1,
pingInterval: -1,
closeConn() {
if (this.conn) {
const conn = this.conn;
@ -100,6 +101,10 @@ const websocket = {
this.closeConn();
this.status = 3;
store.dispatch(disconnect());
clearInterval(this.reconnectInterval);
clearInterval(this.pingInterval);
console.log('ws connect failed.');
reject('ws connect failed!');
}
@ -109,6 +114,8 @@ const websocket = {
store.dispatch(disconnect());
console.log('ws connection close.')
clearInterval(this.pingInterval);
if (this.conn === ws) {
this.reconnectPolicy();
// this.reconnectInterval = setInterval(() => {
@ -124,13 +131,19 @@ const websocket = {
console.error('unknow res op:', wrap.op)
return
}
const res = proto[opPath[0]][opPath[1]].decode(wrap.body)
const type = proto[opPath[0]][opPath[1]];
const res = type.decode(wrap.body)
// const res = api.ResIdentity.decode(wrap.body)
console.log('res msg:', res)
if (wrap.reqMs > 0) {
const ttl = Date.now() - wrap.reqMs;
store.dispatch(setTTL(ttl));
// console.log('ping:', ttl + "ms")
// 向后延迟10s -> ping
if (type !== api.Pong) {
this.runPingInterval();
}
}
if (wrap.seq !== 0) {
@ -199,6 +212,20 @@ const websocket = {
}, 3000);
},
waitCall: {}, // 等待响应的 callback 列表
runPingInterval() {
clearInterval(this.pingInterval);
this.pingInterval = setInterval(async () => {
this.send(api.Ping.create({ms: Date.now()}),
pong => {
const ttl = Date.now() - pong.pingMs;
store.dispatch(setTTL(ttl));
},
err => {
console.log('ping error:', err)
}
);
}, 10000);
},
send(msg, resCall, errCall) {
window.msg = msg;
// 不是认证消息且连接未认证,将请求放到等待队列

8
src/app.js

@ -85,10 +85,10 @@ class App extends Component {
} else {
// 尝试连接 websocket
Promise.all([fetchOpMap(), fetchRouteWs()])
.then(([opMap, wsRes]) => {
// console.log('token', token, opMap, wsRes)
websocket.init(token, opMap.data, wsRes.data);
window.websocket = websocket;
.then(async ([opMapRes, wsRes]) => {
const res = await websocket.init(opMapRes.data, wsRes.data);
console.log('ws identity success:', res)
// window.websocket = websocket;
setTimeout(() => redirectTo({url: '/pages/lobby/lobby'}), 500);
})
.catch(err => {

1
src/assets/icon/coin-3.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="14" height="14" viewBox="0 0 14 14"><g><path d="M8.39773,6.67645e-7C11.0369,-0.00125868,13.3187,1.84119,13.8741,4.42201C14.4295,7.00284,13.1077,9.6212,10.7017,10.7063C9.08883,14.2731,4.40856,15.1265,1.64117,12.3584C-1.12622,9.59021,-0.273063,4.90862,3.2928,3.29526C4.1988,1.28926,6.19608,8.34556e-7,8.39773,6.67645e-7ZM6.29809,4.90054L4.89833,4.90054L4.89833,5.60061C3.9527,5.59831,3.17634,6.34798,3.14531,7.29337C3.11428,8.23876,3.8398,9.03775,4.78355,9.0975L4.89833,9.101L6.29809,9.101L6.36108,9.1066C6.52759,9.13676,6.64867,9.28177,6.64867,9.45104C6.64867,9.6203,6.52759,9.76532,6.36108,9.79547L6.29809,9.80107L3.49857,9.80107L3.49857,11.2012L4.89833,11.2012L4.89833,11.9013L6.29809,11.9013L6.29809,11.2012C7.24372,11.2035,8.02008,10.4539,8.05111,9.50847C8.08214,8.56308,7.35662,7.76409,6.41287,7.70434L6.29809,7.70084L4.89833,7.70084L4.83534,7.69524C4.66883,7.66509,4.54775,7.52007,4.54775,7.35081C4.54775,7.18154,4.66883,7.03653,4.83534,7.00637L4.89833,7.00077L7.69785,7.00077L7.69785,5.60061L6.29809,5.60061L6.29809,4.90054ZM8.39773,1.40015C7.19817,1.39875,6.05557,1.91184,5.25947,2.80941C8.61443,2.60568,11.3915,5.38388,11.1875,8.73976C12.4903,7.58111,12.9419,5.7378,12.3224,4.10786C11.7026,2.47771,10.1407,1.40015,8.39773,1.40015Z" fill="#EE914E" fill-opacity="1"/></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

86
src/components/style/title.scss

@ -12,24 +12,96 @@
}
.page-title {
padding: 0 32px;
padding: 0 14px;
height: 46px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
position: relative;
.title-left {
display: flex;
justify-content: flex-start;
}
.icon {
width: 34px;
height: 30px;
// font-size: 40px;
}
.net-wrap {
display: flex;
align-items: center;
margin-left: 12px;
}
.net-disconnect,.net-connecting,.net-connected {
width: 18px;
height: 18px;
border-radius: 50%;
background-color: #f40;
}
.net-disconnect {
background-color: #F64B4B;
}
.net-connecting {
background-color: #99ADCB;
}
.net-connected {
background-color: #1BCE7D;
}
.net-connected-high {
background-color: #EED87D;
}
.ttl {
margin-left: 4px;
font-weight: normal;
font-size: 12px;
}
.title {
.title,.title1 {
font-size: 18px;
color: #ffffff;
color: #000;
// align-self: center;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
text-align: center;
line-height: 46px;
}
.title-right {
display: flex;
}
.profile {
margin-right: 8px;
}
.username {
font-size: 12px;
text-align: right;
color: #3D3D3D;
font-weight: bold;
font-weight: normal;
margin-top: 0px;
line-height: 28px;
}
.balance-wrap {
font-weight: bold;
color: #EE914E;
font-size: 12px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
line-height: 14px;
}
.balance-icon {
height: 15px;
width: 15px;
}
.balance {
margin-left: 2px;
}
.title-avatar-wrap {
width: 48px;
height: 48px;
@ -44,10 +116,6 @@
border-radius: 50%;
margin-top: 2px;
}
.username {
font-size: 12px;
font-weight: normal;
}
}
}

40
src/components/title.jsx

@ -1,25 +1,48 @@
import React from 'react'
import { View, Text, Image } from '@tarojs/components'
import React from 'react';
import cnames from 'classnames';
import { useSelector } from 'react-redux';
import { View, Text, Image } from '@tarojs/components';
import { Menu, MenuItem } from '@nutui/nutui-react-taro';
import { navigateBack } from '@/utils/application'
import left from '@/assets/icon/left-1.svg'
import './style/title.scss'
import { navigateBack } from '@/utils/application';
import left from '@/assets/icon/left-1.svg';
import './style/title.scss';
import { useSelector } from 'react-redux'
import coinIcon from '@/assets/icon/coin-3.svg'
function Title(props) {
const {username, nickname, avatar, defaultAvatar} = useSelector(state => state.user);
const {username, nickname, avatar, defaultAvatar, balance, status: netStatus, ttl} = useSelector(state => ({
...state.user, ...state.conn
}));
const { leftSolt, leftIcon, onLeftClick, rightSolt } = props;
return (
<View>
<View className={props.bgColor ? "page-top bgc" : "page-top"}>
{/* <View className='topHeight'></View> */}
<View className='page-title'>
<View className="title-left">
{leftSolt || <Image className="icon" src={leftIcon || left} onClick={onLeftClick || navigateBack} />}
{/*1已断开,2连接中,3已连接*/}
<View className="net-wrap">
<View className={cnames('', {
'net-disconnect': netStatus === 1,
'net-connecting': netStatus === 2,
'net-connected': netStatus === 3,
'net-connected-high': netStatus === 3 && ttl > 500,
})}></View>
<View className="ttl">{ttl + 'ms'}</View>
</View>
</View>
<View className={props.colorStyle ? "title" : "title1"}>
<View><Text className="username">{username}</Text></View>
<View><Text>{props.title}</Text></View>
</View>
<View className="title-right">
<View className="profile">
<View className="username"><Text >{username}</Text></View>
<View className="balance-wrap">
<Image src={coinIcon} className="balance-icon"/>
<Text className="balance">{balance}</Text>
</View>
</View>
{
rightSolt || <View className='title-avatar-wrap'>
<Image className='avatar' src={avatar || defaultAvatar} />
@ -27,6 +50,7 @@ function Title(props) {
}
</View>
</View>
</View>
{props.topNull ? '' : <View className='hidden'></View>}
</View>
)

2
src/pages/lobby/lobby.jsx

@ -84,7 +84,7 @@ class Lobby extends Component {
return (
<View>
<Title title={"Lobby!!"} bgColor={true} leftSolt={
<Title title={("Lobby","")} bgColor={true} leftSolt={
<Image className={cnames("refresh-icon", {'refresh-icon-rotate': this.state.lobbyLoading})}
src={refreshIcon}
onClick={this.handleReqLobbyView}

1
src/store/user.js

@ -8,6 +8,7 @@ const userSlice = createSlice({
nickname: 'PromNick',
avatar: '',
defaultAvatar: 'https://img0.baidu.com/it/u=2477829979,2171947490&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
balance: 30000,
},
reducers: {
setUserInfo: (state, {payload}) => {

Loading…
Cancel
Save