main
鲁誉程 2 months ago
parent af403afb01
commit 05fb19c521

@ -269,7 +269,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'WebSocket connection failed'
text : 'WebSocket连接失败'
}));
});
@ -278,7 +278,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'WebSocket disconnected'
text : 'WebSocket已断开连接'
}));
// Close mediasoup Transports.
@ -399,7 +399,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error creating a Consumer: ${error}`
text : `创建用户时出错: ${error}`
}));
throw error;
@ -468,7 +468,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'DataConsumer closed'
text : 'DataConsumer 已关闭'
}));
});
@ -479,7 +479,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `DataConsumer error: ${error}`
text : `DataConsumer 错误: ${error}`
}));
});
@ -543,6 +543,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'userMessage',
title : `${sendingPeer.displayName} says:`,
text : message,
timeout : 5000
@ -587,7 +588,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error creating a DataConsumer: ${error}`
text : `创建DataConsumer时出错: ${error}`
}));
throw error;
@ -636,7 +637,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
text : `${peer.displayName} has joined the room`
text : `${peer.displayName} 加入房间`
}));
break;
@ -859,7 +860,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'Microphone disconnected!'
text : '麦克风断开!'
}));
this.disableMic()
@ -873,7 +874,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error enabling microphone: ${error}`
text : `启用麦克风时出错: ${error}`
}));
if (track)
@ -903,7 +904,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error closing server-side mic Producer: ${error}`
text : `关闭服务器端麦克风生成器时出错: ${error}`
}));
}
@ -931,7 +932,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error pausing server-side mic Producer: ${error}`
text : `暂停服务器端麦克风生成器时出错: ${error}`
}));
}
}
@ -957,7 +958,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error resuming server-side mic Producer: ${error}`
text : `恢复服务器端麦克风生成器时出错: ${error}`
}));
}
}
@ -1148,7 +1149,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'Webcam disconnected!'
text : '网络摄像头已断开连接!'
}));
this.disableWebcam()
@ -1162,7 +1163,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error enabling webcam: ${error}`
text : `启用网络摄像头时出错: ${error}`
}));
if (track)
@ -1195,7 +1196,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error closing server-side webcam Producer: ${error}`
text : `关闭服务器端网络摄像头生成器时出错: ${error}`
}));
}
@ -1265,7 +1266,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Could not change webcam: ${error}`
text : `无法更改网络摄像头: ${error}`
}));
}
@ -1322,7 +1323,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Could not change webcam resolution: ${error}`
text : `无法更改网络摄像头分辨率: ${error}`
}));
}
@ -1517,7 +1518,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'Share disconnected!'
text : '共享已断开连接!'
}));
this.disableShare()
@ -1533,7 +1534,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error sharing: ${error}`
text : `共享错误: ${error}`
}));
}
@ -1567,7 +1568,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error closing server-side share Producer: ${error}`
text : `关闭服务器端共享生成器时出错: ${error}`
}));
}
@ -1674,7 +1675,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
text : 'ICE restarted'
text : 'ICE 重新启动'
}));
}
catch (error)
@ -1684,7 +1685,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `ICE restart failed: ${error}`
text : `ICE 重启失败: ${error}`
}));
}
@ -1710,7 +1711,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error setting max sending video spatial layer: ${error}`
text : `设置最大发送视频空间层时出错: ${error}`
}));
}
}
@ -1736,7 +1737,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error setting Consumer preferred layers: ${error}`
text : `设置用户首选图层时出错: ${error}`
}));
}
}
@ -1760,7 +1761,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error setting Consumer priority: ${error}`
text : `设置用户优先级时出错: ${error}`
}));
}
}
@ -1775,7 +1776,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
text : 'Keyframe requested for video consumer'
text : '为视频用户请求关键帧'
}));
}
catch (error)
@ -1785,7 +1786,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error requesting key frame for Consumer: ${error}`
text : `为用户请求关键帧时出错: ${error}`
}));
}
}
@ -1840,7 +1841,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'Chat DataProducer closed'
text : '聊天数据生成器已关闭'
}));
});
@ -1851,7 +1852,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Chat DataProducer error: ${error}`
text : `聊天数据生成器错误: ${error}`
}));
});
@ -1867,7 +1868,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error enabling chat DataProducer: ${error}`
text : `启用聊天数据生成器时出错: ${error}`
}));
throw error;
@ -1924,7 +1925,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'Bot DataProducer closed'
text : 'Bot DataProducer 已关闭'
}));
});
@ -1935,7 +1936,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Bot DataProducer error: ${error}`
text : `Bot DataProducer 错误: ${error}`
}));
});
@ -1951,7 +1952,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error enabling bot DataProducer: ${error}`
text : `启用bot DataProducter时出错: ${error}`
}));
throw error;
@ -1967,7 +1968,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'No chat DataProducer'
text : '无聊天 DataProducter'
}));
return;
@ -1984,7 +1985,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `chat DataProducer.send() failed: ${error}`
text : `聊天DataProducter.send()失败: ${error}`
}));
}
}
@ -2038,7 +2039,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
text : 'Display name changed'
text : '显示名称已更改'
}));
}
catch (error)
@ -2048,7 +2049,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Could not change display name: ${error}`
text : `无法更改显示名称: ${error}`
}));
// We need to refresh the component for it to render the previous
@ -2225,7 +2226,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error applying network throttle: ${error}`
text : `应用网络节流时出错: ${error}`
}));
}
}
@ -2247,7 +2248,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error resetting network throttle: ${error}`
text : `重置网络节流阀时出错: ${error}`
}));
}
}
@ -2479,11 +2480,12 @@ export default class RoomClient
store.dispatch(
stateActions.removeAllNotifications());
store.dispatch(requestActions.notify(
{
text : 'You are in the room!',
timeout : 3000
}));
// store.dispatch(requestActions.notify(
// {
// isMe : true,
// text : '你已成功加入房间',
// timeout : 3000
// }));
for (const peer of peers)
{
@ -2535,7 +2537,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Could not join the room: ${error}`
text : `无法加入房间: ${error}`
}));
this.close();
@ -2614,7 +2616,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error pausing Consumer: ${error}`
text : `暂停用户时出错: ${error}`
}));
}
}
@ -2640,7 +2642,7 @@ export default class RoomClient
store.dispatch(requestActions.notify(
{
type : 'error',
text : `Error resuming Consumer: ${error}`
text : `恢复用户时出错: ${error}`
}));
}
}

@ -2,18 +2,17 @@ import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRoomContext } from '../RoomContext';
import * as requestActions from '../redux/requestActions';
const BotMessageRegex = new RegExp('^@bot (.*)');
class ChatInput extends React.Component
{
constructor(props)
{
class ChatInput extends React.Component {
constructor(props) {
super(props);
this.state =
{
text : ''
text: ''
};
// TextArea element got via React ref.
@ -21,12 +20,12 @@ class ChatInput extends React.Component
this._textareaElem = null;
}
render()
{
render() {
const {
connected,
chatDataProducer,
botDataProducer
botDataProducer,
sendUserInfo
} = this.props;
const { text } = this.state;
@ -37,27 +36,29 @@ class ChatInput extends React.Component
<div data-component='ChatInput'>
<textarea
ref={(elem) => { this._textareaElem = elem; }}
placeholder={disabled ? 'Chat unavailable' : 'Write here...'}
placeholder={disabled ? '当前聊天不可用' : '请输入聊天内容'}
dir='auto'
autoComplete='off'
disabled={disabled}
value={text}
value={text || ''}
onChange={this.handleChange.bind(this)}
onKeyPress={this.handleKeyPress.bind(this)}
onKeyPress={this.handleKeyPress.bind(this, sendUserInfo)}
/>
<div className='sendOut' onClick={() => {
this.sendOut(sendUserInfo);
}}>发送</div>
</div>
);
}
handleChange(event)
{
handleChange(event) {
const text = event.target.value;
this.setState({ text });
}
handleKeyPress(event)
{
handleKeyPress(sendUserInfo, event) {
// If Shift + Enter do nothing.
if (event.key !== 'Enter' || (event.shiftKey || event.ctrlKey))
return;
@ -65,25 +66,26 @@ class ChatInput extends React.Component
// Don't add the sending Enter into the value.
event.preventDefault();
this.sendOut(sendUserInfo)
}
sendOut(sendUserInfo) {
let text = this.state.text.trim();
this.setState({ text: '' });
if (text)
{
if (text) {
const { roomClient } = this.props;
const match = BotMessageRegex.exec(text);
// Chat message.
if (!match)
{
if (!match) {
text = text.trim();
roomClient.sendChatMessage(text);
sendUserInfo(text);
}
// Message to the bot.
else
{
else {
text = match[1].trim();
roomClient.sendBotMessage(text);
@ -94,14 +96,13 @@ class ChatInput extends React.Component
ChatInput.propTypes =
{
roomClient : PropTypes.any.isRequired,
connected : PropTypes.bool.isRequired,
chatDataProducer : PropTypes.any,
botDataProducer : PropTypes.any
roomClient: PropTypes.any.isRequired,
connected: PropTypes.bool.isRequired,
chatDataProducer: PropTypes.any,
botDataProducer: PropTypes.any
};
const mapStateToProps = (state) =>
{
const mapStateToProps = (state) => {
const dataProducersArray = Object.values(state.dataProducers);
const chatDataProducer = dataProducersArray
.find((dataProducer) => dataProducer.label === 'chat');
@ -109,15 +110,27 @@ const mapStateToProps = (state) =>
.find((dataProducer) => dataProducer.label === 'bot');
return {
connected : state.room.state === 'connected',
connected: state.room.state === 'connected',
chatDataProducer,
botDataProducer
};
};
const mapDispatchToProps = (dispatch) => {
return {
sendUserInfo: (text) => {
dispatch(requestActions.notify({
type: 'userMessage',
isMe: true,
text: text,
}));
}
};
};
const ChatInputContainer = withRoomContext(connect(
mapStateToProps,
undefined
mapDispatchToProps,
)(ChatInput));
export default ChatInputContainer;

@ -159,7 +159,7 @@ class Me extends React.Component
/>
<ReactTooltip
type='light'
place='right'
effect='solid'
delayShow={100}
delayHide={100}

@ -6,55 +6,91 @@ import * as appPropTypes from './appPropTypes';
import * as stateActions from '../redux/stateActions';
import { Appear } from './transitions';
const Notifications = ({ notifications, onClick }) =>
{
const Notifications = ({ notifications, onClick }) => {
console.log("notifications", notifications);
return (
<div data-component='Notifications'>
{
notifications.map((notification) =>
{
return (
<Appear key={notification.id} duration={250}>
<div
className={classnames('notification', notification.type)}
onClick={() => onClick(notification.id)}
>
<div className='icon' />
<div data-component='Notifications' style={{
width: '383px',
background: '#F6F7F9',
borderRadius: '8px',
margin: '48px 30px 19px 0px'
}}>
<div className='chatTitle'>聊天</div>
<div className='body'>
<If condition={notification.title}>
<p className='title'>{notification.title}</p>
</If>
<div className='chatwarp'>
{
notifications.map((notification) => {
return (
<div key={notification.id} style={{ padding: '0 20px', fontSize: '14px' }}>
{
//
notification.type == 'userMessage' ?
<div style={{marginTop: 36}}>
{
notification.isMe ?
<div style={{ display: 'flex', flexDirection: 'row-reverse', flexWrap: 'wrap' }}>
<div style={{ color: '#232B40', marginBottom: 10, width: '100%', textAlign: 'right' }}></div>
<div style={{ width: 'max-content', padding: '10px 20px', color: '#434D6C', lineHeight: '26px', background: '#CDD8F1', borderRadius: '8px 0px 8px 8px' }}>
{notification.text}
</div>
</div> :
<>
<div style={{ color: '#232B40', marginBottom: 10 }}>用户-{notification.id}</div>
<div style={{ width: 'max-content', padding: '10px 20px', color: '#434D6C', lineHeight: '26px', background: '#fff', borderRadius: '0px 8px 8px 8px' }}>
{notification.text}
</div>
</>
}
</div> :
<div style={{width: '100%', margin: '20px 0', textAlign: 'center'}}>
{notification.text}
</div>
}
<p className='text'>{notification.text}</p>
</div>
</div>
</Appear>
);
})
}
//
// <Appear key={notification.id} duration={250}>
// <div
// className={classnames('notification', notification.type)}
// onClick={() => onClick(notification.id)}
// >
// <div className='icon' />
// <div className='body'>
// <If condition={notification.title}>
// <p className='title'>{notification.title}</p>
// </If>
// <p className='text'>{notification.text}</p>
// </div>
// </div>
// </Appear>
);
})
}
</div>
</div>
);
};
Notifications.propTypes =
{
notifications : PropTypes.arrayOf(appPropTypes.Notification).isRequired,
onClick : PropTypes.func.isRequired
notifications: PropTypes.arrayOf(appPropTypes.Notification).isRequired,
onClick: PropTypes.func.isRequired
};
const mapStateToProps = (state) =>
{
const mapStateToProps = (state) => {
const { notifications } = state;
return { notifications };
};
const mapDispatchToProps = (dispatch) =>
{
const mapDispatchToProps = (dispatch) => {
return {
onClick : (notificationId) =>
{
onClick: (notificationId) => {
dispatch(stateActions.removeNotification(notificationId));
}
};

@ -99,7 +99,7 @@ export default class PeerView extends React.Component
return (
<div data-component='PeerView'>
<div className='info'>
<div className='icons'>
{/* <div className='icons'>
<div
className={classnames('icon', 'info', { on: showInfo })}
onClick={() => this.setState({ showInfo: !showInfo })}
@ -395,12 +395,14 @@ export default class PeerView extends React.Component
{this._printConsumerScore(videoConsumerId, videoScore)}
</If>
</If>
</div>
</div> */}
<div className={classnames('peer', { 'is-me': isMe })}>
<div className={classnames('peer', { 'is-me': isMe })} style={{position: 'absolute', bottom: 0}}>
<Choose>
<When condition={isMe}>
<EditableInput
<span className='display-name'>{peer.displayName}</span>
{/* 可自行修改名称 */}
{/* <EditableInput
value={peer.displayName}
propName='displayName'
className='display-name editable'
@ -413,7 +415,7 @@ export default class PeerView extends React.Component
spellCheck : 'false'
}}
onChange={({ displayName }) => onChangeDisplayName(displayName)}
/>
/> */}
</When>
<Otherwise>

@ -34,9 +34,17 @@ class Room extends React.Component
return (
<Appear duration={300}>
<div data-component='Room'>
<div className='crumbs'>
<span className='goback' onClick={() => {history.push('/counselling/expertList')}}>
值班专家<span style={{margin: '0 4px'}}>{`>`}</span>
</span>
<span style={{color: '#5F6368'}}>在线聊天</span>
</div>
<Notifications />
<div className='state'>
{/* 当前房间状态信息 */}
{/* <div className='state'>
<div className={classnames('icon', room.state)} />
<p className={classnames('text', room.state)}>{room.state}</p>
</div>
@ -45,9 +53,10 @@ class Room extends React.Component
<p className='text'><span className='label'>server:&nbsp;&nbsp;</span>{room.mediasoupVersion}</p>
<p className='text'><span className='label'>client:&nbsp;&nbsp;</span>{mediasoupClientVersion}</p>
<p className='text'><span className='label'>handler:&nbsp;&nbsp;</span>{room.mediasoupClientHandler}</p>
</div>
</div> */}
<div className='room-link-wrapper'>
{/* 复制当前房间链接 */}
{/* <div className='room-link-wrapper'>
<div className='room-link'>
<a
className='link'
@ -76,7 +85,7 @@ class Room extends React.Component
invitation link
</a>
</div>
</div>
</div> */}
<Peers />
@ -98,7 +107,7 @@ class Room extends React.Component
on : me.audioOnly,
disabled : me.audioOnlyInProgress
})}
data-tip={'Show/hide participants\' video'}
data-tip={'将参与者的视频 显示/隐藏'}
onClick={() =>
{
me.audioOnly
@ -111,7 +120,7 @@ class Room extends React.Component
className={classnames('button', 'mute-audio', {
on : me.audioMuted
})}
data-tip={'Mute/unmute participants\' audio'}
data-tip={'将参与者的音频 静音/取消静音'}
onClick={() =>
{
me.audioMuted
@ -124,12 +133,13 @@ class Room extends React.Component
className={classnames('button', 'restart-ice', {
disabled : me.restartIceInProgress
})}
data-tip='Restart ICE'
data-tip='重新启动 ICE'
onClick={() => roomClient.restartIce()}
/>
</div>
<Stats />
{/* 当前房间状态信息 */}
{/* <Stats /> */}
<If condition={window.NETWORK_THROTTLE_SECRET}>
<NetworkThrottle
@ -138,7 +148,7 @@ class Room extends React.Component
</If>
<ReactTooltip
type='light'
place='right'
effect='solid'
delayShow={100}
delayHide={100}
@ -182,7 +192,7 @@ const mapDispatchToProps = (dispatch) =>
{
dispatch(requestActions.notify(
{
text : 'Room link copied to the clipboard'
text : '房间链接已复制到剪贴板'
}));
}
};

@ -2,7 +2,7 @@ import randomString from 'random-string';
import * as stateActions from './stateActions';
// This returns a redux-thunk action (a function).
export const notify = ({ type = 'info', text, title, timeout }) =>
export const notify = ({ type = 'info', isMe = false, text, title, timeout }) =>
{
if (!timeout)
{
@ -23,16 +23,16 @@ export const notify = ({ type = 'info', text, title, timeout }) =>
type,
title,
text,
timeout
timeout,
isMe,
};
return (dispatch) =>
{
dispatch(stateActions.addNotification(notification));
setTimeout(() =>
{
dispatch(stateActions.removeNotification(notification.id));
}, timeout);
// setTimeout(() =>
// {
// dispatch(stateActions.removeNotification(notification.id));
// }, timeout);
};
};

@ -2,19 +2,35 @@
position: relative;
height: 100%;
width: 100%;
display: flex;
align-items: center;
> .sendOut {
width: 80px;
height: 34px;
background: linear-gradient( 139deg, #5C64FF 0%, #6988F8 100%);
border-radius: 17px;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 12px;
margin: 0 12px;
}
> textarea {
height: 100%;
// height: 100%;
width: 100%;
padding: 4px 8px;
resize: none;
outline: none;
background-color: rgba(#243B55, 1);
color: #fff;
background-color: rgba(#fff, 1);
color: #000;
font-family: inherit;
font-size: 13px;
font-weight: 400;
line-height: 22px;
line-height: 23px;
border: none;
+placeholder() {

@ -6,7 +6,7 @@
padding: 0 20px;
background: rgba(#fff, 0.95);
border-radius: 4px;
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
// box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
font-family: 'Roboto';
> h1.draggable {

@ -1,19 +1,18 @@
[data-component='Notifications'] {
position: fixed;
z-index: 9999;
pointer-events: none;
// pointer-events: none;
top: 0;
right: 0;
bottom: 0;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
//justify-content: flex-end;
//align-items: flex-end;
+desktop() {
padding: 10px;
width: 300px;
// padding: 10px;
// width: 300px;
}
+mobile() {
@ -22,6 +21,23 @@
max-width: 220px;
}
> .chatTitle {
color: #000;
font-size: 16px;
height: 54px;
line-height: 54px;
padding-left: 20px;
border-bottom: 1px solid #EBEBEB;
font-weight: 500;
}
> .chatwarp {
overflow: hidden;
overflow-y: auto;
height: calc(100% - 50px - 85px);
}
> .notification {
pointer-events: auto;
margin-top: 4px;

@ -165,7 +165,7 @@
}
&:not(.is-me) {
padding: 20px;
padding: 10px;
align-items: flex-start;
pointer-events: none;
}

@ -3,8 +3,9 @@
width: 100%;
+desktop() {
width: 100%;
padding: 40px 0 220px 0;
width: calc(100% - 423px);
background: #fff;
padding: 40px 0 220px 50px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
@ -29,11 +30,12 @@
+desktop() {
flex: 0 0 auto;
height: 382px;
width: 450px;
margin: 6px;
border-radius: 8px;
height: 202px;
width: 264px;
margin: 10px;
border: 1px solid rgba(#fff, 0.15);
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
// box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
transition-property: border-color;
transition-duration: 0.35s;

@ -5,6 +5,21 @@
AppearFadeIn(300ms);
> .crumbs {
position: absolute;
margin: 16px 30px;
font-size: 14px;
> .goback {
cursor: pointer;
color: #C5C5C5;
&:hover {
color: #5F6368;
}
}
}
> .state {
position: fixed;
z-index: 100;
@ -189,7 +204,7 @@
position: fixed;
z-index: 100;
overflow: hidden;
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
// box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
transition-property: border-color;
transition-duration: 0.2s;
@ -198,10 +213,11 @@
}
+desktop() {
height: 250px;
width: 294px;
bottom: 60px;
height: 202px;
width: 264px;
bottom: 20px;
left: 20px;
border-radius: 8px;
border: 1px solid rgba(#fff, 0.15);
}
@ -216,16 +232,19 @@
> .chat-input-container {
position: fixed;
z-index: 100;
z-index: 9999;
overflow: hidden;
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
+desktop() {
height: 30px;
width: 294px;
bottom: 20px;
left: 20px;
border: 1px solid rgba(#fff, 0.15);
bottom: 30px;
right: 45px;
width: 350px;
height: 60px;
height: 60px;
background: #FFFFFF;
box-shadow: 0px 0px 10px 0px rgba(226,226,226,0.5);
border-radius: 8px;
}
+mobile() {
@ -265,7 +284,7 @@
background-position: center;
background-size: 75%;
background-repeat: no-repeat;
background-color: $COLOR_BG_1;
background-color: rgba(#000, 0.3);
cursor: pointer;
transition-property: opacity, background-color;
transition-duration: 0.2s;

@ -16,7 +16,7 @@ html {
// background-size: cover;
// background-repeat: no-repeat;
background: #141E30;
background: linear-gradient(to top, #243B55, #141E30);
background: #fff;
font-family: 'Roboto';
font-weight: 300;
@ -36,6 +36,7 @@ body {
#mediasoup-demo-app-container {
height: 100%;
width: 100%;
background: #fff;
// Components
@import './components/Room';
@ -67,3 +68,23 @@ body {
position: fixed; // Required for old IE
}
}
::-webkit-scrollbar {
height: 6px;
width: 6px;
background: rgba(0, 0, 0, 0.1) !important;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1) !important;
border-radius: 3px;
&:hover {
background: rgba(0, 0, 0, 0.20) !important;
}
}
::-webkit-scrollbar-track {
background-color: #f6f7f94d !important;
box-shadow: initial !important;
}

@ -17,7 +17,7 @@ module.exports =
// Signaling settings (protoo WebSocket server and HTTP API server).
https :
{
listenIp : '192.168.0.167', // 换成你的IP地址
listenIp : '0.0.0.0', // 换成你的IP地址
// NOTE: Don't change listenPort (client app assumes 4443).
listenPort : process.env.PROTOO_LISTEN_PORT || 4443,
// NOTE: Set your own valid certificate files.

Loading…
Cancel
Save