Close window when the call end and there is no error.

Fix call windows behaviours when choosing a call to be displayed (outgoing, paused, waiting room)

Fix a crash on stopping call when video was active.
This commit is contained in:
Julien Wadel 2023-01-13 13:56:10 +01:00
parent c3aa67cd1e
commit b6d7b20afd
8 changed files with 66 additions and 22 deletions

View file

@ -130,6 +130,10 @@ CallModel::CallModel (shared_ptr<linphone::Call> call){
CallModel::~CallModel () {
mMagicSearch->removeListener(mSearch);
removeCall();
}
void CallModel::removeCall(){
if(mCall){
mCall->removeListener(mCallListener);
mConferenceModel = nullptr;// Ordering deletion.

View file

@ -126,6 +126,7 @@ public:
CallModel (std::shared_ptr<linphone::Call> call);
~CallModel ();
void removeCall();
std::shared_ptr<linphone::Call> getCall () const {
return mCall;

View file

@ -540,6 +540,8 @@ void CallsListModel::handleCallStateChanged (const shared_ptr<linphone::Call> &c
if(call->dataExists("call-model")) {
CallModel * model = &call->getData<CallModel>("call-model");
model->endCall();
if(model->getCallError() == "")
removeCall(call);
}
} break;
case linphone::Call::State::Released:
@ -608,22 +610,20 @@ void CallsListModel::addDummyCall () {
void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) {
CallModel *callModel = nullptr;
try {
callModel = &call->getData<CallModel>("call-model");
} catch (const out_of_range &) {
// The call model not exists because the linphone call state
// `CallStateIncomingReceived`/`CallStateOutgoingInit` was not notified.
qWarning() << QStringLiteral("Unable to find call:") << call.get();
if(!call->dataExists("call-model"))
return;
}
callModel = &call->getData<CallModel>("call-model");
if( callModel && callModel->getCallError() != ""){ // Wait some time to display an error on ending call.
QTimer::singleShot( DelayBeforeRemoveCall , this, [this, callModel] {
removeCallCb(callModel);
});
}else
}else{
callModel->removeCall();
remove(callModel);
}
}
void CallsListModel::removeCallCb (CallModel *callModel) {
callModel->removeCall();
remove(callModel);
}

View file

@ -159,6 +159,10 @@ void Camera::removeParticipantDeviceModel(){
mParticipantDeviceModel = nullptr;
}
void Camera::callRemoved(){
mCallModel = nullptr;
}
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
QQuickFramebufferObject::Renderer * renderer = NULL;
if(mWindowIdLocation == CorePreview){
@ -229,6 +233,7 @@ void Camera::setCallModel (CallModel *callModel) {
disconnect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged);
mCallModel = callModel;
connect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged);
connect(mCallModel, &QObject::destroyed, this, &Camera::callRemoved);
updateWindowIdLocation();
update();

View file

@ -94,6 +94,7 @@ private:
void deactivatePreview();
void updateWindowIdLocation();
void removeParticipantDeviceModel();
void callRemoved();
QVariantMap mLastVideoDefinition;
QTimer mLastVideoDefinitionChecker;

View file

@ -165,6 +165,16 @@ function updateSelectedCall (call, index) {
}
}
function getCallToStatusCondition(model, condition){
for(var index = count - 1 ; index >= 0 ; --index){
var callModel = model.data(model.index(index, 0))
if(callModel.status === condition){
return {'callModel': callModel, 'index': index}
}
}
return null
}
function resetSelectedCall () {
updateSelectedCall(null, -1)
}
@ -193,20 +203,43 @@ function handleCountChanged (count) {
}
var call = calls._selectedCall
var model = calls.model
if (call == null) {
if (calls.conferenceModel.count > 0) {
if (call == null) {// No selected call.
if (calls.conferenceModel.count > 0) {// TODO : Is this needed?
return
}
var model = calls.model
var index = count - 1
if(model){
var callModel = model.data(model.index(index, 0))
if( callModel.status === Linphone.CallModel.CallStatusConnected || callModel.isOutgoing )
updateSelectedCall(callModel, index)
if(model){// Choose one call
var candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusConnected)
if(candidate && candidate.callModel.isOutgoing) {
updateSelectedCall(candidate.callModel, candidate.index)
return;
}
candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusOutgoing)
if(candidate){
updateSelectedCall(candidate.callModel, candidate.index)
return;
}
candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusPaused)
if(candidate){
updateSelectedCall(candidate.callModel, candidate.index)
return;
}else
calls.refreshLastCall()
}
} else{
if(model){// Select a call that has been localy initiated.
var candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusConnected)
if(candidate && candidate.callModel.isOutgoing) {
updateSelectedCall(candidate.callModel, candidate.index)
return;
}
candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusOutgoing)
if(candidate){
updateSelectedCall(candidate.callModel, candidate.index)
return;
}
}
} else {
setIndexWithCall(call)
}
}

View file

@ -33,12 +33,12 @@ ListView {
Logic.resetSelectedCall()
}
function refreshLastCall(){
if(lastCall && lastCall.status === CallModel.CallStatusConnected)
if(lastCall && (lastCall.status === CallModel.CallStatusConnected || lastCall.status === CallModel.CallStatusOutgoing))
Logic.setIndexWithCall(lastCall)
else{
for(var i = 0 ; i < model.rowCount() ; ++i){
var call = model.data(model.index(i, 0))
if( call && call.status === CallModel.CallStatusConnected){
if( call && (call.status === CallModel.CallStatusConnected || call.status === CallModel.CallStatusPaused || call.status == CallModel.CallStatusOutgoing)){
Logic.updateSelectedCall(call, i)
return;
}
@ -80,7 +80,7 @@ ListView {
ActionButton {
id: button
property bool isSelected : calls.currentIndex === callId && call.status !== CallModel.CallStatusEnded
property bool isSelected : calls.currentIndex === callId
isCustom: true
backgroundRadius: 4
colorSet: isSelected ? CallsStyle.entry.selectedBurgerMenu : CallsStyle.entry.burgerMenu

View file

@ -88,7 +88,7 @@ Window {
maximumLeftLimit: CallsWindowStyle.callsList.maximumWidth
minimumLeftLimit: CallsWindowStyle.callsList.minimumWidth
hideSplitter: !window.callsIsOpened && middlePane.sourceComponent == incall || middlePane.sourceComponent == waitingRoom
hideSplitter: !window.callsIsOpened && (middlePane.sourceComponent == incall && window.call.status != CallModel.CallStatusPaused) || middlePane.sourceComponent == waitingRoom
// -------------------------------------------------------------------------
// Calls list.