From 3edc55800aac0ffe00373db26c6a7c977e30ab0c Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Tue, 24 Jun 2025 11:47:01 +0200 Subject: [PATCH] Ephemeral settings --- Linphone/core/chat/ChatCore.cpp | 17 +++ Linphone/core/chat/ChatCore.hpp | 6 + Linphone/core/chat/message/EventLogCore.cpp | 19 +-- Linphone/core/chat/message/EventLogCore.hpp | 5 +- Linphone/core/chat/message/EventLogList.cpp | 7 + Linphone/data/image/ephemeral-settings.svg | 16 ++ Linphone/data/image/radio_off.svg | 11 ++ Linphone/data/image/radio_on.svg | 12 ++ Linphone/data/languages/de.ts | 130 ++++++++++------ Linphone/data/languages/en.ts | 137 +++++++++++------ Linphone/data/languages/fr_FR.ts | 138 +++++++++++------ Linphone/model/chat/ChatModel.cpp | 6 + Linphone/model/chat/ChatModel.hpp | 2 + Linphone/tool/Utils.cpp | 9 ++ Linphone/tool/Utils.hpp | 1 + Linphone/view/CMakeLists.txt | 3 + .../Display/Chat/ChatMessagesListView.qml | 17 +++ .../Control/Display/Chat/EphemeralEvent.qml | 34 +++++ .../view/Page/Form/Chat/SelectedChatView.qml | 35 +++-- .../Page/Layout/Chat/EphemeralSettings.qml | 142 ++++++++++++++++++ .../Layout/Chat/GroupConversationInfos.qml | 5 +- .../Page/Layout/Chat/ManageParticipants.qml | 2 - .../Layout/Chat/OneOneConversationInfos.qml | 8 +- Linphone/view/Style/AppIcons.qml | 3 + 24 files changed, 589 insertions(+), 176 deletions(-) create mode 100644 Linphone/data/image/ephemeral-settings.svg create mode 100644 Linphone/data/image/radio_off.svg create mode 100644 Linphone/data/image/radio_on.svg create mode 100644 Linphone/view/Control/Display/Chat/EphemeralEvent.qml create mode 100644 Linphone/view/Page/Layout/Chat/EphemeralSettings.qml diff --git a/Linphone/core/chat/ChatCore.cpp b/Linphone/core/chat/ChatCore.cpp index bda402b0..b35212e7 100644 --- a/Linphone/core/chat/ChatCore.cpp +++ b/Linphone/core/chat/ChatCore.cpp @@ -102,6 +102,7 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec connect(this, &ChatCore::eventsInserted, this, &ChatCore::lUpdateLastMessage); connect(this, &ChatCore::eventRemoved, this, &ChatCore::lUpdateLastMessage); mEphemeralEnabled = chatRoom->ephemeralEnabled(); + mEphemeralLifetime = chatRoom->ephemeralEnabled() ? chatRoom->getEphemeralLifetime() : 0; mIsMuted = chatRoom->getMuted(); mParticipants = buildParticipants(chatRoom); } @@ -285,6 +286,18 @@ void ChatCore::setSelf(QSharedPointer me) { }); }); + mChatModelConnection->makeConnectToCore(&ChatCore::lSetEphemeralLifetime, [this](int time) { + mChatModelConnection->invokeToModel([this, time]() { mChatModel->setEphemeralLifetime(time); }); + }); + mChatModelConnection->makeConnectToModel(&ChatModel::ephemeralLifetimeChanged, [this](int time) { + mChatModelConnection->invokeToCore([this, time]() { + if (mEphemeralLifetime != time) { + mEphemeralLifetime = time; + emit ephemeralLifetimeChanged(); + } + }); + }); + mChatModelConnection->makeConnectToCore(&ChatCore::lSetSubject, [this](QString subject) { mChatModelConnection->invokeToModel([this, subject]() { mChatModel->setSubject(subject); }); }); @@ -534,6 +547,10 @@ bool ChatCore::isEphemeralEnabled() const { return mEphemeralEnabled; } +int ChatCore::getEphemeralLifetime() const { + return mEphemeralLifetime; +} + void ChatCore::setMeAdmin(bool admin) { if (mMeAdmin != admin) { mMeAdmin = admin; diff --git a/Linphone/core/chat/ChatCore.hpp b/Linphone/core/chat/ChatCore.hpp index f7e22898..a12a2266 100644 --- a/Linphone/core/chat/ChatCore.hpp +++ b/Linphone/core/chat/ChatCore.hpp @@ -57,6 +57,8 @@ public: Q_PROPERTY(bool isReadOnly READ getIsReadOnly WRITE setIsReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(QString sendingText READ getSendingText WRITE setSendingText NOTIFY sendingTextChanged) Q_PROPERTY(bool ephemeralEnabled READ isEphemeralEnabled WRITE lEnableEphemeral NOTIFY ephemeralEnabledChanged) + Q_PROPERTY( + int ephemeralLifetime READ getEphemeralLifetime WRITE lSetEphemeralLifetime NOTIFY ephemeralLifetimeChanged) Q_PROPERTY(bool muted READ isMuted WRITE lSetMuted NOTIFY mutedChanged) Q_PROPERTY(bool meAdmin READ getMeAdmin WRITE setMeAdmin NOTIFY meAdminChanged) Q_PROPERTY(QVariantList participants READ getParticipantsGui NOTIFY participantsChanged) @@ -82,6 +84,7 @@ public: bool isMuted() const; bool isEphemeralEnabled() const; + int getEphemeralLifetime() const; QString getIdentifier() const; @@ -150,6 +153,7 @@ signals: void sendingTextChanged(QString text); void mutedChanged(); void ephemeralEnabledChanged(); + void ephemeralLifetimeChanged(); void meAdminChanged(); void participantsChanged(); @@ -167,6 +171,7 @@ signals: void lLeave(); void lSetMuted(bool muted); void lEnableEphemeral(bool enable); + void lSetEphemeralLifetime(int time); void lSetSubject(QString subject); void lRemoveParticipantAtIndex(int index); void lSetParticipantsAddresses(QStringList addresses); @@ -188,6 +193,7 @@ private: bool mIsEncrypted = false; bool mIsReadOnly = false; bool mEphemeralEnabled = false; + int mEphemeralLifetime = 0; bool mIsMuted = false; bool mMeAdmin = false; QList> mParticipants; diff --git a/Linphone/core/chat/message/EventLogCore.cpp b/Linphone/core/chat/message/EventLogCore.cpp index e88b0103..4f3749a4 100644 --- a/Linphone/core/chat/message/EventLogCore.cpp +++ b/Linphone/core/chat/message/EventLogCore.cpp @@ -82,6 +82,8 @@ void EventLogCore::computeEvent(const std::shared_ptr mustBeInLinphoneThread(getClassName()); mHandled = true; mImportant = false; + mEphemeralRelated = false; + auto participantAddress = eventLog->getParticipantAddress() ? eventLog->getParticipantAddress()->clone() : nullptr; switch (eventLog->getType()) { @@ -114,14 +116,18 @@ void EventLogCore::computeEvent(const std::shared_ptr break; } case linphone::EventLog::Type::ConferenceEphemeralMessageEnabled: + mEphemeralRelated = true; mEventDetails = tr("conference_ephemeral_message_enabled_event") - .arg(getEphemeralFormatedTime(eventLog->getEphemeralMessageLifetime())); + .arg(Utils::getEphemeralFormatedTime(eventLog->getEphemeralMessageLifetime())); break; case linphone::EventLog::Type::ConferenceEphemeralMessageLifetimeChanged: + mEphemeralRelated = true; + mHandled = eventLog->getEphemeralMessageLifetime() != 0; // Disabled is sent in case of 0. mEventDetails = tr("conference_ephemeral_message_lifetime_changed_event") - .arg(getEphemeralFormatedTime(eventLog->getEphemeralMessageLifetime())); + .arg(Utils::getEphemeralFormatedTime(eventLog->getEphemeralMessageLifetime())); break; case linphone::EventLog::Type::ConferenceEphemeralMessageDisabled: + mEphemeralRelated = true; mEventDetails = tr("conference_ephemeral_message_disabled_event"); mImportant = true; break; @@ -140,12 +146,3 @@ void EventLogCore::computeEvent(const std::shared_ptr mHandled = false; } } - -QString EventLogCore::getEphemeralFormatedTime(int selectedTime) { - if (selectedTime == 60) return tr("nMinute", "", 1).arg(1); - else if (selectedTime == 3600) return tr("nHour", "", 1).arg(1); - else if (selectedTime == 86400) return tr("nDay", "", 1).arg(1); - else if (selectedTime == 259200) return tr("nDay", "", 3).arg(3); - else if (selectedTime == 604800) return tr("nWeek", "", 1).arg(1); - else return tr("nSeconds", "", selectedTime).arg(selectedTime); -} diff --git a/Linphone/core/chat/message/EventLogCore.hpp b/Linphone/core/chat/message/EventLogCore.hpp index 47c4a7e6..85b93ab4 100644 --- a/Linphone/core/chat/message/EventLogCore.hpp +++ b/Linphone/core/chat/message/EventLogCore.hpp @@ -59,6 +59,9 @@ public: bool isHandled() const { return mHandled; } + bool isEphemeralRelated() const { + return mEphemeralRelated; + } private: DECLARE_ABSTRACT_OBJECT @@ -69,13 +72,13 @@ private: LinphoneEnums::EventLogType mEventLogType; bool mHandled; bool mImportant; + bool mEphemeralRelated; QString mEventDetails; QDateTime mTimestamp; ChatMessageCore *getChatMessageCorePointer(); CallHistoryCore *getCallHistoryCorePointer(); void computeEvent(const std::shared_ptr &eventLog); - QString getEphemeralFormatedTime(int selectedTime); }; #endif // EventLogCore_H_ diff --git a/Linphone/core/chat/message/EventLogList.cpp b/Linphone/core/chat/message/EventLogList.cpp index f2c9b7a6..b4dba478 100644 --- a/Linphone/core/chat/message/EventLogList.cpp +++ b/Linphone/core/chat/message/EventLogList.cpp @@ -143,6 +143,13 @@ QVariant EventLogList::data(const QModelIndex &index, int role) const { case Qt::DisplayRole + 1: return "callLog"; } + } else if (core->isEphemeralRelated()) { + switch (role) { + case Qt::DisplayRole: + return QVariant::fromValue(new EventLogGui(core)); + case Qt::DisplayRole + 1: + return "ephemeralEvent"; + } } else { switch (role) { case Qt::DisplayRole: diff --git a/Linphone/data/image/ephemeral-settings.svg b/Linphone/data/image/ephemeral-settings.svg new file mode 100644 index 00000000..2b9353d8 --- /dev/null +++ b/Linphone/data/image/ephemeral-settings.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Linphone/data/image/radio_off.svg b/Linphone/data/image/radio_off.svg new file mode 100644 index 00000000..788989b7 --- /dev/null +++ b/Linphone/data/image/radio_off.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Linphone/data/image/radio_on.svg b/Linphone/data/image/radio_on.svg new file mode 100644 index 00000000..96273367 --- /dev/null +++ b/Linphone/data/image/radio_on.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index c19da504..d9e3212d 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -2979,47 +2979,6 @@ Error conference_participant_set_admin_event - - - nMinute - - - - - - - - nHour - - - - - - - - - nDay - - - - - - - - nWeek - - - - - - - - nSeconds - - - - - FriendCore @@ -3166,9 +3125,9 @@ Error Flüchtige Nachrichten aktivieren - - group_infos_disable_ephemerals - Flüchtige Nachrichten deaktivieren + + group_infos_ephemerals + Ephemeral messages : @@ -4351,8 +4310,8 @@ Error - one_one_infos_disable_ephemerals - Flüchtige Nachrichten deaktivieren + one_one_infos_ephemerals + Ephemeral messages : @@ -5067,6 +5026,41 @@ Pour les activer dans un projet commercial, merci de nous contacter. Utils + + nMinute + + + + + + + nHour + + + + + + + nDay + + + + + + + nWeek + + + + + + + nSeconds + + + + + information_popup_call_not_created_message @@ -6629,5 +6623,47 @@ Failed to create 1-1 conversation with %1 ! Participants + + EphemeralSettings + + title + Ephemeral messages + Ephemeral messages + + + explanations + By enabling ephemeral messages in this chat, messages sent will be automatically deleted after the defined period. + By enabling ephemeral messages in this chat, messages sent will be automatically deleted after the defined period. + + + one_minute + 1 minute + 1 minute + + + one_hour + 1 hour + 1 hour + + + one_day + 1 day + 1 day + + + one_week + 1 week + 1 week + + + disabled + Disabled + Disabled + + + custom + Custom: + Custom: + + - diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index cea2ca8f..f6428f07 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -2885,12 +2885,13 @@ Only your correspondent can decrypt them. conference_ephemeral_message_enabled_event - Ephemeral messages have been enabled: %1 + Ephemeral messages enabled +Expiration : %1 conference_ephemeral_message_disabled_event - Ephemeral messages have been disabled + Ephemeral messages disabled @@ -2900,48 +2901,8 @@ Only your correspondent can decrypt them. conference_ephemeral_message_lifetime_changed_event - Ephemeral messages have been updated: %1 - - - - nSeconds - - %1 second - %1 seconds - - - - - nMinute - - %1 minute - %1 minutes - - - - - nHour - - %1 hour - %1 hours - - - - - - nDay - - %1 day - %1 days - - - - - nWeek - - %1 week - %1 weeks - + Ephemeral messages updated +Expiration : %1 @@ -3084,9 +3045,9 @@ Only your correspondent can decrypt them. Enable ephemeral messages - - group_infos_disable_ephemerals - Disable ephemeral messages + + group_infos_ephemerals + Ephemeral messages : @@ -4260,8 +4221,8 @@ Only your correspondent can decrypt them. - one_one_infos_disable_ephemerals - Disable ephemeral messages + one_one_infos_ephemerals + Ephemeral messages : @@ -4964,6 +4925,41 @@ To enable them in a commercial project, please contact us. Utils + + nSeconds + + %1 second + %1 seconds + + + + nMinute + + %1 minute + %1 minutes + + + + nHour + + %1 hour + %1 hours + + + + nDay + + %1 day + %1 days + + + + nWeek + + %1 week + %1 weeks + + contact_presence_status_available @@ -6526,4 +6522,47 @@ Failed to create 1-1 conversation with %1 ! Participants + + EphemeralSettings + + title + Ephemeral messages + Ephemeral messages + + + explanations + By enabling ephemeral messages in this chat, messages sent will be automatically deleted after the defined period. + By enabling ephemeral messages in this chat, messages sent will be automatically deleted after the defined period. + + + one_minute + 1 minute + 1 minute + + + one_hour + 1 hour + 1 hour + + + one_day + 1 day + 1 day + + + one_week + 1 week + 1 week + + + disabled + Disabled + Disabled + + + custom + Custom: + Custom: + + diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts index 9792aeaa..cbff1dfc 100644 --- a/Linphone/data/languages/fr_FR.ts +++ b/Linphone/data/languages/fr_FR.ts @@ -2875,17 +2875,19 @@ en bout. Seul votre correspondant peut les déchiffrer. conference_ephemeral_message_enabled_event - Les messages éphémères ont été activés : %1 + Les messages éphémères activés +Expiration : %1 conference_ephemeral_message_lifetime_changed_event - Les messages éphémères ont été mis à jour : %1 + Les messages éphémères mis à jour +Expiration : %1 conference_ephemeral_message_disabled_event - Les messages éphémères ont été désactivés : %1 + Les messages éphémères désactivés @@ -2902,47 +2904,6 @@ en bout. Seul votre correspondant peut les déchiffrer. conference_participant_set_admin_event %1 est maintenant admin - - - nMinute - - %1 minute - %1 minutes - - - - - nHour - - %1 heure - %1 heures - - - - - - nDay - - %1 jour - %1 jours - - - - - nWeek - - %1 semaine - %1 semaines - - - - - nSeconds - - %1 seconde - %1 secondes - - FriendCore @@ -3084,9 +3045,9 @@ en bout. Seul votre correspondant peut les déchiffrer. Activer les messages éphémères - - group_infos_disable_ephemerals - Désactiver les messages éphémères + + group_infos_ephemerals + Messages éphémères : @@ -4255,8 +4216,8 @@ en bout. Seul votre correspondant peut les déchiffrer. - one_one_infos_disable_ephemerals - Désactiver les messages éphémères + one_one_infos_ephemerals + Messages éphémères : @@ -4959,6 +4920,41 @@ Pour les activer dans un projet commercial, merci de nous contacter. Utils + + nMinute + + %1 minute + %1 minutes + + + + nHour + + %1 heure + %1 heures + + + + nDay + + %1 jour + %1 jours + + + + nWeek + + %1 semaine + %1 semaines + + + + nSeconds + + %1 seconde + %1 secondes + + contact_presence_status_available @@ -6521,6 +6517,48 @@ Failed to create 1-1 conversation with %1 ! Participants - + + EphemeralSettings + + title + Ephemeral messages + Messages éphémères + + + explanations + By enabling ephemeral messages in this chat, messages sent will be automatically deleted after the defined period. + En activant les messages éphémères dans cette discussion, les messages envoyés seront automatiquement détruits après le délai défini. + + + one_minute + 1 minute + 1 minute + + + one_hour + 1 hour + 1 heure + + + one_day + 1 day + 1 jour + + + one_week + 1 week + 1 semaine + + + disabled + Disabled + Désactivé + + + custom + Custom: + Personnalisé: + + diff --git a/Linphone/model/chat/ChatModel.cpp b/Linphone/model/chat/ChatModel.cpp index e6d99193..a5458238 100644 --- a/Linphone/model/chat/ChatModel.cpp +++ b/Linphone/model/chat/ChatModel.cpp @@ -114,6 +114,12 @@ void ChatModel::enableEphemeral(bool enable) { emit ephemeralEnableChanged(enable); } +void ChatModel::setEphemeralLifetime(int time) { + mMonitor->setEphemeralLifetime(time); + emit ephemeralLifetimeChanged(time); + enableEphemeral(time != 0); +} + void ChatModel::deleteHistory() { mMonitor->deleteHistory(); emit historyDeleted(); diff --git a/Linphone/model/chat/ChatModel.hpp b/Linphone/model/chat/ChatModel.hpp index 1e64a901..8b07db1f 100644 --- a/Linphone/model/chat/ChatModel.hpp +++ b/Linphone/model/chat/ChatModel.hpp @@ -62,6 +62,7 @@ public: linphone::ChatRoom::State getState() const; void setMuted(bool muted); void enableEphemeral(bool enable); + void setEphemeralLifetime(int time); void setSubject(QString subject) const; void removeParticipantAtIndex(int index) const; void setParticipantAddresses(const QStringList &addresses) const; @@ -73,6 +74,7 @@ signals: void deleted(); void mutedChanged(bool muted); void ephemeralEnableChanged(bool enable); + void ephemeralLifetimeChanged(int time); private: DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index b8351ac4..9e6dd660 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -2102,3 +2102,12 @@ void Utils::setGlobalCursor(Qt::CursorShape cursor) { void Utils::restoreGlobalCursor() { App::getInstance()->restoreOverrideCursor(); } + +QString Utils::getEphemeralFormatedTime(int selectedTime) { + if (selectedTime == 60) return tr("nMinute", "", 1).arg(1); + else if (selectedTime == 3600) return tr("nHour", "", 1).arg(1); + else if (selectedTime == 86400) return tr("nDay", "", 1).arg(1); + else if (selectedTime == 259200) return tr("nDay", "", 3).arg(3); + else if (selectedTime == 604800) return tr("nWeek", "", 1).arg(1); + else return tr("nSeconds", "", selectedTime).arg(selectedTime); +} diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index 5346c102..5d60008f 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -180,6 +180,7 @@ public: Q_INVOKABLE static void sendReplyMessage(ChatMessageGui *message, ChatGui *chatGui, QString text, QVariantList files); Q_INVOKABLE static void sendVoiceRecordingMessage(RecorderGui *recorderGui, ChatGui *chatGui); + Q_INVOKABLE static QString getEphemeralFormatedTime(int selectedTime); // QDir findDirectoryByName(QString startPath, QString name); diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index 39439094..0f7c4c82 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -65,6 +65,7 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Control/Display/Chat/ChatMessageInvitationBubble.qml view/Control/Display/Chat/ChatMessagesListView.qml view/Control/Display/Chat/Event.qml + view/Control/Display/Chat/EphemeralEvent.qml view/Control/Display/Chat/FileView.qml view/Control/Display/Contact/Avatar.qml view/Control/Display/Contact/Contact.qml @@ -161,6 +162,8 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Page/Layout/Chat/ChatInfoActionsGroup.qml view/Page/Layout/Chat/GroupChatInfoParticipants.qml view/Page/Layout/Chat/ManageParticipants.qml + view/Page/Layout/Chat/EphemeralSettings.qml + view/Page/Main/AbstractMainPage.qml view/Page/Main/Account/AccountListView.qml diff --git a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml index 223e8ba2..ccedd6e2 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml @@ -157,6 +157,23 @@ ListView { eventLogGui: modelData } } + } + + DelegateChoice { + roleValue: "ephemeralEvent" + delegate: + Item { + property bool showTopMargin: !header.visible && index == 0 + width: mainItem.width + //height: 40 * DefaultStyle.dp + height: (showTopMargin ? 30 : 0 * DefaultStyle.dp) + eventItem.height + EphemeralEvent { + id: eventItem + anchors.top: parent.top + anchors.topMargin: showTopMargin ? 30 : 0 * DefaultStyle.dp + eventLogGui: modelData + } + } } } diff --git a/Linphone/view/Control/Display/Chat/EphemeralEvent.qml b/Linphone/view/Control/Display/Chat/EphemeralEvent.qml new file mode 100644 index 00000000..46164784 --- /dev/null +++ b/Linphone/view/Control/Display/Chat/EphemeralEvent.qml @@ -0,0 +1,34 @@ +import QtQuick +import QtQuick.Layouts +import Linphone +import UtilsCpp + +Rectangle { + anchors.centerIn: parent + property EventLogGui eventLogGui + property var eventLogCore: eventLogGui.core + visible: eventLogCore.handled + height: row.height + 15 * DefaultStyle.dp + width: row.width + 15 * DefaultStyle.dp + radius: 10 * DefaultStyle.dp + border.width: 2 * DefaultStyle.dp + border.color: DefaultStyle.main2_200 + color: "transparent" + RowLayout { + id: row + anchors.centerIn: parent + EffectImage { + Layout.preferredWidth: visible ? 20 * DefaultStyle.dp : 0 + Layout.preferredHeight: 20 * DefaultStyle.dp + colorizationColor: DefaultStyle.main2_400 + imageSource: AppIcons.clockCountDown + Layout.alignment: Qt.AlignHCenter + } + Text { + id: message + text: eventLogCore.eventDetails + font: Typography.p3 + color: DefaultStyle.main2_400 + } + } +} diff --git a/Linphone/view/Page/Form/Chat/SelectedChatView.qml b/Linphone/view/Page/Form/Chat/SelectedChatView.qml index ed51237e..256dc084 100644 --- a/Linphone/view/Page/Form/Chat/SelectedChatView.qml +++ b/Linphone/view/Page/Form/Chat/SelectedChatView.qml @@ -387,20 +387,23 @@ RowLayout { property bool showingMessageReactions: false property bool showingImdnStatus: false property bool showingManageParticipants: false + property bool showingEphemeralSettings: false anchors.top: parent.top anchors.topMargin: Math.round(39 * DefaultStyle.dp) - sourceComponent: showingMessageReactions - ? messageReactionsComponent - : showingImdnStatus - ? messageImdnStatusComponent - : showingManageParticipants - ? manageParticipantsComponents - : mainItem.chat.core.isGroupChat - ? groupInfoComponent - : oneToOneInfoComponent + sourceComponent: showingEphemeralSettings + ? ephemeralSettingsComponent + : showingMessageReactions + ? messageReactionsComponent + : showingImdnStatus + ? messageImdnStatusComponent + : showingManageParticipants + ? manageParticipantsComponent + : mainItem.chat.core.isGroupChat + ? groupInfoComponent + : oneToOneInfoComponent active: detailsPanel.visible onLoaded: { - if (contentLoader.item) { + if (contentLoader.item && contentLoader.item.parentView) { contentLoader.item.parentView = mainItem } } @@ -410,6 +413,7 @@ RowLayout { id: oneToOneInfoComponent OneOneConversationInfos { chatGui: mainItem.chat + onEphemeralSettingsRequested: contentLoader.showingEphemeralSettings = true } } @@ -418,6 +422,7 @@ RowLayout { GroupConversationInfos { chatGui: mainItem.chat onManageParticipantsRequested: contentLoader.showingManageParticipants = true + onEphemeralSettingsRequested: contentLoader.showingEphemeralSettings = true } } @@ -443,11 +448,19 @@ RowLayout { } Component { - id: manageParticipantsComponents + id: manageParticipantsComponent ManageParticipants { chatGui: mainItem.chat onDone: contentLoader.showingManageParticipants = false } } + + Component { + id: ephemeralSettingsComponent + EphemeralSettings { + chatGui: mainItem.chat + onDone: contentLoader.showingEphemeralSettings = false + } + } } } diff --git a/Linphone/view/Page/Layout/Chat/EphemeralSettings.qml b/Linphone/view/Page/Layout/Chat/EphemeralSettings.qml new file mode 100644 index 00000000..4e5df2f2 --- /dev/null +++ b/Linphone/view/Page/Layout/Chat/EphemeralSettings.qml @@ -0,0 +1,142 @@ +import QtCore +import QtQuick +import QtQuick.Controls.Basic as Control +import QtQuick.Dialogs +import QtQuick.Effects +import QtQuick.Layouts +import Linphone +import UtilsCpp +import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle + +ColumnLayout { + + id: mainItem + property ChatGui chatGui + property var chatCore: chatGui.core + property int selectedLifetime: chatCore.ephemeralLifetime + spacing: Math.round(5 * DefaultStyle.dp) + signal done() + + property var model: [ + {title: qsTr("one_minute"), lifetime: 60}, + {title: qsTr("one_hour"), lifetime: 3600}, + {title: qsTr("one_day"), lifetime: 86400}, + {title: qsTr("one_week"), lifetime: 7*86400}, + {title: qsTr("disabled"), lifetime: 0} + ] + + Component.onCompleted: { + var isLifetimeInRange = model.some(function(item) { + return item.lifetime === selectedLifetime; + }); + if (!isLifetimeInRange) { // Display life time set elsewhere, not in settable range. + model = model.concat({ + title: qsTr("custom")+UtilsCpp.getEphemeralFormatedTime(selectedLifetime), + lifetime: selectedLifetime, + disabled: true + }); + } + } + + RowLayout { + id: manageParticipantsButtons + spacing: Math.round(5 * DefaultStyle.dp) + + BigButton { + id: manageParticipantsBackButton + style: ButtonStyle.noBackground + icon.source: AppIcons.leftArrow + onClicked: { + if (chatCore.ephemeralLifetime != selectedLifetime) + chatCore.ephemeralLifetime = selectedLifetime + mainItem.done() + } + } + + Text { + text: qsTr("title") + color: DefaultStyle.main2_600 + maximumLineCount: 1 + font: Typography.h4 + Layout.fillWidth: true + } + } + + Image { + Layout.preferredWidth: 130 * DefaultStyle.dp + Layout.preferredHeight: 112 * DefaultStyle.dp + Layout.topMargin: Math.round(31 * DefaultStyle.dp) + Layout.alignment: Qt.AlignHCenter + source: AppIcons.ephemeralSettings + fillMode: Image.PreserveAspectFit + Layout.fillWidth: true + } + + Text { + text: qsTr("explanations") + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + font: Typography.p1 + color: DefaultStyle.main2_600 + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: Math.round(31 * DefaultStyle.dp) + Layout.leftMargin: Math.round(15 * DefaultStyle.dp) + Layout.rightMargin: Math.round(15 * DefaultStyle.dp) + } + + RoundedPane { + id: pane + Layout.fillWidth: true + backgroundColor: DefaultStyle.grey_100 + Layout.leftMargin: Math.round(15 * DefaultStyle.dp) + Layout.rightMargin: Math.round(15 * DefaultStyle.dp) + Layout.topMargin: Math.round(31 * DefaultStyle.dp) + contentItem: ColumnLayout { + spacing: 0 + Repeater { + model: mainItem.model + delegate: ColumnLayout { + Layout.fillWidth: true + Layout.leftMargin: Math.round(8 * DefaultStyle.dp) + Control.RadioButton { + enabled: modelData.disabled !== true + opacity: modelData.disabled !== true ? 1.0 : 0.5 + checked: modelData.lifetime === mainItem.selectedLifetime + onClicked: mainItem.selectedLifetime = modelData.lifetime + spacing: Math.round(8 * DefaultStyle.dp) + contentItem: Text { + id: label + text: modelData.title + color: DefaultStyle.main2_600 + font: Typography.p1 + leftPadding: Math.round(8 * DefaultStyle.dp) + wrapMode: Text.NoWrap + elide: Text.ElideRight + anchors.left: ico.right + } + indicator: Image { + id: ico + source: parent.checked ? AppIcons.radioOn : AppIcons.radioOff + width: Math.round(24 * DefaultStyle.dp) + height: Math.round(24 * DefaultStyle.dp) + fillMode: Image.PreserveAspectFit + anchors.verticalCenter: parent.verticalCenter + } + } + Rectangle { + //visible: index < (model.count - 1) + color: DefaultStyle.main2_200 + height: Math.round(1 * DefaultStyle.dp) + Layout.fillWidth: true + } + } + } + } + } + + Item { + Layout.fillHeight: true + } +} diff --git a/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml b/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml index 49e40b31..a81b3f0b 100644 --- a/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml +++ b/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml @@ -16,6 +16,7 @@ ColumnLayout { property var parentView property bool manageParticipants: false signal manageParticipantsRequested() + signal ephemeralSettingsRequested() spacing: 0 @@ -232,11 +233,11 @@ ColumnLayout { { icon: AppIcons.clockCountDown, visible: !mainItem.chatCore.isReadOnly, - text: mainItem.chatCore.ephemeralEnabled ? qsTr("group_infos_disable_ephemerals") : qsTr("group_infos_enable_ephemerals"), + text: mainItem.chatCore.ephemeralEnabled ? qsTr("group_infos_ephemerals")+UtilsCpp.getEphemeralFormatedTime(mainItem.chatCore.ephemeralLifetime) : qsTr("group_infos_enable_ephemerals"), color: DefaultStyle.main2_600, showRightArrow: false, action: function() { - mainItem.chatCore.ephemeralEnabled = !mainItem.chatCore.ephemeralEnabled + mainItem.ephemeralSettingsRequested() } }, { diff --git a/Linphone/view/Page/Layout/Chat/ManageParticipants.qml b/Linphone/view/Page/Layout/Chat/ManageParticipants.qml index 88ce13d3..451422f5 100644 --- a/Linphone/view/Page/Layout/Chat/ManageParticipants.qml +++ b/Linphone/view/Page/Layout/Chat/ManageParticipants.qml @@ -19,7 +19,6 @@ Rectangle { Layout.leftMargin: Math.round(17 * DefaultStyle.dp) Layout.rightMargin: Math.round(10 * DefaultStyle.dp) color: DefaultStyle.grey_0 - radius: Math.round(15 * DefaultStyle.dp) height: participantAddColumn.implicitHeight signal done() @@ -31,7 +30,6 @@ Rectangle { anchors.topMargin: Math.round(17 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp) RowLayout { - id: manageParticipantsButtons spacing: Math.round(5 * DefaultStyle.dp) BigButton { id: manageParticipantsBackButton diff --git a/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml b/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml index 7dcb05b8..ded694aa 100644 --- a/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml +++ b/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml @@ -16,6 +16,8 @@ ColumnLayout { property var contactObj: chatGui ? UtilsCpp.findFriendByAddress(mainItem.chatCore.peerAddress) : null property var parentView spacing: 0 + signal ephemeralSettingsRequested() + Avatar { Layout.alignment: Qt.AlignHCenter @@ -155,12 +157,12 @@ ColumnLayout { }, { icon: AppIcons.clockCountDown, - visible: true, - text: mainItem.chatCore.ephemeralEnabled ? qsTr("one_one_infos_disable_ephemerals") : qsTr("one_one_infos_enable_ephemerals"), + visible: !mainItem.chatCore.isReadOnly, + text: mainItem.chatCore.ephemeralEnabled ? qsTr("one_one_infos_ephemerals")+UtilsCpp.getEphemeralFormatedTime(mainItem.chatCore.ephemeralLifetime) : qsTr("one_one_infos_enable_ephemerals"), color: DefaultStyle.main2_600, showRightArrow: false, action: function() { - mainItem.chatCore.ephemeralEnabled = !mainItem.chatCore.ephemeralEnabled + mainItem.ephemeralSettingsRequested() } }, { diff --git a/Linphone/view/Style/AppIcons.qml b/Linphone/view/Style/AppIcons.qml index cb165ad0..0a25e6a5 100644 --- a/Linphone/view/Style/AppIcons.qml +++ b/Linphone/view/Style/AppIcons.qml @@ -154,4 +154,7 @@ QtObject { property string search: "image://internal/search.svg" property string pdf: "image://internal/pdf.svg" property string photo: "image://internal/photo.svg" + property string ephemeralSettings: "image://internal/ephemeral-settings.svg" + property string radioOn: "image://internal/radio_on.svg" + property string radioOff: "image://internal/radio_off.svg" }