From ee53dc8d19955d9e47d575c06ab61578449af85f Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 24 Mar 2023 16:16:08 +0100 Subject: [PATCH] Remove offline status (not fully supported and is error prone) and stabilize presence feature. Display presence text with time of last seen. Regroup text format into PresenceLevel.qml Set publish expires to 2minutes in order to be more correct. Update SDK for the last seen callback of presence model. # Conflicts: # linphone-app/assets/languages/ja.ts --- CHANGELOG.md | 1 + .../assistant/create-app-sip-account.rc | 1 + .../assets/assistant/use-app-sip-account.rc | 1 + linphone-app/assets/languages/da.ts | 27 ++++++++++ linphone-app/assets/languages/de.ts | 27 ++++++++++ linphone-app/assets/languages/en.ts | 27 ++++++++++ linphone-app/assets/languages/es.ts | 27 ++++++++++ linphone-app/assets/languages/fr_FR.ts | 27 ++++++++++ linphone-app/assets/languages/hu.ts | 27 ++++++++++ linphone-app/assets/languages/it.ts | 27 ++++++++++ linphone-app/assets/languages/ja.ts | 27 ++++++++++ linphone-app/assets/languages/lt.ts | 27 ++++++++++ linphone-app/assets/languages/pt_BR.ts | 27 ++++++++++ linphone-app/assets/languages/ru.ts | 27 ++++++++++ linphone-app/assets/languages/sv.ts | 27 ++++++++++ linphone-app/assets/languages/tr.ts | 27 ++++++++++ linphone-app/assets/languages/uk.ts | 27 ++++++++++ linphone-app/assets/languages/zh_CN.ts | 27 ++++++++++ linphone-app/assets/linphonerc-factory | 1 + .../components/chat-room/ChatRoomModel.cpp | 13 +++++ .../components/chat-room/ChatRoomModel.hpp | 2 + .../src/components/contact/ContactModel.cpp | 9 ++++ .../src/components/contact/ContactModel.hpp | 4 +- .../src/components/core/CoreManager.cpp | 4 ++ .../components/presence/OwnPresenceModel.cpp | 2 +- .../sip-addresses/SipAddressObserver.cpp | 8 +++ .../sip-addresses/SipAddressObserver.hpp | 8 +++ .../sip-addresses/SipAddressesModel.cpp | 12 +++-- .../sip-addresses/SipAddressesModel.hpp | 3 +- linphone-app/src/utils/Constants.cpp | 1 + linphone-app/src/utils/Constants.hpp | 6 ++- .../ui/modules/Linphone/Contact/Avatar.qml | 5 +- .../ui/modules/Linphone/Contact/Contact.qml | 2 +- .../Linphone/Presence/PresenceLevel.qml | 51 ++++++++++++++----- .../ui/views/App/Main/ContactEdit.qml | 1 + linphone-app/ui/views/App/Main/Contacts.qml | 5 +- .../ui/views/App/Main/Conversation.qml | 15 +++--- .../ui/views/App/Main/HistoryView.qml | 3 ++ .../Dialogs/SettingsSipAccountsEdit.js | 2 + .../Dialogs/SettingsSipAccountsEdit.qml | 9 ++++ linphone-sdk | 2 +- 41 files changed, 543 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce47a66b6..a155b25e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add/View contact from a message. - Mute option for each chatrooms. - New Chat Layout. +- Display last seen for contacts. ### Fixed - Update SDK to 5.2.29 diff --git a/linphone-app/assets/assistant/create-app-sip-account.rc b/linphone-app/assets/assistant/create-app-sip-account.rc index 5ae81029d..34384bcb2 100644 --- a/linphone-app/assets/assistant/create-app-sip-account.rc +++ b/linphone-app/assets/assistant/create-app-sip-account.rc @@ -7,6 +7,7 @@ 1 0 1 + 120 sip:voip-metrics@sip.linphone.org;transport=tls 1 180 diff --git a/linphone-app/assets/assistant/use-app-sip-account.rc b/linphone-app/assets/assistant/use-app-sip-account.rc index eb5e95e5d..b1b3b6f09 100644 --- a/linphone-app/assets/assistant/use-app-sip-account.rc +++ b/linphone-app/assets/assistant/use-app-sip-account.rc @@ -7,6 +7,7 @@ 1 0 1 + 120 sip:voip-metrics@sip.linphone.org;transport=tls 1 180 diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts index d59b94375..6022b0e18 100644 --- a/linphone-app/assets/languages/da.ts +++ b/linphone-app/assets/languages/da.ts @@ -2437,6 +2437,29 @@ Klik her: <a href="%1">%1</a> Offline + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Tilgængelig + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Klik her: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts index de0b005d8..b2c5d12ff 100644 --- a/linphone-app/assets/languages/de.ts +++ b/linphone-app/assets/languages/de.ts @@ -2437,6 +2437,29 @@ Klicken Sie hier: <a href="%1">%1</a> Offline + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Verfügbar + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Klicken Sie hier: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts index 3146b9396..8292832b9 100644 --- a/linphone-app/assets/languages/en.ts +++ b/linphone-app/assets/languages/en.ts @@ -2438,6 +2438,29 @@ Click here: <a href="%1">%1</a> Offline + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Online⁣ + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + Online today at %1 + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + Online yesterday at %1 + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + Online on %1 + + QObject @@ -3297,6 +3320,10 @@ Click here: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. invalid E2E encryption keys server URL + + publishDurationLabel + Publish duration (sec) + SettingsTunnel diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts index f16ebb924..6f436e41d 100644 --- a/linphone-app/assets/languages/es.ts +++ b/linphone-app/assets/languages/es.ts @@ -2437,6 +2437,29 @@ Haga clic aquí: <a href="%1">%1 </a> Desconectado + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Disponible + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Haga clic aquí: <a href="%1">%1 </a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts index b8ed9a0ae..400f510d0 100644 --- a/linphone-app/assets/languages/fr_FR.ts +++ b/linphone-app/assets/languages/fr_FR.ts @@ -2437,6 +2437,29 @@ Cliquez ici : <a href="%1">%1</a> Hors-ligne + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + En ligne + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + En ligne aujourd'hui à %1 + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + En ligne hier à %1 + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + En ligne le %1 + + QObject @@ -3273,6 +3296,10 @@ Cliquez ici : <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. URL du serveur de clés pour le chiffrement de bout en bout invalide + + publishDurationLabel + Durée de présence (sec) + SettingsTunnel diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts index 255eb9672..02c9f3dc1 100644 --- a/linphone-app/assets/languages/hu.ts +++ b/linphone-app/assets/languages/hu.ts @@ -2424,6 +2424,29 @@ Kattintson ide: <a href="%1">%1</a> Kapcsolat nélküli + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Elérhető + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3260,6 +3283,10 @@ Kattintson ide: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts index 8a2ee8b28..e26a867ec 100644 --- a/linphone-app/assets/languages/it.ts +++ b/linphone-app/assets/languages/it.ts @@ -2437,6 +2437,29 @@ Clicca: <a href="%1">%1</a> Offline + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Disponibile + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Clicca: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts index 04318c3f2..bbe431614 100644 --- a/linphone-app/assets/languages/ja.ts +++ b/linphone-app/assets/languages/ja.ts @@ -2424,6 +2424,29 @@ オフライン + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + 利用可能 + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3260,6 +3283,10 @@ "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts index 0650c5675..9450d94e1 100644 --- a/linphone-app/assets/languages/lt.ts +++ b/linphone-app/assets/languages/lt.ts @@ -2450,6 +2450,29 @@ Spustelėkite čia: <a href="%1">%1</a> Atsijungęs + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Pasiekiamas + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3286,6 +3309,10 @@ Spustelėkite čia: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts index 33820a3cf..c648e6c99 100644 --- a/linphone-app/assets/languages/pt_BR.ts +++ b/linphone-app/assets/languages/pt_BR.ts @@ -2437,6 +2437,29 @@ Clique aqui: <a href="%1">%1 </a> Offline + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Disponível + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Clique aqui: <a href="%1">%1 </a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. URL de servidor de chaves de criptografia E2E inválida + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts index be17030fe..1826546f1 100644 --- a/linphone-app/assets/languages/ru.ts +++ b/linphone-app/assets/languages/ru.ts @@ -2450,6 +2450,29 @@ Офлайн + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Доступен + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3286,6 +3309,10 @@ "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. неверный адрес сервера ключей шифрования E2E + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts index 71c4e24d6..b68d6d254 100644 --- a/linphone-app/assets/languages/sv.ts +++ b/linphone-app/assets/languages/sv.ts @@ -2437,6 +2437,29 @@ Klicka här: <a href="%1">%1</a> Frånkopplad + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Tillgänglig + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3273,6 +3296,10 @@ Klicka här: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts index d1c333740..d4f44e567 100644 --- a/linphone-app/assets/languages/tr.ts +++ b/linphone-app/assets/languages/tr.ts @@ -2424,6 +2424,29 @@ Buraya tıklayın: <a href="%1">%1</a> Çevrim dışı + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Uygun + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3260,6 +3283,10 @@ Buraya tıklayın: <a href="%1">%1</a> "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts index 068e51048..e78b50949 100644 --- a/linphone-app/assets/languages/uk.ts +++ b/linphone-app/assets/languages/uk.ts @@ -2450,6 +2450,29 @@ Не в мережі + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + Доступний + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3286,6 +3309,10 @@ "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts index 37186c1bd..59c5aa611 100644 --- a/linphone-app/assets/languages/zh_CN.ts +++ b/linphone-app/assets/languages/zh_CN.ts @@ -2424,6 +2424,29 @@ 离线 + + PresenceLevel + + presenceOnline + 'Online⁣': Presence text + 有空 + + + presenceLastSeenToday + 'Online today at %1' : Presence text for today (%1 is the hour) + + + + presenceLastSeenYesterday + 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + + + + presenceLastSeen + 'Online on %1' : Presence text for latter days (%1 is a date) + + + QObject @@ -3260,6 +3283,10 @@ "invalid E2E encryption keys server URL" : Error text about E2E encryption keys server URL. + + publishDurationLabel + + SettingsTunnel diff --git a/linphone-app/assets/linphonerc-factory b/linphone-app/assets/linphonerc-factory index 2b997fbfa..9289dbc06 100644 --- a/linphone-app/assets/linphonerc-factory +++ b/linphone-app/assets/linphonerc-factory @@ -14,6 +14,7 @@ accept_any_encryption=1 chat_messages_aggregation_delay=1000 chat_messages_aggregation=1 zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512 +update_presence_model_timestamp_before_publish_expires_refresh=1 [video] max_conference_size=vga diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index 08d60ac22..3ab296a49 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -392,6 +392,19 @@ int ChatRoomModel::getPresenceStatus() const { return -1; } +QDateTime ChatRoomModel::getPresenceTimestamp() const { + if( mChatRoom && mChatRoom->getNbParticipants() == 1 && !isGroupEnabled()){ + auto participants = getParticipants(false); + auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::coreStringToAppString((*participants.begin())->getAddress()->asString())); + if(contact) { + return contact->getPresenceTimestamp(); + } + else + return QDateTime(); + }else + return QDateTime(); +} + ParticipantListModel* ChatRoomModel::getParticipantListModel() const{ return mParticipantListModel.get(); } diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp index e4bf25ecd..81af65531 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp @@ -82,6 +82,7 @@ public: 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(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceStatusChanged) Q_PROPERTY(LinphoneEnums::ChatRoomState state READ getState NOTIFY stateChanged) Q_PROPERTY(long ephemeralLifetime READ getEphemeralLifetime WRITE setEphemeralLifetime NOTIFY ephemeralLifetimeChanged) @@ -120,6 +121,7 @@ public: QString getUsername () const; QString getAvatar () const; int getPresenceStatus() const; + QDateTime getPresenceTimestamp() const; LinphoneEnums::ChatRoomState getState() const; bool isReadOnly() const; bool isEphemeralEnabled() const; diff --git a/linphone-app/src/components/contact/ContactModel.cpp b/linphone-app/src/components/contact/ContactModel.cpp index c075f9fb2..e8372c2f5 100644 --- a/linphone-app/src/components/contact/ContactModel.cpp +++ b/linphone-app/src/components/contact/ContactModel.cpp @@ -210,10 +210,19 @@ Presence::PresenceStatus ContactModel::getPresenceStatus () const { return static_cast(mLinphoneFriend->getConsolidatedPresence()); } +QDateTime ContactModel::getPresenceTimestamp() const{ + if(mLinphoneFriend->getPresenceModel()){ + return QDateTime::fromMSecsSinceEpoch(mLinphoneFriend->getPresenceModel()->getTimestamp() * 1000); + }else + return QDateTime(); +} + Presence::PresenceLevel ContactModel::getPresenceLevel () const { return Presence::getPresenceLevel(getPresenceStatus()); } + + bool ContactModel::hasCapability(const LinphoneEnums::FriendCapability& capability){ return mLinphoneFriend->hasCapability(LinphoneEnums::toLinphone(capability)); } diff --git a/linphone-app/src/components/contact/ContactModel.hpp b/linphone-app/src/components/contact/ContactModel.hpp index e482b8d88..4d20f1f68 100644 --- a/linphone-app/src/components/contact/ContactModel.hpp +++ b/linphone-app/src/components/contact/ContactModel.hpp @@ -24,6 +24,7 @@ #include "components/presence/Presence.hpp" #include "utils/LinphoneEnums.hpp" +#include #include // ============================================================================= @@ -39,6 +40,7 @@ class ContactModel : public QObject { Q_OBJECT Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged) + Q_PROPERTY(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceStatusChanged) Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY presenceLevelChanged) Q_PROPERTY(VcardModel * vcard READ getVcardModel WRITE setVcardModel NOTIFY contactUpdated) @@ -56,6 +58,7 @@ public: Q_INVOKABLE VcardModel *cloneVcardModel () const; Presence::PresenceLevel getPresenceLevel () const; + QDateTime getPresenceTimestamp() const; Q_INVOKABLE bool hasCapability(const LinphoneEnums::FriendCapability& capability); std::shared_ptr getFriend() const; @@ -73,7 +76,6 @@ private: void updateSipAddresses (VcardModel *oldVcardModel); Presence::PresenceStatus getPresenceStatus () const; - VcardModel *mVcardModel = nullptr; std::shared_ptr mLinphoneFriend; diff --git a/linphone-app/src/components/core/CoreManager.cpp b/linphone-app/src/components/core/CoreManager.cpp index 01bfa2f6c..ff1215ea2 100644 --- a/linphone-app/src/components/core/CoreManager.cpp +++ b/linphone-app/src/components/core/CoreManager.cpp @@ -364,6 +364,10 @@ void CoreManager::migrate () { qInfo() << "Migrating" << accountIdentity << "for version 5. Video conference factory URI" << (exists ? std::string("unchanged") : std::string("= ") +Constants::DefaultVideoConferenceURI).c_str(); // note: using std::string.c_str() to avoid having double quotes in qInfo() } + if( rcVersion < 6) { + newParams->setPublishExpires(Constants::DefaultPublishExpires); + qInfo() << "Migrating" << accountIdentity << "for version 6. publish expires =" << Constants::DefaultPublishExpires; + } if(newParams->getLimeServerUrl().empty()){ if(!oldLimeServerUrl.empty()) newParams->setLimeServerUrl(oldLimeServerUrl); diff --git a/linphone-app/src/components/presence/OwnPresenceModel.cpp b/linphone-app/src/components/presence/OwnPresenceModel.cpp index 29b2a6c57..8d5d7df3a 100644 --- a/linphone-app/src/components/presence/OwnPresenceModel.cpp +++ b/linphone-app/src/components/presence/OwnPresenceModel.cpp @@ -75,7 +75,7 @@ QVariantList OwnPresenceModel::getStatuses () const { addBuildStatus(statuses, Presence::Online); addBuildStatus(statuses, Presence::Busy); addBuildStatus(statuses, Presence::DoNotDisturb); - addBuildStatus(statuses, Presence::Offline); + //addBuildStatus(statuses, Presence::Offline); // Do not propose this status as it is not fully supported return statuses; } diff --git a/linphone-app/src/components/sip-addresses/SipAddressObserver.cpp b/linphone-app/src/components/sip-addresses/SipAddressObserver.cpp index cf714e3ed..2dbb3269e 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressObserver.cpp +++ b/linphone-app/src/components/sip-addresses/SipAddressObserver.cpp @@ -43,6 +43,14 @@ void SipAddressObserver::setPresenceStatus (const Presence::PresenceStatus &pres emit presenceStatusChanged(presenceStatus); } +void SipAddressObserver::setPresenceTimestamp(const QDateTime &presenceTimestamp){ + if (presenceTimestamp == mPresenceTimestamp) + return; + + mPresenceTimestamp = presenceTimestamp; + emit presenceTimestampChanged(presenceTimestamp); +} + void SipAddressObserver::setUnreadMessageCount (int unreadMessageCount) { if (unreadMessageCount == mUnreadMessageCount) return; diff --git a/linphone-app/src/components/sip-addresses/SipAddressObserver.hpp b/linphone-app/src/components/sip-addresses/SipAddressObserver.hpp index cb3175da1..f37cc93f1 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressObserver.hpp +++ b/linphone-app/src/components/sip-addresses/SipAddressObserver.hpp @@ -24,6 +24,7 @@ #include "components/presence/Presence.hpp" #include +#include // ============================================================================= @@ -39,6 +40,7 @@ class SipAddressObserver : public QObject { Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged); Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged); + Q_PROPERTY(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceTimestampChanged); Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged); Q_PROPERTY(bool isOneToOne MEMBER isOneToOne CONSTANT); @@ -54,6 +56,7 @@ public: signals: void contactChanged (QSharedPointer); void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus); + void presenceTimestampChanged (const QDateTime &presenceTimestamp); void unreadMessageCountChanged (int unreadMessageCount); private: @@ -78,8 +81,12 @@ private: Presence::PresenceStatus getPresenceStatus () const { return mPresenceStatus; } + QDateTime getPresenceTimestamp() const{ + return mPresenceTimestamp; + } void setPresenceStatus (const Presence::PresenceStatus &presenceStatus); + void setPresenceTimestamp (const QDateTime &presenceTimestamp); // --------------------------------------------------------------------------- @@ -94,6 +101,7 @@ private: QSharedPointer mContact; Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline; + QDateTime mPresenceTimestamp; int mUnreadMessageCount = 0; }; diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp index e9c427597..7de54dbda 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp +++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp @@ -135,6 +135,7 @@ SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &pee if (it != mPeerAddressToSipAddressEntry.end()) { model->setContact(it->contact); model->setPresenceStatus(it->presenceStatus); + model->setPresenceTimestamp(it->presenceTimestamp); auto it2 = it->localAddressToConferenceEntry.find(cleanedLocalAddress); if (it2 != it->localAddressToConferenceEntry.end()) @@ -364,18 +365,19 @@ void SipAddressesModel::handlePresenceReceived ( status = Presence::PresenceStatus::Offline; break; } - + QDateTime presenceTimestamp = QDateTime::fromMSecsSinceEpoch(presenceModel->getTimestamp()*1000); auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it != mPeerAddressToSipAddressEntry.end()) { qInfo() << QStringLiteral("Update presence of `%1`: %2.").arg(sipAddress).arg(status); it->presenceStatus = status; + it->presenceTimestamp = presenceTimestamp; int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); } - updateObservers(sipAddress, status); + updateObservers(sipAddress, status, presenceTimestamp); } void SipAddressesModel::handleAllEntriesRemoved (ChatRoomModel *chatRoomModel) { @@ -663,9 +665,11 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, QSharedPoint observer->setContact(contact); } -void SipAddressesModel::updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus) { - for (auto &observer : mObservers.values(sipAddress)) +void SipAddressesModel::updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus, const QDateTime &presenceTimestamp) { + for (auto &observer : mObservers.values(sipAddress)){ observer->setPresenceStatus(presenceStatus); + observer->setPresenceTimestamp(presenceTimestamp); + } } void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount) { diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp index b8150a9d5..3d5c918c4 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp +++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp @@ -50,6 +50,7 @@ public: QString sipAddress; QSharedPointer contact; Presence::PresenceStatus presenceStatus; + QDateTime presenceTimestamp; QHash localAddressToConferenceEntry; }; @@ -147,7 +148,7 @@ private: void initRefs (); void updateObservers (const QString &sipAddress, QSharedPointer contact); - void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus); + void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus, const QDateTime &presenceTimestamp); void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount); // --------------------------------------------------------------------------- diff --git a/linphone-app/src/utils/Constants.cpp b/linphone-app/src/utils/Constants.cpp index bb22d44b1..c3e651d8a 100644 --- a/linphone-app/src/utils/Constants.cpp +++ b/linphone-app/src/utils/Constants.cpp @@ -124,6 +124,7 @@ constexpr char Constants::LinphoneDomain[]; constexpr char Constants::DefaultContactParameters[]; constexpr char Constants::DefaultContactParametersOnRemove[]; constexpr int Constants::DefaultExpires; +constexpr int Constants::DefaultPublishExpires; constexpr char Constants::DownloadUrl[]; constexpr char Constants::VersionCheckReleaseUrl[]; constexpr char Constants::VersionCheckNightlyUrl[]; diff --git a/linphone-app/src/utils/Constants.hpp b/linphone-app/src/utils/Constants.hpp index ba11d5e9d..dadcdac5b 100644 --- a/linphone-app/src/utils/Constants.hpp +++ b/linphone-app/src/utils/Constants.hpp @@ -50,7 +50,8 @@ public: static constexpr char DefaultUploadLogsServer[] = "https://www.linphone.org:444/lft.php"; static constexpr char DefaultContactParameters[] = "message-expires=2419200"; static constexpr char DefaultContactParametersOnRemove[] = "message-expires=0"; - static constexpr int DefaultExpires = 3600; + static constexpr int DefaultExpires = 600; + static constexpr int DefaultPublishExpires = 120; static constexpr char DownloadUrl[] = "https://www.linphone.org/technical-corner/linphone"; static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases"; static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots"; @@ -157,10 +158,11 @@ public: static constexpr char VcardScheme[] = EXECUTABLE_NAME "-desktop:/"; static constexpr int CbsCallInterval = 20; static constexpr char RcVersionName[] = "rc_version"; - static constexpr int RcVersionCurrent = 5; // 2 = Conference URI + static constexpr int RcVersionCurrent = 6; // 2 = Conference URI // 3 = CPIM on basic chat rooms // 4 = RTP bundle mode // 5 = Video Conference URI + // 6 = Publish expires //-------------------------------------------------------------------------------- // CISCO //-------------------------------------------------------------------------------- diff --git a/linphone-app/ui/modules/Linphone/Contact/Avatar.qml b/linphone-app/ui/modules/Linphone/Contact/Avatar.qml index acc1aee00..6f7cbd098 100644 --- a/linphone-app/ui/modules/Linphone/Contact/Avatar.qml +++ b/linphone-app/ui/modules/Linphone/Contact/Avatar.qml @@ -13,8 +13,10 @@ Item { id: avatar // --------------------------------------------------------------------------- - + property alias hasPresence: presenceLevelIcon.visible property alias presenceLevel: presenceLevelIcon.level + property alias presenceText: presenceLevelIcon.text + property alias presenceTimestamp: presenceLevelIcon.timestamp property bool isDarkMode: false property color backgroundColor: isDarkMode ? AvatarStyle.backgroundDarkModeColor.color : AvatarStyle.backgroundColor.color property color foregroundColor: 'transparent' @@ -83,7 +85,6 @@ Item { PresenceLevel { id: presenceLevelIcon - visible: level >= 0 anchors { bottom: parent.bottom diff --git a/linphone-app/ui/modules/Linphone/Contact/Contact.qml b/linphone-app/ui/modules/Linphone/Contact/Contact.qml index 87458c9c8..f9fb40e43 100644 --- a/linphone-app/ui/modules/Linphone/Contact/Contact.qml +++ b/linphone-app/ui/modules/Linphone/Contact/Contact.qml @@ -68,7 +68,7 @@ Rectangle { : (entry.presenceStatus >= 0 ? Presence.getPresenceLevel(entry.presenceStatus) : -1) ) :-1 - + presenceTimestamp: entry && entry.contactModel && entry.contactModel.presenceTimestamp username: entry!=undefined ? entry.conferenceInfoModel ? item.organizer diff --git a/linphone-app/ui/modules/Linphone/Presence/PresenceLevel.qml b/linphone-app/ui/modules/Linphone/Presence/PresenceLevel.qml index a4fbc0730..eb1c155a0 100644 --- a/linphone-app/ui/modules/Linphone/Presence/PresenceLevel.qml +++ b/linphone-app/ui/modules/Linphone/Presence/PresenceLevel.qml @@ -3,21 +3,46 @@ import QtQuick 2.7 import Common 1.0 import Linphone 1.0 +import 'qrc:/ui/scripts/Utils/utils.js' as Utils + // ============================================================================= // Wrapper to use `icon` property. Item { - property var level: null - property bool betterIcon : false - - Icon { - anchors.centerIn: parent - - icon: (level !== -1 && level != null) - ? (betterIcon? Presence.getBetterPresenceLevelIconName(level) : Presence.getPresenceLevelIconName(level)) - : '' - iconSize: parent.height > parent.width - ? parent.width - : parent.height - } + property var level: null + property bool betterIcon : false + property var timestamp + property string text: { + if( level === 0) + //: 'Online⁣': Presence text + return qsTr('presenceOnline'); + else if(visible){ + var d = new Date(timestamp) + var yesterday = new Date() + yesterday.setDate(yesterday.getDate() - 1) + if (Utils.equalDate(d, new Date())) + //: 'Online today at %1' : Presence text for today (%1 is the hour) + return qsTr('presenceLastSeenToday').arg(d.toLocaleString(App.locale, 'HH:mm')) + else if(Utils.equalDate(d,yesterday)) + //: 'Online yesterday at %1' : Presence text for yesterday (%1 is the hour) + return qsTr('presenceLastSeenYesterday').arg(d.toLocaleString(App.locale, 'HH:mm')) + else + //: 'Online on %1' : Presence text for latter days (%1 is a date) + return qsTr('presenceLastSeen').arg(d.toLocaleDateString(App.locale)) + }else + return Presence.getPresenceStatusAsString(level) + } + visible: icon.icon != '' + + Icon { + id: icon + anchors.centerIn: parent + + icon: (level !== -1 && level != null && level !== 3)// Hide Offline status as it is not fully supported + ? (betterIcon? Presence.getBetterPresenceLevelIconName(level) : Presence.getPresenceLevelIconName(level)) + : '' + iconSize: parent.height > parent.width + ? parent.width + : parent.height + } } diff --git a/linphone-app/ui/views/App/Main/ContactEdit.qml b/linphone-app/ui/views/App/Main/ContactEdit.qml index 702405aa3..100fe3971 100644 --- a/linphone-app/ui/views/App/Main/ContactEdit.qml +++ b/linphone-app/ui/views/App/Main/ContactEdit.qml @@ -113,6 +113,7 @@ ColumnLayout { image: _vcard ? _vcard.avatar : '' username: _vcard ? _vcard.username : '' presenceLevel: _contact ? _contact.presenceLevel : -1 + presenceTimestamp: _contact && _contact.presenceTimestamp visible: (isLoaded() && !parent.hovered) || !_edition } } diff --git a/linphone-app/ui/views/App/Main/Contacts.qml b/linphone-app/ui/views/App/Main/Contacts.qml index c3665bc5d..75bb237d9 100644 --- a/linphone-app/ui/views/App/Main/Contacts.qml +++ b/linphone-app/ui/views/App/Main/Contacts.qml @@ -108,9 +108,11 @@ ColumnLayout { spacing: ContactsStyle.contact.spacing PresenceLevel { + id: presenceLevel Layout.preferredHeight: ContactsStyle.contact.presenceLevelSize Layout.preferredWidth: ContactsStyle.contact.presenceLevelSize level: $modelData.presenceLevel + timestamp: $modelData.presenceTimestamp } Text { @@ -118,7 +120,8 @@ ColumnLayout { color: ContactsStyle.contact.presence.colorModel.color elide: Text.ElideRight font.pointSize: ContactsStyle.contact.presence.pointSize - text: Presence.getPresenceStatusAsString($modelData.presenceStatus) + text: presenceLevel.presenceText + visible: presenceLevel.visible } } } diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml index c28497cdd..b4adfac79 100644 --- a/linphone-app/ui/views/App/Main/Conversation.qml +++ b/linphone-app/ui/views/App/Main/Conversation.qml @@ -100,6 +100,7 @@ ColumnLayout { image: Logic.getAvatar() presenceLevel: chatRoomModel && chatRoomModel.presenceStatus + presenceTimestamp: chatRoomModel && chatRoomModel.presenceTimestamp //username: Logic.getUsername() username: chatRoomModel?chatRoomModel.username:( conversation._sipAddressObserver ? UtilsCpp.getDisplayName(conversation._sipAddressObserver.peerAddress) : '') @@ -158,12 +159,14 @@ ColumnLayout { titleText: avatar.username titleClickable: chatRoomModel && chatRoomModel.isMeAdmin && !chatRoomModel.isOneToOne subtitleText: if(chatRoomModel) { - if(chatRoomModel.groupEnabled) { - return chatRoomModel.participants.displayNamesToString; - }else if(chatRoomModel.isSecure()) { - return chatRoomModel.participants.addressesToString; - }else - return SipAddressesModel.cleanSipAddress(chatRoomModel.sipAddress) + if(chatRoomModel.groupEnabled) { + return chatRoomModel.participants.displayNamesToString; + }else if(avatar.hasPresence) { + return avatar.presenceText + }else if(chatRoomModel.isSecure()) + return chatRoomModel.participants.addressesToString; + else + return SipAddressesModel.cleanSipAddress(chatRoomModel.sipAddress) }else return '' diff --git a/linphone-app/ui/views/App/Main/HistoryView.qml b/linphone-app/ui/views/App/Main/HistoryView.qml index 294030e2d..239793a35 100644 --- a/linphone-app/ui/views/App/Main/HistoryView.qml +++ b/linphone-app/ui/views/App/Main/HistoryView.qml @@ -57,6 +57,9 @@ ColumnLayout { presenceLevel: historyView._sipAddressObserver?Presence.getPresenceLevel( historyView._sipAddressObserver.presenceStatus ):null + presenceTimestamp: historyView._sipAddressObserver?Presence.getPresenceTimestamp( + historyView._sipAddressObserver.presenceStatus + ):null username: historyView.entry && historyView.entry.wasConference ? historyView.entry.title diff --git a/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js b/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js index acc619ad3..94474f1b5 100644 --- a/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js +++ b/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js @@ -41,6 +41,7 @@ function initForm (account) { sipAddress.text = config.sipAddress serverAddress.text = config.serverAddress registrationDuration.text = config.registrationDuration + publishDuration.text = config.publishDuration var currentTransport = config.transport.toUpperCase() transport.currentIndex = Number( @@ -83,6 +84,7 @@ function validAccount (account) { sipAddress: sipAddress.text, serverAddress: serverAddress.text, registrationDuration: registrationDuration.text, + publishDuration: publishDuration.text, transport: transport.currentText, route: route.text, conferenceUri: conferenceUri.text, diff --git a/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml b/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml index 069a969bf..dace6beee 100644 --- a/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml +++ b/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml @@ -232,6 +232,15 @@ DialogPlus { onClicked: checked = !checked } } + FormGroup { + label: qsTr('publishDurationLabel') + + NumericField { + id: publishDuration + Keys.onEnterPressed: route.forceActiveFocus() + Keys.onReturnPressed: route.forceActiveFocus() + } + } } FormLine { diff --git a/linphone-sdk b/linphone-sdk index e8ec1a4b7..2eadea705 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit e8ec1a4b79a5082ee9f98157199ccaa14f89594e +Subproject commit 2eadea70597365f32e66cceb54d949c8c4a1b94f