basic call
This commit is contained in:
parent
335f8c6502
commit
a0aed1eeb7
196
package-lock.json
generated
196
package-lock.json
generated
@ -8,6 +8,7 @@
|
||||
"name": "abonent_terminal_application",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@ionic-native/media-capture": "^5.36.0",
|
||||
"@ionic/react": "^7.0.0",
|
||||
"@ionic/react-router": "^7.0.0",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
@ -21,11 +22,15 @@
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"history": "^4.9.0",
|
||||
"ionicons": "^7.0.0",
|
||||
"os": "^0.1.2",
|
||||
"os-browserify": "^0.3.0",
|
||||
"peerjs": "^1.5.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "^5.0.0",
|
||||
"socket.io-client": "^4.8.0",
|
||||
"typescript": "^4.1.3",
|
||||
"web-vitals": "^0.2.4",
|
||||
"workbox-background-sync": "^5.1.4",
|
||||
@ -2437,6 +2442,30 @@
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"deprecated": "Use @eslint/object-schema instead"
|
||||
},
|
||||
"node_modules/@ionic-native/core": {
|
||||
"version": "5.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic-native/core/-/core-5.36.0.tgz",
|
||||
"integrity": "sha512-lOrkktadlKYbYf1LrDyAtsu1JnQ0oCCdkOU7iHQ8oXnNOkMwobFfD2m62F1CoOr0u9LIkpYnZSPjng8lZbmbNw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/cordova": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rxjs": "^5.5.0 || ^6.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic-native/media-capture": {
|
||||
"version": "5.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic-native/media-capture/-/media-capture-5.36.0.tgz",
|
||||
"integrity": "sha512-JBXZYsiIYO95bycF6EU8JBEai6UXdEx3dLnkXzJSYgYt8ynWceSr7Z/nPeuYfScEiKI3JA5FmaUGUsTkyHXOnw==",
|
||||
"dependencies": {
|
||||
"@types/cordova": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ionic-native/core": "^5.1.0",
|
||||
"rxjs": "^5.5.0 || ^6.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.8.6.tgz",
|
||||
@ -2993,6 +3022,14 @@
|
||||
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
|
||||
"integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="
|
||||
},
|
||||
"node_modules/@msgpack/msgpack": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz",
|
||||
"integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
|
||||
"version": "5.1.1-v1",
|
||||
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
|
||||
@ -3210,6 +3247,11 @@
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.22.1.tgz",
|
||||
@ -3642,6 +3684,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cordova": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
||||
"integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg=="
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.56.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz",
|
||||
@ -6672,6 +6719,46 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.1.tgz",
|
||||
"integrity": "sha512-aYuoak7I+R83M/BBPIOs2to51BmFIpC1wZe6zZzMrT2llVsHy5cvcmdsJgP2Qz6smHu+sD9oexiSUAVd8OfBPw==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.2.1",
|
||||
"ws": "~8.17.1",
|
||||
"xmlhttprequest-ssl": "~2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-client/node_modules/ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
@ -11377,6 +11464,16 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/os": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz",
|
||||
"integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ=="
|
||||
},
|
||||
"node_modules/os-browserify": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
|
||||
"integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A=="
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
@ -11554,6 +11651,36 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/peerjs": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/peerjs/-/peerjs-1.5.4.tgz",
|
||||
"integrity": "sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw==",
|
||||
"dependencies": {
|
||||
"@msgpack/msgpack": "^2.8.0",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"peerjs-js-binarypack": "^2.1.0",
|
||||
"webrtc-adapter": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/peer"
|
||||
}
|
||||
},
|
||||
"node_modules/peerjs-js-binarypack": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-2.1.0.tgz",
|
||||
"integrity": "sha512-YIwCC+pTzp3Bi8jPI9UFKO0t0SLo6xALnHkiNt/iUFmUUZG0fEEmEyFKvjsDKweiFitzHRyhuh6NvyJZ4nNxMg==",
|
||||
"engines": {
|
||||
"node": ">= 14.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/peer"
|
||||
}
|
||||
},
|
||||
"node_modules/performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
@ -13829,6 +13956,24 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/safe-array-concat": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
|
||||
@ -14006,6 +14151,11 @@
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||
},
|
||||
"node_modules/sdp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz",
|
||||
"integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
|
||||
},
|
||||
"node_modules/select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@ -14267,6 +14417,32 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-client": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.0.tgz",
|
||||
"integrity": "sha512-C0jdhD5yQahMws9alf/yvtsMGTaIDBnZ8Rb5HU56svyq0l5LIrGzIDZZD5pHQlmzxLuU91Gz+VpQMKgCTNYtkw==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io-client": "~6.6.1",
|
||||
"socket.io-parser": "~4.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-parser": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sockjs": {
|
||||
"version": "0.3.24",
|
||||
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
|
||||
@ -16036,6 +16212,18 @@
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/webrtc-adapter": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz",
|
||||
"integrity": "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==",
|
||||
"dependencies": {
|
||||
"sdp": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0",
|
||||
"npm": ">=3.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/websocket-driver": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
|
||||
@ -16729,6 +16917,14 @@
|
||||
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
|
||||
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
|
||||
},
|
||||
"node_modules/xmlhttprequest-ssl": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz",
|
||||
"integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ionic-native/media-capture": "^5.36.0",
|
||||
"@ionic/react": "^7.0.0",
|
||||
"@ionic/react-router": "^7.0.0",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
@ -16,11 +17,15 @@
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"history": "^4.9.0",
|
||||
"ionicons": "^7.0.0",
|
||||
"os": "^0.1.2",
|
||||
"os-browserify": "^0.3.0",
|
||||
"peerjs": "^1.5.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "^5.0.0",
|
||||
"socket.io-client": "^4.8.0",
|
||||
"typescript": "^4.1.3",
|
||||
"web-vitals": "^0.2.4",
|
||||
"workbox-background-sync": "^5.1.4",
|
||||
|
13
src/components/CallContainer.tsx
Normal file
13
src/components/CallContainer.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
// import './ExploreContainer.css';
|
||||
|
||||
const CallContainer: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div id="container">
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CallContainer;
|
@ -1,10 +1,4 @@
|
||||
#container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#container strong {
|
||||
@ -22,3 +16,8 @@
|
||||
#container a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ExploreContainer.css */
|
||||
.call-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
@ -1,13 +1,122 @@
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import './ExploreContainer.css';
|
||||
import InputContainer from './Input';
|
||||
import { IonButton, IonContent, IonFooter, IonToolbar, IonPage, IonHeader, IonTitle, IonToast, IonText } from '@ionic/react';
|
||||
import Peer from 'peerjs';
|
||||
|
||||
const ExploreContainer: React.FC = () => {
|
||||
const [callString, setCallString] = useState("");
|
||||
const [isEnable, setIsEnable] = useState(true);
|
||||
const [peer, setPeer] = useState<Peer | null>(null);
|
||||
const [localStream, setLocalStream] = useState<MediaStream | null>(null);
|
||||
const [connectionInfo, setConnectionInfo] = useState<string | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Инициализация Peer без сервера, только для локальной сети
|
||||
const newPeer = new Peer({
|
||||
debug: 3,
|
||||
});
|
||||
|
||||
setPeer(newPeer);
|
||||
|
||||
newPeer.on('open', (id) => {
|
||||
console.log(`Peer успешно открыт с ID: ${id}`);
|
||||
setConnectionInfo(`Ваш Peer ID: ${id}`);
|
||||
});
|
||||
|
||||
newPeer.on('call', (call) => {
|
||||
console.log('Получен входящий звонок');
|
||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||
setLocalStream(stream);
|
||||
call.answer(stream);
|
||||
call.on('stream', (remoteStream) => {
|
||||
console.log('Получен удалённый поток');
|
||||
playAudio(remoteStream);
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.error('Не удалось получить локальный поток для ответа', err);
|
||||
});
|
||||
});
|
||||
|
||||
newPeer.on('error', (err) => {
|
||||
console.error('Ошибка Peer:', err);
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (peer) {
|
||||
console.log('Уничтожение Peer');
|
||||
peer.destroy();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const makeCall = () => {
|
||||
if (peer && callString) {
|
||||
setIsLoading(true);
|
||||
console.log(`Попытка звонка на: ${callString}`);
|
||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||
setLocalStream(stream);
|
||||
const call = peer.call(callString, stream);
|
||||
call.on('stream', (remoteStream) => {
|
||||
console.log('Получен удалённый поток во время вызова');
|
||||
playAudio(remoteStream);
|
||||
setIsLoading(false);
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.error('Не удалось получить локальный поток', err);
|
||||
setIsLoading(false);
|
||||
});
|
||||
} else {
|
||||
console.warn('Звонок невозможен: отсутствует Peer или callString');
|
||||
}
|
||||
};
|
||||
|
||||
const playAudio = (stream: MediaStream) => {
|
||||
const audioElement = document.createElement('audio');
|
||||
audioElement.srcObject = stream;
|
||||
audioElement.play().then(() => {
|
||||
console.log('Аудио начато воспроизведение');
|
||||
}).catch((error) => {
|
||||
console.error('Ошибка воспроизведения аудио', error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="container">
|
||||
<strong>Ready to create an app?</strong>
|
||||
<p>Start with Ionic <a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components">UI Components</a></p>
|
||||
</div>
|
||||
<>
|
||||
<IonContent fullscreen={true} className="ion-padding">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>
|
||||
DEBUG MODE
|
||||
</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonText>{connectionInfo}</IonText>
|
||||
{isLoading && (
|
||||
<div className="loading-animation">
|
||||
<span>.</span>
|
||||
<span>.</span>
|
||||
<span>.</span>
|
||||
</div>
|
||||
)}
|
||||
</IonContent>
|
||||
|
||||
<IonFooter>
|
||||
<IonToolbar className='panel-optimizer'>
|
||||
<InputContainer
|
||||
callString={callString}
|
||||
setCallString={setCallString}
|
||||
isEnable={isEnable}
|
||||
/>
|
||||
<IonButton className="call-button" onClick={makeCall} disabled={!isEnable || !callString || isLoading} slot="end">
|
||||
{isLoading ? 'Звонок...' : 'Вызов'}
|
||||
</IonButton>
|
||||
</IonToolbar>
|
||||
</IonFooter>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExploreContainer;
|
||||
|
||||
|
25
src/components/Input.tsx
Normal file
25
src/components/Input.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
// Определение интерфейса для пропсов
|
||||
interface InputContainerProps {
|
||||
callString: string;
|
||||
setCallString: (value: string) => void;
|
||||
isEnable: boolean;
|
||||
}
|
||||
|
||||
// InputContainer - форма ввода для начала звонка
|
||||
const InputContainer: React.FC<InputContainerProps> = ({ callString, setCallString, isEnable }) => {
|
||||
return (
|
||||
<div id="container">
|
||||
<input
|
||||
type="text"
|
||||
value={callString}
|
||||
onChange={(e) => setCallString(e.target.value)}
|
||||
disabled={!isEnable}
|
||||
placeholder="Enter call string"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputContainer;
|
12
src/components/LastCall.tsx
Normal file
12
src/components/LastCall.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
// import './ExploreContainer.css';
|
||||
|
||||
const LastCall: React.FC = () => {
|
||||
return (
|
||||
<div id="container">
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LastCall;
|
@ -8,13 +8,13 @@ const Home: React.FC = () => {
|
||||
<IonPage>
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Blank</IonTitle>
|
||||
<IonTitle>Drone RTC</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent fullscreen>
|
||||
<IonHeader collapse="condense">
|
||||
<IonToolbar>
|
||||
<IonTitle size="large">Blank</IonTitle>
|
||||
<IonTitle size="large">Drone RTC</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<ExploreContainer />
|
||||
|
Loading…
Reference in New Issue
Block a user