Compare commits

..

10 commits

Author SHA1 Message Date
Gaelle Braud
ca4380bfd0 hide notification content setting 2026-02-02 13:58:36 +01:00
Gaelle Braud
8df5fb833c check if safe connection is being destroyed before trying lock
Add apply button and success/error toast for managing chatroom participants

debug logs
2026-02-02 08:55:57 +01:00
Gaelle Braud
d9b879fac7 enable native ringing if ringtone is empty 2026-01-30 11:42:26 +01:00
Gaelle Braud
507bee2946 fix hide spinner in chat messages list when model reset 2026-01-29 09:29:50 +01:00
Gaelle Braud
d4e657adff fix linux packaging (CMAKE_OPTIONS was overriding options set in gitlab CI variables) 2026-01-28 17:42:59 +01:00
Gaelle Braud
7685462960 add debug in crashing connect for debug 2026-01-28 15:21:05 +01:00
Gaelle Braud
fe6e3f4e25 activate bugsplat on linux/macos nightly packages 2026-01-28 12:39:19 +01:00
Gaelle Braud
4916c0ad6e do not clone conference info object on model creation as it blocks the creation
fix typo in cancelCreation calling
2026-01-28 12:14:02 +01:00
Gaelle Braud
9214cb5fed fix typo leading to build error 2026-01-27 17:45:39 +01:00
Gaelle Braud
f06f56bead update SDK to 5.5.0 2026-01-27 17:32:53 +01:00
23 changed files with 1524 additions and 1157 deletions

View file

@ -102,7 +102,7 @@ macosx-ninja-package:
- if: $PACKAGE_MACOSX - if: $PACKAGE_MACOSX
- if: $DEPLOY_MACOSX - if: $DEPLOY_MACOSX
variables: variables:
CMAKE_OPTIONS: -DPython3_ROOT_DIR=/opt/bc/pip-packages/ -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_G729=ON CMAKE_OPTIONS: -DPython3_ROOT_DIR=/opt/bc/pip-packages/ -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_G729=ON -DENABLE_BUGSPLAT_SYMBOLS_UPLOAD=ON -DBUGSPLAT_CLIENT_ID=$BUGSPLAT_CLIENT_ID -DBUGSPLAT_CLIENT_SECRET=$BUGSPLAT_CLIENT_SECRET -DBUGSPLAT_DATABASE=$BUGSPLAT_DATABASE
RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER
extends: macosx-ninja extends: macosx-ninja
script: script:

View file

@ -223,10 +223,22 @@ void ChatCore::setSelf(const QSharedPointer<ChatCore> &me) {
mChatModelConnection->makeConnectToModel( mChatModelConnection->makeConnectToModel(
&ChatModel::chatMessagesReceived, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, &ChatModel::chatMessagesReceived, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::list<std::shared_ptr<linphone::EventLog>> &eventsLog) { const std::list<std::shared_ptr<linphone::EventLog>> &eventsLog) {
if (!mChatModel) {
lWarning() << log().arg("Chat model is null !");
return;
} else if (!mChatModelConnection) {
lWarning() << log().arg("Connection between Core and Model is null !");
return;
}
if (mChatModel->getMonitor() != chatRoom) return; if (mChatModel->getMonitor() != chatRoom) return;
lDebug() << log().arg("CHAT MESSAGE RECEIVED IN CHATROOM") << this << mChatModel->getTitle(); lInfo() << log().arg("Chat message received in chatroom") << this << mChatModel->getTitle();
lInfo() << log().arg("Connection =") << mChatModelConnection.get();
QList<QSharedPointer<EventLogCore>> list; QList<QSharedPointer<EventLogCore>> list;
for (auto &e : eventsLog) { for (auto &e : eventsLog) {
if (!e) {
lWarning() << log().arg("Event log is null, continue");
continue;
}
auto event = EventLogCore::create(e, chatRoom); auto event = EventLogCore::create(e, chatRoom);
list.push_back(event); list.push_back(event);
} }
@ -377,6 +389,15 @@ void ChatCore::setSelf(const QSharedPointer<ChatCore> &me) {
setMeAdmin(meAdmin); setMeAdmin(meAdmin);
}); });
}); });
mChatModelConnection->makeConnectToModel(
&ChatModel::participantAddressesChanged,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, bool success) {
if (!success) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants] { setParticipants(participants); });
}
mChatModelConnection->invokeToCore([this, success] { emit participantAddressesChanged(success); });
});
mChatModelConnection->makeConnectToCore(&ChatCore::lRemoveParticipantAtIndex, [this](int index) { mChatModelConnection->makeConnectToCore(&ChatCore::lRemoveParticipantAtIndex, [this](int index) {
mChatModelConnection->invokeToModel([this, index]() { mChatModel->removeParticipantAtIndex(index); }); mChatModelConnection->invokeToModel([this, index]() { mChatModel->removeParticipantAtIndex(index); });
}); });

View file

@ -175,6 +175,7 @@ signals:
void fileListChanged(); void fileListChanged();
void isSecuredChanged(); void isSecuredChanged();
void conferenceJoined(); void conferenceJoined();
void participantAddressesChanged(bool success);
void lDeleteMessage(ChatMessageGui *message); void lDeleteMessage(ChatMessageGui *message);
void lDelete(); void lDelete();

View file

@ -366,7 +366,8 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
txt = tr("new_conference_invitation"); txt = tr("new_conference_invitation");
}; };
if (messages.size() == 1) { // Display only sender on mono message. if (messages.size() == 1 &&
SettingsModel::getInstance()->getDisplayNotificationContent()) { // Display only sender on mono message.
if (message->isRead()) return; if (message->isRead()) return;
getMessage(message); getMessage(message);
if (txt.isEmpty()) { // Do not notify message without content if (txt.isEmpty()) { // Do not notify message without content
@ -382,6 +383,9 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
} }
} }
if (unreadCount == 0) return; if (unreadCount == 0) return;
else if (unreadCount == 1)
//: 'New message received!' Notification that warn the user of a new message.
txt = tr("new_chat_room_message");
if (unreadCount > 1) if (unreadCount > 1)
//: 'New messages received!' Notification that warn the user of new messages. //: 'New messages received!' Notification that warn the user of new messages.
txt = tr("new_chat_room_messages"); txt = tr("new_chat_room_messages");

View file

@ -275,71 +275,73 @@ QString Paths::getLogsDirPath() {
QString Paths::getAppRootCaFilePath() { QString Paths::getAppRootCaFilePath() {
// Hardcoded because it comes from linphone and is not customizable. // Hardcoded because it comes from linphone and is not customizable.
return getReadableFilePath(getAppPackageDataDirPath() + "/linphone/rootca.pem"); return getReadableFilePath(getAppPackageDataDirPath() + "/linphone/rootca.pem");
QString Paths::getCrashpadDirPath() { }
QString Paths::getCrashpadDirPath() {
#ifdef HAVE_CRASH_HANDLER #ifdef HAVE_CRASH_HANDLER
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathCrashpad); Constants::PathCrashpad);
#else #else
return ""; return "";
#endif #endif
} }
QString Paths::getMetricsDirPath() { QString Paths::getMetricsDirPath() {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathMetrics); Constants::PathMetrics);
} }
QString Paths::getMessageHistoryFilePath() { QString Paths::getMessageHistoryFilePath() {
return getReadableFilePath( return getReadableFilePath(
getAppMessageHistoryFilePath()); // No need to ensure that the file exists as this DB is deprecated getAppMessageHistoryFilePath()); // No need to ensure that the file exists as this DB is deprecated
} }
QString Paths::getPackageMsPluginsDirPath() { QString Paths::getPackageMsPluginsDirPath() {
return getReadableDirPath(getAppPackageMsPluginsDirPath()); return getReadableDirPath(getAppPackageMsPluginsDirPath());
} }
QString Paths::getPackagePluginsAppDirPath() { QString Paths::getPackagePluginsAppDirPath() {
return getReadableDirPath(getAppPackagePluginsDirPath() + Constants::PathPluginsApp); return getReadableDirPath(getAppPackagePluginsDirPath() + Constants::PathPluginsApp);
} }
QString Paths::getPackageTopDirPath() { QString Paths::getPackageTopDirPath() {
return getReadableDirPath(getAppPackageDataDirPath()); return getReadableDirPath(getAppPackageDataDirPath());
} }
QString Paths::getPluginsAppDirPath() { QString Paths::getPluginsAppDirPath() {
return getWritableDirPath(getAppPluginsDirPath() + Constants::PathPluginsApp); return getWritableDirPath(getAppPluginsDirPath() + Constants::PathPluginsApp);
} }
QStringList Paths::getPluginsAppFolders() { QStringList Paths::getPluginsAppFolders() {
QStringList pluginPaths; QStringList pluginPaths;
pluginPaths << Paths::getPluginsAppDirPath(); pluginPaths << Paths::getPluginsAppDirPath();
pluginPaths << Paths::getPackagePluginsAppDirPath(); pluginPaths << Paths::getPackagePluginsAppDirPath();
return pluginPaths; return pluginPaths;
} }
QString Paths::getToolsDirPath() { QString Paths::getToolsDirPath() {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathTools); Constants::PathTools);
} }
QString Paths::getUserCertificatesDirPath() { QString Paths::getUserCertificatesDirPath() {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathUserCertificates); Constants::PathUserCertificates);
} }
QString Paths::getZrtpSecretsFilePath() { QString Paths::getZrtpSecretsFilePath() {
return getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + return getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +
Constants::PathZrtpSecrets); Constants::PathZrtpSecrets);
} }
QString Paths::getCrashpadHandlerFilePath() { QString Paths::getCrashpadHandlerFilePath() {
#ifdef HAVE_CRASH_HANDLER #ifdef HAVE_CRASH_HANDLER
return getAppBinDirPath() + Constants::PathCrashpadHandler; return getAppBinDirPath() + Constants::PathCrashpadHandler;
#else #else
return ""; return "";
#endif #endif
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void Paths::migrate() { void Paths::migrate() {
} }

View file

@ -92,6 +92,8 @@ void MagicSearchList::setSelf(const QSharedPointer<MagicSearchList> &me) {
mModelConnection->makeConnectToModel( mModelConnection->makeConnectToModel(
&MagicSearchModel::searchResultsReceived, &MagicSearchModel::searchResultsReceived,
[this](const std::list<std::shared_ptr<linphone::SearchResult>> &results) { [this](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {
lInfo() << log().arg("Search result received : Safe Connection =") << mModelConnection.get();
lInfo() << log().arg("this =") << this;
auto *contacts = new QList<QSharedPointer<FriendCore>>(); auto *contacts = new QList<QSharedPointer<FriendCore>>();
auto ldapContacts = ToolModel::getLdapFriendList(); auto ldapContacts = ToolModel::getLdapFriendList();
auto core = CoreModel::getInstance()->getCore(); auto core = CoreModel::getInstance()->getCore();

View file

@ -50,6 +50,7 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
mVideoEnabled = settingsModel->getVideoEnabled(); mVideoEnabled = settingsModel->getVideoEnabled();
mEchoCancellationEnabled = settingsModel->getEchoCancellationEnabled(); mEchoCancellationEnabled = settingsModel->getEchoCancellationEnabled();
mAutoDownloadReceivedFiles = settingsModel->getAutoDownloadReceivedFiles(); mAutoDownloadReceivedFiles = settingsModel->getAutoDownloadReceivedFiles();
mDisplayNotificationContent = settingsModel->getDisplayNotificationContent();
mAutomaticallyRecordCallsEnabled = settingsModel->getAutomaticallyRecordCallsEnabled(); mAutomaticallyRecordCallsEnabled = settingsModel->getAutomaticallyRecordCallsEnabled();
mRingtonePath = settingsModel->getRingtone(); mRingtonePath = settingsModel->getRingtone();
QFileInfo ringtone(mRingtonePath); QFileInfo ringtone(mRingtonePath);
@ -164,6 +165,7 @@ SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
mVideoEnabled = settingsCore.mVideoEnabled; mVideoEnabled = settingsCore.mVideoEnabled;
mEchoCancellationEnabled = settingsCore.mEchoCancellationEnabled; mEchoCancellationEnabled = settingsCore.mEchoCancellationEnabled;
mAutoDownloadReceivedFiles = settingsCore.mAutoDownloadReceivedFiles; mAutoDownloadReceivedFiles = settingsCore.mAutoDownloadReceivedFiles;
mDisplayNotificationContent = settingsCore.mDisplayNotificationContent;
mAutomaticallyRecordCallsEnabled = settingsCore.mAutomaticallyRecordCallsEnabled; mAutomaticallyRecordCallsEnabled = settingsCore.mAutomaticallyRecordCallsEnabled;
// Audio // Audio
@ -250,6 +252,7 @@ void SettingsCore::reloadSettings() {
setVideoEnabled(settingsModel->getVideoEnabled()); setVideoEnabled(settingsModel->getVideoEnabled());
setEchoCancellationEnabled(settingsModel->getEchoCancellationEnabled()); setEchoCancellationEnabled(settingsModel->getEchoCancellationEnabled());
setAutoDownloadReceivedFiles(settingsModel->getAutoDownloadReceivedFiles()); setAutoDownloadReceivedFiles(settingsModel->getAutoDownloadReceivedFiles());
setDisplayNotificationContent(settingsModel->getDisplayNotificationContent());
setAutomaticallyRecordCallsEnabled(settingsModel->getAutomaticallyRecordCallsEnabled()); setAutomaticallyRecordCallsEnabled(settingsModel->getAutomaticallyRecordCallsEnabled());
setRingtone(settingsModel->getRingtone()); setRingtone(settingsModel->getRingtone());
@ -400,6 +403,12 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
mSettingsModelConnection->invokeToCore([this, enabled]() { setAutoDownloadReceivedFiles(enabled); }); mSettingsModelConnection->invokeToCore([this, enabled]() { setAutoDownloadReceivedFiles(enabled); });
}); });
// Auto download incoming files
mSettingsModelConnection->makeConnectToModel(
&SettingsModel::displayNotificationContentChanged, [this](const bool enabled) {
mSettingsModelConnection->invokeToCore([this, enabled]() { setDisplayNotificationContent(enabled); });
});
// Auto recording // Auto recording
mSettingsModelConnection->makeConnectToModel( mSettingsModelConnection->makeConnectToModel(
&SettingsModel::automaticallyRecordCallsEnabledChanged, [this](const bool enabled) { &SettingsModel::automaticallyRecordCallsEnabledChanged, [this](const bool enabled) {
@ -640,6 +649,7 @@ void SettingsCore::reset(const SettingsCore &settingsCore) {
setAutomaticallyRecordCallsEnabled(settingsCore.mAutomaticallyRecordCallsEnabled); setAutomaticallyRecordCallsEnabled(settingsCore.mAutomaticallyRecordCallsEnabled);
setAutoDownloadReceivedFiles(settingsCore.mAutoDownloadReceivedFiles); setAutoDownloadReceivedFiles(settingsCore.mAutoDownloadReceivedFiles);
setDisplayNotificationContent(settingsCore.mDisplayNotificationContent);
// Audio // Audio
setCaptureDevices(settingsCore.mCaptureDevices); setCaptureDevices(settingsCore.mCaptureDevices);
setPlaybackDevices(settingsCore.mPlaybackDevices); setPlaybackDevices(settingsCore.mPlaybackDevices);
@ -795,6 +805,14 @@ void SettingsCore::setAutoDownloadReceivedFiles(bool enabled) {
} }
} }
void SettingsCore::setDisplayNotificationContent(bool enabled) {
if (mDisplayNotificationContent != enabled) {
mDisplayNotificationContent = enabled;
emit displayNotificationContentChanged();
setIsSaved(false);
}
}
void SettingsCore::setAutomaticallyRecordCallsEnabled(bool enabled) { void SettingsCore::setAutomaticallyRecordCallsEnabled(bool enabled) {
if (mAutomaticallyRecordCallsEnabled != enabled) { if (mAutomaticallyRecordCallsEnabled != enabled) {
mAutomaticallyRecordCallsEnabled = enabled; mAutomaticallyRecordCallsEnabled = enabled;
@ -1241,6 +1259,8 @@ void SettingsCore::writeIntoModel(std::shared_ptr<SettingsModel> model) const {
// Chat // Chat
model->setAutoDownloadReceivedFiles(mAutoDownloadReceivedFiles); model->setAutoDownloadReceivedFiles(mAutoDownloadReceivedFiles);
model->setDisplayNotificationContent(mDisplayNotificationContent);
// Audio // Audio
model->setRingerDevice(mRingerDevice); model->setRingerDevice(mRingerDevice);
model->setCaptureDevice(mCaptureDevice); model->setCaptureDevice(mCaptureDevice);
@ -1316,6 +1336,7 @@ void SettingsCore::writeFromModel(const std::shared_ptr<SettingsModel> &model) {
// Chat // Chat
mAutoDownloadReceivedFiles = model->getAutoDownloadReceivedFiles(); mAutoDownloadReceivedFiles = model->getAutoDownloadReceivedFiles();
mDisplayNotificationContent = model->getDisplayNotificationContent();
// Audio // Audio
mCaptureDevices = model->getCaptureDevices(); mCaptureDevices = model->getCaptureDevices();

View file

@ -42,6 +42,8 @@ public:
echoCancellationEnabledChanged) echoCancellationEnabledChanged)
Q_PROPERTY(bool autoDownloadReceivedFiles READ getAutoDownloadReceivedFiles WRITE setAutoDownloadReceivedFiles Q_PROPERTY(bool autoDownloadReceivedFiles READ getAutoDownloadReceivedFiles WRITE setAutoDownloadReceivedFiles
NOTIFY autoDownloadReceivedFilesChanged) NOTIFY autoDownloadReceivedFilesChanged)
Q_PROPERTY(bool displayNotificationContent READ getDisplayNotificationContent WRITE setDisplayNotificationContent
NOTIFY displayNotificationContentChanged)
Q_PROPERTY( Q_PROPERTY(
int echoCancellationCalibration READ getEchoCancellationCalibration NOTIFY echoCancellationCalibrationChanged) int echoCancellationCalibration READ getEchoCancellationCalibration NOTIFY echoCancellationCalibrationChanged)
Q_PROPERTY(bool automaticallyRecordCallsEnabled READ getAutomaticallyRecordCallsEnabled WRITE Q_PROPERTY(bool automaticallyRecordCallsEnabled READ getAutomaticallyRecordCallsEnabled WRITE
@ -93,18 +95,17 @@ public:
Q_PROPERTY(bool fullLogsEnabled READ getFullLogsEnabled WRITE setFullLogsEnabled NOTIFY fullLogsEnabledChanged) Q_PROPERTY(bool fullLogsEnabled READ getFullLogsEnabled WRITE setFullLogsEnabled NOTIFY fullLogsEnabledChanged)
Q_PROPERTY(bool crashReporterEnabled READ getCrashReporterEnabled WRITE setCrashReporterEnabled NOTIFY Q_PROPERTY(bool crashReporterEnabled READ getCrashReporterEnabled WRITE setCrashReporterEnabled NOTIFY
crashReporterEnabledChanged) crashReporterEnabledChanged)
Q_PROPERTY(QString logsEmail READ getLogsEmail) Q_PROPERTY(QString logsEmail READ getLogsEmail) Q_PROPERTY(QString logsFolder READ getLogsFolder)
Q_PROPERTY(QString logsFolder READ getLogsFolder) Q_PROPERTY(QString ringtoneName READ getRingtoneFileName NOTIFY ringtoneChanged)
Q_PROPERTY(QString ringtoneName READ getRingtoneFileName NOTIFY ringtoneChanged) Q_PROPERTY(QString ringtonePath READ getRingtonePath WRITE setRingtone NOTIFY ringtoneChanged)
Q_PROPERTY(QString ringtonePath READ getRingtonePath WRITE setRingtone NOTIFY ringtoneChanged) Q_PROPERTY(QString ringtoneFolder MEMBER mRingtoneFolder NOTIFY ringtoneChanged)
Q_PROPERTY(QString ringtoneFolder MEMBER mRingtoneFolder NOTIFY ringtoneChanged) Q_PROPERTY(bool dnd READ dndEnabled WRITE lEnableDnd NOTIFY dndChanged)
Q_PROPERTY(bool dnd READ dndEnabled WRITE lEnableDnd NOTIFY dndChanged) Q_PROPERTY(bool isSaved READ isSaved WRITE setIsSaved NOTIFY isSavedChanged)
Q_PROPERTY(bool isSaved READ isSaved WRITE setIsSaved NOTIFY isSavedChanged)
Q_PROPERTY( Q_PROPERTY(bool showAccountDevices READ showAccountDevices WRITE setShowAccountDevices
bool showAccountDevices READ showAccountDevices WRITE setShowAccountDevices NOTIFY showAccountDevicesChanged) NOTIFY showAccountDevicesChanged)
static QSharedPointer<SettingsCore> create(); static QSharedPointer<SettingsCore> create();
SettingsCore(QObject *parent = Q_NULLPTR); SettingsCore(QObject *parent = Q_NULLPTR);
SettingsCore(const SettingsCore &settingsCore); SettingsCore(const SettingsCore &settingsCore);
virtual ~SettingsCore(); virtual ~SettingsCore();
@ -152,6 +153,11 @@ public:
} }
void setAutoDownloadReceivedFiles(bool enabled); void setAutoDownloadReceivedFiles(bool enabled);
bool getDisplayNotificationContent() {
return mDisplayNotificationContent;
}
void setDisplayNotificationContent(bool enabled);
bool getAutomaticallyRecordCallsEnabled() { bool getAutomaticallyRecordCallsEnabled() {
return mAutomaticallyRecordCallsEnabled; return mAutomaticallyRecordCallsEnabled;
} }
@ -309,6 +315,7 @@ signals:
void echoCancellationEnabledChanged(); void echoCancellationEnabledChanged();
void autoDownloadReceivedFilesChanged(); void autoDownloadReceivedFilesChanged();
void displayNotificationContentChanged();
void automaticallyRecordCallsEnabledChanged(); void automaticallyRecordCallsEnabledChanged();
@ -406,6 +413,7 @@ private:
bool mVideoEnabled; bool mVideoEnabled;
bool mEchoCancellationEnabled; bool mEchoCancellationEnabled;
bool mAutoDownloadReceivedFiles; bool mAutoDownloadReceivedFiles;
bool mDisplayNotificationContent;
bool mAutomaticallyRecordCallsEnabled; bool mAutomaticallyRecordCallsEnabled;
// Audio // Audio

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -237,17 +237,23 @@ void ChatModel::toggleParticipantAdminStatusAtIndex(int index) const {
mMonitor->setParticipantAdminStatus(participant, !participant->isAdmin()); mMonitor->setParticipantAdminStatus(participant, !participant->isAdmin());
} }
void ChatModel::setParticipantAddresses(const QStringList &addresses) const { void ChatModel::setParticipantAddresses(const QStringList &addresses) {
QSet<QString> s{addresses.cbegin(), addresses.cend()}; QSet<QString> s{addresses.cbegin(), addresses.cend()};
bool soFarSoGood = true;
for (auto p : mMonitor->getParticipants()) { for (auto p : mMonitor->getParticipants()) {
auto address = Utils::coreStringToAppString(p->getAddress()->asStringUriOnly()); auto address = Utils::coreStringToAppString(p->getAddress()->asStringUriOnly());
if (s.contains(address)) s.remove(address); if (s.contains(address)) s.remove(address);
else mMonitor->removeParticipant(p); else {
mMonitor->removeParticipants({p});
}
} }
for (const auto &a : s) { for (const auto &a : s) {
auto address = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(a)); auto address = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(a));
if (address) mMonitor->addParticipant(address); if (address) {
soFarSoGood &= mMonitor->addParticipants({address});
}
} }
emit participantAddressesChanged(mMonitor, soFarSoGood);
} }
//---------------------------------------------------------------// //---------------------------------------------------------------//

View file

@ -84,7 +84,7 @@ public:
void setEphemeralLifetime(int time); void setEphemeralLifetime(int time);
void setSubject(QString subject) const; void setSubject(QString subject) const;
void removeParticipantAtIndex(int index) const; void removeParticipantAtIndex(int index) const;
void setParticipantAddresses(const QStringList &addresses) const; void setParticipantAddresses(const QStringList &addresses);
void toggleParticipantAdminStatusAtIndex(int index) const; void toggleParticipantAdminStatusAtIndex(int index) const;
signals: signals:
@ -94,6 +94,7 @@ signals:
void mutedChanged(bool muted); void mutedChanged(bool muted);
void ephemeralEnableChanged(bool enable); void ephemeralEnableChanged(bool enable);
void ephemeralLifetimeChanged(int time); void ephemeralLifetimeChanged(int time);
void participantAddressesChanged(const std::shared_ptr<linphone::ChatRoom> &chatRoom, bool success);
private: private:
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT

View file

@ -37,6 +37,7 @@ ChatMessageModel::ChatMessageModel(const std::shared_ptr<linphone::ChatMessage>
mEphemeralTimer.setInterval(60); mEphemeralTimer.setInterval(60);
mEphemeralTimer.setSingleShot(false); mEphemeralTimer.setSingleShot(false);
if (mMonitor->getEphemeralExpireTime() != 0) mEphemeralTimer.start(); if (mMonitor->getEphemeralExpireTime() != 0) mEphemeralTimer.start();
mChatRoom = mMonitor->getChatRoom();
connect(&mEphemeralTimer, &QTimer::timeout, this, connect(&mEphemeralTimer, &QTimer::timeout, this,
[this] { emit ephemeralMessageTimeUpdated(mMonitor, mMonitor->getEphemeralExpireTime()); }); [this] { emit ephemeralMessageTimeUpdated(mMonitor, mMonitor->getEphemeralExpireTime()); });
connect(this, &ChatMessageModel::ephemeralMessageTimerStarted, this, [this] { mEphemeralTimer.start(); }); connect(this, &ChatMessageModel::ephemeralMessageTimerStarted, this, [this] { mEphemeralTimer.start(); });
@ -47,7 +48,8 @@ ChatMessageModel::ChatMessageModel(const std::shared_ptr<linphone::ChatMessage>
// We need to force this signal sending because there is no callback to know when a message has been read // We need to force this signal sending because there is no callback to know when a message has been read
connect(CoreModel::getInstance().get(), &CoreModel::chatRoomRead, this, connect(CoreModel::getInstance().get(), &CoreModel::chatRoomRead, this,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom) { [this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
if (chatRoom == mMonitor->getChatRoom()) { if (!mMonitor || !mChatRoom.lock()) return;
if (chatRoom == mChatRoom.lock()) {
if (mMonitor->isRead()) { if (mMonitor->isRead()) {
emit messageRead(mMonitor); emit messageRead(mMonitor);
} }

View file

@ -33,7 +33,7 @@ DEFINE_ABSTRACT_OBJECT(ConferenceInfoModel)
ConferenceInfoModel::ConferenceInfoModel(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo, ConferenceInfoModel::ConferenceInfoModel(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo,
QObject *parent) QObject *parent)
// TODO : remove cloning when a fix will be done in SDK (#SDK-1001 ticket) // TODO : remove cloning when a fix will be done in SDK (#SDK-1001 ticket)
: mConferenceInfo(conferenceInfo->clone()) { : mConferenceInfo(conferenceInfo) {
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
} }

View file

@ -521,6 +521,17 @@ void SettingsModel::setAutoDownloadReceivedFiles(bool status) {
emit autoDownloadReceivedFilesChanged(status); emit autoDownloadReceivedFilesChanged(status);
} }
bool SettingsModel::getDisplayNotificationContent() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return !!mConfig->getInt(UiSection, "display_notification_content", 1);
}
void SettingsModel::setDisplayNotificationContent(bool display) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mConfig->setInt(UiSection, "display_notification_content", display);
emit displayNotificationContentChanged(display);
}
bool SettingsModel::getEchoCancellationEnabled() const { bool SettingsModel::getEchoCancellationEnabled() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return CoreModel::getInstance()->getCore()->echoCancellationEnabled(); return CoreModel::getInstance()->getCore()->echoCancellationEnabled();

View file

@ -66,6 +66,9 @@ public:
void setAutoDownloadReceivedFiles(bool enabled); void setAutoDownloadReceivedFiles(bool enabled);
bool getAutoDownloadReceivedFiles() const; bool getAutoDownloadReceivedFiles() const;
void setDisplayNotificationContent(bool display);
bool getDisplayNotificationContent() const;
// Audio. -------------------------------------------------------------------- // Audio. --------------------------------------------------------------------
bool getIsInCall() const; bool getIsInCall() const;
@ -287,6 +290,7 @@ signals:
// Messages. -------------------------------------------------------------------- // Messages. --------------------------------------------------------------------
void autoDownloadReceivedFilesChanged(bool enabled); void autoDownloadReceivedFilesChanged(bool enabled);
void displayNotificationContentChanged(bool display);
private: private:
void notifyConfigReady(); void notifyConfigReady();

View file

@ -66,7 +66,7 @@ template <class A, class B>
class SafeConnection : public QObject { class SafeConnection : public QObject {
// Use create functions. // Use create functions.
protected: protected:
SafeConnection(const QSharedPointer<A> &a, std::shared_ptr<B> b) SafeConnection(QSharedPointer<A> a, std::shared_ptr<B> b)
: mCore(a), mModel(b), mCoreObject(a.get()), mModelObject(b.get()) { : mCore(a), mModel(b), mCoreObject(a.get()), mModelObject(b.get()) {
} }
SafeConnection(QSharedPointer<A> a, QSharedPointer<B> b) SafeConnection(QSharedPointer<A> a, QSharedPointer<B> b)
@ -150,6 +150,7 @@ public:
} }
bool tryLock() { bool tryLock() {
if (!this) return false;
mLocker.lock(); mLocker.lock();
auto coreLocked = mCore.lock(); auto coreLocked = mCore.lock();
auto modelLocked = mModel.lock(); auto modelLocked = mModel.lock();

View file

@ -87,6 +87,7 @@ ListView {
onModelAboutToBeReset: { onModelAboutToBeReset: {
loading = true loading = true
} }
onModelReset: loading = false
onModelUpdated: { onModelUpdated: {
loading = false loading = false
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex()

View file

@ -22,6 +22,22 @@ Rectangle {
height: participantAddColumn.implicitHeight height: participantAddColumn.implicitHeight
signal done() signal done()
Connections {
enabled: chatGui !== null
target: chatGui.core
function onParticipantAddressesChanged(success) {
if (!success) UtilsCpp.showInformationPopup(qsTr("info_popup_error_title"),
//: Error while setting participants !
qsTr("info_popup_manage_participant_error_message"), false)
else {
mainItem.done()
UtilsCpp.showInformationPopup(qsTr("info_popup_success_title"),
//: Participants updated
qsTr("info_popup_manage_participant_updated_message"), true)
}
}
}
ColumnLayout { ColumnLayout {
id: participantAddColumn id: participantAddColumn
anchors.fill: parent anchors.fill: parent
@ -36,7 +52,6 @@ Rectangle {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
onClicked: { onClicked: {
mainItem.chatGui.core.lSetParticipantsAddresses(manageParticipantsLayout.selectedParticipants)
mainItem.done() mainItem.done()
} }
} }
@ -47,6 +62,14 @@ Rectangle {
font: Typography.h4 font: Typography.h4
Layout.fillWidth: true Layout.fillWidth: true
} }
MediumButton {
id: manageParticipantsApplyButton
//: Apply
text: qsTr("apply_button_text")
onClicked: {
mainItem.chatGui.core.lSetParticipantsAddresses(manageParticipantsLayout.selectedParticipants)
}
}
} }
AddParticipantsForm { AddParticipantsForm {
id: manageParticipantsLayout id: manageParticipantsLayout

View file

@ -15,6 +15,13 @@ AbstractSettingsLayout {
subTitle: "", subTitle: "",
contentComponent: attachedFilesParamComp, contentComponent: attachedFilesParamComp,
// hideTopMargin: true // hideTopMargin: true
},
{
//: Notifications
title: qsTr("settings_chat_notifications_title"),
subTitle: "",
contentComponent: displayNotifParamComp,
// hideTopMargin: true
} }
] ]
@ -28,6 +35,24 @@ AbstractSettingsLayout {
propertyName: "autoDownloadReceivedFiles" propertyName: "autoDownloadReceivedFiles"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
Connections {
target: mainItem
function onSave() {
SettingsCpp.save()
}
}
}
}
Component {
id: displayNotifParamComp
SwitchSetting {
//: "Display notification content"
titleText: qsTr("settings_chat_display_notification_content_title")
//: "Display the content of the received message"
subTitleText: qsTr("settings_chat_display_notification_content_subtitle")
propertyName: "displayNotificationContent"
propertyOwner: SettingsCpp
Connections { Connections {
target: mainItem target: mainItem
function onSave() { function onSave() {

View file

@ -321,7 +321,7 @@ AbstractMainPage {
meetingSetup.conferenceInfoGui.core.save() meetingSetup.conferenceInfoGui.core.save()
//: "Création de la réunion en cours " //: "Création de la réunion en cours "
mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () { mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () {
meetingSetup.conferenceInfoGui.core.cancelCreation() meetingSetup.conferenceInfoGui.core.lCancelCreation()
}) })
} }
} }

@ -1 +1 @@
Subproject commit cbf282611d1d39dac1405a5a9388de0e8ee5b9e5 Subproject commit 2e6e6b927ce202f6948da02ea33081a52b89bf48