From a5851855d97cfe2994fe4bebd662ee9e8315a87c Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Thu, 3 Jul 2025 12:07:18 +0200 Subject: [PATCH] show shared medias/files + expand button on chat participant list --- Linphone/core/App.cpp | 2 + Linphone/core/CMakeLists.txt | 2 + Linphone/core/chat/ChatCore.cpp | 33 +++ Linphone/core/chat/ChatCore.hpp | 6 + .../core/chat/files/ChatMessageFileList.cpp | 73 +++++ .../core/chat/files/ChatMessageFileList.hpp | 52 ++++ .../core/chat/files/ChatMessageFileProxy.cpp | 65 +++++ .../core/chat/files/ChatMessageFileProxy.hpp | 56 ++++ .../core/chat/message/ChatMessageCore.cpp | 5 +- .../core/chat/message/ChatMessageCore.hpp | 2 + Linphone/core/chat/message/EventLogList.cpp | 5 +- Linphone/core/chat/message/EventLogList.hpp | 1 - .../content/ChatMessageContentProxy.hpp | 2 - Linphone/data/languages/de.ts | 149 +++++----- Linphone/data/languages/en.ts | 154 ++++++----- Linphone/data/languages/fr_FR.ts | 149 +++++----- Linphone/view/CMakeLists.txt | 1 + .../Display/Chat/ChatMessageContent.qml | 3 +- .../view/Control/Display/Chat/FileView.qml | 255 ++++++++++++------ .../Input/Chat/ChatDroppableTextArea.qml | 1 - .../view/Page/Form/Chat/SelectedChatView.qml | 39 ++- .../Layout/Chat/GroupChatInfoParticipants.qml | 23 +- .../Layout/Chat/GroupConversationInfos.qml | 10 +- .../Page/Layout/Chat/MessageInfosLayout.qml | 2 + .../Layout/Chat/MessageSharedFilesInfos.qml | 35 +++ .../Layout/Chat/OneOneConversationInfos.qml | 5 +- Linphone/view/Page/Main/Chat/ChatPage.qml | 2 +- 27 files changed, 816 insertions(+), 316 deletions(-) create mode 100644 Linphone/core/chat/files/ChatMessageFileList.cpp create mode 100644 Linphone/core/chat/files/ChatMessageFileList.hpp create mode 100644 Linphone/core/chat/files/ChatMessageFileProxy.cpp create mode 100644 Linphone/core/chat/files/ChatMessageFileProxy.hpp create mode 100644 Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index a50ae9a05..5df64ee6a 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -54,6 +54,7 @@ #include "core/call/CallProxy.hpp" #include "core/camera/CameraGui.hpp" #include "core/chat/ChatProxy.hpp" +#include "core/chat/files/ChatMessageFileProxy.hpp" #include "core/chat/message/ChatMessageGui.hpp" #include "core/chat/message/EventLogGui.hpp" #include "core/chat/message/EventLogList.hpp" @@ -678,6 +679,7 @@ void App::initCppInterfaces() { qmlRegisterType(Constants::MainQmlUri, 1, 0, "EventLogList"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "EventLogProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "ChatMessageContentProxy"); + qmlRegisterType(Constants::MainQmlUri, 1, 0, "ChatMessageFileProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "ChatMessageContentGui"); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "ConferenceCore", QLatin1String("Uncreatable")); diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index dd36f50c1..bd35e12a9 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -33,6 +33,8 @@ list(APPEND _LINPHONEAPP_SOURCES core/chat/message/content/ChatMessageContentGui.cpp core/chat/message/content/ChatMessageContentList.cpp core/chat/message/content/ChatMessageContentProxy.cpp + core/chat/files/ChatMessageFileList.cpp + core/chat/files/ChatMessageFileProxy.cpp core/chat/message/imdn/ImdnStatusList.cpp core/chat/message/imdn/ImdnStatusProxy.cpp core/emoji/EmojiList.cpp diff --git a/Linphone/core/chat/ChatCore.cpp b/Linphone/core/chat/ChatCore.cpp index 798c7365a..75aaa530c 100644 --- a/Linphone/core/chat/ChatCore.cpp +++ b/Linphone/core/chat/ChatCore.cpp @@ -92,6 +92,13 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec for (auto &event : lHistory) { auto eventLogCore = EventLogCore::create(event); eventList.append(eventLogCore); + if (auto isMessage = eventLogCore->getChatMessageCore()) { + for (auto content : isMessage->getChatMessageContentList()) { + if (content->isFile() && !content->isVoiceRecording()) { + mFileList.append(content); + } + } + } } resetEventLogList(eventList); mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier()); @@ -105,6 +112,22 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec connect(this, &ChatCore::eventListChanged, this, &ChatCore::lUpdateLastMessage); connect(this, &ChatCore::eventsInserted, this, &ChatCore::lUpdateLastMessage); connect(this, &ChatCore::eventRemoved, this, &ChatCore::lUpdateLastMessage); + auto resetFileListLambda = [this] { + QList> fileList; + for (auto &eventLogCore : mEventLogList) { + if (auto isMessage = eventLogCore->getChatMessageCore()) { + for (auto content : isMessage->getChatMessageContentList()) { + if (content->isFile() && !content->isVoiceRecording()) { + fileList.append(content); + } + } + } + } + resetFileList(fileList); + }; + connect(this, &ChatCore::eventListChanged, this, resetFileListLambda); + connect(this, &ChatCore::eventsInserted, this, resetFileListLambda); + connect(this, &ChatCore::eventRemoved, this, resetFileListLambda); mEphemeralEnabled = chatRoom->ephemeralEnabled(); mEphemeralLifetime = chatRoom->ephemeralEnabled() ? chatRoom->getEphemeralLifetime() : 0; mIsMuted = chatRoom->getMuted(); @@ -114,6 +137,7 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec ChatCore::~ChatCore() { lDebug() << "[ChatCore] delete" << this; mustBeInMainThread("~" + getClassName()); + mChatModelConnection->disconnect(); emit mChatModel->removeListener(); } @@ -555,6 +579,15 @@ QString ChatCore::getComposingAddress() const { return mComposingAddress; } +QList> ChatCore::getFileList() const { + return mFileList; +} + +void ChatCore::resetFileList(QList> list) { + mFileList = list; + emit fileListChanged(); +} + std::shared_ptr ChatCore::getModel() const { return mChatModel; } diff --git a/Linphone/core/chat/ChatCore.hpp b/Linphone/core/chat/ChatCore.hpp index bb51cd161..f17348c82 100644 --- a/Linphone/core/chat/ChatCore.hpp +++ b/Linphone/core/chat/ChatCore.hpp @@ -64,6 +64,7 @@ public: Q_PROPERTY(QVariantList participants READ getParticipantsGui NOTIFY participantsChanged) Q_PROPERTY(QStringList participantsAddresses READ getParticipantsAddresses WRITE lSetParticipantsAddresses NOTIFY participantsChanged) + Q_PROPERTY(QList> fileList READ getFileList NOTIFY fileListChanged) // Should be call from model Thread. Will be automatically in App thread after initialization static QSharedPointer create(const std::shared_ptr &chatRoom); @@ -94,6 +95,9 @@ public: ChatMessageGui *getLastMessage() const; QString getLastMessageText() const; + QList> getFileList() const; + void resetFileList(QList> list); + LinphoneEnums::ChatMessageState getLastMessageState() const; LinphoneEnums::ChatRoomState getChatRoomState() const; @@ -157,6 +161,7 @@ signals: void ephemeralLifetimeChanged(); void meAdminChanged(); void participantsChanged(); + void fileListChanged(); void lDeleteMessage(ChatMessageGui *message); void lDelete(); @@ -195,6 +200,7 @@ private: bool mIsReadOnly = false; bool mEphemeralEnabled = false; int mEphemeralLifetime = 0; + QList> mFileList; bool mIsMuted = false; bool mMeAdmin = false; QList> mParticipants; diff --git a/Linphone/core/chat/files/ChatMessageFileList.cpp b/Linphone/core/chat/files/ChatMessageFileList.cpp new file mode 100644 index 000000000..10b97bcfa --- /dev/null +++ b/Linphone/core/chat/files/ChatMessageFileList.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ChatMessageFileList.hpp" +#include "core/App.hpp" +#include "core/chat/message/content/ChatMessageContentCore.hpp" + +#include + +#include + +// ============================================================================= + +DEFINE_ABSTRACT_OBJECT(ChatMessageFileList) + +QSharedPointer ChatMessageFileList::create() { + auto model = QSharedPointer(new ChatMessageFileList(), &QObject::deleteLater); + model->moveToThread(App::getInstance()->thread()); + return model; +} + +ChatMessageFileList::ChatMessageFileList(QObject *parent) : ListProxy(parent) { + mustBeInMainThread(getClassName()); + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); +} + +ChatMessageFileList::~ChatMessageFileList() { + mustBeInMainThread("~" + getClassName()); + mList.clear(); +} + +QSharedPointer ChatMessageFileList::getChatCore() const { + return mChat; +} + +void ChatMessageFileList::setChatCore(QSharedPointer chatCore) { + if (mChat != chatCore) { + if (mChat) disconnect(mChat.get()); + mChat = chatCore; + auto lUpdate = [this] { + auto fileList = mChat->getFileList(); + resetData(fileList); + }; + if (mChat) connect(mChat.get(), &ChatCore::fileListChanged, this, lUpdate); + lUpdate(); + emit chatChanged(); + } +} + +QVariant ChatMessageFileList::data(const QModelIndex &index, int role) const { + int row = index.row(); + if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); + if (role == Qt::DisplayRole) + return QVariant::fromValue(new ChatMessageContentGui(mList[row].objectCast())); + return QVariant(); +} \ No newline at end of file diff --git a/Linphone/core/chat/files/ChatMessageFileList.hpp b/Linphone/core/chat/files/ChatMessageFileList.hpp new file mode 100644 index 000000000..7ad069ef8 --- /dev/null +++ b/Linphone/core/chat/files/ChatMessageFileList.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CHAT_MESSAGE_FILE_LIST_H_ +#define CHAT_MESSAGE_FILE_LIST_H_ + +#include "core/chat/ChatCore.hpp" +#include "core/proxy/ListProxy.hpp" +#include "tool/AbstractObject.hpp" +#include "tool/thread/SafeConnection.hpp" +#include + +// ============================================================================= + +class ChatMessageFileList : public ListProxy, public AbstractObject { + Q_OBJECT +public: + static QSharedPointer create(); + ChatMessageFileList(QObject *parent = Q_NULLPTR); + ~ChatMessageFileList(); + + QSharedPointer getChatCore() const; + void setChatCore(QSharedPointer chatCore); + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +signals: + void chatChanged(); + +private: + QSharedPointer mChat; + DECLARE_ABSTRACT_OBJECT +}; + +#endif diff --git a/Linphone/core/chat/files/ChatMessageFileProxy.cpp b/Linphone/core/chat/files/ChatMessageFileProxy.cpp new file mode 100644 index 000000000..2fbcffd1e --- /dev/null +++ b/Linphone/core/chat/files/ChatMessageFileProxy.cpp @@ -0,0 +1,65 @@ + +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ChatMessageFileProxy.hpp" +#include "core/App.hpp" +#include "core/chat/ChatGui.hpp" + +DEFINE_ABSTRACT_OBJECT(ChatMessageFileProxy) + +ChatMessageFileProxy::ChatMessageFileProxy(QObject *parent) : LimitProxy(parent) { + mList = ChatMessageFileList::create(); + connect(mList.get(), &ChatMessageFileList::chatChanged, this, &ChatMessageFileProxy::chatGuiChanged); + connect(this, &ChatMessageFileProxy::filterTypeChanged, this, [this] { invalidate(); }); + setSourceModels(new SortFilterList(mList.get())); +} + +ChatMessageFileProxy::~ChatMessageFileProxy() { +} + +ChatGui *ChatMessageFileProxy::getChatGui() const { + return mList && mList->getChatCore() ? new ChatGui(mList->getChatCore()) : nullptr; +} + +void ChatMessageFileProxy::setChatGui(ChatGui *chat) const { + if (mList) mList->setChatCore(chat ? chat->mCore : nullptr); +} + +bool ChatMessageFileProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + if (getFilterType() == (int)FilterContentType::All) return true; + else { + auto contentCore = getItemAtSource(sourceRow); + if (!contentCore) return false; + bool isMedia = Utils::isVideo(contentCore->getFilePath()) || Utils::isImage(contentCore->getFilePath()) || + Utils::isAnimatedImage(contentCore->getFilePath()); + if (getFilterType() == (int)FilterContentType::Medias) { + return isMedia; + } else { + return !isMedia; + } + return false; + } +} + +bool ChatMessageFileProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, + const QModelIndex &sourceRight) const { + return true; +} diff --git a/Linphone/core/chat/files/ChatMessageFileProxy.hpp b/Linphone/core/chat/files/ChatMessageFileProxy.hpp new file mode 100644 index 000000000..eb0935f1b --- /dev/null +++ b/Linphone/core/chat/files/ChatMessageFileProxy.hpp @@ -0,0 +1,56 @@ + +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CHAT_MESSAGE_FILE_PROXY_H_ +#define CHAT_MESSAGE_FILE_PROXY_H_ + +#include "ChatMessageFileList.hpp" +#include "core/chat/message/ChatMessageCore.hpp" +#include "core/proxy/LimitProxy.hpp" +#include "tool/AbstractObject.hpp" + +// ============================================================================= + +class ChatMessageFileProxy : public LimitProxy, public AbstractObject { + Q_OBJECT + Q_PROPERTY(ChatGui *chat READ getChatGui WRITE setChatGui NOTIFY chatGuiChanged) + +public: + enum class FilterContentType { All = 0, Medias = 1, Documents = 2 }; + Q_ENUM(FilterContentType) + + DECLARE_SORTFILTER_CLASS() + ChatMessageFileProxy(QObject *parent = Q_NULLPTR); + ~ChatMessageFileProxy(); + + ChatGui *getChatGui() const; + void setChatGui(ChatGui *chat) const; + +signals: + void chatGuiChanged(); + void filterChanged(); + +protected: + QSharedPointer mList; + DECLARE_ABSTRACT_OBJECT +}; + +#endif diff --git a/Linphone/core/chat/message/ChatMessageCore.cpp b/Linphone/core/chat/message/ChatMessageCore.cpp index bda8e7432..6c40bbb65 100644 --- a/Linphone/core/chat/message/ChatMessageCore.cpp +++ b/Linphone/core/chat/message/ChatMessageCore.cpp @@ -20,7 +20,6 @@ #include "ChatMessageCore.hpp" #include "core/App.hpp" -#include "core/chat/ChatCore.hpp" #include "model/tool/ToolModel.hpp" DEFINE_ABSTRACT_OBJECT(ChatMessageCore) @@ -406,6 +405,10 @@ bool ChatMessageCore::isFromChatGroup() const { return mIsFromChatGroup; } +bool ChatMessageCore::hasFileContent() const { + return mHasFileContent; +} + bool ChatMessageCore::isRead() const { return mIsRead; } diff --git a/Linphone/core/chat/message/ChatMessageCore.hpp b/Linphone/core/chat/message/ChatMessageCore.hpp index 9dda840d5..b4efd1171 100644 --- a/Linphone/core/chat/message/ChatMessageCore.hpp +++ b/Linphone/core/chat/message/ChatMessageCore.hpp @@ -131,6 +131,8 @@ public: bool isRemoteMessage() const; bool isFromChatGroup() const; + bool hasFileContent() const; + bool isRead() const; void setIsRead(bool read); diff --git a/Linphone/core/chat/message/EventLogList.cpp b/Linphone/core/chat/message/EventLogList.cpp index b4dba478d..4c15f2c0d 100644 --- a/Linphone/core/chat/message/EventLogList.cpp +++ b/Linphone/core/chat/message/EventLogList.cpp @@ -47,7 +47,6 @@ EventLogList::EventLogList(QObject *parent) : ListProxy(parent) { EventLogList::~EventLogList() { mustBeInMainThread("~" + getClassName()); - mModelConnection = nullptr; } ChatGui *EventLogList::getChat() const { @@ -97,9 +96,7 @@ int EventLogList::findFirstUnreadIndex() { } void EventLogList::setSelf(QSharedPointer me) { - mModelConnection = SafeConnection::create(me, CoreModel::getInstance()); - - mModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() { + connect(this, &EventLogList::lUpdate, this, [this]() { for (auto &event : getSharedList()) { auto message = event->getChatMessageCore(); if (message) disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr); diff --git a/Linphone/core/chat/message/EventLogList.hpp b/Linphone/core/chat/message/EventLogList.hpp index 4ffe365ea..6e112b778 100644 --- a/Linphone/core/chat/message/EventLogList.hpp +++ b/Linphone/core/chat/message/EventLogList.hpp @@ -58,7 +58,6 @@ signals: private: QString mFilter; QSharedPointer mChatCore; - QSharedPointer> mModelConnection; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/chat/message/content/ChatMessageContentProxy.hpp b/Linphone/core/chat/message/content/ChatMessageContentProxy.hpp index 9bceeb067..34c7ca933 100644 --- a/Linphone/core/chat/message/content/ChatMessageContentProxy.hpp +++ b/Linphone/core/chat/message/content/ChatMessageContentProxy.hpp @@ -53,8 +53,6 @@ public: signals: void chatChanged(); - void filterChanged(); - void messageInserted(int index, ChatMessageGui *message); protected: QSharedPointer mList; diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index 37d87e17b..b0a61cb8b 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -523,74 +523,74 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Möchten Sie die Remote-Konfiguration von dieser Adresse herunterladen und anwenden? - + application_description "A free and open source SIP video-phone." Ein kostenloses Open-Source SIP Video-Telefon. - + command_line_arg_order "Send an order to the application towards a command line" Kommandozeilen-Befehl an die Anwendung schicken - + command_line_option_show_help Zeige Hilfe - + command_line_option_show_app_version Zeige App-Version - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Abzurufende Linphone-Konfigurationsdatei angeben. Sie wird mit der aktuellen Konfiguration zusammengeführt. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, Pfad oder Datei - + command_line_option_minimized - + command_line_option_log_to_stdout Debug-Informationen auf der Standardausgabe ausgeben - + command_line_option_print_app_logs_only "Print only logs from the application" Nur Anwendungs-Logs ausgeben - + hide_action "Cacher" "Afficher" Ausblenden - + show_action Zeigen - + quit_action "Quitter" Beenden @@ -1728,13 +1728,13 @@ ChatCore - + info_toast_deleted_title Deleted - + info_toast_deleted_message_history Message history has been deleted @@ -1743,13 +1743,13 @@ ChatDroppableTextArea - + chat_view_send_area_placeholder_text Say something… : placeholder text for sending message text area - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing @@ -1957,19 +1957,19 @@ Error ChatMessageCore - + all_reactions_label "Reactions": all reactions for one message label - + info_toast_deleted_title Deleted - + info_toast_deleted_message The message has been deleted @@ -2022,20 +2022,20 @@ Error ChatMessagesListView - + chat_message_list_encrypted_header_title End to end encrypted chat - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. - + chat_message_is_writing_info %1 is writing… @@ -3070,55 +3070,55 @@ Error GroupChatInfoParticipants - + group_infos_participant_is_admin Admin - + group_infos_manage_participants_title "Gérer des participants" Manage Participants - + menu_see_existing_contact "Show contact" Kontakt anzeigen - + menu_add_address_to_contacts "Add to contacts" Zu Kontakten hinzufügen - + group_infos_give_admin_rights Give admin rights - + group_infos_remove_admin_rights Remove admin rights - + group_infos_copy_sip_address Copy SIP Address - + group_infos_remove_participant Remove participant - + group_infos_remove_participants_toast_title Remove participant ? - + group_infos_remove_participants_toast_message Participant will be removed from chat room. @@ -3126,37 +3126,37 @@ Error GroupConversationInfos - + group_infos_call "Appel" Anrufen - + group_infos_mute Stummschalten - + group_infos_unmute "Sourdine" Unmute - + group_infos_meeting "Réunion" Meeting - + group_infos_participants Participants (%1) - - + group_infos_media_docs + Medias & documents Medien & Dokumente @@ -3165,55 +3165,62 @@ Error Geteilte Medien - + group_infos_shared_docs + Shared documents Geteilte Dokumente - + group_infos_other_actions Weitere Aktionen - + group_infos_enable_ephemerals Flüchtige Nachrichten aktivieren - + group_infos_ephemerals Ephemeral messages : - + group_infos_leave_room - + group_infos_delete_history Verlauf löschen - + group_infos_delete_history_toast_title Delete history ? Verlauf löschen? - + group_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? Alle Nachrichten werden aus dem Chat entfernt. Möchten Sie fortfahren? - + group_infos_leave_room_toast_title Leave Chat Room ? Chatraum verlassen? - + + group_infos_shared_medias + Shared medias + + + + group_infos_leave_room_toast_message All the messages will be removed from the chat room. Do you want to continue ? Alle Nachrichten werden aus dem Chat entfernt. Möchten Sie fortfahren? @@ -4324,82 +4331,82 @@ Error OneOneConversationInfos - + one_one_infos_call "Appel" Anrufen - + one_one_infos_mute Stummschalten - + one_one_infos_unmute "Sourdine" Unmute - + one_one_infos_search "Rechercher" Suchen - + one_one_infos_media_docs Medien & Dokumente - + one_one_infos_shared_media Geteilte Medien - + one_one_infos_shared_docs Geteilte Dokumente - + one_one_infos_other_actions Weitere Aktionen - + one_one_infos_enable_ephemerals Flüchtige Nachrichten aktivieren - + one_one_infos_ephemerals Ephemeral messages : - + one_one_infos_delete_history Verlauf löschen - + one_one_infos_delete_history_toast_title Delete history ? Verlauf löschen? - + one_one_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? Alle Nachrichten werden aus dem Chat entfernt. Möchten Sie fortfahren? - + one_one_infos_open_contact Kontakt öffnen - + one_one_infos_create_contact Kontakt erstellen @@ -4952,6 +4959,18 @@ Pour les activer dans un projet commercial, merci de nous contacter. Reply to %1 + + + shared_medias_title + Shared medias + + + + + shared_documents_title + Shared documents + + SettingsPage diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index 080801abd..f7efb0b25 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -523,74 +523,74 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Do you want to download and apply remote provisioning from this address ? - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Show app version - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimize - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Hide - + show_action Show - + quit_action "Quitter" Quit @@ -1690,13 +1690,13 @@ ChatCore - + info_toast_deleted_title Deleted Deleted - + info_toast_deleted_message_history Message history has been deleted Message history has been deleted @@ -1705,13 +1705,13 @@ ChatDroppableTextArea - + chat_view_send_area_placeholder_text Say something… : placeholder text for sending message text area Say something… - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing Cannot record a message while a call is ongoing @@ -1919,19 +1919,19 @@ Error ChatMessageCore - + all_reactions_label "Reactions": all reactions for one message label Reactions - + info_toast_deleted_title Deleted Deleted - + info_toast_deleted_message The message has been deleted The message has been deleted @@ -1984,13 +1984,13 @@ Error ChatMessagesListView - + chat_message_list_encrypted_header_title End to end encrypted chat End to end encrypted chat - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. @@ -1998,7 +1998,7 @@ Error Only your correspondent can decrypt them. - + chat_message_is_writing_info %1 is writing… %1 is writing… @@ -2995,55 +2995,55 @@ Expiration : %1 GroupChatInfoParticipants - + group_infos_manage_participants_title "Gérer des participants" Manage participants - + group_infos_participant_is_admin Admin - + menu_see_existing_contact "Show contact" Show contact - + menu_add_address_to_contacts "Add to contacts" Add to contacts - + group_infos_give_admin_rights Give admin rights - + group_infos_remove_admin_rights Remove admin rights - + group_infos_copy_sip_address Copy SIP Address - + group_infos_remove_participant Remove participant - + group_infos_remove_participants_toast_title Remove participant ? - + group_infos_remove_participants_toast_message Participant will be removed from chat room. @@ -3051,89 +3051,96 @@ Expiration : %1 GroupConversationInfos - + group_infos_call "Appel" Call - + group_infos_mute Mute - + group_infos_unmute "Sourdine" Unmute - + group_infos_meeting "Réunion" Meeting - + group_infos_participants Participants (%1) - - + group_infos_media_docs + Medias & documents Medias & documents - + + group_infos_shared_medias + Shared medias + Shared medias + + + group_infos_shared_docs + Shared documents Shared documents - + group_infos_other_actions Other actions - + group_infos_enable_ephemerals Enable ephemeral messages - + group_infos_ephemerals Ephemeral messages : - + group_infos_delete_history Delete history - + group_infos_delete_history_toast_title Delete history ? Delete history ? - + group_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? All the messages will be removed from the chat room. Do you want to continue ? - + group_infos_leave_room Leave Chat Room - + group_infos_leave_room_toast_title Leave Chat Room ? Leave Chat Room ? - + group_infos_leave_room_toast_message All the messages will be removed from the chat room. Do you want to continue ? All the messages will be removed from the chat room. Do you want to continue ? @@ -3983,11 +3990,6 @@ Expiration : %1 Message status Message status - - click_to_delete_reaction_info - Click to delete - Click to delete - MessageReactionsInfos @@ -4235,82 +4237,82 @@ Expiration : %1 OneOneConversationInfos - + one_one_infos_call "Appel" Call - + one_one_infos_mute Mute - + one_one_infos_unmute "Sourdine" Unmute - + one_one_infos_search "Rechercher" Search - + one_one_infos_media_docs Medias & documents - + one_one_infos_shared_media Shared medias - + one_one_infos_shared_docs Shared documents - + one_one_infos_other_actions Other actions - + one_one_infos_enable_ephemerals Enable ephemeral messages - + one_one_infos_ephemerals Ephemeral messages : - + one_one_infos_delete_history Delete history - + one_one_infos_delete_history_toast_title Delete history ? Delete history ? - + one_one_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? All the messages will be removed from the chat room. Do you want to continue ? - + one_one_infos_open_contact Show contact - + one_one_infos_create_contact Create contact @@ -4851,6 +4853,18 @@ To enable them in a commercial project, please contact us. Reply to %1 Reply to %1 + + + shared_medias_title + Shared medias + Shared medias + + + + shared_documents_title + Shared documents + Shared documents + SettingsPage diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts index 57ac8b048..48792ec9e 100644 --- a/Linphone/data/languages/fr_FR.ts +++ b/Linphone/data/languages/fr_FR.ts @@ -523,74 +523,74 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Afficher la version de l'application - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimiser - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Cacher - + show_action Afficher - + quit_action "Quitter" Quitter @@ -1690,13 +1690,13 @@ ChatCore - + info_toast_deleted_title Deleted Supprimé - + info_toast_deleted_message_history Message history has been deleted L'historique des messages a été supprimé @@ -1705,13 +1705,13 @@ ChatDroppableTextArea - + chat_view_send_area_placeholder_text Say something… : placeholder text for sending message text area Dites quelque chose… - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing Impossible d'enregistrer un message vocal pendant un appel @@ -1919,19 +1919,19 @@ Error ChatMessageCore - + all_reactions_label "Reactions": all reactions for one message label Réactions - + info_toast_deleted_title Deleted Supprimé - + info_toast_deleted_message The message has been deleted Le message a été supprimé @@ -1984,13 +1984,13 @@ Error ChatMessagesListView - + chat_message_list_encrypted_header_title End to end encrypted chat Conversation chiffrée de bout en bout - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. @@ -1998,7 +1998,7 @@ Error en bout. Seul votre correspondant peut les déchiffrer. - + chat_message_is_writing_info %1 is writing… %1 est en train d'écrire… @@ -2995,55 +2995,55 @@ Expiration : %1 GroupChatInfoParticipants - + group_infos_manage_participants_title "Gérer des participants" Gérer les participants - + group_infos_participant_is_admin Admin - + menu_see_existing_contact "Show contact" Voir le contact - + menu_add_address_to_contacts "Add to contacts" Ajouter aux contacts - + group_infos_give_admin_rights Donner les droits admins - + group_infos_remove_admin_rights Retirer les droits admins - + group_infos_copy_sip_address Copier l’adresse SIP - + group_infos_remove_participant Retirer le participant - + group_infos_remove_participants_toast_title Retirer le participant ? - + group_infos_remove_participants_toast_message La participant sere retiré de la conversation @@ -3051,89 +3051,96 @@ Expiration : %1 GroupConversationInfos - + group_infos_call "Appel" Appel - + group_infos_mute Sourdine - + group_infos_unmute "Sourdine" Réactiver les notifications - + group_infos_meeting "Réunion" Réunion - + group_infos_participants Participants (%1) - - + group_infos_media_docs + Medias & documents Medias & documents - + + group_infos_shared_medias + Shared medias + Médias partagés + + + group_infos_shared_docs + Shared documents Documents partagés - + group_infos_other_actions Autres actions - + group_infos_enable_ephemerals Activer les messages éphémères - + group_infos_ephemerals Messages éphémères : - + group_infos_delete_history Supprimer l'historique - + group_infos_delete_history_toast_title Delete history ? Supprimer l'historique ? - + group_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? Tous les messages seront supprimés. Souhaitez-vous continuer ? - + group_infos_leave_room Quitter la conversation - + group_infos_leave_room_toast_title Leave Chat Room ? Quitter la conversation ? - + group_infos_leave_room_toast_message All the messages will be removed from the chat room. Do you want to continue ? Vous ne recevrez ni pourrez envoyer des messages dans cette conversation, quitter ? @@ -4230,82 +4237,82 @@ Expiration : %1 OneOneConversationInfos - + one_one_infos_call "Appel" Appel - + one_one_infos_mute Sourdine - + one_one_infos_unmute "Sourdine" Réactiver les notifications - + one_one_infos_search "Rechercher" Rechercher - + one_one_infos_media_docs Medias & documents - + one_one_infos_shared_media Médias partagés - + one_one_infos_shared_docs Documents partagés - + one_one_infos_other_actions Autres actions - + one_one_infos_enable_ephemerals Activer les messages éphémères - + one_one_infos_ephemerals Messages éphémères : - + one_one_infos_delete_history Supprimer l'historique - + one_one_infos_delete_history_toast_title Delete history ? Supprimer l'historique ? - + one_one_infos_delete_history_toast_message All the messages will be removed from the chat room. Do you want to continue ? Tous les messages seront supprimés. Souhaitez-vous continuer ? - + one_one_infos_open_contact Voir le contact - + one_one_infos_create_contact Créer un contact @@ -4846,6 +4853,18 @@ Pour les activer dans un projet commercial, merci de nous contacter.Reply to %1 Réponse à %1 + + + shared_medias_title + Shared medias + Médias partagés + + + + shared_documents_title + Shared documents + Documents partagés + SettingsPage diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index 8f1fe4899..e35dd9961 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -159,6 +159,7 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Page/Layout/Chat/MessageImdnStatusInfos.qml view/Page/Layout/Chat/MessageInfosLayout.qml view/Page/Layout/Chat/MessageReactionsInfos.qml + view/Page/Layout/Chat/MessageSharedFilesInfos.qml view/Page/Layout/Chat/OneOneConversationInfos.qml view/Page/Layout/Chat/ChatInfoActionsGroup.qml view/Page/Layout/Chat/GroupChatInfoParticipants.qml diff --git a/Linphone/view/Control/Display/Chat/ChatMessageContent.qml b/Linphone/view/Control/Display/Chat/ChatMessageContent.qml index 706d35c78..d79642243 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessageContent.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessageContent.qml @@ -68,9 +68,8 @@ ColumnLayout { Layout.fillHeight: true // Layout.preferredHeight: contentHeight chatMessageGui: mainItem.chatMessageGui - // onIsHoveringFileChanged: mainItem.isHoveringFile = isHoveringFile onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile) - // borderWidth: mainItem.fileBorderWidth + // borderWidth: mainItem.fileBorderWidth // property int availableSection: mainItem.availableWidth / mainItem.filesBestWidth // property int bestFitSection: mainItem.bestWidth / mainItem.filesBestWidth // columns: Math.max(1, Math.min(availableSection , bestFitSection)) diff --git a/Linphone/view/Control/Display/Chat/FileView.qml b/Linphone/view/Control/Display/Chat/FileView.qml index a2078b7a8..ebe792910 100644 --- a/Linphone/view/Control/Display/Chat/FileView.qml +++ b/Linphone/view/Control/Display/Chat/FileView.qml @@ -28,6 +28,8 @@ Item { property bool isThumbnail: isVideo || isImage || isPdf property int overriddenWidth property int overriddenHeight + // property to change default view display + property bool showAsSquare: true Connections { enabled: contentGui @@ -116,6 +118,7 @@ Item { anchors.fill: parent Image { anchors.fill: parent + z: parent.z + 1 visible: parent.status !== Image.Ready source: AppIcons.fileImage sourceSize.width: mainItem.width @@ -187,101 +190,177 @@ Item { // --------------------------------------------------------------------- Component { id: defaultFileView - - Control.Control { - id: defaultView - leftPadding: Math.round(4 * DefaultStyle.dp) - rightPadding: Math.round(4 * DefaultStyle.dp) - topPadding: Math.round(23 * DefaultStyle.dp) - bottomPadding: Math.round(4 * DefaultStyle.dp) - hoverEnabled: false - background: Rectangle { - anchors.fill: parent - color: FileViewStyle.extension.background.color - radius: FileViewStyle.extension.radius - - Rectangle { - color: DefaultStyle.main2_200 - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: Math.round(23 * DefaultStyle.dp) - EffectImage { - anchors.centerIn: parent - imageSource: contentGui - ? UtilsCpp.isImage(mainItem.filePath) - ? AppIcons.fileImage - : UtilsCpp.isPdf(mainItem.filePath) - ? AppIcons.filePdf - : UtilsCpp.isText(mainItem.filePath) - ? AppIcons.fileText - : AppIcons.file - : '' - imageWidth: Math.round(14 * DefaultStyle.dp) - imageHeight: Math.round(14 * DefaultStyle.dp) - colorizationColor: DefaultStyle.main2_600 + Control.StackView { + id: defaultViewStack + width: childrenRect.width + height: childrenRect.height + initialItem: mainItem.showAsSquare ? defaultSquareView : defaultView + Connections { + target: mainItem + function onShowAsSquareChanged() { + if (mainItem.showAsSquare) defaultViewStack.replace(defaultSquareView) + else defaultViewStack.replace(defaultView) + } + } + property var imageSource: mainItem.contentGui + ? UtilsCpp.isImage(mainItem.filePath) + ? AppIcons.fileImage + : UtilsCpp.isPdf(mainItem.filePath) + ? AppIcons.filePdf + : UtilsCpp.isText(mainItem.filePath) + ? AppIcons.fileText + : AppIcons.file + : '' + + Component { + id: defaultSquareView + Control.Control { + leftPadding: Math.round(4 * DefaultStyle.dp) + rightPadding: Math.round(4 * DefaultStyle.dp) + topPadding: Math.round(23 * DefaultStyle.dp) + bottomPadding: Math.round(4 * DefaultStyle.dp) + hoverEnabled: false + + background: Rectangle { + anchors.fill: parent + color: FileViewStyle.extension.background.color + radius: FileViewStyle.extension.radius + + Rectangle { + color: DefaultStyle.main2_200 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: Math.round(23 * DefaultStyle.dp) + EffectImage { + anchors.centerIn: parent + imageSource: defaultViewStack.imageSource + imageWidth: Math.round(14 * DefaultStyle.dp) + imageHeight: Math.round(14 * DefaultStyle.dp) + colorizationColor: DefaultStyle.main2_600 + } + } + } + + contentItem: Item { + Text { + id: fileName + visible: !progressBar.visible + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + // visible: mainItem.contentGui && !mainItem.isAnimatedImage + font.pixelSize: Typography.f1.pixelSize + font.weight: Typography.f1l.weight + wrapMode: Text.WrapAnywhere + maximumLineCount: 2 + text: mainItem.name + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + Text { + id: fileSizeText + visible: !progressBar.visible + anchors.bottom: parent.bottom + anchors.right: parent.right + text: Utils.formatSize(mainItem.fileSize) + font.pixelSize: Typography.f1l.pixelSize + font.weight: Typography.f1l.weight + } + RoundProgressBar { + id: progressBar + anchors.centerIn: parent + to: 100 + value: mainItem.contentGui ? (mainItem.fileSize>0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset / mainItem.fileSize) : 0) : to + visible: mainItem.isTransferring && value != 0 + /* Change format? Current is % + text: if(mainRow.contentGui){ + var mainItem.fileSize = Utils.formatSize(mainRow.contentGui.core.mainItem.fileSize) + return progressBar.visible + ? Utils.formatSize(mainRow.contentGui.core.fileOffset) + '/' + mainItem.fileSize + : mainItem.fileSize + }else + return '' + */ + } + Rectangle { + visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) + color: DefaultStyle.grey_0 + opacity: 0.5 + anchors.fill: parent + } + EffectImage { + visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) + anchors.centerIn: parent + imageSource: AppIcons.download + width: Math.round(24 * DefaultStyle.dp) + height: Math.round(24 * DefaultStyle.dp) + colorizationColor: DefaultStyle.main2_600 + } } } } - - contentItem: Item { - Text { - id: fileName - visible: !progressBar.visible - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - // visible: mainItem.contentGui && !mainItem.isAnimatedImage - font.pixelSize: Typography.f1.pixelSize - font.weight: Typography.f1l.weight - wrapMode: Text.WrapAnywhere - maximumLineCount: 2 - text: mainItem.name - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - Text { - id: fileSizeText - visible: !progressBar.visible - anchors.bottom: parent.bottom - anchors.right: parent.right - text: Utils.formatSize(mainItem.fileSize) - font.pixelSize: Typography.f1l.pixelSize - font.weight: Typography.f1l.weight - } - RoundProgressBar { - id: progressBar - anchors.centerIn: parent - to: 100 - value: mainItem.contentGui ? (mainItem.fileSize>0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset / mainItem.fileSize) : 0) : to - visible: mainItem.isTransferring && value != 0 - /* Change format? Current is % - text: if(mainRow.contentGui){ - var mainItem.fileSize = Utils.formatSize(mainRow.contentGui.core.mainItem.fileSize) - return progressBar.visible - ? Utils.formatSize(mainRow.contentGui.core.fileOffset) + '/' + mainItem.fileSize - : mainItem.fileSize - }else - return '' - */ - } - Rectangle { - visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) - color: DefaultStyle.grey_0 - opacity: 0.5 - anchors.fill: parent - } - EffectImage { - visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) - anchors.centerIn: parent - imageSource: AppIcons.download - width: Math.round(24 * DefaultStyle.dp) - height: Math.round(24 * DefaultStyle.dp) - colorizationColor: DefaultStyle.main2_600 + Component { + id: defaultView + Control.Control { + rightPadding: Math.round(17*DefaultStyle.dp) + + background: Rectangle { + id: bg + color: DefaultStyle.grey_100 + width: mainItem.width + height: mainItem.height + radius: Math.round(10 * DefaultStyle.dp) + } + contentItem: RowLayout { + spacing: Math.round(16 * DefaultStyle.dp) + Rectangle { + color: DefaultStyle.main2_200 + width: Math.round(58 * DefaultStyle.dp) + height: bg.height + radius: bg.radius + Rectangle { + anchors.right: parent.right + color: DefaultStyle.main2_200 + width: parent.width / 2 + height: parent.height + radius: parent.radius + + } + EffectImage { + z: parent.z + 1 + anchors.centerIn: parent + imageSource: defaultViewStack.imageSource + width: Math.round(22 * DefaultStyle.dp) + height: width + colorizationColor: DefaultStyle.main2_600 + } + } + ColumnLayout { + spacing: Math.round(1 * DefaultStyle.dp) + Text { + text: mainItem.name + Layout.fillWidth: true + font { + pixelSize: Typography.p2.pixelSize + weight: Typography.p2.weight + } + } + Text { + text: mainItem.fileSize + Layout.fillWidth: true + font { + pixelSize: Typography.p4.pixelSize + weight: Typography.p4.weight + } + } + } + } } } } + } Loader { diff --git a/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml b/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml index 2c8fa27f7..687a99206 100644 --- a/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml +++ b/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml @@ -67,7 +67,6 @@ Control.Control { contentItem: Control.StackView { id: sendingAreaStackView initialItem: textAreaComp - width: currentItem.width onHeightChanged: { mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding } diff --git a/Linphone/view/Page/Form/Chat/SelectedChatView.qml b/Linphone/view/Page/Form/Chat/SelectedChatView.qml index ab9346b1b..edcfded16 100644 --- a/Linphone/view/Page/Form/Chat/SelectedChatView.qml +++ b/Linphone/view/Page/Form/Chat/SelectedChatView.qml @@ -434,6 +434,8 @@ RowLayout { contentItem: Loader { id: contentLoader property bool showingMessageReactions: false + property bool showingSharedFiles: false + property bool showingMedias: false property bool showingImdnStatus: false property bool showingManageParticipants: false property bool showingEphemeralSettings: false @@ -445,11 +447,13 @@ RowLayout { ? messageReactionsComponent : showingImdnStatus ? messageImdnStatusComponent - : showingManageParticipants - ? manageParticipantsComponent - : mainItem.chat.core.isGroupChat - ? groupInfoComponent - : oneToOneInfoComponent + : showingSharedFiles + ? sharedFilesComponent + : showingManageParticipants + ? manageParticipantsComponent + : mainItem.chat.core.isGroupChat + ? groupInfoComponent + : oneToOneInfoComponent active: detailsPanel.visible onLoaded: { if (contentLoader.item && contentLoader.item.parentView) { @@ -463,6 +467,10 @@ RowLayout { OneOneConversationInfos { chatGui: mainItem.chat onEphemeralSettingsRequested: contentLoader.showingEphemeralSettings = true + onShowSharedFilesRequested: (showMedias) => { + contentLoader.showingSharedFiles = true + contentLoader.showingMedias = showMedias + } } } @@ -471,6 +479,10 @@ RowLayout { GroupConversationInfos { chatGui: mainItem.chat onManageParticipantsRequested: contentLoader.showingManageParticipants = true + onShowSharedFilesRequested: (showMedias) => { + contentLoader.showingSharedFiles = true + contentLoader.showingMedias = showMedias + } onEphemeralSettingsRequested: contentLoader.showingEphemeralSettings = true } } @@ -495,6 +507,23 @@ RowLayout { } } } + + Component { + id: sharedFilesComponent + MessageSharedFilesInfos { + chatGui: mainItem.chat + title: contentLoader.showingMedias + //: Shared medias + ? qsTr("shared_medias_title") + //: Shared documents + : qsTr("shared_documents_title") + filter: contentLoader.showingMedias ? ChatMessageFileProxy.FilterContentType.Medias : ChatMessageFileProxy.FilterContentType.Documents + onGoBackRequested: { + // detailsPanel.visible = false + contentLoader.showingSharedFiles = false + } + } + } Component { id: manageParticipantsComponent diff --git a/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml b/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml index 033764228..a881397a0 100644 --- a/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml +++ b/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml @@ -21,14 +21,25 @@ ColumnLayout { return chatCore && chatCore.meAdmin && !chatCore.isReadOnly } - Text { - font: Typography.h4 - color: DefaultStyle.main2_600 - text: title - Layout.topMargin: Math.round(5 * DefaultStyle.dp) - } + RowLayout { + Text { + font: Typography.h4 + color: DefaultStyle.main2_600 + text: title + Layout.topMargin: Math.round(5 * DefaultStyle.dp) + } + Item{Layout.fillWidth: true} + BigButton { + id: expandButton + style: ButtonStyle.noBackground + checkable: true + checked: true + icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow + } + } Rectangle { + visible: expandButton.checked Layout.fillWidth: true Layout.topMargin: Math.round(9 * DefaultStyle.dp) color: DefaultStyle.grey_100 diff --git a/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml b/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml index a81b3f0b4..626081504 100644 --- a/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml +++ b/Linphone/view/Page/Layout/Chat/GroupConversationInfos.qml @@ -17,6 +17,7 @@ ColumnLayout { property bool manageParticipants: false signal manageParticipantsRequested() signal ephemeralSettingsRequested() + signal showSharedFilesRequested(bool showMedias) spacing: 0 @@ -201,26 +202,29 @@ ColumnLayout { ChatInfoActionsGroup { Layout.topMargin: Math.round(30 * DefaultStyle.dp) + //: Medias & documents title: qsTr("group_infos_media_docs") entries: [ { icon: AppIcons.photo, visible: true, - text: qsTr("group_infos_media_docs"), + //: Shared medias + text: qsTr("group_infos_shared_medias"), color: DefaultStyle.main2_600, showRightArrow: true, action: function() { - console.log("group_infos_shared_media") + mainItem.showSharedFilesRequested(true) } }, { icon: AppIcons.pdf, visible: true, + //: Shared documents text: qsTr("group_infos_shared_docs"), color: DefaultStyle.main2_600, showRightArrow: true, action: function() { - console.log("Opening shared documents") + mainItem.showSharedFilesRequested(false) } } ] diff --git a/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml b/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml index a00020b5f..da533ed83 100644 --- a/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml +++ b/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml @@ -20,6 +20,7 @@ ColumnLayout { property alias tabbar: tabbar property alias listView: listView property var parentView + property alias content: contentLayout.children spacing: Math.round(25 * DefaultStyle.dp) @@ -41,6 +42,7 @@ ColumnLayout { } ColumnLayout { + id: contentLayout spacing: Math.round(21 * DefaultStyle.dp) Layout.leftMargin: Math.round(16 * DefaultStyle.dp) Layout.rightMargin: Math.round(16 * DefaultStyle.dp) diff --git a/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml b/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml new file mode 100644 index 000000000..c2b880704 --- /dev/null +++ b/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml @@ -0,0 +1,35 @@ +import QtCore +import QtQuick +import QtQuick.Layouts +import Linphone +import UtilsCpp + +MessageInfosLayout { + id: mainItem + spacing: Math.round(25 * DefaultStyle.dp) + property ChatGui chatGui + property int filter + tabbar.visible: false + + content: [ + GridView { + id: gridView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: contentHeight + cellWidth: mainItem.filter === ChatMessageFileProxy.FilterContentType.Documents ? width : width / 4 + cellHeight: mainItem.filter === ChatMessageFileProxy.FilterContentType.Documents ? Math.round(69 * DefaultStyle.dp) : width / 4 + model: ChatMessageFileProxy { + chat: mainItem.chatGui + filterType: mainItem.filter + } + delegate: FileView { + contentGui: modelData + showAsSquare: false + width: gridView.cellWidth - Math.round(2 * DefaultStyle.dp) + height: gridView.cellHeight - Math.round(2 * DefaultStyle.dp) + } + }, + Item{Layout.fillHeight: true} + ] +} \ No newline at end of file diff --git a/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml b/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml index ded694aa9..29707f78e 100644 --- a/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml +++ b/Linphone/view/Page/Layout/Chat/OneOneConversationInfos.qml @@ -17,6 +17,7 @@ ColumnLayout { property var parentView spacing: 0 signal ephemeralSettingsRequested() + signal showSharedFilesRequested() Avatar { @@ -119,7 +120,7 @@ ColumnLayout { color: DefaultStyle.main2_600, showRightArrow: true, action: function() { - console.log("Opening shared media") + mainItem.showSharedFilesRequested(true) } }, { @@ -129,7 +130,7 @@ ColumnLayout { color: DefaultStyle.main2_600, showRightArrow: true, action: function() { - console.log("Opening shared documents") + mainItem.showSharedFilesRequested(false) } } ] diff --git a/Linphone/view/Page/Main/Chat/ChatPage.qml b/Linphone/view/Page/Main/Chat/ChatPage.qml index f310ebff9..380a494b8 100644 --- a/Linphone/view/Page/Main/Chat/ChatPage.qml +++ b/Linphone/view/Page/Main/Chat/ChatPage.qml @@ -113,7 +113,7 @@ AbstractMainPage { height: Math.round(24 * DefaultStyle.dp) focus: true popup.x: 0 - KeyNavigation.right: newCallButton + KeyNavigation.right: newChatButton KeyNavigation.down: listStackView popup.contentItem: ColumnLayout { IconLabelButton {