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