mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-05-03 22:56:49 +00:00
Rework of chat room creations for selections.
- Avoid to select a chat room that is creating/terminating. - Add a loading spinner when the state of the chat room is updating. - On creation, wait on chat room state before automatically selecting it.
This commit is contained in:
parent
05e7ada86e
commit
5b5268ff60
13 changed files with 111 additions and 16 deletions
|
|
@ -355,9 +355,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
|
|||
CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = false;
|
||||
result["chatRoomModel"] = QVariant::fromValue(timeline->getChatRoomModel());
|
||||
if(selectAfterCreation) {// The timeline here will not receive the first creation event. Set Selected if needed
|
||||
QTimer::singleShot(200, [timeline](){// Delay process in order to let GUI time for Timeline building/linking before doing actions
|
||||
timeline->setSelected(true);
|
||||
});
|
||||
timeline->delaySelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ void ChatRoomInitializer::setAdmins(QList< std::shared_ptr<linphone::Address>> a
|
|||
|
||||
void ChatRoomInitializer::start(QSharedPointer<ChatRoomInitializer> initializer){
|
||||
QObject * context = new QObject();
|
||||
QObject::connect(initializer.get(), &ChatRoomInitializer::finished, context, [context, initializer](int state){
|
||||
QObject::connect(initializer.get(), &ChatRoomInitializer::finished, context, [context, initializer](LinphoneEnums::ChatRoomState state){
|
||||
qDebug() << "[ChatRoomInitializer] initialized";
|
||||
context->deleteLater();// This will destroy context and initializer
|
||||
});
|
||||
|
|
@ -93,7 +93,7 @@ void ChatRoomInitializer::checkInitialization(){
|
|||
if( mAdmins.size() > 0 && !mAdminsSet)
|
||||
return;
|
||||
|
||||
emit finished((int)mChatRoom->getState());
|
||||
emit finished(LinphoneEnums::fromLinphone(mChatRoom->getState()));
|
||||
}
|
||||
|
||||
void ChatRoomInitializer::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include "ChatRoomInitializer.hpp"
|
||||
#include "utils/LinphoneEnums.hpp"
|
||||
|
||||
|
||||
#include <QList>
|
||||
|
|
@ -54,7 +55,7 @@ public:
|
|||
virtual void onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState);
|
||||
|
||||
signals:
|
||||
void finished(int state); // this signal is emit before deletion and give the current linphone::ChatRoom:State of the chat room.
|
||||
void finished(LinphoneEnums::ChatRoomState state); // this signal is emit before deletion and give the current linphone::ChatRoom:State of the chat room.
|
||||
|
||||
private:
|
||||
void connectTo(ChatRoomListener * listener);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
|
|||
QObject::connect(coreManager->getContactsListModel(), &ContactsListModel::contactUpdated, this, &ChatRoomModel::avatarChanged);
|
||||
|
||||
connect(this, &ChatRoomModel::fullPeerAddressChanged, this, &ChatRoomModel::usernameChanged);
|
||||
connect(this, &ChatRoomModel::stateChanged, this, &ChatRoomModel::updatingChanged);
|
||||
|
||||
if(mChatRoom){
|
||||
mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this);
|
||||
|
|
@ -404,8 +405,8 @@ std::list<std::shared_ptr<linphone::Participant>> ChatRoomModel::getParticipants
|
|||
return participantList;
|
||||
}
|
||||
|
||||
int ChatRoomModel::getState() const {
|
||||
return mChatRoom ? (int)mChatRoom->getState() : 0;
|
||||
LinphoneEnums::ChatRoomState ChatRoomModel::getState() const {
|
||||
return mChatRoom ? LinphoneEnums::fromLinphone(mChatRoom->getState()) : LinphoneEnums::ChatRoomStateNone;
|
||||
}
|
||||
|
||||
bool ChatRoomModel::isReadOnly() const{
|
||||
|
|
@ -481,6 +482,10 @@ bool ChatRoomModel::isBasic() const{
|
|||
return mChatRoom && mChatRoom->hasCapability((int)linphone::ChatRoomCapabilities::Basic);
|
||||
}
|
||||
|
||||
bool ChatRoomModel::isUpdating() const{
|
||||
return getState() == LinphoneEnums::ChatRoomStateCreationPending || getState() == LinphoneEnums::ChatRoomStateTerminationPending;
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::ChatRoom> ChatRoomModel::getChatRoom(){
|
||||
return mChatRoom;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "app/proxyModel/ProxyListModel.hpp"
|
||||
#include <QDateTime>
|
||||
|
||||
#include "utils/LinphoneEnums.hpp"
|
||||
|
||||
// =============================================================================
|
||||
// Fetch all N messages of a ChatRoom.
|
||||
// =============================================================================
|
||||
|
|
@ -73,13 +75,14 @@ public:
|
|||
Q_PROPERTY(bool isComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged)
|
||||
Q_PROPERTY(QList<QString> composers READ getComposers NOTIFY isRemoteComposingChanged)
|
||||
Q_PROPERTY(bool isReadOnly READ isReadOnly NOTIFY isReadOnlyChanged)
|
||||
Q_PROPERTY(bool updating READ isUpdating NOTIFY updatingChanged)
|
||||
|
||||
Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString sipAddressUriOnly READ getPeerAddress NOTIFY fullPeerAddressChanged)
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
|
||||
Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)
|
||||
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
|
||||
Q_PROPERTY(LinphoneEnums::ChatRoomState state READ getState NOTIFY stateChanged)
|
||||
|
||||
Q_PROPERTY(long ephemeralLifetime READ getEphemeralLifetime WRITE setEphemeralLifetime NOTIFY ephemeralLifetimeChanged)
|
||||
Q_PROPERTY(bool ephemeralEnabled READ isEphemeralEnabled WRITE setEphemeralEnabled NOTIFY ephemeralEnabledChanged)
|
||||
|
|
@ -116,7 +119,7 @@ public:
|
|||
QString getUsername () const;
|
||||
QString getAvatar () const;
|
||||
int getPresenceStatus() const;
|
||||
int getState() const;
|
||||
LinphoneEnums::ChatRoomState getState() const;
|
||||
bool isReadOnly() const;
|
||||
bool isEphemeralEnabled() const;
|
||||
long getEphemeralLifetime() const;
|
||||
|
|
@ -135,6 +138,8 @@ public:
|
|||
bool getIsRemoteComposing () const;
|
||||
bool isEntriesLoading() const;
|
||||
bool isBasic() const;
|
||||
bool isUpdating() const;
|
||||
|
||||
ParticipantListModel* getParticipantListModel() const;
|
||||
std::list<std::shared_ptr<linphone::Participant>> getParticipants(const bool& withMe = true) const;
|
||||
std::shared_ptr<linphone::ChatRoom> getChatRoom();
|
||||
|
|
@ -273,6 +278,7 @@ signals:
|
|||
void markAsReadEnabledChanged();
|
||||
void chatRoomDeleted();// Must be connected with DirectConnection mode
|
||||
void replyChanged();
|
||||
void updatingChanged();
|
||||
|
||||
// Chat Room listener callbacks
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,10 @@ void TimelineListModel::select(ChatRoomModel * chatRoomModel){
|
|||
if(chatRoomModel) {
|
||||
auto timeline = getTimeline(chatRoomModel->getChatRoom(), false);
|
||||
if(timeline){
|
||||
timeline->setSelected(true);
|
||||
if(timeline->isUpdating())
|
||||
timeline->delaySelected();
|
||||
else
|
||||
timeline->setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ TimelineModel::TimelineModel (std::shared_ptr<linphone::ChatRoom> chatRoom, cons
|
|||
QObject::connect(this, &TimelineModel::selectedChanged, this, &TimelineModel::updateUnreadCount);
|
||||
QObject::connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &TimelineModel::onDefaultAccountChanged);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::chatRoomDeleted, this, &TimelineModel::onChatRoomDeleted);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::updatingChanged, this, &TimelineModel::updatingChanged);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::stateChanged, this, &TimelineModel::onChatRoomStateChanged);
|
||||
}
|
||||
if(chatRoom){
|
||||
mChatRoomListener = std::make_shared<ChatRoomListener>();
|
||||
|
|
@ -103,6 +105,8 @@ TimelineModel::TimelineModel(const TimelineModel * model){
|
|||
QObject::connect(this, &TimelineModel::selectedChanged, this, &TimelineModel::updateUnreadCount);
|
||||
QObject::connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &TimelineModel::onDefaultAccountChanged);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::chatRoomDeleted, this, &TimelineModel::onChatRoomDeleted);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::updatingChanged, this, &TimelineModel::updatingChanged);
|
||||
QObject::connect(mChatRoomModel.get(), &ChatRoomModel::stateChanged, this, &TimelineModel::onChatRoomStateChanged);
|
||||
}
|
||||
if(mChatRoomModel->getChatRoom()){
|
||||
mChatRoomListener = model->mChatRoomListener;
|
||||
|
|
@ -141,6 +145,10 @@ int TimelineModel::getPresenceStatus() const{
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool TimelineModel::isUpdating() const{
|
||||
return !mChatRoomModel || mChatRoomModel->isUpdating();
|
||||
}
|
||||
|
||||
ChatRoomModel *TimelineModel::getChatRoomModel() const{
|
||||
return mChatRoomModel.get();
|
||||
}
|
||||
|
|
@ -165,6 +173,15 @@ void TimelineModel::setSelected(const bool& selected){
|
|||
}
|
||||
}
|
||||
|
||||
void TimelineModel::delaySelected(){
|
||||
if( mChatRoomModel->getState() == LinphoneEnums::ChatRoomStateCreated){
|
||||
QTimer::singleShot(200, [&](){// Delay process in order to let GUI time for Timeline building/linking before doing actions
|
||||
setSelected(true);
|
||||
});
|
||||
}else
|
||||
mDelaySelection = true;
|
||||
}
|
||||
|
||||
void TimelineModel::updateUnreadCount(){
|
||||
if(!mSelected){// updateUnreadCount is called when selected has changed;: So if mSelected is false then we are going out of it.
|
||||
mChatRoomModel->resetMessageCount();// The reset will appear when the chat room has "mark as read enabled", that means that we should have read messages when going out.
|
||||
|
|
@ -230,4 +247,11 @@ void TimelineModel::onChatMessageParticipantImdnStateChanged(const std::shared_p
|
|||
|
||||
void TimelineModel::onChatRoomDeleted(){
|
||||
emit chatRoomDeleted();
|
||||
}
|
||||
|
||||
void TimelineModel::onChatRoomStateChanged(){
|
||||
if(mDelaySelection && mChatRoomModel->getState() == LinphoneEnums::ChatRoomStateCreated){
|
||||
mDelaySelection = false;
|
||||
setSelected(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,6 +52,7 @@ public:
|
|||
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel CONSTANT)
|
||||
|
||||
Q_PROPERTY(bool selected MEMBER mSelected WRITE setSelected NOTIFY selectedChanged)
|
||||
Q_PROPERTY(bool updating READ isUpdating NOTIFY updatingChanged)
|
||||
|
||||
|
||||
QString getFullPeerAddress() const;
|
||||
|
|
@ -61,7 +62,10 @@ public:
|
|||
QString getAvatar() const;
|
||||
int getPresenceStatus() const;
|
||||
|
||||
bool isUpdating() const;
|
||||
|
||||
void setSelected(const bool& selected);
|
||||
void delaySelected();
|
||||
|
||||
Q_INVOKABLE ChatRoomModel* getChatRoomModel() const;
|
||||
|
||||
|
|
@ -102,6 +106,7 @@ public slots:
|
|||
void updateUnreadCount();
|
||||
void onDefaultAccountChanged();
|
||||
void onChatRoomDeleted();
|
||||
void onChatRoomStateChanged();
|
||||
|
||||
signals:
|
||||
void fullPeerAddressChanged();
|
||||
|
|
@ -112,9 +117,12 @@ signals:
|
|||
void selectedChanged(bool selected);
|
||||
void conferenceLeft();
|
||||
void chatRoomDeleted();
|
||||
void updatingChanged();
|
||||
|
||||
private:
|
||||
|
||||
bool mDelaySelection = false;
|
||||
|
||||
void connectTo(ChatRoomListener * listener);
|
||||
std::shared_ptr<ChatRoomListener> mChatRoomListener;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
void LinphoneEnums::registerMetaTypes(){
|
||||
qRegisterMetaType<LinphoneEnums::CallStatus>();
|
||||
qRegisterMetaType<LinphoneEnums::ChatMessageState>();
|
||||
qRegisterMetaType<LinphoneEnums::ChatRoomState>();
|
||||
qRegisterMetaType<LinphoneEnums::ConferenceLayout>();
|
||||
qRegisterMetaType<LinphoneEnums::ConferenceInfoState>();
|
||||
qRegisterMetaType<LinphoneEnums::ConferenceSchedulerState>();
|
||||
|
|
@ -67,6 +68,14 @@ LinphoneEnums::ChatMessageState LinphoneEnums::fromLinphone(const linphone::Chat
|
|||
return static_cast<LinphoneEnums::ChatMessageState>(data);
|
||||
}
|
||||
|
||||
linphone::ChatRoom::State LinphoneEnums::toLinphone(const LinphoneEnums::ChatRoomState& data){
|
||||
return static_cast<linphone::ChatRoom::State>(data);
|
||||
}
|
||||
|
||||
LinphoneEnums::ChatRoomState LinphoneEnums::fromLinphone(const linphone::ChatRoom::State& data){
|
||||
return static_cast<LinphoneEnums::ChatRoomState>(data);
|
||||
}
|
||||
|
||||
linphone::Call::Status LinphoneEnums::toLinphone(const LinphoneEnums::CallStatus& data){
|
||||
return static_cast<linphone::Call::Status>(data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,8 +95,25 @@ enum ChatMessageState {
|
|||
};
|
||||
Q_ENUM_NS(ChatMessageState)
|
||||
|
||||
linphone::ChatMessage::State toLinphone(const LinphoneEnums::ChatMessageState& capability);
|
||||
LinphoneEnums::ChatMessageState fromLinphone(const linphone::ChatMessage::State& capability);
|
||||
linphone::ChatMessage::State toLinphone(const LinphoneEnums::ChatMessageState& data);
|
||||
LinphoneEnums::ChatMessageState fromLinphone(const linphone::ChatMessage::State& data);
|
||||
|
||||
enum ChatRoomState {
|
||||
ChatRoomStateNone = int(linphone::ChatRoom::State::None),
|
||||
ChatRoomStateInstantiated = int(linphone::ChatRoom::State::Instantiated),
|
||||
ChatRoomStateCreationPending = int(linphone::ChatRoom::State::CreationPending),
|
||||
ChatRoomStateCreated = int(linphone::ChatRoom::State::Created),
|
||||
ChatRoomStateCreationFailed = int(linphone::ChatRoom::State::CreationFailed),
|
||||
ChatRoomStateTerminationPending = int(linphone::ChatRoom::State::TerminationPending),
|
||||
ChatRoomStateTerminated = int(linphone::ChatRoom::State::Terminated),
|
||||
ChatRoomStateTerminationFailed = int(linphone::ChatRoom::State::TerminationFailed),
|
||||
ChatRoomStateDeleted = int(linphone::ChatRoom::State::Deleted),
|
||||
};
|
||||
Q_ENUM_NS(ChatRoomState)
|
||||
|
||||
linphone::ChatRoom::State toLinphone(const LinphoneEnums::ChatRoomState& data);
|
||||
LinphoneEnums::ChatRoomState fromLinphone(const linphone::ChatRoom::State& data);
|
||||
|
||||
|
||||
enum CallStatus {
|
||||
CallStatusDeclined = int(linphone::Call::Status::Declined),
|
||||
|
|
@ -202,6 +219,7 @@ void fromString(const QString& transportType, LinphoneEnums::TransportType *tran
|
|||
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::CallStatus)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ChatMessageState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ChatRoomState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ConferenceLayout)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ConferenceInfoState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ConferenceSchedulerState)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ Rectangle {
|
|||
|
||||
property bool displayUnreadMessageCount: false
|
||||
property bool showSubtitle : true
|
||||
property bool showBusyIndicator: false
|
||||
property string subtitle: ''
|
||||
|
||||
property string subject: (entry && entry.conferenceInfoModel && entry.conferenceInfoModel.subject
|
||||
|
|
@ -89,6 +90,27 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
onClicked: item.avatarClicked(mouse)
|
||||
}
|
||||
|
||||
Loader{
|
||||
id: busyLoader
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
|
||||
active: item.showBusyIndicator
|
||||
sourceComponent: Component{
|
||||
BusyIndicator{// Joining spinner
|
||||
id: joiningSpinner
|
||||
running: false
|
||||
Timer{// Delay starting spinner (Qt bug)
|
||||
id: indicatorDelay
|
||||
interval: 100
|
||||
onTriggered: joiningSpinner.running = true
|
||||
}
|
||||
Component.onCompleted: indicatorDelay.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContactDescription {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ Item {
|
|||
NumberAnimation { target: optionsView; property: 'x'; to:optionsView.width; duration: 200;}
|
||||
}
|
||||
]
|
||||
enabled: !contactView.showBusyIndicator
|
||||
|
||||
|
||||
Contact {
|
||||
|
|
@ -68,7 +69,8 @@ Item {
|
|||
? TimelineStyle.contact.title.color.selected
|
||||
: TimelineStyle.contact.title.color.normal
|
||||
showSubtitle: mainItem.timelineModel && (mainItem.timelineModel.chatRoomModel && (mainItem.timelineModel.chatRoomModel.isOneToOne || !mainItem.timelineModel.chatRoomModel.isConference))
|
||||
TooltipArea {
|
||||
showBusyIndicator: mainItem.timelineModel && mainItem.timelineModel.updating
|
||||
TooltipArea {
|
||||
id: contactTooltip
|
||||
text: mainItem.timelineModel && UtilsCpp.toDateTimeString(mainItem.timelineModel.chatRoomModel.lastUpdateTime)
|
||||
isClickable: true
|
||||
|
|
@ -160,5 +162,4 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -239,7 +239,7 @@ ColumnLayout {
|
|||
sipAddresses: _contact ? _contact.vcard.sipAddresses : [ contactEdit.sipAddress ]
|
||||
|
||||
function viewConversation(chatRoomModel){
|
||||
if( chatRoomModel){
|
||||
if( chatRoomModel && !chatRoomModel.updating){
|
||||
window.setView('Conversation', {
|
||||
chatRoomModel:chatRoomModel
|
||||
}, function(){
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue