Meeting invitation display in chat conversations
This commit is contained in:
parent
ac7164fb0b
commit
f8276ac834
13 changed files with 479 additions and 20 deletions
|
|
@ -39,6 +39,8 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
||||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||||
mChatMessageModel->setSelf(mChatMessageModel);
|
mChatMessageModel->setSelf(mChatMessageModel);
|
||||||
mText = mChatMessageModel->getText();
|
mText = mChatMessageModel->getText();
|
||||||
|
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||||
|
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||||
auto from = chatmessage->getFromAddress();
|
auto from = chatmessage->getFromAddress();
|
||||||
auto to = chatmessage->getLocalAddress();
|
auto to = chatmessage->getLocalAddress();
|
||||||
|
|
@ -56,6 +58,12 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
||||||
mIsRead = chatmessage->isRead();
|
mIsRead = chatmessage->isRead();
|
||||||
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
||||||
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
||||||
|
for (auto content : chatmessage->getContents()) {
|
||||||
|
if (content->isIcalendar()) {
|
||||||
|
auto conferenceInfo = linphone::Factory::get()->createConferenceInfoFromIcalendarContent(content);
|
||||||
|
mConferenceInfo = ConferenceInfoCore::create(conferenceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessageCore::~ChatMessageCore() {
|
ChatMessageCore::~ChatMessageCore() {
|
||||||
|
|
@ -165,3 +173,7 @@ void ChatMessageCore::setMessageState(LinphoneEnums::ChatMessageState state) {
|
||||||
std::shared_ptr<ChatMessageModel> ChatMessageCore::getModel() const {
|
std::shared_ptr<ChatMessageModel> ChatMessageCore::getModel() const {
|
||||||
return mChatMessageModel;
|
return mChatMessageModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConferenceInfoGui *ChatMessageCore::getConferenceInfoGui() const {
|
||||||
|
return mConferenceInfo ? new ConferenceInfoGui(mConferenceInfo) : nullptr;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
#ifndef CHATMESSAGECORE_H_
|
#ifndef CHATMESSAGECORE_H_
|
||||||
#define CHATMESSAGECORE_H_
|
#define CHATMESSAGECORE_H_
|
||||||
|
|
||||||
|
#include "core/conference/ConferenceInfoCore.hpp"
|
||||||
|
#include "core/conference/ConferenceInfoGui.hpp"
|
||||||
#include "model/chat/message/ChatMessageModel.hpp"
|
#include "model/chat/message/ChatMessageModel.hpp"
|
||||||
#include "tool/AbstractObject.hpp"
|
#include "tool/AbstractObject.hpp"
|
||||||
#include "tool/thread/SafeConnection.hpp"
|
#include "tool/thread/SafeConnection.hpp"
|
||||||
|
|
@ -35,6 +37,8 @@ class ChatMessageCore : public QObject, public AbstractObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QDateTime timestamp READ getTimestamp WRITE setTimestamp NOTIFY timestampChanged)
|
Q_PROPERTY(QDateTime timestamp READ getTimestamp WRITE setTimestamp NOTIFY timestampChanged)
|
||||||
Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged)
|
Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged)
|
||||||
|
Q_PROPERTY(QString utf8Text MEMBER mUtf8Text CONSTANT)
|
||||||
|
Q_PROPERTY(bool hasTextContent MEMBER mHasTextContent CONSTANT)
|
||||||
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT)
|
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT)
|
||||||
Q_PROPERTY(QString fromAddress READ getFromAddress CONSTANT)
|
Q_PROPERTY(QString fromAddress READ getFromAddress CONSTANT)
|
||||||
Q_PROPERTY(QString toAddress READ getToAddress CONSTANT)
|
Q_PROPERTY(QString toAddress READ getToAddress CONSTANT)
|
||||||
|
|
@ -45,6 +49,7 @@ class ChatMessageCore : public QObject, public AbstractObject {
|
||||||
Q_PROPERTY(bool isRemoteMessage READ isRemoteMessage CONSTANT)
|
Q_PROPERTY(bool isRemoteMessage READ isRemoteMessage CONSTANT)
|
||||||
Q_PROPERTY(bool isFromChatGroup READ isFromChatGroup CONSTANT)
|
Q_PROPERTY(bool isFromChatGroup READ isFromChatGroup CONSTANT)
|
||||||
Q_PROPERTY(bool isRead READ isRead WRITE setIsRead NOTIFY isReadChanged)
|
Q_PROPERTY(bool isRead READ isRead WRITE setIsRead NOTIFY isReadChanged)
|
||||||
|
Q_PROPERTY(ConferenceInfoGui *conferenceInfo READ getConferenceInfoGui CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QSharedPointer<ChatMessageCore> create(const std::shared_ptr<linphone::ChatMessage> &chatmessage);
|
static QSharedPointer<ChatMessageCore> create(const std::shared_ptr<linphone::ChatMessage> &chatmessage);
|
||||||
|
|
@ -75,10 +80,12 @@ public:
|
||||||
void setMessageState(LinphoneEnums::ChatMessageState state);
|
void setMessageState(LinphoneEnums::ChatMessageState state);
|
||||||
|
|
||||||
std::shared_ptr<ChatMessageModel> getModel() const;
|
std::shared_ptr<ChatMessageModel> getModel() const;
|
||||||
|
ConferenceInfoGui *getConferenceInfoGui() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void timestampChanged(QDateTime timestamp);
|
void timestampChanged(QDateTime timestamp);
|
||||||
void textChanged(QString text);
|
void textChanged(QString text);
|
||||||
|
void utf8TextChanged(QString text);
|
||||||
void isReadChanged(bool read);
|
void isReadChanged(bool read);
|
||||||
void isRemoteMessageChanged(bool isRemote);
|
void isRemoteMessageChanged(bool isRemote);
|
||||||
void messageStateChanged();
|
void messageStateChanged();
|
||||||
|
|
@ -90,6 +97,8 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_ABSTRACT_OBJECT QString mText;
|
DECLARE_ABSTRACT_OBJECT QString mText;
|
||||||
|
QString mUtf8Text;
|
||||||
|
bool mHasTextContent;
|
||||||
QString mPeerAddress;
|
QString mPeerAddress;
|
||||||
QString mFromAddress;
|
QString mFromAddress;
|
||||||
QString mToAddress;
|
QString mToAddress;
|
||||||
|
|
@ -101,6 +110,7 @@ private:
|
||||||
bool mIsFromChatGroup = false;
|
bool mIsFromChatGroup = false;
|
||||||
bool mIsRead = false;
|
bool mIsRead = false;
|
||||||
LinphoneEnums::ChatMessageState mMessageState;
|
LinphoneEnums::ChatMessageState mMessageState;
|
||||||
|
QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<ChatMessageModel> mChatMessageModel;
|
std::shared_ptr<ChatMessageModel> mChatMessageModel;
|
||||||
QSharedPointer<SafeConnection<ChatMessageCore, ChatMessageModel>> mChatMessageModelConnection;
|
QSharedPointer<SafeConnection<ChatMessageCore, ChatMessageModel>> mChatMessageModelConnection;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Belledonne Communications SARL.
|
* Copyright (c) 2021 Belledonne Communications SARL.
|
||||||
*
|
*
|
||||||
* This file is part of linphone-desktop
|
* This file is part of linphone-desktop
|
||||||
|
|
@ -74,11 +74,7 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo>
|
||||||
mEndDateTime = mDateTime.addSecs(mDuration * 60);
|
mEndDateTime = mDateTime.addSecs(mDuration * 60);
|
||||||
mIsScheduled = mDateTime.isValid();
|
mIsScheduled = mDateTime.isValid();
|
||||||
mOrganizerAddress = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->asStringUriOnly());
|
mOrganizerAddress = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->asStringUriOnly());
|
||||||
mOrganizerName = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->getDisplayName());
|
mOrganizerName = mConferenceInfoModel->getOrganizerName();
|
||||||
if (mOrganizerName.isEmpty()) {
|
|
||||||
mOrganizerName = Utils::coreStringToAppString(conferenceInfo->getOrganizer()->getUsername());
|
|
||||||
mOrganizerName.replace(".", " ");
|
|
||||||
}
|
|
||||||
mSubject = Utils::coreStringToAppString(conferenceInfo->getSubject());
|
mSubject = Utils::coreStringToAppString(conferenceInfo->getSubject());
|
||||||
mDescription = Utils::coreStringToAppString(conferenceInfo->getDescription());
|
mDescription = Utils::coreStringToAppString(conferenceInfo->getDescription());
|
||||||
mIsEnded = getDateTimeUtc().addSecs(mDuration * 60) < QDateTime::currentDateTimeUtc();
|
mIsEnded = getDateTimeUtc().addSecs(mDuration * 60) < QDateTime::currentDateTimeUtc();
|
||||||
|
|
|
||||||
|
|
@ -4316,6 +4316,24 @@ To enable them in a commercial project, please contact us.</translation>
|
||||||
<source>unknown_audio_device_name</source>
|
<source>unknown_audio_device_name</source>
|
||||||
<translation>Unknown device name</translation>
|
<translation>Unknown device name</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation</source>
|
||||||
|
<extracomment>"Invitation à une réunion;"</extracomment>
|
||||||
|
<translation>Meeting invitation</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation_cancelled</source>
|
||||||
|
<extracomment>"Annulation d'une réunion;"</extracomment>
|
||||||
|
<translation>Meeting cancellation</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation_updated</source>
|
||||||
|
<extracomment>"Modification d'une réunion;"</extracomment>
|
||||||
|
<translation>Meeting modification</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Utils</name>
|
<name>Utils</name>
|
||||||
|
|
@ -5831,4 +5849,55 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
||||||
<translation>Ok</translation>
|
<translation>Ok</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ChatMessageInvitationBubble</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_invites_you_to</source>
|
||||||
|
<extracomment>" vous invite à :;"</extracomment>
|
||||||
|
<translation> invites you to :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_modified</source>
|
||||||
|
<extracomment>" a modifié :;"</extracomment>
|
||||||
|
<translation> modified :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_cancelled</source>
|
||||||
|
<extracomment>" a annulé :;"</extracomment>
|
||||||
|
<translation> cancelled :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_meeting_from</source>
|
||||||
|
<extracomment>"de ;"</extracomment>
|
||||||
|
<translation>from </translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_meeting_to</source>
|
||||||
|
<extracomment>" à ;"</extracomment>
|
||||||
|
<translation> to </translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_description_title</source>
|
||||||
|
<extracomment>"Description;"</extracomment>
|
||||||
|
<translation>Description</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_join</source>
|
||||||
|
<extracomment>"Rejoindre;"</extracomment>
|
||||||
|
<translation>Join</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_participants</source>
|
||||||
|
<extracomment>" participants;"</extracomment>
|
||||||
|
<translation> participants</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
||||||
|
|
@ -4331,6 +4331,24 @@ Pour les activer dans un projet commercial, merci de nous contacter.</translatio
|
||||||
<source>unknown_audio_device_name</source>
|
<source>unknown_audio_device_name</source>
|
||||||
<translation>Appareil inconnu</translation>
|
<translation>Appareil inconnu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation</source>
|
||||||
|
<extracomment>"Invitation à une réunion;"</extracomment>
|
||||||
|
<translation>Invitation à une réunion</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation_cancelled</source>
|
||||||
|
<extracomment>"Annulation d'une réunion;"</extracomment>
|
||||||
|
<translation>Annulation d'une réunion</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../model/chat/message/ChatMessageModel.cpp"/>
|
||||||
|
<source>conference_invitation_updated</source>
|
||||||
|
<extracomment>"Modification d'une réunion;"</extracomment>
|
||||||
|
<translation>Modification d'une réunion</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Utils</name>
|
<name>Utils</name>
|
||||||
|
|
@ -5846,4 +5864,55 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
||||||
<translation>Ok</translation>
|
<translation>Ok</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ChatMessageInvitationBubble</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_invites_you_to</source>
|
||||||
|
<extracomment>" vous invite à :"</extracomment>
|
||||||
|
<translation> vous invite à :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_modified</source>
|
||||||
|
<extracomment>" a modifié :;"</extracomment>
|
||||||
|
<translation> a modifié :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_organiser_cancelled</source>
|
||||||
|
<extracomment>" a annulé :;"</extracomment>
|
||||||
|
<translation> a annulé :</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_meeting_from</source>
|
||||||
|
<extracomment>"de ;"</extracomment>
|
||||||
|
<translation>de </translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_meeting_to</source>
|
||||||
|
<extracomment>" à ;"</extracomment>
|
||||||
|
<translation> à </translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_description_title</source>
|
||||||
|
<extracomment>"Description;"</extracomment>
|
||||||
|
<translation>Description</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_join</source>
|
||||||
|
<extracomment>"Rejoindre;"</extracomment>
|
||||||
|
<translation>Rejoindre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessageInvitationBubble.qml"/>
|
||||||
|
<source>ics_bubble_participants</source>
|
||||||
|
<extracomment>" participants;"</extracomment>
|
||||||
|
<translation> participants</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,17 @@ QString ChatMessageModel::getText() const {
|
||||||
return ToolModel::getMessageFromContent(mMonitor->getContents());
|
return ToolModel::getMessageFromContent(mMonitor->getContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ChatMessageModel::getUtf8Text() const {
|
||||||
|
return Utils::coreStringToAppString(mMonitor->getUtf8Text());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatMessageModel::getHasTextContent() const {
|
||||||
|
for (auto content : mMonitor->getContents()) {
|
||||||
|
if (content->isText()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString ChatMessageModel::getPeerAddress() const {
|
QString ChatMessageModel::getPeerAddress() const {
|
||||||
return Utils::coreStringToAppString(mMonitor->getPeerAddress()->asStringUriOnly());
|
return Utils::coreStringToAppString(mMonitor->getPeerAddress()->asStringUriOnly());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ public:
|
||||||
~ChatMessageModel();
|
~ChatMessageModel();
|
||||||
|
|
||||||
QString getText() const;
|
QString getText() const;
|
||||||
|
QString getUtf8Text() const;
|
||||||
|
bool getHasTextContent() const;
|
||||||
|
|
||||||
QDateTime getTimestamp() const;
|
QDateTime getTimestamp() const;
|
||||||
|
|
||||||
QString getPeerAddress() const;
|
QString getPeerAddress() const;
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,7 @@ linphone::ConferenceInfo::State ConferenceInfoModel::getState() const {
|
||||||
QString ConferenceInfoModel::getOrganizerName() const {
|
QString ConferenceInfoModel::getOrganizerName() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
auto organizer = mConferenceInfo->getOrganizer()->clone();
|
auto organizer = mConferenceInfo->getOrganizer()->clone();
|
||||||
auto name = Utils::coreStringToAppString(organizer->getDisplayName());
|
return ToolModel::getDisplayName(organizer);
|
||||||
if (name.isEmpty()) name = ToolModel::getDisplayName(organizer);
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConferenceInfoModel::getOrganizerAddress() const {
|
QString ConferenceInfoModel::getOrganizerAddress() const {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
#include "core/conference/ConferenceInfoCore.hpp"
|
||||||
|
|
||||||
DEFINE_ABSTRACT_OBJECT(ToolModel)
|
DEFINE_ABSTRACT_OBJECT(ToolModel)
|
||||||
|
|
||||||
|
|
@ -385,13 +386,21 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr<linphone::FriendList>
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ToolModel::getMessageFromContent(std::list<std::shared_ptr<linphone::Content>> contents) {
|
QString ToolModel::getMessageFromContent(std::list<std::shared_ptr<linphone::Content>> contents) {
|
||||||
|
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||||
for (auto &content : contents) {
|
for (auto &content : contents) {
|
||||||
if (content->isText()) {
|
if (content->isText()) {
|
||||||
return Utils::coreStringToAppString(content->getUtf8Text());
|
return Utils::coreStringToAppString(content->getUtf8Text());
|
||||||
} else if (content->isFile()) {
|
} else if (content->isFile()) {
|
||||||
return Utils::coreStringToAppString(content->getName());
|
return Utils::coreStringToAppString(content->getName());
|
||||||
} else if (content->isIcalendar()) {
|
} else if (content->isIcalendar()) {
|
||||||
return QString("Invitation à une réunion");
|
auto conferenceInfo = linphone::Factory::get()->createConferenceInfoFromIcalendarContent(content);
|
||||||
|
auto conferenceInfoCore = ConferenceInfoCore::create(conferenceInfo);
|
||||||
|
if (conferenceInfoCore->getConferenceInfoState() == LinphoneEnums::ConferenceInfoState::New)
|
||||||
|
return tr("conference_invitation");
|
||||||
|
if (conferenceInfoCore->getConferenceInfoState() == LinphoneEnums::ConferenceInfoState::Updated)
|
||||||
|
return tr("conference_invitation_updated");
|
||||||
|
if (conferenceInfoCore->getConferenceInfoState() == LinphoneEnums::ConferenceInfoState::Cancelled)
|
||||||
|
return tr("conference_invitation_cancelled");
|
||||||
} else if (content->isMultipart()) {
|
} else if (content->isMultipart()) {
|
||||||
return getMessageFromContent(content->getParts());
|
return getMessageFromContent(content->getParts());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/Control/Display/Call/CallStatistics.qml
|
view/Control/Display/Call/CallStatistics.qml
|
||||||
view/Control/Display/Chat/ChatListView.qml
|
view/Control/Display/Chat/ChatListView.qml
|
||||||
view/Control/Display/Chat/ChatMessage.qml
|
view/Control/Display/Chat/ChatMessage.qml
|
||||||
|
view/Control/Display/Chat/ChatMessageInvitationBubble.qml
|
||||||
view/Control/Display/Chat/ChatMessagesListView.qml
|
view/Control/Display/Chat/ChatMessagesListView.qml
|
||||||
view/Control/Display/Contact/Avatar.qml
|
view/Control/Display/Contact/Avatar.qml
|
||||||
view/Control/Display/Contact/Contact.qml
|
view/Control/Display/Contact/Contact.qml
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ Control.Control {
|
||||||
property bool isRemoteMessage: chatMessage? chatMessage.core.isRemoteMessage : false
|
property bool isRemoteMessage: chatMessage? chatMessage.core.isRemoteMessage : false
|
||||||
property bool isFromChatGroup: chatMessage? chatMessage.core.isFromChatGroup : false
|
property bool isFromChatGroup: chatMessage? chatMessage.core.isFromChatGroup : false
|
||||||
property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle
|
property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle
|
||||||
property string richFormatText: UtilsCpp.encodeTextToQmlRichFormat(modelData.core.text)
|
property string richFormatText: modelData.core.hasTextContent ? UtilsCpp.encodeTextToQmlRichFormat(modelData.core.utf8Text) : ""
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
property bool linkHovered: false
|
property bool linkHovered: false
|
||||||
|
|
||||||
|
|
@ -43,6 +43,12 @@ Control.Control {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDefaultMouseEvent(event) {
|
||||||
|
if (event.button === Qt.RightButton) {
|
||||||
|
optionsMenu.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
@ -69,15 +75,13 @@ Control.Control {
|
||||||
leftPadding: Math.round(12 * DefaultStyle.dp)
|
leftPadding: Math.round(12 * DefaultStyle.dp)
|
||||||
rightPadding: Math.round(12 * DefaultStyle.dp)
|
rightPadding: Math.round(12 * DefaultStyle.dp)
|
||||||
|
|
||||||
MouseArea {
|
MouseArea { // Default mouse area. Each sub bubble can control the mouse and pass on to the main mouse handler. Child bubble mouse area must cover the entire bubble.
|
||||||
|
id: defaultMouseArea
|
||||||
|
visible: invitationLoader.status !== Loader.Ready // Add other bubbles here that could control the mouse themselves, then add in bubble a signal onMouseEvent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.RightButton
|
acceptedButtons: Qt.RightButton
|
||||||
onClicked: (mouse) => {
|
onClicked: (mouse) => mainItem.handleDefaultMouseEvent(mouse)
|
||||||
if (mouse.button === Qt.RightButton) {
|
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
optionsMenu.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.IBeamCursor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Item {
|
background: Item {
|
||||||
|
|
@ -110,7 +114,7 @@ Control.Control {
|
||||||
visible: mainItem.imgUrl != undefined
|
visible: mainItem.imgUrl != undefined
|
||||||
id: contentimage
|
id: contentimage
|
||||||
}
|
}
|
||||||
Text {
|
Text { // Uses default mouse area for link hovering.
|
||||||
id: textElement
|
id: textElement
|
||||||
visible: mainItem.richFormatText !== ""
|
visible: mainItem.richFormatText !== ""
|
||||||
text: mainItem.richFormatText
|
text: mainItem.richFormatText
|
||||||
|
|
@ -134,6 +138,25 @@ Control.Control {
|
||||||
mainItem.linkHovered = hoveredLink !== ""
|
mainItem.linkHovered = hoveredLink !== ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Meeting invitation bubble
|
||||||
|
/////////////////////////////
|
||||||
|
Loader {
|
||||||
|
id: invitationLoader
|
||||||
|
active: modelData.core.conferenceInfo !== null
|
||||||
|
sourceComponent: invitationComponent
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: invitationComponent
|
||||||
|
ChatMessageInvitationBubble {
|
||||||
|
conferenceInfoGui: modelData.core.conferenceInfo
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
onMouseEvent: mainItem.handleDefaultMouseEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
Text {
|
Text {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,258 @@
|
||||||
|
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
|
||||||
|
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: mainItem
|
||||||
|
width: 490 * DefaultStyle.dp
|
||||||
|
height: content.implicitHeight
|
||||||
|
radius: 10 * DefaultStyle.dp
|
||||||
|
clip: true
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
property var conferenceInfoGui: ConferenceInfoGui
|
||||||
|
property var conferenceInfo: conferenceInfoGui?.core
|
||||||
|
property string timeRangeText: ""
|
||||||
|
property bool linkHovered: false
|
||||||
|
|
||||||
|
signal mouseEvent(MouseEvent event)
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
onClicked: (mouse) => mouseEvent(mouse)
|
||||||
|
acceptedButtons: Qt.AllButtons // Send all to parent
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTimeRange() {
|
||||||
|
if (!conferenceInfo || !conferenceInfo.dateTime || !conferenceInfo.duration)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let locale = Qt.locale();
|
||||||
|
let startDate = conferenceInfo.dateTime;
|
||||||
|
let endDate = new Date(startDate.getTime() + (conferenceInfo.duration * 60 * 1000));
|
||||||
|
|
||||||
|
let startTime = startDate.toLocaleTimeString(locale, "hh:mm");
|
||||||
|
let endTime = endDate.toLocaleTimeString(locale, "hh:mm");
|
||||||
|
|
||||||
|
let offsetMinutes = -startDate.getTimezoneOffset();
|
||||||
|
let offsetHours = Math.floor(offsetMinutes / 60);
|
||||||
|
let timeZone = "UTC" + (offsetHours >= 0 ? "+" : "") + offsetHours;
|
||||||
|
|
||||||
|
timeRangeText =
|
||||||
|
qsTr("ics_bubble_meeting_from") + startTime +
|
||||||
|
qsTr("ics_bubble_meeting_to") + endTime + " (" + timeZone + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: row1.implicitHeight + 32 * DefaultStyle.dp
|
||||||
|
color: DefaultStyle.grey_100
|
||||||
|
radius: 10 * DefaultStyle.dp // rounded all, but only top visible
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: row1
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 16 * DefaultStyle.dp
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.organizerName + (
|
||||||
|
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ?
|
||||||
|
qsTr("ics_bubble_organiser_invites_you_to") :
|
||||||
|
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
|
||||||
|
qsTr("ics_bubble_organiser_modified") :
|
||||||
|
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
|
||||||
|
qsTr("ics_bubble_organiser_cancelled") :
|
||||||
|
""
|
||||||
|
)
|
||||||
|
font: Typography.p2
|
||||||
|
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ?
|
||||||
|
DefaultStyle.main2_600 :
|
||||||
|
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
|
||||||
|
DefaultStyle.warning_600 :
|
||||||
|
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
|
||||||
|
DefaultStyle.danger_500main :
|
||||||
|
DefaultStyle.main2_600
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 10 * DefaultStyle.dp
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 48 * DefaultStyle.dp
|
||||||
|
height: 48 * DefaultStyle.dp
|
||||||
|
radius: 10 * DefaultStyle.dp
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#33000000"
|
||||||
|
radius: 10 * DefaultStyle.dp
|
||||||
|
anchors.verticalCenterOffset: 4 * DefaultStyle.dp
|
||||||
|
z: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: dayRect
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: 10 * DefaultStyle.dp
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 2 * DefaultStyle.dp
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "ddd") + "."
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
font: Typography.p4
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 23 * DefaultStyle.dp
|
||||||
|
height: 23 * DefaultStyle.dp
|
||||||
|
radius: width / 2
|
||||||
|
color: DefaultStyle.main1_500_main
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.dateTime.getDate().toString()
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
font: Typography.h4
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info
|
||||||
|
ColumnLayout {
|
||||||
|
RowLayout {
|
||||||
|
EffectImage {
|
||||||
|
imageSource: AppIcons.usersThree
|
||||||
|
colorizationColor: DefaultStyle.main2_600
|
||||||
|
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.subject
|
||||||
|
font: Typography.p2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
color: DefaultStyle.main2_600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy")
|
||||||
|
font: Typography.p4
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: timeRangeText
|
||||||
|
font: Typography.p4
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 10 * DefaultStyle.dp
|
||||||
|
color: DefaultStyle.grey_100
|
||||||
|
Layout.topMargin: -10 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: row2.implicitHeight + 32 * DefaultStyle.dp
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
radius: 10 * DefaultStyle.dp
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: row2
|
||||||
|
spacing: 10 * DefaultStyle.dp
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 16 * DefaultStyle.dp
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("ics_bubble_description_title")
|
||||||
|
font: Typography.p4
|
||||||
|
color: DefaultStyle.main2_800
|
||||||
|
visible: conferenceInfo.description.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: UtilsCpp.encodeTextToQmlRichFormat(conferenceInfo.description)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textFormat: Text.RichText
|
||||||
|
font: Typography.p4
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
visible: conferenceInfo.description.length > 0
|
||||||
|
onLinkActivated: {
|
||||||
|
if (link.startsWith('sip'))
|
||||||
|
UtilsCpp.createCall(link)
|
||||||
|
else
|
||||||
|
Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
onHoveredLinkChanged: {
|
||||||
|
mainItem.linkHovered = hoveredLink !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||||
|
spacing: 10 * DefaultStyle.dp
|
||||||
|
EffectImage {
|
||||||
|
imageSource: AppIcons.usersTwo
|
||||||
|
colorizationColor: DefaultStyle.main2_600
|
||||||
|
Layout.preferredWidth: Math.round(14 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(14 * DefaultStyle.dp)
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: conferenceInfo.participantCount + qsTr("ics_bubble_participants")
|
||||||
|
font: Typography.p4
|
||||||
|
color: DefaultStyle.main2_800
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
MediumButton {
|
||||||
|
style: ButtonStyle.ButtonStyle
|
||||||
|
//: "Rejoindre"
|
||||||
|
text: qsTr("ics_bubble_join")
|
||||||
|
visible: !SettingsCpp.disableMeetingsFeature && conferenceInfo.state != LinphoneEnums.ConferenceInfoState.Cancelled
|
||||||
|
onClicked: {
|
||||||
|
var callsWindow = UtilsCpp.getCallsWindow()
|
||||||
|
callsWindow.setupConference(mainItem.conferenceInfoGui)
|
||||||
|
UtilsCpp.smartShowWindow(callsWindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ QtObject {
|
||||||
pixelSize: Math.round(20 * DefaultStyle.dp),
|
pixelSize: Math.round(20 * DefaultStyle.dp),
|
||||||
weight: Math.min(Math.round(800 * DefaultStyle.dp), 1000)
|
weight: Math.min(Math.round(800 * DefaultStyle.dp), 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Title/H2 - Large bloc title
|
// Title/H2 - Large bloc title
|
||||||
property font h2: Qt.font( {
|
property font h2: Qt.font( {
|
||||||
family: DefaultStyle.defaultFont,
|
family: DefaultStyle.defaultFont,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue