Add button styling

This commit is contained in:
2020-02-09 00:42:25 -05:00
parent b2fe2ba202
commit fd8b82cf9f
8 changed files with 84 additions and 15 deletions

10
.vscode/settings.json vendored Normal file
View 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
View 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
View 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

View 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);
}

View File

@@ -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>
); );
} }

View File

@@ -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>
); );
} }

View File

@@ -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()

View File

@@ -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()