mirror of https://github.com/jitsi/jitsi-meet
parent
2ddfead4f5
commit
b2895b7095
@ -0,0 +1,75 @@ |
||||
.cpick { |
||||
border: 1px solid #A4B8D1; |
||||
color: #fff; |
||||
display: flex; |
||||
font-size: 15px; |
||||
height: 38px; |
||||
line-height: 24px; |
||||
|
||||
&-selector { |
||||
align-items: center; |
||||
background-color: #283447; |
||||
border-right: 1px solid #A4B8D1; |
||||
cursor: pointer; |
||||
display: flex; |
||||
padding: 8px 10px; |
||||
position: relative; |
||||
width: 88px; |
||||
} |
||||
|
||||
&-icon { |
||||
margin-right: 8px; |
||||
position: absolute; |
||||
right: 0; |
||||
top: 12px; |
||||
|
||||
& > svg { |
||||
fill: #fff; |
||||
} |
||||
} |
||||
|
||||
&-input { |
||||
padding: 8px; |
||||
background: #1C2025; |
||||
border: 0; |
||||
margin: 0; |
||||
color: #fff; |
||||
caret-color: #0376DA; |
||||
flex-grow: 1; |
||||
} |
||||
|
||||
&-dropdown { |
||||
height: 190px; |
||||
overflow-y: auto; |
||||
width: 343px; |
||||
} |
||||
|
||||
&-dropdown-entry { |
||||
align-items: center; |
||||
cursor: pointer; |
||||
display: flex; |
||||
height: 40px; |
||||
padding: 0 10px; |
||||
|
||||
&:hover { |
||||
background-color: #66768b; |
||||
} |
||||
|
||||
&-text { |
||||
color: #fff; |
||||
flex-grow: 1; |
||||
font-size: 15px; |
||||
line-height: 24px; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
// Override @Atlaskit/inline-dialog styles |
||||
.cpick-container > div > div:nth-child(2) > div > div { |
||||
outline: none; |
||||
padding: 8px 0 0 0; |
||||
} |
@ -0,0 +1,182 @@ |
||||
.prejoin-dialog { |
||||
background: #1C2025; |
||||
box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.5); |
||||
border-radius: 5px; |
||||
color: #fff; |
||||
height: 400px; |
||||
width: 375px; |
||||
|
||||
&--small { |
||||
height: 300; |
||||
width: 400; |
||||
} |
||||
|
||||
&-label { |
||||
font-size: 15px; |
||||
line-height: 24px; |
||||
|
||||
&-num { |
||||
background: #2b3b4b; |
||||
border: 1px solid #A4B8D1; |
||||
border-radius: 50%; |
||||
color: #fff; |
||||
display: inline-block; |
||||
height: 24px; |
||||
margin-right: 8px; |
||||
width: 24px; |
||||
} |
||||
} |
||||
|
||||
&-container { |
||||
align-items: center; |
||||
background: rgba(0,0,0,0.6); |
||||
display: flex; |
||||
height: 100vh; |
||||
justify-content: center; |
||||
left: 0; |
||||
position: absolute; |
||||
top: 0; |
||||
width: 100vw; |
||||
z-index: 3; |
||||
} |
||||
|
||||
&-flag { |
||||
display: inline-block; |
||||
margin-right: 8px; |
||||
transform: scale(1.2); |
||||
} |
||||
|
||||
&-title { |
||||
display: inline-block; |
||||
font-size: 24px; |
||||
line-height: 32px; |
||||
} |
||||
|
||||
&-icon { |
||||
cursor: pointer; |
||||
|
||||
> svg { |
||||
fill: #A4B8D1; |
||||
} |
||||
} |
||||
|
||||
&-btn { |
||||
width: 309px; |
||||
} |
||||
|
||||
&-dialin-container { |
||||
text-align: center; |
||||
} |
||||
|
||||
&-delimiter { |
||||
background: #5f6266; |
||||
border: 0; |
||||
height: 1px; |
||||
margin: 0; |
||||
padding: 0; |
||||
width: 100%; |
||||
|
||||
&-container { |
||||
margin: 16px 0 24px 0; |
||||
position: relative; |
||||
} |
||||
|
||||
&-txt-container { |
||||
position: absolute; |
||||
text-align: center; |
||||
top: -8px; |
||||
width: 100%; |
||||
} |
||||
|
||||
&-txt { |
||||
background: #1C2025; |
||||
color: #5f6266; |
||||
font-size: 11px; |
||||
text-transform: uppercase; |
||||
padding: 0 8px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.prejoin-dialog-callout { |
||||
padding: 16px; |
||||
|
||||
&-header { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
margin-bottom: 24px; |
||||
} |
||||
|
||||
&-picker { |
||||
margin: 8px 0 16px 0; |
||||
} |
||||
} |
||||
|
||||
.prejoin-dialog-dialin { |
||||
text-align: center; |
||||
|
||||
&-header { |
||||
align-items: center; |
||||
margin: 16px 0 32px 16px; |
||||
display: flex; |
||||
} |
||||
|
||||
&-icon { |
||||
margin-right: 16px; |
||||
} |
||||
|
||||
&-num { |
||||
background: #3e474f; |
||||
border-radius: 4px; |
||||
display: inline-block; |
||||
font-size: 15px; |
||||
line-height: 24px; |
||||
margin: 4px; |
||||
padding: 8px; |
||||
|
||||
&-container { |
||||
min-height: 48px; |
||||
margin: 8px 0; |
||||
} |
||||
} |
||||
|
||||
&-link { |
||||
color: #6FB1EA; |
||||
cursor: pointer; |
||||
display: inline-block; |
||||
font-size: 13px; |
||||
line-height: 20px; |
||||
margin-bottom: 24px; |
||||
} |
||||
|
||||
&-spaced-label { |
||||
margin-bottom: 16px; |
||||
margin-top: 28px; |
||||
} |
||||
|
||||
&-btns { |
||||
&> div { |
||||
margin-bottom: 16px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.prejoin-dialog-calling { |
||||
padding: 16px; |
||||
text-align: center; |
||||
|
||||
&-header { |
||||
text-align: right; |
||||
} |
||||
|
||||
&-label { |
||||
font-size: 15px; |
||||
margin: 8px 0 16px 0; |
||||
} |
||||
|
||||
&-number { |
||||
font-size: 19px; |
||||
line-height: 28px; |
||||
margin: 16px 0; |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The text for the Label. |
||||
*/ |
||||
children: React$Node, |
||||
|
||||
/** |
||||
* The CSS class of the label. |
||||
*/ |
||||
className?: string, |
||||
|
||||
/** |
||||
* The (round) number prefix for the Label. |
||||
*/ |
||||
number?: string | number, |
||||
|
||||
/** |
||||
* The click handler. |
||||
*/ |
||||
onClick?: Function, |
||||
}; |
||||
|
||||
/** |
||||
* Label for the dialogs. |
||||
* |
||||
* @returns {ReactElement} |
||||
*/ |
||||
function Label({ children, className, number, onClick }: Props) { |
||||
const containerClass = className |
||||
? `prejoin-dialog-label ${className}` |
||||
: 'prejoin-dialog-label'; |
||||
|
||||
return ( |
||||
<div |
||||
className = { containerClass } |
||||
onClick = { onClick }> |
||||
{number && <div className = 'prejoin-dialog-label-num'>{number}</div>} |
||||
<span>{children}</span> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default Label; |
@ -0,0 +1,33 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
import { countries } from '../../utils'; |
||||
import CountryRow from './CountryRow'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* Click handler for a single entry. |
||||
*/ |
||||
onEntryClick: Function, |
||||
}; |
||||
|
||||
/** |
||||
* This component displays the dropdown for the country picker. |
||||
* |
||||
* @returns {ReactElement} |
||||
*/ |
||||
function CountryDropdown({ onEntryClick }: Props) { |
||||
return ( |
||||
<div className = 'cpick-dropdown'> |
||||
{countries.map(country => ( |
||||
<CountryRow |
||||
country = { country } |
||||
key = { `${country.code}` } |
||||
onEntryClick = { onEntryClick } /> |
||||
))} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default CountryDropdown; |
@ -0,0 +1,250 @@ |
||||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react'; |
||||
import InlineDialog from '@atlaskit/inline-dialog'; |
||||
|
||||
import { connect } from '../../../base/redux'; |
||||
import { setDialOutCountry, setDialOutNumber } from '../../actions'; |
||||
import { getDialOutCountry, getDialOutNumber } from '../../functions'; |
||||
import { getCountryFromDialCodeText } from '../../utils'; |
||||
|
||||
import CountrySelector from './CountrySelector'; |
||||
import CountryDropDown from './CountryDropdown'; |
||||
|
||||
const PREFIX_REG = /^(00)|\+/; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The country to dial out to. |
||||
*/ |
||||
dialOutCountry: { name: string, dialCode: string, code: string }, |
||||
|
||||
/** |
||||
* The number to dial out to. |
||||
*/ |
||||
dialOutNumber: string, |
||||
|
||||
/** |
||||
* Handler used when user presses 'Enter'. |
||||
*/ |
||||
onSubmit: Function, |
||||
|
||||
/** |
||||
* Sets the dial out number. |
||||
*/ |
||||
setDialOutNumber: Function, |
||||
|
||||
/** |
||||
* Sets the dial out country. |
||||
*/ |
||||
setDialOutCountry: Function, |
||||
}; |
||||
|
||||
type State = { |
||||
|
||||
/** |
||||
* If the country picker is open or not. |
||||
*/ |
||||
isOpen: boolean, |
||||
|
||||
/** |
||||
* The value of the input. |
||||
*/ |
||||
value: string |
||||
} |
||||
|
||||
/** |
||||
* This component displays a country picker with an input for the phone number. |
||||
*/ |
||||
class CountryPicker extends PureComponent<Props, State> { |
||||
/** |
||||
* A React ref to the HTML element containing the {@code input} instance. |
||||
*/ |
||||
inputRef: Object; |
||||
|
||||
/** |
||||
* Initializes a new {@code CountryPicker} instance. |
||||
* |
||||
* @inheritdoc |
||||
*/ |
||||
constructor(props) { |
||||
super(props); |
||||
|
||||
this.state = { |
||||
isOpen: false, |
||||
value: '' |
||||
}; |
||||
this.inputRef = React.createRef(); |
||||
this._onChange = this._onChange.bind(this); |
||||
this._onDropdownClose = this._onDropdownClose.bind(this); |
||||
this._onCountrySelectorClick = this._onCountrySelectorClick.bind(this); |
||||
this._onEntryClick = this._onEntryClick.bind(this); |
||||
this._onKeyPress = this._onKeyPress.bind(this); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Implements React's {@link Component#componentDidUnmount()}. |
||||
* |
||||
* @inheritdoc |
||||
*/ |
||||
componentDidMount() { |
||||
this.inputRef.current.focus(); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
const { dialOutCountry, dialOutNumber } = this.props; |
||||
const { isOpen } = this.state; |
||||
const { |
||||
inputRef, |
||||
_onChange, |
||||
_onCountrySelectorClick, |
||||
_onDropdownClose, |
||||
_onKeyPress, |
||||
_onEntryClick |
||||
} = this; |
||||
|
||||
return ( |
||||
<div className = 'cpick-container'> |
||||
<InlineDialog |
||||
content = { <CountryDropDown onEntryClick = { _onEntryClick } /> } |
||||
isOpen = { isOpen } |
||||
onClose = { _onDropdownClose }> |
||||
<div className = 'cpick'> |
||||
<CountrySelector |
||||
country = { dialOutCountry } |
||||
onClick = { _onCountrySelectorClick } /> |
||||
<input |
||||
className = 'cpick-input' |
||||
onChange = { _onChange } |
||||
onKeyPress = { _onKeyPress } |
||||
ref = { inputRef } |
||||
value = { dialOutNumber } /> |
||||
</div> |
||||
</InlineDialog> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
_onChange: (Object) => void; |
||||
|
||||
/** |
||||
* Handles the input text change. |
||||
* Automatically updates the country from the 'CountrySelector' if a |
||||
* phone number prefix is entered (00 or +). |
||||
* |
||||
* @param {Object} e - The synthetic event. |
||||
* @returns {void} |
||||
*/ |
||||
_onChange({ target: { value } }) { |
||||
if (PREFIX_REG.test(value)) { |
||||
const textWithDialCode = value.replace(PREFIX_REG, ''); |
||||
|
||||
if (textWithDialCode.length >= 4) { |
||||
const country = getCountryFromDialCodeText(textWithDialCode); |
||||
|
||||
if (country) { |
||||
const rest = textWithDialCode.replace(country.dialCode, ''); |
||||
|
||||
this.props.setDialOutCountry(country); |
||||
this.props.setDialOutNumber(rest); |
||||
|
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
this.props.setDialOutNumber(value); |
||||
} |
||||
|
||||
_onCountrySelectorClick: (Object) => void; |
||||
|
||||
/** |
||||
* Click handler for country selector. |
||||
* |
||||
* @param {Object} e - The synthetic event. |
||||
* @returns {void} |
||||
*/ |
||||
_onCountrySelectorClick(e) { |
||||
e.stopPropagation(); |
||||
|
||||
this.setState({ |
||||
isOpen: !this.setState.isOpen |
||||
}); |
||||
} |
||||
|
||||
_onDropdownClose: () => void; |
||||
|
||||
/** |
||||
* Closes the dropdown. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
_onDropdownClose() { |
||||
this.setState({ |
||||
isOpen: false |
||||
}); |
||||
} |
||||
|
||||
_onEntryClick: (Object) => void; |
||||
|
||||
/** |
||||
* Click handler for a single entry from the dropdown. |
||||
* |
||||
* @param {Object} country - The country used for dialing out. |
||||
* @returns {void} |
||||
*/ |
||||
_onEntryClick(country) { |
||||
this.props.setDialOutCountry(country); |
||||
this._onDropdownClose(); |
||||
} |
||||
|
||||
_onKeyPress: (Object) => void; |
||||
|
||||
/** |
||||
* Handler for key presses. |
||||
* |
||||
* @param {Object} e - The synthetic event. |
||||
* @returns {void} |
||||
*/ |
||||
_onKeyPress(e) { |
||||
if (e.key === 'Enter') { |
||||
this.props.onSubmit(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Maps (parts of) the redux state to the React {@code Component} props. |
||||
* |
||||
* @param {Object} state - The redux state. |
||||
* @returns {Props} |
||||
*/ |
||||
function mapStateToProps(state) { |
||||
return { |
||||
dialOutCountry: getDialOutCountry(state), |
||||
dialOutNumber: getDialOutNumber(state) |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Maps redux actions to the props of the component. |
||||
* |
||||
* @type {{ |
||||
* setDialOutCountry: Function, |
||||
* setDialOutNumber: Function |
||||
* }} |
||||
*/ |
||||
const mapDispatchToProps = { |
||||
setDialOutCountry, |
||||
setDialOutNumber |
||||
}; |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(CountryPicker); |
@ -0,0 +1,68 @@ |
||||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* Country of the entry. |
||||
*/ |
||||
country: { name: string, dialCode: string, code: string }, |
||||
|
||||
/** |
||||
* Entry click handler. |
||||
*/ |
||||
onEntryClick: Function, |
||||
}; |
||||
|
||||
/** |
||||
* This component displays a row from the country picker dropdown. |
||||
*/ |
||||
class CountryRow extends PureComponent<Props> { |
||||
/** |
||||
* Initializes a new {@code CountryRow} instance. |
||||
* |
||||
* @param {Props} props - The props of the component. |
||||
*/ |
||||
constructor(props: Props) { |
||||
super(props); |
||||
|
||||
this._onClick = this._onClick.bind(this); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
const { |
||||
country: { code, dialCode, name } |
||||
} = this.props; |
||||
|
||||
return ( |
||||
<div |
||||
className = 'cpick-dropdown-entry' |
||||
onClick = { this._onClick }> |
||||
<div className = { `prejoin-dialog-flag iti-flag ${code}` } /> |
||||
<div className = 'cpick-dropdown-entry-text'> |
||||
{`${name} (+${dialCode})`} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
_onClick: () => void; |
||||
|
||||
/** |
||||
* Click handler. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
_onClick() { |
||||
this.props.onEntryClick(this.props.country); |
||||
} |
||||
} |
||||
|
||||
export default CountryRow; |
@ -0,0 +1,39 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
import { Icon, IconArrowDown } from '../../../base/icons'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* Country object of the entry. |
||||
*/ |
||||
country: { name: string, dialCode: string, code: string }, |
||||
|
||||
/** |
||||
* Click handler for the selector. |
||||
*/ |
||||
onClick: Function, |
||||
}; |
||||
|
||||
/** |
||||
* This component displays the country selector with the flag. |
||||
* |
||||
* @returns {ReactElement} |
||||
*/ |
||||
function CountrySelector({ country: { code, dialCode }, onClick }: Props) { |
||||
return ( |
||||
<div |
||||
className = 'cpick-selector' |
||||
onClick = { onClick }> |
||||
<div className = { `prejoin-dialog-flag iti-flag ${code}` } /> |
||||
<span>{`+${dialCode}`}</span> |
||||
<Icon |
||||
className = 'cpick-icon' |
||||
size = { 16 } |
||||
src = { IconArrowDown } /> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default CountrySelector; |
@ -0,0 +1,64 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
import { Avatar } from '../../../base/avatar'; |
||||
import { translate } from '../../../base/i18n'; |
||||
import { Icon, IconClose } from '../../../base/icons'; |
||||
import Label from '../Label'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The phone number that is being called. |
||||
*/ |
||||
number: string, |
||||
|
||||
/** |
||||
* Closes the dialog. |
||||
*/ |
||||
onClose: Function, |
||||
|
||||
/** |
||||
* Handler used on hangup click. |
||||
*/ |
||||
onHangup: Function, |
||||
|
||||
/** |
||||
* The status of the call. |
||||
*/ |
||||
status: string, |
||||
|
||||
/** |
||||
* Used for translation. |
||||
*/ |
||||
t: Function, |
||||
}; |
||||
|
||||
/** |
||||
* Dialog displayed when the user gets called by the meeting. |
||||
* |
||||
* @param {Props} props - The props of the component. |
||||
* @returns {ReactElement} |
||||
*/ |
||||
function CallingDialog(props: Props) { |
||||
const { number, onClose, status, t } = props; |
||||
|
||||
return ( |
||||
<div className = 'prejoin-dialog-calling'> |
||||
<div className = 'prejoin-dialog-calling-header'> |
||||
<Icon |
||||
className = 'prejoin-dialog-icon' |
||||
onClick = { onClose } |
||||
size = { 24 } |
||||
src = { IconClose } /> |
||||
</div> |
||||
<Label className = 'prejoin-dialog-calling-label'> |
||||
{t(status)} |
||||
</Label> |
||||
<Avatar size = { 72 } /> |
||||
<div className = 'prejoin-dialog-calling-number'>{number}</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default translate(CallingDialog); |
@ -0,0 +1,121 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
import { translate } from '../../../base/i18n'; |
||||
import { Icon, IconArrowLeft } from '../../../base/icons'; |
||||
import { getCountryCodeFromPhone } from '../../utils'; |
||||
import ActionButton from '../buttons/ActionButton'; |
||||
import Label from '../Label'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The number to call in order to join the conference. |
||||
*/ |
||||
number: string, |
||||
|
||||
/** |
||||
* Handler used when clicking the back button. |
||||
*/ |
||||
onBack: Function, |
||||
|
||||
/** |
||||
* Click handler for the text button. |
||||
*/ |
||||
onTextButtonClick: Function, |
||||
|
||||
/** |
||||
* Click handler for primary button. |
||||
*/ |
||||
onPrimaryButtonClick: Function, |
||||
|
||||
/** |
||||
* Click handler for the small additional text. |
||||
*/ |
||||
onSmallTextClick: Function, |
||||
|
||||
/** |
||||
* The passCode of the conference. |
||||
*/ |
||||
passCode: string, |
||||
|
||||
/** |
||||
* Used for translation. |
||||
*/ |
||||
t: Function, |
||||
}; |
||||
|
||||
/** |
||||
* This component displays the dialog whith all the information |
||||
* to join a meeting by calling it. |
||||
* |
||||
* @param {Props} props - The props of the component. |
||||
* @returns {React$Element} |
||||
*/ |
||||
function DialinDialog(props: Props) { |
||||
const { |
||||
number, |
||||
onBack, |
||||
onPrimaryButtonClick, |
||||
onSmallTextClick, |
||||
onTextButtonClick, |
||||
passCode, |
||||
t |
||||
} = props; |
||||
const flagClassName = `prejoin-dialog-flag iti-flag ${getCountryCodeFromPhone( |
||||
number, |
||||
)}`;
|
||||
|
||||
return ( |
||||
<div className = 'prejoin-dialog-dialin'> |
||||
<div className = 'prejoin-dialog-dialin-header'> |
||||
<Icon |
||||
className = 'prejoin-dialog-icon prejoin-dialog-dialin-icon' |
||||
onClick = { onBack } |
||||
size = { 24 } |
||||
src = { IconArrowLeft } /> |
||||
<div className = 'prejoin-dialog-title'> |
||||
{t('prejoin.dialInMeeting')} |
||||
</div> |
||||
</div> |
||||
<Label number = { 1 }>{ t('prejoin.dialInPin') }</Label> |
||||
|
||||
<div className = 'prejoin-dialog-dialin-num-container'> |
||||
<div className = 'prejoin-dialog-dialin-num'> |
||||
<div className = { flagClassName } /> |
||||
<span>{number}</span> |
||||
</div> |
||||
<div className = 'prejoin-dialog-dialin-num'>{passCode}</div> |
||||
</div> |
||||
<div> |
||||
<span |
||||
className = 'prejoin-dialog-dialin-link' |
||||
onClick = { onSmallTextClick }> |
||||
{t('prejoin.viewAllNumbers')} |
||||
</span> |
||||
</div> |
||||
<div className = 'prejoin-dialog-delimiter' /> |
||||
<Label |
||||
className = 'prejoin-dialog-dialin-spaced-label' |
||||
number = { 2 }> |
||||
{t('prejoin.connectedWithAudioQ')} |
||||
</Label> |
||||
<div className = 'prejoin-dialog-dialin-btns'> |
||||
<ActionButton |
||||
className = 'prejoin-dialog-btn' |
||||
onClick = { onPrimaryButtonClick } |
||||
type = 'primary'> |
||||
{t('prejoin.joinMeeting')} |
||||
</ActionButton> |
||||
<ActionButton |
||||
className = 'prejoin-dialog-btn' |
||||
onClick = { onTextButtonClick } |
||||
type = 'text'> |
||||
{t('dialog.Cancel')} |
||||
</ActionButton> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default translate(DialinDialog); |
@ -0,0 +1,86 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
|
||||
import { translate } from '../../../base/i18n'; |
||||
import { Icon, IconClose } from '../../../base/icons'; |
||||
import ActionButton from '../buttons/ActionButton'; |
||||
import CountryPicker from '../country-picker/CountryPicker'; |
||||
import Label from '../Label'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* Closes a dialog. |
||||
*/ |
||||
onClose: Function, |
||||
|
||||
/** |
||||
* Submit handler. |
||||
*/ |
||||
onSubmit: Function, |
||||
|
||||
/** |
||||
* Handler for text button. |
||||
*/ |
||||
onTextButtonClick: Function, |
||||
|
||||
/** |
||||
* Used for translation. |
||||
*/ |
||||
t: Function, |
||||
}; |
||||
|
||||
/** |
||||
* This component displays the dialog from wich the user can enter the |
||||
* phone number in order to be called by the meeting. |
||||
* |
||||
* @param {Props} props - The props of the component. |
||||
* @returns {React$Element} |
||||
*/ |
||||
function DialOutDialog(props: Props) { |
||||
const { onClose, onTextButtonClick, onSubmit, t } = props; |
||||
|
||||
return ( |
||||
<div className = 'prejoin-dialog-callout'> |
||||
<div className = 'prejoin-dialog-callout-header'> |
||||
<div className = 'prejoin-dialog-title'> |
||||
{t('prejoin.startWithPhone')} |
||||
</div> |
||||
<Icon |
||||
className = 'prejoin-dialog-icon' |
||||
onClick = { onClose } |
||||
size = { 24 } |
||||
src = { IconClose } /> |
||||
</div> |
||||
<Label>{t('prejoin.callMeAtNumber')}</Label> |
||||
<div className = 'prejoin-dialog-callout-picker'> |
||||
<CountryPicker onSubmit = { onSubmit } /> |
||||
</div> |
||||
<ActionButton |
||||
className = 'prejoin-dialog-btn' |
||||
onClick = { onSubmit } |
||||
type = 'primary'> |
||||
{t('prejoin.callMe')} |
||||
</ActionButton> |
||||
<div className = 'prejoin-dialog-delimiter-container'> |
||||
<div className = 'prejoin-dialog-delimiter' /> |
||||
<div className = 'prejoin-dialog-delimiter-txt-container'> |
||||
<span className = 'prejoin-dialog-delimiter-txt'> |
||||
{t('prejoin.or')} |
||||
</span> |
||||
</div> |
||||
</div> |
||||
<div className = 'prejoin-dialog-dialin-container'> |
||||
<ActionButton |
||||
className = 'prejoin-dialog-btn' |
||||
onClick = { onTextButtonClick } |
||||
type = 'text'> |
||||
{t('prejoin.iWantToDialIn')} |
||||
</ActionButton> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default translate(DialOutDialog); |
@ -0,0 +1,248 @@ |
||||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react'; |
||||
|
||||
import { connect } from '../../../base/redux'; |
||||
import { |
||||
getConferenceId, |
||||
getDefaultDialInNumber, |
||||
updateDialInNumbers |
||||
} from '../../../invite'; |
||||
import { |
||||
dialOut as dialOutAction, |
||||
joinConferenceWithoutAudio as joinConferenceWithoutAudioAction, |
||||
openDialInPage as openDialInPageAction |
||||
} from '../../actions'; |
||||
import { getDialOutStatus, getFullDialOutNumber } from '../../functions'; |
||||
|
||||
import CallingDialog from './CallingDialog'; |
||||
import DialInDialog from './DialInDialog'; |
||||
import DialOutDialog from './DialOutDialog'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The number to call in order to join the conference. |
||||
*/ |
||||
dialInNumber: string, |
||||
|
||||
/** |
||||
* The status of the call when the meeting calss the user. |
||||
*/ |
||||
dialOutStatus: string, |
||||
|
||||
/** |
||||
* The action by which the meeting calls the user. |
||||
*/ |
||||
dialOut: Function, |
||||
|
||||
/** |
||||
* The number the conference should call. |
||||
*/ |
||||
dialOutNumber: string, |
||||
|
||||
/** |
||||
* Fetches conference dial in numbers & conference id |
||||
*/ |
||||
fetchConferenceDetails: Function, |
||||
|
||||
/** |
||||
* Joins the conference without audio. |
||||
*/ |
||||
joinConferenceWithoutAudio: Function, |
||||
|
||||
/** |
||||
* Closes the dialog. |
||||
*/ |
||||
onClose: Function, |
||||
|
||||
/** |
||||
* Opens a web page with all the dial in numbers. |
||||
*/ |
||||
openDialInPage: Function, |
||||
|
||||
/** |
||||
* The passCode of the conference used when joining a meeting by phone. |
||||
*/ |
||||
passCode: string, |
||||
}; |
||||
|
||||
type State = { |
||||
|
||||
/** |
||||
* The dialout call is ongoing, 'CallingDialog' is shown; |
||||
*/ |
||||
isCalling: boolean, |
||||
|
||||
/** |
||||
* If should show 'DialInDialog'. |
||||
*/ |
||||
showDialIn: boolean, |
||||
|
||||
/** |
||||
* If should show 'DialOutDialog'. |
||||
*/ |
||||
showDialOut: boolean |
||||
} |
||||
|
||||
/** |
||||
* This is the dialog shown when a user wants to join with phone audio. |
||||
*/ |
||||
class JoinByPhoneDialog extends PureComponent<Props, State> { |
||||
/** |
||||
* Initializes a new {@code JoinByPhoneDialog} instance. |
||||
* |
||||
* @param {Props} props - The props of the component. |
||||
* @inheritdoc |
||||
*/ |
||||
constructor(props) { |
||||
super(props); |
||||
|
||||
this.state = { |
||||
isCalling: false, |
||||
showDialOut: true, |
||||
showDialIn: false |
||||
}; |
||||
|
||||
this._dialOut = this._dialOut.bind(this); |
||||
this._showDialInDialog = this._showDialInDialog.bind(this); |
||||
this._showDialOutDialog = this._showDialOutDialog.bind(this); |
||||
} |
||||
|
||||
_dialOut: () => void; |
||||
|
||||
/** |
||||
* Meeting calls the user & shows the 'CallingDialog'. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
_dialOut() { |
||||
const { dialOut, joinConferenceWithoutAudio } = this.props; |
||||
|
||||
this.setState({ |
||||
isCalling: true, |
||||
showDialOut: false, |
||||
showDialIn: false |
||||
}); |
||||
dialOut(joinConferenceWithoutAudio, this._showDialOutDialog); |
||||
} |
||||
|
||||
_showDialInDialog: () => void; |
||||
|
||||
/** |
||||
* Shows the 'DialInDialog'. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
_showDialInDialog() { |
||||
this.setState({ |
||||
isCalling: false, |
||||
showDialOut: false, |
||||
showDialIn: true |
||||
}); |
||||
} |
||||
|
||||
_showDialOutDialog: () => void; |
||||
|
||||
/** |
||||
* Shows the 'DialOutDialog'. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
_showDialOutDialog() { |
||||
this.setState({ |
||||
isCalling: false, |
||||
showDialOut: true, |
||||
showDialIn: false |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#componentDidMount()}. |
||||
* |
||||
* @inheritdoc |
||||
*/ |
||||
componentDidMount() { |
||||
this.props.fetchConferenceDetails(); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
const { |
||||
dialOutStatus, |
||||
dialInNumber, |
||||
dialOutNumber, |
||||
joinConferenceWithoutAudio, |
||||
passCode, |
||||
onClose, |
||||
openDialInPage |
||||
} = this.props; |
||||
const { |
||||
_dialOut, |
||||
_showDialInDialog, |
||||
_showDialOutDialog |
||||
} = this; |
||||
const { isCalling, showDialOut, showDialIn } = this.state; |
||||
const className = isCalling |
||||
? 'prejoin-dialog prejoin-dialog--small' |
||||
: 'prejoin-dialog'; |
||||
|
||||
return ( |
||||
<div className = 'prejoin-dialog-container'> |
||||
<div className = { className }> |
||||
{showDialOut && ( |
||||
<DialOutDialog |
||||
onClose = { onClose } |
||||
onSubmit = { _dialOut } |
||||
onTextButtonClick = { _showDialInDialog } /> |
||||
)} |
||||
{showDialIn && ( |
||||
<DialInDialog |
||||
number = { dialInNumber } |
||||
onBack = { _showDialOutDialog } |
||||
onPrimaryButtonClick = { joinConferenceWithoutAudio } |
||||
onSmallTextClick = { openDialInPage } |
||||
onTextButtonClick = { onClose } |
||||
passCode = { passCode } /> |
||||
)} |
||||
{isCalling && ( |
||||
<CallingDialog |
||||
number = { dialOutNumber } |
||||
onClose = { onClose } |
||||
status = { dialOutStatus } /> |
||||
)} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Maps (parts of) the redux state to the React {@code Component} props. |
||||
* |
||||
* @param {Object} state - The redux state. |
||||
* @returns {Object} |
||||
*/ |
||||
function mapStateToProps(state): Object { |
||||
return { |
||||
dialInNumber: getDefaultDialInNumber(state), |
||||
dialOutNumber: getFullDialOutNumber(state), |
||||
dialOutStatus: getDialOutStatus(state), |
||||
passCode: getConferenceId(state) |
||||
}; |
||||
} |
||||
|
||||
const mapDispatchToProps = { |
||||
dialOut: dialOutAction, |
||||
fetchConferenceDetails: updateDialInNumbers, |
||||
joinConferenceWithoutAudio: joinConferenceWithoutAudioAction, |
||||
openDialInPage: openDialInPageAction |
||||
}; |
||||
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JoinByPhoneDialog); |
@ -0,0 +1,799 @@ |
||||
// @flow
|
||||
|
||||
export const countries = [ |
||||
{ name: 'Afghanistan', |
||||
dialCode: '93', |
||||
code: 'af' }, |
||||
{ name: 'Aland Islands', |
||||
dialCode: '358', |
||||
code: 'ax' }, |
||||
{ name: 'Albania', |
||||
dialCode: '355', |
||||
code: 'al' }, |
||||
{ name: 'Algeria', |
||||
dialCode: '213', |
||||
code: 'dz' }, |
||||
{ name: 'AmericanSamoa', |
||||
dialCode: '1684', |
||||
code: 'as' }, |
||||
{ name: 'Andorra', |
||||
dialCode: '376', |
||||
code: 'ad' }, |
||||
{ name: 'Angola', |
||||
dialCode: '244', |
||||
code: 'ao' }, |
||||
{ name: 'Anguilla', |
||||
dialCode: '1264', |
||||
code: 'ai' }, |
||||
{ name: 'Antarctica', |
||||
dialCode: '672', |
||||
code: 'aq' }, |
||||
{ name: 'Antigua and Barbuda', |
||||
dialCode: '1268', |
||||
code: 'ag' }, |
||||
{ name: 'Argentina', |
||||
dialCode: '54', |
||||
code: 'ar' }, |
||||
{ name: 'Armenia', |
||||
dialCode: '374', |
||||
code: 'am' }, |
||||
{ name: 'Aruba', |
||||
dialCode: '297', |
||||
code: 'aw' }, |
||||
{ name: 'Australia', |
||||
dialCode: '61', |
||||
code: 'au' }, |
||||
{ name: 'Austria', |
||||
dialCode: '43', |
||||
code: 'at' }, |
||||
{ name: 'Azerbaijan', |
||||
dialCode: '994', |
||||
code: 'az' }, |
||||
{ name: 'Bahamas', |
||||
dialCode: '1242', |
||||
code: 'bs' }, |
||||
{ name: 'Bahrain', |
||||
dialCode: '973', |
||||
code: 'bh' }, |
||||
{ name: 'Bangladesh', |
||||
dialCode: '880', |
||||
code: 'bd' }, |
||||
{ name: 'Barbados', |
||||
dialCode: '1246', |
||||
code: 'bb' }, |
||||
{ name: 'Belarus', |
||||
dialCode: '375', |
||||
code: 'by' }, |
||||
{ name: 'Belgium', |
||||
dialCode: '32', |
||||
code: 'be' }, |
||||
{ name: 'Belize', |
||||
dialCode: '501', |
||||
code: 'bz' }, |
||||
{ name: 'Benin', |
||||
dialCode: '229', |
||||
code: 'bj' }, |
||||
{ name: 'Bermuda', |
||||
dialCode: '1441', |
||||
code: 'bm' }, |
||||
{ name: 'Bhutan', |
||||
dialCode: '975', |
||||
code: 'bt' }, |
||||
{ name: 'Bolivia, Plurinational State of', |
||||
dialCode: '591', |
||||
code: 'bo' }, |
||||
{ name: 'Bosnia and Herzegovina', |
||||
dialCode: '387', |
||||
code: 'ba' }, |
||||
{ name: 'Botswana', |
||||
dialCode: '267', |
||||
code: 'bw' }, |
||||
{ name: 'Brazil', |
||||
dialCode: '55', |
||||
code: 'br' }, |
||||
{ name: 'British Indian Ocean Territory', |
||||
dialCode: '246', |
||||
code: 'io' }, |
||||
{ name: 'Brunei Darussalam', |
||||
dialCode: '673', |
||||
code: 'bn' }, |
||||
{ name: 'Bulgaria', |
||||
dialCode: '359', |
||||
code: 'bg' }, |
||||
{ name: 'Burkina Faso', |
||||
dialCode: '226', |
||||
code: 'bf' }, |
||||
{ name: 'Burundi', |
||||
dialCode: '257', |
||||
code: 'bi' }, |
||||
{ name: 'Cambodia', |
||||
dialCode: '855', |
||||
code: 'kh' }, |
||||
{ name: 'Cameroon', |
||||
dialCode: '237', |
||||
code: 'cm' }, |
||||
{ name: 'Canada', |
||||
dialCode: '1', |
||||
code: 'ca' }, |
||||
{ name: 'Cape Verde', |
||||
dialCode: '238', |
||||
code: 'cv' }, |
||||
{ name: 'Cayman Islands', |
||||
dialCode: ' 345', |
||||
code: 'ky' }, |
||||
{ name: 'Central African Republic', |
||||
dialCode: '236', |
||||
code: 'cf' }, |
||||
{ name: 'Chad', |
||||
dialCode: '235', |
||||
code: 'td' }, |
||||
{ name: 'Chile', |
||||
dialCode: '56', |
||||
code: 'cl' }, |
||||
{ name: 'China', |
||||
dialCode: '86', |
||||
code: 'cn' }, |
||||
{ name: 'Christmas Island', |
||||
dialCode: '61', |
||||
code: 'cx' }, |
||||
{ name: 'Cocos (Keeling) Islands', |
||||
dialCode: '61', |
||||
code: 'cc' }, |
||||
{ name: 'Colombia', |
||||
dialCode: '57', |
||||
code: 'co' }, |
||||
{ name: 'Comoros', |
||||
dialCode: '269', |
||||
code: 'km' }, |
||||
{ name: 'Congo', |
||||
dialCode: '242', |
||||
code: 'cg' }, |
||||
{ |
||||
name: 'Congo, The Democratic Republic of the Congo', |
||||
dialCode: '243', |
||||
code: 'cd' |
||||
}, |
||||
{ name: 'Cook Islands', |
||||
dialCode: '682', |
||||
code: 'ck' }, |
||||
{ name: 'Costa Rica', |
||||
dialCode: '506', |
||||
code: 'cr' }, |
||||
{ name: 'Cote d\'Ivoire', |
||||
dialCode: '225', |
||||
code: 'ci' }, |
||||
{ name: 'Croatia', |
||||
dialCode: '385', |
||||
code: 'hr' }, |
||||
{ name: 'Cuba', |
||||
dialCode: '53', |
||||
code: 'cu' }, |
||||
{ name: 'Cyprus', |
||||
dialCode: '357', |
||||
code: 'cy' }, |
||||
{ name: 'Czech Republic', |
||||
dialCode: '420', |
||||
code: 'cz' }, |
||||
{ name: 'Denmark', |
||||
dialCode: '45', |
||||
code: 'dk' }, |
||||
{ name: 'Djibouti', |
||||
dialCode: '253', |
||||
code: 'dj' }, |
||||
{ name: 'Dominica', |
||||
dialCode: '1767', |
||||
code: 'dm' }, |
||||
{ name: 'Dominican Republic', |
||||
dialCode: '1849', |
||||
code: 'do' }, |
||||
{ name: 'Ecuador', |
||||
dialCode: '593', |
||||
code: 'ec' }, |
||||
{ name: 'Egypt', |
||||
dialCode: '20', |
||||
code: 'eg' }, |
||||
{ name: 'El Salvador', |
||||
dialCode: '503', |
||||
code: 'sv' }, |
||||
{ name: 'Equatorial Guinea', |
||||
dialCode: '240', |
||||
code: 'gq' }, |
||||
{ name: 'Eritrea', |
||||
dialCode: '291', |
||||
code: 'er' }, |
||||
{ name: 'Estonia', |
||||
dialCode: '372', |
||||
code: 'ee' }, |
||||
{ name: 'Ethiopia', |
||||
dialCode: '251', |
||||
code: 'et' }, |
||||
{ name: 'Falkland Islands (Malvinas)', |
||||
dialCode: '500', |
||||
code: 'fk' }, |
||||
{ name: 'Faroe Islands', |
||||
dialCode: '298', |
||||
code: 'fo' }, |
||||
{ name: 'Fiji', |
||||
dialCode: '679', |
||||
code: 'fj' }, |
||||
{ name: 'Finland', |
||||
dialCode: '358', |
||||
code: 'fi' }, |
||||
{ name: 'France', |
||||
dialCode: '33', |
||||
code: 'fr' }, |
||||
{ name: 'French Guiana', |
||||
dialCode: '594', |
||||
code: 'gf' }, |
||||
{ name: 'French Polynesia', |
||||
dialCode: '689', |
||||
code: 'pf' }, |
||||
{ name: 'Gabon', |
||||
dialCode: '241', |
||||
code: 'ga' }, |
||||
{ name: 'Gambia', |
||||
dialCode: '220', |
||||
code: 'gm' }, |
||||
{ name: 'Georgia', |
||||
dialCode: '995', |
||||
code: 'ge' }, |
||||
{ name: 'Germany', |
||||
dialCode: '49', |
||||
code: 'de' }, |
||||
{ name: 'Ghana', |
||||
dialCode: '233', |
||||
code: 'gh' }, |
||||
{ name: 'Gibraltar', |
||||
dialCode: '350', |
||||
code: 'gi' }, |
||||
{ name: 'Greece', |
||||
dialCode: '30', |
||||
code: 'gr' }, |
||||
{ name: 'Greenland', |
||||
dialCode: '299', |
||||
code: 'gl' }, |
||||
{ name: 'Grenada', |
||||
dialCode: '1473', |
||||
code: 'gd' }, |
||||
{ name: 'Guadeloupe', |
||||
dialCode: '590', |
||||
code: 'gp' }, |
||||
{ name: 'Guam', |
||||
dialCode: '1671', |
||||
code: 'gu' }, |
||||
{ name: 'Guatemala', |
||||
dialCode: '502', |
||||
code: 'gt' }, |
||||
{ name: 'Guernsey', |
||||
dialCode: '44', |
||||
code: 'gg' }, |
||||
{ name: 'Guinea', |
||||
dialCode: '224', |
||||
code: 'gn' }, |
||||
{ name: 'Guinea-Bissau', |
||||
dialCode: '245', |
||||
code: 'gw' }, |
||||
{ name: 'Guyana', |
||||
dialCode: '595', |
||||
code: 'gy' }, |
||||
{ name: 'Haiti', |
||||
dialCode: '509', |
||||
code: 'ht' }, |
||||
{ name: 'Holy See (Vatican City State)', |
||||
dialCode: '379', |
||||
code: 'va' }, |
||||
{ name: 'Honduras', |
||||
dialCode: '504', |
||||
code: 'hn' }, |
||||
{ name: 'Hong Kong', |
||||
dialCode: '852', |
||||
code: 'hk' }, |
||||
{ name: 'Hungary', |
||||
dialCode: '36', |
||||
code: 'hu' }, |
||||
{ name: 'Iceland', |
||||
dialCode: '354', |
||||
code: 'is' }, |
||||
{ name: 'India', |
||||
dialCode: '91', |
||||
code: 'in' }, |
||||
{ name: 'Indonesia', |
||||
dialCode: '62', |
||||
code: 'id' }, |
||||
{ |
||||
name: 'Iran, Islamic Republic of Persian Gulf', |
||||
dialCode: '98', |
||||
code: 'ir' |
||||
}, |
||||
{ name: 'Iraq', |
||||
dialCode: '964', |
||||
code: 'iq' }, |
||||
{ name: 'Ireland', |
||||
dialCode: '353', |
||||
code: 'ie' }, |
||||
{ name: 'Isle of Man', |
||||
dialCode: '44', |
||||
code: 'im' }, |
||||
{ name: 'Israel', |
||||
dialCode: '972', |
||||
code: 'il' }, |
||||
{ name: 'Italy', |
||||
dialCode: '39', |
||||
code: 'it' }, |
||||
{ name: 'Jamaica', |
||||
dialCode: '1876', |
||||
code: 'jm' }, |
||||
{ name: 'Japan', |
||||
dialCode: '81', |
||||
code: 'jp' }, |
||||
{ name: 'Jersey', |
||||
dialCode: '44', |
||||
code: 'je' }, |
||||
{ name: 'Jordan', |
||||
dialCode: '962', |
||||
code: 'jo' }, |
||||
{ name: 'Kazakhstan', |
||||
dialCode: '77', |
||||
code: 'kz' }, |
||||
{ name: 'Kenya', |
||||
dialCode: '254', |
||||
code: 'ke' }, |
||||
{ name: 'Kiribati', |
||||
dialCode: '686', |
||||
code: 'ki' }, |
||||
{ |
||||
name: 'Korea, Democratic People\'s Republic of Korea', |
||||
dialCode: '850', |
||||
code: 'kp' |
||||
}, |
||||
{ name: 'Korea, Republic of South Korea', |
||||
dialCode: '82', |
||||
code: 'kr' }, |
||||
{ name: 'Kuwait', |
||||
dialCode: '965', |
||||
code: 'kw' }, |
||||
{ name: 'Kyrgyzstan', |
||||
dialCode: '996', |
||||
code: 'kg' }, |
||||
{ name: 'Laos', |
||||
dialCode: '856', |
||||
code: 'la' }, |
||||
{ name: 'Latvia', |
||||
dialCode: '371', |
||||
code: 'lv' }, |
||||
{ name: 'Lebanon', |
||||
dialCode: '961', |
||||
code: 'lb' }, |
||||
{ name: 'Lesotho', |
||||
dialCode: '266', |
||||
code: 'ls' }, |
||||
{ name: 'Liberia', |
||||
dialCode: '231', |
||||
code: 'lr' }, |
||||
{ name: 'Libyan Arab Jamahiriya', |
||||
dialCode: '218', |
||||
code: 'ly' }, |
||||
{ name: 'Liechtenstein', |
||||
dialCode: '423', |
||||
code: 'li' }, |
||||
{ name: 'Lithuania', |
||||
dialCode: '370', |
||||
code: 'lt' }, |
||||
{ name: 'Luxembourg', |
||||
dialCode: '352', |
||||
code: 'lu' }, |
||||
{ name: 'Macao', |
||||
dialCode: '853', |
||||
code: 'mo' }, |
||||
{ name: 'Macedonia', |
||||
dialCode: '389', |
||||
code: 'mk' }, |
||||
{ name: 'Madagascar', |
||||
dialCode: '261', |
||||
code: 'mg' }, |
||||
{ name: 'Malawi', |
||||
dialCode: '265', |
||||
code: 'mw' }, |
||||
{ name: 'Malaysia', |
||||
dialCode: '60', |
||||
code: 'my' }, |
||||
{ name: 'Maldives', |
||||
dialCode: '960', |
||||
code: 'mv' }, |
||||
{ name: 'Mali', |
||||
dialCode: '223', |
||||
code: 'ml' }, |
||||
{ name: 'Malta', |
||||
dialCode: '356', |
||||
code: 'mt' }, |
||||
{ name: 'Marshall Islands', |
||||
dialCode: '692', |
||||
code: 'mh' }, |
||||
{ name: 'Martinique', |
||||
dialCode: '596', |
||||
code: 'mq' }, |
||||
{ name: 'Mauritania', |
||||
dialCode: '222', |
||||
code: 'mr' }, |
||||
{ name: 'Mauritius', |
||||
dialCode: '230', |
||||
code: 'mu' }, |
||||
{ name: 'Mayotte', |
||||
dialCode: '262', |
||||
code: 'yt' }, |
||||
{ name: 'Mexico', |
||||
dialCode: '52', |
||||
code: 'mx' }, |
||||
{ |
||||
name: 'Micronesia, Federated States of Micronesia', |
||||
dialCode: '691', |
||||
code: 'fm' |
||||
}, |
||||
{ name: 'Moldova', |
||||
dialCode: '373', |
||||
code: 'md' }, |
||||
{ name: 'Monaco', |
||||
dialCode: '377', |
||||
code: 'mc' }, |
||||
{ name: 'Mongolia', |
||||
dialCode: '976', |
||||
code: 'mn' }, |
||||
{ name: 'Montenegro', |
||||
dialCode: '382', |
||||
code: 'me' }, |
||||
{ name: 'Montserrat', |
||||
dialCode: '1664', |
||||
code: 'ms' }, |
||||
{ name: 'Morocco', |
||||
dialCode: '212', |
||||
code: 'ma' }, |
||||
{ name: 'Mozambique', |
||||
dialCode: '258', |
||||
code: 'mz' }, |
||||
{ name: 'Myanmar', |
||||
dialCode: '95', |
||||
code: 'mm' }, |
||||
{ name: 'Namibia', |
||||
dialCode: '264', |
||||
code: 'na' }, |
||||
{ name: 'Nauru', |
||||
dialCode: '674', |
||||
code: 'nr' }, |
||||
{ name: 'Nepal', |
||||
dialCode: '977', |
||||
code: 'np' }, |
||||
{ name: 'Netherlands', |
||||
dialCode: '31', |
||||
code: 'nl' }, |
||||
{ name: 'Netherlands Antilles', |
||||
dialCode: '599', |
||||
code: 'an' }, |
||||
{ name: 'New Caledonia', |
||||
dialCode: '687', |
||||
code: 'nc' }, |
||||
{ name: 'New Zealand', |
||||
dialCode: '64', |
||||
code: 'nz' }, |
||||
{ name: 'Nicaragua', |
||||
dialCode: '505', |
||||
code: 'ni' }, |
||||
{ name: 'Niger', |
||||
dialCode: '227', |
||||
code: 'ne' }, |
||||
{ name: 'Nigeria', |
||||
dialCode: '234', |
||||
code: 'ng' }, |
||||
{ name: 'Niue', |
||||
dialCode: '683', |
||||
code: 'nu' }, |
||||
{ name: 'Norfolk Island', |
||||
dialCode: '672', |
||||
code: 'nf' }, |
||||
{ name: 'Northern Mariana Islands', |
||||
dialCode: '1670', |
||||
code: 'mp' }, |
||||
{ name: 'Norway', |
||||
dialCode: '47', |
||||
code: 'no' }, |
||||
{ name: 'Oman', |
||||
dialCode: '968', |
||||
code: 'om' }, |
||||
{ name: 'Pakistan', |
||||
dialCode: '92', |
||||
code: 'pk' }, |
||||
{ name: 'Palau', |
||||
dialCode: '680', |
||||
code: 'pw' }, |
||||
{ name: 'Palestinian Territory, Occupied', |
||||
dialCode: '970', |
||||
code: 'ps' }, |
||||
{ name: 'Panama', |
||||
dialCode: '507', |
||||
code: 'pa' }, |
||||
{ name: 'Papua New Guinea', |
||||
dialCode: '675', |
||||
code: 'pg' }, |
||||
{ name: 'Paraguay', |
||||
dialCode: '595', |
||||
code: 'py' }, |
||||
{ name: 'Peru', |
||||
dialCode: '51', |
||||
code: 'pe' }, |
||||
{ name: 'Philippines', |
||||
dialCode: '63', |
||||
code: 'ph' }, |
||||
{ name: 'Pitcairn', |
||||
dialCode: '872', |
||||
code: 'pn' }, |
||||
{ name: 'Poland', |
||||
dialCode: '48', |
||||
code: 'pl' }, |
||||
{ name: 'Portugal', |
||||
dialCode: '351', |
||||
code: 'pt' }, |
||||
{ name: 'Puerto Rico', |
||||
dialCode: '1939', |
||||
code: 'pr' }, |
||||
{ name: 'Qatar', |
||||
dialCode: '974', |
||||
code: 'qa' }, |
||||
{ name: 'Romania', |
||||
dialCode: '40', |
||||
code: 'ro' }, |
||||
{ name: 'Russia', |
||||
dialCode: '7', |
||||
code: 'ru' }, |
||||
{ name: 'Rwanda', |
||||
dialCode: '250', |
||||
code: 'rw' }, |
||||
{ name: 'Reunion', |
||||
dialCode: '262', |
||||
code: 're' }, |
||||
{ name: 'Saint Barthelemy', |
||||
dialCode: '590', |
||||
code: 'bl' }, |
||||
{ |
||||
name: 'Saint Helena, Ascension and Tristan Da Cunha', |
||||
dialCode: '290', |
||||
code: 'sh' |
||||
}, |
||||
{ name: 'Saint Kitts and Nevis', |
||||
dialCode: '1869', |
||||
code: 'kn' }, |
||||
{ name: 'Saint Lucia', |
||||
dialCode: '1758', |
||||
code: 'lc' }, |
||||
{ name: 'Saint Martin', |
||||
dialCode: '590', |
||||
code: 'mf' }, |
||||
{ name: 'Saint Pierre and Miquelon', |
||||
dialCode: '508', |
||||
code: 'pm' }, |
||||
{ name: 'Saint Vincent and the Grenadines', |
||||
dialCode: '1784', |
||||
code: 'vc' }, |
||||
{ name: 'Samoa', |
||||
dialCode: '685', |
||||
code: 'ws' }, |
||||
{ name: 'San Marino', |
||||
dialCode: '378', |
||||
code: 'sm' }, |
||||
{ name: 'Sao Tome and Principe', |
||||
dialCode: '239', |
||||
code: 'st' }, |
||||
{ name: 'Saudi Arabia', |
||||
dialCode: '966', |
||||
code: 'sa' }, |
||||
{ name: 'Senegal', |
||||
dialCode: '221', |
||||
code: 'sn' }, |
||||
{ name: 'Serbia', |
||||
dialCode: '381', |
||||
code: 'rs' }, |
||||
{ name: 'Seychelles', |
||||
dialCode: '248', |
||||
code: 'sc' }, |
||||
{ name: 'Sierra Leone', |
||||
dialCode: '232', |
||||
code: 'sl' }, |
||||
{ name: 'Singapore', |
||||
dialCode: '65', |
||||
code: 'sg' }, |
||||
{ name: 'Slovakia', |
||||
dialCode: '421', |
||||
code: 'sk' }, |
||||
{ name: 'Slovenia', |
||||
dialCode: '386', |
||||
code: 'si' }, |
||||
{ name: 'Solomon Islands', |
||||
dialCode: '677', |
||||
code: 'sb' }, |
||||
{ name: 'Somalia', |
||||
dialCode: '252', |
||||
code: 'so' }, |
||||
{ name: 'South Africa', |
||||
dialCode: '27', |
||||
code: 'za' }, |
||||
{ name: 'South Sudan', |
||||
dialCode: '211', |
||||
code: 'ss' }, |
||||
{ |
||||
name: 'South Georgia and the South Sandwich Islands', |
||||
dialCode: '500', |
||||
code: 'gs' |
||||
}, |
||||
{ name: 'Spain', |
||||
dialCode: '34', |
||||
code: 'es' }, |
||||
{ name: 'Sri Lanka', |
||||
dialCode: '94', |
||||
code: 'lk' }, |
||||
{ name: 'Sudan', |
||||
dialCode: '249', |
||||
code: 'sd' }, |
||||
{ name: 'Suriname', |
||||
dialCode: '597', |
||||
code: 'sr' }, |
||||
{ name: 'Svalbard and Jan Mayen', |
||||
dialCode: '47', |
||||
code: 'sj' }, |
||||
{ name: 'Swaziland', |
||||
dialCode: '268', |
||||
code: 'sz' }, |
||||
{ name: 'Sweden', |
||||
dialCode: '46', |
||||
code: 'se' }, |
||||
{ name: 'Switzerland', |
||||
dialCode: '41', |
||||
code: 'ch' }, |
||||
{ name: 'Syrian Arab Republic', |
||||
dialCode: '963', |
||||
code: 'sy' }, |
||||
{ name: 'Taiwan', |
||||
dialCode: '886', |
||||
code: 'tw' }, |
||||
{ name: 'Tajikistan', |
||||
dialCode: '992', |
||||
code: 'tj' }, |
||||
{ |
||||
name: 'Tanzania, United Republic of Tanzania', |
||||
dialCode: '255', |
||||
code: 'tz' |
||||
}, |
||||
{ name: 'Thailand', |
||||
dialCode: '66', |
||||
code: 'th' }, |
||||
{ name: 'Timor-Leste', |
||||
dialCode: '670', |
||||
code: 'tl' }, |
||||
{ name: 'Togo', |
||||
dialCode: '228', |
||||
code: 'tg' }, |
||||
{ name: 'Tokelau', |
||||
dialCode: '690', |
||||
code: 'tk' }, |
||||
{ name: 'Tonga', |
||||
dialCode: '676', |
||||
code: 'to' }, |
||||
{ name: 'Trinidad and Tobago', |
||||
dialCode: '1868', |
||||
code: 'tt' }, |
||||
{ name: 'Tunisia', |
||||
dialCode: '216', |
||||
code: 'tn' }, |
||||
{ name: 'Turkey', |
||||
dialCode: '90', |
||||
code: 'tr' }, |
||||
{ name: 'Turkmenistan', |
||||
dialCode: '993', |
||||
code: 'tm' }, |
||||
{ name: 'Turks and Caicos Islands', |
||||
dialCode: '1649', |
||||
code: 'tc' }, |
||||
{ name: 'Tuvalu', |
||||
dialCode: '688', |
||||
code: 'tv' }, |
||||
{ name: 'Uganda', |
||||
dialCode: '256', |
||||
code: 'ug' }, |
||||
{ name: 'Ukraine', |
||||
dialCode: '380', |
||||
code: 'ua' }, |
||||
{ name: 'United Arab Emirates', |
||||
dialCode: '971', |
||||
code: 'ae' }, |
||||
{ name: 'United Kingdom', |
||||
dialCode: '44', |
||||
code: 'gb' }, |
||||
{ name: 'United States', |
||||
dialCode: '1', |
||||
code: 'us' }, |
||||
{ name: 'Uruguay', |
||||
dialCode: '598', |
||||
code: 'uy' }, |
||||
{ name: 'Uzbekistan', |
||||
dialCode: '998', |
||||
code: 'uz' }, |
||||
{ name: 'Vanuatu', |
||||
dialCode: '678', |
||||
code: 'vu' }, |
||||
{ |
||||
name: 'Venezuela, Bolivarian Republic of Venezuela', |
||||
dialCode: '58', |
||||
code: 've' |
||||
}, |
||||
{ name: 'Vietnam', |
||||
dialCode: '84', |
||||
code: 'vn' }, |
||||
{ name: 'Virgin Islands, British', |
||||
dialCode: '1284', |
||||
code: 'vg' }, |
||||
{ name: 'Virgin Islands, U.S.', |
||||
dialCode: '1340', |
||||
code: 'vi' }, |
||||
{ name: 'Wallis and Futuna', |
||||
dialCode: '681', |
||||
code: 'wf' }, |
||||
{ name: 'Yemen', |
||||
dialCode: '967', |
||||
code: 'ye' }, |
||||
{ name: 'Zambia', |
||||
dialCode: '260', |
||||
code: 'zm' }, |
||||
{ name: 'Zimbabwe', |
||||
dialCode: '263', |
||||
code: 'zw' } |
||||
]; |
||||
|
||||
const countriesByCodeMap = countries.reduce((result, country) => { |
||||
result[country.dialCode] = country; |
||||
|
||||
return result; |
||||
}, {}); |
||||
|
||||
/** |
||||
* Map between country dial codes and country objects. |
||||
* |
||||
*/ |
||||
const codesByNumbersMap = countries.reduce((result, country) => { |
||||
result[country.dialCode] = country.code; |
||||
|
||||
return result; |
||||
}, {}); |
||||
|
||||
/** |
||||
* Returns the corresponding country code from a phone number. |
||||
* |
||||
* @param {string} phoneNumber - The phone number. |
||||
* @returns {string} |
||||
*/ |
||||
export function getCountryCodeFromPhone(phoneNumber: string): string { |
||||
const number = phoneNumber.replace(/[+.\s]/g, ''); |
||||
|
||||
|
||||
for (let i = 4; i > 0; i--) { |
||||
const prefix = number.slice(0, i); |
||||
|
||||
if (codesByNumbersMap[prefix]) { |
||||
return codesByNumbersMap[prefix]; |
||||
} |
||||
} |
||||
|
||||
return ''; |
||||
} |
||||
|
||||
/** |
||||
* Returns the corresponding country for a text starting with the dial code. |
||||
* |
||||
* @param {string} text - The text containing the dial code. |
||||
* @returns {Object} |
||||
*/ |
||||
export function getCountryFromDialCodeText(text: string): Object { |
||||
return ( |
||||
countriesByCodeMap[text.slice(0, 4)] |
||||
|| countriesByCodeMap[text.slice(0, 3)] |
||||
|| countriesByCodeMap[text.slice(0, 2)] |
||||
|| countriesByCodeMap[text.slice(0, 1)] |
||||
|| null |
||||
); |
||||
} |
Loading…
Reference in new issue