diff --git a/.restyled.yaml b/.restyled.yaml index ed4b219cf5..ad90851f3a 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -8,4 +8,6 @@ restylers: enabled: false - pyment: enabled: false + - clazy: + enabled: false - "*" diff --git a/img/status/on_call.svg b/img/status/on_call.svg new file mode 100644 index 0000000000..82ac7a2413 --- /dev/null +++ b/img/status/on_call.svg @@ -0,0 +1,89 @@ + + + +image/svg+xml diff --git a/res.qrc b/res.qrc index 249f311707..9dae976b22 100644 --- a/res.qrc +++ b/res.qrc @@ -30,6 +30,7 @@ img/status/offline.svg img/status/online_notification.svg img/status/online.svg + img/status/on_call.svg img/taskbar/dark/taskbar_away_event.svg img/taskbar/dark/taskbar_away.svg img/taskbar/dark/taskbar_busy_event.svg diff --git a/src/model/friendlist/ifriendlistitem.h b/src/model/friendlist/ifriendlistitem.h index c2f6e173d0..7eaae40f5f 100644 --- a/src/model/friendlist/ifriendlistitem.h +++ b/src/model/friendlist/ifriendlistitem.h @@ -22,6 +22,8 @@ class IFriendListItem virtual bool isFriend() const = 0; virtual bool isConference() const = 0; virtual bool isOnline() const = 0; + virtual void startCall() = 0; + virtual void stopCall() = 0; virtual bool widgetIsVisible() const = 0; virtual QString getNameItem() const = 0; virtual QDateTime getLastActivity() const = 0; diff --git a/src/widget/conferencewidget.cpp b/src/widget/conferencewidget.cpp index b26b0a6beb..80c30fc776 100644 --- a/src/widget/conferencewidget.cpp +++ b/src/widget/conferencewidget.cpp @@ -30,6 +30,7 @@ ConferenceWidget::ConferenceWidget(std::shared_ptr chatroom_, bo Settings& settings_, Style& style_, QWidget* parent) : GenericChatroomWidget(compact_, settings_, style_, parent) , chatroom{std::move(chatroom_)} + , hasActiveCallSession(false) , conferenceId{chatroom->getConference()->getPersistentId()} { avatar->setPixmap(Style::scaleSvgImage(":img/conference.svg", avatar->width(), avatar->height())); @@ -153,12 +154,34 @@ void ConferenceWidget::setAsInactiveChatroom() avatar->setPixmap(Style::scaleSvgImage(":img/conference.svg", avatar->width(), avatar->height())); } +/* + * @brief ConferenceWidget::startCall light up the on call indicator. + */ +void ConferenceWidget::startCall() +{ + hasActiveCallSession = true; + updateStatusLight(); +} + +/* + * @brief ConferenceWidget::stopCall shut down the on call indicator. + */ +void ConferenceWidget::stopCall() +{ + hasActiveCallSession = false; + updateStatusLight(); +} + void ConferenceWidget::updateStatusLight() { Conference* c = chatroom->getConference(); const bool event = c->getEventFlag(); - statusPic.setPixmap(QPixmap(Status::getIconPath(Status::Status::Online, event))); + if (hasActiveCallSession) { + statusPic.setPixmap(QPixmap(":/img/status/on_call.svg")); + } else { + statusPic.setPixmap(QPixmap(Status::getIconPath(Status::Status::Online, event))); + } statusPic.setMargin(event ? 1 : 3); } diff --git a/src/widget/conferencewidget.h b/src/widget/conferencewidget.h index 1e3b6aae72..30ff4bc486 100644 --- a/src/widget/conferencewidget.h +++ b/src/widget/conferencewidget.h @@ -37,6 +37,8 @@ class ConferenceWidget final : public GenericChatroomWidget, public IFriendListI bool isConference() const final; QString getNameItem() const final; bool isOnline() const final; + void startCall() final; + void stopCall() final; bool widgetIsVisible() const final; QDateTime getLastActivity() const final; QWidget* getWidget() final; @@ -61,6 +63,7 @@ private slots: private: std::shared_ptr chatroom; + bool hasActiveCallSession; public: ConferenceId conferenceId; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index a55538da4e..493f16ce57 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -339,6 +339,7 @@ void ChatForm::onAvStart(uint32_t friendId, bool video) } emit stopNotification(); + emit startCallNotification(friendId); updateCallButtons(); startCounter(); } @@ -356,7 +357,7 @@ void ChatForm::onAvEnd(uint32_t friendId, bool error) } emit stopNotification(); - emit endCallNotification(); + emit endCallNotification(friendId); updateCallButtons(); stopCounter(error); hideNetcam(); diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index f955157cc6..603bb78993 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -61,7 +61,8 @@ class ChatForm : public GenericChatForm void incomingNotification(uint32_t friendId); void outgoingNotification(); void stopNotification(); - void endCallNotification(); + void startCallNotification(uint32_t friendId); + void endCallNotification(uint32_t friendId); void rejectCall(uint32_t friendId); void acceptCall(uint32_t friendId); void updateFriendActivity(Friend& frnd); diff --git a/src/widget/form/conferenceform.cpp b/src/widget/form/conferenceform.cpp index 14d52117db..9f1623d66c 100644 --- a/src/widget/form/conferenceform.cpp +++ b/src/widget/form/conferenceform.cpp @@ -460,6 +460,7 @@ void ConferenceForm::joinConferenceCall() audioInputFlag = true; audioOutputFlag = true; inCall = true; + emit startConferenceCallNotification(conference->getId()); } void ConferenceForm::leaveConferenceCall() @@ -469,4 +470,5 @@ void ConferenceForm::leaveConferenceCall() audioInputFlag = false; audioOutputFlag = false; inCall = false; + emit endConferenceCallNotification(conference->getId()); } diff --git a/src/widget/form/conferenceform.h b/src/widget/form/conferenceform.h index 60c479b63c..a9c001114e 100644 --- a/src/widget/form/conferenceform.h +++ b/src/widget/form/conferenceform.h @@ -42,6 +42,10 @@ class ConferenceForm : public GenericChatForm void peerAudioPlaying(ToxPk peerPk); +signals: + void startConferenceCallNotification(uint32_t conferenceId); + void endConferenceCallNotification(uint32_t conferenceId); + private slots: void onScreenshotClicked() override; void onAttachClicked() override; diff --git a/src/widget/friendwidget.cpp b/src/widget/friendwidget.cpp index 7997de74ed..301b5b22a4 100644 --- a/src/widget/friendwidget.cpp +++ b/src/widget/friendwidget.cpp @@ -52,6 +52,7 @@ FriendWidget::FriendWidget(std::shared_ptr chatroom_, bool compa , style{style_} , messageBoxManager{messageBoxManager_} , profile{profile_} + , hasActiveCallSession(false) { avatar->setPixmap(QPixmap(":/img/contact.svg")); statusPic.setPixmap(QPixmap(Status::getIconPath(Status::Status::Offline))); @@ -302,11 +303,33 @@ void FriendWidget::setActive(bool active_) } } +/* + * @brief FriendWidget::startCall light up the on call indicator. + */ +void FriendWidget::startCall() +{ + hasActiveCallSession = true; + updateStatusLight(); +} + +/* + * @brief FriendWidget::stopCall shut down the on call indicator. + */ +void FriendWidget::stopCall() +{ + hasActiveCallSession = false; + updateStatusLight(); +} + void FriendWidget::updateStatusLight() { auto* const frnd = chatroom->getFriend(); const bool event = frnd->getEventFlag(); - statusPic.setPixmap(QPixmap(Status::getIconPath(frnd->getStatus(), event))); + if (hasActiveCallSession) { + statusPic.setPixmap(QPixmap(":/img/status/on_call.svg")); + } else { + statusPic.setPixmap(QPixmap(Status::getIconPath(frnd->getStatus(), event))); + } if (event) { const Settings& s = settings; diff --git a/src/widget/friendwidget.h b/src/widget/friendwidget.h index e3a0880e1e..6c7224dcf3 100644 --- a/src/widget/friendwidget.h +++ b/src/widget/friendwidget.h @@ -41,6 +41,8 @@ class FriendWidget : public GenericChatroomWidget, public IFriendListItem bool isFriend() const final; bool isConference() const final; bool isOnline() const final; + void startCall() final; + void stopCall() final; bool widgetIsVisible() const final; QString getNameItem() const final; QDateTime getLastActivity() const final; @@ -82,4 +84,7 @@ private slots: Style& style; IMessageBoxManager& messageBoxManager; Profile& profile; + +private: + bool hasActiveCallSession; }; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index cae096fddc..53f94c7637 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1095,9 +1095,65 @@ void Widget::outgoingNotification() playNotificationSound(IAudioSink::Sound::OutgoingCall, true); } -void Widget::onCallEnd() +void Widget::onStartConferenceCall(uint32_t conferenceId) +{ + const ConferenceId& confId = conferenceList->id2Key(conferenceId); + Conference* c = conferenceList->findConference(confId); + // Check if we have such conference in the list + // as confId can be a default value. + if (c == nullptr) { + return; + } + if (conferenceWidgets.contains(confId)) { + ConferenceWidget* widget = conferenceWidgets[confId]; + widget->startCall(); + } +} + +void Widget::onEndConferenceCall(uint32_t conferenceId) +{ + const ConferenceId& confId = conferenceList->id2Key(conferenceId); + Conference* c = conferenceList->findConference(confId); + // Check if we have such conference in the list + // as confId can be a default value. + if (c == nullptr) { + return; + } + if (conferenceWidgets.contains(confId)) { + ConferenceWidget* widget = conferenceWidgets[confId]; + widget->stopCall(); + } +} + +void Widget::onCallStart(uint32_t friendId) +{ + const ToxPk& toxPk = friendList->id2Key(friendId); + // Check if we have such friend in the list + // as toxPk can be a default value. + Friend* f = friendList->findFriend(toxPk); + if (f == nullptr) { + return; + } + if (friendWidgets.contains(toxPk)) { + FriendWidget* widget = friendWidgets[toxPk]; + widget->startCall(); + } +} + +void Widget::onCallEnd(uint32_t friendId) { playNotificationSound(IAudioSink::Sound::CallEnd); + const ToxPk& toxPk = friendList->id2Key(friendId); + // Check if we have such friend in the list + // as toxPk can be a default value. + Friend* f = friendList->findFriend(toxPk); + if (f == nullptr) { + return; + } + if (friendWidgets.contains(toxPk)) { + FriendWidget* widget = friendWidgets[toxPk]; + widget->stopCall(); + } } /** @@ -1230,6 +1286,7 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk) connect(friendForm, &ChatForm::incomingNotification, this, &Widget::incomingNotification); connect(friendForm, &ChatForm::outgoingNotification, this, &Widget::outgoingNotification); connect(friendForm, &ChatForm::stopNotification, this, &Widget::onStopNotification); + connect(friendForm, &ChatForm::startCallNotification, this, &Widget::onCallStart); connect(friendForm, &ChatForm::endCallNotification, this, &Widget::onCallEnd); connect(friendForm, &ChatForm::rejectCall, this, &Widget::onRejectCall); @@ -2184,6 +2241,10 @@ Conference* Widget::createConference(uint32_t conferencenumber, const Conference connect(newConference, &Conference::titleChangedByUser, this, &Widget::titleChangedByUser); connect(core, &Core::usernameSet, newConference, &Conference::setSelfName); + connect(form, &ConferenceForm::startConferenceCallNotification, this, + &Widget::onStartConferenceCall); + connect(form, &ConferenceForm::endConferenceCallNotification, this, &Widget::onEndConferenceCall); + return newConference; } diff --git a/src/widget/widget.h b/src/widget/widget.h index 6bfa0a4b12..263bc87a95 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -234,9 +234,12 @@ private slots: void friendRequestsUpdate(); void conferenceInvitesUpdate(); void conferenceInvitesClear(); + void onStartConferenceCall(uint32_t conferenceId); + void onEndConferenceCall(uint32_t conferenceId); void onDialogShown(GenericChatroomWidget* widget); void outgoingNotification(); - void onCallEnd(); + void onCallStart(uint32_t friendId); + void onCallEnd(uint32_t friendId); void incomingNotification(uint32_t friendNum); void onRejectCall(uint32_t friendId); void onStopNotification(); diff --git a/test/model/friendlistmanager_test.cpp b/test/model/friendlistmanager_test.cpp index db16b01b80..45b15880e5 100644 --- a/test/model/friendlistmanager_test.cpp +++ b/test/model/friendlistmanager_test.cpp @@ -42,6 +42,8 @@ class MockFriend : public IFriendListItem { return online; } + void startCall() override {} + void stopCall() override {} bool widgetIsVisible() const override { return visible; @@ -101,6 +103,8 @@ class MockConference : public IFriendListItem { return true; } + void startCall() override {} + void stopCall() override {} bool widgetIsVisible() const override { return visible;