Commit 71674725 authored by Muhammadali's avatar Muhammadali

update-

parent 4c503192
{ {
"name": "boxdialer", "name": "boxdialer",
"version": "3.3.3", "version": "3.3.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "boxdialer", "name": "boxdialer",
"version": "3.3.3", "version": "3.3.4",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"ecmascript-webrtc-sipml": "git+https://git.4u.uz/kulya/ecmascript-webrtc-sipml.git", "ecmascript-webrtc-sipml": "git+https://git.4u.uz/kulya/ecmascript-webrtc-sipml.git",
"i": "^0.3.7", "i": "^0.3.7",
"jssip": "^3.10.0",
"npm": "^10.1.0", "npm": "^10.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
...@@ -2401,6 +2402,14 @@ ...@@ -2401,6 +2402,14 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/debug": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.9.tgz",
"integrity": "sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==",
"dependencies": {
"@types/ms": "*"
}
},
"node_modules/@types/eslint": { "node_modules/@types/eslint": {
"version": "8.44.2", "version": "8.44.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz",
...@@ -2427,6 +2436,11 @@ ...@@ -2427,6 +2436,11 @@
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"dev": true "dev": true
}, },
"node_modules/@types/events": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.1.tgz",
"integrity": "sha512-QfUFdKjGSc+iCf8OFZhqJKfDuqB6lP57kSMkPw8ba3yNDANicUwCdaPt5ytZ4nDXXVFxQkvT8v73I4stSVrCxA=="
},
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.17", "version": "4.17.17",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
...@@ -2484,6 +2498,11 @@ ...@@ -2484,6 +2498,11 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true "dev": true
}, },
"node_modules/@types/ms": {
"version": "0.7.32",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz",
"integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g=="
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.5.1", "version": "20.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz",
...@@ -4172,7 +4191,6 @@ ...@@ -4172,7 +4191,6 @@
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"engines": { "engines": {
"node": ">=0.8.x" "node": ">=0.8.x"
} }
...@@ -5202,6 +5220,39 @@ ...@@ -5202,6 +5220,39 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/jssip": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/jssip/-/jssip-3.10.0.tgz",
"integrity": "sha512-iJj+bhnNl0S296sUDc2ZjIbAetnelzZ92aWARyW01oKZ0X8t+5aGrYfJdMFliLFm8hxMcnkep3vmSRGe/yRjsA==",
"dependencies": {
"@types/debug": "^4.1.7",
"@types/events": "^3.0.0",
"debug": "^4.3.1",
"events": "^3.3.0",
"sdp-transform": "^2.14.1"
}
},
"node_modules/jssip/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/jssip/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
...@@ -9412,6 +9463,14 @@ ...@@ -9412,6 +9463,14 @@
"url": "https://opencollective.com/webpack" "url": "https://opencollective.com/webpack"
} }
}, },
"node_modules/sdp-transform": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz",
"integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==",
"bin": {
"sdp-verify": "checker.js"
}
},
"node_modules/select-hose": { "node_modules/select-hose": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"ecmascript-webrtc-sipml": "git+https://git.4u.uz/kulya/ecmascript-webrtc-sipml.git", "ecmascript-webrtc-sipml": "git+https://git.4u.uz/kulya/ecmascript-webrtc-sipml.git",
"i": "^0.3.7", "i": "^0.3.7",
"jssip": "^3.10.0",
"npm": "^10.1.0", "npm": "^10.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
......
...@@ -11,21 +11,16 @@ import PauseIcon from '@mui/icons-material/Pause'; ...@@ -11,21 +11,16 @@ import PauseIcon from '@mui/icons-material/Pause';
import SendToMobileIcon from '@mui/icons-material/SendToMobile'; import SendToMobileIcon from '@mui/icons-material/SendToMobile';
import DialpadIcon from '@mui/icons-material/Dialpad'; import DialpadIcon from '@mui/icons-material/Dialpad';
import CallCardDropDown from '../CallCardDropDown'; import CallCardDropDown from '../CallCardDropDown';
import ModalNumpad from '../ModalNumpad';
const Modal = ({ const Modal = ({ children, hidden, hangupButton, phoneNumber, callType }) => {
children,
hidden,
hangupButton,
phoneNumber,
callType,
callAnswerType,
}) => {
const boxDialer = window.BoxDialer; const boxDialer = window.BoxDialer;
const [rollUp, setRollUp] = useState(false); const [rollUp, setRollUp] = useState(false);
const [modalHidden, setModalHidden] = useState(false); const [modalHidden, setModalHidden] = useState(false);
const [callEvents, setCallEvents] = useState({}); const [callEvents, setCallEvents] = useState({});
const [transferModel, setTransferModel] = useState(true); const [transferModel, setTransferModel] = useState(true);
const [numpadModal, setNumpadModal] = useState(false);
useEffect(() => { useEffect(() => {
boxDialer.setSipStateChangeCallback(setCallEvents, 'setCallEvents'); boxDialer.setSipStateChangeCallback(setCallEvents, 'setCallEvents');
}, []); }, []);
...@@ -41,75 +36,44 @@ const Modal = ({ ...@@ -41,75 +36,44 @@ const Modal = ({
} }
}; };
const openNumpad = () => {
if (window.BX) {
} else {
setNumpadModal(!numpadModal);
}
};
if (!modalHidden) return; if (!modalHidden) return;
return (
<MainBlock
hidden={modalHidden || modalHidden}
rollUp={rollUp}
onClick={(e) => e.stopPropagation()}>
<ModalContainer onClick={(e) => e.stopPropagation()} rollUp={rollUp}>
{children}
<ModalContainer.Top className={'top'} rollUp={rollUp}>
{callType === 'outcoming' ? (
<p>Звонок на {phoneNumber}</p>
) : (
<p>Звонок от {phoneNumber}</p>
)}
<p className='rollUpButton' onClick={() => setRollUp(true)}> const selectModalType = (type) => {
Свернуть switch (type) {
</p> case 'incoming':
</ModalContainer.Top> return (
<hr /> <ModalContainer.Footer rollUp={rollUp}>
<ModalContainer.Head rollUp={rollUp}> <button
<div className='round'></div> className='redButton'
<p className='name'>No name</p> onClick={() => boxDialer.skipButtonClick()}>
</ModalContainer.Head>
<hr />
<ModalContainer.Body rollUp={rollUp}></ModalContainer.Body>
<hr />
<ModalContainer.Bottom rollUp={rollUp}></ModalContainer.Bottom>
<hr />
{callType === 'outcoming' ? (
<ModalContainer.Footer justify={'space-between'} rollUp={rollUp}>
<div className='outcomingEventStyle'>
<div onClick={() => boxDialer.holdButtonClick()}>
{callEvents.callHold ? (
<PlayArrowIcon style={{ color: '#fff' }} />
) : (
<PauseIcon style={{ color: '#fff' }} />
)}
</div>
<div onClick={() => boxDialer.muteButtonClick()}>
{callEvents.callMute ? (
<MicOffIcon style={{ color: '#fff' }} />
) : (
<MicIcon style={{ color: '#fff' }} />
)}
</div>
<div
className='transferAreaIcon'
onClick={() => {
window.BX
? boxDialer.selectUser()
: setTransferModel(!transferModel);
}}>
<SendToMobileIcon style={{ color: '#fff' }} />
<CallCardDropDown
hiddenState={transferModel}
selectUserFunc={selectUserFunc}
/>
</div>
<div>
<DialpadIcon style={{ color: '#fff' }} />
</div>
</div>
<button className='redButton' onClick={() => hangupButton()}>
<CallEndIcon /> <CallEndIcon />
ЗАКРЫТЬ ЗАКРЫТЬ
</button> </button>
<button
className='greenButton'
onClick={() => boxDialer.answerButtonClick()}>
ОТВЕТИТЬ
</button>
</ModalContainer.Footer> </ModalContainer.Footer>
) : callAnswerType !== 'answered' ? ( );
case 'outgoing':
return (
<ModalContainer.Footer rollUp={rollUp}>
<button
className='greenButton'
onClick={() => boxDialer.answerButtonClick()}>
ОТВЕТИТЬ
</button>
</ModalContainer.Footer>
);
case 'connectingIncoming':
return (
<ModalContainer.Footer rollUp={rollUp}> <ModalContainer.Footer rollUp={rollUp}>
<button <button
className='redButton' className='redButton'
...@@ -117,13 +81,21 @@ const Modal = ({ ...@@ -117,13 +81,21 @@ const Modal = ({
<CallEndIcon /> <CallEndIcon />
ЗАКРЫТЬ ЗАКРЫТЬ
</button> </button>
</ModalContainer.Footer>
);
case 'connectingOutgoing':
return (
<ModalContainer.Footer rollUp={rollUp}>
<button <button
className='greenButton' className='redButton'
onClick={() => boxDialer.answerButtonClick()}> onClick={() => boxDialer.skipButtonClick()}>
ОТВЕТИТЬ <CallEndIcon />
ЗАКРЫТЬ
</button> </button>
</ModalContainer.Footer> </ModalContainer.Footer>
) : ( );
case 'connected':
return (
<ModalContainer.Footer justify={'space-between'} rollUp={rollUp}> <ModalContainer.Footer justify={'space-between'} rollUp={rollUp}>
<div className='outcomingEventStyle'> <div className='outcomingEventStyle'>
<div onClick={() => boxDialer.holdButtonClick()}> <div onClick={() => boxDialer.holdButtonClick()}>
...@@ -153,8 +125,12 @@ const Modal = ({ ...@@ -153,8 +125,12 @@ const Modal = ({
selectUserFunc={selectUserFunc} selectUserFunc={selectUserFunc}
/> />
</div> </div>
<div> <div className={'openNumpadAreaIcon'}>
<DialpadIcon style={{ color: '#fff' }} /> <DialpadIcon
style={{ color: '#fff' }}
onClick={() => openNumpad()}
/>
<ModalNumpad hidden={numpadModal} />
</div> </div>
</div> </div>
<button <button
...@@ -164,7 +140,43 @@ const Modal = ({ ...@@ -164,7 +140,43 @@ const Modal = ({
ЗАКРЫТЬ ЗАКРЫТЬ
</button> </button>
</ModalContainer.Footer> </ModalContainer.Footer>
)} );
default:
return (
<ModalContainer.Footer rollUp={rollUp}>
Do not fount event
</ModalContainer.Footer>
);
}
};
return (
<MainBlock
hidden={modalHidden || modalHidden}
rollUp={rollUp}
onClick={(e) => e.stopPropagation()}>
<ModalContainer onClick={(e) => e.stopPropagation()} rollUp={rollUp}>
{children}
<ModalContainer.Top className={'top'} rollUp={rollUp}>
<p>
Звонок {callType === 'outcoming' ? 'на' : 'от'} {phoneNumber}
</p>
<p className='rollUpButton' onClick={() => setRollUp(true)}>
Свернуть
</p>
</ModalContainer.Top>
<hr />
<ModalContainer.Head rollUp={rollUp}>
<div className='round'></div>
<p className='name'>No name</p>
</ModalContainer.Head>
{/* <hr />
<ModalContainer.Body rollUp={rollUp}></ModalContainer.Body>
<hr />
<ModalContainer.Bottom rollUp={rollUp}></ModalContainer.Bottom>
<hr /> */}
{selectModalType(callType)}
</ModalContainer> </ModalContainer>
<div className='rollUpVesion'> <div className='rollUpVesion'>
<button <button
......
...@@ -113,6 +113,7 @@ ModalContainer.Footer = styled.div` ...@@ -113,6 +113,7 @@ ModalContainer.Footer = styled.div`
align-items: center; align-items: center;
padding: 15px; padding: 15px;
gap: 20px; gap: 20px;
color: #fff;
.outcomingEventStyle { .outcomingEventStyle {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -132,6 +133,9 @@ ModalContainer.Footer = styled.div` ...@@ -132,6 +133,9 @@ ModalContainer.Footer = styled.div`
.transferAreaIcon { .transferAreaIcon {
position: relative; position: relative;
} }
.openNumpadAreaIcon {
position: relative;
}
.redButton { .redButton {
background-color: #9d0f23; background-color: #9d0f23;
border-radius: 50px; border-radius: 50px;
......
/** @format */
import React, { useState } from 'react';
import Block, { NumberButton } from './style';
import numbers from '../../lib/numbers';
const ModalNumpad = ({ hidden }) => {
const boxDialer = window.BoxDialer;
const [dtmfValue, setDtmfValue] = useState('');
const selectNumberType = (value) => {
boxDialer.sipSendDTMF(value);
if (dtmfValue.length > 10) {
let sliceValue = (dtmfValue + value).slice(1);
setDtmfValue(sliceValue);
} else {
setDtmfValue(dtmfValue + value);
}
};
// 11
return (
<Block visiblevalue={hidden}>
<Block.ShowNumbersArea>{dtmfValue}</Block.ShowNumbersArea>
{numbers?.map((mapItem) => (
<NumberButton
className='nocopy'
key={mapItem.id}
onClick={() => selectNumberType(mapItem.value)}>
{mapItem.nameNumber}
<NumberButton.Icon>{mapItem.icon}</NumberButton.Icon>
</NumberButton>
))}
</Block>
);
};
export default ModalNumpad;
/** @format */
import styled from 'styled-components';
const Block = styled.div`
width: 200px;
padding: 8px;
background-color: #c9d5d9;
position: absolute;
bottom: 50px;
border-radius: 10px;
left: 50%;
transition: 0.3s;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 8px;
transform: translate(-50%, 0);
${({ visiblevalue }) =>
visiblevalue
? {
opacity: '1',
transform: 'translate(-50%, 0)',
}
: {
opacity: '0',
transform: 'translate(-50%, 0)',
}}
`;
Block.ShowNumbersArea = styled.div`
grid-column: 1/4;
height: 33px;
color: #000;
font-size: 22px;
text-align: center;
letter-spacing: 5px;
font-weight: bold;
`;
const NumberButton = styled.div`
color: #fff;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
border-radius: 7px;
font-size: 22px;
cursor: pointer;
height: 33px;
background-color: ${({ status = '', type = '' }) =>
type === 'call_button'
? status === 'pending'
? 'orange'
: status === 'connected' && '#a0c13d'
: '#5e5e5e'};
`;
NumberButton.Icon = styled.div`
font-size: 20px;
`;
export { NumberButton };
export default Block;
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import ModalPhoneNumpadStyle, { NumberButton, Input } from './style'; import ModalPhoneNumpadStyle, { NumberButton, Input } from './style';
import numbers from './numbers'; import numbers from '../../lib/numbers';
import CallIcon from '@mui/icons-material/Call'; import CallIcon from '@mui/icons-material/Call';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import DropDown from '../DropDown'; import DropDown from '../DropDown';
...@@ -45,7 +45,7 @@ const ModalPhoneNumpad = ({ ...@@ -45,7 +45,7 @@ const ModalPhoneNumpad = ({
const inputController = ({ value, type, from }) => { const inputController = ({ value, type, from }) => {
boxDialer.onSoundType({ type: 'pick', bool: true }); boxDialer.onSoundType({ type: 'pick', bool: true });
if (modalState.callType === 'outcoming' && modalState.bool) { if (modalState.callType === 'outcoming' && modalState.bool) {
boxDialer.sipSendDTMF(value); // boxDialer.sipSendDTMF(value);
} }
switch (type) { switch (type) {
case 'add': case 'add':
......
This diff is collapsed.
...@@ -10,10 +10,10 @@ const ControlRenderBX = () => { ...@@ -10,10 +10,10 @@ const ControlRenderBX = () => {
if (!window.alovoice_wsphone) { if (!window.alovoice_wsphone) {
setWsphonedata({ setWsphonedata({
iscloud: true, iscloud: true,
number: '4003', number: '2020',
wsurl: 'cld.alovoice.uz:61040', wsurl: 'cld.alovoice.uz:61040',
server_id: 40, server_id: 40,
secret: '26a830', secret: '97bff7',
lefttime: 231461, lefttime: 231461,
reasons: ['free', 'outcalls', 'home', 'totop'], reasons: ['free', 'outcalls', 'home', 'totop'],
reason: 'free', reason: 'free',
......
...@@ -52,20 +52,20 @@ const Root = ({ wsphonedata, onSetDnd, setWsphonedata, callMethod }) => { ...@@ -52,20 +52,20 @@ const Root = ({ wsphonedata, onSetDnd, setWsphonedata, callMethod }) => {
if (wsphonedata && wsphonedata?.number) { if (wsphonedata && wsphonedata?.number) {
boxDialer.setSipStateChangeCallback(setDynamicValue, 'dynamicValue'); boxDialer.setSipStateChangeCallback(setDynamicValue, 'dynamicValue');
boxDialer.setSipStateChangeCallback(setModalState, 'modalState'); boxDialer.setSipStateChangeCallback(setModalState, 'modalState');
boxDialer.setSipStateChangeCallback(setPhoneModal, 'phoneModal');
boxDialer.setSipStateChangeCallback(setSecondLine, 'secondLine'); boxDialer.setSipStateChangeCallback(setSecondLine, 'secondLine');
boxDialer.sipRegister(wsphonedata); boxDialer.sipRegister(wsphonedata);
} }
// setData(data);
}, []); }, []);
const hangupButton = () => { const hangupButton = () => {
boxDialer.hangupButtonClick(); boxDialer.hangupButtonClick();
}; };
window.setWSData = (result) => { window.setWSData = (result) => {
console.log('setWsphonedata', result); console.log('setWsphonedata', result);
setWsphonedata(result); setWsphonedata(result);
}; };
const reasonSelect = async (e) => { const reasonSelect = async (e) => {
let result = await onSetDnd(e); let result = await onSetDnd(e);
setWsphonedata(result); setWsphonedata(result);
...@@ -130,9 +130,10 @@ const Root = ({ wsphonedata, onSetDnd, setWsphonedata, callMethod }) => { ...@@ -130,9 +130,10 @@ const Root = ({ wsphonedata, onSetDnd, setWsphonedata, callMethod }) => {
<Modal <Modal
className='tailwindGlobalCss' className='tailwindGlobalCss'
callAnswerType={modalState.callType}
hidden={modalState.bool} hidden={modalState.bool}
// hidden={true}
callType={modalState.callType} callType={modalState.callType}
// callType={'connected'}
hangupButton={hangupButton} hangupButton={hangupButton}
phoneNumber={ phoneNumber={
modalState.callType === 'outcoming' modalState.callType === 'outcoming'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment