add ui to show active calls
This commit is contained in:
@@ -229,6 +229,37 @@
|
||||
<div>Audio Call Address</div>
|
||||
<div class="text-sm text-gray-700">{{ config.audio_call_address_hash }}</div>
|
||||
</div>
|
||||
<div class="p-1 flex">
|
||||
<div>
|
||||
<div>Status</div>
|
||||
<div class="text-sm text-gray-700">
|
||||
<div v-if="activeAudioCalls.length > 0" class="flex space-x-2">
|
||||
<span v-if="activeInboundAudioCalls.length > 0">{{ activeInboundAudioCalls.length }} Incoming {{ activeInboundAudioCalls.length === 1 ? 'Call' : 'Calls' }}</span>
|
||||
<span v-else>{{ activeOutboundAudioCalls.length }} Outgoing {{ activeOutboundAudioCalls.length === 1 ? 'Call' : 'Calls' }}</span>
|
||||
</div>
|
||||
<div v-else>Hung up, waiting for call...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeAudioCalls.length > 0" class="ml-auto my-auto mr-1 space-x-2">
|
||||
|
||||
<!-- view incoming calls -->
|
||||
<a href="call.html" target="_blank" title="View Incoming Calls" class="my-auto inline-flex items-center gap-x-1 rounded-full bg-green-500 p-2 text-sm font-semibold text-white shadow-sm hover:bg-green-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5">
|
||||
<path fill-rule="evenodd" d="M4.25 5.5a.75.75 0 0 0-.75.75v8.5c0 .414.336.75.75.75h8.5a.75.75 0 0 0 .75-.75v-4a.75.75 0 0 1 1.5 0v4A2.25 2.25 0 0 1 12.75 17h-8.5A2.25 2.25 0 0 1 2 14.75v-8.5A2.25 2.25 0 0 1 4.25 4h5a.75.75 0 0 1 0 1.5h-5Z" clip-rule="evenodd" />
|
||||
<path fill-rule="evenodd" d="M6.194 12.753a.75.75 0 0 0 1.06.053L16.5 4.44v2.81a.75.75 0 0 0 1.5 0v-4.5a.75.75 0 0 0-.75-.75h-4.5a.75.75 0 0 0 0 1.5h2.553l-9.056 8.194a.75.75 0 0 0-.053 1.06Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
|
||||
</a>
|
||||
|
||||
<!-- hangup all calls -->
|
||||
<button title="Hangup all Calls" @click="hangupAllCalls" type="button" class="my-auto inline-flex items-center gap-x-1 rounded-full bg-red-500 p-2 text-sm font-semibold text-white shadow-sm hover:bg-red-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5 rotate-[135deg] translate-y-0.5">
|
||||
<path fill-rule="evenodd" d="M2 3.5A1.5 1.5 0 0 1 3.5 2h1.148a1.5 1.5 0 0 1 1.465 1.175l.716 3.223a1.5 1.5 0 0 1-1.052 1.767l-.933.267c-.41.117-.643.555-.48.95a11.542 11.542 0 0 0 6.254 6.254c.395.163.833-.07.95-.48l.267-.933a1.5 1.5 0 0 1 1.767-1.052l3.223.716A1.5 1.5 0 0 1 18 15.352V16.5a1.5 1.5 0 0 1-1.5 1.5H15c-1.149 0-2.263-.15-3.326-.43A13.022 13.022 0 0 1 2.43 8.326 13.019 13.019 0 0 1 2 5V3.5Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -574,6 +605,7 @@
|
||||
displayName: "Anonymous Peer",
|
||||
config: null,
|
||||
|
||||
audioCalls: [],
|
||||
lxmfDeliveryAnnounces: [],
|
||||
|
||||
tab: "peers",
|
||||
@@ -606,12 +638,22 @@
|
||||
};
|
||||
},
|
||||
mounted: function() {
|
||||
|
||||
this.connectWebsocket();
|
||||
this.getLxmfDeliveryAnnounces();
|
||||
this.getNomadnetworkNodeAnnounces();
|
||||
window.onNodePageUrlClick = (url) => {
|
||||
this.onNodePageUrlClick(url);
|
||||
};
|
||||
|
||||
// update calls list
|
||||
this.updateCallsList();
|
||||
|
||||
// update calls list every 5 seconds
|
||||
setInterval(() => {
|
||||
this.updateCallsList();
|
||||
}, 3000);
|
||||
|
||||
},
|
||||
methods: {
|
||||
connectWebsocket: function() {
|
||||
@@ -1515,6 +1557,39 @@
|
||||
onDestinationPathClick: function(path) {
|
||||
alert(`${path.hops} ${ path.hops === 1 ? 'hop' : 'hops' } away via ${path.next_hop_interface}`);
|
||||
},
|
||||
async updateCallsList() {
|
||||
try {
|
||||
|
||||
// fetch calls
|
||||
const response = await axios.get("/api/v1/calls");
|
||||
|
||||
// update ui
|
||||
this.audioCalls = response.data.audio_calls;
|
||||
|
||||
} catch(e) {
|
||||
// do nothing on error
|
||||
}
|
||||
},
|
||||
async hangupAllCalls() {
|
||||
|
||||
// confirm user wants to hang up calls
|
||||
if(!confirm("Are you sure you want to hang up all incoming and outgoing calls?")){
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// hangup all calls
|
||||
await axios.get(`/api/v1/calls/hangup-all`);
|
||||
|
||||
// reload calls list
|
||||
await this.updateCallsList();
|
||||
|
||||
} catch(e) {
|
||||
// ignore error hanging up call
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isMobile() {
|
||||
@@ -1593,6 +1668,21 @@
|
||||
return true;
|
||||
|
||||
},
|
||||
activeAudioCalls() {
|
||||
return this.audioCalls.filter(function(audioCall) {
|
||||
return audioCall.is_active;
|
||||
});
|
||||
},
|
||||
activeInboundAudioCalls() {
|
||||
return this.activeAudioCalls.filter(function(audioCall) {
|
||||
return !audioCall.is_outbound;
|
||||
});
|
||||
},
|
||||
activeOutboundAudioCalls() {
|
||||
return this.activeAudioCalls.filter(function(audioCall) {
|
||||
return audioCall.is_outbound;
|
||||
});
|
||||
},
|
||||
},
|
||||
}).mount('#app');
|
||||
</script>
|
||||
|
||||
@@ -134,6 +134,12 @@ class AudioCallManager:
|
||||
if audio_call is not None:
|
||||
self.audio_calls.remove(audio_call)
|
||||
|
||||
# hangup all calls
|
||||
def hangup_all(self):
|
||||
for audio_call in self.audio_calls:
|
||||
audio_call.hangup()
|
||||
return None
|
||||
|
||||
# attempts to initiate a call to the provided destination and returns the link hash on success
|
||||
async def initiate(self, destination_hash: bytes, timeout_seconds: int = 15) -> bytes:
|
||||
|
||||
|
||||
10
web.py
10
web.py
@@ -175,6 +175,14 @@ class ReticulumWebChat:
|
||||
"audio_calls": audio_calls,
|
||||
})
|
||||
|
||||
# hangup all calls
|
||||
@routes.get("/api/v1/calls/hangup-all")
|
||||
async def index(request):
|
||||
self.audio_call_manager.hangup_all()
|
||||
return web.json_response({
|
||||
"message": "All calls have been hungup",
|
||||
})
|
||||
|
||||
# get call
|
||||
@routes.get("/api/v1/calls/{audio_call_link_hash}")
|
||||
async def index(request):
|
||||
@@ -325,7 +333,7 @@ class ReticulumWebChat:
|
||||
audio_call.hangup()
|
||||
|
||||
return web.json_response({
|
||||
"message": "call has been hungup",
|
||||
"message": "Call has been hungup",
|
||||
})
|
||||
|
||||
# announce
|
||||
|
||||
Reference in New Issue
Block a user