delete history for chatroom

delete chat message

delete chat room
This commit is contained in:
Gaelle Braud 2025-05-05 14:54:10 +02:00
parent 179be1bb15
commit bdff2bddcd
24 changed files with 435 additions and 97 deletions

View file

@ -52,11 +52,11 @@
#include "core/call/CallGui.hpp"
#include "core/call/CallList.hpp"
#include "core/call/CallProxy.hpp"
#include "core/chat/ChatProxy.hpp"
#include "core/chat/message/ChatMessageProxy.hpp"
#include "core/chat/message/ChatMessageList.hpp"
#include "core/chat/message/ChatMessageGui.hpp"
#include "core/camera/CameraGui.hpp"
#include "core/chat/ChatProxy.hpp"
#include "core/chat/message/ChatMessageGui.hpp"
#include "core/chat/message/ChatMessageList.hpp"
#include "core/chat/message/ChatMessageProxy.hpp"
#include "core/conference/ConferenceGui.hpp"
#include "core/conference/ConferenceInfoGui.hpp"
#include "core/conference/ConferenceInfoProxy.hpp"
@ -263,7 +263,7 @@ void App::setAutoStart(bool enabled) {
// -----------------------------------------------------------------------------
App::App(int &argc, char *argv[])
: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
// Do not use APPLICATION_NAME here.
// The EXECUTABLE_NAME will be used in qt standard paths. It's our goal.
QThread::currentThread()->setPriority(QThread::HighPriority);
@ -526,7 +526,7 @@ void App::initCore() {
setLocale(settings->getConfigLocale());
setAutoStart(settings->getAutoStart());
setQuitOnLastWindowClosed(settings->getExitOnClose());
}
}
const QUrl url("qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml");
QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this,
@ -577,28 +577,28 @@ void App::initLocale() {
mLocale = QLocale(QLocale::English);
if (!installLocale(*this, *mDefaultTranslatorCore, mLocale)) qFatal("Unable to install default translator.");
// if (installLocale(*this, *mTranslatorCore, getLocale())) {
// qDebug() << "installed locale" << getLocale().name();
// return;
// }
// if (installLocale(*this, *mTranslatorCore, getLocale())) {
// qDebug() << "installed locale" << getLocale().name();
// return;
// }
// Try to use system locale.
// #ifdef Q_OS_MACOS
// Use this workaround if there is still an issue about detecting wrong language from system on Mac. Qt doesn't use
// the current system language on QLocale::system(). So we need to get it from user settings and overwrite its
// Locale.
// QSettings settings;
// QString preferredLanguage = settings.value("AppleLanguages").toStringList().first();
// QStringList qtLocale = QLocale::system().name().split('_');
// if(qtLocale[0] != preferredLanguage){
// qInfo() << "Override Qt language from " << qtLocale[0] << " to the preferred language : " <<
// preferredLanguage; qtLocale[0] = preferredLanguage;
// }
// QLocale sysLocale = QLocale(qtLocale.join('_'));
// #else
// Try to use system locale.
// #ifdef Q_OS_MACOS
// Use this workaround if there is still an issue about detecting wrong language from system on Mac. Qt doesn't use
// the current system language on QLocale::system(). So we need to get it from user settings and overwrite its
// Locale.
// QSettings settings;
// QString preferredLanguage = settings.value("AppleLanguages").toStringList().first();
// QStringList qtLocale = QLocale::system().name().split('_');
// if(qtLocale[0] != preferredLanguage){
// qInfo() << "Override Qt language from " << qtLocale[0] << " to the preferred language : " <<
// preferredLanguage; qtLocale[0] = preferredLanguage;
// }
// QLocale sysLocale = QLocale(qtLocale.join('_'));
// #else
QLocale sysLocale(QLocale::system().name()); // Use Locale from name because Qt has a bug where it didn't use the
// QLocale::language (aka : translator.language != locale.language) on
// Mac. #endif
// QLocale::language (aka : translator.language != locale.language) on
// Mac. #endif
if (installLocale(*this, *mTranslatorCore, sysLocale)) {
qDebug() << "installed sys locale" << sysLocale.name();
setLocale(sysLocale.name());
@ -785,34 +785,36 @@ void App::createCommandParser() {
//: "A free and open source SIP video-phone."
mParser->setApplicationDescription(tr("application_description"));
//: "Send an order to the application towards a command line"
mParser->addPositionalArgument("command", tr("command_line_arg_order").replace("%1", APPLICATION_NAME), "[command]");
mParser->addPositionalArgument("command", tr("command_line_arg_order").replace("%1", APPLICATION_NAME),
"[command]");
mParser->addOptions({
//: "Show this help"
{{"h", "help"}, tr("command_line_option_show_help")},
//: "Show this help"
{{"h", "help"}, tr("command_line_option_show_help")},
//{"cli-help", tr("commandLineOptionCliHelp").replace("%1", APPLICATION_NAME)},
//:"Show app version"
{{"v", "version"}, tr("command_line_option_show_app_version")},
//:"Show app version"
{{"v", "version"}, tr("command_line_option_show_app_version")},
//{"config", tr("command_line_option_config").replace("%1", EXECUTABLE_NAME), tr("command_line_option_config_arg")},
//{"config", tr("command_line_option_config").replace("%1", EXECUTABLE_NAME),
// tr("command_line_option_config_arg")},
{"fetch-config",
//: "Specify the linphone configuration file to be fetched. It will be merged with the current configuration."
tr("command_line_option_config_to_fetch")
.replace("%1", EXECUTABLE_NAME),
//: "URL, path or file"
tr("command_line_option_config_to_fetch_arg")},
//: "Specify the linphone configuration file to be fetched. It will be merged with the current configuration."
tr("command_line_option_config_to_fetch").replace("%1", EXECUTABLE_NAME),
//: "URL, path or file"
tr("command_line_option_config_to_fetch_arg")},
//{{"c", "call"}, tr("command_line_option_call").replace("%1", EXECUTABLE_NAME), tr("command_line_option_call_arg")},
//{{"c", "call"}, tr("command_line_option_call").replace("%1", EXECUTABLE_NAME),
// tr("command_line_option_call_arg")},
{"minimized", tr("command_line_option_minimized")},
{"minimized", tr("command_line_option_minimized")},
//: "Log to stdout some debug information while running"
{{"V", "verbose"}, tr("command_line_option_log_to_stdout")},
//: "Log to stdout some debug information while running"
{{"V", "verbose"}, tr("command_line_option_log_to_stdout")},
//: "Print only logs from the application"
{"qt-logs-only", tr("command_line_option_print_app_logs_only")},
//: "Print only logs from the application"
{"qt-logs-only", tr("command_line_option_print_app_logs_only")},
});
}
// Should be call only at first start
@ -1174,7 +1176,7 @@ void App::setSysTrayIcon() {
//: "Afficher"
restoreAction->setText(visible ? tr("hide_action") : tr("show_action"));
};
setRestoreActionText(root->isVisible());
setRestoreActionText(root ? root->isVisible() : false);
connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText);
root->connect(restoreAction, &QAction::triggered, this, [this, restoreAction](bool checked) {

View file

@ -88,18 +88,80 @@ ChatCore::~ChatCore() {
void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
mChatModelConnection = SafeConnection<ChatCore, ChatModel>::create(me, mChatModel);
// mChatModelConnection->makeConnectToCore(&ChatCore::lSetMicrophoneMuted, [this](bool isMuted) {
// mChatModelConnection->invokeToModel(
// [this, isMuted]() { mChatModel->setMicrophoneMuted(isMuted); });
// });
mChatModelConnection->makeConnectToCore(&ChatCore::lDeleteHistory, [this]() {
mChatModelConnection->invokeToModel([this]() { mChatModel->deleteHistory(); });
});
mChatModelConnection->makeConnectToModel(&ChatModel::historyDeleted, [this]() {
mChatModelConnection->invokeToCore([this]() {
qDebug() << log().arg("history deleted for chatRoom") << this;
clearMessagesList();
Utils::showInformationPopup(tr("Supprimé"), tr("L'historique des messages a été supprimé."), true);
});
});
mChatModelConnection->makeConnectToCore(&ChatCore::lUpdateUnreadCount, [this]() {
mChatModelConnection->invokeToModel([this]() {
auto count = mChatModel->getUnreadMessagesCount();
mChatModelConnection->invokeToCore([this, count] { setUnreadMessagesCount(count); });
});
});
mChatModelConnection->makeConnectToCore(&ChatCore::lDelete, [this]() {
mChatModelConnection->invokeToModel([this]() { mChatModel->deleteChatRoom(); });
});
mChatModelConnection->makeConnectToModel(
&ChatModel::deleted, [this]() { mChatModelConnection->invokeToCore([this]() { emit deleted(); }); });
mChatModelConnection->makeConnectToModel(&ChatModel::chatMessageReceived,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
if (mChatModel->getMonitor() != chatRoom) return;
qDebug() << "MESSAGE RECEIVED IN CHATROOM" << mChatModel->getTitle();
// mChatModelConnection->invokeToCore([this, isMuted]() {
// setMicrophoneMuted(isMuted); });
emit lUpdateLastMessage();
emit lUpdateUnreadCount();
auto message = eventLog->getChatMessage();
qDebug() << "EVENT LOG RECEIVED IN CHATROOM" << mChatModel->getTitle();
if (message) {
auto newMessage = ChatMessageCore::create(message);
mChatModelConnection->invokeToCore([this, newMessage]() {
qDebug() << log().arg("append message to chatRoom") << this;
appendMessageToMessageList(newMessage);
});
}
});
mChatModelConnection->makeConnectToModel(
&ChatModel::chatMessagesReceived, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::list<std::shared_ptr<linphone::EventLog>> &chatMessages) {
if (mChatModel->getMonitor() != chatRoom) return;
emit lUpdateLastMessage();
emit lUpdateUnreadCount();
qDebug() << "EVENT LOGS RECEIVED IN CHATROOM" << mChatModel->getTitle();
QList<QSharedPointer<ChatMessageCore>> list;
for (auto &m : chatMessages) {
auto message = m->getChatMessage();
if (message) {
auto newMessage = ChatMessageCore::create(message);
list.push_back(newMessage);
}
}
mChatModelConnection->invokeToCore([this, list]() {
qDebug() << log().arg("append messages to chatRoom") << this;
appendMessagesToMessageList(list);
});
});
mChatModelConnection->makeConnectToCore(&ChatCore::lMarkAsRead, [this]() {
mChatModelConnection->invokeToModel([this]() { mChatModel->markAsRead(); });
});
mChatModelConnection->makeConnectToModel(&ChatModel::messagesRead, [this]() {
auto unread = mChatModel->getUnreadMessagesCount();
mChatModelConnection->invokeToCore([this, unread]() { setUnreadMessagesCount(unread); });
});
mChatModelConnection->makeConnectToCore(&ChatCore::lUpdateLastMessage, [this]() {
mChatModelConnection->invokeToModel([this]() {
auto message = mChatModel->getLastMessageInHistory();
mChatModelConnection->invokeToCore([this, message]() { setLastMessageInHistory(message); });
});
});
}
QDateTime ChatCore::getLastUpdatedTime() const {
@ -175,6 +237,7 @@ void ChatCore::setUnreadMessagesCount(int count) {
QList<QSharedPointer<ChatMessageCore>> ChatCore::getChatMessageList() const {
return mChatMessageList;
}
void ChatCore::resetChatMessageList(QList<QSharedPointer<ChatMessageCore>> list) {
mChatMessageList = list;
emit messageListChanged();
@ -190,6 +253,12 @@ void ChatCore::appendMessagesToMessageList(QList<QSharedPointer<ChatMessageCore>
if (nbAdded > 0) emit messageListChanged();
}
void ChatCore::appendMessageToMessageList(QSharedPointer<ChatMessageCore> message) {
if (mChatMessageList.contains(message)) return;
mChatMessageList.append(message);
emit messageListChanged();
}
void ChatCore::removeMessagesFromMessageList(QList<QSharedPointer<ChatMessageCore>> list) {
int nbRemoved = 0;
for (auto &message : list) {
@ -201,6 +270,11 @@ void ChatCore::removeMessagesFromMessageList(QList<QSharedPointer<ChatMessageCor
if (nbRemoved > 0) emit messageListChanged();
}
void ChatCore::clearMessagesList() {
mChatMessageList.clear();
emit messageListChanged();
}
std::shared_ptr<ChatModel> ChatCore::getModel() const {
return mChatModel;
}

View file

@ -70,8 +70,10 @@ public:
QList<QSharedPointer<ChatMessageCore>> getChatMessageList() const;
void resetChatMessageList(QList<QSharedPointer<ChatMessageCore>> list);
void appendMessageToMessageList(QSharedPointer<ChatMessageCore> message);
void appendMessagesToMessageList(QList<QSharedPointer<ChatMessageCore>> list);
void removeMessagesFromMessageList(QList<QSharedPointer<ChatMessageCore>> list);
void clearMessagesList();
QString getAvatarUri() const;
void setAvatarUri(QString avatarUri);
@ -86,6 +88,14 @@ signals:
void unreadMessagesCountChanged(int count);
void messageListChanged();
void avatarUriChanged();
void deleted();
void lDeleteMessage();
void lDelete();
void lDeleteHistory();
void lMarkAsRead();
void lUpdateLastMessage();
void lUpdateUnreadCount();
private:
QString id;

View file

@ -67,6 +67,17 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
chats->push_back(model);
}
mModelConnection->invokeToCore([this, chats]() {
for (auto &chat : getSharedList<ChatCore>()) {
if (chat) disconnect(chat.get(), &ChatCore::deleted, this, nullptr);
}
for (auto &chat : *chats) {
connect(chat.get(), &ChatCore::deleted, this, [this, chat] {
remove(chat);
// We cannot use countChanged here because it is called before mList
// really has removed the item, then emit specific signal
emit chatRemoved(chat ? new ChatGui(chat) : nullptr);
});
}
mustBeInMainThread(getClassName());
resetData<ChatCore>(*chats);
delete chats;
@ -78,7 +89,7 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
&CoreModel::chatRoomStateChanged,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom,
linphone::ChatRoom::State state) {
// check account, filtre, puis ajout si c'est bon
// check account, filter, then add if ok
if (chatRoom->getAccount() == core->getDefaultAccount()) {
if (state == linphone::ChatRoom::State::Created) {
auto list = getSharedList<ChatCore>();

View file

@ -46,6 +46,7 @@ public:
signals:
void lUpdate();
void filterChanged(QString filter);
void chatRemoved(ChatGui *chat);
private:
QString mFilter;

View file

@ -42,6 +42,7 @@ void ChatProxy::setSourceModel(QAbstractItemModel *model) {
if (newChatList) {
connect(this, &ChatProxy::filterTextChanged, newChatList,
[this, newChatList] { emit newChatList->filterChanged(getFilterText()); });
connect(newChatList, &ChatList::chatRemoved, this, &ChatProxy::chatRemoved);
}
setSourceModels(new SortFilterList(model));
sort(0);

View file

@ -41,6 +41,9 @@ public:
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
signals:
void chatRemoved(ChatGui *chat);
protected:
QSharedPointer<ChatList> mList;
DECLARE_ABSTRACT_OBJECT

View file

@ -20,6 +20,7 @@
#include "ChatMessageCore.hpp"
#include "core/App.hpp"
#include "core/chat/ChatCore.hpp"
#include "model/tool/ToolModel.hpp"
DEFINE_ABSTRACT_OBJECT(ChatMessageCore)
@ -51,6 +52,13 @@ ChatMessageCore::~ChatMessageCore() {
void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
mChatMessageModelConnection = SafeConnection<ChatMessageCore, ChatMessageModel>::create(me, mChatMessageModel);
mChatMessageModelConnection->makeConnectToCore(&ChatMessageCore::lDelete, [this] {
mChatMessageModelConnection->invokeToModel([this] { mChatMessageModel->deleteMessageFromChatRoom(); });
});
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::messageDeleted, [this]() {
Utils::showInformationPopup(tr("Supprimé"), tr("Message supprimé"), true);
emit deleted();
});
}
QDateTime ChatMessageCore::getTimestamp() const {
@ -93,3 +101,7 @@ void ChatMessageCore::setIsRemoteMessage(bool isRemote) {
emit isRemoteMessageChanged(isRemote);
}
}
std::shared_ptr<ChatMessageModel> ChatMessageCore::getModel() const {
return mChatMessageModel;
}

View file

@ -29,6 +29,8 @@
#include <linphone++/linphone.hh>
class ChatCore;
class ChatMessageCore : public QObject, public AbstractObject {
Q_OBJECT
Q_PROPERTY(QDateTime timestamp READ getTimestamp WRITE setTimestamp NOTIFY timestampChanged)
@ -55,14 +57,18 @@ public:
bool isRemoteMessage() const;
void setIsRemoteMessage(bool isRemote);
std::shared_ptr<ChatMessageModel> getModel() const;
signals:
void timestampChanged(QDateTime timestamp);
void textChanged(QString text);
void isRemoteMessageChanged(bool isRemote);
void lDelete();
void deleted();
private:
DECLARE_ABSTRACT_OBJECT
QString mText;
DECLARE_ABSTRACT_OBJECT QString mText;
QString mPeerAddress;
QString mPeerName;
QDateTime mTimestamp;

View file

@ -21,9 +21,9 @@
#include "ChatMessageList.hpp"
#include "ChatMessageCore.hpp"
#include "ChatMessageGui.hpp"
#include "core/App.hpp"
#include "core/chat/ChatCore.hpp"
#include "core/chat/ChatGui.hpp"
#include "core/App.hpp"
#include <QSharedPointer>
#include <linphone++/linphone.hh>
@ -39,7 +39,8 @@ QSharedPointer<ChatMessageList> ChatMessageList::create() {
return model;
}
QSharedPointer<ChatMessageCore> ChatMessageList::createChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &chatMessage) {
QSharedPointer<ChatMessageCore>
ChatMessageList::createChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &chatMessage) {
auto chatMessageCore = ChatMessageCore::create(chatMessage);
return chatMessageCore;
}
@ -55,7 +56,7 @@ ChatMessageList::~ChatMessageList() {
mModelConnection = nullptr;
}
ChatGui* ChatMessageList::getChat() const {
ChatGui *ChatMessageList::getChat() const {
if (mChatCore) return new ChatGui(mChatCore);
else return nullptr;
}
@ -66,12 +67,14 @@ QSharedPointer<ChatCore> ChatMessageList::getChatCore() const {
void ChatMessageList::setChatCore(QSharedPointer<ChatCore> core) {
if (mChatCore != core) {
if (mChatCore) disconnect(mChatCore.get(), &ChatCore::messageListChanged, this, nullptr);
mChatCore = core;
if (mChatCore) connect(mChatCore.get(), &ChatCore::messageListChanged, this, &ChatMessageList::lUpdate);
emit chatChanged();
}
}
void ChatMessageList::setChatGui(ChatGui* chat) {
void ChatMessageList::setChatGui(ChatGui *chat) {
auto chatCore = chat ? chat->mCore : nullptr;
setChatCore(chatCore);
}
@ -80,17 +83,17 @@ void ChatMessageList::setSelf(QSharedPointer<ChatMessageList> me) {
mModelConnection = SafeConnection<ChatMessageList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&ChatMessageList::lUpdate, [this]() {
// mModelConnection->invokeToModel([this]() {
// // Avoid copy to lambdas
// QList<QSharedPointer<CallCore>> *calls = new QList<QSharedPointer<CallCore>>();
// mustBeInLinphoneThread(getClassName());
// mModelConnection->invokeToCore([this, calls, currentCallCore]() {
// mustBeInMainThread(getClassName());
// resetData<CallCore>(*calls);
// });
// });
for (auto &message : getSharedList<ChatMessageCore>()) {
if (message) disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr);
}
if (!mChatCore) return;
auto messages = mChatCore->getChatMessageList();
for (auto &message : messages) {
connect(message.get(), &ChatMessageCore::deleted, this, [this, message] {
emit mChatCore->lUpdateLastMessage();
remove(message);
});
}
resetData<ChatMessageCore>(messages);
});
@ -104,6 +107,7 @@ void ChatMessageList::setSelf(QSharedPointer<ChatMessageList> me) {
QVariant ChatMessageList::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 ChatMessageGui(mList[row].objectCast<ChatMessageCore>()));
if (role == Qt::DisplayRole)
return QVariant::fromValue(new ChatMessageGui(mList[row].objectCast<ChatMessageCore>()));
return QVariant();
}

View file

@ -103,6 +103,22 @@ QString ChatModel::getLastMessageInHistory(std::list<std::shared_ptr<linphone::C
int ChatModel::getUnreadMessagesCount() const {
return mMonitor->getUnreadMessagesCount();
}
void ChatModel::markAsRead() {
mMonitor->markAsRead();
emit messagesRead();
}
void ChatModel::deleteHistory() {
mMonitor->deleteHistory();
emit historyDeleted();
}
void ChatModel::deleteChatRoom() {
CoreModel::getInstance()->getCore()->deleteChatRoom(mMonitor);
emit deleted();
}
//---------------------------------------------------------------//
void ChatModel::onIsComposingReceived(const std::shared_ptr<linphone::ChatRoom> &chatRoom,

View file

@ -42,8 +42,16 @@ public:
QString getPeerAddress() const;
QString getLastMessageInHistory(std::list<std::shared_ptr<linphone::Content>> startList = {}) const;
int getUnreadMessagesCount() const;
void markAsRead();
std::list<std::shared_ptr<linphone::ChatMessage>> getHistory() const;
QString getIdentifier() const;
void deleteHistory();
void deleteChatRoom();
signals:
void historyDeleted();
void messagesRead();
void deleted();
private:
DECLARE_ABSTRACT_OBJECT

View file

@ -59,3 +59,11 @@ ChatMessageModel::onFileTransferSend(const std::shared_ptr<linphone::ChatMessage
size_t size) {
return nullptr;
}
void ChatMessageModel::deleteMessageFromChatRoom() {
auto chatRoom = mMonitor->getChatRoom();
if (chatRoom) {
chatRoom->deleteMessage(mMonitor);
emit messageDeleted();
}
}

View file

@ -42,6 +42,11 @@ public:
QString getPeerAddress() const;
void deleteMessageFromChatRoom();
signals:
void messageDeleted();
private:
DECLARE_ABSTRACT_OBJECT
virtual std::shared_ptr<linphone::Buffer> onFileTransferSend(const std::shared_ptr<linphone::ChatMessage> &message,

View file

@ -22,6 +22,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Button/Settings/SwitchSetting.qml
view/Control/Container/Carousel.qml
view/Control/Container/DetailLayout.qml
view/Control/Container/FormItemLayout.qml
view/Control/Container/ScrollBar.qml
view/Control/Container/Section.qml

View file

@ -12,6 +12,7 @@ ColumnLayout {
spacing: Math.round(30 * DefaultStyle.dp)
property var callHistoryGui
property var chatGui
property FriendGui contact
property var conferenceInfo: callHistoryGui?.core.conferenceInfo

View file

@ -0,0 +1,54 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
ColumnLayout {
id: mainItem
spacing: Math.round(15 * DefaultStyle.dp)
property string label
property var icon
property alias content: contentControl.contentItem
signal titleIconClicked
RowLayout {
spacing: Math.round(10 * DefaultStyle.dp)
Text {
text: mainItem.label
color: DefaultStyle.main1_500_main
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
RoundButton {
visible: mainItem.icon != undefined
icon.source: mainItem.icon
style: ButtonStyle.noBackgroundOrange
onClicked: mainItem.titleIconClicked()
}
Item {
Layout.fillWidth: true
}
RoundButton {
id: expandButton
style: ButtonStyle.noBackground
checkable: true
checked: true
icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow
KeyNavigation.down: contentControl
}
}
RoundedPane {
id: contentControl
visible: expandButton.checked
Layout.fillWidth: true
leftPadding: Math.round(20 * DefaultStyle.dp)
rightPadding: Math.round(20 * DefaultStyle.dp)
topPadding: Math.round(17 * DefaultStyle.dp)
bottomPadding: Math.round(17 * DefaultStyle.dp)
}
}

View file

@ -31,13 +31,18 @@ ListView {
}
filterText: mainItem.searchText
onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: Math.max(
20,
2 * mainItem.height / (Math.round(56 * DefaultStyle.dp)))
displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: {
mainItem.resultsReceived()
}
initialDisplayItems: Math.max(
20,
2 * mainItem.height / (Math.round(56 * DefaultStyle.dp)))
displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: {
mainItem.resultsReceived()
}
onChatRemoved: {
var indexToSelect = mainItem.currentIndex
mainItem.currentIndex = -1
mainItem.currentIndex = indexToSelect
}
}
// flickDeceleration: 10000
spacing: Math.round(10 * DefaultStyle.dp)
@ -56,19 +61,15 @@ ListView {
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0
onCountChanged: {
if (currentIndex < 0 && count > 0) {
mainItem.currentIndex = 0 // Select first item after loading model
}
if (atYBeginning)
positionViewAtBeginning() // Stay at beginning
}
onAtYEndChanged: {
if (atYEnd && count > 0) {
chatProxy.displayMore()
}
}
onCountChanged: {
if (count > 0 && currentIndex < 0) currentIndex = 0
}
//----------------------------------------------------------------
function moveToCurrentItem() {
@ -93,10 +94,6 @@ ListView {
}
// //----------------------------------------------------------------
onVisibleChanged: {
// if (!visible)
// currentIndex = -1
}
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
@ -218,8 +215,39 @@ ListView {
//sourdine, éphémère, IMDN
}
}
PopupButton {
id: chatroomPopup
// z: 1
popup.x: 0
popup.padding: Math.round(10 * DefaultStyle.dp)
visible: mouseArea.containsMouse || hovered || popup.opened
enabled: visible
popup.contentItem: ColumnLayout {
IconLabelButton {
//: "Supprimer"
text: qsTr("chat_room_delete")
icon.source: AppIcons.trashCan
spacing: Math.round(10 * DefaultStyle.dp)
Layout.fillWidth: true
onClicked: {
mainWindow.showConfirmationLambdaPopup(qsTr("Supprimer le chat ?"),
qsTr("Le chat ainsi que tous ses messages seront supprimés. Souhaitez-vous continuer ?"),
"",
function(confirmed) {
if (confirmed) {
modelData.core.lDelete()
chatroomPopup.close()
}
})
}
style: ButtonStyle.noBackgroundRed
}
}
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
focus: true

View file

@ -16,10 +16,59 @@ Control.Control {
property string imgUrl
property string contentText
topPadding: Math.round(12 * DefaultStyle.dp)
bottomPadding: Math.round(12 * DefaultStyle.dp)
leftPadding: Math.round(18 * DefaultStyle.dp)
rightPadding: Math.round(18 * DefaultStyle.dp)
signal messageDeletionRequested()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: (mouse) => {
console.log("message clicked")
if (mouse.button === Qt.RightButton) {
optionsMenu.x = mouse.x
optionsMenu.open()
}
}
}
Popup {
id: optionsMenu
background: Item {
anchors.fill: parent
Rectangle {
id: popupBackground
anchors.fill: parent
color: DefaultStyle.grey_0
radius: Math.round(16 * DefaultStyle.dp)
}
MultiEffect {
source: popupBackground
anchors.fill: popupBackground
shadowEnabled: true
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.4
}
}
contentItem: ColumnLayout {
IconLabelButton {
//: "Supprimer"
text: qsTr("chat_message_delete")
icon.source: AppIcons.trashCan
spacing: Math.round(10 * DefaultStyle.dp)
Layout.fillWidth: true
onClicked: {
mainItem.messageDeletionRequested()
optionsMenu.close()
}
style: ButtonStyle.noBackgroundRed
}
}
}
background: Item {
anchors.fill: parent

View file

@ -15,6 +15,8 @@ ListView {
Component.onCompleted: positionViewAtEnd()
onCountChanged: positionViewAtEnd();
model: ChatMessageProxy {
chatGui: mainItem.chat
}
@ -34,5 +36,7 @@ ListView {
anchors.right: !isRemoteMessage && parent
? parent.right
: undefined
onMessageDeletionRequested: modelData.core.lDelete()
}
}

View file

@ -15,6 +15,11 @@ RowLayout {
property CallGui call
property alias callHeaderContent: splitPanel.headerContent
spacing: 0
onChatChanged: {
// TODO : call when all messages read after scroll to unread feature available
if (chat) chat.core.lMarkAsRead()
}
MainRightPanel {
id: splitPanel
Layout.fillWidth: true
@ -62,9 +67,10 @@ RowLayout {
BigButton {
style: ButtonStyle.noBackground
checkable: true
checkedImageColor: DefaultStyle.main1_500_main
icon.source: AppIcons.info
onCheckedChanged: {
detailsPanel.visible = !detailsPanel.visible
}
}
}
@ -184,8 +190,46 @@ RowLayout {
color: DefaultStyle.grey_0
anchors.fill: parent
}
contentItem: ColumnLayout {
contentItem: CallHistoryLayout {
chatGui: mainItem.chat
detailContent: ColumnLayout {
DetailLayout {
//: Other actions
label: qsTr("Autres actions")
content: ColumnLayout {
// IconLabelButton {
// Layout.fillWidth: true
// Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
// icon.source: AppIcons.signOut
// //: "Quitter la conversation"
// text: qsTr("Quitter la conversation")
// onClicked: {
// }
// style: ButtonStyle.noBackground
// }
IconLabelButton {
Layout.fillWidth: true
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
icon.source: AppIcons.trashCan
//: "Supprimer l'historique"
text: qsTr("Supprimer l'historique")
onClicked: {
mainWindow.showConfirmationLambdaPopup(qsTr("Supprimer l'historique ?"),
qsTr("Tous les messages seront supprimés de la chatroom.Souhaitez-vous continuer ?"),
"",
function(confirmed) {
if (confirmed) {
mainItem.chat.core.lDeleteHistory()
}
})
}
style: ButtonStyle.noBackgroundRed
}
}
}
Item {Layout.fillHeight: true}
}
}
}
}

View file

@ -154,9 +154,6 @@ AbstractMainPage {
onCurrentIndexChanged: {
mainItem.selectedChatGui = model.getAt(currentIndex)
}
onCountChanged: {
mainItem.selectedChatGui = model.getAt(currentIndex)
}
Connections {
target: mainItem
@ -185,9 +182,6 @@ AbstractMainPage {
objectName: "newChatItem"
width: parent?.width
height: parent?.height
Control.StackView.onActivated: {
callContactsList.forceActiveFocus()
}
ColumnLayout {
anchors.fill: parent
spacing: 0

View file

@ -92,6 +92,7 @@ QtObject {
property string settings: "image://internal/gear.svg"
property string clock: "image://internal/clock.svg"
property string note: "image://internal/note.svg"
property string signOut: "image://internal/sign-out.svg"
property string userRectangle: "image://internal/user-rectangle.svg"
property string usersTwo: "image://internal/users.svg"
property string globe: "image://internal/globe-hemisphere-west.svg"

View file

@ -132,7 +132,7 @@
normal: "#00000000",
hovered: "#00000000",
pressed: "#00000000",
checked: Linphone.DefaultStyle.main1_500main
checked: "#00000000"
},
text: {
normal: Linphone.DefaultStyle.main2_600,
@ -144,7 +144,7 @@
normal: Linphone.DefaultStyle.main2_600,
hovered: Linphone.DefaultStyle.main2_700,
pressed: Linphone.DefaultStyle.main2_800,
checked: Linphone.DefaultStyle.main1_500main
checked: Linphone.DefaultStyle.main1_500main,
}
}
@ -163,7 +163,8 @@
image: {
normal: Linphone.DefaultStyle.danger_500main,
hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900
pressed: Linphone.DefaultStyle.danger_900,
checked: Linphone.DefaultStyle.danger_900
}
}