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