Add button styling
This commit is contained in:
10
.vscode/settings.json
vendored
Normal file
10
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"css.lint.validProperties": [
|
||||||
|
"composes"
|
||||||
|
],
|
||||||
|
"css.lint.unknownAtRules": "ignore",
|
||||||
|
"scss.lint.validProperties": [
|
||||||
|
"composes"
|
||||||
|
],
|
||||||
|
"scss.lint.unknownAtRules": "ignore"
|
||||||
|
}
|
||||||
1
public/phone-solid.svg
Normal file
1
public/phone-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="phone" class="svg-inline--fa fa-phone fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="white" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 504 B |
1
public/play-solid.svg
Normal file
1
public/play-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="play" class="svg-inline--fa fa-play fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="white" d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 332 B |
50
src/Components/Phone/Button/button.module.css
Normal file
50
src/Components/Phone/Button/button.module.css
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
.button {
|
||||||
|
border-radius: 50%;
|
||||||
|
border: none;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
.button:after {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.connect {
|
||||||
|
composes: button;
|
||||||
|
background-color: #45bd57;
|
||||||
|
}
|
||||||
|
.connect:hover {
|
||||||
|
background-image: linear-gradient(#76b880, #5fb86c);
|
||||||
|
}
|
||||||
|
.connect:after {
|
||||||
|
content: url(/play-solid.svg);
|
||||||
|
transform: scale(0.4);
|
||||||
|
position: relative;
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer {
|
||||||
|
composes: button;
|
||||||
|
background-color: #45bd57;
|
||||||
|
}
|
||||||
|
.answer:hover {
|
||||||
|
background-image: linear-gradient(#84b68c, #5fb86c);
|
||||||
|
}
|
||||||
|
.answer:after {
|
||||||
|
content: url(/phone-solid.svg);
|
||||||
|
transform: scale(0.65);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hangup, .reject {
|
||||||
|
composes: button;
|
||||||
|
background-color: #ff3b2f;
|
||||||
|
}
|
||||||
|
.hangup:hover, .reject:hover {
|
||||||
|
background-image: linear-gradient(#fd7f79, #fc564e);
|
||||||
|
}
|
||||||
|
.hangup:after, .reject:after {
|
||||||
|
content: url(/phone-solid.svg);
|
||||||
|
transform: rotate(224deg) scale(0.65);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import styles from './button.module.css';
|
||||||
|
|
||||||
interface ButtonSettings
|
interface ButtonSettings
|
||||||
{
|
{
|
||||||
@@ -8,8 +9,7 @@ interface ButtonSettings
|
|||||||
|
|
||||||
export default function Button({title, onClick} : ButtonSettings) {
|
export default function Button({title, onClick} : ButtonSettings) {
|
||||||
return (
|
return (
|
||||||
<button onClick={() => onClick()}>
|
<button className={styles[title]} onClick={() => onClick()}>
|
||||||
{ title }
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import useVoice, { Voice } from '../../Wrappers/voice';
|
import useVoice, { Voice } from '../../Wrappers/voice';
|
||||||
import { voiceToken } from '../../Wrappers/default-config';
|
import { voiceToken } from '../../Wrappers/default-config';
|
||||||
import Button from './button';
|
import Button from './Button/button';
|
||||||
import DeviceState from './display-device-state';
|
import DeviceState from './display-device-state';
|
||||||
|
|
||||||
export default function Phone({voice:{ startDevice, answer, reject, hangup, dial, voiceState} }: {voice: Voice})
|
export default function Phone({voice:{ startDevice, answer, reject, hangup, dial, voiceState} }: {voice: Voice})
|
||||||
@@ -11,7 +11,7 @@ export default function Phone({voice:{ startDevice, answer, reject, hangup, dial
|
|||||||
return (
|
return (
|
||||||
<div className="Phone">
|
<div className="Phone">
|
||||||
<DeviceState deviceState = {voiceState.deviceState}/>
|
<DeviceState deviceState = {voiceState.deviceState}/>
|
||||||
<Button title = "Start Device" onClick = {() => startDevice(voiceToken)}/>
|
<Button title = "connect" onClick = {() => startDevice(voiceToken)}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -20,8 +20,8 @@ export default function Phone({voice:{ startDevice, answer, reject, hangup, dial
|
|||||||
return (
|
return (
|
||||||
<div className="Phone">
|
<div className="Phone">
|
||||||
<DeviceState deviceState = {voiceState.deviceState}/>
|
<DeviceState deviceState = {voiceState.deviceState}/>
|
||||||
<Button title = "Answer" onClick = {() => answer()}/>
|
<Button title = "reject" onClick = {() => reject()}/>
|
||||||
<Button title = "Reject" onClick = {() => reject()}/>
|
<Button title = "answer" onClick = {() => answer()}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ export default function Phone({voice:{ startDevice, answer, reject, hangup, dial
|
|||||||
return (
|
return (
|
||||||
<div className="Phone">
|
<div className="Phone">
|
||||||
<DeviceState deviceState = {voiceState.deviceState}/>
|
<DeviceState deviceState = {voiceState.deviceState}/>
|
||||||
<Button title = "Hang Up" onClick = {() => hangup()}/>
|
<Button title = "hangup" onClick = {() => hangup()}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Connection, ConnectionParameters, ConnectionStatus, ConnectionEvent } from "twilio-client";
|
import { Connection, ConnectionParameters, ConnectionStatus, ConnectionEvent } from "twilio-client";
|
||||||
|
import { defaultDelay } from "./mock-device";
|
||||||
|
|
||||||
export class MockConnection implements Connection
|
export class MockConnection implements Connection
|
||||||
{
|
{
|
||||||
@@ -13,31 +14,35 @@ export class MockConnection implements Connection
|
|||||||
private readonly handlers = <{[key in ConnectionEvent]: ((mute?: boolean) => void)[]}>{};
|
private readonly handlers = <{[key in ConnectionEvent]: ((mute?: boolean) => void)[]}>{};
|
||||||
private muted: boolean = false;
|
private muted: boolean = false;
|
||||||
|
|
||||||
|
private executeHandler(handlerName: ConnectionEvent)
|
||||||
|
{
|
||||||
|
setTimeout(() => this.handlers[handlerName]?.forEach(handler => handler()), defaultDelay);
|
||||||
|
}
|
||||||
|
|
||||||
public accept(audioConstraints?: any)
|
public accept(audioConstraints?: any)
|
||||||
{
|
{
|
||||||
setTimeout(() => this.handlers["accept"].forEach(handler => handler()), 500)
|
this.executeHandler("accept");
|
||||||
}
|
}
|
||||||
|
|
||||||
public reject()
|
public reject()
|
||||||
{
|
{
|
||||||
setTimeout(() => this.handlers["disconnect"].forEach(handler => handler()), 500)
|
this.executeHandler("disconnect");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ignore()
|
public ignore()
|
||||||
{
|
{
|
||||||
setTimeout(() => this.handlers["disconnect"].forEach(handler => handler()), 500)
|
this.executeHandler("disconnect");
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnect()
|
public disconnect()
|
||||||
{
|
{
|
||||||
setTimeout(() => this.handlers["disconnect"].forEach(handler => handler()), 500)
|
this.executeHandler("disconnect");
|
||||||
}
|
}
|
||||||
|
|
||||||
public mute(mute: boolean)
|
public mute(mute: boolean)
|
||||||
{
|
{
|
||||||
this.muted = mute
|
this.muted = mute;
|
||||||
setTimeout(() => this.handlers["mute"].forEach(handler => handler(this.muted)), 500)
|
this.executeHandler("mute");
|
||||||
}
|
}
|
||||||
|
|
||||||
public isMuted()
|
public isMuted()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Device, DeviceAudio, SetupParams, Connection, DeviceStatus, DeviceEvent } from "twilio-client";
|
import { Device, DeviceAudio, SetupParams, Connection, DeviceStatus, DeviceEvent } from "twilio-client";
|
||||||
import { MockConnection } from "./mock-connection";
|
import { MockConnection } from "./mock-connection";
|
||||||
|
|
||||||
|
export const defaultDelay = 500;
|
||||||
|
|
||||||
export class MockDevice implements Device
|
export class MockDevice implements Device
|
||||||
{
|
{
|
||||||
public audio: DeviceAudio = <DeviceAudio>{};
|
public audio: DeviceAudio = <DeviceAudio>{};
|
||||||
@@ -27,12 +29,12 @@ export class MockDevice implements Device
|
|||||||
|
|
||||||
public destroy(): void
|
public destroy(): void
|
||||||
{
|
{
|
||||||
this.handlers["offline"].forEach(handler => handler());
|
setTimeout(() => this.handlers["offline"]?.forEach(handler => handler()), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnectAll(): void
|
public disconnectAll(): void
|
||||||
{
|
{
|
||||||
this.handlers["disconnect"].forEach(handler => handler());
|
setTimeout(() => this.handlers["disconnect"]?.forEach(handler => handler()), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
public status()
|
public status()
|
||||||
|
|||||||
Reference in New Issue
Block a user